dom/bluetooth/ObexBase.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/bluetooth/ObexBase.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,272 @@
     1.4 +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
     1.5 +/* vim: set ts=2 et sw=2 tw=80: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#ifndef mozilla_dom_bluetooth_obexbase_h__
    1.11 +#define mozilla_dom_bluetooth_obexbase_h__
    1.12 +
    1.13 +#include "BluetoothCommon.h"
    1.14 +#include "nsAutoPtr.h"
    1.15 +#include "nsTArray.h"
    1.16 +
    1.17 +BEGIN_BLUETOOTH_NAMESPACE
    1.18 +
    1.19 +const char FINAL_BIT = 0x80;
    1.20 +
    1.21 +/*
    1.22 + * Defined in section 2.1 "OBEX Headers", IrOBEX ver 1.2
    1.23 + */
    1.24 +enum ObexHeaderId {
    1.25 +  Count = 0xC0,
    1.26 +  Name = 0x01,
    1.27 +  Type = 0x42,
    1.28 +  Length = 0xC3,
    1.29 +  TimeISO8601 = 0x44,
    1.30 +  Time4Byte = 0xC4,
    1.31 +  Description = 0x05,
    1.32 +  Target = 0x46,
    1.33 +  HTTP = 0x47,
    1.34 +  Body = 0x48,
    1.35 +  EndOfBody = 0x49,
    1.36 +  Who = 0x4A,
    1.37 +  ConnectionId = 0xCB,
    1.38 +  AppParameters = 0x4C,
    1.39 +  AuthChallenge = 0x4D,
    1.40 +  AuthResponse = 0x4E,
    1.41 +  ObjectClass = 0x4F
    1.42 +};
    1.43 +
    1.44 +/*
    1.45 + * Defined in section 3.3 "OBEX Operations and Opcode definitions",
    1.46 + * IrOBEX ver 1.2
    1.47 + */
    1.48 +enum ObexRequestCode {
    1.49 +  Connect = 0x80,
    1.50 +  Disconnect = 0x81,
    1.51 +  Put = 0x02,
    1.52 +  PutFinal = 0x82,
    1.53 +  Get = 0x03,
    1.54 +  GetFinal = 0x83,
    1.55 +  SetPath = 0x85,
    1.56 +  Abort = 0xFF
    1.57 +};
    1.58 +
    1.59 +/*
    1.60 + * Defined in section 3.2.1 "Response Code values", IrOBEX ver 1.2
    1.61 + */
    1.62 +enum ObexResponseCode {
    1.63 +  Continue = 0x90,
    1.64 +
    1.65 +  Success = 0xA0,
    1.66 +  Created = 0xA1,
    1.67 +  Accepted = 0xA2,
    1.68 +  NonAuthoritativeInfo = 0xA3,
    1.69 +  NoContent = 0xA4,
    1.70 +  ResetContent = 0xA5,
    1.71 +  PartialContent = 0xA6,
    1.72 +
    1.73 +  MultipleChoices = 0xB0,
    1.74 +  MovedPermanently = 0xB1,
    1.75 +  MovedTemporarily = 0xB2,
    1.76 +  SeeOther = 0xB3,
    1.77 +  NotModified = 0xB4,
    1.78 +  UseProxy = 0xB5,
    1.79 +
    1.80 +  BadRequest = 0xC0,
    1.81 +  Unauthorized = 0xC1,
    1.82 +  PaymentRequired = 0xC2,
    1.83 +  Forbidden = 0xC3,
    1.84 +  NotFound = 0xC4,
    1.85 +  MethodNotAllowed = 0xC5,
    1.86 +  NotAcceptable = 0xC6,
    1.87 +  ProxyAuthenticationRequired = 0xC7,
    1.88 +  RequestTimeOut = 0xC8,
    1.89 +  Conflict = 0xC9,
    1.90 +  Gone = 0xCA,
    1.91 +  LengthRequired = 0xCB,
    1.92 +  PreconditionFailed = 0xCC,
    1.93 +  RequestedEntityTooLarge = 0xCD,
    1.94 +  RequestUrlTooLarge = 0xCE,
    1.95 +  UnsupprotedMediaType = 0xCF,
    1.96 +
    1.97 +  InternalServerError = 0xD0,
    1.98 +  NotImplemented = 0xD1,
    1.99 +  BadGateway = 0xD2,
   1.100 +  ServiceUnavailable = 0xD3,
   1.101 +  GatewayTimeout = 0xD4,
   1.102 +  HttpVersionNotSupported = 0xD5,
   1.103 +
   1.104 +  DatabaseFull = 0xE0,
   1.105 +  DatabaseLocked = 0xE1,
   1.106 +};
   1.107 +
   1.108 +class ObexHeader
   1.109 +{
   1.110 +public:
   1.111 +  ObexHeader(ObexHeaderId aId, int aDataLength, const uint8_t* aData)
   1.112 +    : mId(aId)
   1.113 +    , mDataLength(aDataLength)
   1.114 +    , mData(nullptr)
   1.115 +  {
   1.116 +    mData = new uint8_t[mDataLength];
   1.117 +    memcpy(mData, aData, aDataLength);
   1.118 +  }
   1.119 +
   1.120 +  ~ObexHeader()
   1.121 +  {
   1.122 +  }
   1.123 +
   1.124 +  ObexHeaderId mId;
   1.125 +  int mDataLength;
   1.126 +  nsAutoArrayPtr<uint8_t> mData;
   1.127 +};
   1.128 +
   1.129 +class ObexHeaderSet
   1.130 +{
   1.131 +public:
   1.132 +  ObexHeaderSet(uint8_t aOpcode) : mOpcode(aOpcode)
   1.133 +  {
   1.134 +  }
   1.135 +
   1.136 +  ~ObexHeaderSet()
   1.137 +  {
   1.138 +  }
   1.139 +
   1.140 +  void AddHeader(ObexHeader* aHeader)
   1.141 +  {
   1.142 +    mHeaders.AppendElement(aHeader);
   1.143 +  }
   1.144 +
   1.145 +  void GetName(nsString& aRetName) const
   1.146 +  {
   1.147 +    aRetName.Truncate();
   1.148 +
   1.149 +    int length = mHeaders.Length();
   1.150 +
   1.151 +    for (int i = 0; i < length; ++i) {
   1.152 +      if (mHeaders[i]->mId == ObexHeaderId::Name) {
   1.153 +        /*
   1.154 +         * According to section 2.2.2 [Name] of IrOBEX spec, we know that
   1.155 +         * the Name header is "a null terminated Unicode text string describing
   1.156 +         * the name of the object.", and that's the reason why we need to minus
   1.157 +         * 1 to get the real length of the file name.
   1.158 +         */
   1.159 +        int nameLength = mHeaders[i]->mDataLength / 2 - 1;
   1.160 +        uint8_t* ptr = mHeaders[i]->mData.get();
   1.161 +
   1.162 +        for (int j = 0; j < nameLength; ++j) {
   1.163 +          char16_t c = ((((uint32_t)ptr[j * 2]) << 8) | ptr[j * 2 + 1]);
   1.164 +          aRetName += c;
   1.165 +        }
   1.166 +
   1.167 +        break;
   1.168 +      }
   1.169 +    }
   1.170 +  }
   1.171 +
   1.172 +  void GetContentType(nsString& aRetContentType) const
   1.173 +  {
   1.174 +    aRetContentType.Truncate();
   1.175 +
   1.176 +    int length = mHeaders.Length();
   1.177 +
   1.178 +    for (int i = 0; i < length; ++i) {
   1.179 +      if (mHeaders[i]->mId == ObexHeaderId::Type) {
   1.180 +        uint8_t* ptr = mHeaders[i]->mData.get();
   1.181 +        aRetContentType.AssignASCII((const char*)ptr);
   1.182 +        break;
   1.183 +      }
   1.184 +    }
   1.185 +  }
   1.186 +
   1.187 +  // @return file length, 0 means file length is unknown.
   1.188 +  void GetLength(uint32_t* aRetLength) const
   1.189 +  {
   1.190 +    int length = mHeaders.Length();
   1.191 +    *aRetLength = 0;
   1.192 +
   1.193 +    for (int i = 0; i < length; ++i) {
   1.194 +      if (mHeaders[i]->mId == ObexHeaderId::Length) {
   1.195 +        uint8_t* ptr = mHeaders[i]->mData.get();
   1.196 +        *aRetLength = ((uint32_t)ptr[0] << 24) |
   1.197 +                      ((uint32_t)ptr[1] << 16) |
   1.198 +                      ((uint32_t)ptr[2] << 8) |
   1.199 +                      ((uint32_t)ptr[3]);
   1.200 +        return;
   1.201 +      }
   1.202 +    }
   1.203 +  }
   1.204 +
   1.205 +  void GetBodyLength(int* aRetBodyLength) const
   1.206 +  {
   1.207 +    int length = mHeaders.Length();
   1.208 +    *aRetBodyLength = 0;
   1.209 +
   1.210 +    for (int i = 0; i < length; ++i) {
   1.211 +      if (mHeaders[i]->mId == ObexHeaderId::Body ||
   1.212 +          mHeaders[i]->mId == ObexHeaderId::EndOfBody) {
   1.213 +        *aRetBodyLength = mHeaders[i]->mDataLength;
   1.214 +        return;
   1.215 +      }
   1.216 +    }
   1.217 +  }
   1.218 +
   1.219 +  void GetBody(uint8_t** aRetBody) const
   1.220 +  {
   1.221 +    int length = mHeaders.Length();
   1.222 +    *aRetBody = nullptr;
   1.223 +
   1.224 +    for (int i = 0; i < length; ++i) {
   1.225 +      if (mHeaders[i]->mId == ObexHeaderId::Body ||
   1.226 +          mHeaders[i]->mId == ObexHeaderId::EndOfBody) {
   1.227 +        uint8_t* ptr = mHeaders[i]->mData.get();
   1.228 +        *aRetBody = new uint8_t[mHeaders[i]->mDataLength];
   1.229 +        memcpy(*aRetBody, ptr, mHeaders[i]->mDataLength);
   1.230 +        return;
   1.231 +      }
   1.232 +    }
   1.233 +  }
   1.234 +
   1.235 +  bool Has(ObexHeaderId aId) const
   1.236 +  {
   1.237 +    int length = mHeaders.Length();
   1.238 +    for (int i = 0; i < length; ++i) {
   1.239 +      if (mHeaders[i]->mId == aId) {
   1.240 +        return true;
   1.241 +      }
   1.242 +    }
   1.243 +
   1.244 +    return false;
   1.245 +  }
   1.246 +
   1.247 +  void ClearHeaders()
   1.248 +  {
   1.249 +    mHeaders.Clear();
   1.250 +  }
   1.251 +
   1.252 +private:
   1.253 +  uint8_t mOpcode;
   1.254 +  nsTArray<nsAutoPtr<ObexHeader> > mHeaders;
   1.255 +};
   1.256 +
   1.257 +int AppendHeaderName(uint8_t* aRetBuf, int aBufferSize, const char* aName,
   1.258 +                     int aLength);
   1.259 +int AppendHeaderBody(uint8_t* aRetBuf, int aBufferSize, const uint8_t* aData,
   1.260 +                     int aLength);
   1.261 +int AppendHeaderEndOfBody(uint8_t* aRetBuf);
   1.262 +int AppendHeaderLength(uint8_t* aRetBuf, int aObjectLength);
   1.263 +int AppendHeaderConnectionId(uint8_t* aRetBuf, int aConnectionId);
   1.264 +void SetObexPacketInfo(uint8_t* aRetBuf, uint8_t aOpcode, int aPacketLength);
   1.265 +
   1.266 +/**
   1.267 + * @return true when the message was parsed without any error, false otherwise.
   1.268 + */
   1.269 +bool ParseHeaders(const uint8_t* aHeaderStart,
   1.270 +                  int aTotalLength,
   1.271 +                  ObexHeaderSet* aRetHanderSet);
   1.272 +
   1.273 +END_BLUETOOTH_NAMESPACE
   1.274 +
   1.275 +#endif

mercurial