-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathcy_ble_gap.c
1636 lines (1464 loc) · 65.6 KB
/
cy_ble_gap.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/***************************************************************************//**
* \file cy_ble_gap.c
* \version 3.60
*
* \brief
* This file contains the source code for the GAP API of the PSoC 6 BLE Middleware.
*
********************************************************************************
* \copyright
* Copyright 2017-2021, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_ble.h"
#include "cy_ble_hal_pvt.h"
#if defined(CY_IP_MXBLESS)
/*******************************************************************************
* Global Variables
*******************************************************************************/
/* BLE state */
cy_en_ble_state_t cy_ble_state;
/* BLE Advertising state */
cy_en_ble_adv_state_t cy_ble_advState;
/* BLE Scanning state */
cy_en_ble_scan_state_t cy_ble_scanState;
/* BLE Connection state */
cy_en_ble_conn_state_t cy_ble_connState[CY_BLE_MAX_SUPPORTED_CONN_COUNT];
/** Variable is initialized after connection with peer device,
* after CY_BLE_EVT_GATT_CONNECT_IND event, and could be used by application code
* to send data to peer device */
cy_stc_ble_conn_handle_t cy_ble_connHandle[CY_BLE_MAX_SUPPORTED_CONN_COUNT];
/* Connection parameter */
cy_stc_ble_gapc_conn_info_t cy_ble_connectionParameters;
/**
* Connecting timeout is set to 30 seconds in Cy_BLE_Init function.
* Not zero value starts timer in Cy_BLE_GAPC_ConnectDevice().
*/
cy_stc_ble_timer_info_t cy_ble_connectingTimeout;
/* Active Advertising configuration */
uint8_t cy_ble_advIndex;
/* Active Scanning configuration */
uint8_t cy_ble_scanIndex;
/**
* Store information that device connected as role:
* CY_BLE_GAP_LL_ROLE_SLAVE or CY_BLE_GAP_LL_ROLE_MASTER.
*/
uint8_t cy_ble_devConnRole[CY_BLE_MAX_SUPPORTED_CONN_COUNT];
/* Stored information is device paired */
bool cy_ble_pairStatus[CY_BLE_MAX_SUPPORTED_CONN_COUNT];
/**
* Bonding type setting of peer device, CY_BLE_GAP_BONDING_NONE or
* CY_BLE_GAP_BONDING. It is initialized after pairing with peer device and
* used for cy_ble_pendingFlashWrite variable setting.
*/
uint8_t cy_ble_peerBonding[CY_BLE_MAX_SUPPORTED_CONN_COUNT];
/* Store advertising interval type (fast or slow) with timings entered. Need to process advertising timeout */
uint8_t cy_ble_advertisingIntervalType;
/* Store scanning interval type (fast or slow) with timings entered. Need to process scanning timeout */
uint8_t cy_ble_scanningIntervalType;
/* The pointer to the global BLE GAP server config structure */
const cy_stc_ble_gaps_config_t *cy_ble_gapsConfigPtr = NULL;
/* The pointer to the global BLE GAP client config structure */
const cy_stc_ble_gapc_config_t *cy_ble_gapcConfigPtr = NULL;
/* Stored BD handle to clear CCCD values by Cy_BLE_StoreBondingData() */
uint8_t cy_ble_pendingFlashClearCccdHandle = 0u;
/**
* \addtogroup group_ble_common_api_global_variables
* \{
*/
/**
* Variable is used to detect status of pending write to flash operation for
* BLE Stack data and CCCD.
*/
uint8_t cy_ble_pendingFlashWrite;
/** \} group_ble_common_api_global_variables */
#if CY_BLE_LIB_HOST_CORE
/*******************************************************************************
* Private Function Prototypes
*******************************************************************************/
static void Cy_BLE_ChangeAdLocalName(const char8 name[], uint8_t dest);
/******************************************************************************
* Function Name: Cy_BLE_GAPS_Init
***************************************************************************//**
*
* This function initializes server of the GAP service.
*
* \param config: Configuration structure for the GAP.
*
* \return
* \ref cy_en_ble_api_result_t : Return value indicates whether the function succeeded or
* failed. The following are possible error codes.
*
* Error Codes | Description
* ------------ | -----------
* CY_BLE_SUCCESS | The function completed successfully.
* CY_BLE_ERROR_INVALID_PARAMETER | On specifying NULL as input parameter.
*
******************************************************************************/
cy_en_ble_api_result_t Cy_BLE_GAPS_Init(const cy_stc_ble_gaps_config_t *config)
{
cy_en_ble_api_result_t apiResult = CY_BLE_SUCCESS;
if(config == NULL)
{
apiResult = CY_BLE_ERROR_INVALID_PARAMETER;
}
else
{
/* Registers a pointer to config structure */
cy_ble_gapsConfigPtr = config;
}
return(apiResult);
}
/******************************************************************************
* Function Name: Cy_BLE_GAPC_Init
***************************************************************************//**
*
* This function initializes client of the GAP service.
*
* \param config: Configuration structure for the GAP.
*
* \return
* \ref cy_en_ble_api_result_t : Return value indicates whether the function succeeded or
* failed. The following are possible error codes.
*
* Error Codes | Description
* ------------ | -----------
* CY_BLE_SUCCESS | The function completed successfully.
* CY_BLE_ERROR_INVALID_PARAMETER | On specifying NULL as input parameter.
* CY_BLE_ERROR_MEMORY_ALLOCATION_FAILED | Buffer overflow in the registration callback.
*
******************************************************************************/
cy_en_ble_api_result_t Cy_BLE_GAPC_Init(const cy_stc_ble_gapc_config_t *config)
{
cy_en_ble_api_result_t apiResult = CY_BLE_SUCCESS;
if((config == NULL) || ((cy_ble_configPtr->params->gattRole & CY_BLE_GATT_CLIENT) == 0u))
{
apiResult = CY_BLE_ERROR_INVALID_PARAMETER;
}
else
{
uint32_t idx;
/* Registers a pointer to config structure */
cy_ble_gapcConfigPtr = config;
for(idx = 0u; idx < cy_ble_configPtr->params->maxClientCount; idx++)
{
uint32 servCnt = cy_ble_configPtr->context->discServiCount;
uint32 gapServIdx = cy_ble_gapcConfigPtr->serviceDiscIdx;
/* Check service range before clearing to support partial discovery */
if(cy_ble_configPtr->context->serverInfo[(idx * servCnt) + gapServIdx].range.startHandle ==
CY_BLE_GATT_INVALID_ATTR_HANDLE_VALUE)
{
(void)memset(&cy_ble_gapcConfigPtr->attrInfo[idx], 0, sizeof(cy_stc_ble_gapc_t));
/* Initialize UUID */
cy_ble_configPtr->context->serverInfo[(idx * servCnt) + gapServIdx].uuid = CY_BLE_UUID_GAP_SERVICE;
}
}
}
return(apiResult);
}
/******************************************************************************
* Function Name: Cy_BLE_StoreAppData
***************************************************************************//**
*
* This function is used to back up application-specific data into the flash.
*
* This function works in two Write modes: blocking or non-blocking:
* * Blocking (#CY_BLE_STORE_DATA_MODE_BLOCKING) - The function writes
* all data from srcBuff and returns #CY_BLE_SUCCESS when finished.
* <br>
* * Non-blocking (#CY_BLE_STORE_DATA_MODE_NON_BLOCKING) - The function initiates
* Write data and returns #CY_BLE_INFO_FLASH_WRITE_IN_PROGRESS when the Write
* is in progress, or #CY_BLE_SUCCESS when finished. In order to write complete
* data, the application needs to continue calling this function with
* the same input parameter (param), until this function returns CY_BLE_SUCCESS.
* The application must not change the input parameter's structure and content
* until this function returns CY_BLE_SUCCESS.
*
* \param param: The parameter of type \ref cy_stc_ble_app_flash_param_t.
* * param->srcBuff: The source buffer.
* * param->destAddr: The destination address. The destination buffer size
* should be greater than or equal to the source buffer.
* * param->buffLen: The length of srcData (in bytes).
* * param->writeMode: Blocking or non-blocking Write mode.
*
* param->destAddr - An array address to be defined in the
* application and aligned to the size of the device's flash row.
*
* An example of a declaration of such an array (100 bytes):
* - CY_ALIGN(CY_FLASH_SIZEOF_ROW) const uint8_t appBuff[100u] = {0u}; <br>
* <br>
* CY_ALIGN() - Aligns the array to the size of the device's flash row.
* Even if the length of srcData is not a multiple of the flash row size,
* Cy_BLE_StoreAppData() forms whole rows, and programs them in sequence.
*
* The approximate time to write one row - 16ms.
*
* The following code snippet shows the usage of Cy_BLE_StoreAppData()
* \snippet ble/snippet/main.c BLE Common API: Cy_BLE_StoreAppData()
*
* \return
* \ref cy_en_ble_api_result_t : Return value indicates whether the function
* succeeded or failed. Following are the possible error codes.
*
* Error codes | Description
* ------------ | -----------
* CY_BLE_SUCCESS | On successful operation.
* CY_BLE_INFO_FLASH_WRITE_IN_PROGRESS | Write operation is in progress.
* CY_BLE_ERROR_INVALID_PARAMETER | An invalid input parameter.
* CY_BLE_ERROR_FLASH_WRITE | An error in the flash Write.
* CY_BLE_ERROR_FLASH_WRITE_NOT_PERMITED | Flash operation is not permitted (see Note)
*
* \note: Flash operation is not permitted with protection context (PC)
* value > 0 and core voltage 0.9V, because of a preproduction
* hardware limitation.
*
******************************************************************************/
cy_en_ble_api_result_t Cy_BLE_StoreAppData(const cy_stc_ble_app_flash_param_t *param)
{
static cy_en_ble_api_result_t storeState = CY_BLE_SUCCESS;
static uint32_t tLength = 0u;
if ((param == NULL) || (param->writeMode > CY_BLE_STORE_DATA_MODE_NON_BLOCKING))
{
storeState = CY_BLE_ERROR_INVALID_PARAMETER;
}
else
{
uint8_t *tSrcPtr = (uint8_t *) param->srcBuff;
uint32_t tOffset = (uint32) param->destAddr - CY_FLASH_BASE; /* Get offset */
uint32_t blockSize;
bool exitFlag = false;
switch (storeState)
{
case CY_BLE_SUCCESS:
case CY_BLE_ERROR_INVALID_PARAMETER:
case CY_BLE_ERROR_FLASH_WRITE:
tLength = param->buffLen;
break;
case CY_BLE_INFO_FLASH_WRITE_IN_PROGRESS:
if (tLength == 0u)
{
storeState = CY_BLE_SUCCESS;
exitFlag = true;
}
else
{
/* Restore offset and srcPtr according to length */
if(tSrcPtr != NULL)
{
tSrcPtr += param->buffLen - tLength;
}
tOffset += param->buffLen - tLength;
}
break;
default:
break;
}
while((tLength != 0u) && (exitFlag == false))
{
/* Split srcBuff into parts of flash row size (512 bytes) */
blockSize = (tOffset >> 9) << 9; /* Get current row size regarding to address */
blockSize = CY_FLASH_SIZEOF_ROW - (tOffset - blockSize); /* Calculate final length of the block which
we can write to row */
blockSize = (blockSize > tLength ) ? tLength : blockSize;
/* Write 512 byte block */
storeState = Cy_BLE_HAL_NvramWrite(tSrcPtr, (uint8_t *)(tOffset + CY_FLASH_BASE),
blockSize, CY_BLE_FLASH_NON_BLOCKING_MODE);
if((storeState & CY_PDL_STATUS_ERROR) != 0u)
{
exitFlag = true;
}
if(tSrcPtr != NULL)
{
tSrcPtr += blockSize;
}
tOffset += blockSize;
tLength -= blockSize;
/* For CY_BLE_STORE_DATA_MODE_NON_BLOCKING mode write one row per call */
if(param->writeMode == CY_BLE_STORE_DATA_MODE_NON_BLOCKING)
{
if (storeState == CY_BLE_SUCCESS)
{
storeState = CY_BLE_INFO_FLASH_WRITE_IN_PROGRESS;
}
exitFlag = true;
}
/* Cy_BLE_ProcessEvents() allows BLE Stack to process pending events */
Cy_BLE_ProcessEvents();
}
}
return(storeState);
}
/******************************************************************************
* Function Name: Cy_BLE_StoreBondingData
***************************************************************************//**
*
* This function writes the new bonding data from RAM to the dedicated flash
* location as defined by the PSoC 6 BLE Middleware. It performs a data comparison
* between RAM and flash before writing to flash. If there is no change between
* RAM and flash data, then no write is performed. It writes one flash row
* in one call.
* The application should keep calling this function until it returns
* #CY_BLE_SUCCESS. This function is available only when Bonding requirement
* is selected in Security settings.
*
* \return
* \ref cy_en_ble_api_result_t : Return value indicates whether the function
* succeeded or failed. Following are the possible error codes.
*
* Error Codes | Description
* ---------------------------------- | ------------------------------------
* CY_BLE_SUCCESS | On successful operation
* CY_BLE_INFO_FLASH_WRITE_IN_PROGRESS | Writing in progress
* CY_BLE_ERROR_FLASH_WRITE | Error in flash write
* CY_BLE_ERROR_FLASH_WRITE_NOT_PERMITED | Flash operation is not permitted (see Note)
*
* \note: Flash operation is not permitted with protection context (PC)
* value > 0 and core voltage 0.9V, because of a preproduction
* hardware limitation.
*
* \globalvars
* The \ref cy_ble_pendingFlashWrite variable is used to detect status
* of pending write to flash operation for BLE Stack data and CCCD.
* This function automatically clears pending bits after the write operation
* completes.
*
******************************************************************************/
cy_en_ble_api_result_t Cy_BLE_StoreBondingData(void)
{
cy_en_ble_api_result_t apiResult = CY_BLE_SUCCESS;
if(cy_ble_configPtr != NULL)
{
/* Store BLE Stack data */
if((cy_ble_pendingFlashWrite & CY_BLE_PENDING_STACK_FLASH_WRITE_BIT) != 0u)
{
cy_stc_ble_stack_flash_param_t stackFlashParam =
{
.bitField = CY_BLE_PERSISTENT_BOND_LIST_BITMASK |
CY_BLE_PERSISTENT_RPA_LIST_BITMASK |
CY_BLE_PERSISTENT_WHITELIST_BITMASK
};
apiResult = Cy_BLE_StoreStackData(&stackFlashParam);
if(apiResult == CY_BLE_SUCCESS)
{
cy_ble_pendingFlashWrite &= (uint8_t) ~CY_BLE_PENDING_STACK_FLASH_WRITE_BIT;
/* Change apiResult if there are more pending data to store */
if((cy_ble_pendingFlashWrite & CY_BLE_PENDING_CCCD_FLASH_WRITE_BIT) != 0u)
{
apiResult = CY_BLE_INFO_FLASH_WRITE_IN_PROGRESS;
}
}
}
/* Store CCCD values */
if( (apiResult == CY_BLE_SUCCESS) && (cy_ble_configPtr->flashStorage->cccdCount != 0u) &&
((cy_ble_pendingFlashWrite & CY_BLE_PENDING_CCCD_FLASH_WRITE_BIT) != 0u) )
{
uint32_t i;
cy_stc_ble_app_flash_param_t appFlashParam;
/* Update CCCD values from RAM for active connections supporting bonding */
for(i = 0u; i < cy_ble_configPtr->stackParam->maxConnCount; i++)
{
if((Cy_BLE_GetConnectionState(cy_ble_connHandle[i]) >= CY_BLE_CONN_STATE_CONNECTED) &&
(cy_ble_peerBonding[cy_ble_connHandle[i].attId] == CY_BLE_GAP_BONDING))
{
uint32_t cccdBlockSize = (uint32_t) cy_ble_configPtr->flashStorage->cccdCount + CY_BLE_CCCD_CRC_BYTE;
uint32_t cccdBlockCrcOffset = cccdBlockSize - CY_BLE_CCCD_CRC_BYTE;
uint32_t cccdBlockOffsetRam = cy_ble_connHandle[i].attId * cccdBlockSize;
uint32_t cccdBlockOffsetFlash = cy_ble_connHandle[i].bdHandle * cccdBlockSize;
uint8_t calcCrc;
appFlashParam.buffLen = (uint32_t) cy_ble_configPtr->flashStorage->cccdCount + CY_BLE_CCCD_CRC_BYTE;
appFlashParam.srcBuff = &cy_ble_configPtr->flashStorage->cccdRamPtr[cccdBlockOffsetRam];
appFlashParam.destAddr = &cy_ble_configPtr->flashStorage->cccdFlashPtr[cccdBlockOffsetFlash];
appFlashParam.writeMode = CY_BLE_STORE_DATA_MODE_BLOCKING;
/* Calculate CRC for CCCD block */
calcCrc = Cy_BLE_HAL_CalcCRC8(&cy_ble_configPtr->flashStorage->cccdRamPtr[cccdBlockOffsetRam],
cy_ble_configPtr->flashStorage->cccdCount);
/* Store new CRC value */
cy_ble_configPtr->flashStorage->cccdRamPtr[cccdBlockOffsetRam + cccdBlockCrcOffset] = calcCrc;
apiResult = Cy_BLE_StoreAppData(&appFlashParam);
if(apiResult != CY_BLE_SUCCESS)
{
break;
}
}
}
if(apiResult == CY_BLE_SUCCESS)
{
cy_ble_pendingFlashWrite &= (uint8_t) ~CY_BLE_PENDING_CCCD_FLASH_WRITE_BIT;
}
}
/* Clear requested CCCD values */
if( (apiResult == CY_BLE_SUCCESS) && (cy_ble_configPtr->flashStorage->cccdCount != 0u) &&
((cy_ble_pendingFlashWrite & CY_BLE_PENDING_CCCD_FLASH_CLEAR_MASK) != 0u) )
{
if((cy_ble_pendingFlashWrite & CY_BLE_PENDING_CCCD_FLASH_CLEAR_ALL_BIT) != 0u)
{
/* Remove CCCD values for all bonded devices */
uint32_t maxBond = (cy_ble_configPtr->stackParam->maxBondedDevListSize + cy_ble_configPtr->stackParam->maxConnCount);
uint32_t cccdBlockSizeAll = (cy_ble_configPtr->flashStorage->cccdCount + CY_BLE_CCCD_CRC_BYTE) * maxBond;
cy_stc_ble_app_flash_param_t appFlashParam;
appFlashParam.srcBuff = NULL;
appFlashParam.destAddr = (uint8_t*)cy_ble_configPtr->flashStorage->cccdFlashPtr;
appFlashParam.buffLen = cccdBlockSizeAll;
appFlashParam.writeMode = CY_BLE_STORE_DATA_MODE_BLOCKING;
apiResult = Cy_BLE_StoreAppData(&appFlashParam);
if(apiResult == CY_BLE_SUCCESS)
{
cy_ble_pendingFlashWrite &= (uint8_t) ~CY_BLE_PENDING_CCCD_FLASH_CLEAR_ALL_BIT;
}
}
else /* Remove CCCD values for particular device */
{
uint32_t cccdBlockSize = cy_ble_configPtr->flashStorage->cccdCount + CY_BLE_CCCD_CRC_BYTE;
cy_stc_ble_app_flash_param_t appFlashParam;
appFlashParam.srcBuff = NULL;
appFlashParam.destAddr = (uint8_t*)&cy_ble_configPtr->flashStorage->
cccdFlashPtr[cy_ble_pendingFlashClearCccdHandle * cccdBlockSize];
appFlashParam.buffLen = cccdBlockSize;
appFlashParam.writeMode = CY_BLE_STORE_DATA_MODE_BLOCKING;
apiResult = Cy_BLE_StoreAppData(&appFlashParam);
if(apiResult == CY_BLE_SUCCESS)
{
cy_ble_pendingFlashWrite &= (uint8_t) ~CY_BLE_PENDING_CCCD_FLASH_CLEAR_BIT;
}
}
}
/* Flash operation is not allowed */
if (apiResult == CY_BLE_ERROR_FLASH_WRITE_NOT_PERMITED)
{
cy_ble_pendingFlashWrite = 0u;
}
}
else
{
apiResult = CY_BLE_ERROR_INVALID_OPERATION;
}
return(apiResult);
}
/******************************************************************************
* Function Name: Cy_BLE_GAP_RemoveBondedDevice
***************************************************************************//**
*
* This function removes the bonding information of the device including CCCD
* values.
*
* This function is available only when Bonding requirement is selected in
* Security settings.
*
* \param bdAddr: Pointer to peer device address,
* of type \ref cy_stc_ble_gap_bd_addr_t.
*
* \return
* \ref cy_en_ble_api_result_t : Return value indicates whether the function
* succeeded or failed. The following are possible error codes.
*
* Error Codes | Description
* --------------------------------- | ------------------------------------
* CY_BLE_SUCCESS | On successful operation.
* CY_BLE_ERROR_INVALID_PARAMETER | On specifying NULL as input parameter. for 'bdAddr'.
* CY_BLE_ERROR_INVALID_OPERATION | Whitelist is already in use or there is pending write to flash operation.
* CY_BLE_ERROR_NO_DEVICE_ENTITY | Device does not exist in the bond list.
*
* \globalvars
* The bdHandle is set in \ref cy_ble_pendingFlashWrite variable to indicate that
* data should be stored to flash by Cy_BLE_StoreBondingData() afterwards.
*
******************************************************************************/
cy_en_ble_api_result_t Cy_BLE_GAP_RemoveBondedDevice(cy_stc_ble_gap_bd_addr_t* bdAddr)
{
cy_en_ble_api_result_t apiResult = CY_BLE_SUCCESS;
cy_stc_ble_gap_peer_addr_info_t peerAddrInfoParam;
if(bdAddr == NULL)
{
apiResult = CY_BLE_ERROR_INVALID_PARAMETER;
}
else if( (cy_ble_configPtr != NULL) && (cy_ble_pendingFlashWrite == 0u) )
{
if(cy_ble_configPtr->flashStorage->cccdCount != 0u)
{
/* Request to clear CCCD values which will be done by Cy_BLE_StoreBondingData() */
cy_stc_ble_gap_bd_addr_t invalidBdAddr = { { 0u, 0u, 0u, 0u, 0u, 0u }, 0u };
if(memcmp(((uint8_t*)&(bdAddr->bdAddr)), ((uint8_t*)&(invalidBdAddr.bdAddr)), CY_BLE_GAP_BD_ADDR_SIZE) == 0u)
{
/* Request to remove all bonded devices by Cy_BLE_StoreBondingData() */
cy_ble_pendingFlashWrite |= CY_BLE_PENDING_CCCD_FLASH_CLEAR_ALL_BIT;
}
else
{
/* Get the BD handle from Address */
peerAddrInfoParam.bdAddr = *bdAddr;
apiResult = Cy_BLE_GAP_GetPeerBdHandle(&peerAddrInfoParam);
if(apiResult == CY_BLE_SUCCESS)
{
/* Store BD handle to clear CCCD values by Cy_BLE_StoreBondingData() */
cy_ble_pendingFlashWrite |= CY_BLE_PENDING_CCCD_FLASH_CLEAR_BIT;
cy_ble_pendingFlashClearCccdHandle = peerAddrInfoParam.bdHandle;
}
}
}
if(apiResult == CY_BLE_SUCCESS)
{
apiResult = Cy_BLE_GAP_RemoveDeviceFromBondList(bdAddr);
}
}
else
{
apiResult = CY_BLE_ERROR_INVALID_OPERATION;
}
return(apiResult);
}
/******************************************************************************
* Function Name: Cy_BLE_GAPP_StartAdvertisement
***************************************************************************//**
*
* This function is used to start the advertisement using the advertisement data
* set in the BLE Component customizer's GUI indicated by the advertisingParamIndex.
* After invoking this function, the device will be available for connection by
* the devices configured for GAP central role. It is only included if the
* device is configured for GAP Peripheral or GAP Peripheral + Central role.
*
* On start of advertisement, GAP Peripheral receives the
* #CY_BLE_EVT_GAPP_ADVERTISEMENT_START_STOP event. The following events are
* possible on invoking this function:
*
* * #CY_BLE_EVT_GAP_DEVICE_CONNECTED - If the device connects to a GAP Central and
* Link Layer Privacy is disabled.
* * #CY_BLE_EVT_GAP_ENHANCE_CONN_COMPLETE - If the device connects to a GAP Central and
* Link Layer Privacy is enabled.
* * #CY_BLE_EVT_TIMEOUT: If no device in GAP Central mode connects to this
* device within the specified timeout limit. BLE Stack
* automatically initiate stop advertising when Slow
* advertising was initiated, or starts Slow advertising
* after Fast advertising timeout occur.
* * #CY_BLE_EVT_GAPP_ADVERTISEMENT_START_STOP: If device started or stopped
* advertising. Use Cy_BLE_GetAdvertisementState() to
* determine the state. Sequential advertising could be
* started when #CY_BLE_ADV_STATE_STOPPED state is returned.
*
* \param advertisingIntervalType: Fast or slow advertising interval with timings
* entered in Advertising settings section of the
* BT Configurator.
* * CY_BLE_ADVERTISING_FAST 0x00u
* * CY_BLE_ADVERTISING_SLOW 0x01u
* * CY_BLE_ADVERTISING_CUSTOM 0x02u
*
* \param advertisingParamIndex: The index of the peripheral and broadcast
* configuration in BT Configurator. For example:
* * CY_BLE_PERIPHERAL_CONFIGURATION_0_INDEX 0x00
* * CY_BLE_BROADCASTER_CONFIGURATION_0_INDEX 0x01
*
* \return
* \ref cy_en_ble_api_result_t : Return value indicates whether the function succeeded or
* failed. The following are possible error codes.
*
* Error Codes | Description
* --------------------------------- | --------------------------------
* CY_BLE_SUCCESS | On successful operation.
* CY_BLE_ERROR_INVALID_PARAMETER | On passing an invalid parameter.
* CY_BLE_ERROR_INVALID_STATE | On calling this function not in Stopped state.
* CY_BLE_ERROR_INVALID_OPERATION | The operation is not permitted due to connection
* | limit exceeded.
*
* \note
* #CY_BLE_EVT_GAPP_ADVERTISEMENT_START_STOP event is generated after calling
* Cy_BLE_GAPP_StartAdvertisement() and Cy_BLE_GAPP_StopAdvertisement() functions.
* Application should keep track of which function call resulted into this event
*
*******************************************************************************/
cy_en_ble_api_result_t Cy_BLE_GAPP_StartAdvertisement(uint8_t advertisingIntervalType,
uint8_t advertisingParamIndex)
{
cy_en_ble_api_result_t apiResult;
if(cy_ble_configPtr == NULL)
{
apiResult = CY_BLE_ERROR_INVALID_OPERATION;
}
else if((advertisingIntervalType > CY_BLE_ADVERTISING_CUSTOM) ||
(advertisingParamIndex >= cy_ble_configPtr->params->gappConfCount))
{
apiResult = CY_BLE_ERROR_INVALID_PARAMETER;
}
else if( ((cy_ble_configPtr->params->gapRole & CY_BLE_GAP_PERIPHERAL) != 0u) &&
(Cy_BLE_GetNumOfActiveConn() == cy_ble_configPtr->stackParam->maxConnCount) &&
((cy_ble_configPtr->discoveryModeInfo[advertisingParamIndex].advParam->advType <
CY_BLE_GAPP_SCANNABLE_UNDIRECTED_ADV) ||
(cy_ble_configPtr->discoveryModeInfo[advertisingParamIndex].advParam->advType >
CY_BLE_GAPP_NON_CONNECTABLE_UNDIRECTED_ADV)) )
{
apiResult = CY_BLE_ERROR_INVALID_OPERATION;
}
else if(Cy_BLE_GetAdvertisementState() == CY_BLE_ADV_STATE_STOPPED)
{
cy_ble_advIndex = advertisingParamIndex;
if(advertisingIntervalType == CY_BLE_ADVERTISING_FAST)
{
cy_ble_configPtr->discoveryModeInfo[advertisingParamIndex].advTo =
cy_ble_configPtr->gappAdvParams[advertisingParamIndex].fastAdvTimeOut;
cy_ble_configPtr->discoveryModeInfo[advertisingParamIndex].advParam->advIntvMin =
cy_ble_configPtr->gappAdvParams[advertisingParamIndex].fastAdvIntervalMin;
cy_ble_configPtr->discoveryModeInfo[advertisingParamIndex].advParam->advIntvMax =
cy_ble_configPtr->gappAdvParams[advertisingParamIndex].fastAdvIntervalMax;
}
else if(advertisingIntervalType == CY_BLE_ADVERTISING_SLOW)
{
cy_ble_configPtr->discoveryModeInfo[advertisingParamIndex].advTo =
cy_ble_configPtr->gappAdvParams[advertisingParamIndex].slowAdvTimeOut;
cy_ble_configPtr->discoveryModeInfo[advertisingParamIndex].advParam->advIntvMin =
cy_ble_configPtr->gappAdvParams[advertisingParamIndex].slowAdvIntervalMin;
cy_ble_configPtr->discoveryModeInfo[advertisingParamIndex].advParam->advIntvMax =
cy_ble_configPtr->gappAdvParams[advertisingParamIndex].slowAdvIntervalMax;
}
else /* Do not update advertising intervals */
{
}
cy_ble_advertisingIntervalType = advertisingIntervalType;
apiResult = Cy_BLE_GAPP_EnterDiscoveryMode(&cy_ble_configPtr->discoveryModeInfo[cy_ble_advIndex]);
if(apiResult == CY_BLE_SUCCESS)
{
Cy_BLE_SetAdvertisementState(CY_BLE_ADV_STATE_ADV_INITIATED);
}
}
else
{
apiResult = CY_BLE_ERROR_INVALID_STATE;
}
return(apiResult);
}
/******************************************************************************
* Function Name: Cy_BLE_GAPP_StopAdvertisement
***************************************************************************//**
*
* This function can be used to exit from discovery mode. After the execution
* of this function, there will no longer be any advertisements. On stopping
* advertising, GAP Peripheral receives #CY_BLE_EVT_GAPP_ADVERTISEMENT_START_STOP
* event.
*
* The following event occurs on invoking this function:
* * #CY_BLE_EVT_GAPP_ADVERTISEMENT_START_STOP
*
*
* \return
* \ref cy_en_ble_api_result_t : Return value indicates whether the function succeeded or
* failed. The following are possible error codes.
*
* Error Codes | Description
* ------------ | -----------
* CY_BLE_SUCCESS | On successful operation.
* CY_BLE_ERROR_MEMORY_ALLOCATION_FAILED | Memory allocation failed.
* CY_BLE_ERROR_INVALID_STATE | On calling this function not in Advertising state.
*
* \note
* #CY_BLE_EVT_GAPP_ADVERTISEMENT_START_STOP event is generated after calling
* Cy_BLE_GAPP_StartAdvertisement() and Cy_BLE_GAPP_StopAdvertisement() functions.
* Application should keep track of which function call resulted into this event.
*
*******************************************************************************/
cy_en_ble_api_result_t Cy_BLE_GAPP_StopAdvertisement(void)
{
cy_en_ble_api_result_t apiResult;
if(Cy_BLE_GetAdvertisementState() != CY_BLE_ADV_STATE_STOPPED)
{
apiResult = Cy_BLE_GAPP_ExitDiscoveryMode();
if(apiResult == CY_BLE_SUCCESS)
{
Cy_BLE_SetAdvertisementState(CY_BLE_ADV_STATE_STOP_INITIATED);
}
}
else
{
apiResult = CY_BLE_ERROR_INVALID_STATE;
}
return(apiResult);
}
/******************************************************************************
* Function Name: Cy_BLE_ChangeAdDeviceAddress
***************************************************************************//**
*
* This function is used to set the Bluetooth device address into the
* advertisement or scan response data structures.
*
* \param bdAddr: Bluetooth Device address. The variable is of type #cy_stc_ble_gap_bd_addr_t.
* \param dest: 0 - selects advertisement structure, not zero value selects scan
* response structure.
*
*******************************************************************************/
void Cy_BLE_ChangeAdDeviceAddress(const cy_stc_ble_gap_bd_addr_t* bdAddr,
uint8_t dest)
{
uint32_t fFlag;
uint32_t byteCounter;
uint32_t maxLength;
uint32_t advIndex = 0u;
uint8_t *destBuffer;
if(cy_ble_configPtr != NULL)
{
do
{
fFlag = 0u;
byteCounter = 0u;
if(dest == 0u) /* Destination - advertising structure */
{
destBuffer = cy_ble_configPtr->discoveryModeInfo[advIndex].advData->advData;
maxLength = cy_ble_configPtr->discoveryModeInfo[advIndex].advData->advDataLen;
}
else /* Destination - scan response structure */
{
destBuffer = cy_ble_configPtr->discoveryModeInfo[advIndex].scanRspData->scanRspData;
maxLength = cy_ble_configPtr->discoveryModeInfo[advIndex].scanRspData->scanRspDataLen;
}
while((byteCounter < maxLength) && (fFlag == 0u))
{
uint32_t adLength = destBuffer[byteCounter];
if(adLength != 0u)
{
/* Increment byte counter so it can point to AD type */
byteCounter++;
if(destBuffer[byteCounter] == CY_BLE_ADV_DEVICE_ADDR)
{
/* Start of the device address type was found. Set flag and exit the loop. */
fFlag = 1u;
}
else
{
byteCounter += adLength;
}
}
else
{
/* The end of advertisement data structure was encountered though exit the loop. */
break;
}
}
if(fFlag != 0u)
{
uint32_t i;
/* Increment byte counter so it can point to Device address */
byteCounter++;
/* Update Device Address type */
destBuffer[byteCounter] = bdAddr->type;
for(i = 0u; i < CY_BLE_GAP_BD_ADDR_SIZE; i++)
{
destBuffer[byteCounter + i + 1u] = bdAddr->bdAddr[i];
}
}
advIndex++;
}
while(advIndex < cy_ble_configPtr->params->gappConfCount);
}
}
/******************************************************************************
* Function Name: Cy_BLE_GAPC_StartScan
***************************************************************************//**
*
* This function is used for discovering GAP peripheral devices that are
* available for connection. It performs the scanning routine using the
* parameters entered in the Component's customizer indicated by
* scanParamIndex parameter.
*
* As soon as the discovery operation starts, #CY_BLE_EVT_GAPC_SCAN_START_STOP
* event is generated. The #CY_BLE_EVT_GAPC_SCAN_PROGRESS_RESULT event is
* generated when a GAP peripheral device is located. There are three discovery
* procedures can be selected in the customizer's GUI:
*
* * Observation procedure: A device performing the observer role receives only
* advertisement data from devices irrespective of
* their discoverable mode settings. Advertisement
* data received is provided by the event,
* #CY_BLE_EVT_GAPC_SCAN_PROGRESS_RESULT. This procedure
* requires the scanType sub parameter to be passive
* scanning.
*
* * Discovery procedure: A device performing the discovery procedure receives
* the advertisement data and scan response data from
* devices in both limited discoverable mode and the
* general discoverable mode. Received data is provided
* by the event, #CY_BLE_EVT_GAPC_SCAN_PROGRESS_RESULT.
* This procedure requires the scanType sub-parameter
* to be active scanning.
*
* Every Advertisement / Scan response packet is received in a new event,
* #CY_BLE_EVT_GAPC_SCAN_PROGRESS_RESULT.
* If 'scanTo' sub-parameter is a non-zero value, then upon commencement of
* discovery procedure and elapsed time = 'scanTo', #CY_BLE_EVT_TIMEOUT event
* is generated with the event parameter indicating #CY_BLE_GAP_SCAN_TO.
* Possible generated events are:
* * #CY_BLE_EVT_GAPC_SCAN_START_STOP: If a device started or stopped scanning.
* Use Cy_BLE_GetScanState() to determine the
* state. Sequential scanning could be
* started when #CY_BLE_ADV_STATE_STOPPED
* state is returned.
* * #CY_BLE_EVT_GAPC_SCAN_PROGRESS_RESULT
* * #CY_BLE_EVT_TIMEOUT (CY_BLE_GAP_SCAN_TO)
*
* \param scanningIntervalType: Fast or slow scanning interval with
* timings entered in Scan settings section of the customizer.
* * CY_BLE_SCANNING_FAST 0x00u
* * CY_BLE_SCANNING_SLOW 0x01u
* * CY_BLE_SCANNING_CUSTOM 0x02u
*
* \param scanParamIndex: The index of the central and scan configuration
* in customizer.
*
* \return
* \ref cy_en_ble_api_result_t : Return value indicates whether the function succeeded or
* failed. The following are possible error codes.
*
* Error Codes | Description
* ---------------------------------- | -----------------------------------
* CY_BLE_SUCCESS | On successful operation.
* CY_BLE_ERROR_INVALID_PARAMETER | On passing an invalid parameter.
* CY_BLE_ERROR_INVALID_STATE | On calling this function not in Stopped state.
* CY_BLE_ERROR_INVALID_OPERATION |
*******************************************************************************/
cy_en_ble_api_result_t Cy_BLE_GAPC_StartScan(uint8_t scanningIntervalType,
uint8_t scanParamIndex)
{
cy_en_ble_api_result_t apiResult;
if(scanningIntervalType > CY_BLE_SCANNING_CUSTOM)
{
apiResult = CY_BLE_ERROR_INVALID_PARAMETER;
}
else if((cy_ble_configPtr != NULL) && (Cy_BLE_GetScanState() == CY_BLE_SCAN_STATE_STOPPED))
{
cy_ble_scanIndex = scanParamIndex;
if(scanningIntervalType == CY_BLE_SCANNING_FAST)
{
cy_ble_configPtr->discoveryInfo[scanParamIndex].scanTo =
cy_ble_configPtr->gapcScanParams[scanParamIndex].fastScanTimeOut;
cy_ble_configPtr->discoveryInfo[scanParamIndex].scanIntv =
cy_ble_configPtr->gapcScanParams[scanParamIndex].fastScanInterval;
cy_ble_configPtr->discoveryInfo[scanParamIndex].scanWindow =
cy_ble_configPtr->gapcScanParams[scanParamIndex].fastScanWindow;
}
else if(scanningIntervalType == CY_BLE_SCANNING_SLOW)
{
cy_ble_configPtr->discoveryInfo[scanParamIndex].scanTo =
cy_ble_configPtr->gapcScanParams[scanParamIndex].slowScanTimeOut;
cy_ble_configPtr->discoveryInfo[scanParamIndex].scanIntv =
cy_ble_configPtr->gapcScanParams[scanParamIndex].slowScanInterval;
cy_ble_configPtr->discoveryInfo[scanParamIndex].scanWindow =
cy_ble_configPtr->gapcScanParams[scanParamIndex].slowScanWindow;
}
else /* Do not update scanning intervals */
{
}
cy_ble_scanningIntervalType = scanningIntervalType;
apiResult = Cy_BLE_GAPC_StartDiscovery(&cy_ble_configPtr->discoveryInfo[scanParamIndex]);
if(apiResult == CY_BLE_SUCCESS)
{
Cy_BLE_SetScanState(CY_BLE_SCAN_STATE_SCAN_INITIATED);
}
}
else
{
apiResult = CY_BLE_ERROR_INVALID_STATE;
}
return(apiResult);
}
/******************************************************************************
* Function Name: Cy_BLE_GAPC_StopScan
***************************************************************************//**
*
* This function used to stop the discovery of devices. On stopping discovery
* operation, #CY_BLE_EVT_GAPC_SCAN_START_STOP event is generated. Application
* layer needs to keep track of the function call made before receiving this
* event to associate this event with either the start or stop discovery
* function.
*
* Possible events generated are:
* * #CY_BLE_EVT_GAPC_SCAN_START_STOP
*
* \return
* \ref cy_en_ble_api_result_t : Return value indicates whether the function succeeded or
* failed. The following are possible error codes.
*
* Error Codes | Description
* ------------------------------------- | -----------------------------------
* CY_BLE_SUCCESS | On successful operation.
* CY_BLE_ERROR_MEMORY_ALLOCATION_FAILED | Memory allocation failed.
* CY_BLE_ERROR_INVALID_STATE | On calling this function not in Scanning state.
*
*******************************************************************************/
cy_en_ble_api_result_t Cy_BLE_GAPC_StopScan(void)
{
cy_en_ble_api_result_t apiResult;
if(Cy_BLE_GetScanState() == CY_BLE_SCAN_STATE_SCANNING)
{
apiResult = Cy_BLE_GAPC_StopDiscovery();
if(apiResult == CY_BLE_SUCCESS)
{
Cy_BLE_SetScanState(CY_BLE_SCAN_STATE_STOP_INITIATED);
}
}
else
{
apiResult = CY_BLE_ERROR_INVALID_STATE;
}
return(apiResult);
}