dom/bluetooth/ObexBase.h

Thu, 15 Jan 2015 15:55:04 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:55:04 +0100
branch
TOR_BUG_9701
changeset 9
a63d609f5ebe
permissions
-rw-r--r--

Back out 97036ab72558 which inappropriately compared turds to third parties.

michael@0 1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
michael@0 2 /* vim: set ts=2 et sw=2 tw=80: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #ifndef mozilla_dom_bluetooth_obexbase_h__
michael@0 8 #define mozilla_dom_bluetooth_obexbase_h__
michael@0 9
michael@0 10 #include "BluetoothCommon.h"
michael@0 11 #include "nsAutoPtr.h"
michael@0 12 #include "nsTArray.h"
michael@0 13
michael@0 14 BEGIN_BLUETOOTH_NAMESPACE
michael@0 15
michael@0 16 const char FINAL_BIT = 0x80;
michael@0 17
michael@0 18 /*
michael@0 19 * Defined in section 2.1 "OBEX Headers", IrOBEX ver 1.2
michael@0 20 */
michael@0 21 enum ObexHeaderId {
michael@0 22 Count = 0xC0,
michael@0 23 Name = 0x01,
michael@0 24 Type = 0x42,
michael@0 25 Length = 0xC3,
michael@0 26 TimeISO8601 = 0x44,
michael@0 27 Time4Byte = 0xC4,
michael@0 28 Description = 0x05,
michael@0 29 Target = 0x46,
michael@0 30 HTTP = 0x47,
michael@0 31 Body = 0x48,
michael@0 32 EndOfBody = 0x49,
michael@0 33 Who = 0x4A,
michael@0 34 ConnectionId = 0xCB,
michael@0 35 AppParameters = 0x4C,
michael@0 36 AuthChallenge = 0x4D,
michael@0 37 AuthResponse = 0x4E,
michael@0 38 ObjectClass = 0x4F
michael@0 39 };
michael@0 40
michael@0 41 /*
michael@0 42 * Defined in section 3.3 "OBEX Operations and Opcode definitions",
michael@0 43 * IrOBEX ver 1.2
michael@0 44 */
michael@0 45 enum ObexRequestCode {
michael@0 46 Connect = 0x80,
michael@0 47 Disconnect = 0x81,
michael@0 48 Put = 0x02,
michael@0 49 PutFinal = 0x82,
michael@0 50 Get = 0x03,
michael@0 51 GetFinal = 0x83,
michael@0 52 SetPath = 0x85,
michael@0 53 Abort = 0xFF
michael@0 54 };
michael@0 55
michael@0 56 /*
michael@0 57 * Defined in section 3.2.1 "Response Code values", IrOBEX ver 1.2
michael@0 58 */
michael@0 59 enum ObexResponseCode {
michael@0 60 Continue = 0x90,
michael@0 61
michael@0 62 Success = 0xA0,
michael@0 63 Created = 0xA1,
michael@0 64 Accepted = 0xA2,
michael@0 65 NonAuthoritativeInfo = 0xA3,
michael@0 66 NoContent = 0xA4,
michael@0 67 ResetContent = 0xA5,
michael@0 68 PartialContent = 0xA6,
michael@0 69
michael@0 70 MultipleChoices = 0xB0,
michael@0 71 MovedPermanently = 0xB1,
michael@0 72 MovedTemporarily = 0xB2,
michael@0 73 SeeOther = 0xB3,
michael@0 74 NotModified = 0xB4,
michael@0 75 UseProxy = 0xB5,
michael@0 76
michael@0 77 BadRequest = 0xC0,
michael@0 78 Unauthorized = 0xC1,
michael@0 79 PaymentRequired = 0xC2,
michael@0 80 Forbidden = 0xC3,
michael@0 81 NotFound = 0xC4,
michael@0 82 MethodNotAllowed = 0xC5,
michael@0 83 NotAcceptable = 0xC6,
michael@0 84 ProxyAuthenticationRequired = 0xC7,
michael@0 85 RequestTimeOut = 0xC8,
michael@0 86 Conflict = 0xC9,
michael@0 87 Gone = 0xCA,
michael@0 88 LengthRequired = 0xCB,
michael@0 89 PreconditionFailed = 0xCC,
michael@0 90 RequestedEntityTooLarge = 0xCD,
michael@0 91 RequestUrlTooLarge = 0xCE,
michael@0 92 UnsupprotedMediaType = 0xCF,
michael@0 93
michael@0 94 InternalServerError = 0xD0,
michael@0 95 NotImplemented = 0xD1,
michael@0 96 BadGateway = 0xD2,
michael@0 97 ServiceUnavailable = 0xD3,
michael@0 98 GatewayTimeout = 0xD4,
michael@0 99 HttpVersionNotSupported = 0xD5,
michael@0 100
michael@0 101 DatabaseFull = 0xE0,
michael@0 102 DatabaseLocked = 0xE1,
michael@0 103 };
michael@0 104
michael@0 105 class ObexHeader
michael@0 106 {
michael@0 107 public:
michael@0 108 ObexHeader(ObexHeaderId aId, int aDataLength, const uint8_t* aData)
michael@0 109 : mId(aId)
michael@0 110 , mDataLength(aDataLength)
michael@0 111 , mData(nullptr)
michael@0 112 {
michael@0 113 mData = new uint8_t[mDataLength];
michael@0 114 memcpy(mData, aData, aDataLength);
michael@0 115 }
michael@0 116
michael@0 117 ~ObexHeader()
michael@0 118 {
michael@0 119 }
michael@0 120
michael@0 121 ObexHeaderId mId;
michael@0 122 int mDataLength;
michael@0 123 nsAutoArrayPtr<uint8_t> mData;
michael@0 124 };
michael@0 125
michael@0 126 class ObexHeaderSet
michael@0 127 {
michael@0 128 public:
michael@0 129 ObexHeaderSet(uint8_t aOpcode) : mOpcode(aOpcode)
michael@0 130 {
michael@0 131 }
michael@0 132
michael@0 133 ~ObexHeaderSet()
michael@0 134 {
michael@0 135 }
michael@0 136
michael@0 137 void AddHeader(ObexHeader* aHeader)
michael@0 138 {
michael@0 139 mHeaders.AppendElement(aHeader);
michael@0 140 }
michael@0 141
michael@0 142 void GetName(nsString& aRetName) const
michael@0 143 {
michael@0 144 aRetName.Truncate();
michael@0 145
michael@0 146 int length = mHeaders.Length();
michael@0 147
michael@0 148 for (int i = 0; i < length; ++i) {
michael@0 149 if (mHeaders[i]->mId == ObexHeaderId::Name) {
michael@0 150 /*
michael@0 151 * According to section 2.2.2 [Name] of IrOBEX spec, we know that
michael@0 152 * the Name header is "a null terminated Unicode text string describing
michael@0 153 * the name of the object.", and that's the reason why we need to minus
michael@0 154 * 1 to get the real length of the file name.
michael@0 155 */
michael@0 156 int nameLength = mHeaders[i]->mDataLength / 2 - 1;
michael@0 157 uint8_t* ptr = mHeaders[i]->mData.get();
michael@0 158
michael@0 159 for (int j = 0; j < nameLength; ++j) {
michael@0 160 char16_t c = ((((uint32_t)ptr[j * 2]) << 8) | ptr[j * 2 + 1]);
michael@0 161 aRetName += c;
michael@0 162 }
michael@0 163
michael@0 164 break;
michael@0 165 }
michael@0 166 }
michael@0 167 }
michael@0 168
michael@0 169 void GetContentType(nsString& aRetContentType) const
michael@0 170 {
michael@0 171 aRetContentType.Truncate();
michael@0 172
michael@0 173 int length = mHeaders.Length();
michael@0 174
michael@0 175 for (int i = 0; i < length; ++i) {
michael@0 176 if (mHeaders[i]->mId == ObexHeaderId::Type) {
michael@0 177 uint8_t* ptr = mHeaders[i]->mData.get();
michael@0 178 aRetContentType.AssignASCII((const char*)ptr);
michael@0 179 break;
michael@0 180 }
michael@0 181 }
michael@0 182 }
michael@0 183
michael@0 184 // @return file length, 0 means file length is unknown.
michael@0 185 void GetLength(uint32_t* aRetLength) const
michael@0 186 {
michael@0 187 int length = mHeaders.Length();
michael@0 188 *aRetLength = 0;
michael@0 189
michael@0 190 for (int i = 0; i < length; ++i) {
michael@0 191 if (mHeaders[i]->mId == ObexHeaderId::Length) {
michael@0 192 uint8_t* ptr = mHeaders[i]->mData.get();
michael@0 193 *aRetLength = ((uint32_t)ptr[0] << 24) |
michael@0 194 ((uint32_t)ptr[1] << 16) |
michael@0 195 ((uint32_t)ptr[2] << 8) |
michael@0 196 ((uint32_t)ptr[3]);
michael@0 197 return;
michael@0 198 }
michael@0 199 }
michael@0 200 }
michael@0 201
michael@0 202 void GetBodyLength(int* aRetBodyLength) const
michael@0 203 {
michael@0 204 int length = mHeaders.Length();
michael@0 205 *aRetBodyLength = 0;
michael@0 206
michael@0 207 for (int i = 0; i < length; ++i) {
michael@0 208 if (mHeaders[i]->mId == ObexHeaderId::Body ||
michael@0 209 mHeaders[i]->mId == ObexHeaderId::EndOfBody) {
michael@0 210 *aRetBodyLength = mHeaders[i]->mDataLength;
michael@0 211 return;
michael@0 212 }
michael@0 213 }
michael@0 214 }
michael@0 215
michael@0 216 void GetBody(uint8_t** aRetBody) const
michael@0 217 {
michael@0 218 int length = mHeaders.Length();
michael@0 219 *aRetBody = nullptr;
michael@0 220
michael@0 221 for (int i = 0; i < length; ++i) {
michael@0 222 if (mHeaders[i]->mId == ObexHeaderId::Body ||
michael@0 223 mHeaders[i]->mId == ObexHeaderId::EndOfBody) {
michael@0 224 uint8_t* ptr = mHeaders[i]->mData.get();
michael@0 225 *aRetBody = new uint8_t[mHeaders[i]->mDataLength];
michael@0 226 memcpy(*aRetBody, ptr, mHeaders[i]->mDataLength);
michael@0 227 return;
michael@0 228 }
michael@0 229 }
michael@0 230 }
michael@0 231
michael@0 232 bool Has(ObexHeaderId aId) const
michael@0 233 {
michael@0 234 int length = mHeaders.Length();
michael@0 235 for (int i = 0; i < length; ++i) {
michael@0 236 if (mHeaders[i]->mId == aId) {
michael@0 237 return true;
michael@0 238 }
michael@0 239 }
michael@0 240
michael@0 241 return false;
michael@0 242 }
michael@0 243
michael@0 244 void ClearHeaders()
michael@0 245 {
michael@0 246 mHeaders.Clear();
michael@0 247 }
michael@0 248
michael@0 249 private:
michael@0 250 uint8_t mOpcode;
michael@0 251 nsTArray<nsAutoPtr<ObexHeader> > mHeaders;
michael@0 252 };
michael@0 253
michael@0 254 int AppendHeaderName(uint8_t* aRetBuf, int aBufferSize, const char* aName,
michael@0 255 int aLength);
michael@0 256 int AppendHeaderBody(uint8_t* aRetBuf, int aBufferSize, const uint8_t* aData,
michael@0 257 int aLength);
michael@0 258 int AppendHeaderEndOfBody(uint8_t* aRetBuf);
michael@0 259 int AppendHeaderLength(uint8_t* aRetBuf, int aObjectLength);
michael@0 260 int AppendHeaderConnectionId(uint8_t* aRetBuf, int aConnectionId);
michael@0 261 void SetObexPacketInfo(uint8_t* aRetBuf, uint8_t aOpcode, int aPacketLength);
michael@0 262
michael@0 263 /**
michael@0 264 * @return true when the message was parsed without any error, false otherwise.
michael@0 265 */
michael@0 266 bool ParseHeaders(const uint8_t* aHeaderStart,
michael@0 267 int aTotalLength,
michael@0 268 ObexHeaderSet* aRetHanderSet);
michael@0 269
michael@0 270 END_BLUETOOTH_NAMESPACE
michael@0 271
michael@0 272 #endif

mercurial