RDK Documentation (Open Sourced RDK Components)
btrCore_le.c
1 /*
2  * If not stated otherwise in this file or this component's Licenses.txt file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2017 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18 */
19 /*
20  * btrCore_le.c
21  * Implementation of Gatt functionalities of Bluetooth
22  * Here is hiearchy of Gatt profile.
23  * -> /com/example/service1
24  * | - org.freedesktop.DBus.Properties
25  * | - org.bluez.GattService1
26  - /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0100 (0100..n)
27  | - /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0100/char01100
28  | - /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0100/char01200
29  | - /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0100/char01300
30  | - /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0100/char01300/desc0100
31  | - /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0100/char01300/desc0200
32  * |
33  * -> /com/example/service1/char0
34  * - org.freedesktop.DBus.Properties
35  * - org.bluez.GattCharacteristic1
36  *
37  */
38 
39 /* System Headers */
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <stdint.h>
44 #include <unistd.h>
45 
46 /* External Library Headers */
47 #include <glib.h>
48 
49 /* Interface lib Headers */
50 #include "btrCore_logger.h"
51 
52 /* Local Headers */
53 #include "btrCore_le.h"
54 #include "btrCore_service.h"
55 
56 #include "btrCore_bt_ifce.h"
57 
58 
59 #define BTR_MAX_GATT_PROFILE 16
60 #define BTR_MAX_GATT_SERVICE BT_MAX_NUM_GATT_SERVICE
61 #define BTR_MAX_GATT_CHAR BT_MAX_NUM_GATT_CHAR
62 #define BTR_MAX_GATT_DESC BT_MAX_NUM_GATT_DESC
63 
64 
65 #define BTR_MAX_GATT_CHAR_FLAGS BT_MAX_NUM_GATT_CHAR_FLAGS
66 #define BTR_MAX_GATT_DESC_FLAGS BT_MAX_NUM_GATT_DESC_FLAGS
67 #define BTR_MAX_NUMBER_OF_UUID 32
68 
69 
70 /* Characteristic Property bit field and Characteristic Extented Property bit field Values */
71 #define BTR_GATT_CHAR_FLAG_READ BT_GATT_CHAR_FLAG_READ
72 #define BTR_GATT_CHAR_FLAG_WRITE BT_GATT_CHAR_FLAG_WRITE
73 #define BTR_GATT_CHAR_FLAG_ENCRYPT_READ BT_GATT_CHAR_FLAG_ENCRYPT_READ
74 #define BTR_GATT_CHAR_FLAG_ENCRYPT_WRITE BT_GATT_CHAR_FLAG_ENCRYPT_WRITE
75 #define BTR_GATT_CHAR_FLAG_ENCRYPT_AUTHENTICATED_READ BT_GATT_CHAR_FLAG_ENCRYPT_AUTHENTICATED_READ
76 #define BTR_GATT_CHAR_FLAG_ENCRYPT_AUTHENTICATED_WRITE BT_GATT_CHAR_FLAG_ENCRYPT_AUTHENTICATED_WRITE
77 #define BTR_GATT_CHAR_FLAG_SECURE_READ BT_GATT_CHAR_FLAG_SECURE_READ /* Server Mode only */
78 #define BTR_GATT_CHAR_FLAG_SECURE_WRITE BT_GATT_CHAR_FLAG_SECURE_WRITE /* Server Mode only */
79 #define BTR_GATT_CHAR_FLAG_NOTIFY BT_GATT_CHAR_FLAG_NOTIFY
80 #define BTR_GATT_CHAR_FLAG_INDICATE BT_GATT_CHAR_FLAG_INDICATE
81 #define BTR_GATT_CHAR_FLAG_BROADCAST BT_GATT_CHAR_FLAG_BROADCAST
82 #define BTR_GATT_CHAR_FLAG_WRITE_WITHOUT_RESPONSE BT_GATT_CHAR_FLAG_WRITE_WITHOUT_RESPONSE
83 #define BTR_GATT_CHAR_FLAG_AUTHENTICATED_SIGNED_WRITES BT_GATT_CHAR_FLAG_AUTHENTICATED_SIGNED_WRITES
84 #define BTR_GATT_CHAR_FLAG_RELIABLE_WRITE BT_GATT_CHAR_FLAG_RELIABLE_WRITE
85 #define BTR_GATT_CHAR_FLAG_WRITABLE_AUXILIARIES BT_GATT_CHAR_FLAG_WRITABLE_AUXILIARIES
86 
87 #if 0
88 /* Descriptor Property bit field Values */
89 #define BTR_GATT_DESC_FLAG_READ BTR_GATT_CHAR_FLAG_READ
90 #define BTR_GATT_DESC_FLAG_WRITE BTR_GATT_CHAR_FLAG_WRITE
91 #define BTR_GATT_DESC_FLAG_ENCRYPT_READ BTR_GATT_CHAR_FLAG_ENCRYPT_READ
92 #define BTR_GATT_DESC_FLAG_ENCRYPT_WRITE BTR_GATT_CHAR_FLAG_ENCRYPT_WRITE
93 #define BTR_GATT_DESC_FLAG_ENCRYPT_AUTHENTICATED_READ BTR_GATT_CHAR_FLAG_ENCRYPT_AUTHENTICATED_READ
94 #define BTR_GATT_DESC_FLAG_ENCRYPT_AUTHENTICATED_WRITE BTR_GATT_CHAR_FLAG_ENCRYPT_AUTHENTICATED_WRITE
95 #define BTR_GATT_DESC_FLAG_SECURE_READ BTR_GATT_CHAR_FLAG_SECURE_READ /* Server Mode only */
96 #define BTR_GATT_DESC_FLAG_SECURE_WRITE BTR_GATT_CHAR_FLAG_SECURE_WRITE /* Server Mode only */
97 #endif
98 
99 
100 /* Immediate Alert Service UUID */
101 #define BTR_GATT_LE_IAS_UUID "00001802-0000-1000-8000-00805f9b34fb"
102 #define BTR_LE_IAS_ALERT_LEVEL_CHR_UUID "00002a06-0000-1000-8000-00805f9b34fb"
103 
104 /* Random UUID for testing purpose */
105 #define BTR_LE_IAS_RW_DESCRIPTOR_UUID "8260c653-1a54-426b-9e36-e84c238bc669"
106 
107 /* Advertisement data structure */
108 typedef struct _stBTRCoreLeManfData {
109  unsigned short ManfID; /* Manufacturer ID Key */
110  unsigned int lenManfData; /* Length of data associated with the manufacturer ID */
111  unsigned char data[BT_MAX_GATT_OP_DATA_LEN]; /* Data associated with the manufacturer ID */
113 
114 typedef struct _stBTRCoreLeServData {
115  char UUID[BT_MAX_STR_LEN]; /* UUID of the service data - Key */
116  uint8_t data[BT_MAX_GATT_OP_DATA_LEN]; /* Data associated with the service UUID */
118 
119 typedef struct _stBTRCoreLeCustomAdv {
120  char AdvertisementType[BT_MAX_STR_LEN]; /* Type of advertising packet : "Broadcast"/"Peripheral" */
121  char ServiceUUID[BT_MAX_NUM_GATT_SERVICE][BT_MAX_STR_LEN]; /* List of the UUIDs of the services supported by the device */
122  int numServiceUUID; /* Number of Services supported by the device */
123  char SolicitUUID[BT_MAX_NUM_GATT_SERVICE][BT_MAX_STR_LEN]; /* Services the Peripheral device maybe interested in when it is a Gatt client too */
124  int numSolicitUUID; /* Number of solicit services of the device */
125  stBTRCoreLeManfData ManfData; /* Manufacturer Id and the data assosciated */
126  stBTRCoreLeServData ServiceData; /* Arbitary data associated with the UUID */
127  unsigned char bTxPower; /* Includes Tx power in advertisement */
129 
130 /* GattDescriptor1 Properties */
131 typedef struct _stBTRCoreLeGattDesc {
132  char descPath[BTRCORE_MAX_STR_LEN]; /* Descriptor Path */
133  char descUuid[BT_MAX_UUID_STR_LEN]; /* 128-bit service UUID */
134  unsigned short descFlags; /* Descriptor Flags - bit field values */
135  char propertyValue[BT_MAX_GATT_OP_DATA_LEN]; /* value of the descriptor */
136  void* parentChar; /* ptr to parent Characteristic */
138 
139 /* GattCharacteristic1 Path and Properties */
140 typedef struct _stBTRCoreLeGattChar {
141  char charPath[BTRCORE_MAX_STR_LEN]; /* Characteristic Path */
142  char charUuid[BT_MAX_UUID_STR_LEN]; /* 128-bit service UUID */
143  stBTRCoreLeGattDesc atBTRGattDesc[BTR_MAX_GATT_DESC]; /* Max of 8 Gatt Descriptor array */
144  unsigned short ui16NumberOfGattDesc; /* Number of Gatt Service ID */
145  unsigned short charFlags; /* Characteristic Flags - bit field values */
146  char value[BT_MAX_GATT_OP_DATA_LEN]; /* value of the characteristic */
147  void* parentService; /* ptr to parent Service */
149 
150 /* GattService Path and Properties */
151 typedef struct _stBTRCoreLeGattService {
152  BOOLEAN serviceType; /* Primary(True) or secondary(False) gatt service*/
153  char servicePath[BTRCORE_MAX_STR_LEN]; /* Service Path */
154  char serviceUuid[BT_MAX_UUID_STR_LEN]; /* 128-bit service UUID */
155  stBTRCoreLeGattChar astBTRGattChar[BTR_MAX_GATT_CHAR]; /* Max of 6 Gatt Charactristic array */
156  unsigned short ui16NumberOfGattChar; /* Number of Gatt Charactristics */
157  void* parentProfile; /* ptr to parent Device Profile */
159 
160 /* GattProfile coresponds to a Device's Gatt Services */
161 typedef struct _stBTRCoreLeGattProfile {
162  tBTRCoreDevId deviceID; /* TODO To be generated from a common btrCore if */
163  char devicePath[BTRCORE_MAX_STR_LEN]; /* Object Path */
164  char i8LeGattOpReady;
165  stBTRCoreLeGattService astBTRGattService[BTR_MAX_GATT_SERVICE]; /* Max of 4 Gatt Service array */
166  unsigned short ui16NumberOfGattService; /* Number of Gatt Service ID */
168 
169 typedef struct _stBTRCoreLeUUID {
170  unsigned short flags;
171  char uuid[BT_MAX_UUID_STR_LEN];
173 
174 typedef struct _stBTRCoreLeUUIDList {
175  unsigned short numberOfUUID;
176  stBTRCoreLeUUID uuidList[BTR_MAX_NUMBER_OF_UUID];
178 
179 
180 typedef struct _stBTRCoreLeHdl {
181 
182  void* btIfceHdl;
183 
184  stBTRCoreLeGattProfile astBTRGattProfile[BTR_MAX_GATT_PROFILE];
185  unsigned short ui16NumberOfGattProfile;
186 
187  fPtr_BTRCore_LeStatusUpdateCb fpcBTRCoreLeStatusUpdate;
188  void* pvBtLeStatusUserData;
189 
190  stBTRCoreLeCustomAdv stCustomAdv;
191  /* Local gatt services */
192  stBTRCoreLeGattService stBTRLeGattService[BTR_MAX_GATT_SERVICE];
193  unsigned short ui16NumOfLocalGattServices;
194 
196 
197 
198 /* Static Function Prototypes */
199 static tBTRCoreDevId btrCore_LE_BTGenerateUniqueDeviceID (const char* apcDeviceAddress);
200 
201 static stBTRCoreLeGattProfile* btrCore_LE_FindGattProfile (stBTRCoreLeHdl *pstBTRCoreLeHdl, tBTRCoreDevId aBtrDeviceID);
202 static stBTRCoreLeGattService* btrCore_LE_FindGattService (stBTRCoreLeGattProfile *pstGattProfile, const char *pService);
203 static stBTRCoreLeGattChar* btrCore_LE_FindGattCharacteristic (stBTRCoreLeGattService *pstService, const char *pChar);
204 static stBTRCoreLeGattDesc* btrCore_LE_FindGattDescriptor (stBTRCoreLeGattChar *pstChar, const char *desc);
205 
206 static BOOLEAN btrCore_LE_isServiceSupported (char* apUUID);
207 
208 static enBTRCoreRet btrCore_LE_GetGattCharacteristicUUIDList (stBTRCoreLeGattService *pstService, void* uuidList);
209 static enBTRCoreRet btrCore_LE_GetGattDescriptorUUIDList (stBTRCoreLeGattChar *pstChar, void* uuidList);
210 static enBTRCoreRet btrCore_LE_GetDataPath (stBTRCoreLeHdl* pstBTRCoreLeHdl, tBTRCoreDevId atBTRCoreDevId,
211  const char* apBtLeUuid, char* rpBtLePath, enBTOpIfceType* renBTOpIfceType);
212 static unsigned short btrCore_LE_GetAllowedGattFlagValues (char (*flags)[BT_MAX_UUID_STR_LEN], enBTOpIfceType aenBtOpIfceType);
213 static enBTRCoreRet btrCore_LE_GetGattInfo(tBTRCoreLeHdl hBTRCoreLe, char* aUUID, enBTRCoreLEGattProp aGattProp, void *aValue);
214 
215 static enBTRCoreRet btrCore_LE_UpdateLocalGattInfoCb(enBTOpIfceType aenBtOpIfceType, enBTLeGattOp aenBtLeGattOp, const char* aBtrAddr, const char* apBtGattPath, char* apValue, void* apUserData);
216 static enBTRCoreRet btrCore_LE_LocalGattServerInfoCb( const char* apBtAdvPath, const char* apcBtDevAddr, stBTLeGattService **apstBTRCoreLeGattService, int *aNumOfGattServices, void* apUserData);
217 
218 /* Callbacks */
219 static int btrCore_LE_GattInfoCb (enBTOpIfceType enBtOpIfceType, enBTLeGattOp aenGattOp, const char* apBtGattPath, const char* aBtdevAddr, enBTDeviceState aenBTDeviceState, void* apCbInfo, void* apUserData );
220 static int btrCore_LE_AdvInfoCb(const char* apBtAdvPath, stBTLeCustomAdv** appstBtLeCustomAdv, void* apUserData);
221 
222 
223 /* static function definitions */
224 /* To move this implementation to a common file accessible for BTRCore moduels */
225 static tBTRCoreDevId
226 btrCore_LE_BTGenerateUniqueDeviceID (
227  const char* apcDeviceAddress
228 ) {
229  unsigned long long int lBTRCoreDevId = 0;
230  char lcDevHdlArr[13] = {'\0'};
231 
232  if (apcDeviceAddress && (strlen(apcDeviceAddress) >= 17)) {
233  lcDevHdlArr[0] = apcDeviceAddress[0];
234  lcDevHdlArr[1] = apcDeviceAddress[1];
235  lcDevHdlArr[2] = apcDeviceAddress[3];
236  lcDevHdlArr[3] = apcDeviceAddress[4];
237  lcDevHdlArr[4] = apcDeviceAddress[6];
238  lcDevHdlArr[5] = apcDeviceAddress[7];
239  lcDevHdlArr[6] = apcDeviceAddress[9];
240  lcDevHdlArr[7] = apcDeviceAddress[10];
241  lcDevHdlArr[8] = apcDeviceAddress[12];
242  lcDevHdlArr[9] = apcDeviceAddress[13];
243  lcDevHdlArr[10] = apcDeviceAddress[15];
244  lcDevHdlArr[11] = apcDeviceAddress[16];
245 
246  lBTRCoreDevId = (tBTRCoreDevId) strtoll(lcDevHdlArr, NULL, 16);
247  }
248 
249  return lBTRCoreDevId;
250 }
251 
252 
254 btrCore_LE_FindGattProfile (
255  stBTRCoreLeHdl* pstBTRCoreLeHdl,
256  tBTRCoreDevId aBtrDeviceID
257 ) {
258  unsigned short ui16LoopIdx = 0;
259  stBTRCoreLeGattProfile* pstProfile = NULL;
260 
261  if (pstBTRCoreLeHdl) {
262  for (ui16LoopIdx = 0; ui16LoopIdx < pstBTRCoreLeHdl->ui16NumberOfGattProfile; ui16LoopIdx++) {
263  if (pstBTRCoreLeHdl->astBTRGattProfile[ui16LoopIdx].deviceID == aBtrDeviceID) {
264  pstProfile = &pstBTRCoreLeHdl->astBTRGattProfile[ui16LoopIdx];
265  BTRCORELOG_DEBUG ("Gatt Profile for Device %llu Found.\n", aBtrDeviceID);
266  break;
267  }
268  }
269  }
270 
271  return pstProfile;
272 }
273 
274 
276 btrCore_LE_FindGattService (
277  stBTRCoreLeGattProfile* pstProfile,
278  const char* pService
279 ) {
280  unsigned short ui16LoopIdx = 0;
281  stBTRCoreLeGattService* pstService = NULL;
282 
283  if (pstProfile) {
284  for (ui16LoopIdx = 0; ui16LoopIdx < pstProfile->ui16NumberOfGattService; ui16LoopIdx++) {
285  if (!strcmp(pstProfile->astBTRGattService[ui16LoopIdx].servicePath, pService)) {
286  pstService = &pstProfile->astBTRGattService[ui16LoopIdx];
287  BTRCORELOG_DEBUG ("Gatt Service %s Found.\n", pService);
288  break;
289  }
290  }
291  }
292 
293  return pstService;
294 }
295 
296 
297 static stBTRCoreLeGattChar*
298 btrCore_LE_FindGattCharacteristic (
299  stBTRCoreLeGattService* pstService,
300  const char* pChar
301 ) {
302  unsigned short ui16LoopIdx = 0;
303  stBTRCoreLeGattChar* pstChar = NULL;
304 
305  if (pstService) {
306  for (ui16LoopIdx = 0; ui16LoopIdx < pstService->ui16NumberOfGattChar; ui16LoopIdx++) {
307  if (!strcmp(pstService->astBTRGattChar[ui16LoopIdx].charPath, pChar)) {
308  pstChar = &pstService->astBTRGattChar[ui16LoopIdx];
309  BTRCORELOG_DEBUG ("Gatt Char %s Found.\n", pChar);
310  break;
311  }
312  }
313  }
314 
315  return pstChar;
316 }
317 
318 
319 static stBTRCoreLeGattDesc*
320 btrCore_LE_FindGattDescriptor (
321  stBTRCoreLeGattChar* pstChar,
322  const char* pDesc
323 ) {
324  unsigned short ui16LoopIdx = 0;
325  stBTRCoreLeGattDesc* pstDesc = NULL;
326 
327  if (pstChar) {
328  for (ui16LoopIdx = 0; ui16LoopIdx < pstChar->ui16NumberOfGattDesc; ui16LoopIdx++) {
329  if (!strcmp(pstChar->atBTRGattDesc[ui16LoopIdx].descPath, pDesc)) {
330  pstDesc = &pstChar->atBTRGattDesc[ui16LoopIdx];
331  BTRCORELOG_DEBUG ("Gatt Descriptor %s Found.\n", pDesc);
332  break;
333  }
334  }
335  }
336 
337  return pstDesc;
338 }
339 
340 // Could make this to a common layer as btrcore.c also uses similar api
341 static BOOLEAN
342 btrCore_LE_isServiceSupported (
343  char* apUUID
344 ) {
345  BOOLEAN isSupported = FALSE;
346  char lUUID[8];
347 
348  if (!apUUID) {
349  BTRCORELOG_ERROR ("enBTRCoreInvalidArg\n");
350  return enBTRCoreInvalidArg;
351  }
352 
353  lUUID[0] = '0';
354  lUUID[1] = 'x';
355  lUUID[2] = apUUID[4];
356  lUUID[3] = apUUID[5];
357  lUUID[4] = apUUID[6];
358  lUUID[5] = apUUID[7];
359  lUUID[6] = '\0';
360 
361  if (!strcmp(lUUID, BTR_CORE_GATT_TILE_1) ||
362  !strcmp(lUUID, BTR_CORE_GATT_TILE_2) ||
363  !strcmp(lUUID, BTR_CORE_GATT_TILE_3) ||
364  !strcmp(lUUID, BTR_CORE_GEN_ATRIB)) {
365  isSupported = TRUE;
366  } /* - Add further supported Services */
367 
368  return isSupported;
369 }
370 
371 static enBTRCoreRet
372 btrCore_LE_GetGattCharacteristicUUIDList (
373  stBTRCoreLeGattService* pstService,
374  void* uuidList
375 ) {
376  stBTRCoreLeUUIDList* lstBTRCoreLeUUIDList = (stBTRCoreLeUUIDList*)uuidList;
377  unsigned short ui16LoopIdx = 0;
378 
379  if (!pstService || !uuidList) {
380  BTRCORELOG_ERROR ("enBTRCoreInvalidArg\n");
381  return enBTRCoreInvalidArg;
382  }
383 
384  for (ui16LoopIdx = 0; ui16LoopIdx < pstService->ui16NumberOfGattChar; ui16LoopIdx++) {
385  strncpy(lstBTRCoreLeUUIDList->uuidList[ui16LoopIdx].uuid, pstService->astBTRGattChar[ui16LoopIdx].charUuid, BT_MAX_UUID_STR_LEN-1);
386  lstBTRCoreLeUUIDList->uuidList[ui16LoopIdx].flags = pstService->astBTRGattChar[ui16LoopIdx].charFlags;
387  }
388 
389  lstBTRCoreLeUUIDList->numberOfUUID = ui16LoopIdx;
390 
391 
392  return enBTRCoreSuccess;
393 }
394 
395 
396 static enBTRCoreRet
397 btrCore_LE_GetGattDescriptorUUIDList (
398  stBTRCoreLeGattChar* pstChar,
399  void* uuidList
400 ) {
401  stBTRCoreLeUUIDList* lstBTRCoreLeUUIDList = (stBTRCoreLeUUIDList*)uuidList;
402  unsigned short ui16LoopIdx = 0;
403 
404  if (!pstChar || !uuidList) {
405  BTRCORELOG_ERROR ("enBTRCoreInvalidArg\n");
406  return enBTRCoreInvalidArg;
407  }
408 
409  for (ui16LoopIdx = 0; ui16LoopIdx < pstChar->ui16NumberOfGattDesc; ui16LoopIdx++) {
410  strncpy(lstBTRCoreLeUUIDList->uuidList[ui16LoopIdx].uuid, pstChar->atBTRGattDesc[ui16LoopIdx].descUuid, BT_MAX_UUID_STR_LEN-1);
411  lstBTRCoreLeUUIDList->uuidList[ui16LoopIdx].flags = pstChar->atBTRGattDesc[ui16LoopIdx].descFlags;
412  }
413 
414  lstBTRCoreLeUUIDList->numberOfUUID = ui16LoopIdx;
415 
416 
417  return enBTRCoreSuccess;
418 }
419 
420 
421 static enBTRCoreRet
422 btrCore_LE_GetDataPath (
423  stBTRCoreLeHdl* pstBTRCoreLeHdl,
424  tBTRCoreDevId atBTRCoreDevId,
425  const char* apBtLeUuid,
426  char* rpBtLePath,
427  enBTOpIfceType* renBTOpIfceType
428 ) {
429  unsigned short ui16PLoopindex = 0;
430  char* retLeDataPath = NULL;
431  stBTRCoreLeGattProfile* pProfile = NULL;
432 
433  if (!pstBTRCoreLeHdl || !atBTRCoreDevId || !apBtLeUuid) {
434  BTRCORELOG_ERROR ("enBTRCoreInvalidArg\n");
435  return enBTRCoreInvalidArg;
436  }
437 
438  if (!pstBTRCoreLeHdl->ui16NumberOfGattProfile) {
439  BTRCORELOG_ERROR ("No Gatt Profile Exists!!!!\n");
440  return enBTRCoreFailure;
441  }
442 
443  for (ui16PLoopindex = 0; ui16PLoopindex < pstBTRCoreLeHdl->ui16NumberOfGattProfile; ui16PLoopindex++) {
444  pProfile = &pstBTRCoreLeHdl->astBTRGattProfile[ui16PLoopindex];
445 
446  if (atBTRCoreDevId == pProfile->deviceID) {
447  unsigned short ui16SLoopindex = 0;
448  stBTRCoreLeGattService *pService = NULL;
449 
450  BTRCORELOG_DEBUG ("Profile Matched for Device %llu \n", atBTRCoreDevId);
451 
452  if (pProfile->ui16NumberOfGattService == 0) {
453  BTRCORELOG_ERROR ("No Gatt Service Exists!!!\n");
454  break; // profile loop
455  }
456 
457  for (ui16SLoopindex = 0; ui16SLoopindex < pProfile->ui16NumberOfGattService; ui16SLoopindex++) {
458  pService = &pProfile->astBTRGattService[ui16SLoopindex];
459 
460  if (strstr(pService->serviceUuid, apBtLeUuid)) {
461  retLeDataPath = pService->servicePath;
462  *renBTOpIfceType = enBTGattService;
463  BTRCORELOG_DEBUG ("UUID matched Service : %s.\n", pService->servicePath);
464  break; // service loop
465  }
466  }
467 
468  if (ui16SLoopindex != pProfile->ui16NumberOfGattService) {
469  break; // profile loop
470  }
471 
472  for (ui16SLoopindex = 0; ui16SLoopindex < pProfile->ui16NumberOfGattService; ui16SLoopindex++) {
473  unsigned short ui16CLoopindex = 0;
474  stBTRCoreLeGattChar* pChar = NULL;
475 
476  pService = &pProfile->astBTRGattService[ui16SLoopindex];
477 
478  if (pService->ui16NumberOfGattChar == 0) {
479  continue; /* Service has no Char to loop through */
480  }
481 
482  for (ui16CLoopindex = 0; ui16CLoopindex < pService->ui16NumberOfGattChar; ui16CLoopindex++) {
483  pChar = &pService->astBTRGattChar[ui16CLoopindex];
484 
485  if (!strcmp(pChar->charUuid, apBtLeUuid)) {
486  retLeDataPath = pChar->charPath;
487  *renBTOpIfceType = enBTGattCharacteristic;
488  BTRCORELOG_DEBUG ("UUID matched Characteristic : %s.\n", pChar->charPath);
489  break; // char loop
490  }
491  else {
492  unsigned short ui16DLoopindex = 0;
493  stBTRCoreLeGattDesc* pDesc = NULL;
494 
495  if (pChar->ui16NumberOfGattDesc == 0) {
496  continue; /* Char has no desc to loop through */
497  }
498 
499  for (ui16DLoopindex = 0; ui16DLoopindex < pChar->ui16NumberOfGattDesc; ui16DLoopindex++) {
500  pDesc = &pChar->atBTRGattDesc[ui16DLoopindex];
501 
502  if (!strcmp(apBtLeUuid, pDesc->descUuid)) {
503  retLeDataPath = pDesc->descPath;
504  *renBTOpIfceType = enBTGattDescriptor;
505  BTRCORELOG_DEBUG ("UUID matched Descriptor : %s\n", pDesc->descPath);
506  break; // desc loop
507  }
508  }
509 
510  if (ui16DLoopindex != pChar->ui16NumberOfGattDesc) {
511  break; // char loop
512  }
513  }
514  }
515 
516  if (ui16CLoopindex != pService->ui16NumberOfGattChar) {
517  break; // service loop
518  }
519  }
520  break; // profile loop
521  }
522  }
523 
524  if (ui16PLoopindex == pstBTRCoreLeHdl->ui16NumberOfGattProfile) {
525  BTRCORELOG_ERROR ("Profile Not Found for Dev : %llu!!!\n", atBTRCoreDevId);
526  }
527 
528  if (retLeDataPath) {
529  strncpy (rpBtLePath, retLeDataPath, BT_MAX_STR_LEN-1);
530  } else {
531  BTRCORELOG_ERROR ("No match found for UUID : %s !!!\n", apBtLeUuid);
532  return enBTRCoreFailure;
533  }
534 
535  return enBTRCoreSuccess;
536 }
537 
538 
539 static unsigned short
540 btrCore_LE_GetAllowedGattFlagValues (
541  char (*flags)[BT_MAX_UUID_STR_LEN],
542  enBTOpIfceType aenBtOpIfceType
543 ) {
544  unsigned short flagBits = 0;
545  unsigned char u8idx = 0;
546  unsigned char maxFlags = 0;
547 
548  if (!flags || !flags[0]) {
549  BTRCORELOG_ERROR ("enBTRCoreInvalidArg\n");
550  return 0;
551  }
552 
553  if (aenBtOpIfceType == enBTGattCharacteristic) {
554  maxFlags = BTR_MAX_GATT_CHAR_FLAGS;
555  }
556  else if (aenBtOpIfceType == enBTGattDescriptor) {
557  maxFlags = BTR_MAX_GATT_DESC_FLAGS;
558  }
559 
560  for (u8idx = 0; u8idx < maxFlags && flags[u8idx]; u8idx++) {
561  if (!strcmp("read", flags[u8idx])) {
562  flagBits |= BTR_GATT_CHAR_FLAG_READ;
563  }
564  if (!strcmp("write", flags[u8idx])) {
565  flagBits |= BTR_GATT_CHAR_FLAG_WRITE;
566  }
567  if (!strcmp("encrypt-read", flags[u8idx])) {
568  flagBits |= BTR_GATT_CHAR_FLAG_ENCRYPT_READ;
569  }
570  if (!strcmp("encrypt-write", flags[u8idx])) {
571  flagBits |= BTR_GATT_CHAR_FLAG_ENCRYPT_WRITE;
572  }
573  if (!strcmp("encrypt-authenticated-read", flags[u8idx])) {
574  flagBits |= BTR_GATT_CHAR_FLAG_ENCRYPT_AUTHENTICATED_READ;
575  }
576  if (!strcmp("encrypt-authenticated-write", flags[u8idx])) {
577  flagBits |= BTR_GATT_CHAR_FLAG_ENCRYPT_AUTHENTICATED_WRITE;
578  }
579  if (!strcmp("secure-read", flags[u8idx])) {
580  flagBits |= BTR_GATT_CHAR_FLAG_SECURE_READ;
581  }
582  if (!strcmp("secure-write", flags[u8idx])) {
583  flagBits |= BTR_GATT_CHAR_FLAG_SECURE_WRITE;
584  }
585  if (!strcmp("notify", flags[u8idx])) {
586  flagBits |= BTR_GATT_CHAR_FLAG_NOTIFY;
587  }
588  if (!strcmp("indicate", flags[u8idx])) {
589  flagBits |= BTR_GATT_CHAR_FLAG_INDICATE;
590  }
591  if (!strcmp("broadcast", flags[u8idx])) {
592  flagBits |= BTR_GATT_CHAR_FLAG_BROADCAST;
593  }
594  if (!strcmp("write-without-response", flags[u8idx])) {
595  flagBits |= BTR_GATT_CHAR_FLAG_WRITE_WITHOUT_RESPONSE;
596  }
597  if (!strcmp("authenticated-signed-writes", flags[u8idx])) {
598  flagBits |= BTR_GATT_CHAR_FLAG_AUTHENTICATED_SIGNED_WRITES;
599  }
600  if (!strcmp("reliable-write", flags[u8idx])) {
601  flagBits |= BTR_GATT_CHAR_FLAG_RELIABLE_WRITE;
602  }
603  if (!strcmp("writable-auxiliaries", flags[u8idx])) {
604  flagBits |= BTR_GATT_CHAR_FLAG_WRITABLE_AUXILIARIES;
605  }
606  }
607 
608  BTRCORELOG_INFO ("- %d\n", flagBits);
609 
610  return flagBits;
611 }
612 
613 static enBTRCoreRet
614 btrCore_LE_GetGattInfo (
615  tBTRCoreLeHdl hBTRCoreLe,
616  char* aUUID,
617  enBTRCoreLEGattProp aGattProp,
618  void* aValue
619 ) {
620  stBTRCoreLeHdl* pstlhBTRCoreLe = (stBTRCoreLeHdl*)hBTRCoreLe;
621  enBTRCoreRet lenBTRCoreRet = enBTRCoreSuccess;
622  int lNumGattServices = pstlhBTRCoreLe->ui16NumOfLocalGattServices;
623  stBTRCoreLeGattDesc* lpstBTRCoreLeGattDesc = NULL;
624  stBTRCoreLeGattChar* lpstBTRCoreLeGattChar = NULL;
625  stBTRCoreLeGattService* lCurrGattService = NULL, *lpstBTRCoreLeGattService = NULL;
626  BOOLEAN lbFoundUUID = FALSE;
627 
628  lpstBTRCoreLeGattService = pstlhBTRCoreLe->stBTRLeGattService;
629  for (int ServiceIndex = 0; (ServiceIndex < lNumGattServices) && (FALSE == lbFoundUUID); ServiceIndex++) {
630  lCurrGattService = &lpstBTRCoreLeGattService[ServiceIndex];
631  if (!strncmp(aUUID, lCurrGattService->serviceUuid, BT_MAX_STR_LEN)) {
632  lbFoundUUID = TRUE;
633  break;
634  }
635 
636  for (int index = 0; (index < lCurrGattService->ui16NumberOfGattChar) && (FALSE == lbFoundUUID); index++) {
637  lpstBTRCoreLeGattChar = &lCurrGattService->astBTRGattChar[index];
638  if (!strncmp(aUUID, lpstBTRCoreLeGattChar->charUuid, BT_MAX_STR_LEN)) {
639  lbFoundUUID = TRUE;
640  break;
641  }
642 
643  for (int descIndex = 0; (descIndex < lpstBTRCoreLeGattChar->ui16NumberOfGattDesc); descIndex++) {
644  lpstBTRCoreLeGattDesc = &lpstBTRCoreLeGattChar->atBTRGattDesc[descIndex];
645  if (!strncmp(aUUID, lpstBTRCoreLeGattDesc->descUuid, BT_MAX_STR_LEN)) {
646  lbFoundUUID = TRUE;
647  break;
648  }
649  }
650  }
651  }
652 
653  if (TRUE == lbFoundUUID) {
654  switch (aGattProp) {
655  case enBTRCoreLEGPropService: {
656  stBTRCoreLeGattService **lpstGattService = (stBTRCoreLeGattService**)aValue;
657  *lpstGattService = lCurrGattService;
658  BTRCORELOG_INFO("enBTRCoreLEGPropService UUID is %s\n", (*lpstGattService)->serviceUuid);
659  }
660  break;
661  case enBTRCoreLEGPropChar: {
662  stBTRCoreLeGattChar **lpstGattChar = (stBTRCoreLeGattChar**)aValue;
663  *lpstGattChar = lpstBTRCoreLeGattChar;
664  BTRCORELOG_INFO("enBTRCoreLEGPropChar UUID is %s\n", (*lpstGattChar)->charUuid);
665  }
666  break;
667  case enBTRCoreLEGPropDesc: {
668  stBTRCoreLeGattDesc **lpstGattDesc = (stBTRCoreLeGattDesc**)aValue;
669  *lpstGattDesc = lpstBTRCoreLeGattDesc;
670  BTRCORELOG_INFO("enBTRCoreLEGPropDesc UUID is %s\n", (*lpstGattDesc)->descUuid);
671  }
672  break;
673  case enBTRCoreLEGPropValue: {
674  char **lCharPropValue = (char**)aValue;
675  *lCharPropValue = lpstBTRCoreLeGattChar->value;
676  BTRCORELOG_INFO("Characteristic value for UUID is %s\n", *lCharPropValue);
677  }
678  break;
679  case enBTRCoreLEGPropDescValue: {
680  char **lDescPropValue = (char**)aValue;
681  *lDescPropValue = lpstBTRCoreLeGattDesc->propertyValue;
682  BTRCORELOG_INFO("Descriptor value for UUID is %s\n", *lDescPropValue);
683  }
684  break;
685  default: {
686  lenBTRCoreRet = enBTRCoreFailure;
687  }
688  break;
689  }
690  }
691  else {
692  BTRCORELOG_ERROR("UUID %s could not be found\n", aUUID);
693  lenBTRCoreRet = enBTRCoreFailure;
694  }
695 
696  return lenBTRCoreRet;
697 }
698 
699 
700 static enBTRCoreRet
701 btrCore_LE_LocalGattServerInfoCb(
702  const char* apBtAdvPath,
703  const char* apcBtDevAddr,
704  stBTLeGattService** appstBTRCoreLeGattService,
705  int* aNumOfGattServices,
706  void* apUserData
707 ) {
708  stBTRCoreLeHdl* lpstlhBTRCoreLe = (stBTRCoreLeHdl*)apUserData;
709  stBTLeGattService* apstBTRCoreLeGattService = *appstBTRCoreLeGattService;
710  stBTRCoreLeGattService* lpstBTRLeGattService = lpstlhBTRCoreLe->stBTRLeGattService;
711 
712  for (unsigned short lui16serviceIndex = 0; lui16serviceIndex < lpstlhBTRCoreLe->ui16NumOfLocalGattServices; lui16serviceIndex++) {
713  apstBTRCoreLeGattService->serviceType = lpstBTRLeGattService->serviceType;
714  apstBTRCoreLeGattService->ui16NumberOfGattChar = lpstBTRLeGattService->ui16NumberOfGattChar;
715  strncpy(apstBTRCoreLeGattService->servicePath, lpstBTRLeGattService->servicePath, BT_MAX_STR_LEN - 1);
716  strncpy(apstBTRCoreLeGattService->serviceUuid, lpstBTRLeGattService->serviceUuid, BT_MAX_UUID_STR_LEN - 1);
717 
718  stBTLeGattChar* apstBtLeGattChar = apstBTRCoreLeGattService->astBTRGattChar;
719  stBTRCoreLeGattChar* lpstBTRLeGattChar = lpstBTRLeGattService->astBTRGattChar;
720  for (unsigned short lui16charIndex = 0; lui16charIndex < lpstBTRLeGattService->ui16NumberOfGattChar; lui16charIndex++) {
721  apstBtLeGattChar->charFlags = lpstBTRLeGattChar->charFlags;
722  apstBtLeGattChar->ui16NumberOfGattDesc = lpstBTRLeGattChar->ui16NumberOfGattDesc;
723  strncpy(apstBtLeGattChar->charPath, lpstBTRLeGattChar->charPath, BT_MAX_STR_LEN - 1);
724  strncpy(apstBtLeGattChar->charUuid, lpstBTRLeGattChar->charUuid, BT_MAX_UUID_STR_LEN - 1);
725  strncpy(apstBtLeGattChar->value, lpstBTRLeGattChar->value, BT_MAX_GATT_OP_DATA_LEN - 1);
726 
727  stBTLeGattDesc* apstBtLeGattDesc = apstBtLeGattChar->atBTRGattDesc;
728  stBTRCoreLeGattDesc* lpstBTRLeGattDesc = lpstBTRLeGattChar->atBTRGattDesc;
729  for (unsigned short lui16descIndex = 0; lui16descIndex < lpstBTRLeGattChar->ui16NumberOfGattDesc; lui16descIndex++) {
730  apstBtLeGattDesc->descFlags = lpstBTRLeGattDesc->descFlags;
731  strncpy(apstBtLeGattDesc->descPath, lpstBTRLeGattDesc->descPath, BT_MAX_STR_LEN - 1);
732  strncpy(apstBtLeGattDesc->descUuid, lpstBTRLeGattDesc->descUuid, BT_MAX_UUID_STR_LEN - 1);
733  strncpy(apstBtLeGattDesc->propertyValue, lpstBTRLeGattDesc->propertyValue, BT_MAX_GATT_OP_DATA_LEN - 1);
734 
735  apstBtLeGattDesc++;
736  lpstBTRLeGattDesc++;
737  }
738 
739  apstBtLeGattChar++;
740  lpstBTRLeGattChar++;
741  }
742 
743  apstBTRCoreLeGattService++;
744  lpstBTRLeGattService++;
745  }
746 
747  *aNumOfGattServices = lpstlhBTRCoreLe->ui16NumOfLocalGattServices;
748 
749  return enBTRCoreSuccess;
750 }
751 
752 static enBTRCoreRet
753 btrCore_LE_UpdateLocalGattInfoCb (
754  enBTOpIfceType aenBtOpIfceType,
755  enBTLeGattOp aenBtLeGattOp,
756  const char* aBtrAddr,
757  const char* apBtGattPath,
758  char* apValue,
759  void* apUserData
760 ) {
761  stBTRCoreLeHdl* lpstlhBTRCoreLe = (stBTRCoreLeHdl*)apUserData;
762  stBTRCoreLeGattInfo lstBtrLeInfo;
763  stBTRCoreLeGattDesc* lpstBTRCoreLeGattDesc = NULL;
764  stBTRCoreLeGattChar* lpstBTRCoreLeGattChar = NULL;
765  stBTRCoreLeGattService* lCurrGattService = NULL, *lpstBTRCoreLeGattService = NULL;
766  int lNumGattServices = 0;
767  BOOLEAN lbFoundGattPath = FALSE;
768  enBTRCoreRet lRetValue = enBTRCoreSuccess;
769 
770  if (!apBtGattPath || !apUserData) {
771  BTRCORELOG_ERROR("Invalid arguments!!!\n");
772  return enBTRCoreInvalidArg;
773  }
774 
775  lpstBTRCoreLeGattService = lpstlhBTRCoreLe->stBTRLeGattService;
776  lNumGattServices = lpstlhBTRCoreLe->ui16NumOfLocalGattServices;
777 
778  /* Find the data structure pointer corresponding to the path */
779  for (int ServiceIndex = 0; ServiceIndex < lNumGattServices; ServiceIndex++) {
780 
781  if (FALSE == lbFoundGattPath) {
782  lCurrGattService = &lpstBTRCoreLeGattService[ServiceIndex];
783 
784  for (int index = 0; index < (lCurrGattService->ui16NumberOfGattChar) && (FALSE == lbFoundGattPath); index++) {
785  lpstBTRCoreLeGattChar = &lCurrGattService->astBTRGattChar[index];
786 
787  if (!strncmp(apBtGattPath, lpstBTRCoreLeGattChar->charPath, BT_MAX_STR_LEN)) {
788  lbFoundGattPath = TRUE;
789  break;
790  }
791 
792  for (int descIndex = 0; descIndex < lpstBTRCoreLeGattChar->ui16NumberOfGattDesc; descIndex++) {
793  lpstBTRCoreLeGattDesc = &lpstBTRCoreLeGattChar->atBTRGattDesc[descIndex];
794 
795  if (!strncmp(apBtGattPath, lpstBTRCoreLeGattDesc->descPath, BT_MAX_STR_LEN)) {
796  lbFoundGattPath = TRUE;
797  break;
798  }
799  }
800  }
801  }
802  }
803 
804  if (TRUE == lbFoundGattPath) {
805  switch (aenBtLeGattOp) {
806  case enBTLeGattOpReadValue: {
807  switch (aenBtOpIfceType) {
808  case enBTGattCharacteristic: {
809  lstBtrLeInfo.pui8Uuid = lpstBTRCoreLeGattChar->charUuid;
810  lstBtrLeInfo.enLeProp = enBTRCoreLEGPropChar;
811  /* Update stBTRCoreLeGattInfo and cb to upper layer */
812  lstBtrLeInfo.enLeOper = enBTRCoreLEGOpReadValue;
813  lstBtrLeInfo.pui8Value = apValue;
814  BTRCORELOG_TRACE("Btr address of device reading value is %s\n", aBtrAddr);
815  lpstlhBTRCoreLe->fpcBTRCoreLeStatusUpdate(&lstBtrLeInfo, aBtrAddr, lpstlhBTRCoreLe->pvBtLeStatusUserData);
816  BTRCORELOG_TRACE("Value of UUID %s\n", apValue);
817  strncpy(lpstBTRCoreLeGattChar->value, apValue, BT_MAX_GATT_OP_DATA_LEN - 1);
818  }
819  break;
820  case enBTGattDescriptor: {
821  lstBtrLeInfo.pui8Uuid = lpstBTRCoreLeGattDesc->descUuid;
822  lstBtrLeInfo.enLeProp = enBTRCoreLEGPropDesc;
823  /* Get value from upper layer */
824  lstBtrLeInfo.enLeOper = enBTRCoreLEGOpReadValue;
825  lstBtrLeInfo.pui8Value = apValue;
826  BTRCORELOG_TRACE("Btr address of device reading value is %s\n", aBtrAddr);
827  lpstlhBTRCoreLe->fpcBTRCoreLeStatusUpdate(&lstBtrLeInfo, aBtrAddr, lpstlhBTRCoreLe->pvBtLeStatusUserData);
828  BTRCORELOG_TRACE("Value of UUID %s\n", apValue);
829  strncpy(lpstBTRCoreLeGattDesc->propertyValue, apValue, BT_MAX_GATT_OP_DATA_LEN - 1);
830  }
831  break;
832  default:
833  break;
834  }
835  }
836  break;
837  case enBTLeGattOpWriteValue: {
838  switch (aenBtOpIfceType) {
839  case enBTGattCharacteristic: {
840  strncpy(lpstBTRCoreLeGattChar->value, apValue, BT_MAX_GATT_OP_DATA_LEN - 1);
841  BTRCORELOG_TRACE("Value is %s\n", lpstBTRCoreLeGattChar->value);
842  lstBtrLeInfo.pui8Uuid = lpstBTRCoreLeGattChar->charUuid;
843  lstBtrLeInfo.pui8Value = lpstBTRCoreLeGattChar->value;
844  lstBtrLeInfo.enLeProp = enBTRCoreLEGPropChar;
845  }
846  break;
847  case enBTGattDescriptor: {
848  strncpy(lpstBTRCoreLeGattDesc->propertyValue, apValue, BT_MAX_GATT_OP_DATA_LEN - 1);
849  lstBtrLeInfo.pui8Uuid = lpstBTRCoreLeGattDesc->descUuid;
850  lstBtrLeInfo.pui8Value = lpstBTRCoreLeGattDesc->propertyValue;
851  lstBtrLeInfo.enLeProp = enBTRCoreLEGPropDesc;
852  }
853  break;
854  default:
855  break;
856  }
857 
858  /* Update stBTRCoreLeGattInfo and cb to upper layer */
859  lstBtrLeInfo.enLeOper = enBTRCoreLEGOpWriteValue;
860  BTRCORELOG_TRACE("Btr address of device writing value is %s\n", aBtrAddr);
861  lpstlhBTRCoreLe->fpcBTRCoreLeStatusUpdate(&lstBtrLeInfo, aBtrAddr, lpstlhBTRCoreLe->pvBtLeStatusUserData);
862  }
863  break;
864  default:
865  break;
866  }
867  }
868  else {
869  lRetValue = enBTRCoreFailure;
870  BTRCORELOG_ERROR("UUID could not be found\n");
871  }
872 
873  return lRetValue;
874 }
875 
876 
877 //////////////////
878 // Interfaces //
879 //////////////////
880 enBTRCoreRet
882  tBTRCoreLeHdl* phBTRCoreLe,
883  void* apBtConn,
884  const char* apBtAdapter
885 ) {
886  enBTRCoreRet lenBTRCoreRet = enBTRCoreSuccess;
887  stBTRCoreLeHdl* pstlhBTRCoreLe = NULL;
888 
889  if (!phBTRCoreLe || !apBtConn || !apBtAdapter) {
890  BTRCORELOG_ERROR ("enBTRCoreInvalidArg\n");
891  return enBTRCoreInvalidArg;
892  }
893 
894  BTRCORELOG_WARN ("BTRCore_LE_Init\n");
895 
896  pstlhBTRCoreLe = (stBTRCoreLeHdl*)g_malloc0(sizeof(stBTRCoreLeHdl));
897 
898  if (!pstlhBTRCoreLe) {
899  BTRCORELOG_ERROR ("Memory Allocation Failed\n");
900  return enBTRCoreInitFailure;
901  }
902 
903  pstlhBTRCoreLe->btIfceHdl = apBtConn;
904 
905  if (BtrCore_BTRegisterLEGattInfoCb (apBtConn,
906  apBtAdapter,
907  &btrCore_LE_GattInfoCb,
908  pstlhBTRCoreLe)) {
909  lenBTRCoreRet = enBTRCoreFailure;
910  }
911 
912  if (BtrCore_BTRegisterLEAdvInfoCb(apBtConn,
913  apBtAdapter,
914  &btrCore_LE_AdvInfoCb,
915  pstlhBTRCoreLe)) {
916  lenBTRCoreRet = enBTRCoreFailure;
917  }
918 
919  if (lenBTRCoreRet != enBTRCoreSuccess) {
920  g_free(pstlhBTRCoreLe);
921  pstlhBTRCoreLe = NULL;
922  }
923 
924  *phBTRCoreLe = (tBTRCoreLeHdl)pstlhBTRCoreLe;
925 
926  return lenBTRCoreRet;
927 }
928 
929 
930 enBTRCoreRet
932  tBTRCoreLeHdl hBTRCoreLe,
933  void* apBtConn,
934  const char* apBtAdapter
935 ) {
936  stBTRCoreLeHdl* pstlhBTRCoreLe = (stBTRCoreLeHdl*)hBTRCoreLe;;
937  enBTRCoreRet lenBTRCoreRet = enBTRCoreSuccess;
938 
939  if (!hBTRCoreLe || !apBtConn || !apBtAdapter) {
940  return enBTRCoreInvalidArg;
941  }
942 
943  if (pstlhBTRCoreLe->btIfceHdl != apBtConn) {
944  BTRCORELOG_WARN ("Incorrect Argument - btIfceHdl : Continue\n");
945  }
946 
947  g_free(hBTRCoreLe);
948 
949  return lenBTRCoreRet;
950 }
951 
952 
953 enBTRCoreRet
955  tBTRCoreLeHdl hBTRCoreLe,
956  void* apBtConn,
957  const char* apBtAdapter
958 ) {
959  enBTRCoreRet lenBTRCoreRet = enBTRCoreSuccess;
960 
961  if (!hBTRCoreLe || !apBtConn || !apBtAdapter) {
962  return enBTRCoreInvalidArg;
963  }
964 
965  /* Invoke method calls for RegisterAdvertisement and RegisterApplication from here for now */
966  if (BtrCore_BTRegisterLeAdvertisement(apBtConn, apBtAdapter)) {
967  BTRCORELOG_ERROR("Unable to register advertisement\n");
968  lenBTRCoreRet = enBTRCoreFailure;
969  }
970 
971  if (BtrCore_BTRegisterLeGatt(apBtConn, apBtAdapter)) {
972  BTRCORELOG_ERROR("Unable to register application (gatt service)\n");
973  lenBTRCoreRet = enBTRCoreFailure;
974  }
975 
976  return lenBTRCoreRet;
977 }
978 
979 
980 enBTRCoreRet
982  tBTRCoreLeHdl hBTRCoreLe,
983  void* apBtConn,
984  const char* apBtAdapter
985 ) {
986  stBTRCoreLeHdl* pstlhBTRCoreLe = (stBTRCoreLeHdl*)hBTRCoreLe;
987  enBTRCoreRet lenBTRCoreRet = enBTRCoreSuccess;
988 
989  if (!hBTRCoreLe || !apBtConn || !apBtAdapter) {
990  return enBTRCoreInvalidArg;
991  }
992 
993  if (pstlhBTRCoreLe->btIfceHdl != apBtConn) {
994  BTRCORELOG_WARN("Incorrect Argument - btIfceHdl : Continue\n");
995  }
996 
997  if (BtrCore_BTUnRegisterLeGatt (apBtConn,
998  apBtAdapter)) {
999  lenBTRCoreRet = enBTRCoreFailure;
1000  }
1001 
1002  return lenBTRCoreRet;
1003 }
1004 
1005 enBTRCoreRet
1007  tBTRCoreLeHdl hBTRCoreLe,
1008  char* aAdvtType
1009 ) {
1010  stBTRCoreLeHdl* lpstlhBTRCoreLe = (stBTRCoreLeHdl*)hBTRCoreLe;
1011  enBTRCoreRet lenBTRCoreRet = enBTRCoreFailure;
1012  stBTRCoreLeCustomAdv* lpstBTRCoreLeCustAdv = NULL;
1013 
1014  if (NULL != lpstlhBTRCoreLe) {
1015  lpstBTRCoreLeCustAdv = &lpstlhBTRCoreLe->stCustomAdv;
1016 
1017  if (!(strncmp(aAdvtType, "peripheral", BTRCORE_MAX_STR_LEN)) ||
1018  !(strncmp(aAdvtType, "broadcast", BTRCORE_MAX_STR_LEN))) {
1019  strncpy(lpstBTRCoreLeCustAdv->AdvertisementType, aAdvtType, BTRCORE_MAX_STR_LEN);
1020  BTRCORELOG_INFO("Adv type : %s\n", lpstBTRCoreLeCustAdv->AdvertisementType);
1021  lenBTRCoreRet = enBTRCoreSuccess;
1022  }
1023  else {
1024  lenBTRCoreRet = enBTRCoreInvalidArg;
1025  }
1026  }
1027 
1028  return lenBTRCoreRet;
1029 }
1030 
1031 enBTRCoreRet
1033  tBTRCoreLeHdl hBTRCoreLe,
1034  char* aUUID
1035 ) {
1036  stBTRCoreLeHdl* lpstlhBTRCoreLe = (stBTRCoreLeHdl*)hBTRCoreLe;
1037  enBTRCoreRet lenBTRCoreRet = enBTRCoreFailure;
1038  stBTRCoreLeCustomAdv* lpstBTRCoreLeCustAdv = NULL;
1039 
1040  if (NULL != lpstlhBTRCoreLe) {
1041  lpstBTRCoreLeCustAdv = &lpstlhBTRCoreLe->stCustomAdv;
1042 
1043  if (BTR_MAX_GATT_SERVICE > lpstBTRCoreLeCustAdv->numServiceUUID) {
1044  strncpy(lpstBTRCoreLeCustAdv->ServiceUUID[lpstBTRCoreLeCustAdv->numServiceUUID], aUUID, BTRCORE_MAX_STR_LEN);
1045  BTRCORELOG_INFO("Service UUID : %s\n", lpstBTRCoreLeCustAdv->ServiceUUID[lpstBTRCoreLeCustAdv->numServiceUUID]);
1046  lpstBTRCoreLeCustAdv->numServiceUUID += 1;
1047  lenBTRCoreRet = enBTRCoreSuccess;
1048  }
1049  else {
1050  lenBTRCoreRet = enBTRCoreInvalidArg;
1051  }
1052  }
1053 
1054  return lenBTRCoreRet;
1055 }
1056 
1057 enBTRCoreRet
1059  tBTRCoreLeHdl hBTRCoreLe,
1060  unsigned short aManfId,
1061  unsigned char* aDeviceDetails,
1062  int aLenManfData
1063 ) {
1064  stBTRCoreLeHdl* lpstlhBTRCoreLe = (stBTRCoreLeHdl*)hBTRCoreLe;
1065  enBTRCoreRet lenBTRCoreRet = enBTRCoreFailure;
1066  stBTRCoreLeCustomAdv* lpstBTRCoreLeCustAdv = NULL;
1067  stBTRCoreLeManfData* lpstManfData = NULL;
1068 
1069  if (NULL != lpstlhBTRCoreLe) {
1070  lpstBTRCoreLeCustAdv = &lpstlhBTRCoreLe->stCustomAdv;
1071 
1072  lpstManfData = &lpstBTRCoreLeCustAdv->ManfData;
1073  lpstManfData->ManfID = aManfId;
1074  BTRCORELOG_INFO("Manf ID : %x\n", lpstBTRCoreLeCustAdv->ManfData.ManfID);
1075  lpstManfData->lenManfData = aLenManfData;
1076 
1077  for (int index = 0; index < aLenManfData; index++) {
1078  lpstManfData->data[index] = aDeviceDetails[index];
1079  BTRCORELOG_INFO("Manf data %x\n", lpstBTRCoreLeCustAdv->ManfData.data[index]);
1080  }
1081  lenBTRCoreRet = enBTRCoreSuccess;
1082  }
1083 
1084  return lenBTRCoreRet;
1085 }
1086 
1087 enBTRCoreRet
1089  tBTRCoreLeHdl hBTRCoreLe,
1090  BOOLEAN aTxPower
1091 ) {
1092  stBTRCoreLeHdl* lpstlhBTRCoreLe = (stBTRCoreLeHdl*)hBTRCoreLe;
1093  enBTRCoreRet lenBTRCoreRet = enBTRCoreFailure;
1094  stBTRCoreLeCustomAdv* lpstBTRCoreLeCustAdv = NULL;
1095 
1096  if (NULL != lpstlhBTRCoreLe) {
1097  lpstBTRCoreLeCustAdv = &lpstlhBTRCoreLe->stCustomAdv;
1098 
1099  lpstBTRCoreLeCustAdv->bTxPower = aTxPower;
1100  BTRCORELOG_INFO("TX power is: %d\n", lpstBTRCoreLeCustAdv->bTxPower);
1101  lenBTRCoreRet = enBTRCoreSuccess;
1102  }
1103 
1104  return lenBTRCoreRet;
1105 }
1106 
1107 int*
1109  tBTRCoreLeHdl hBTRCoreLe,
1110  const char* apBtAdapter,
1111  char* aBtrDevAddr,
1112  char* aUUID,
1113  BOOLEAN aServiceType,
1114  int* aNumGattServices
1115 ) {
1116  stBTRCoreLeHdl* lpstlhBTRCoreLe = (stBTRCoreLeHdl*)hBTRCoreLe;
1117  stBTRCoreLeGattService* lpstBTRGattService = NULL;
1118  int* pService = NULL;
1119 
1120  /* Check whether service uuid exists */
1121  btrCore_LE_GetGattInfo(lpstlhBTRCoreLe, aUUID, enBTRCoreLEGPropService, (void*)&pService);
1122  /* If service does not exist */
1123  if (NULL == pService) {
1124  if (BTR_MAX_GATT_SERVICE > lpstlhBTRCoreLe->ui16NumOfLocalGattServices) {
1125  int lIndex = lpstlhBTRCoreLe->ui16NumOfLocalGattServices;
1126  lpstBTRGattService = &lpstlhBTRCoreLe->stBTRLeGattService[lIndex];
1127  char lpBtLeGattSrvEpPath[BT_MAX_DEV_PATH_LEN] = "\0";
1128  char lCurAdapterAddress[BT_MAX_DEV_PATH_LEN] = "\0";
1129 
1130  strncpy(lCurAdapterAddress, aBtrDevAddr, strlen(aBtrDevAddr));
1131 
1132  char *current_pos = strchr(lCurAdapterAddress, ':');
1133  while (current_pos){
1134  *current_pos = '_';
1135  current_pos = strchr(current_pos, ':');
1136  }
1137 
1138  memset(lpBtLeGattSrvEpPath, '\0', BT_MAX_DEV_PATH_LEN);
1139  strncpy(lpBtLeGattSrvEpPath, apBtAdapter, strlen(apBtAdapter));
1140  strncat(lpBtLeGattSrvEpPath, "/dev_", (sizeof(lpBtLeGattSrvEpPath) - strlen(lpBtLeGattSrvEpPath) -1));
1141  strncat(lpBtLeGattSrvEpPath, lCurAdapterAddress, strlen(lCurAdapterAddress));
1142 
1143  /* Set gatt service UUID */
1144  strncpy(lpstBTRGattService->serviceUuid, aUUID, sizeof(lpstBTRGattService->serviceUuid));
1145  /* Set primary/secondary gatt service */
1146  lpstBTRGattService->serviceType = aServiceType;
1147  /* Set service path */
1148  snprintf(lpstBTRGattService->servicePath, BT_MAX_STR_LEN - 1, "%s/%s%02d", lpBtLeGattSrvEpPath, "service", lIndex);
1149  BTRCORELOG_INFO("Service path %s\n", lpstBTRGattService->servicePath);
1150 
1151  lpstlhBTRCoreLe->ui16NumOfLocalGattServices += 1;
1152 
1153  *aNumGattServices = lpstlhBTRCoreLe->ui16NumOfLocalGattServices;
1154  }
1155  }
1156 
1157  /* return service pointer */
1158  return (int*)lpstBTRGattService;
1159 }
1160 
1161 
1162 int*
1164  tBTRCoreLeHdl hBTRCoreLe, /* Handle to CoreLe */
1165  const char* apBtAdapter,
1166  char* aBtrDevAddr, /* Bt address of advertising device */
1167  char* aParentUUID, /* Service the characteristic belongs to */
1168  char* aUUID, /* UUID of characteristic */
1169  unsigned short aCharFlags, /* Bit field to indicate usage of characteristic */
1170  char* aValue /* Value of the characteristic if applicable */
1171 ) {
1172  stBTRCoreLeHdl* lpstlhBTRCoreLe = (stBTRCoreLeHdl*)hBTRCoreLe;
1173  stBTRCoreLeGattService* lpstBTRGattService = NULL;
1174  stBTRCoreLeGattChar* lpstBTRCoreLeGattChar = NULL;
1175  int* pChar = NULL;
1176  int* pParent = NULL;
1177 
1178  /* Check whether the char uuid exists */
1179  btrCore_LE_GetGattInfo(lpstlhBTRCoreLe, aUUID, enBTRCoreLEGPropChar, (void*)&pChar);
1180  if (NULL == pChar) {
1181  /* Check whether parent service uuid exists */
1182  btrCore_LE_GetGattInfo(lpstlhBTRCoreLe, aParentUUID, enBTRCoreLEGPropService, (void*)&pParent);
1183  if (NULL != pParent) {
1184  lpstBTRGattService = (stBTRCoreLeGattService*)pParent;
1185 
1186  if (BTR_MAX_GATT_CHAR > lpstBTRGattService->ui16NumberOfGattChar) {
1187  int lIndex = lpstBTRGattService->ui16NumberOfGattChar;
1188  lpstBTRCoreLeGattChar = &lpstBTRGattService->astBTRGattChar[lIndex];
1189 
1190  /* Set gatt char UUID */
1191  strncpy(lpstBTRCoreLeGattChar->charUuid, aUUID, sizeof(lpstBTRCoreLeGattChar->charUuid));
1192  /* Set parent service */
1193  lpstBTRCoreLeGattChar->parentService = pParent;
1194  /* Set char path */
1195  int ret = snprintf(lpstBTRCoreLeGattChar->charPath, BT_MAX_STR_LEN - 1, "%s/%s%04d", lpstBTRGattService->servicePath, "char", lIndex);
1196  if (ret > (BT_MAX_STR_LEN - 1)) {
1197  BTRCORELOG_INFO("lpstBTRCoreLeGattChar->charPath truncated\n");
1198  }
1199  /* Set char flags */
1200  lpstBTRCoreLeGattChar->charFlags = aCharFlags;
1201  /* Set the value of the characteristic after checking it is a characteristic to be read */
1202  if ((NULL != aValue) && (BTR_GATT_CHAR_FLAG_READ == (BTR_GATT_CHAR_FLAG_READ & aCharFlags))) {
1203  strncpy(lpstBTRCoreLeGattChar->value, aValue, sizeof(lpstBTRCoreLeGattChar->value));
1204  }
1205 
1206  lpstBTRGattService->ui16NumberOfGattChar += 1;
1207  }
1208  }
1209  }
1210 
1211  return (int*)lpstBTRCoreLeGattChar;
1212 }
1213 
1214 int*
1216  tBTRCoreLeHdl hBTRCoreLe, /* Handle to CoreLe */
1217  const char* apBtAdapter,
1218  char* aBtrDevAddr, /* Bt address of advertising device */
1219  char* aParentUUID, /* Char the descriptor belongs to */
1220  char* aUUID, /* UUID of descriptor */
1221  unsigned short aDescFlags, /* Bit field to indicate usage of descriptor */
1222  char* aValue /* Value of the descriptor if applicable */
1223 ) {
1224  stBTRCoreLeHdl* lpstlhBTRCoreLe = (stBTRCoreLeHdl*)hBTRCoreLe;
1225  stBTRCoreLeGattChar *lpstBTRGattChar = NULL;
1226  stBTRCoreLeGattDesc* lpstBTRGattDesc = NULL;
1227  int *pDesc = NULL;
1228  int *pParent = NULL;
1229 
1230  /* Check whether the char uuid exists */
1231  btrCore_LE_GetGattInfo(lpstlhBTRCoreLe, aUUID, enBTRCoreLEGPropDesc, (void*)&pDesc);
1232  if (NULL == pDesc) {
1233  /* Check whether parent service uuid exists */
1234  btrCore_LE_GetGattInfo(lpstlhBTRCoreLe, aParentUUID, enBTRCoreLEGPropChar, (void*)&pParent);
1235  if (NULL != pParent) {
1236  lpstBTRGattChar = (stBTRCoreLeGattChar*)pParent;
1237  if (BTR_MAX_GATT_DESC > lpstBTRGattChar->ui16NumberOfGattDesc) {
1238  int lIndex = lpstBTRGattChar->ui16NumberOfGattDesc;
1239  lpstBTRGattDesc = &lpstBTRGattChar->atBTRGattDesc[lIndex];
1240 
1241  /* Set desc UUID */
1242  strncpy(lpstBTRGattDesc->descUuid, aUUID, sizeof(lpstBTRGattDesc->descUuid));
1243  /* Set desc parent char */
1244  lpstBTRGattDesc->parentChar = pParent;
1245  /* Set desc path */
1246  int ret = snprintf(lpstBTRGattDesc->descPath, BT_MAX_STR_LEN - 1, "%s/%s%03d", lpstBTRGattChar->charPath, "desc", lIndex);
1247  if (ret > (BT_MAX_STR_LEN - 1)) {
1248  BTRCORELOG_INFO("lpstBTRGattDesc->descPath truncated\n");
1249  }
1250  BTRCORELOG_INFO("Desc path %s\n", lpstBTRGattDesc->descPath);
1251  /* Set desc flags */
1252  lpstBTRGattDesc->descFlags = aDescFlags;
1253  /* Set value of desc if it can be read */
1254  if ((NULL != aValue) && (BTR_GATT_CHAR_FLAG_READ == (BTR_GATT_CHAR_FLAG_READ & aDescFlags))) {
1255  strncpy(lpstBTRGattDesc->propertyValue, aValue, sizeof(lpstBTRGattDesc->propertyValue));
1256  }
1257 
1258  lpstBTRGattChar->ui16NumberOfGattDesc += 1;
1259  }
1260  }
1261  }
1262  /* return desc pointer */
1263  return (int*)lpstBTRGattDesc;
1264 }
1265 
1266 enBTRCoreRet
1268  tBTRCoreLeHdl hBTRCoreLe,
1269  char* aUUID,
1270  char* aValue,
1271  enBTRCoreLEGattProp aGattProp
1272 ) {
1273  stBTRCoreLeHdl* lpstlhBTRCoreLe = (stBTRCoreLeHdl*)hBTRCoreLe;
1274  stBTRCoreLeGattChar* lpstBTRGattChar = NULL;
1275  unBTOpIfceProp lunBtOpAdapProp;
1276  //BOOLEAN notifying = FALSE;
1277 
1278  if (!hBTRCoreLe) {
1279  BTRCORELOG_ERROR("enBTRCoreNotInitialized\n");
1280  return enBTRCoreNotInitialized;
1281  }
1282  else if ((!aValue) || (!aUUID)) {
1283  BTRCORELOG_ERROR("enBTRCoreInvalidArg\n");
1284  return enBTRCoreInvalidArg;
1285  }
1286 
1287  lunBtOpAdapProp.enBtGattCharProp = enBTGattCPropValue;
1288  //lunBtOpAdapProp.enBtGattCharProp = enBTGattCPropNotifying;
1289  /* Check whether service uuid exists */
1290  btrCore_LE_GetGattInfo(lpstlhBTRCoreLe, aUUID, aGattProp, (void*)&lpstBTRGattChar);
1291  BTRCORELOG_INFO("Value is %s - \n", aValue);
1292  if (NULL != lpstBTRGattChar) {
1293  if (BtrCore_BTSetProp(lpstlhBTRCoreLe->btIfceHdl, lpstBTRGattChar->charPath, enBTGattCharacteristic, lunBtOpAdapProp, (void*)aValue)) {
1294  BTRCORELOG_ERROR("Set Char Property Value - FAILED\n");
1295  return enBTRCoreFailure;
1296  }
1297  }
1298 
1299 
1300  return enBTRCoreSuccess;
1301 }
1302 
1303 enBTRCoreRet
1305  tBTRCoreLeHdl hBTRCoreLe,
1306  tBTRCoreDevId atBTRCoreDevId,
1307  const char* apcBtUuid,
1308  enBTRCoreLEGattProp aenBTRCoreLEGattProp,
1309  void* apvBtPropValue
1310 ) {
1311  stBTRCoreLeHdl* lpstlhBTRCoreLe = (stBTRCoreLeHdl*)hBTRCoreLe;
1312  char lpcBtLePath[BT_MAX_STR_LEN] = "\0";
1313  enBTOpIfceType lenBTOpIfceType = enBTUnknown;
1314  unBTOpIfceProp lunBTOpIfceProp;
1315 
1316  if (!hBTRCoreLe || !atBTRCoreDevId || !apcBtUuid) {
1317  BTRCORELOG_ERROR ("enBTRCoreInvalidArg\n");
1318  return enBTRCoreInvalidArg;
1319  }
1320 
1321  if (btrCore_LE_GetDataPath(lpstlhBTRCoreLe, atBTRCoreDevId, apcBtUuid, lpcBtLePath, &lenBTOpIfceType) != enBTRCoreSuccess) {
1322  BTRCORELOG_ERROR ("Failed to get LE Path for UUID %s !!!\n", apcBtUuid);
1323  return enBTRCoreFailure;
1324  }
1325 
1326  if (!lpcBtLePath[0]) {
1327  BTRCORELOG_ERROR ("Obtained LE Path is NULL!!!\n");
1328  return enBTRCoreFailure;
1329  }
1330 
1331  switch (aenBTRCoreLEGattProp) {
1332 
1333  case enBTRCoreLEGPropUUID:
1334  if (lenBTOpIfceType == enBTGattService) {
1335  stBTRCoreLeGattProfile* pProfile = btrCore_LE_FindGattProfile(lpstlhBTRCoreLe, atBTRCoreDevId);
1336  stBTRCoreLeGattService* pService = btrCore_LE_FindGattService(pProfile, lpcBtLePath);
1337 
1338  if (!pService) {
1339  BTRCORELOG_ERROR ("Failed to find pProfile|pService|pChar : %p|%p\n", pProfile, pService);
1340  return enBTRCoreFailure;
1341  }
1342 
1343  if (btrCore_LE_GetGattCharacteristicUUIDList(pService, apvBtPropValue) != enBTRCoreSuccess) {
1344  BTRCORELOG_ERROR ("Failed to get Char UUID List for Service %s\n", lpcBtLePath);
1345  return enBTRCoreFailure;
1346  }
1347 
1348  return enBTRCoreSuccess; /* Is it Ok to have return here or return logically at function End? */
1349  }
1350  else if (lenBTOpIfceType == enBTGattCharacteristic) {
1351  char servicePath[BT_MAX_STR_LEN] = "\0";
1352 
1353  lunBTOpIfceProp.enBtGattCharProp = enBTGattCPropService;
1354  if (BtrCore_BTGetProp(lpstlhBTRCoreLe->btIfceHdl, lpcBtLePath, lenBTOpIfceType, lunBTOpIfceProp, servicePath)) {
1355  BTRCORELOG_ERROR ("BtrCore_BTGetProp Failed to get servicePath on %s !!!\n", lpcBtLePath);
1356  return enBTRCoreFailure;
1357  }
1358 
1359  stBTRCoreLeGattProfile* pProfile = btrCore_LE_FindGattProfile(lpstlhBTRCoreLe, atBTRCoreDevId);
1360  stBTRCoreLeGattService* pService = btrCore_LE_FindGattService(pProfile, servicePath);
1361  stBTRCoreLeGattChar* pChar = btrCore_LE_FindGattCharacteristic(pService, lpcBtLePath);
1362 
1363  if (!pChar) {
1364  BTRCORELOG_ERROR ("Failed to find pProfile|pService|pChar : %p|%p|%p\n", pProfile, pService, pChar);
1365  return enBTRCoreFailure;
1366  }
1367 
1368  if (btrCore_LE_GetGattDescriptorUUIDList(pChar, apvBtPropValue) != enBTRCoreSuccess) {
1369  BTRCORELOG_ERROR ("Failed to get Desc UUID List for Char %s\n", lpcBtLePath);
1370  return enBTRCoreFailure;
1371  }
1372 
1373  return enBTRCoreSuccess; /* Is it Ok to have return here or return logically at function End? */
1374  }
1375  else if (lenBTOpIfceType == enBTGattDescriptor) {
1376  char servicePath[BT_MAX_STR_LEN] = "\0";
1377  char charPath[BT_MAX_STR_LEN] = "\0";
1378  stBTRCoreLeUUIDList* lstBTRCoreLeUUIDList = (stBTRCoreLeUUIDList*)apvBtPropValue;
1379  char retCPath = -1, retSPath = -1;
1380 
1381  lunBTOpIfceProp.enBtGattDescProp = enBTGattDPropCharacteristic;
1382  retCPath = BtrCore_BTGetProp (lpstlhBTRCoreLe->btIfceHdl, lpcBtLePath, lenBTOpIfceType, lunBTOpIfceProp, charPath);
1383 
1384  lunBTOpIfceProp.enBtGattCharProp = enBTGattCPropService;
1385  retSPath = BtrCore_BTGetProp (lpstlhBTRCoreLe->btIfceHdl, charPath, lenBTOpIfceType, lunBTOpIfceProp, servicePath);
1386 
1387  if (retCPath || retSPath) {
1388  BTRCORELOG_ERROR ("BtrCore_BTGetProp Failed to get charPath/servicePath : %s / %s\n", charPath, servicePath);
1389  return enBTRCoreFailure;
1390  }
1391 
1392  stBTRCoreLeGattProfile* pProfile = btrCore_LE_FindGattProfile(lpstlhBTRCoreLe, atBTRCoreDevId);
1393  stBTRCoreLeGattService* pService = btrCore_LE_FindGattService(pProfile, servicePath);
1394  stBTRCoreLeGattChar* pChar = btrCore_LE_FindGattCharacteristic(pService, charPath);
1395  stBTRCoreLeGattDesc* pDesc = btrCore_LE_FindGattDescriptor(pChar, lpcBtLePath);
1396 
1397  if (pDesc) {
1398  BTRCORELOG_ERROR ("Failed to find pProfile|pService|pChar|pDesc : %p|%p|%p|%p\n", pProfile, pService, pChar, pDesc);
1399  return enBTRCoreFailure;
1400  }
1401 
1402  strncpy(lstBTRCoreLeUUIDList->uuidList[0].uuid, pDesc->descUuid, BT_MAX_UUID_STR_LEN-1);
1403  lstBTRCoreLeUUIDList->uuidList[0].flags = pDesc->descFlags;
1404 
1405  return enBTRCoreSuccess; /* Is it Ok to have return here or return logically at function End? */
1406  }
1407  break;
1408 
1409  case enBTRCoreLEGPropPrimary:
1410  lunBTOpIfceProp.enBtGattServiceProp = enBTGattSPropPrimary;
1411  break;
1412 
1413  case enBTRCoreLEGPropDevice:
1414  lunBTOpIfceProp.enBtGattServiceProp = enBTGattSPropDevice;
1415  break;
1416 
1417  case enBTRCoreLEGPropService:
1418  lunBTOpIfceProp.enBtGattCharProp = enBTGattCPropService;
1419  break;
1420 
1421  case enBTRCoreLEGPropValue:
1422  if (lenBTOpIfceType == enBTGattCharacteristic) {
1423  lunBTOpIfceProp.enBtGattCharProp = enBTGattCPropValue;
1424  }
1425  else if (lenBTOpIfceType == enBTGattDescriptor) {
1426  lunBTOpIfceProp.enBtGattDescProp = enBTGattDPropValue;
1427  }
1428  break;
1429 
1430  case enBTRCoreLEGPropNotifying:
1431  lunBTOpIfceProp.enBtGattCharProp = enBTGattCPropNotifying;
1432  break;
1433 
1434  case enBTRCoreLEGPropFlags:
1435  if (lenBTOpIfceType == enBTGattCharacteristic) {
1436  lunBTOpIfceProp.enBtGattCharProp = enBTGattCPropFlags;
1437  }
1438  else if (lenBTOpIfceType == enBTGattDescriptor) {
1439  lunBTOpIfceProp.enBtGattDescProp = enBTGattDPropFlags;
1440  }
1441  break;
1442 
1443  case enBTRCoreLEGPropChar:
1444  lunBTOpIfceProp.enBtGattDescProp = enBTGattDPropCharacteristic;
1445  break;
1446 
1447  case enBTRCoreLEGPropUnknown:
1448  default:
1449  BTRCORELOG_ERROR ("Invalid enBTRCoreLEGattProp Options %d !!!\n", aenBTRCoreLEGattProp);
1450  break;
1451 
1452  }
1453 
1454  if (lenBTOpIfceType == enBTUnknown || BtrCore_BTGetProp (lpstlhBTRCoreLe->btIfceHdl,
1455  lpcBtLePath,
1456  lenBTOpIfceType,
1457  lunBTOpIfceProp,
1458  apvBtPropValue)) {
1459  BTRCORELOG_ERROR ("Failed to get Gatt %d Prop for UUID : %s!!!\n", aenBTRCoreLEGattProp, apcBtUuid);
1460  return enBTRCoreFailure;
1461  }
1462 
1463  return enBTRCoreSuccess;
1464 }
1465 
1466 /* Get the UUIDs implicitly based on the Op type ? instead of getting it from the higher layer */
1467 enBTRCoreRet
1469  tBTRCoreLeHdl hBTRCoreLe,
1470  tBTRCoreDevId atBTRCoreDevId,
1471  const char* apcBtUuid,
1472  enBTRCoreLEGattOp aenBTRCoreLEGattOp,
1473  char* apLeOpArg,
1474  char* rpLeOpRes
1475 ) {
1476  stBTRCoreLeHdl* lpstlhBTRCoreLe = (stBTRCoreLeHdl*)hBTRCoreLe;
1477  char lpcBtLePath[BT_MAX_STR_LEN] = "\0";
1478  char* lpDevicePath = "\0";
1479  enBTOpIfceType lenBTOpIfceType = enBTUnknown;
1480  enBTLeGattOp lenBTLeGattOp = enBTLeGattOpUnknown;
1481 
1482  if (!hBTRCoreLe || !atBTRCoreDevId || !apcBtUuid) {
1483  BTRCORELOG_ERROR ("enBTRCoreInvalidArg\n");
1484  return enBTRCoreInvalidArg;
1485  }
1486 
1487  if (btrCore_LE_GetDataPath(lpstlhBTRCoreLe, atBTRCoreDevId, apcBtUuid, lpcBtLePath, &lenBTOpIfceType) != enBTRCoreSuccess) {
1488  BTRCORELOG_ERROR ("Failed to get LE Path for UUID %s !!!\n", apcBtUuid);
1489  return enBTRCoreFailure;
1490  }
1491 
1492  if (!lpcBtLePath[0]) {
1493  BTRCORELOG_ERROR ("LE Path is NULL!!!\n");
1494  return enBTRCoreFailure;
1495  }
1496 
1497  if (lenBTOpIfceType == enBTGattService) {
1498  BTRCORELOG_ERROR ("enBTRCoreInvalidArg | %s is a Service UUID...LE Service Ops are not available!!!\n", apcBtUuid);
1499  return enBTRCoreFailure;
1500  }
1501  else if ((lenBTOpIfceType == enBTGattCharacteristic) ||
1502  (lenBTOpIfceType == enBTGattDescriptor)) {
1503  stBTRCoreLeGattProfile* pProfile = btrCore_LE_FindGattProfile(lpstlhBTRCoreLe, atBTRCoreDevId);
1504 
1505  if (pProfile)
1506  lpDevicePath = pProfile->devicePath;
1507  }
1508 
1509  // Validate UUID
1510  switch (aenBTRCoreLEGattOp) {
1511 
1512  case enBTRCoreLEGOpReadValue:
1513  lenBTLeGattOp = enBTLeGattOpReadValue;
1514  break;
1515  case enBTRCoreLEGOpWriteValue:
1516  lenBTLeGattOp = enBTLeGattOpWriteValue;
1517  break;
1518  case enBTRCoreLEGOpStartNotify:
1519  lenBTLeGattOp = enBTLeGattOpStartNotify;
1520  break;
1521  case enBTRCoreLEGOpStopNotify:
1522  lenBTLeGattOp = enBTLeGattOpStopNotify;
1523  break;
1524  case enBTRCoreLEGOpUnknown:
1525  default:
1526  BTRCORELOG_ERROR ("Invalid enBTRCoreLEGattOp Options %d !!!.\n", aenBTRCoreLEGattOp);
1527  break;
1528  }
1529 
1530  if (lenBTLeGattOp == enBTLeGattOpUnknown || BtrCore_BTPerformLeGattOp (lpstlhBTRCoreLe->btIfceHdl,
1531  lpcBtLePath,
1532  lenBTOpIfceType,
1533  lenBTLeGattOp,
1534  lpDevicePath, // for now
1535  apLeOpArg,
1536  rpLeOpRes) ) {
1537  BTRCORELOG_ERROR ("Failed to Perform Le Gatt Op %d for UUID %s !!!.\n", aenBTRCoreLEGattOp, apcBtUuid);
1538  return enBTRCoreFailure;
1539  }
1540 
1541  return enBTRCoreSuccess;
1542 }
1543 
1544 // Outgoing callbacks Registration Interfaces
1545 enBTRCoreRet
1546 BTRCore_LE_RegisterStatusUpdateCb (
1547  tBTRCoreLeHdl hBTRCoreLe,
1548  fPtr_BTRCore_LeStatusUpdateCb afpcBTRCoreLeStatusUpdate,
1549  void* apvBtLeStatusUserData
1550 ) {
1551  stBTRCoreLeHdl* phBTRCoreLe = NULL;
1552 
1553  if (!hBTRCoreLe || !afpcBTRCoreLeStatusUpdate) {
1554  BTRCORELOG_ERROR ("enBTRCoreInvalidArg\n");
1555  return enBTRCoreInvalidArg;
1556  }
1557 
1558  phBTRCoreLe = (stBTRCoreLeHdl*)hBTRCoreLe;
1559 
1560  phBTRCoreLe->fpcBTRCoreLeStatusUpdate = afpcBTRCoreLeStatusUpdate;
1561  phBTRCoreLe->pvBtLeStatusUserData = apvBtLeStatusUserData;
1562 
1563  return enBTRCoreSuccess;
1564 }
1565 
1566 
1567 //incoming callbacks
1568 
1569 static int
1570 btrCore_LE_AdvInfoCb (
1571  const char* apBtAdvPath,
1572  stBTLeCustomAdv** appstBtLeCustomAdv,
1573  void* apUserData
1574 ) {
1575  stBTRCoreLeHdl* lpstlhBTRCoreLe = (stBTRCoreLeHdl*)apUserData;
1576  stBTRCoreLeCustomAdv* lpstCustomAdv = &lpstlhBTRCoreLe->stCustomAdv;
1577  stBTLeCustomAdv* lpstBTLeCustomAdv = *appstBtLeCustomAdv;
1578 
1579  strncpy(lpstBTLeCustomAdv->AdvertisementType, lpstCustomAdv->AdvertisementType, (BT_MAX_STR_LEN - 1));
1580  lpstBTLeCustomAdv->bTxPower = lpstCustomAdv->bTxPower;
1581 
1582  lpstBTLeCustomAdv->numServiceUUID = lpstCustomAdv->numServiceUUID;
1583  for (int index = 0; index < lpstCustomAdv->numServiceUUID; index++) {
1584  strncpy(lpstBTLeCustomAdv->ServiceUUID[index], lpstCustomAdv->ServiceUUID[index], (BT_MAX_STR_LEN - 1));
1585  }
1586 
1587  lpstBTLeCustomAdv->numSolicitUUID = lpstCustomAdv->numSolicitUUID;
1588  for (int index = 0; index < lpstCustomAdv->numSolicitUUID; index++) {
1589  strncpy(lpstBTLeCustomAdv->SolicitUUID[index], lpstCustomAdv->SolicitUUID[index], (BT_MAX_STR_LEN - 1));
1590  }
1591 
1592  lpstBTLeCustomAdv->ManfData.ManfID = lpstCustomAdv->ManfData.ManfID;
1593  lpstBTLeCustomAdv->ManfData.lenManfData = lpstCustomAdv->ManfData.lenManfData;
1594  for (int index = 0; index < lpstCustomAdv->ManfData.lenManfData; index++) {
1595  lpstBTLeCustomAdv->ManfData.data[index] = lpstCustomAdv->ManfData.data[index];
1596  }
1597 
1598  return 0;
1599 }
1600 
1601 static int
1602 btrCore_LE_GattInfoCb (
1603  enBTOpIfceType aenBtOpIfceType,
1604  enBTLeGattOp aenGattOp,
1605  const char* apBtGattPath,
1606  const char* aBtdevAddr,
1607  enBTDeviceState aenBTDeviceState,
1608  void* apLeCbData,
1609  void* apUserData
1610 ) {
1611  stBTRCoreLeHdl* lpstlhBTRCoreLe = (stBTRCoreLeHdl*)apUserData;
1612  stBTRCoreLeGattProfile* pProfile = NULL;
1613  tBTRCoreDevId ltBTRCoreDevId = -1;
1614 
1615  if (!apBtGattPath || !aBtdevAddr || !apUserData) {
1616  BTRCORELOG_ERROR("Invalid arguments!!!\n");
1617  return -1;
1618  }
1619 
1620  ltBTRCoreDevId = btrCore_LE_BTGenerateUniqueDeviceID (aBtdevAddr);
1621  BTRCORELOG_DEBUG("apBtGattPath : %s\n", apBtGattPath);
1622 
1623  if (enBTAdvertisement == aenBtOpIfceType) {
1624  if (NULL != apLeCbData) {
1625  BTRCORELOG_TRACE("Inovking btrCore_LE_LocalGattServerInfoCb\n");
1626  stBTLeGattService* lpstBTLeGattSrv = ((stBTLeGattInfo*)apLeCbData)->astBTRGattService;
1627  btrCore_LE_LocalGattServerInfoCb(apBtGattPath, aBtdevAddr, &lpstBTLeGattSrv, &((stBTLeGattInfo*)apLeCbData)->nNumGattServices, apUserData);
1628  }
1629  }
1630  else if (aenBTDeviceState == enBTDevStFound) {
1631  char lBtUuid[BT_MAX_STR_LEN] = "\0";
1632  unBTOpIfceProp aunBTOpIfceProp;
1633 
1634  if (aenBtOpIfceType == enBTGattService) {
1635  BTRCORELOG_DEBUG ("Storing GATT Service Info...\n");
1636  char lBtDevPath[BT_MAX_STR_LEN] = "\0";
1637  char retUuid = -1, retDPath = -1;
1638  stBTRCoreLeGattService *pService = NULL;
1639 
1640  aunBTOpIfceProp.enBtGattServiceProp = enBTGattSPropUUID;
1641  retUuid = BtrCore_BTGetProp(lpstlhBTRCoreLe->btIfceHdl, apBtGattPath, aenBtOpIfceType, aunBTOpIfceProp, (void*)&lBtUuid);
1642 
1643  if (!retUuid && btrCore_LE_isServiceSupported(lBtUuid)) {
1644 
1645  aunBTOpIfceProp.enBtGattServiceProp = enBTGattSPropDevice;
1646  retDPath = BtrCore_BTGetProp(lpstlhBTRCoreLe->btIfceHdl, apBtGattPath, aenBtOpIfceType, aunBTOpIfceProp, (void*)&lBtDevPath);
1647 
1648  if (!retDPath) {
1649  if (!(pProfile = btrCore_LE_FindGattProfile(lpstlhBTRCoreLe, ltBTRCoreDevId))) {
1650 
1651  if (lpstlhBTRCoreLe->ui16NumberOfGattProfile < BTR_MAX_GATT_PROFILE) {
1652  pProfile = &lpstlhBTRCoreLe->astBTRGattProfile[lpstlhBTRCoreLe->ui16NumberOfGattProfile];
1653  strncpy(pProfile->devicePath, lBtDevPath, BTRCORE_MAX_STR_LEN - 1);
1654  pProfile->deviceID = ltBTRCoreDevId;
1655  lpstlhBTRCoreLe->ui16NumberOfGattProfile++;
1656  BTRCORELOG_DEBUG ("Added Profile for Device %llu Successfully.\n", ltBTRCoreDevId);
1657  }
1658  else {
1659  BTRCORELOG_ERROR ("BTR_MAX_GATT_PROFILE Added. Couldn't add anymore...\n");
1660  }
1661  }
1662 
1663  if (pProfile && pProfile->ui16NumberOfGattService < BTR_MAX_GATT_SERVICE) {
1664  if (!(pService = btrCore_LE_FindGattService(pProfile, apBtGattPath))) {
1665  pService = &pProfile->astBTRGattService[pProfile->ui16NumberOfGattService];
1666  strncpy(pService->serviceUuid, lBtUuid, BT_MAX_UUID_STR_LEN - 1);
1667  strncpy(pService->servicePath, apBtGattPath, BTRCORE_MAX_STR_LEN - 1);
1668  pService->parentProfile = pProfile;
1669  pProfile->ui16NumberOfGattService++;
1670  BTRCORELOG_DEBUG ("Added Service %s Successfully.\n", lBtUuid);
1671  }
1672  else {
1673  BTRCORELOG_WARN ("Gatt Service %s already exists...\n", apBtGattPath);
1674  }
1675  }
1676  else {
1677  BTRCORELOG_WARN ("BTR_MAX_GATT_SERVICE Added. Couldn't add anymore...\n");
1678  }
1679  }
1680  else {
1681  BTRCORELOG_ERROR ("BtrCore_BTGetProp Failed retUuid : %d | retDPath : %d.\n",retUuid, retDPath);
1682  }
1683  }
1684  else {
1685  BTRCORELOG_WARN ("Service Not Supported | UUID : %s\n", lBtUuid);
1686  }
1687  }
1688  else if (aenBtOpIfceType == enBTGattCharacteristic) {
1689  BTRCORELOG_DEBUG ("Storing GATT Characteristic Info...\n");
1690  char lBtSerivcePath[BT_MAX_STR_LEN] = "\0";
1691  char retUuid = -1, retSPath = -1;
1692  stBTRCoreLeGattService *pService = NULL;
1693  stBTRCoreLeGattChar *pChar = NULL;
1694 
1695  aunBTOpIfceProp.enBtGattCharProp = enBTGattCPropUUID;
1696  retUuid = BtrCore_BTGetProp(lpstlhBTRCoreLe->btIfceHdl, apBtGattPath, aenBtOpIfceType, aunBTOpIfceProp, (void*)&lBtUuid);
1697 
1698  aunBTOpIfceProp.enBtGattCharProp = enBTGattCPropService;
1699  retSPath = BtrCore_BTGetProp(lpstlhBTRCoreLe->btIfceHdl, apBtGattPath, aenBtOpIfceType, aunBTOpIfceProp, (void*)&lBtSerivcePath);
1700 
1701  if (!retUuid && !retSPath) {
1702 
1703  if ((pProfile = btrCore_LE_FindGattProfile(lpstlhBTRCoreLe, ltBTRCoreDevId))) {
1704  if ((pService = btrCore_LE_FindGattService(pProfile, lBtSerivcePath))) {
1705 
1706  if ((pService->ui16NumberOfGattChar < BTR_MAX_GATT_CHAR)) {
1707 
1708  if (!(pChar = btrCore_LE_FindGattCharacteristic(pService, apBtGattPath))) {
1709  char cFlags[BTR_MAX_GATT_CHAR_FLAGS][BT_MAX_UUID_STR_LEN];
1710  memset (cFlags, 0, sizeof(cFlags));
1711  pChar = &pService->astBTRGattChar[pService->ui16NumberOfGattChar];
1712  strncpy(pChar->charUuid, lBtUuid, BT_MAX_UUID_STR_LEN - 1 );
1713  strncpy(pChar->charPath, apBtGattPath, BTRCORE_MAX_STR_LEN - 1);
1714  pChar->parentService = pService;
1715  aunBTOpIfceProp.enBtGattCharProp = enBTGattCPropFlags;
1716  if (!BtrCore_BTGetProp(lpstlhBTRCoreLe->btIfceHdl, apBtGattPath, aenBtOpIfceType, aunBTOpIfceProp, (void*)&cFlags)) {
1717  pChar->charFlags = btrCore_LE_GetAllowedGattFlagValues(cFlags, enBTGattCharacteristic);
1718  }
1719  pService->ui16NumberOfGattChar++;
1720  BTRCORELOG_DEBUG ("Added Characteristic %s Successfully.\n", lBtUuid);
1721  }
1722  else {
1723  BTRCORELOG_WARN ("Gatt Characteristic %s already exists.\n", apBtGattPath);
1724  }
1725  }
1726  else {
1727  BTRCORELOG_WARN ("BTR_MAX_GATT_CHAR Addedd. Couldn't add anymore.\n");
1728  }
1729  }
1730  else {
1731  BTRCORELOG_ERROR ("Gatt Service %s not found.\n", lBtSerivcePath);
1732  }
1733  }
1734  else {
1735  BTRCORELOG_ERROR ("Gatt Profile for device %llu not found.\n", ltBTRCoreDevId);
1736  }
1737  }
1738  else {
1739  BTRCORELOG_ERROR ("BtrCore_BTGetProp Failed retUuid : %d | retSPath : %d\n",retUuid, retSPath);
1740  }
1741  }
1742  else if (aenBtOpIfceType == enBTGattDescriptor) {
1743  BTRCORELOG_DEBUG ("Storing GATT Descriptor Info...\n");
1744  char lBtSerivcePath[BT_MAX_STR_LEN] = "\0";
1745  char lBtCharPath[BT_MAX_STR_LEN] = "\0";
1746  char retUuid = -1, retCPath = -1, retSPath = -1;
1747  stBTRCoreLeGattService *pService = NULL;
1748  stBTRCoreLeGattChar *pChar = NULL;
1749  stBTRCoreLeGattDesc *pDesc = NULL;
1750 
1751  aunBTOpIfceProp.enBtGattDescProp = enBTGattDPropUUID;
1752  retUuid = BtrCore_BTGetProp(lpstlhBTRCoreLe->btIfceHdl, apBtGattPath, aenBtOpIfceType, aunBTOpIfceProp, (void*)&lBtUuid);
1753 
1754  aunBTOpIfceProp.enBtGattDescProp = enBTGattDPropCharacteristic;
1755  retCPath = BtrCore_BTGetProp(lpstlhBTRCoreLe->btIfceHdl, apBtGattPath, aenBtOpIfceType, aunBTOpIfceProp, (void*)&lBtCharPath);
1756 
1757  aunBTOpIfceProp.enBtGattCharProp = enBTGattCPropService;
1758  retSPath = BtrCore_BTGetProp(lpstlhBTRCoreLe->btIfceHdl, lBtCharPath, enBTGattCharacteristic, aunBTOpIfceProp, (void*)&lBtSerivcePath);
1759 
1760  if (!retUuid && !retCPath && !retSPath) {
1761 
1762  if ((pProfile = btrCore_LE_FindGattProfile(lpstlhBTRCoreLe, ltBTRCoreDevId))) {
1763  if ((pService = btrCore_LE_FindGattService(pProfile, lBtSerivcePath))) {
1764  if ((pChar = btrCore_LE_FindGattCharacteristic(pService, lBtCharPath))) {
1765 
1766  if (pChar->ui16NumberOfGattDesc < BTR_MAX_GATT_DESC) {
1767 
1768  if (!(pDesc = btrCore_LE_FindGattDescriptor(pChar, apBtGattPath))) {
1769  char dFlags[BTR_MAX_GATT_DESC_FLAGS][BT_MAX_UUID_STR_LEN];
1770  memset (dFlags, 0, sizeof(dFlags));
1771  pDesc = &pChar->atBTRGattDesc[pChar->ui16NumberOfGattDesc];
1772  strncpy (pDesc->descUuid, lBtUuid, BT_MAX_UUID_STR_LEN - 1);
1773  strncpy(pDesc->descPath, apBtGattPath, BTRCORE_MAX_STR_LEN - 1);
1774  pDesc->parentChar = pChar;
1775  aunBTOpIfceProp.enBtGattDescProp = enBTGattDPropFlags;
1776  if (!BtrCore_BTGetProp(lpstlhBTRCoreLe->btIfceHdl, apBtGattPath, aenBtOpIfceType, aunBTOpIfceProp, (void*)&dFlags)) {
1777  pDesc->descFlags = btrCore_LE_GetAllowedGattFlagValues(dFlags, enBTGattDescriptor);
1778  }
1779  pChar->ui16NumberOfGattDesc++;
1780  BTRCORELOG_DEBUG ("Added Gatt Descriptor %s Successfully.\n", lBtUuid);
1781  }
1782  else {
1783  BTRCORELOG_WARN ("Gatt Descriptor %s already exists.\n", apBtGattPath);
1784  }
1785  }
1786  else {
1787  BTRCORELOG_WARN ("BTR_MAX_GATT_DESC Added. Couldn't add anymore.\n");
1788  }
1789  }
1790  else {
1791  BTRCORELOG_ERROR ("Gatt Characteristic not found for Desc %s\n", lBtCharPath);
1792  }
1793  }
1794  else {
1795  BTRCORELOG_ERROR ("Gatt Service not found for Desc %s.\n", lBtSerivcePath);
1796  }
1797  }
1798  else {
1799  BTRCORELOG_ERROR ("Gatt Profile for device %llu not found...\n", ltBTRCoreDevId);
1800  }
1801  }
1802  else {
1803  BTRCORELOG_ERROR ("BtrCore_BTGetProp Failed retUuid : %d | retCPath : %d | retSpath : %d !!!\n", retUuid, retCPath, retSPath);
1804  }
1805  }
1806  }
1807  else if (aenBTDeviceState == enBTDevStLost) {
1808  if (aenBtOpIfceType == enBTGattService) {
1809  BTRCORELOG_DEBUG ("Freeing Gatt Service %s \n", apBtGattPath);
1810  /* Decide on this later as, enBTDevStLost won't be called upon a LE Dev disconnect/Lost */
1811  }
1812  else if (aenBtOpIfceType == enBTGattCharacteristic) {
1813  BTRCORELOG_DEBUG ("Freeing GATT Characteristic %s \n", apBtGattPath);
1814  /* Decide on this later as, enBTDevStLost won't be called upon a LE Dev disconnect/Lost */
1815  }
1816  else if (aenBtOpIfceType == enBTGattDescriptor) {
1817  BTRCORELOG_DEBUG ("Freeing GATT Descriptor %s \n", apBtGattPath);
1818  /* Decide on this later as, enBTDevStLost won't be called upon a LE Dev disconnect/Lost */
1819  }
1820  }
1821  else if (aenBTDeviceState == enBTDevStPropChanged) {
1822  if (aenBtOpIfceType == enBTGattService) {
1823  BTRCORELOG_DEBUG ("Property Changed for Gatt Service %s\n", apBtGattPath);
1824  }
1825  else if (aenBtOpIfceType == enBTGattCharacteristic) {
1826  BTRCORELOG_DEBUG("Property Changed for Gatt Char %s\n", apBtGattPath);
1827 
1828  if ((enBTLeGattOpReadValue == aenGattOp) || (enBTLeGattOpWriteValue == aenGattOp)) {
1829  if (NULL != apLeCbData) {
1830  BTRCORELOG_TRACE("Inovking btrCore_LE_UpdateLocalGattInfoCb\n");
1831  btrCore_LE_UpdateLocalGattInfoCb(aenBtOpIfceType, aenGattOp, aBtdevAddr, apBtGattPath, (char*)apLeCbData, apUserData);
1832  }
1833  }
1834  else if (enBTLeGattOpUnknown == aenGattOp) {
1835  char lBtSerivcePath[BT_MAX_STR_LEN] = "\0";
1836  unBTOpIfceProp aunBtOpIfceProp;
1837  aunBtOpIfceProp.enBtGattCharProp = enBTGattCPropService;
1838  stBTRCoreLeGattService *pService = NULL;
1839  stBTRCoreLeGattChar *pChar = NULL;
1840 
1841  if (!BtrCore_BTGetProp(lpstlhBTRCoreLe->btIfceHdl, apBtGattPath, aenBtOpIfceType, aunBtOpIfceProp, (void*)&lBtSerivcePath)) {
1842  if ((pProfile = btrCore_LE_FindGattProfile(lpstlhBTRCoreLe, ltBTRCoreDevId))) {
1843  if ((pService = btrCore_LE_FindGattService(pProfile, lBtSerivcePath))) {
1844  if ((pChar = btrCore_LE_FindGattCharacteristic(pService, apBtGattPath))) {
1845 
1846  if ((pChar->charFlags & BTR_GATT_CHAR_FLAG_READ) ||
1847  (pChar->charFlags & BTR_GATT_CHAR_FLAG_NOTIFY)) {
1848  stBTRCoreLeGattInfo lstBtrLeInfo;
1849  char value[BT_MAX_GATT_OP_DATA_LEN];
1850 
1851  memset(value, '\0', BT_MAX_GATT_OP_DATA_LEN);
1852  memset(&lstBtrLeInfo, 0, sizeof(stBTRCoreLeGattInfo));
1853 
1854 
1855  aunBtOpIfceProp.enBtGattCharProp = enBTGattCPropValue;
1856  if (!BtrCore_BTGetProp(lpstlhBTRCoreLe->btIfceHdl, apBtGattPath, enBTGattCharacteristic, aunBtOpIfceProp, (void*)&value)) {
1857  BTRCORELOG_TRACE("Obtained Characteristic Value \"%s\" with len %lu\n", value, (unsigned long)strlen(value));
1858 
1859  if (!strlen(value)) {
1860  lstBtrLeInfo.enLeOper = enBTRCoreLEGOpStartNotify; //TODO: Differentiate between enBTRCoreLEGOpStartNotify & enBTRCoreLEGOpStopNotify
1861  }
1862  else {
1863  lstBtrLeInfo.enLeOper = enBTRCoreLEGOpReadValue; //TODO: Deduce from Bt-Ifce and locally stored information
1864  }
1865  lstBtrLeInfo.enLeProp = enBTRCoreLEGPropValue; //TODO: Deduce from Bt-Ifce and locally stored information
1866  //TODO: The above needs to be changed correctly
1867  lstBtrLeInfo.pui8Value = value;
1868  lstBtrLeInfo.pui8Uuid = pChar->charUuid;
1869 
1870  /* -------------Callback to Higher Layers-------------- */
1871  lpstlhBTRCoreLe->fpcBTRCoreLeStatusUpdate(&lstBtrLeInfo, aBtdevAddr, lpstlhBTRCoreLe->pvBtLeStatusUserData);
1872  }
1873  else {
1874  BTRCORELOG_ERROR("BtrCore_BTGetProp Failed to get property enBTGattCPropValue.\n");
1875  }
1876  }
1877  else {
1878  BTRCORELOG_ERROR("BTR_GATT_CHAR_FLAG_NOTIFY/READ Operation not permitted in interface %s\n", apBtGattPath);
1879  }
1880  }
1881  else {
1882  BTRCORELOG_ERROR("Gatt Char %s Not Found\n", apBtGattPath);
1883  }
1884  }
1885  else {
1886  BTRCORELOG_ERROR("Gatt Service %s Not Found\n", lBtSerivcePath);
1887  }
1888  }
1889  else {
1890  BTRCORELOG_ERROR("Gatt Profile for Device %llu Not Found\n", ltBTRCoreDevId);
1891  }
1892  }
1893  }
1894  else {
1895  BTRCORELOG_ERROR("BtrCore_BTGetProp Failed to get property enBTGattCPropService\n");
1896  }
1897  }
1898  else if (aenBtOpIfceType == enBTGattDescriptor) {
1899  BTRCORELOG_DEBUG ("Property Changed for Gatt Desc %s\n", apBtGattPath);
1900  if ((enBTLeGattOpReadValue == aenGattOp) || (enBTLeGattOpWriteValue == aenGattOp)) {
1901  if (NULL != apLeCbData) {
1902  BTRCORELOG_DEBUG("Inovking btrCore_LE_UpdateLocalGattInfoCb\n");
1903  btrCore_LE_UpdateLocalGattInfoCb(aenBtOpIfceType, aenGattOp, aBtdevAddr, apBtGattPath, (char*)apLeCbData, apUserData);
1904  }
1905  }
1906  }
1907  else if (aenBtOpIfceType == enBTDevice) {
1908  if ((pProfile = btrCore_LE_FindGattProfile(lpstlhBTRCoreLe, ltBTRCoreDevId))) {
1909  stBTRCoreLeGattInfo lstBtrLeInfo;
1910  unBTOpIfceProp aunBtOpIfceProp;
1911  int i32value = 0;
1912 
1913  memset (&lstBtrLeInfo, 0, sizeof(stBTRCoreLeGattInfo));
1914 
1915  aunBtOpIfceProp.enBtDeviceProp = enBTDevPropSrvRslvd;
1916  if (!BtrCore_BTGetProp (lpstlhBTRCoreLe->btIfceHdl, apBtGattPath, enBTDevice, aunBtOpIfceProp, (void*)&i32value)) {
1917  BTRCORELOG_WARN ("Obtained Device SERVICESRESOLVED Value %d\n", i32value);
1918 
1919  if (pProfile->i8LeGattOpReady != (char)i32value) {
1920  pProfile->i8LeGattOpReady = (char)i32value;
1921 
1922  if (pProfile->i8LeGattOpReady) {
1923  lstBtrLeInfo.enLeOper = enBTRCoreLEGOpReady;
1924  lstBtrLeInfo.pui8Value = &pProfile->i8LeGattOpReady;
1925 
1926  /* -------------Callback to Higher Layers-------------- */
1927  lpstlhBTRCoreLe->fpcBTRCoreLeStatusUpdate (&lstBtrLeInfo, aBtdevAddr, lpstlhBTRCoreLe->pvBtLeStatusUserData);
1928  }
1929  }
1930  }
1931  else {
1932  BTRCORELOG_ERROR ("BtrCore_BTGetProp Failed to get property enBTGattCPropValue.\n");
1933  }
1934  }
1935  }
1936  }
1937  else {
1938  BTRCORELOG_WARN ("Callback for irrelavent DeviceState : %d!!!\n", aenBTDeviceState);
1939  }
1940 
1941  return 0;
1942 }
1943 
_stBTLeGattService
Definition: btrCore_bt_ifce.h:756
BOOLEAN
unsigned char BOOLEAN
DTCP Manager return codes.
Definition: dtcpmgr.h:163
BtrCore_BTRegisterLeGatt
int BtrCore_BTRegisterLeGatt(void *apBtConn, const char *apBtAdapter)
This API is used to invoke the bluez API gatt service method call RegisterApplication.
Definition: btrCore_dbus_bluez5.c:6771
BtrCore_BTSetProp
int BtrCore_BTSetProp(void *apBtConn, const char *apcOpIfcePath, enBTOpIfceType aenBtOpIfceType, unBTOpIfceProp aunBtOpIfceProp, void *apvVal)
This API sets different properties of different BT devices and services.
Definition: btrCore_dbus_bluez4.c:1737
_stBTLeCustomAdv
Definition: btrCore_bt_ifce.h:781
BtrCore_BTRegisterLeAdvertisement
int BtrCore_BTRegisterLeAdvertisement(void *apstBtIfceHdl, const char *apBtAdapter)
This API is used to invoke the bluez API advertisement method call RegisterAdvertisment.
Definition: btrCore_dbus_bluez5.c:6710
_stBTRCoreLeCustomAdv
Definition: btrCore_le.c:119
BTRCore_LE_GetGattProperty
enBTRCoreRet BTRCore_LE_GetGattProperty(tBTRCoreLeHdl hBTRCoreLe, tBTRCoreDevId atBTRCoreDevId, const char *apcBtUuid, enBTRCoreLEGattProp aenBTRCoreLEGattProp, void *apvBtPropValue)
This API fetches the GATT property value that is supported.
Definition: btrCore_le.c:1304
BtrCore_LE_PerformGattOp
enBTRCoreRet BtrCore_LE_PerformGattOp(tBTRCoreLeHdl hBTRCoreLe, tBTRCoreDevId atBTRCoreDevId, const char *apcBtUuid, enBTRCoreLEGattOp aenBTRCoreLEGattOp, char *apLeOpArg, char *rpLeOpRes)
This API is used to perform read, write, notify operations on LE devices.
Definition: btrCore_le.c:1468
BTRCore_LE_SetPropertyValue
enBTRCoreRet BTRCore_LE_SetPropertyValue(tBTRCoreLeHdl hBTRCoreLe, char *aUUID, char *aValue, enBTRCoreLEGattProp aGattProp)
This API Returns the specified property value associated with the UUID.
Definition: btrCore_le.c:1267
_stBTRCoreLeUUIDList
Definition: btrCore_le.c:174
BTRCore_LE_StartAdvertisement
enBTRCoreRet BTRCore_LE_StartAdvertisement(tBTRCoreLeHdl hBTRCoreLe, void *apBtConn, const char *apBtAdapter)
This API is used to invoke method calls to RegisterAdvertisement and RegisterApplication to begin LE ...
Definition: btrCore_le.c:954
_unBTOpIfceProp
Definition: btrCore_bt_ifce.h:609
BTRCore_LE_AddGattDescInfo
int * BTRCore_LE_AddGattDescInfo(tBTRCoreLeHdl hBTRCoreLe, const char *apBtAdapter, char *aBtrDevAddr, char *aParentUUID, char *aUUID, unsigned short aDescFlags, char *aValue)
This API is used to add gatt descriptor info for the advertisement.
Definition: btrCore_le.c:1215
BTRCore_LE_SetEnableTxPower
enBTRCoreRet BTRCore_LE_SetEnableTxPower(tBTRCoreLeHdl hBTRCoreLe, BOOLEAN aTxPower)
This API is used to enable/disable sending tranmission power with the advertisement data.
Definition: btrCore_le.c:1088
enBTDeviceState
enum _enBTDeviceState enBTDeviceState
Bluetooth device state.
BT_MAX_UUID_STR_LEN
#define BT_MAX_UUID_STR_LEN
Bluetooth max uuid length.
Definition: btrCore_bt_ifce.h:52
_stBTRCoreLeGattProfile
Definition: btrCore_le.c:161
_stBTRCoreLeGattService
Definition: btrCore_le.c:151
BtrCore_BTPerformLeGattOp
int BtrCore_BTPerformLeGattOp(void *apBtConn, const char *apBtLePath, enBTOpIfceType aenBTOpIfceType, enBTLeGattOp aenBTLeGattOp, char *apLeGatOparg1, char *apLeGatOparg2, char *rpLeOpRes)
This API is used to perform gatt services of the BT device .
Definition: btrCore_dbus_bluez5.c:6995
BtrCore_BTGetProp
int BtrCore_BTGetProp(void *apBtConn, const char *apcOpIfcePath, enBTOpIfceType aenBtOpIfceType, unBTOpIfceProp aunBtOpIfceProp, void *apvVal)
This API gets different properties of different BT devices and services.
Definition: btrCore_dbus_bluez4.c:1560
_stBTLeGattDesc
Definition: btrCore_bt_ifce.h:738
BTRCore_LE_SetServiceUUIDs
enBTRCoreRet BTRCore_LE_SetServiceUUIDs(tBTRCoreLeHdl hBTRCoreLe, char *aUUID)
This API is used to store the UUIDs that would be advertised by the device during the advertisement.
Definition: btrCore_le.c:1032
_stBTRCoreLeUUID
Definition: btrCore_le.c:169
_stBTRCoreLeGattDesc
Definition: btrCore_le.c:131
BTRCore_LE_AddGattCharInfo
int * BTRCore_LE_AddGattCharInfo(tBTRCoreLeHdl hBTRCoreLe, const char *apBtAdapter, char *aBtrDevAddr, char *aParentUUID, char *aUUID, unsigned short aCharFlags, char *aValue)
This API is used to add gatt characteristic info for the advertisement.
Definition: btrCore_le.c:1163
BtrCore_BTUnRegisterLeGatt
int BtrCore_BTUnRegisterLeGatt(void *apBtConn, const char *apBtAdapter)
This API is used to invoke the bluez API gatt service method call UnRegisterApplication.
Definition: btrCore_dbus_bluez5.c:6880
BTRCore_LE_SetManufacturerData
enBTRCoreRet BTRCore_LE_SetManufacturerData(tBTRCoreLeHdl hBTRCoreLe, unsigned short aManfId, unsigned char *aDeviceDetails, int aLenManfData)
This API is used to store the manufacturer data to be sent with the advertisement.
Definition: btrCore_le.c:1058
_stBTRCoreLeServData
Definition: btrCore_le.c:114
BTRCore_LE_StopAdvertisement
enBTRCoreRet BTRCore_LE_StopAdvertisement(tBTRCoreLeHdl hBTRCoreLe, void *apBtConn, const char *apBtAdapter)
This API is used to invoke method calls to UnRegisterAdvertisement and UnRegisterApplication to stop ...
Definition: btrCore_le.c:981
BTRCore_LE_Init
enBTRCoreRet BTRCore_LE_Init(tBTRCoreLeHdl *phBTRCoreLe, void *apBtConn, const char *apBtAdapter)
This API registers the callback function that has to be called when the LE device are added or remove...
Definition: btrCore_le.c:881
_stBTRCoreLeGattChar
Definition: btrCore_le.c:140
BTRCore_LE_DeInit
enBTRCoreRet BTRCore_LE_DeInit(tBTRCoreLeHdl hBTRCoreLe, void *apBtConn, const char *apBtAdapter)
This API deinitializes the LE device.
Definition: btrCore_le.c:931
_stBTLeGattInfo
Definition: btrCore_bt_ifce.h:764
BT_MAX_STR_LEN
#define BT_MAX_STR_LEN
Bluetooth max string length.
Definition: btrCore_bt_ifce.h:38
enBTOpIfceType
enum _enBTOpType enBTOpIfceType
Bluetooth device operation types.
BTRCore_LE_SetAdvertisementType
enBTRCoreRet BTRCore_LE_SetAdvertisementType(tBTRCoreLeHdl hBTRCoreLe, char *aAdvtType)
This API is used to store the advertisement type supported by device.
Definition: btrCore_le.c:1006
_stBTRCoreLeGattInfo
Definition: btrCore_le.h:74
BT_MAX_DEV_PATH_LEN
#define BT_MAX_DEV_PATH_LEN
Bluetooth max device path length.
Definition: btrCore_bt_ifce.h:44
_stBTLeGattChar
Definition: btrCore_bt_ifce.h:746
TRUE
#define TRUE
Defines for TRUE/FALSE/ENABLE flags.
Definition: wifi_common_hal.h:199
enBTLeGattOp
enum _enBTLeGattOp enBTLeGattOp
Bluetooth Gatt operations.
_stBTRCoreLeManfData
Definition: btrCore_le.c:108
_stBTRCoreLeHdl
Definition: btrCore_le.c:180
BTRCore_LE_AddGattServiceInfo
int * BTRCore_LE_AddGattServiceInfo(tBTRCoreLeHdl hBTRCoreLe, const char *apBtAdapter, char *aBtrDevAddr, char *aUUID, BOOLEAN aServiceType, int *aNumGattServices)
This API is used to add service info for the advertisement.
Definition: btrCore_le.c:1108