|
1 /* |
|
2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <errno.h> |
|
20 #include <sys/types.h> |
|
21 #include <sys/stat.h> |
|
22 #include <dirent.h> |
|
23 #include <sys/uio.h> |
|
24 #include <unistd.h> |
|
25 #include <fcntl.h> |
|
26 |
|
27 #include "fs_methodcall.h" |
|
28 #include "javajniutils.h" |
|
29 #include "servicerecord.h" |
|
30 #include "logger.h" |
|
31 #include "javasymbianoslayer.h" |
|
32 #include "bluetoothconsts.h" |
|
33 #include "applicationinfo.h" |
|
34 #include "fileutilities.h" |
|
35 #include "javaoslayer.h" |
|
36 #include "javacommonutils.h" |
|
37 #include "btservicerecordpopulator.h" |
|
38 #include "serviceclasshandler.h" |
|
39 #include "fileutilities.h" |
|
40 #include "exceptionbase.h" |
|
41 |
|
42 using namespace java::util; |
|
43 using namespace java::fileutils; |
|
44 |
|
45 namespace java |
|
46 { |
|
47 namespace bluetooth |
|
48 { |
|
49 |
|
50 #define SERVICE_AVAILABLE 0xFF |
|
51 #define KGOEP 0x0008 // This is the fixed Id. Should not be modified at any time. |
|
52 #define SERVICE_CLASSES_BITS_POS 13 |
|
53 |
|
54 // Permission: Read,Write,Execute for both Owner & Group |
|
55 #define BT_DIR_PERM 0777 |
|
56 |
|
57 /** |
|
58 * Returns the new ServiceRecord object. |
|
59 */ |
|
60 OS_EXPORT ServiceRecord* ServiceRecord::NewL(BluetoothFunctionServer* aServer) |
|
61 { |
|
62 JELOG2(EJavaBluetooth); |
|
63 ServiceRecord* servRec = new ServiceRecord(aServer); |
|
64 CleanupStack::PushL(servRec); |
|
65 |
|
66 servRec->ConstructL(); |
|
67 |
|
68 CleanupStack::Pop(servRec); |
|
69 |
|
70 return servRec; |
|
71 } |
|
72 |
|
73 OS_EXPORT void ServiceRecord::cleanup(ServiceRecord*& aServer) |
|
74 { |
|
75 JELOG2(EJavaBluetooth); |
|
76 if (aServer) |
|
77 { |
|
78 aServer->cleanUp(); |
|
79 delete aServer; |
|
80 aServer = NULL; |
|
81 } |
|
82 } |
|
83 |
|
84 void ServiceRecord::ConstructL() |
|
85 { |
|
86 JELOG2(EJavaBluetooth); |
|
87 |
|
88 mInitializedByPush = false; |
|
89 mRestoredFromPersistentFile = false; |
|
90 |
|
91 // Open sdp session |
|
92 User::LeaveIfError(mSdp.Connect()); |
|
93 |
|
94 // Open sdp database session |
|
95 User::LeaveIfError(mSdpDB.Open(mSdp)); |
|
96 |
|
97 mRecordState = 0; |
|
98 } |
|
99 |
|
100 ServiceRecord::ServiceRecord(BluetoothFunctionServer* aServer) |
|
101 { |
|
102 JELOG2(EJavaBluetooth); |
|
103 mFunctionServer = aServer; |
|
104 mRecord = 0; |
|
105 mSrvRecFd = 0; |
|
106 } |
|
107 |
|
108 ServiceRecord::~ServiceRecord() |
|
109 { |
|
110 JELOG2(EJavaBluetooth); |
|
111 mFunctionServer = NULL; |
|
112 } |
|
113 |
|
114 void ServiceRecord::cleanUp() |
|
115 { |
|
116 JELOG2(EJavaBluetooth); |
|
117 if (mRecord) |
|
118 { |
|
119 TRAP_IGNORE(mSdpDB.DeleteRecordL(mRecord)); |
|
120 mRecord = 0; |
|
121 } |
|
122 mSdpDB.Close(); |
|
123 mSdp.Close(); |
|
124 } |
|
125 |
|
126 /** |
|
127 * Used in case there is no persistence storage of service record |
|
128 * On success returns 0; otherwise err number. |
|
129 * |
|
130 * Creates and initializes the Service record. |
|
131 * aProtocol: One among the PROTOCOL_L2CAP, PROTOCOL_RFCOMM, PROTOCOL_GOEP |
|
132 * aPSMValue: In case of L2CAP it should be PSM Value; |
|
133 * In case of RFComm it should be channel number. |
|
134 * aUuid: UUID string of the current service |
|
135 * aServiceName: Name of the current service. |
|
136 */ |
|
137 |
|
138 OS_EXPORT int ServiceRecord::initializeRecord(int aProtocol, int aPSMValue, |
|
139 std::wstring aUuid, std::wstring aServiceName) |
|
140 { |
|
141 JELOG2(EJavaBluetooth); |
|
142 |
|
143 int uuidByteLength = 0; |
|
144 TUint8* uuidBytes = uuidToByteArray(aUuid, uuidByteLength); |
|
145 |
|
146 TUUID uuid; |
|
147 |
|
148 TPtrC8 uuidDes(uuidBytes, uuidByteLength); |
|
149 TRAPD(err, uuid.SetL(uuidDes)); |
|
150 |
|
151 delete uuidBytes; |
|
152 uuidBytes = NULL; |
|
153 |
|
154 if (KErrNone != err) |
|
155 { |
|
156 LOG2(EJavaBluetooth, EInfo, |
|
157 "- ServiceRecord::initializeRecord Error SetL:%d [UUID:%S]", |
|
158 err, aUuid.c_str()); |
|
159 return err; |
|
160 } |
|
161 |
|
162 HBufC* nameString = wstringToBuf(aServiceName); |
|
163 TPtrC nameBufPointer(nameString->Des()); |
|
164 |
|
165 HBufC8* utf8NameBuffer = HBufC8::NewMax(aServiceName.length() + 1); |
|
166 TPtr8 utf8NameBufferPtr(utf8NameBuffer->Des()); |
|
167 |
|
168 utf8NameBufferPtr.Copy(nameBufPointer); |
|
169 |
|
170 TRAP(err, initializeRecordL(aProtocol, aPSMValue, uuid, utf8NameBufferPtr)); |
|
171 |
|
172 return err; |
|
173 } |
|
174 |
|
175 /** |
|
176 * Used in case of persistence storage of updated service record |
|
177 */ |
|
178 OS_EXPORT int ServiceRecord::restorePersistentRecord() |
|
179 { |
|
180 JELOG2(EJavaBluetooth); |
|
181 int ret = 0; |
|
182 |
|
183 CallMethod(ret, this, &ServiceRecord::restorePersistentRecordFs, |
|
184 mFunctionServer); |
|
185 return ret; |
|
186 } |
|
187 |
|
188 int ServiceRecord::restorePersistentRecordFs() |
|
189 { |
|
190 JELOG2(EJavaBluetooth); |
|
191 |
|
192 // Can set this flag as this function will get called |
|
193 // only in case of push invocation |
|
194 mInitializedByPush = true; |
|
195 |
|
196 std::wstring persistentFileName = getPersistentFileName(); |
|
197 int persistentRecFd = -1; |
|
198 int ret = 0; |
|
199 int err = 0; |
|
200 |
|
201 if (persistentFileName.length() > 0) |
|
202 { |
|
203 try |
|
204 { |
|
205 char *fileName = java::util::JavaCommonUtils::wstringToUtf8( |
|
206 persistentFileName); |
|
207 persistentRecFd = open(fileName, O_RDONLY); |
|
208 delete fileName; |
|
209 } |
|
210 catch (ExceptionBase ex) |
|
211 { |
|
212 ELOG1( |
|
213 EJavaBluetooth, |
|
214 "- ServiceRecord::restorePersistentRecordFs exception Caught: %S", |
|
215 ex.toString().c_str()); |
|
216 } |
|
217 } |
|
218 |
|
219 if (persistentRecFd < 0) |
|
220 return errno; |
|
221 |
|
222 // Reading and restoring the DeviceServiceClasses bits |
|
223 int devServClass = 0; |
|
224 ret = read(persistentRecFd, &devServClass, sizeof(devServClass)); |
|
225 |
|
226 if (ret <= 0) |
|
227 return errno; |
|
228 |
|
229 if (devServClass != 0) |
|
230 { |
|
231 LOG1(EJavaBluetooth, EInfo, |
|
232 " ServiceRecord::restorePersistentRecordFs Setting COD:0x%X", |
|
233 devServClass); |
|
234 ret = ServiceClassHandler::setDeviceServiceClass(devServClass, true); |
|
235 LOG1(EJavaBluetooth, EInfo, |
|
236 " ServiceRecord::restorePersistentRecordFs Set COD Return:%d", |
|
237 ret); |
|
238 } |
|
239 |
|
240 // Restoring all other service record data |
|
241 int attrId = 0; |
|
242 while ((ret = read(persistentRecFd, &attrId, sizeof(attrId))) > 0) |
|
243 { |
|
244 int dataType = 0; |
|
245 |
|
246 ret = read(persistentRecFd, &dataType, sizeof(dataType)); |
|
247 if (ret <= 0) |
|
248 break; |
|
249 |
|
250 LOG2(EJavaBluetooth, EInfo, " ServiceRecord reading %X, %X", attrId, |
|
251 dataType); |
|
252 |
|
253 switch (dataType) |
|
254 { |
|
255 case DataElement_DATSEQ: |
|
256 case DataElement_DATALT: |
|
257 { |
|
258 err = attributeListStartFs(attrId, dataType, EFalse); |
|
259 break; |
|
260 } |
|
261 case DataElement_EndList: |
|
262 { |
|
263 err = attributeListEndFs(attrId, EFalse); |
|
264 break; |
|
265 } |
|
266 case DataElement_NULL: |
|
267 { |
|
268 err = setAttributeNilFs(attrId, EFalse); |
|
269 break; |
|
270 } |
|
271 case DataElement_BOOL: |
|
272 { |
|
273 TUint8 val = 0; |
|
274 ret = read(persistentRecFd, &val, sizeof(val)); |
|
275 if (ret <= 0) |
|
276 break; |
|
277 |
|
278 LOG1(EJavaBluetooth, EInfo, " ServiceRecord reading Bool %X", val); |
|
279 err = setAttributeBoolFs(attrId, (val) ? ETrue : EFalse, EFalse); |
|
280 break; |
|
281 } |
|
282 case DataElement_INT_1: |
|
283 case DataElement_INT_2: |
|
284 case DataElement_INT_4: |
|
285 { |
|
286 int len = 0; |
|
287 ret = read(persistentRecFd, &len, sizeof(len)); |
|
288 if (ret <= 0) |
|
289 break; |
|
290 |
|
291 TUint8 buf[20] = { 0 }; |
|
292 ret = read(persistentRecFd, buf, len); |
|
293 if (ret <= 0) |
|
294 break; |
|
295 std::auto_ptr<HBufC8> val(convertIntToDesC(buf, dataType)); |
|
296 err = setAttributeIntFs(attrId, dataType, *val, EFalse); |
|
297 break; |
|
298 } |
|
299 case DataElement_INT_8: |
|
300 case DataElement_INT_16: |
|
301 { |
|
302 int len = 0; |
|
303 ret = read(persistentRecFd, &len, sizeof(len)); |
|
304 if (ret <= 0) |
|
305 break; |
|
306 |
|
307 TUint8 buf[20] = { 0 }; |
|
308 ret = read(persistentRecFd, buf, len); |
|
309 if (ret <= 0) |
|
310 break; |
|
311 TPtrC8 val(buf, len); |
|
312 err = setAttributeIntFs(attrId, dataType, val, EFalse); |
|
313 break; |
|
314 } |
|
315 case DataElement_U_INT_1: |
|
316 case DataElement_U_INT_2: |
|
317 case DataElement_U_INT_4: |
|
318 { |
|
319 int len = 0; |
|
320 ret = read(persistentRecFd, &len, sizeof(len)); |
|
321 if (ret <= 0) |
|
322 break; |
|
323 |
|
324 TUint8 buf[20] = { 0 }; |
|
325 ret = read(persistentRecFd, buf, len); |
|
326 if (ret <= 0) |
|
327 break; |
|
328 |
|
329 LOG2(EJavaBluetooth, EInfo, " ServiceRecord reading INT8 %X, %S", |
|
330 len, buf); |
|
331 |
|
332 std::auto_ptr<HBufC8> val(convertIntToDesC(buf, dataType)); |
|
333 err = setAttributeUintFs(attrId, dataType, *val, EFalse); |
|
334 break; |
|
335 } |
|
336 case DataElement_U_INT_8: |
|
337 case DataElement_U_INT_16: |
|
338 { |
|
339 int len = 0; |
|
340 ret = read(persistentRecFd, &len, sizeof(len)); |
|
341 if (ret <= 0) |
|
342 break; |
|
343 |
|
344 TUint8 buf[20] = { 0 }; |
|
345 ret = read(persistentRecFd, buf, len); |
|
346 if (ret <= 0) |
|
347 break; |
|
348 |
|
349 LOG2(EJavaBluetooth, EInfo, " ServiceRecord reading INT16 %X, %S", |
|
350 len, buf); |
|
351 |
|
352 TPtrC8 val(buf, len); |
|
353 err = setAttributeUintFs(attrId, dataType, val, EFalse); |
|
354 break; |
|
355 } |
|
356 case DataElement_UUID: |
|
357 { |
|
358 int len = 0; |
|
359 ret = read(persistentRecFd, &len, sizeof(len)); |
|
360 if (ret <= 0) |
|
361 break; |
|
362 |
|
363 TUint8 buf[256] = { 0 }; |
|
364 ret = read(persistentRecFd, buf, len); |
|
365 if (ret <= 0) |
|
366 break; |
|
367 |
|
368 LOG2(EJavaBluetooth, EInfo, " ServiceRecord reading UUID %X, %S", |
|
369 len, buf); |
|
370 |
|
371 TPtrC8 uuidDes(buf, len); |
|
372 |
|
373 TUUID val; |
|
374 TRAP(err, val.SetL(uuidDes)); |
|
375 |
|
376 if (KErrNone == err) |
|
377 { |
|
378 err = setAttributeUUIDFs(attrId, val, EFalse); |
|
379 } |
|
380 break; |
|
381 } |
|
382 case DataElement_STRING: |
|
383 { |
|
384 int len = 0; |
|
385 ret = read(persistentRecFd, &len, sizeof(len)); |
|
386 if (ret <= 0) |
|
387 break; |
|
388 |
|
389 TUint8 buf[1024] = {0}; |
|
390 ret = read(persistentRecFd, buf, len); |
|
391 if (ret <= 0) |
|
392 break; |
|
393 |
|
394 LOG1(EJavaBluetooth, EInfo, " ServiceRecord reading STRING %X", |
|
395 len); |
|
396 |
|
397 TPtrC8 val(buf, len); |
|
398 err = setAttributeStringFs(attrId, val, EFalse); |
|
399 break; |
|
400 } |
|
401 case DataElement_URL: |
|
402 { |
|
403 int len = 0; |
|
404 ret = read(persistentRecFd, &len, sizeof(len)); |
|
405 if (ret <= 0) |
|
406 break; |
|
407 |
|
408 TUint8 buf[1024] = {0}; |
|
409 ret = read(persistentRecFd, buf, len); |
|
410 if (ret <= 0) |
|
411 break; |
|
412 |
|
413 LOG2(EJavaBluetooth, EInfo, " ServiceRecord reading URL %X, %S", |
|
414 len, buf); |
|
415 |
|
416 TPtrC8 val(buf, len); |
|
417 err = setAttributeUrlFs(attrId, val, EFalse); |
|
418 break; |
|
419 } |
|
420 default: |
|
421 break; |
|
422 } |
|
423 |
|
424 // Treated as EOF reached. |
|
425 if (ret <= 0) |
|
426 break; |
|
427 } |
|
428 |
|
429 // Indicates a successful retrieval |
|
430 // of the service record from the persistent file |
|
431 mRestoredFromPersistentFile = true; |
|
432 |
|
433 return ret; |
|
434 } |
|
435 |
|
436 /** |
|
437 * Creates and initializes the Service record. |
|
438 * aProtocol: One among the PROTOCOL_L2CAP, PROTOCOL_RFCOMM, PROTOCOL_GOEP |
|
439 * aPSMValue: In case of L2CAP it should be PSM Value; |
|
440 * In case of RFComm it should be channel number. |
|
441 * aServiceUUID: UUID of the current service |
|
442 * aServiceName: Name of the current service. |
|
443 */ |
|
444 OS_EXPORT void ServiceRecord::initializeRecordL(TInt aProtocol, TInt aPsmValue, |
|
445 TUUID &aServiceUUID, TDesC8 &aServiceName) |
|
446 { |
|
447 JELOG2(EJavaBluetooth); |
|
448 CallMethodL(this, &ServiceRecord::initializeRecordFsL, aProtocol, |
|
449 aPsmValue, aServiceUUID, aServiceName, mFunctionServer); |
|
450 } |
|
451 |
|
452 /** |
|
453 * Returns the service record handle. |
|
454 */ |
|
455 OS_EXPORT int ServiceRecord::getServiceRecordID() |
|
456 { |
|
457 return mRecord; |
|
458 } |
|
459 |
|
460 void ServiceRecord::initializeRecordFsL(TInt aProtocol, TInt aPsmValue, |
|
461 TUUID &aServiceUUID, TDesC8 &aServiceName) |
|
462 { |
|
463 JELOG2(EJavaBluetooth); |
|
464 // Open sdp session |
|
465 User::LeaveIfError(mSdp.Connect()); |
|
466 // Open sdp database session |
|
467 User::LeaveIfError(mSdpDB.Open(mSdp)); |
|
468 |
|
469 LOG1( |
|
470 EJavaBluetooth, |
|
471 EInfo, |
|
472 " ServiceRecord::initializeRecordFsL: After registering to SDPDB: %S", |
|
473 aServiceUUID.Des().Ptr()); |
|
474 |
|
475 // Creating proper ServiceClassID list |
|
476 CSdpAttrValueDES *serviceClassIds = CSdpAttrValueDES::NewDESL(NULL); |
|
477 serviceClassIds->BuildUUIDL(aServiceUUID); |
|
478 if (PROTOCOL_RFCOMM == aProtocol) |
|
479 { |
|
480 LOG(EJavaBluetooth, EInfo, |
|
481 " ServiceRecord::initializeRecordFsL: Adding KSerialPortUUID"); |
|
482 |
|
483 serviceClassIds->BuildUUIDL(TUUID(KSerialPortUUID)); |
|
484 } |
|
485 |
|
486 // Create a record of the correct service class |
|
487 mSdpDB.CreateServiceRecordL(*serviceClassIds, mRecord); |
|
488 |
|
489 // Add a protocol to the record |
|
490 mSdpAttrValueList = CSdpAttrValueDES::NewDESL(NULL); |
|
491 mLastSdpAttr = mSdpAttrValueList; |
|
492 CleanupStack::PushL(mSdpAttrValueList); |
|
493 |
|
494 // Getting port number |
|
495 TSdpIntBuf<TUint> portBuf(aPsmValue); |
|
496 LOG1(EJavaBluetooth, EInfo, |
|
497 " ServiceRecord::initializeRecordFsL: port value : %d", aPsmValue); |
|
498 |
|
499 LOG(EJavaBluetooth, EInfo, |
|
500 " ServiceRecord::initializeRecordFsL: Creating protocol list"); |
|
501 |
|
502 // Create protocol list for our service |
|
503 |
|
504 switch (aProtocol) |
|
505 { |
|
506 case PROTOCOL_L2CAP: |
|
507 LOG(EJavaBluetooth, EInfo, |
|
508 " ServiceRecord::initializeRecordFsL: PROTOCOL_L2CAP"); |
|
509 mLastSdpAttr = mLastSdpAttr -> StartListL(); |
|
510 mLastSdpAttr = mLastSdpAttr -> BuildDESL(); |
|
511 mLastSdpAttr = mLastSdpAttr -> StartListL(); |
|
512 mLastSdpAttr = mLastSdpAttr -> BuildUUIDL(KL2CAP); |
|
513 mLastSdpAttr = mLastSdpAttr -> BuildUintL(portBuf); |
|
514 mLastSdpAttr = mLastSdpAttr -> EndListL(); |
|
515 mLastSdpAttr = mLastSdpAttr -> EndListL(); |
|
516 break; |
|
517 case PROTOCOL_RFCOMM: |
|
518 LOG(EJavaBluetooth, EInfo, |
|
519 " ServiceRecord::initializeRecordFsL: PROTOCOL_RFCOMM"); |
|
520 mLastSdpAttr = mLastSdpAttr -> StartListL(); |
|
521 mLastSdpAttr = mLastSdpAttr -> BuildDESL(); |
|
522 mLastSdpAttr = mLastSdpAttr -> StartListL(); |
|
523 mLastSdpAttr = mLastSdpAttr -> BuildUUIDL(KL2CAP); |
|
524 mLastSdpAttr = mLastSdpAttr -> EndListL(); |
|
525 mLastSdpAttr = mLastSdpAttr -> BuildDESL(); |
|
526 mLastSdpAttr = mLastSdpAttr -> StartListL(); |
|
527 mLastSdpAttr = mLastSdpAttr -> BuildUUIDL(KRFCOMM); |
|
528 mLastSdpAttr = mLastSdpAttr -> BuildUintL(portBuf); |
|
529 mLastSdpAttr = mLastSdpAttr -> EndListL(); |
|
530 mLastSdpAttr = mLastSdpAttr -> EndListL(); |
|
531 break; |
|
532 case PROTOCOL_GOEP: |
|
533 LOG(EJavaBluetooth, EInfo, |
|
534 " ServiceRecord::initializeRecordFsL: PROTOCOL_GOEP"); |
|
535 mLastSdpAttr = mLastSdpAttr -> StartListL(); |
|
536 mLastSdpAttr = mLastSdpAttr -> BuildDESL(); |
|
537 mLastSdpAttr = mLastSdpAttr -> StartListL(); |
|
538 mLastSdpAttr = mLastSdpAttr -> BuildUUIDL(KL2CAP); |
|
539 mLastSdpAttr = mLastSdpAttr -> EndListL(); |
|
540 mLastSdpAttr = mLastSdpAttr -> BuildDESL(); |
|
541 mLastSdpAttr = mLastSdpAttr -> StartListL(); |
|
542 mLastSdpAttr = mLastSdpAttr -> BuildUUIDL(KRFCOMM); |
|
543 mLastSdpAttr = mLastSdpAttr -> BuildUintL(portBuf); |
|
544 mLastSdpAttr = mLastSdpAttr -> EndListL(); |
|
545 mLastSdpAttr = mLastSdpAttr -> BuildDESL(); |
|
546 mLastSdpAttr = mLastSdpAttr -> StartListL(); |
|
547 mLastSdpAttr = mLastSdpAttr -> BuildUUIDL(KGOEP); |
|
548 mLastSdpAttr = mLastSdpAttr -> EndListL(); |
|
549 mLastSdpAttr = mLastSdpAttr -> EndListL(); |
|
550 break; |
|
551 } |
|
552 |
|
553 LOG(EJavaBluetooth, EInfo, |
|
554 " ServiceRecord::initializeRecordFsL: Set protocol list to the record"); |
|
555 // Set protocol list to the record |
|
556 mSdpDB.UpdateAttributeL(mRecord, KSdpAttrIdProtocolDescriptorList, |
|
557 *mSdpAttrValueList); |
|
558 CleanupStack::PopAndDestroy(mSdpAttrValueList); |
|
559 |
|
560 mSdpAttrValueList = NULL; |
|
561 mLastSdpAttr = NULL; |
|
562 |
|
563 LOG(EJavaBluetooth, EInfo, |
|
564 " ServiceRecord::initializeRecordFsL: Update attribute"); |
|
565 |
|
566 if (aServiceName.Size() > 0) |
|
567 { |
|
568 // Add a name to the record |
|
569 mSdpDB.UpdateAttributeL(mRecord, KSdpAttrIdBasePrimaryLanguage |
|
570 + KSdpAttrIdOffsetServiceName, aServiceName); |
|
571 LOG1(EJavaBluetooth, EInfo, |
|
572 " ServiceRecord::initializeRecordFsL: Update Name: %d", |
|
573 KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceName); |
|
574 } |
|
575 |
|
576 mOrigUuid = uuidToWstring(aServiceUUID); |
|
577 |
|
578 LOG1(EJavaBluetooth, EInfo, |
|
579 " ServiceRecord::initializeRecordFsL mOrigUuid = %S", |
|
580 mOrigUuid.c_str()); |
|
581 |
|
582 mProtocol = aProtocol; |
|
583 } |
|
584 |
|
585 /** |
|
586 * Opens the persistent file. Called when Update Record triggered. |
|
587 * And stores the DeviceServiceClasses bits (32 bit) in the persistent file |
|
588 * While retrieving the service record back from the file, it is must to read first |
|
589 * one integer which depicts this DeviceServiceClasses. If the service classes is not |
|
590 * set for the corresponding service, then the value 0(32 bits) is stored in place of the |
|
591 * DeviceServiceClasses bits. |
|
592 * |
|
593 */ |
|
594 OS_EXPORT void ServiceRecord::initializeUpdateRecord(int aDeviceServiceClasses) |
|
595 { |
|
596 JELOG2(EJavaBluetooth); |
|
597 std::wstring persistentFileName; |
|
598 |
|
599 persistentFileName = getPersistentFileName(); |
|
600 |
|
601 if (persistentFileName.length() > 0) |
|
602 { |
|
603 try |
|
604 { |
|
605 char *fileName = java::util::JavaCommonUtils::wstringToUtf8( |
|
606 persistentFileName); |
|
607 mSrvRecFd = open(fileName, O_CREAT | O_WRONLY | O_TRUNC, 0666); |
|
608 |
|
609 if (mSrvRecFd < 0) |
|
610 { |
|
611 ELOG1( |
|
612 EJavaBluetooth, |
|
613 "- ServiceRecord::initializeUpdateRecord Err while file open. %d", |
|
614 errno); |
|
615 return; |
|
616 } |
|
617 // Storing the Current DeviceClass (32 bits) |
|
618 write(mSrvRecFd, (char *) &aDeviceServiceClasses, |
|
619 sizeof(aDeviceServiceClasses)); |
|
620 |
|
621 delete fileName; |
|
622 } |
|
623 catch (ExceptionBase ex) |
|
624 { |
|
625 ELOG1( |
|
626 EJavaBluetooth, |
|
627 "- ServiceRecord::initializeUpdateRecord exception Caught: %S", |
|
628 ex.toString().c_str()); |
|
629 } |
|
630 } |
|
631 } |
|
632 |
|
633 /** |
|
634 * Closes the persistent file. |
|
635 */ |
|
636 OS_EXPORT void ServiceRecord::completesUpdateRecord() |
|
637 { |
|
638 JELOG2(EJavaBluetooth); |
|
639 if (0 != mSrvRecFd) |
|
640 { |
|
641 close(mSrvRecFd); |
|
642 mSrvRecFd = 0; |
|
643 } |
|
644 } |
|
645 |
|
646 /** |
|
647 * Gets the persistent file name. This function returns the file name pattern |
|
648 * srv_rec_<uuid>_<protocol>.txt And also, the srv_rec_XXX.txt |
|
649 * file name will be prepended with midlet's private directory for |
|
650 * bluetooth. That is, the final outcome of this function may be something |
|
651 * like, <midlet_private_dir>/bt/srv_rec_XXX.txt |
|
652 * |
|
653 * @param aUuid |
|
654 * uuid string |
|
655 * @param aProtocol |
|
656 * protocol name |
|
657 * @return Null when connection not registered for push; |
|
658 * otherwise srv_rec_XXX file name |
|
659 */ |
|
660 std::wstring ServiceRecord::getPersistentFileName() |
|
661 { |
|
662 JELOG2(EJavaBluetooth); |
|
663 std::wstring noFileName; |
|
664 std::wstring srvRecFile; |
|
665 |
|
666 LOG1(EJavaBluetooth, EInfo, "+ ServiceRecord:getPersistentFileName %d", |
|
667 mProtocol); |
|
668 |
|
669 const java::runtime::ApplicationInfo& appInf = |
|
670 java::runtime::ApplicationInfo::getInstance(); |
|
671 const std::wstring btFilesPath = appInf.getRootPath() + L"bt\\"; |
|
672 |
|
673 if (false == FileUtilities::exists(btFilesPath)) |
|
674 { |
|
675 try |
|
676 { |
|
677 LOG1(EJavaBluetooth, EInfo, |
|
678 " ServiceRecord:getPersistentFileName mkdir:%S", |
|
679 btFilesPath.c_str()); |
|
680 |
|
681 char *dirName = JavaCommonUtils::wstringToUtf8(btFilesPath); |
|
682 if (mkdir(dirName, BT_DIR_PERM) < 0) |
|
683 { |
|
684 ELOG1(EJavaBluetooth, |
|
685 "- ServiceRecord:getPersistentFileName Err, mkdir:%d",errno); |
|
686 delete[] dirName; |
|
687 return noFileName; |
|
688 } |
|
689 delete[] dirName; |
|
690 } |
|
691 catch (ExceptionBase ex) |
|
692 { |
|
693 ELOG1(EJavaBluetooth, |
|
694 "- ServiceRecord::getPersistentFileName exception Caught: %S", |
|
695 ex.toString().c_str()); |
|
696 return noFileName; |
|
697 } |
|
698 } |
|
699 |
|
700 srvRecFile = btFilesPath + L"srv_rec_"; |
|
701 |
|
702 switch (mProtocol) |
|
703 { |
|
704 case PROTOCOL_L2CAP: |
|
705 srvRecFile += mOrigUuid + L"_btl2cap.txt"; |
|
706 break; |
|
707 case PROTOCOL_RFCOMM: |
|
708 srvRecFile += mOrigUuid + L"_btspp.txt"; |
|
709 break; |
|
710 case PROTOCOL_GOEP: |
|
711 srvRecFile += mOrigUuid + L"_btgoep.txt"; |
|
712 break; |
|
713 } |
|
714 |
|
715 LOG1(EJavaBluetooth, EInfo, |
|
716 "- ServiceRecord:getPersistentFileName %S", srvRecFile.c_str()); |
|
717 return srvRecFile; |
|
718 } |
|
719 |
|
720 /** |
|
721 * Exporting this function only for the use of ServerConnection::AcceptL |
|
722 * and ServerConnection::HandleAcceptL methods. In rest of the cases, |
|
723 * this method should be called via setAdvertise() |
|
724 */ |
|
725 OS_EXPORT int ServiceRecord::setAdvertiseFs(TBool aAvailable) |
|
726 { |
|
727 LOG1(EJavaBluetooth, EInfo, "+ ServiceRecord::setAdvertise %s", |
|
728 (aAvailable)?"True":"False"); |
|
729 int err = 0; |
|
730 |
|
731 TInt state = aAvailable ? SERVICE_AVAILABLE : !SERVICE_AVAILABLE; |
|
732 |
|
733 // Set availability |
|
734 TRAP(err, |
|
735 { |
|
736 mSdpDB.UpdateAttributeL(mRecord, |
|
737 KSdpAttrIdServiceAvailability, state); |
|
738 |
|
739 mSdpDB.UpdateAttributeL(mRecord, |
|
740 KSdpAttrIdServiceRecordState, ++mRecordState); |
|
741 } |
|
742 ); |
|
743 return err; |
|
744 } |
|
745 |
|
746 /** |
|
747 * Creates and starts the new list (DEA/DES) |
|
748 * On success returns 0; otherwise err number. |
|
749 */ |
|
750 OS_EXPORT int ServiceRecord::attributeListStart(int aAttrId, int aAttrType) |
|
751 { |
|
752 JELOG2(EJavaBluetooth); |
|
753 int ret = 0; |
|
754 TBool persistentReq = ETrue; |
|
755 |
|
756 CallMethod(ret, this, &ServiceRecord::attributeListStartFs, |
|
757 aAttrId, aAttrType, persistentReq, mFunctionServer); |
|
758 return ret; |
|
759 } |
|
760 |
|
761 int ServiceRecord::attributeListStartFs(int aAttrId, int aAttrType, TBool isPersistenceRequired) |
|
762 { |
|
763 JELOG2(EJavaBluetooth); |
|
764 LOG1(EJavaBluetooth, EInfo, "+ ServiceRecord::attributeListStart %d", aAttrId); |
|
765 |
|
766 TRAPD(err, |
|
767 { |
|
768 if (aAttrId >= 0) |
|
769 { |
|
770 switch (aAttrType) |
|
771 { |
|
772 case DataElement_DATSEQ: |
|
773 mSdpAttrValueList = CSdpAttrValueDES::NewDESL(NULL); |
|
774 break; |
|
775 case DataElement_DATALT: |
|
776 mSdpAttrValueList = CSdpAttrValueDEA::NewDEAL(NULL); |
|
777 break; |
|
778 default: |
|
779 break; |
|
780 } |
|
781 mLastSdpAttr = mSdpAttrValueList; |
|
782 } |
|
783 else |
|
784 { |
|
785 switch (aAttrType) |
|
786 { |
|
787 case DataElement_DATSEQ: |
|
788 if (mLastSdpAttr) |
|
789 mLastSdpAttr = mLastSdpAttr -> BuildDESL(); |
|
790 break; |
|
791 case DataElement_DATALT: |
|
792 if (mLastSdpAttr) |
|
793 mLastSdpAttr = mLastSdpAttr -> BuildDESL(); |
|
794 break; |
|
795 default: |
|
796 break; |
|
797 } |
|
798 } |
|
799 mLastSdpAttr = mLastSdpAttr -> StartListL(); |
|
800 } |
|
801 ); |
|
802 |
|
803 // Writing into persistent file for further usage |
|
804 if (0 != mSrvRecFd && isPersistenceRequired) |
|
805 { |
|
806 LOG2(EJavaBluetooth, EInfo, " ServiceRecord Writing %d, %d", |
|
807 aAttrId, aAttrType); |
|
808 write(mSrvRecFd, (char *)&aAttrId, sizeof(aAttrId)); |
|
809 write(mSrvRecFd, (char *)&aAttrType, sizeof(aAttrType)); |
|
810 } |
|
811 return err; |
|
812 } |
|
813 |
|
814 /** |
|
815 * Ends the list (DEA/DES), and update the attribute list of SDP database |
|
816 * On success returns 0; otherwise err number. |
|
817 */ |
|
818 OS_EXPORT int ServiceRecord::attributeListEnd(int aAttrId) |
|
819 { |
|
820 JELOG2(EJavaBluetooth); |
|
821 int ret = 0; |
|
822 TBool persistentReq = ETrue; |
|
823 |
|
824 CallMethod(ret, this, &ServiceRecord::attributeListEndFs, |
|
825 aAttrId, persistentReq, mFunctionServer); |
|
826 return ret; |
|
827 } |
|
828 |
|
829 int ServiceRecord::attributeListEndFs(int aAttrId, TBool isPersistenceRequired) |
|
830 { |
|
831 JELOG2(EJavaBluetooth); |
|
832 LOG1(EJavaBluetooth, EInfo, "+ ServiceRecord::attributeListEnd %d", aAttrId); |
|
833 int err = 0; |
|
834 |
|
835 if (mLastSdpAttr) |
|
836 TRAP(err, mLastSdpAttr = mLastSdpAttr -> EndListL()); |
|
837 if (KErrNone == err && aAttrId >= 0) |
|
838 { |
|
839 LOG1(EJavaBluetooth, EInfo, "* ServiceRecord::attributeListEnd %d", aAttrId); |
|
840 TRAP(err, mSdpDB.UpdateAttributeL(mRecord, aAttrId, *mSdpAttrValueList)); |
|
841 LOG1(EJavaBluetooth, EInfo, "x ServiceRecord::attributeListEnd %d", aAttrId); |
|
842 delete mSdpAttrValueList; |
|
843 mSdpAttrValueList = NULL; |
|
844 mLastSdpAttr = NULL; |
|
845 } |
|
846 |
|
847 // Writing into persistent file for further usage |
|
848 if (0 != mSrvRecFd && isPersistenceRequired) |
|
849 { |
|
850 int type = DataElement_EndList; |
|
851 LOG2(EJavaBluetooth, EInfo, " ServiceRecord Writing %d, %d", |
|
852 aAttrId, type); |
|
853 write(mSrvRecFd, (char *)&aAttrId, sizeof(aAttrId)); |
|
854 write(mSrvRecFd, (char *)&type, sizeof(type)); |
|
855 } |
|
856 return err; |
|
857 } |
|
858 |
|
859 /** |
|
860 * Adds unsigned integer to the list (DEA/DES), |
|
861 * or update the attribute list of SDP database |
|
862 * On success returns 0; otherwise err number. |
|
863 */ |
|
864 OS_EXPORT int ServiceRecord::setAttributeUint(int aAttrId, int aAttrType, TDesC8 &aNumVal) |
|
865 { |
|
866 JELOG2(EJavaBluetooth); |
|
867 int ret = 0; |
|
868 TBool persistentReq = ETrue; |
|
869 |
|
870 CallMethod(ret, this, &ServiceRecord::setAttributeUintFs, |
|
871 aAttrId, aAttrType, aNumVal, persistentReq, mFunctionServer); |
|
872 return ret; |
|
873 } |
|
874 |
|
875 int ServiceRecord::setAttributeUintFs(int aAttrId, int aAttrType, TDesC8 &aNumVal, TBool isPersistenceRequired) |
|
876 { |
|
877 JELOG2(EJavaBluetooth); |
|
878 LOG1(EJavaBluetooth, EInfo, "+ ServiceRecord::setAttributeUint %d", aAttrId); |
|
879 |
|
880 TRAPD(err, |
|
881 { |
|
882 if (aAttrId < 0) |
|
883 { |
|
884 if (mLastSdpAttr) |
|
885 mLastSdpAttr = mLastSdpAttr -> BuildUintL(aNumVal); |
|
886 } |
|
887 else |
|
888 { |
|
889 CSdpAttrValueUint *val = NULL; |
|
890 val = CSdpAttrValueUint::NewUintL(aNumVal); |
|
891 mSdpDB.UpdateAttributeL(mRecord, aAttrId, *val); |
|
892 delete val; |
|
893 } |
|
894 } |
|
895 ); |
|
896 |
|
897 // Writing into persistent file for further usage |
|
898 if (0 != mSrvRecFd && isPersistenceRequired) |
|
899 { |
|
900 int size = aNumVal.Size(); |
|
901 const TUint8 *ptr = aNumVal.Ptr(); |
|
902 |
|
903 LOG4(EJavaBluetooth, EInfo," ServiceRecord Writing %d, %d, %d, [%S]", |
|
904 aAttrId, aAttrType, size, ptr); |
|
905 |
|
906 write(mSrvRecFd, (char *)&aAttrId, sizeof(aAttrId)); |
|
907 write(mSrvRecFd, (char *)&aAttrType, sizeof(aAttrType)); |
|
908 write(mSrvRecFd, (char *)&size, sizeof(size)); |
|
909 write(mSrvRecFd, (char *)ptr, size); |
|
910 } |
|
911 return err; |
|
912 } |
|
913 |
|
914 /** |
|
915 * Adds integer to the list (DEA/DES), |
|
916 * or update the attribute list of SDP database |
|
917 * On success returns 0; otherwise err number. |
|
918 */ |
|
919 OS_EXPORT int ServiceRecord::setAttributeInt(int aAttrId, int aAttrType, TDesC8 &aNumVal) |
|
920 { |
|
921 JELOG2(EJavaBluetooth); |
|
922 int ret = 0; |
|
923 TBool persistentReq = ETrue; |
|
924 |
|
925 CallMethod(ret, this, &ServiceRecord::setAttributeIntFs, |
|
926 aAttrId, aAttrType, aNumVal, persistentReq, mFunctionServer); |
|
927 return ret; |
|
928 } |
|
929 |
|
930 int ServiceRecord::setAttributeIntFs(int aAttrId, int aAttrType, TDesC8 &aNumVal, TBool isPersistenceRequired) |
|
931 { |
|
932 JELOG2(EJavaBluetooth); |
|
933 LOG1(EJavaBluetooth, EInfo, "+ ServiceRecord::setAttributeInt %d", aAttrId); |
|
934 |
|
935 TRAPD(err, |
|
936 { |
|
937 if (aAttrId < 0) |
|
938 { |
|
939 if (mLastSdpAttr) |
|
940 mLastSdpAttr = mLastSdpAttr -> BuildIntL(aNumVal); |
|
941 } |
|
942 else |
|
943 { |
|
944 CSdpAttrValueInt *val = NULL; |
|
945 val = CSdpAttrValueInt::NewIntL(aNumVal); |
|
946 mSdpDB.UpdateAttributeL(mRecord, aAttrId, *val); |
|
947 delete val; |
|
948 } |
|
949 } |
|
950 ); |
|
951 |
|
952 // Writing into persistent file for further usage |
|
953 if (0 != mSrvRecFd && isPersistenceRequired) |
|
954 { |
|
955 int size = aNumVal.Size(); |
|
956 const TUint8 *ptr = aNumVal.Ptr(); |
|
957 |
|
958 LOG4(EJavaBluetooth, EInfo," ServiceRecord Writing %d, %d, %d, [%S]", |
|
959 aAttrId, aAttrType, size, ptr); |
|
960 |
|
961 write(mSrvRecFd, (char *)&aAttrId, sizeof(aAttrId)); |
|
962 write(mSrvRecFd, (char *)&aAttrType, sizeof(aAttrType)); |
|
963 write(mSrvRecFd, (char *)&size, sizeof(size)); |
|
964 write(mSrvRecFd, (char *)ptr, size); |
|
965 } |
|
966 return err; |
|
967 } |
|
968 |
|
969 /** |
|
970 * Adds boolean value to the list (DEA/DES), |
|
971 * or update the attribute list of SDP database |
|
972 * On success returns 0; otherwise err number. |
|
973 */ |
|
974 OS_EXPORT int ServiceRecord::setAttributeBool(int aAttrId, TBool aBoolVal) |
|
975 { |
|
976 JELOG2(EJavaBluetooth); |
|
977 int ret = 0; |
|
978 TBool persistentReq = ETrue; |
|
979 |
|
980 CallMethod(ret, this, &ServiceRecord::setAttributeBoolFs, |
|
981 aAttrId, aBoolVal, persistentReq, mFunctionServer); |
|
982 return ret; |
|
983 } |
|
984 |
|
985 int ServiceRecord::setAttributeBoolFs(int aAttrId, TBool aBoolVal, TBool isPersistenceRequired) |
|
986 { |
|
987 JELOG2(EJavaBluetooth); |
|
988 LOG1(EJavaBluetooth, EInfo, "+ ServiceRecord::setAttributeBool %d", aAttrId); |
|
989 |
|
990 TRAPD(err, |
|
991 { |
|
992 if (aAttrId < 0) |
|
993 { |
|
994 if (mLastSdpAttr) |
|
995 mLastSdpAttr = mLastSdpAttr -> BuildBooleanL(aBoolVal); |
|
996 } |
|
997 else |
|
998 { |
|
999 CSdpAttrValueBoolean *val = NULL; |
|
1000 val = CSdpAttrValueBoolean::NewBoolL(aBoolVal); |
|
1001 mSdpDB.UpdateAttributeL(mRecord, aAttrId, *val); |
|
1002 delete val; |
|
1003 } |
|
1004 } |
|
1005 ); |
|
1006 |
|
1007 // Writing into persistent file for further usage |
|
1008 if (0 != mSrvRecFd && isPersistenceRequired) |
|
1009 { |
|
1010 // Taking largest type for storage |
|
1011 int type = DataElement_BOOL; |
|
1012 TUint8 val = (aBoolVal) ? 1 : 0; |
|
1013 |
|
1014 LOG3(EJavaBluetooth, EInfo," ServiceRecord Writing %d, %d, %d", |
|
1015 aAttrId, type, val); |
|
1016 |
|
1017 write(mSrvRecFd, (char *)&aAttrId, sizeof(aAttrId)); |
|
1018 write(mSrvRecFd, (char *)&type, sizeof(type)); |
|
1019 write(mSrvRecFd, (char *)&val, 1); |
|
1020 } |
|
1021 return err; |
|
1022 } |
|
1023 |
|
1024 /** |
|
1025 * Adds UUID to the list (DEA/DES), |
|
1026 * or update the attribute list of SDP database |
|
1027 * On success returns 0; otherwise err number. |
|
1028 */ |
|
1029 OS_EXPORT int ServiceRecord::setAttributeUUID(int aAttrId, TUUID &aUUIDVal) |
|
1030 { |
|
1031 JELOG2(EJavaBluetooth); |
|
1032 int ret = 0; |
|
1033 TBool persistentReq = ETrue; |
|
1034 |
|
1035 CallMethod(ret, this, &ServiceRecord::setAttributeUUIDFs, |
|
1036 aAttrId, aUUIDVal, persistentReq, mFunctionServer); |
|
1037 return ret; |
|
1038 } |
|
1039 |
|
1040 int ServiceRecord::setAttributeUUIDFs(int aAttrId, TUUID &aUUIDVal, TBool isPersistenceRequired) |
|
1041 { |
|
1042 JELOG2(EJavaBluetooth); |
|
1043 LOG1(EJavaBluetooth, EInfo, "+ ServiceRecord::setAttributeUUID %d", aAttrId); |
|
1044 |
|
1045 TRAPD(err, |
|
1046 { |
|
1047 if (aAttrId < 0) |
|
1048 { |
|
1049 if (mLastSdpAttr) |
|
1050 mLastSdpAttr = mLastSdpAttr -> BuildUUIDL(aUUIDVal); |
|
1051 } |
|
1052 else |
|
1053 { |
|
1054 CSdpAttrValueUUID *val = NULL; |
|
1055 val = CSdpAttrValueUUID::NewUUIDL(aUUIDVal); |
|
1056 mSdpDB.UpdateAttributeL(mRecord, aAttrId, *val); |
|
1057 delete val; |
|
1058 } |
|
1059 } |
|
1060 ); |
|
1061 |
|
1062 // Writing into persistent file for further usage |
|
1063 if (0 != mSrvRecFd && isPersistenceRequired) |
|
1064 { |
|
1065 int type = DataElement_UUID; |
|
1066 int size = aUUIDVal.Des().Size(); |
|
1067 const TUint8 *ptr = aUUIDVal.Des().Ptr(); |
|
1068 |
|
1069 LOG4(EJavaBluetooth, EInfo," ServiceRecord Writing %d, %d, %d, [%S]", |
|
1070 aAttrId, type, size, ptr); |
|
1071 |
|
1072 write(mSrvRecFd, (char *)&aAttrId, sizeof(aAttrId)); |
|
1073 write(mSrvRecFd, (char *)&type, sizeof(type)); |
|
1074 write(mSrvRecFd, (char *)&size, sizeof(size)); |
|
1075 write(mSrvRecFd, (char *)ptr, size); |
|
1076 } |
|
1077 return err; |
|
1078 } |
|
1079 |
|
1080 /** |
|
1081 * Adds string to the list (DEA/DES), |
|
1082 * or update the attribute list of SDP database |
|
1083 * On success returns 0; otherwise err number. |
|
1084 */ |
|
1085 OS_EXPORT int ServiceRecord::setAttributeString(int aAttrId, TDesC8 &aStrVal) |
|
1086 { |
|
1087 JELOG2(EJavaBluetooth); |
|
1088 int ret = 0; |
|
1089 TBool persistentReq = ETrue; |
|
1090 |
|
1091 CallMethod(ret, this, &ServiceRecord::setAttributeStringFs, |
|
1092 aAttrId, aStrVal, persistentReq, mFunctionServer); |
|
1093 return ret; |
|
1094 } |
|
1095 |
|
1096 int ServiceRecord::setAttributeStringFs(int aAttrId, TDesC8 &aStrVal, TBool isPersistenceRequired) |
|
1097 { |
|
1098 JELOG2(EJavaBluetooth); |
|
1099 LOG1(EJavaBluetooth, EInfo, |
|
1100 "+ ServiceRecord::setAttributeString %d", aAttrId); |
|
1101 |
|
1102 TRAPD(err, |
|
1103 { |
|
1104 if (aAttrId < 0) |
|
1105 { |
|
1106 if (mLastSdpAttr) |
|
1107 mLastSdpAttr = mLastSdpAttr -> BuildStringL(aStrVal); |
|
1108 } |
|
1109 else |
|
1110 { |
|
1111 CSdpAttrValueString *val = NULL; |
|
1112 val = CSdpAttrValueString::NewStringL(aStrVal); |
|
1113 mSdpDB.UpdateAttributeL(mRecord, aAttrId, *val); |
|
1114 delete val; |
|
1115 } |
|
1116 } |
|
1117 ); |
|
1118 |
|
1119 // Writing into persistent file for further usage |
|
1120 if (0 != mSrvRecFd && isPersistenceRequired) |
|
1121 { |
|
1122 int type = DataElement_STRING; |
|
1123 int size = aStrVal.Size(); |
|
1124 const TUint8 *ptr = aStrVal.Ptr(); |
|
1125 |
|
1126 LOG3(EJavaBluetooth, EInfo," ServiceRecord Writing %d, %d, %d", |
|
1127 aAttrId, type, size); |
|
1128 |
|
1129 write(mSrvRecFd, (char *)&aAttrId, sizeof(aAttrId)); |
|
1130 write(mSrvRecFd, (char *)&type, sizeof(type)); |
|
1131 write(mSrvRecFd, (char *)&size, sizeof(size)); |
|
1132 write(mSrvRecFd, (char *)ptr, size); |
|
1133 } |
|
1134 return err; |
|
1135 } |
|
1136 |
|
1137 /** |
|
1138 * Adds URL to the list (DEA/DES), |
|
1139 * or update the attribute list of SDP database |
|
1140 * On success returns 0; otherwise err number. |
|
1141 */ |
|
1142 OS_EXPORT int ServiceRecord::setAttributeUrl(int aAttrId, TDesC8 &aUrlVal) |
|
1143 { |
|
1144 JELOG2(EJavaBluetooth); |
|
1145 int ret = 0; |
|
1146 TBool persistentReq = ETrue; |
|
1147 |
|
1148 CallMethod(ret, this, &ServiceRecord::setAttributeUrlFs, |
|
1149 aAttrId, aUrlVal, persistentReq, mFunctionServer); |
|
1150 return ret; |
|
1151 } |
|
1152 |
|
1153 int ServiceRecord::setAttributeUrlFs(int aAttrId, TDesC8 &aUrlVal, TBool isPersistenceRequired) |
|
1154 { |
|
1155 JELOG2(EJavaBluetooth); |
|
1156 LOG1(EJavaBluetooth, EInfo, "+ ServiceRecord::setAttributeUrl %d", aAttrId); |
|
1157 |
|
1158 TRAPD(err, |
|
1159 { |
|
1160 if (aAttrId < 0) |
|
1161 { |
|
1162 if (mLastSdpAttr) |
|
1163 mLastSdpAttr = mLastSdpAttr -> BuildURLL(aUrlVal); |
|
1164 } |
|
1165 else |
|
1166 { |
|
1167 CSdpAttrValueURL *val = NULL; |
|
1168 val = CSdpAttrValueURL::NewURLL(aUrlVal); |
|
1169 mSdpDB.UpdateAttributeL(mRecord, aAttrId, *val); |
|
1170 delete val; |
|
1171 } |
|
1172 } |
|
1173 ); |
|
1174 // Writing into persistent file for further usage |
|
1175 if (0 != mSrvRecFd && isPersistenceRequired) |
|
1176 { |
|
1177 int type = DataElement_URL; |
|
1178 int size = aUrlVal.Size(); |
|
1179 const TUint8 *ptr = aUrlVal.Ptr(); |
|
1180 |
|
1181 LOG4(EJavaBluetooth, EInfo," ServiceRecord Writing %d, %d, %d, [%S]", |
|
1182 aAttrId, type, size, ptr); |
|
1183 |
|
1184 write(mSrvRecFd, (char *)&aAttrId, sizeof(aAttrId)); |
|
1185 write(mSrvRecFd, (char *)&type, sizeof(type)); |
|
1186 write(mSrvRecFd, (char *)&size, sizeof(size)); |
|
1187 write(mSrvRecFd, (char *)ptr, size); |
|
1188 } |
|
1189 return err; |
|
1190 } |
|
1191 |
|
1192 /** |
|
1193 * Adds NIL to the list (DEA/DES), |
|
1194 * or update the attribute list of SDP database |
|
1195 * On success returns 0; otherwise err number. |
|
1196 */ |
|
1197 OS_EXPORT int ServiceRecord::setAttributeNil(int aAttrId) |
|
1198 { |
|
1199 JELOG2(EJavaBluetooth); |
|
1200 int ret = 0; |
|
1201 TBool persistentReq = ETrue; |
|
1202 |
|
1203 CallMethod(ret, this, &ServiceRecord::setAttributeNilFs, |
|
1204 aAttrId, persistentReq, mFunctionServer); |
|
1205 return ret; |
|
1206 } |
|
1207 |
|
1208 int ServiceRecord::setAttributeNilFs(int aAttrId, TBool isPersistenceRequired) |
|
1209 { |
|
1210 JELOG2(EJavaBluetooth); |
|
1211 LOG1(EJavaBluetooth, EInfo, "+ ServiceRecord::setAttributeNil %d", aAttrId); |
|
1212 |
|
1213 TRAPD(err, |
|
1214 { |
|
1215 if (aAttrId < 0) |
|
1216 { |
|
1217 if (mLastSdpAttr) |
|
1218 mLastSdpAttr = mLastSdpAttr -> BuildNilL(); |
|
1219 } |
|
1220 else |
|
1221 { |
|
1222 CSdpAttrValueNil *val = NULL; |
|
1223 val = CSdpAttrValueNil::NewNilL(); |
|
1224 mSdpDB.UpdateAttributeL(mRecord, aAttrId, *val); |
|
1225 delete val; |
|
1226 } |
|
1227 } |
|
1228 ); |
|
1229 |
|
1230 // Writing into persistent file for further usage |
|
1231 if (0 != mSrvRecFd && isPersistenceRequired) |
|
1232 { |
|
1233 // Taking largest type for storage |
|
1234 int type = DataElement_NULL; |
|
1235 |
|
1236 LOG2(EJavaBluetooth, EInfo, " ServiceRecord Writing %d, %d", |
|
1237 aAttrId, type); |
|
1238 |
|
1239 write(mSrvRecFd, (char *)&aAttrId, sizeof(aAttrId)); |
|
1240 write(mSrvRecFd, (char *)&type, sizeof(type)); |
|
1241 } |
|
1242 return err; |
|
1243 } |
|
1244 |
|
1245 /* |
|
1246 * This function is used to restore the Java Service Record by reading the |
|
1247 * persistent file. This function will work only once after midlet took |
|
1248 * the server connection handle from the Push framework. |
|
1249 * This function tries to populate Java Service record only when there is a |
|
1250 * successful retrieval of persistent storage exists. |
|
1251 */ |
|
1252 |
|
1253 OS_EXPORT void ServiceRecord::restoreJavaServiceRecordL( |
|
1254 JNIEnv *aJni, jobject aServiceRecordImpl) |
|
1255 { |
|
1256 JELOG2(EJavaBluetooth); |
|
1257 |
|
1258 if (false == mInitializedByPush) |
|
1259 { |
|
1260 // No need of restoring anything since it is not a push service |
|
1261 return; |
|
1262 } |
|
1263 |
|
1264 // Setting service record handle. |
|
1265 BTServiceRecordPopulator* srvRecPopulator = |
|
1266 BTServiceRecordPopulator::New(aJni, aServiceRecordImpl); |
|
1267 |
|
1268 srvRecPopulator->SetServiceRecordHandle(mRecord); |
|
1269 |
|
1270 if (false == mRestoredFromPersistentFile) |
|
1271 { |
|
1272 // No need of restoring anything from persistent file. |
|
1273 delete srvRecPopulator; |
|
1274 return; |
|
1275 } |
|
1276 |
|
1277 std::wstring persistentFileName = getPersistentFileName(); |
|
1278 |
|
1279 int persistentRecFd = -1; |
|
1280 int ret = 0; |
|
1281 |
|
1282 if (persistentFileName.length()> 0) |
|
1283 { |
|
1284 try |
|
1285 { |
|
1286 char *fileName = |
|
1287 java::util::JavaCommonUtils::wstringToUtf8(persistentFileName); |
|
1288 persistentRecFd = open(fileName, O_RDONLY); |
|
1289 delete fileName; |
|
1290 } |
|
1291 catch (ExceptionBase ex) |
|
1292 { |
|
1293 ELOG1(EJavaBluetooth, |
|
1294 "- ServiceRecord::restoreJavaServiceRecord exception caught: %S", |
|
1295 ex.toString().c_str()); |
|
1296 } |
|
1297 } |
|
1298 |
|
1299 if (persistentRecFd < 0) |
|
1300 { |
|
1301 // Nothing else to be done, as persistent file can not be opened or |
|
1302 // it is empty. |
|
1303 delete srvRecPopulator; |
|
1304 return; |
|
1305 } |
|
1306 |
|
1307 MSdpElementBuilder* elementBuilder = (MSdpElementBuilder*) srvRecPopulator; |
|
1308 |
|
1309 // Reading and restoring the DeviceServiceClasses bits (If any) |
|
1310 unsigned int devServClass = 0; |
|
1311 ret = read(persistentRecFd, &devServClass, sizeof(devServClass)); |
|
1312 if (ret <= 0) |
|
1313 return; |
|
1314 |
|
1315 elementBuilder = srvRecPopulator->SetDeviceServiceClass(devServClass); |
|
1316 |
|
1317 |
|
1318 // Calling first BuildDESL, is mandatory |
|
1319 elementBuilder = elementBuilder->BuildDESL(); |
|
1320 elementBuilder = elementBuilder->StartListL(); |
|
1321 |
|
1322 int attrId = 0; |
|
1323 while ((ret = read(persistentRecFd, &attrId, sizeof(attrId))) > 0) |
|
1324 { |
|
1325 int dataType = 0; |
|
1326 |
|
1327 ret = read(persistentRecFd, &dataType, sizeof(dataType)); |
|
1328 if (ret <= 0) |
|
1329 break; |
|
1330 |
|
1331 if (attrId > 0 && DataElement_EndList != dataType) |
|
1332 { |
|
1333 TSdpIntBuf<TUint> attrIdBuf(attrId); |
|
1334 elementBuilder = elementBuilder->BuildUintL(attrIdBuf); |
|
1335 } |
|
1336 |
|
1337 LOG2(EJavaBluetooth, EInfo, |
|
1338 " ServiceRecord reading %X, %X", attrId, dataType); |
|
1339 |
|
1340 switch (dataType) |
|
1341 { |
|
1342 case DataElement_DATSEQ: |
|
1343 { |
|
1344 elementBuilder = elementBuilder->BuildDESL(); |
|
1345 elementBuilder = elementBuilder->StartListL(); |
|
1346 break; |
|
1347 } |
|
1348 case DataElement_DATALT: |
|
1349 { |
|
1350 elementBuilder = elementBuilder->BuildDEAL(); |
|
1351 elementBuilder = elementBuilder->StartListL(); |
|
1352 break; |
|
1353 } |
|
1354 case DataElement_EndList: |
|
1355 { |
|
1356 elementBuilder = elementBuilder->EndListL(); |
|
1357 break; |
|
1358 } |
|
1359 case DataElement_NULL: |
|
1360 { |
|
1361 elementBuilder = elementBuilder->BuildNilL(); |
|
1362 break; |
|
1363 } |
|
1364 case DataElement_BOOL: |
|
1365 { |
|
1366 TUint8 val = 0; |
|
1367 ret = read(persistentRecFd, &val, sizeof(val)); |
|
1368 if (ret <= 0) |
|
1369 break; |
|
1370 |
|
1371 LOG1(EJavaBluetooth, EInfo, |
|
1372 " ServiceRecord reading Bool %X", val); |
|
1373 elementBuilder = |
|
1374 elementBuilder->BuildBooleanL((val) ? ETrue : EFalse); |
|
1375 break; |
|
1376 } |
|
1377 case DataElement_U_INT_1: |
|
1378 case DataElement_U_INT_2: |
|
1379 case DataElement_U_INT_4: |
|
1380 { |
|
1381 int len = 0; |
|
1382 ret = read(persistentRecFd, &len, sizeof(len)); |
|
1383 if (ret <= 0) |
|
1384 break; |
|
1385 |
|
1386 TUint8 bytes[20] = {0}; |
|
1387 ret = read(persistentRecFd, bytes, len); |
|
1388 if (ret <= 0) |
|
1389 break; |
|
1390 |
|
1391 LOG2(EJavaBluetooth, EInfo, " ServiceRecord reading INT 0x%X, 0x%X", len, bytes); |
|
1392 |
|
1393 std::auto_ptr<HBufC8> buf(convertIntToDesC(bytes, dataType)); |
|
1394 elementBuilder = elementBuilder->BuildUintL(*buf); |
|
1395 break; |
|
1396 } |
|
1397 case DataElement_U_INT_8: |
|
1398 case DataElement_U_INT_16: |
|
1399 { |
|
1400 int len = 0; |
|
1401 ret = read(persistentRecFd, &len, sizeof(len)); |
|
1402 if (ret <= 0) |
|
1403 break; |
|
1404 |
|
1405 TUint8 buf[20] = {0}; |
|
1406 ret = read(persistentRecFd, buf, len); |
|
1407 if (ret <= 0) |
|
1408 break; |
|
1409 |
|
1410 LOG2(EJavaBluetooth, EInfo, " ServiceRecord reading INT 0x%X, %S", len, buf); |
|
1411 |
|
1412 TPtrC8 val(buf, len); |
|
1413 elementBuilder = elementBuilder->BuildUintL(val); |
|
1414 break; |
|
1415 } |
|
1416 case DataElement_INT_1: |
|
1417 case DataElement_INT_2: |
|
1418 case DataElement_INT_4: |
|
1419 { |
|
1420 int len = 0; |
|
1421 ret = read(persistentRecFd, &len, sizeof(len)); |
|
1422 if (ret <= 0) |
|
1423 break; |
|
1424 |
|
1425 TUint8 bytes[20] = {0}; |
|
1426 ret = read(persistentRecFd, bytes, len); |
|
1427 if (ret <= 0) |
|
1428 break; |
|
1429 |
|
1430 LOG2(EJavaBluetooth, EInfo, " ServiceRecord reading INT 0x%X, %S", len, bytes); |
|
1431 |
|
1432 std::auto_ptr<HBufC8> buf(convertIntToDesC(bytes, dataType)); |
|
1433 elementBuilder = elementBuilder->BuildIntL(*buf); |
|
1434 break; |
|
1435 } |
|
1436 case DataElement_INT_8: |
|
1437 case DataElement_INT_16: |
|
1438 { |
|
1439 int len = 0; |
|
1440 ret = read(persistentRecFd, &len, sizeof(len)); |
|
1441 if (ret <= 0) |
|
1442 break; |
|
1443 |
|
1444 TUint8 buf[20] = {0}; |
|
1445 ret = read(persistentRecFd, buf, len); |
|
1446 if (ret <= 0) |
|
1447 break; |
|
1448 |
|
1449 LOG2(EJavaBluetooth, EInfo, " ServiceRecord reading INT %X, %S", len, buf); |
|
1450 |
|
1451 TPtrC8 val(buf, len); |
|
1452 elementBuilder = elementBuilder->BuildIntL(val); |
|
1453 break; |
|
1454 } |
|
1455 case DataElement_UUID: |
|
1456 { |
|
1457 int len = 0; |
|
1458 ret = read(persistentRecFd, &len, sizeof(len)); |
|
1459 if (ret <= 0) |
|
1460 break; |
|
1461 |
|
1462 TUint8 buf[256] = {0}; |
|
1463 ret = read(persistentRecFd, buf, len); |
|
1464 if (ret <= 0) |
|
1465 break; |
|
1466 |
|
1467 LOG2(EJavaBluetooth, EInfo, " ServiceRecord reading UUID %X, %S", len, buf); |
|
1468 |
|
1469 TPtrC8 uuidDes(buf, len); |
|
1470 |
|
1471 TUUID val; |
|
1472 val.SetL(uuidDes); |
|
1473 |
|
1474 elementBuilder = elementBuilder->BuildUUIDL(val); |
|
1475 break; |
|
1476 } |
|
1477 case DataElement_STRING: |
|
1478 { |
|
1479 int len = 0; |
|
1480 ret = read(persistentRecFd, &len, sizeof(len)); |
|
1481 if (ret <= 0) |
|
1482 break; |
|
1483 |
|
1484 TUint8 buf[1024] = {0}; |
|
1485 ret = read(persistentRecFd, buf, len); |
|
1486 if (ret <= 0) |
|
1487 break; |
|
1488 |
|
1489 LOG1(EJavaBluetooth, EInfo, |
|
1490 " ServiceRecord reading STRING %X", len); |
|
1491 |
|
1492 TPtrC8 val(buf, len); |
|
1493 LOG(EJavaBluetooth, EInfo, |
|
1494 " ServiceRecord::RestoreJavaServiceRecord BuildStringL"); |
|
1495 elementBuilder = elementBuilder->BuildStringL(val); |
|
1496 break; |
|
1497 } |
|
1498 case DataElement_URL: |
|
1499 { |
|
1500 int len = 0; |
|
1501 ret = read(persistentRecFd, &len, sizeof(len)); |
|
1502 if (ret <= 0) |
|
1503 break; |
|
1504 |
|
1505 TUint8 buf[1024] = {0}; |
|
1506 ret = read(persistentRecFd, buf, len); |
|
1507 if (ret <= 0) |
|
1508 break; |
|
1509 |
|
1510 LOG2(EJavaBluetooth, EInfo, |
|
1511 " ServiceRecord reading URL %X, %S", len, buf); |
|
1512 |
|
1513 TPtrC8 val(buf, len); |
|
1514 elementBuilder = elementBuilder->BuildURLL(val); |
|
1515 break; |
|
1516 } |
|
1517 default: |
|
1518 break; |
|
1519 } |
|
1520 if (0 == ret) |
|
1521 break; |
|
1522 } |
|
1523 |
|
1524 delete srvRecPopulator; |
|
1525 |
|
1526 return; |
|
1527 } |
|
1528 |
|
1529 // Helper function |
|
1530 HBufC8* ServiceRecord::convertIntToDesC(TUint8 *aBytes, int aDataType) |
|
1531 { |
|
1532 JELOG2(EJavaBluetooth); |
|
1533 HBufC8* descBytes = NULL; |
|
1534 switch (aDataType) |
|
1535 { |
|
1536 case DataElement_INT_1: |
|
1537 case DataElement_U_INT_1: |
|
1538 { |
|
1539 descBytes = HBufC8::New(sizeof(TUint8) + 1); |
|
1540 TPtr8 ptr = descBytes->Des(); |
|
1541 TUint value = *(TUint *)aBytes; |
|
1542 value=ByteOrder::Swap32(value); |
|
1543 |
|
1544 TSdpIntBuf<TUint8> buf(value); |
|
1545 ptr.Copy(buf); |
|
1546 break; |
|
1547 } |
|
1548 case DataElement_INT_2: |
|
1549 case DataElement_U_INT_2: |
|
1550 { |
|
1551 descBytes = HBufC8::New(sizeof(TUint16) + 1); |
|
1552 TPtr8 ptr = descBytes->Des(); |
|
1553 TUint value = *(TUint *)aBytes; |
|
1554 value=ByteOrder::Swap32(value); |
|
1555 |
|
1556 TSdpIntBuf<TUint16> buf(value); |
|
1557 ptr.Copy(buf); |
|
1558 break; |
|
1559 } |
|
1560 case DataElement_INT_4: |
|
1561 case DataElement_U_INT_4: |
|
1562 { |
|
1563 descBytes = HBufC8::New(sizeof(TUint32) + 1); |
|
1564 TPtr8 ptr = descBytes->Des(); |
|
1565 TUint value = *(TUint *)aBytes; |
|
1566 value=ByteOrder::Swap32(value); |
|
1567 |
|
1568 TSdpIntBuf<TUint32> buf(value); |
|
1569 ptr.Copy(buf); |
|
1570 break; |
|
1571 } |
|
1572 default: |
|
1573 { |
|
1574 descBytes = HBufC8::New(sizeof(TUint64) + 1); |
|
1575 TPtr8 ptr = descBytes->Des(); |
|
1576 |
|
1577 TSdpIntBuf<TUint64> buf(*(TUint64 *)aBytes); |
|
1578 ptr.Copy(buf); |
|
1579 break; |
|
1580 } |
|
1581 } |
|
1582 |
|
1583 return descBytes; |
|
1584 } |
|
1585 |
|
1586 TUint8 *ServiceRecord::uuidToByteArray(std::wstring aUuid, |
|
1587 int &aUuidByteLength) |
|
1588 { |
|
1589 JELOG2(EJavaBluetooth); |
|
1590 |
|
1591 int len = aUuid.length(); |
|
1592 int resultLen = (len/2) + 1; |
|
1593 TUint8 *result = new TUint8[resultLen]; |
|
1594 int index = 0; |
|
1595 int byteIndex = 0; |
|
1596 |
|
1597 LOG1(EJavaBluetooth, EInfo, " ServiceRecord::uuidToByteArray Length:%d", len); |
|
1598 |
|
1599 if ((len % 2) != 0) |
|
1600 { |
|
1601 int charPos = charToInt(aUuid[index]); |
|
1602 index += 1; |
|
1603 result[byteIndex ++] = charPos; |
|
1604 } |
|
1605 |
|
1606 while (index < len) |
|
1607 { |
|
1608 result[byteIndex ++] = (charToInt(aUuid[index]) << 4) | |
|
1609 charToInt(aUuid[index + 1]); |
|
1610 index += 2; |
|
1611 } |
|
1612 aUuidByteLength = (len /2) + (len %2); |
|
1613 |
|
1614 return result; |
|
1615 } |
|
1616 |
|
1617 TInt8 ServiceRecord::charToInt(wchar_t ch) |
|
1618 { |
|
1619 std::wstring validUpperChars(L"0123456789ABCDEF"); // Never change this. |
|
1620 std::wstring validLowerChars(L"0123456789abcdef"); // Never change this. |
|
1621 TInt8 result = -1; |
|
1622 if ((result = validUpperChars.find(ch)) == std::wstring::npos) |
|
1623 { |
|
1624 result = validLowerChars.find(ch); |
|
1625 } |
|
1626 return result; |
|
1627 } |
|
1628 |
|
1629 std::wstring ServiceRecord::uuidToWstring(TUUID aUuid) |
|
1630 { |
|
1631 JELOG2(EJavaBluetooth); |
|
1632 |
|
1633 std::wstring validChars(L"0123456789ABCDEF"); // Never change this. |
|
1634 std::wstring result; |
|
1635 |
|
1636 int len = aUuid.Des().Size(); |
|
1637 const TUint8 *ptr = aUuid.Des().Ptr(); |
|
1638 |
|
1639 for (int i = 0; i < len; i ++, ptr ++) |
|
1640 { |
|
1641 result += validChars[((*ptr) >> 4)]; |
|
1642 result += validChars[((*ptr) & 0x0F)]; |
|
1643 LOG1(EJavaBluetooth, EInfo, |
|
1644 " ServiceRecord::uuidToWstring %S", result.c_str()); |
|
1645 } |
|
1646 |
|
1647 return result; |
|
1648 } |
|
1649 |
|
1650 } //end namespace bluetooth |
|
1651 } //end namespace java |