dom/bluetooth/ObexBase.h

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

mercurial