1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "gap_le.h"
17 #include "gap_internal.h"
18
19 #include <securec.h>
20
21 #include "allocator.h"
22 #include "log.h"
23
24 #include "btm.h"
25 #include "hci/hci.h"
26 #include "hci/hci_error.h"
27
28 typedef struct {
29 GapAdvCallback callback;
30 void *context;
31 } LeAdvCallback;
32
33 typedef struct {
34 GapExAdvCallback callback;
35 void *context;
36 } LeExAdvCallback;
37
38 static LeAdvCallback g_leAdvCallback;
39 static LeExAdvCallback g_leExAdvCallback;
40
GapFindExAdvInfoByAdvHandle(void * nodeData,void * param)41 static bool GapFindExAdvInfoByAdvHandle(void *nodeData, void *param)
42 {
43 uint8_t advHandle = *(uint8_t *)param;
44
45 return ((LeExAdvInfo *)nodeData)->advHandle == advHandle;
46 }
47
GapLeReadMaximumAdvertisingDataLengthComplete(const HciLeReadMaximumAdvertisingDataLengthReturnParam * param)48 void GapLeReadMaximumAdvertisingDataLengthComplete(const HciLeReadMaximumAdvertisingDataLengthReturnParam *param)
49 {
50 LeExAdvBlock *exAdvBlock = GapGetLeExAdvBlock();
51 if (param->status == HCI_SUCCESS) {
52 exAdvBlock->exAdvDataMaxLen = param->maximumAdvertisingDataLength;
53 } else {
54 exAdvBlock->exAdvDataMaxLen = 0;
55 }
56 }
57
GapLeReadNumberofSupportedAdvertisingSetsComplete(const HciLeReadNumberofSupportedAdvertisingSetsReturnParam * param)58 void GapLeReadNumberofSupportedAdvertisingSetsComplete(
59 const HciLeReadNumberofSupportedAdvertisingSetsReturnParam *param)
60 {
61 LeExAdvBlock *exAdvBlock = GapGetLeExAdvBlock();
62 if (param->status == HCI_SUCCESS) {
63 exAdvBlock->exAdvMaxNumber = param->numSupportedAdvertisingSets;
64 } else {
65 exAdvBlock->exAdvMaxNumber = 0;
66 }
67 }
68
GAP_LeExAdvGetMaxDataLen(uint16_t * len)69 int GAP_LeExAdvGetMaxDataLen(uint16_t *len)
70 {
71 LOG_INFO("%{public}s:", __FUNCTION__);
72 LeExAdvBlock *exAdvBlock = GapGetLeExAdvBlock();
73 *len = exAdvBlock->exAdvDataMaxLen;
74 return GAP_SUCCESS;
75 }
76
GAP_LeExAdvGetMaxHandleNum(uint8_t * num)77 int GAP_LeExAdvGetMaxHandleNum(uint8_t *num)
78 {
79 LOG_INFO("%{public}s:", __FUNCTION__);
80 LeExAdvBlock *exAdvBlock = GapGetLeExAdvBlock();
81 *num = exAdvBlock->exAdvMaxNumber;
82 return GAP_SUCCESS;
83 }
84
GAP_RegisterExAdvCallback(const GapExAdvCallback * callback,void * context)85 int GAP_RegisterExAdvCallback(const GapExAdvCallback *callback, void *context)
86 {
87 LOG_INFO("%{public}s:%{public}s", __FUNCTION__, callback ? "register" : "NULL");
88 if (callback == NULL) {
89 (void)memset_s(
90 &g_leExAdvCallback.callback, sizeof(g_leExAdvCallback.callback), 0x00, sizeof(g_leExAdvCallback.callback));
91 } else {
92 g_leExAdvCallback.callback = *callback;
93 }
94 g_leExAdvCallback.context = context;
95 return GAP_SUCCESS;
96 }
97
GAP_DeregisterExAdvCallback(void)98 int GAP_DeregisterExAdvCallback(void)
99 {
100 (void)memset_s(
101 &g_leExAdvCallback.callback, sizeof(g_leExAdvCallback.callback), 0x00, sizeof(g_leExAdvCallback.callback));
102 g_leExAdvCallback.context = NULL;
103 return GAP_SUCCESS;
104 }
105
GapLeSetAdvertisingSetRandomAddress(uint8_t advHandle,const uint8_t addr[BT_ADDRESS_SIZE])106 static int GapLeSetAdvertisingSetRandomAddress(uint8_t advHandle, const uint8_t addr[BT_ADDRESS_SIZE])
107 {
108 HciLeSetAdvertisingSetRandomAddressParam hciCmdParam;
109
110 LeExAdvInfo *info = ListForEachData(GapGetLeExAdvBlock()->exAdvInfoList, GapFindExAdvInfoByAdvHandle, &advHandle);
111 if (info != NULL) {
112 (void)memcpy_s(info->randomAddress, BT_ADDRESS_SIZE, addr, BT_ADDRESS_SIZE);
113 } else {
114 info = MEM_MALLOC.alloc(sizeof(LeExAdvInfo));
115 if (info != NULL) {
116 info->advHandle = advHandle;
117 (void)memcpy_s(info->randomAddress, BT_ADDRESS_SIZE, addr, BT_ADDRESS_SIZE);
118 ListAddLast(GapGetLeExAdvBlock()->exAdvInfoList, info);
119 }
120 }
121
122 hciCmdParam.advertisingHandle = advHandle;
123 (void)memcpy_s(hciCmdParam.randomAddress, BT_ADDRESS_SIZE, addr, BT_ADDRESS_SIZE);
124
125 return HCI_LeSetAdvertisingSetRandomAddress(&hciCmdParam);
126 }
127
GapLeSetAdvertisingSetRandomAddressComplete(const HciLeSetAdvertisingSetRandomAddressReturnParam * param)128 void GapLeSetAdvertisingSetRandomAddressComplete(const HciLeSetAdvertisingSetRandomAddressReturnParam *param)
129 {
130 if (g_leExAdvCallback.callback.exAdvSetRandAddrResult) {
131 g_leExAdvCallback.callback.exAdvSetRandAddrResult(param->status, g_leExAdvCallback.context);
132 }
133 }
134
GAP_LeExAdvSetRandAddr(uint8_t advHandle,const uint8_t addr[BT_ADDRESS_SIZE])135 int GAP_LeExAdvSetRandAddr(uint8_t advHandle, const uint8_t addr[BT_ADDRESS_SIZE])
136 {
137 int ret;
138 LOG_INFO("%{public}s:" BT_ADDR_FMT, __FUNCTION__, BT_ADDR_FMT_OUTPUT(addr));
139 if (GapIsLeEnable() == false) {
140 return GAP_ERR_NOT_ENABLE;
141 }
142
143 if (GapLeRolesCheck(GAP_LE_ROLE_BROADCASTER | GAP_LE_ROLE_PREIPHERAL) == false) {
144 ret = GAP_ERR_INVAL_STATE;
145 } else {
146 ret = GapLeSetAdvertisingSetRandomAddress(advHandle, addr);
147 }
148 return ret;
149 }
150
GapLeSetExtendedAdvertisingParameters(uint8_t advHandle,uint8_t properties,int8_t txPower,GapLeExAdvParam advExParam)151 static int GapLeSetExtendedAdvertisingParameters(
152 uint8_t advHandle, uint8_t properties, int8_t txPower, GapLeExAdvParam advExParam)
153 {
154 HciLeSetExtendedAdvertisingParametersParam hciCmdParam;
155 hciCmdParam.advertisingHandle = advHandle;
156 hciCmdParam.advertisingEventProperties = properties;
157 (void)memcpy_s(hciCmdParam.priAdvertisingIntervalMin,
158 sizeof(hciCmdParam.priAdvertisingIntervalMin),
159 &advExParam.advIntervalMin,
160 sizeof(hciCmdParam.priAdvertisingIntervalMin));
161 (void)memcpy_s(hciCmdParam.priAdvertisingIntervalMax,
162 sizeof(hciCmdParam.priAdvertisingIntervalMax),
163 &advExParam.advIntervalMax,
164 sizeof(hciCmdParam.priAdvertisingIntervalMax));
165 hciCmdParam.priAdvertisingChannelMap = advExParam.advChannelMap;
166 hciCmdParam.ownAddressType = BTM_GetOwnAddressType();
167 hciCmdParam.peerAddressType = advExParam.peerAddr->type;
168 (void)memcpy_s(hciCmdParam.peerAddress, BT_ADDRESS_SIZE, advExParam.peerAddr->addr, BT_ADDRESS_SIZE);
169 hciCmdParam.advertisingFilterPolicy = advExParam.advFilterPolicy;
170 hciCmdParam.advertisingTxPower = txPower;
171 hciCmdParam.priAdvertisingPHY = advExParam.primaryAdvPhy;
172 hciCmdParam.secondaryAdvertisingMaxSkip = advExParam.secondaryAdvMaxSkip;
173 hciCmdParam.secondaryAdvertisingPHY = advExParam.secondaryAdvPhy;
174 hciCmdParam.advertisingSID = advExParam.advSid;
175 hciCmdParam.scanRequestNotificationEnable = advExParam.scanRequestNotifyEnable;
176 return HCI_LeSetExtendedAdvertisingParameters(&hciCmdParam);
177 }
178
GapLeSetExtendedAdvertisingParametersComplete(const HciLeSetExtendedAdvertisingParametersReturnParam * param)179 void GapLeSetExtendedAdvertisingParametersComplete(const HciLeSetExtendedAdvertisingParametersReturnParam *param)
180 {
181 if (g_leExAdvCallback.callback.exAdvSetParamResult) {
182 g_leExAdvCallback.callback.exAdvSetParamResult(
183 param->status, param->selectedTxPower, g_leExAdvCallback.context);
184 }
185 }
186
GAP_LeExAdvSetParam(uint8_t advHandle,uint8_t properties,int8_t txPower,GapLeExAdvParam advExParam)187 int GAP_LeExAdvSetParam(uint8_t advHandle, uint8_t properties, int8_t txPower, GapLeExAdvParam advExParam)
188 {
189 int ret;
190 LOG_INFO("%{public}s:", __FUNCTION__);
191 if (GapIsLeEnable() == false) {
192 return GAP_ERR_NOT_ENABLE;
193 }
194
195 if (GapLeRolesCheck(GAP_LE_ROLE_BROADCASTER | GAP_LE_ROLE_PREIPHERAL) == false) {
196 ret = GAP_ERR_INVAL_STATE;
197 } else {
198 ret = GapLeSetExtendedAdvertisingParameters(advHandle, properties, txPower, advExParam);
199 }
200 return ret;
201 }
202
GapLeSetExtendedAdvertisingData(uint8_t advHandle,uint8_t operation,uint8_t fragmentPreference,uint8_t advDataLength,const uint8_t * advData)203 static int GapLeSetExtendedAdvertisingData(
204 uint8_t advHandle, uint8_t operation, uint8_t fragmentPreference, uint8_t advDataLength, const uint8_t *advData)
205 {
206 HciLeSetExtendedAdvertisingDataParam hciCmdParam;
207 hciCmdParam.advertisingHandle = advHandle;
208 hciCmdParam.fragmentPreference = fragmentPreference;
209 hciCmdParam.operation = operation;
210 hciCmdParam.advertisingDataLength = advDataLength;
211 hciCmdParam.advertisingData = advData;
212
213 return HCI_LeSetExtendedAdvertisingData(&hciCmdParam);
214 }
215
GapLeSetExtendedAdvertisingDataComplete(const HciLeSetExtendedAdvertisingDataReturnParam * param)216 void GapLeSetExtendedAdvertisingDataComplete(const HciLeSetExtendedAdvertisingDataReturnParam *param)
217 {
218 if (g_leExAdvCallback.callback.exAdvSetDataResult) {
219 g_leExAdvCallback.callback.exAdvSetDataResult(param->status, g_leExAdvCallback.context);
220 }
221 }
222
GAP_LeExAdvSetData(uint8_t advHandle,uint8_t operation,uint8_t fragmentPreference,uint8_t advDataLength,const uint8_t * advData)223 int GAP_LeExAdvSetData(
224 uint8_t advHandle, uint8_t operation, uint8_t fragmentPreference, uint8_t advDataLength, const uint8_t *advData)
225 {
226 int ret;
227 LOG_INFO("%{public}s:", __FUNCTION__);
228 if (GapIsLeEnable() == false) {
229 return GAP_ERR_NOT_ENABLE;
230 }
231
232 if (GapLeRolesCheck(GAP_LE_ROLE_BROADCASTER | GAP_LE_ROLE_PREIPHERAL) == false) {
233 ret = GAP_ERR_INVAL_STATE;
234 } else {
235 ret = GapLeSetExtendedAdvertisingData(advHandle, operation, fragmentPreference, advDataLength, advData);
236 }
237 return ret;
238 }
239
GapLeSetExtendedScanResponseData(uint8_t advHandle,uint8_t operation,uint8_t fragmentPreference,uint8_t scanResponseDataLength,const uint8_t * scanResponseData)240 static int GapLeSetExtendedScanResponseData(uint8_t advHandle, uint8_t operation, uint8_t fragmentPreference,
241 uint8_t scanResponseDataLength, const uint8_t *scanResponseData)
242 {
243 HciLeSetExtendedScanResponseDataParam hciCmdParam;
244 hciCmdParam.advertisingHandle = advHandle;
245 hciCmdParam.fragmentPreference = fragmentPreference;
246 hciCmdParam.operation = operation;
247 hciCmdParam.scanResponseDataLength = scanResponseDataLength;
248 hciCmdParam.scanResponseData = scanResponseData;
249
250 return HCI_LeSetExtendedScanResponseData(&hciCmdParam);
251 }
252
GapLeSetExtendedScanResponseDataComplete(const HciLeSetExtendedScanResponseDataReturnParam * param)253 void GapLeSetExtendedScanResponseDataComplete(const HciLeSetExtendedScanResponseDataReturnParam *param)
254 {
255 if (g_leExAdvCallback.callback.exAdvSetScanRspDataResult) {
256 g_leExAdvCallback.callback.exAdvSetScanRspDataResult(param->status, g_leExAdvCallback.context);
257 }
258 }
259
GAP_LeExAdvSetScanRspData(uint8_t advHandle,uint8_t operation,uint8_t fragmentPreference,uint8_t scanResponseDataLen,const uint8_t * scanResponseData)260 int GAP_LeExAdvSetScanRspData(uint8_t advHandle, uint8_t operation, uint8_t fragmentPreference,
261 uint8_t scanResponseDataLen, const uint8_t *scanResponseData)
262 {
263 int ret;
264 LOG_INFO("%{public}s:", __FUNCTION__);
265 if (GapIsLeEnable() == false) {
266 return GAP_ERR_NOT_ENABLE;
267 }
268
269 if (GapLeRolesCheck(GAP_LE_ROLE_BROADCASTER | GAP_LE_ROLE_PREIPHERAL) == false) {
270 ret = GAP_ERR_INVAL_STATE;
271 } else {
272 ret = GapLeSetExtendedScanResponseData(
273 advHandle, operation, fragmentPreference, scanResponseDataLen, scanResponseData);
274 }
275 return ret;
276 }
277
GapLeSetExtendedAdvertisingEnable(uint8_t enable,uint8_t numberOfSet,const GapExAdvSet * advSet)278 static int GapLeSetExtendedAdvertisingEnable(uint8_t enable, uint8_t numberOfSet, const GapExAdvSet *advSet)
279 {
280 int ret;
281 HciLeSetExtendedAdvertisingEnableParam hciCmdParam;
282
283 hciCmdParam.enable = enable;
284 hciCmdParam.numberofSets = numberOfSet;
285 hciCmdParam.sets = MEM_MALLOC.alloc(numberOfSet * sizeof(HciLeExtendedAdvertisingParamSet));
286 if (hciCmdParam.sets) {
287 for (int i = 0; i < numberOfSet; i++) {
288 hciCmdParam.sets[i].adverHandle = advSet[i].advHandle;
289 hciCmdParam.sets[i].duration = advSet[i].duration;
290 hciCmdParam.sets[i].maxExtendAdvertisingEvents = advSet[i].maxExAdvEvt;
291 }
292
293 ret = HCI_LeSetExtendedAdvertisingEnable(&hciCmdParam);
294 MEM_MALLOC.free(hciCmdParam.sets);
295 } else {
296 ret = GAP_ERR_OUT_OF_RES;
297 }
298
299 return ret;
300 }
301
GapLeSetExtendedAdvertisingEnableComplete(const HciLeSetExtendedAdvertisingEnableReturnParam * param)302 void GapLeSetExtendedAdvertisingEnableComplete(const HciLeSetExtendedAdvertisingEnableReturnParam *param)
303 {
304 if (g_leExAdvCallback.callback.exAdvSetEnableResult) {
305 g_leExAdvCallback.callback.exAdvSetEnableResult(param->status, g_leExAdvCallback.context);
306 }
307 }
308
GAP_LeExAdvSetEnable(uint8_t enable,uint8_t numberOfSet,const GapExAdvSet * advSet)309 int GAP_LeExAdvSetEnable(uint8_t enable, uint8_t numberOfSet, const GapExAdvSet *advSet)
310 {
311 int ret;
312 LOG_INFO("%{public}s:", __FUNCTION__);
313 if (GapIsLeEnable() == false) {
314 return GAP_ERR_NOT_ENABLE;
315 }
316
317 if (GapLeRolesCheck(GAP_LE_ROLE_BROADCASTER | GAP_LE_ROLE_PREIPHERAL) == false) {
318 ret = GAP_ERR_INVAL_STATE;
319 } else {
320 ret = GapLeSetExtendedAdvertisingEnable(enable, numberOfSet, advSet);
321 }
322 return ret;
323 }
324
GapOnLeScanRequestReceivedEvent(const HciLeScanRequestReceivedEventParam * eventParam)325 void GapOnLeScanRequestReceivedEvent(const HciLeScanRequestReceivedEventParam *eventParam)
326 {
327 if (g_leExAdvCallback.callback.exAdvScanRequestReceived) {
328 BtAddr addr;
329 GapChangeHCIAddr(&addr, &eventParam->scannerAddress, eventParam->scannerAddressType);
330 g_leExAdvCallback.callback.exAdvScanRequestReceived(
331 eventParam->advertisingHandle, &addr, g_leExAdvCallback.context);
332 }
333 }
334
GapLeRemoveAdvertisingSetComplete(const HciLeRemoveAdvertisingSetReturnParam * param)335 void GapLeRemoveAdvertisingSetComplete(const HciLeRemoveAdvertisingSetReturnParam *param)
336 {
337 if (g_leExAdvCallback.callback.exAdvRemoveHandleResult) {
338 g_leExAdvCallback.callback.exAdvRemoveHandleResult(param->status, g_leExAdvCallback.context);
339 }
340 }
341
GapLeClearAdvertisingSets(void)342 static int GapLeClearAdvertisingSets(void)
343 {
344 ListClear(GapGetLeExAdvBlock()->exAdvInfoList);
345
346 return HCI_LeClearAdvertisingSets();
347 }
348
GapLeClearAdvertisingSetsComplete(const HciLeClearAdvertisingSetsReturnParam * param)349 void GapLeClearAdvertisingSetsComplete(const HciLeClearAdvertisingSetsReturnParam *param)
350 {
351 if (g_leExAdvCallback.callback.exAdvClearHandleResult) {
352 g_leExAdvCallback.callback.exAdvClearHandleResult(param->status, g_leExAdvCallback.context);
353 }
354 }
355
GAP_LeExAdvClearHandle(void)356 int GAP_LeExAdvClearHandle(void)
357 {
358 LOG_INFO("%{public}s:", __FUNCTION__);
359 int ret;
360
361 if (GapIsLeEnable() == false) {
362 return GAP_ERR_NOT_ENABLE;
363 }
364
365 if (GapLeRolesCheck(GAP_LE_ROLE_BROADCASTER | GAP_LE_ROLE_PREIPHERAL) == false) {
366 ret = GAP_ERR_INVAL_STATE;
367 } else {
368 ret = GapLeClearAdvertisingSets();
369 }
370 return ret;
371 }
372
GapOnLeAdvertisingSetTerminated(const HciLeAdvertisingSetTerminatedEventParam * eventParam)373 void GapOnLeAdvertisingSetTerminated(const HciLeAdvertisingSetTerminatedEventParam *eventParam)
374 {
375 if (eventParam->status == HCI_SUCCESS) {
376 LeDeviceInfo *deviceInfo = ListForEachData(GapGetLeConnectionInfoBlock()->deviceList,
377 GapFindLeConnectionDeviceByHandle,
378 (void *)&eventParam->connectionHandle);
379 if (deviceInfo != NULL && deviceInfo->ownAddr.type == BT_RANDOM_DEVICE_ADDRESS) {
380 LeExAdvInfo *info = ListForEachData(GapGetLeExAdvBlock()->exAdvInfoList,
381 GapFindExAdvInfoByAdvHandle,
382 (void *)&eventParam->advertisingHandle);
383 if (info != NULL) {
384 LOG_INFO("%{public}s: change own address " BT_ADDR_FMT " -> " BT_ADDR_FMT,
385 __FUNCTION__,
386 BT_ADDR_FMT_OUTPUT(deviceInfo->ownAddr.addr),
387 BT_ADDR_FMT_OUTPUT(info->randomAddress));
388 (void)memcpy_s(deviceInfo->ownAddr.addr, BT_ADDRESS_SIZE, info->randomAddress, BT_ADDRESS_SIZE);
389 }
390 }
391 if (deviceInfo != NULL && GapLeDeviceNeedBond(deviceInfo)) {
392 GapLeDoPair(&deviceInfo->addr);
393 }
394 if (eventParam->status == HCI_SUCCESS) {
395 if (deviceInfo != NULL) {
396 deviceInfo->ownAddrUpdated = true;
397 }
398 if (deviceInfo != NULL && deviceInfo->securityReq != NULL) {
399 GapLeRequestSecurityProcess(deviceInfo);
400 }
401 }
402 }
403
404 if (g_leExAdvCallback.callback.exAdvTerminatedAdvSet) {
405 g_leExAdvCallback.callback.exAdvTerminatedAdvSet(eventParam->status,
406 eventParam->advertisingHandle,
407 eventParam->connectionHandle,
408 eventParam->numCompletedExtendedAdvertisingEvents,
409 g_leExAdvCallback.context);
410 }
411 }
412
GAP_RegisterAdvCallback(const GapAdvCallback * callback,void * context)413 int GAP_RegisterAdvCallback(const GapAdvCallback *callback, void *context)
414 {
415 LOG_INFO("%{public}s:%{public}s", __FUNCTION__, callback ? "register" : "NULL");
416 if (callback == NULL) {
417 (void)memset_s(
418 &g_leAdvCallback.callback, sizeof(g_leAdvCallback.callback), 0x00, sizeof(g_leAdvCallback.callback));
419 } else {
420 g_leAdvCallback.callback = *callback;
421 }
422 g_leAdvCallback.context = context;
423 return GAP_SUCCESS;
424 }
425
GAP_DeregisterAdvCallback(void)426 int GAP_DeregisterAdvCallback(void)
427 {
428 (void)memset_s(&g_leAdvCallback.callback, sizeof(g_leAdvCallback.callback), 0x00, sizeof(g_leAdvCallback.callback));
429 g_leAdvCallback.context = NULL;
430 return GAP_SUCCESS;
431 }
432
GAP_LeAdvSetParam(uint8_t advType,GapLeAdvParam advParam)433 int GAP_LeAdvSetParam(uint8_t advType, GapLeAdvParam advParam)
434 {
435 LOG_INFO("%{public}s:", __FUNCTION__);
436 int ret;
437
438 if (GapIsLeEnable() == false) {
439 return GAP_ERR_NOT_ENABLE;
440 }
441
442 if (GapLeRolesCheck(GAP_LE_ROLE_BROADCASTER | GAP_LE_ROLE_PREIPHERAL) == false) {
443 ret = GAP_ERR_INVAL_STATE;
444 } else if (GapLeRolesCheck(GAP_LE_ROLE_PREIPHERAL) == false && advType != GAP_ADV_TYPE_SCAN_UNDIR &&
445 advType != GAP_ADV_TYPE_NON_CONN_UNDIR) {
446 ret = GAP_ERR_INVAL_PARAM;
447 } else {
448 HciLeSetAdvertisingParametersParam hciCmdParam;
449
450 hciCmdParam.advertisingType = advType;
451 hciCmdParam.advertisingIntervalMin = advParam.advIntervalMin;
452 hciCmdParam.advertisingIntervalMax = advParam.advIntervalMax;
453 hciCmdParam.ownAddressType = BTM_GetOwnAddressType();
454 hciCmdParam.peerAddressType = advParam.peerAddr->type;
455 (void)memcpy_s(hciCmdParam.peerAddress.raw, BT_ADDRESS_SIZE, advParam.peerAddr->addr, BT_ADDRESS_SIZE);
456 hciCmdParam.advertisingChannelMap = advParam.advChannelMap;
457 hciCmdParam.advertisingFilterPolicy = advParam.advFilterPolicy;
458
459 ret = HCI_LeSetAdvertisingParameters(&hciCmdParam);
460 if (ret != BT_NO_ERROR) {
461 LOG_ERROR("HCI Command Error ret = %{public}d.", ret);
462 }
463 }
464
465 return ret;
466 }
467
GapLeAdvSetParamComplete(const HciLeSetAdvertisingParametersReturnParam * param)468 void GapLeAdvSetParamComplete(const HciLeSetAdvertisingParametersReturnParam *param)
469 {
470 if (g_leAdvCallback.callback.advSetParamResult) {
471 g_leAdvCallback.callback.advSetParamResult(param->status, g_leAdvCallback.context);
472 }
473 }
474
GAP_LeAdvReadTxPower(void)475 int GAP_LeAdvReadTxPower(void)
476 {
477 LOG_INFO("%{public}s:", __FUNCTION__);
478 int ret;
479
480 if (GapIsLeEnable() == false) {
481 return GAP_ERR_NOT_ENABLE;
482 }
483
484 if (GapLeRolesCheck(GAP_LE_ROLE_BROADCASTER | GAP_LE_ROLE_PREIPHERAL) == false) {
485 ret = GAP_ERR_INVAL_STATE;
486 } else {
487 ret = HCI_LeReadAdvertisingChannelTxPower();
488 }
489
490 return ret;
491 }
492
GapLeAdvReadTxPowerComplete(const HciLeReadAdvertisingChannelTxPowerReturnParam * param)493 void GapLeAdvReadTxPowerComplete(const HciLeReadAdvertisingChannelTxPowerReturnParam *param)
494 {
495 if (g_leAdvCallback.callback.advReadTxPower) {
496 g_leAdvCallback.callback.advReadTxPower(param->status, param->transmitPowerLevel, g_leAdvCallback.context);
497 }
498 }
499
GAP_LeAdvSetData(uint8_t advDataLength,const uint8_t * advData)500 int GAP_LeAdvSetData(uint8_t advDataLength, const uint8_t *advData)
501 {
502 LOG_INFO("%{public}s:", __FUNCTION__);
503 int ret;
504
505 if (advDataLength > GAP_ADVERTISING_DATA_LENGTH_MAX) {
506 return GAP_ERR_INVAL_PARAM;
507 }
508
509 if (GapIsLeEnable() == false) {
510 return GAP_ERR_NOT_ENABLE;
511 }
512
513 if (GapLeRolesCheck(GAP_LE_ROLE_BROADCASTER | GAP_LE_ROLE_PREIPHERAL) == false) {
514 ret = GAP_ERR_INVAL_STATE;
515 } else {
516 HciLeSetAdvertisingDataParam hciCmdParam = {
517 .advertisingDataLen = advDataLength,
518 };
519 (void)memcpy_s(hciCmdParam.advertisingData, sizeof(hciCmdParam.advertisingData), advData, advDataLength);
520
521 ret = HCI_LeSetAdvertisingData(&hciCmdParam);
522 }
523
524 return ret;
525 }
526
GapLeAdvSetDataComplete(const HciLeSetAdvertisingDataReturnParam * param)527 void GapLeAdvSetDataComplete(const HciLeSetAdvertisingDataReturnParam *param)
528 {
529 if (g_leAdvCallback.callback.advSetDataResult) {
530 g_leAdvCallback.callback.advSetDataResult(param->status, g_leAdvCallback.context);
531 }
532 }
533
GAP_LeAdvSetScanRspData(uint8_t advDataLength,const uint8_t * advData)534 int GAP_LeAdvSetScanRspData(uint8_t advDataLength, const uint8_t *advData)
535 {
536 LOG_INFO("%{public}s:", __FUNCTION__);
537 int ret;
538
539 if (GapIsLeEnable() == false) {
540 return GAP_ERR_NOT_ENABLE;
541 }
542
543 if (advDataLength > GAP_ADVERTISING_DATA_LENGTH_MAX) {
544 return GAP_ERR_INVAL_PARAM;
545 }
546
547 if (GapLeRolesCheck(GAP_LE_ROLE_BROADCASTER | GAP_LE_ROLE_PREIPHERAL) == false) {
548 ret = GAP_ERR_INVAL_STATE;
549 } else {
550 HciLeSetScanResponseDataParam hciCmdParam = {
551 .scanResponseDataLength = advDataLength,
552 };
553 (void)memcpy_s(hciCmdParam.scanResponseData, sizeof(hciCmdParam.scanResponseData), advData, advDataLength);
554
555 ret = HCI_LeSetScanResponseData(&hciCmdParam);
556 }
557
558 return ret;
559 }
560
GapLeAdvSetScanRspDataComplete(const HciLeSetScanResponseDataReturnParam * param)561 void GapLeAdvSetScanRspDataComplete(const HciLeSetScanResponseDataReturnParam *param)
562 {
563 if (g_leAdvCallback.callback.advSetScanRspDataResult) {
564 g_leAdvCallback.callback.advSetScanRspDataResult(param->status, g_leAdvCallback.context);
565 }
566 }
567
GAP_LeAdvSetEnable(uint8_t enable)568 int GAP_LeAdvSetEnable(uint8_t enable)
569 {
570 LOG_INFO("%{public}s:", __FUNCTION__);
571 int ret;
572
573 if (GapIsLeEnable() == false) {
574 return GAP_ERR_NOT_ENABLE;
575 }
576
577 if (GapLeRolesCheck(GAP_LE_ROLE_BROADCASTER | GAP_LE_ROLE_PREIPHERAL) == false) {
578 ret = GAP_ERR_INVAL_STATE;
579 } else {
580 HciLeSetAdvertisingEnableParam hciCmdParam = {
581 .advertisingEnable = enable,
582 };
583
584 ret = HCI_LeSetAdvertisingEnable(&hciCmdParam);
585 }
586
587 return ret;
588 }
589
GapLeAdvSetEnableComplete(const HciLeSetAdvertisingEnableReturnParam * param)590 void GapLeAdvSetEnableComplete(const HciLeSetAdvertisingEnableReturnParam *param)
591 {
592 if (g_leAdvCallback.callback.advSetEnableResult) {
593 g_leAdvCallback.callback.advSetEnableResult(param->status, g_leAdvCallback.context);
594 }
595 }
596