gapbondmgr.c 66 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219
  1. /**************************************************************************************************
  2. Phyplus Microelectronics Limited confidential and proprietary.
  3. All rights reserved.
  4. IMPORTANT: All rights of this software belong to Phyplus Microelectronics
  5. Limited ("Phyplus"). Your use of this Software is limited to those
  6. specific rights granted under the terms of the business contract, the
  7. confidential agreement, the non-disclosure agreement and any other forms
  8. of agreements as a customer or a partner of Phyplus. You may not use this
  9. Software unless you agree to abide by the terms of these agreements.
  10. You acknowledge that the Software may not be modified, copied,
  11. distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy
  12. (BLE) integrated circuit, either as a product or is integrated into your
  13. products. Other than for the aforementioned purposes, you may not use,
  14. reproduce, copy, prepare derivative works of, modify, distribute, perform,
  15. display or sell this Software and/or its documentation for any purposes.
  16. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  17. PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  18. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  19. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  20. PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT,
  21. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  22. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  23. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  24. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  25. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  26. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  27. **************************************************************************************************/
  28. /**************************************************************************************************
  29. Filename: gapbondmgr.c
  30. Revised:
  31. Revision:
  32. Description: GAP peripheral profile manages bonded connections
  33. **************************************************************************************************/
  34. #if ( HOST_CONFIG & ( CENTRAL_CFG | PERIPHERAL_CFG ) )
  35. /*********************************************************************
  36. * INCLUDES
  37. */
  38. #include "bcomdef.h"
  39. #include "OSAL.h"
  40. #include "osal_snv.h"
  41. #include "gap.h"
  42. #include "linkdb.h"
  43. #include "gatt.h"
  44. #include "gatt_uuid.h"
  45. #include "hci.h"
  46. #include "gattservapp.h"
  47. #include "gapgattserver.h"
  48. #include "gapbondmgr.h"
  49. // temp set
  50. //#define osal_snv_write( a, b, c ) (1)
  51. //#define osal_snv_read( a, b, c ) (1)
  52. //#define osal_snv_compact( a ) (1)
  53. /*********************************************************************
  54. * MACROS
  55. */
  56. /*********************************************************************
  57. * CONSTANTS
  58. */
  59. // Task event types
  60. #define GAP_BOND_SYNC_CC_EVT 0x0001 // Sync char config
  61. #define GAP_BOND_SAVE_REC_EVT 0x0002 // Save bond record in NV
  62. // Once NV usage reaches this percentage threshold, NV compaction gets triggered.
  63. #define NV_COMPACT_THRESHOLD 80
  64. // Bonded State Flags
  65. #define GAP_BONDED_STATE_AUTHENTICATED 0x0001
  66. #define GAP_BONDED_STATE_SERVICE_CHANGED 0x0002
  67. /**
  68. * GAP Bond Manager NV layout
  69. *
  70. * The NV definitions:
  71. * BLE_NVID_GAP_BOND_START - starting NV ID
  72. * GAP_BONDINGS_MAX - Maximum number of bonding allowed (10 is max for number of NV IDs allocated in bcomdef.h).
  73. *
  74. * A single bonding entry consists of 6 components (NV items):
  75. * Bond Record - defined as gapBondRec_t and uses GAP_BOND_REC_ID_OFFSET for an NV ID
  76. * local LTK Info - defined as gapBondLTK_t and uses GAP_BOND_LOCAL_LTK_OFFSET for an NV ID
  77. * device LTK Info - defined as gapBondLTK_t and uses GAP_BOND_DEV_LTK_OFFSET for an NV ID
  78. * device IRK - defined as "uint8 devIRK[KEYLEN]" and uses GAP_BOND_DEV_IRK_OFFSET for an NV ID
  79. * device CSRK - defined as "uint8 devCSRK[KEYLEN]" and uses GAP_BOND_DEV_CSRK_OFFSET for an NV ID
  80. * device Sign Counter - defined as a uint32 and uses GAP_BOND_DEV_SIGN_COUNTER_OFFSET for an NV ID
  81. *
  82. * When the device is initialized for the first time, all (GAP_BONDINGS_MAX) NV items are created and
  83. * initialized to all 0xFF's. A bonding record of all 0xFF's indicates that the bonding record is empty
  84. * and free to use.
  85. *
  86. * The calculation for each bonding records NV IDs:
  87. * mainRecordNvID = ((bondIdx * GAP_BOND_REC_IDS) + BLE_NVID_GAP_BOND_START)
  88. * localLTKNvID = (((bondIdx * GAP_BOND_REC_IDS) + GAP_BOND_LOCAL_LTK_OFFSET) + BLE_NVID_GAP_BOND_START)
  89. *
  90. */
  91. #define GAP_BOND_REC_ID_OFFSET 0 //!< NV ID for the main bonding record
  92. #define GAP_BOND_LOCAL_LTK_OFFSET 1 //!< NV ID for the bonding record's local LTK information
  93. #define GAP_BOND_DEV_LTK_OFFSET 2 //!< NV ID for the bonding records' device LTK information
  94. #define GAP_BOND_DEV_IRK_OFFSET 3 //!< NV ID for the bonding records' device IRK
  95. #define GAP_BOND_DEV_CSRK_OFFSET 4 //!< NV ID for the bonding records' device CSRK
  96. #define GAP_BOND_DEV_SIGN_COUNTER_OFFSET 5 //!< NV ID for the bonding records' device Sign Counter
  97. #define GAP_BOND_REC_IDS 6
  98. // Macros to calculate the index/offset in to NV space
  99. #define calcNvID(Idx, offset) (((((Idx) * GAP_BOND_REC_IDS) + (offset))) + BLE_NVID_GAP_BOND_START)
  100. #define mainRecordNvID(bondIdx) (calcNvID((bondIdx), GAP_BOND_REC_ID_OFFSET))
  101. #define localLTKNvID(bondIdx) (calcNvID((bondIdx), GAP_BOND_LOCAL_LTK_OFFSET))
  102. #define devLTKNvID(bondIdx) (calcNvID((bondIdx), GAP_BOND_DEV_LTK_OFFSET))
  103. #define devIRKNvID(bondIdx) (calcNvID((bondIdx), GAP_BOND_DEV_IRK_OFFSET))
  104. #define devCSRKNvID(bondIdx) (calcNvID((bondIdx), GAP_BOND_DEV_CSRK_OFFSET))
  105. #define devSignCounterNvID(bondIdx) (calcNvID((bondIdx), GAP_BOND_DEV_SIGN_COUNTER_OFFSET))
  106. // Macros to calculate the GATT index/offset in to NV space
  107. #define gattCfgNvID(Idx) ((Idx) + BLE_NVID_GATT_CFG_START)
  108. // Key Size Limits
  109. #define MIN_ENC_KEYSIZE 7 //!< Minimum number of bytes for the encryption key
  110. #define MAX_ENC_KEYSIZE 16 //!< Maximum number of bytes for the encryption key
  111. /*********************************************************************
  112. * TYPEDEFS
  113. */
  114. // Structure of NV data for the connected device's encryption information
  115. typedef struct
  116. {
  117. uint8 LTK[KEYLEN]; // Long Term Key (LTK)
  118. uint16 div; //lint -e754 // LTK eDiv
  119. uint8 rand[B_RANDOM_NUM_SIZE]; // LTK random number
  120. uint8 keySize; // LTK key size
  121. } gapBondLTK_t;
  122. // Structure of NV data for the connected device's address information
  123. typedef struct
  124. {
  125. uint8 publicAddr[B_ADDR_LEN]; // Master's address
  126. uint8 reconnectAddr[B_ADDR_LEN]; // Privacy Reconnection Address
  127. uint16 stateFlags; // State flags: SM_AUTH_STATE_AUTHENTICATED & SM_AUTH_STATE_BONDING
  128. } gapBondRec_t;
  129. // Structure of NV data for the connected device's characteristic configuration
  130. typedef struct
  131. {
  132. uint16 attrHandle; // attribute handle
  133. uint8 value; // attribute value for this device
  134. } gapBondCharCfg_t;
  135. /*********************************************************************
  136. * GLOBAL VARIABLES
  137. */
  138. /*********************************************************************
  139. * EXTERNAL VARIABLES
  140. */
  141. /*********************************************************************
  142. * EXTERNAL FUNCTIONS
  143. */
  144. /*********************************************************************
  145. * LOCAL VARIABLES
  146. */
  147. static uint8 gapBondMgr_TaskID = INVALID_TASK_ID; // Task ID for internal task/event processing
  148. // GAPBonding Parameters
  149. static uint8 gapBond_PairingMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
  150. static uint16 gapBond_InitiateWait = 1000; // Default to 1 second
  151. static uint8 gapBond_MITM = FALSE;
  152. static uint8 gapBond_IOCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
  153. static uint8 gapBond_OOBDataFlag = FALSE;
  154. static uint8 gapBond_OOBData[KEYLEN] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  155. static uint8 gapBond_Bonding = FALSE;
  156. static uint8 gapBond_AutoFail = FALSE;
  157. static uint8 gapBond_AutoFailReason = SMP_PAIRING_FAILED_NOT_SUPPORTED;
  158. static uint8 gapBond_KeyDistList =
  159. (
  160. GAPBOND_KEYDIST_SENCKEY // sEncKey enabled, to send the encryption key
  161. | GAPBOND_KEYDIST_SIDKEY // sIdKey enabled, to send the IRK, and BD_ADDR
  162. | GAPBOND_KEYDIST_SSIGN // sSign enabled, to send the CSRK
  163. | GAPBOND_KEYDIST_MENCKEY // mEncKey enabled, to get the master's encryption key
  164. | GAPBOND_KEYDIST_MIDKEY // mIdKey enabled, to get the master's IRK and BD_ADDR
  165. | GAPBOND_KEYDIST_MSIGN // mSign enabled, to get the master's CSRK
  166. );
  167. static uint32 gapBond_Passcode = 0;
  168. static uint8 gapBond_KeySize = MAX_ENC_KEYSIZE;
  169. #if ( HOST_CONFIG & CENTRAL_CFG )
  170. static uint8 gapBond_BondFailOption = GAPBOND_FAIL_TERMINATE_LINK;
  171. #endif
  172. static const gapBondCBs_t *pGapBondCB = NULL;
  173. // Local RAM shadowed bond records
  174. static gapBondRec_t bonds[GAP_BONDINGS_MAX] = {0};
  175. static uint8 autoSyncWhiteList = FALSE;
  176. static uint8 eraseAllBonds = FALSE;
  177. static uint8 bondsToDelete[GAP_BONDINGS_MAX] = {FALSE};
  178. // Globals used for saving bond record and CCC values in NV
  179. static uint8 bondIdx = GAP_BONDINGS_MAX;
  180. static gapAuthCompleteEvent_t *pAuthEvt = NULL;
  181. /*********************************************************************
  182. * LOCAL FUNCTIONS
  183. */
  184. static uint8 gapBondMgrChangeState( uint8 idx, uint16 state, uint8 set );
  185. static uint8 gapBondMgrUpdateCharCfg( uint8 idx, uint16 attrHandle, uint16 value );
  186. static gapBondCharCfg_t *gapBondMgrFindCharCfgItem( uint16 attrHandle,
  187. gapBondCharCfg_t *charCfgTbl );
  188. static void gapBondMgrInvertCharCfgItem( gapBondCharCfg_t *charCfgTbl );
  189. static uint8 gapBondMgrAddBond( gapBondRec_t *pBondRec, gapAuthCompleteEvent_t *pPkt );
  190. static uint8 gapBondMgrGetStateFlags( uint8 idx );
  191. static bStatus_t gapBondMgrGetPublicAddr( uint8 idx, uint8 *pAddr );
  192. static uint8 gapBondMgrFindReconnectAddr( uint8 *pReconnectAddr );
  193. static uint8 gapBondMgrFindAddr( uint8 *pDevAddr );
  194. static uint8 gapBondMgrResolvePrivateAddr( uint8 *pAddr );
  195. static void gapBondMgrReadBonds( void );
  196. static uint8 gapBondMgrFindEmpty( void );
  197. static uint8 gapBondMgrBondTotal( void );
  198. static bStatus_t gapBondMgrEraseAllBondings( void );
  199. static bStatus_t gapBondMgrEraseBonding( uint8 idx );
  200. static uint8 gapBondMgr_ProcessOSALMsg( osal_event_hdr_t *pMsg );
  201. static void gapBondMgrSendServiceChange( linkDBItem_t *pLinkItem );
  202. static void gapBondMgr_ProcessGATTMsg( gattMsgEvent_t *pMsg );
  203. static void gapBondMgr_ProcessGATTServMsg( gattEventHdr_t *pMsg );
  204. static void gapBondSetupPrivFlag( void );
  205. static void gapBondMgrBondReq( uint16 connHandle, uint8 idx, uint8 stateFlags,
  206. uint8 role, uint8 startEncryption );
  207. static void gapBondMgrAuthenticate( uint16 connHandle, uint8 addrType,
  208. gapPairingReq_t *pPairReq );
  209. static void gapBondMgr_SyncWhiteList( void );
  210. static uint8 gapBondMgr_SyncCharCfg( uint16 connHandle );
  211. static void gapBondFreeAuthEvt( void );
  212. #if ( HOST_CONFIG & PERIPHERAL_CFG )
  213. static void gapBondMgrSlaveSecurityReq( uint16 connHandle );
  214. #endif
  215. /*********************************************************************
  216. * NETWORK LAYER CALLBACKS
  217. */
  218. /*********************************************************************
  219. * PUBLIC FUNCTIONS
  220. */
  221. /*********************************************************************
  222. * @brief Set a GAP Bond Manager parameter.
  223. *
  224. * Public function defined in gapbondmgr.h.
  225. */
  226. bStatus_t GAPBondMgr_SetParameter( uint16 param, uint8 len, void *pValue )
  227. {
  228. bStatus_t ret = SUCCESS; // return value
  229. switch ( param )
  230. {
  231. case GAPBOND_PAIRING_MODE:
  232. if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= GAPBOND_PAIRING_MODE_INITIATE) )
  233. {
  234. gapBond_PairingMode = *((uint8*)pValue);
  235. }
  236. else
  237. {
  238. ret = bleInvalidRange;
  239. }
  240. break;
  241. case GAPBOND_INITIATE_WAIT:
  242. if ( len == sizeof ( uint16 ) )
  243. {
  244. gapBond_InitiateWait = *((uint16*)pValue);
  245. }
  246. else
  247. {
  248. ret = bleInvalidRange;
  249. }
  250. break;
  251. case GAPBOND_MITM_PROTECTION:
  252. if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= TRUE) )
  253. {
  254. gapBond_MITM = *((uint8*)pValue);
  255. }
  256. else
  257. {
  258. ret = bleInvalidRange;
  259. }
  260. break;
  261. case GAPBOND_IO_CAPABILITIES:
  262. if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= GAPBOND_IO_CAP_KEYBOARD_DISPLAY) )
  263. {
  264. gapBond_IOCap = *((uint8*)pValue);
  265. }
  266. else
  267. {
  268. ret = bleInvalidRange;
  269. }
  270. break;
  271. case GAPBOND_OOB_ENABLED:
  272. if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= TRUE) )
  273. {
  274. gapBond_OOBDataFlag = *((uint8*)pValue);
  275. }
  276. else
  277. {
  278. ret = bleInvalidRange;
  279. }
  280. break;
  281. case GAPBOND_OOB_DATA:
  282. if ( len == KEYLEN )
  283. {
  284. VOID osal_memcpy( gapBond_OOBData, pValue, KEYLEN ) ;
  285. }
  286. else
  287. {
  288. ret = bleInvalidRange;
  289. }
  290. break;
  291. case GAPBOND_BONDING_ENABLED:
  292. if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= TRUE) )
  293. {
  294. gapBond_Bonding = *((uint8*)pValue);
  295. }
  296. else
  297. {
  298. ret = bleInvalidRange;
  299. }
  300. break;
  301. case GAPBOND_KEY_DIST_LIST:
  302. if ( len == sizeof ( uint8 ) )
  303. {
  304. gapBond_KeyDistList = *((uint8*)pValue);
  305. }
  306. else
  307. {
  308. ret = bleInvalidRange;
  309. }
  310. break;
  311. case GAPBOND_DEFAULT_PASSCODE:
  312. if ( (len == sizeof ( uint32 ))
  313. && (*((uint32*)pValue) <= GAP_PASSCODE_MAX) )
  314. {
  315. gapBond_Passcode = *((uint32*)pValue);
  316. }
  317. else
  318. {
  319. ret = bleInvalidRange;
  320. }
  321. break;
  322. case GAPBOND_ERASE_ALLBONDS:
  323. if ( len == 0 )
  324. {
  325. // Make sure there's no active connection
  326. if ( GAP_NumActiveConnections() == 0 )
  327. {
  328. // Erase all bonding records
  329. VOID gapBondMgrEraseAllBondings();
  330. // See if NV needs a compaction
  331. VOID osal_snv_compact( NV_COMPACT_THRESHOLD );
  332. // Make sure Bond RAM Shadow is up-to-date
  333. gapBondMgrReadBonds();
  334. }
  335. else
  336. {
  337. eraseAllBonds = TRUE;
  338. }
  339. }
  340. else
  341. {
  342. ret = bleInvalidRange;
  343. }
  344. break;
  345. case GAPBOND_ERASE_SINGLEBOND:
  346. if ( len == (1 + B_ADDR_LEN) )
  347. {
  348. uint8 idx;
  349. uint8 devAddr[B_ADDR_LEN];
  350. // Reverse bytes
  351. VOID osal_revmemcpy( devAddr, (uint8 *)pValue+1, B_ADDR_LEN );
  352. // Resolve address and find index
  353. idx = GAPBondMgr_ResolveAddr( *((uint8 *)pValue), devAddr, NULL );
  354. if ( idx < GAP_BONDINGS_MAX )
  355. {
  356. // Make sure there's no active connection
  357. if ( GAP_NumActiveConnections() == 0 )
  358. {
  359. // Erase bond
  360. VOID gapBondMgrEraseBonding( idx );
  361. // See if NV needs a compaction
  362. VOID osal_snv_compact( NV_COMPACT_THRESHOLD );
  363. // Make sure Bond RAM Shadow is up-to-date
  364. gapBondMgrReadBonds();
  365. }
  366. else
  367. {
  368. // Mark entry to be deleted when disconnected
  369. bondsToDelete[idx] = TRUE;
  370. }
  371. }
  372. else
  373. {
  374. ret = INVALIDPARAMETER;
  375. }
  376. }
  377. else
  378. {
  379. // Parameter is not the correct length
  380. ret = bleInvalidRange;
  381. }
  382. break;
  383. case GAPBOND_AUTO_FAIL_PAIRING:
  384. if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= TRUE) )
  385. {
  386. gapBond_AutoFail = *((uint8*)pValue);
  387. }
  388. else
  389. {
  390. ret = bleInvalidRange;
  391. }
  392. break;
  393. case GAPBOND_AUTO_FAIL_REASON:
  394. if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= SMP_PAIRING_FAILED_REPEATED_ATTEMPTS) )
  395. {
  396. gapBond_AutoFailReason = *((uint8*)pValue);
  397. }
  398. else
  399. {
  400. ret = bleInvalidRange;
  401. }
  402. break;
  403. case GAPBOND_KEYSIZE:
  404. if ( (len == sizeof ( uint8 ))
  405. && ((*((uint8*)pValue) >= MIN_ENC_KEYSIZE) && (*((uint8*)pValue) <= MAX_ENC_KEYSIZE)) )
  406. {
  407. gapBond_KeySize = *((uint8*)pValue);
  408. }
  409. else
  410. {
  411. ret = bleInvalidRange;
  412. }
  413. break;
  414. case GAPBOND_AUTO_SYNC_WL:
  415. if ( len == sizeof( uint8 ) )
  416. {
  417. uint8 oldVal = autoSyncWhiteList;
  418. autoSyncWhiteList = *((uint8 *)pValue);
  419. // only call if parameter changes from FALSE to TRUE
  420. if ( ( oldVal == FALSE ) && ( autoSyncWhiteList == TRUE ) )
  421. {
  422. // make sure bond is updated from NV
  423. gapBondMgrReadBonds();
  424. }
  425. }
  426. else
  427. {
  428. ret = bleInvalidRange;
  429. }
  430. break;
  431. #if ( HOST_CONFIG & CENTRAL_CFG )
  432. case GAPBOND_BOND_FAIL_ACTION:
  433. if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= GAPBOND_FAIL_TERMINATE_ERASE_BONDS) )
  434. {
  435. gapBond_BondFailOption = *((uint8*)pValue);
  436. }
  437. else
  438. {
  439. ret = bleInvalidRange;
  440. }
  441. break;
  442. #endif
  443. default:
  444. // The param value isn't part of this profile, try the GAP.
  445. if ( (param < TGAP_PARAMID_MAX) && (len == sizeof ( uint16 )) )
  446. {
  447. ret = GAP_SetParamValue( param, *((uint16*)pValue) );
  448. }
  449. else
  450. {
  451. ret = INVALIDPARAMETER;
  452. }
  453. break;
  454. }
  455. return ( ret );
  456. }
  457. /*********************************************************************
  458. * @brief Get a GAP Bond Manager parameter.
  459. *
  460. * Public function defined in gapbondmgr.h.
  461. */
  462. bStatus_t GAPBondMgr_GetParameter( uint16 param, void *pValue )
  463. {
  464. bStatus_t ret = SUCCESS; // return value
  465. switch ( param )
  466. {
  467. case GAPBOND_PAIRING_MODE:
  468. *((uint8*)pValue) = gapBond_PairingMode;
  469. break;
  470. case GAPBOND_INITIATE_WAIT:
  471. *((uint16*)pValue) = gapBond_InitiateWait;
  472. break;
  473. case GAPBOND_MITM_PROTECTION:
  474. *((uint8*)pValue) = gapBond_MITM;
  475. break;
  476. case GAPBOND_IO_CAPABILITIES:
  477. *((uint8*)pValue) = gapBond_IOCap;
  478. break;
  479. case GAPBOND_OOB_ENABLED:
  480. *((uint8*)pValue) = gapBond_OOBDataFlag;
  481. break;
  482. case GAPBOND_OOB_DATA:
  483. VOID osal_memcpy( pValue, gapBond_OOBData, KEYLEN ) ;
  484. break;
  485. case GAPBOND_BONDING_ENABLED:
  486. *((uint8*)pValue) = gapBond_Bonding;
  487. break;
  488. case GAPBOND_KEY_DIST_LIST:
  489. *((uint8*)pValue) = gapBond_KeyDistList;
  490. break;
  491. case GAPBOND_DEFAULT_PASSCODE:
  492. *((uint32*)pValue) = gapBond_Passcode;
  493. break;
  494. case GAPBOND_AUTO_FAIL_PAIRING:
  495. *((uint8*)pValue) = gapBond_AutoFail;
  496. break;
  497. case GAPBOND_AUTO_FAIL_REASON:
  498. *((uint8*)pValue) = gapBond_AutoFailReason;
  499. break;
  500. case GAPBOND_KEYSIZE:
  501. *((uint8*)pValue) = gapBond_KeySize;
  502. break;
  503. case GAPBOND_AUTO_SYNC_WL:
  504. *((uint8*)pValue) = autoSyncWhiteList;
  505. break;
  506. case GAPBOND_BOND_COUNT:
  507. *((uint8*)pValue) = gapBondMgrBondTotal();
  508. break;
  509. default:
  510. // The param value isn't part of this profile, try the GAP.
  511. if ( param < TGAP_PARAMID_MAX )
  512. {
  513. *((uint16*)pValue) = GAP_GetParamValue( param );
  514. }
  515. else
  516. {
  517. ret = INVALIDPARAMETER;
  518. }
  519. break;
  520. }
  521. return ( ret );
  522. }
  523. /*********************************************************************
  524. * @brief Notify the Bond Manager that a connection has been made.
  525. *
  526. * Public function defined in gapbondmgr.h.
  527. */
  528. bStatus_t GAPBondMgr_LinkEst( uint8 addrType, uint8 *pDevAddr, uint16 connHandle, uint8 role )
  529. {
  530. uint8 idx; // NV Index
  531. uint8 publicAddr[B_ADDR_LEN] // Place to put the public address
  532. = {0, 0, 0, 0, 0, 0};
  533. idx = GAPBondMgr_ResolveAddr( addrType, pDevAddr, publicAddr );
  534. if ( idx < GAP_BONDINGS_MAX )
  535. {
  536. uint8 stateFlags = gapBondMgrGetStateFlags( idx );
  537. smSigningInfo_t signingInfo;
  538. gapBondCharCfg_t charCfg[GAP_CHAR_CFG_MAX]; // Space to read a char cfg record from NV
  539. // On peripheral, load the key information for the bonding
  540. // On central and initiaiting security, load key to initiate encyption
  541. gapBondMgrBondReq( connHandle, idx, stateFlags, role,
  542. ((gapBond_PairingMode == GAPBOND_PAIRING_MODE_INITIATE ) ? TRUE : FALSE) );
  543. // Load the Signing Key
  544. VOID osal_memset( &signingInfo, 0, sizeof ( smSigningInfo_t ) );
  545. if ( osal_snv_read( devCSRKNvID(idx), KEYLEN, signingInfo.srk ) == SUCCESS )
  546. {
  547. if ( osal_isbufset( signingInfo.srk, 0xFF, KEYLEN ) == FALSE )
  548. {
  549. // Load the signing information for this connection
  550. VOID osal_snv_read( devSignCounterNvID(idx), sizeof ( uint32 ), &(signingInfo.signCounter) );
  551. VOID GAP_Signable( connHandle,
  552. ((stateFlags & GAP_BONDED_STATE_AUTHENTICATED) ? TRUE : FALSE),
  553. &signingInfo );
  554. }
  555. }
  556. // Load the characteristic configuration
  557. if ( osal_snv_read( gattCfgNvID(idx), sizeof ( charCfg ), charCfg ) == SUCCESS )
  558. {
  559. gapBondMgrInvertCharCfgItem( charCfg );
  560. for ( uint8 i = 0; i < GAP_CHAR_CFG_MAX; i++ )
  561. {
  562. gapBondCharCfg_t *pItem = &(charCfg[i]);
  563. // Apply the characteristic configuration for this connection
  564. if ( pItem->attrHandle != GATT_INVALID_HANDLE )
  565. {
  566. VOID GATTServApp_UpdateCharCfg( connHandle, pItem->attrHandle,
  567. (uint16)(pItem->value) );
  568. }
  569. }
  570. }
  571. // Has there been a service change?
  572. if ( stateFlags & GAP_BONDED_STATE_SERVICE_CHANGED )
  573. {
  574. VOID GATTServApp_SendServiceChangedInd( connHandle, gapBondMgr_TaskID );
  575. }
  576. }
  577. #if ( HOST_CONFIG & CENTRAL_CFG )
  578. else if ( role == GAP_PROFILE_CENTRAL &&
  579. gapBond_PairingMode == GAPBOND_PAIRING_MODE_INITIATE )
  580. {
  581. // If Central and initiating and not bonded, then initiate pairing
  582. gapBondMgrAuthenticate( connHandle, addrType, NULL );
  583. // Call app state callback
  584. if ( pGapBondCB && pGapBondCB->pairStateCB )
  585. {
  586. pGapBondCB->pairStateCB( connHandle, GAPBOND_PAIRING_STATE_STARTED, SUCCESS );
  587. }
  588. }
  589. #endif
  590. #if ( HOST_CONFIG & PERIPHERAL_CFG )
  591. // If Peripheral and initiating, send a slave security request to
  592. // initiate either pairing or encryption
  593. if ( role == GAP_PROFILE_PERIPHERAL &&
  594. gapBond_PairingMode == GAPBOND_PAIRING_MODE_INITIATE )
  595. {
  596. gapBondMgrSlaveSecurityReq( connHandle );
  597. }
  598. #endif
  599. return ( SUCCESS );
  600. }
  601. /*********************************************************************
  602. * @brief Resolve an address from bonding information.
  603. *
  604. * Public function defined in gapbondmgr.h.
  605. */
  606. uint8 GAPBondMgr_ResolveAddr( uint8 addrType, uint8 *pDevAddr, uint8 *pResolvedAddr )
  607. {
  608. uint8 idx = GAP_BONDINGS_MAX;
  609. switch ( addrType )
  610. {
  611. case ADDRTYPE_PUBLIC:
  612. case ADDRTYPE_STATIC:
  613. idx = gapBondMgrFindAddr( pDevAddr );
  614. if ( (idx < GAP_BONDINGS_MAX) && (pResolvedAddr) )
  615. {
  616. VOID osal_memcpy( pResolvedAddr, pDevAddr, B_ADDR_LEN );
  617. }
  618. break;
  619. case ADDRTYPE_PRIVATE_NONRESOLVE:
  620. // This could be a reconnection address
  621. idx = gapBondMgrFindReconnectAddr( pDevAddr );
  622. if ( (idx < GAP_BONDINGS_MAX) && (pResolvedAddr) )
  623. {
  624. VOID gapBondMgrGetPublicAddr( idx, pResolvedAddr );
  625. }
  626. break;
  627. case ADDRTYPE_PRIVATE_RESOLVE:
  628. // Master's don't use Private Resolvable addresses but just in case
  629. idx = gapBondMgrResolvePrivateAddr( pDevAddr );
  630. if ( (idx < GAP_BONDINGS_MAX) && (pResolvedAddr) )
  631. {
  632. VOID gapBondMgrGetPublicAddr( idx, pResolvedAddr );
  633. }
  634. break;
  635. default:
  636. break;
  637. }
  638. return ( idx );
  639. }
  640. /*********************************************************************
  641. * @brief Set/clear the service change indication in a bond record.
  642. *
  643. * Public function defined in gapbondmgr.h.
  644. */
  645. bStatus_t GAPBondMgr_ServiceChangeInd( uint16 connectionHandle, uint8 setParam )
  646. {
  647. bStatus_t ret = bleNoResources; // return value
  648. if ( connectionHandle == 0xFFFF )
  649. {
  650. uint8 idx; // loop counter
  651. // Run through the bond database and update the Service Change indication
  652. for ( idx = 0; idx < GAP_BONDINGS_MAX; idx++ )
  653. {
  654. if ( gapBondMgrChangeState( idx, GAP_BONDED_STATE_SERVICE_CHANGED, setParam ) )
  655. {
  656. ret = SUCCESS;
  657. }
  658. }
  659. // If the service change indication is TRUE, tell the connected devices
  660. if ( setParam )
  661. {
  662. // Run connected database
  663. linkDB_PerformFunc( gapBondMgrSendServiceChange );
  664. }
  665. }
  666. else
  667. {
  668. // Find connection information
  669. linkDBItem_t *pLinkItem = linkDB_Find( connectionHandle );
  670. if ( pLinkItem )
  671. {
  672. uint8 idx; // loop counter
  673. idx = GAPBondMgr_ResolveAddr( pLinkItem->addrType, pLinkItem->addr, NULL );
  674. if ( idx < GAP_BONDINGS_MAX )
  675. {
  676. // Bond found, update it.
  677. VOID gapBondMgrChangeState( idx, GAP_BONDED_STATE_SERVICE_CHANGED, setParam );
  678. ret = SUCCESS;
  679. }
  680. // If the service change indication is TRUE, tell the connected device
  681. if ( setParam )
  682. {
  683. gapBondMgrSendServiceChange( pLinkItem );
  684. }
  685. }
  686. else
  687. {
  688. ret = bleNotConnected;
  689. }
  690. }
  691. return ( ret );
  692. }
  693. /*********************************************************************
  694. * @brief Update the Characteristic Configuration in a bond record.
  695. *
  696. * Public function defined in gapbondmgr.h.
  697. */
  698. bStatus_t GAPBondMgr_UpdateCharCfg( uint16 connectionHandle, uint16 attrHandle, uint16 value )
  699. {
  700. bStatus_t ret = bleNoResources; // return value
  701. if ( connectionHandle == INVALID_CONNHANDLE )
  702. {
  703. uint8 idx; // loop counter
  704. // Run through the bond database and update the Characteristic Configuration
  705. for ( idx = 0; idx < GAP_BONDINGS_MAX; idx++ )
  706. {
  707. if ( gapBondMgrUpdateCharCfg( idx, attrHandle, value ) )
  708. {
  709. ret = SUCCESS;
  710. }
  711. }
  712. }
  713. else
  714. {
  715. // Find connection information
  716. linkDBItem_t *pLinkItem = linkDB_Find( connectionHandle );
  717. if ( pLinkItem )
  718. {
  719. uint8 idx = GAPBondMgr_ResolveAddr( pLinkItem->addrType, pLinkItem->addr, NULL );
  720. if ( idx < GAP_BONDINGS_MAX )
  721. {
  722. // Bond found, update it.
  723. VOID gapBondMgrUpdateCharCfg( idx, attrHandle, value );
  724. ret = SUCCESS;
  725. }
  726. }
  727. else
  728. {
  729. ret = bleNotConnected;
  730. }
  731. }
  732. return ( ret );
  733. }
  734. /*********************************************************************
  735. * @brief Register callback functions with the bond manager.
  736. *
  737. * Public function defined in gapbondmgr.h.
  738. */
  739. void GAPBondMgr_Register( gapBondCBs_t *pCB )
  740. {
  741. pGapBondCB = pCB;
  742. if(gapBondMgr_TaskID != INVALID_TASK_ID)
  743. {
  744. // Take over the processing of Authentication messages
  745. VOID GAP_SetParamValue( TGAP_AUTH_TASK_ID, gapBondMgr_TaskID );
  746. // Register with GATT Server App for event messages
  747. GATTServApp_RegisterForMsg( gapBondMgr_TaskID );
  748. }
  749. }
  750. /*********************************************************************
  751. * @brief Respond to a passcode request.
  752. *
  753. * Public function defined in gapbondmgr.h.
  754. */
  755. bStatus_t GAPBondMgr_PasscodeRsp( uint16 connectionHandle, uint8 status, uint32 passcode )
  756. {
  757. bStatus_t ret = SUCCESS;
  758. if ( status == SUCCESS )
  759. {
  760. // Truncate the passcode
  761. passcode = passcode % (GAP_PASSCODE_MAX + 1);
  762. ret = GAP_PasscodeUpdate( passcode, connectionHandle );
  763. if ( ret != SUCCESS )
  764. {
  765. VOID GAP_TerminateAuth( connectionHandle, SMP_PAIRING_FAILED_PASSKEY_ENTRY_FAILED );
  766. }
  767. }
  768. else
  769. {
  770. VOID GAP_TerminateAuth( connectionHandle, status );
  771. }
  772. return ret;
  773. }
  774. /*********************************************************************
  775. * @brief This is a bypass mechanism to allow the bond manager to process
  776. * GAP messages.
  777. *
  778. * Public function defined in gapbondmgr.h.
  779. */
  780. uint8 GAPBondMgr_ProcessGAPMsg( gapEventHdr_t *pMsg )
  781. {
  782. switch ( pMsg->opcode )
  783. {
  784. case GAP_PASSKEY_NEEDED_EVENT:
  785. {
  786. gapPasskeyNeededEvent_t *pPkt = (gapPasskeyNeededEvent_t *)pMsg;
  787. if ( pGapBondCB && pGapBondCB->passcodeCB )
  788. {
  789. // Ask app for a passcode
  790. pGapBondCB->passcodeCB( pPkt->deviceAddr, pPkt->connectionHandle, pPkt->uiInputs, pPkt->uiOutputs );
  791. }
  792. else
  793. {
  794. // No app support, use the default passcode
  795. if ( GAP_PasscodeUpdate( gapBond_Passcode, pPkt->connectionHandle ) != SUCCESS )
  796. {
  797. VOID GAP_TerminateAuth( pPkt->connectionHandle, SMP_PAIRING_FAILED_PASSKEY_ENTRY_FAILED );
  798. }
  799. }
  800. }
  801. break;
  802. case GAP_AUTHENTICATION_COMPLETE_EVENT:
  803. {
  804. gapAuthCompleteEvent_t *pPkt = (gapAuthCompleteEvent_t *)pMsg;
  805. // Should we save bonding information (one save at a time)
  806. if ( (pPkt->hdr.status == SUCCESS) &&
  807. (pPkt->authState & SM_AUTH_STATE_BONDING) &&
  808. (pAuthEvt == NULL) )
  809. {
  810. gapBondRec_t bondRec;
  811. VOID osal_memset( &bondRec, 0, sizeof ( gapBondRec_t ) ) ;
  812. // Do we have a public address in the data?
  813. if ( pPkt->pIdentityInfo )
  814. {
  815. VOID osal_memcpy( bondRec.publicAddr, pPkt->pIdentityInfo->bd_addr, B_ADDR_LEN );
  816. }
  817. else
  818. {
  819. linkDBItem_t *pLinkItem = linkDB_Find( pPkt->connectionHandle );
  820. if ( pLinkItem )
  821. {
  822. VOID osal_memcpy( bondRec.publicAddr, pLinkItem->addr, B_ADDR_LEN );
  823. }
  824. else
  825. {
  826. // We don't have an address, so ignore the message.
  827. break;
  828. }
  829. }
  830. // Save off of the authentication state
  831. bondRec.stateFlags |= (pPkt->authState & SM_AUTH_STATE_AUTHENTICATED) ? GAP_BONDED_STATE_AUTHENTICATED : 0;
  832. if ( !gapBondMgrAddBond( &bondRec, pPkt ) )
  833. {
  834. // Notify our task to save bonding information in NV
  835. osal_set_event( gapBondMgr_TaskID, GAP_BOND_SAVE_REC_EVT );
  836. // We're not done with this message; it will be freed later
  837. return ( FALSE );
  838. }
  839. }
  840. // Call app state callback in the fail case. Success is handled after GAP_BOND_SAVE_REC_EVT.
  841. if ( pGapBondCB && pGapBondCB->pairStateCB )
  842. {
  843. pGapBondCB->pairStateCB( pPkt->connectionHandle, GAPBOND_PAIRING_STATE_COMPLETE, pPkt->hdr.status );
  844. }
  845. }
  846. break;
  847. case GAP_BOND_COMPLETE_EVENT:
  848. // This message is received when the bonding is complete. If hdr.status is SUCCESS
  849. // then call app state callback. If hdr.status is NOT SUCCESS, the connection will be
  850. // dropped at the LL because of a MIC failure, so again nothing to do.
  851. {
  852. gapBondCompleteEvent_t *pPkt = (gapBondCompleteEvent_t *)pMsg;
  853. #if ( HOST_CONFIG & CENTRAL_CFG )
  854. if ( pPkt->hdr.status == LL_ENC_KEY_REQ_REJECTED )
  855. {
  856. // LTK not found on peripheral device (Pin or Key Missing). See which
  857. // option was configured for unsuccessful bonding.
  858. linkDBItem_t *pLinkItem = linkDB_Find( pPkt->connectionHandle );
  859. if ( pLinkItem )
  860. {
  861. switch ( gapBond_BondFailOption )
  862. {
  863. case GAPBOND_FAIL_INITIATE_PAIRING:
  864. // Initiate pairing
  865. gapBondMgrAuthenticate( pPkt->connectionHandle, pLinkItem->addrType, NULL );
  866. break;
  867. case GAPBOND_FAIL_TERMINATE_LINK:
  868. // Drop connection
  869. GAP_TerminateLinkReq( pLinkItem->taskID, pPkt->connectionHandle, HCI_DISCONNECT_AUTH_FAILURE );
  870. break;
  871. case GAPBOND_FAIL_TERMINATE_ERASE_BONDS:
  872. // Set up bond manager to erase all existing bonds after connection terminates
  873. VOID GAPBondMgr_SetParameter( GAPBOND_ERASE_ALLBONDS, 0, NULL );
  874. // Drop connection
  875. GAP_TerminateLinkReq( pLinkItem->taskID, pPkt->connectionHandle, HCI_DISCONNECT_AUTH_FAILURE );
  876. break;
  877. case GAPBOND_FAIL_NO_ACTION:
  878. // fall through
  879. default:
  880. // do nothing
  881. break;
  882. }
  883. }
  884. }
  885. #endif
  886. if ( pGapBondCB && pGapBondCB->pairStateCB )
  887. {
  888. pGapBondCB->pairStateCB( pPkt->connectionHandle, GAPBOND_PAIRING_STATE_BONDED, pMsg->hdr.status );
  889. }
  890. }
  891. break;
  892. case GAP_SIGNATURE_UPDATED_EVENT:
  893. {
  894. uint8 idx;
  895. gapSignUpdateEvent_t *pPkt = (gapSignUpdateEvent_t *)pMsg;
  896. idx = GAPBondMgr_ResolveAddr( pPkt->addrType, pPkt->devAddr, NULL );
  897. if ( idx < GAP_BONDINGS_MAX )
  898. {
  899. // Save the sign counter
  900. VOID osal_snv_write( devSignCounterNvID(idx), sizeof ( uint32 ), &(pPkt->signCounter) );
  901. }
  902. }
  903. break;
  904. #if ( HOST_CONFIG & PERIPHERAL_CFG )
  905. case GAP_PAIRING_REQ_EVENT:
  906. {
  907. gapPairingReqEvent_t *pPkt = (gapPairingReqEvent_t *)pMsg;
  908. if ( gapBond_AutoFail != FALSE )
  909. {
  910. // Auto Fail TEST MODE (DON'T USE THIS) - Sends pre-setup reason
  911. VOID GAP_TerminateAuth( pPkt->connectionHandle, gapBond_AutoFailReason );
  912. }
  913. else if ( gapBond_PairingMode == GAPBOND_PAIRING_MODE_NO_PAIRING )
  914. {
  915. // No Pairing - Send error
  916. VOID GAP_TerminateAuth( pPkt->connectionHandle, SMP_PAIRING_FAILED_NOT_SUPPORTED );
  917. }
  918. else
  919. {
  920. linkDBItem_t *pLinkItem = linkDB_Find( pPkt->connectionHandle );
  921. // Requesting bonding?
  922. if ( pPkt->pairReq.authReq & SM_AUTH_STATE_BONDING )
  923. {
  924. if ( pLinkItem )
  925. {
  926. if ( (pLinkItem->addrType != ADDRTYPE_PUBLIC) && (pPkt->pairReq.keyDist.mIdKey == FALSE) )
  927. {
  928. uint8 publicAddr[B_ADDR_LEN];
  929. // Check if we already have the public address in NV
  930. if ( GAPBondMgr_ResolveAddr(pLinkItem->addrType, pLinkItem->addr, publicAddr ) == FALSE )
  931. {
  932. // Can't bond to a non-public address if we don't know the public address
  933. VOID GAP_TerminateAuth( pPkt->connectionHandle, SMP_PAIRING_FAILED_AUTH_REQ );
  934. break;
  935. }
  936. }
  937. }
  938. else
  939. {
  940. // Can't find the connection, ignore the message
  941. break;
  942. }
  943. }
  944. // Send pairing response
  945. gapBondMgrAuthenticate( pPkt->connectionHandle, pLinkItem->addrType, &(pPkt->pairReq) );
  946. // Call app state callback
  947. if ( pGapBondCB && pGapBondCB->pairStateCB )
  948. {
  949. pGapBondCB->pairStateCB( pPkt->connectionHandle, GAPBOND_PAIRING_STATE_STARTED, SUCCESS );
  950. }
  951. }
  952. }
  953. break;
  954. #endif
  955. #if ( HOST_CONFIG & CENTRAL_CFG )
  956. case GAP_SLAVE_REQUESTED_SECURITY_EVENT:
  957. {
  958. uint16 connHandle = ((gapSlaveSecurityReqEvent_t *)pMsg)->connectionHandle;
  959. uint8 idx;
  960. uint8 publicAddr[B_ADDR_LEN] = {0, 0, 0, 0, 0, 0};
  961. linkDBItem_t *pLink = linkDB_Find( connHandle );
  962. // If link found and not already initiating security
  963. if (pLink != NULL && gapBond_PairingMode != GAPBOND_PAIRING_MODE_INITIATE)
  964. {
  965. // If already bonded initiate encryption
  966. idx = GAPBondMgr_ResolveAddr( pLink->addrType, pLink->addr, publicAddr );
  967. if ( idx < GAP_BONDINGS_MAX )
  968. {
  969. gapBondMgrBondReq( connHandle, idx, gapBondMgrGetStateFlags( idx ),
  970. GAP_PROFILE_CENTRAL, TRUE );
  971. }
  972. // Else if no pairing allowed
  973. else if ( gapBond_PairingMode == GAPBOND_PAIRING_MODE_NO_PAIRING )
  974. {
  975. // Send error
  976. VOID GAP_TerminateAuth( connHandle, SMP_PAIRING_FAILED_NOT_SUPPORTED );
  977. }
  978. // Else if waiting for request
  979. else if (gapBond_PairingMode == GAPBOND_PAIRING_MODE_WAIT_FOR_REQ)
  980. {
  981. // Initiate pairing
  982. gapBondMgrAuthenticate( connHandle, pLink->addrType, NULL );
  983. }
  984. }
  985. }
  986. break;
  987. #endif
  988. case GAP_LINK_TERMINATED_EVENT:
  989. if ( GAP_NumActiveConnections() == 0 )
  990. {
  991. // See if we're asked to erase all bonding records
  992. if ( eraseAllBonds == TRUE )
  993. {
  994. VOID gapBondMgrEraseAllBondings();
  995. eraseAllBonds = FALSE;
  996. // Reset bonds to delete table
  997. osal_memset( bondsToDelete, FALSE, sizeof( bondsToDelete ) );
  998. }
  999. else
  1000. {
  1001. // See if we're asked to erase any single bonding records
  1002. for (uint8 idx = 0; idx < GAP_BONDINGS_MAX; idx++)
  1003. {
  1004. if ( bondsToDelete[idx] == TRUE )
  1005. {
  1006. VOID gapBondMgrEraseBonding( idx );
  1007. bondsToDelete[idx] = FALSE;
  1008. }
  1009. }
  1010. }
  1011. // See if NV needs a compaction
  1012. VOID osal_snv_compact( NV_COMPACT_THRESHOLD );
  1013. // Make sure Bond RAM Shadow is up-to-date
  1014. gapBondMgrReadBonds();
  1015. }
  1016. break;
  1017. default:
  1018. break;
  1019. }
  1020. return ( TRUE );
  1021. }
  1022. /*********************************************************************
  1023. * LOCAL FUNCTION PROTOTYPES
  1024. */
  1025. /*********************************************************************
  1026. * @fn gapBondMgrChangeState
  1027. *
  1028. * @brief Change a state flag in the stateFlags field of the bond record.
  1029. *
  1030. * @param idx - Bond NV index
  1031. * @param state - state flage to set or clear
  1032. * @param set - TRUE to set the flag, FALSE to clear the flag
  1033. *
  1034. * @return TRUE if NV Record exists, FALSE if NV Record is empty
  1035. */
  1036. static uint8 gapBondMgrChangeState( uint8 idx, uint16 state, uint8 set )
  1037. {
  1038. gapBondRec_t bondRec; // Space to read a Bond record from NV
  1039. // Look for public address that is used (not all 0xFF's)
  1040. if ( (osal_snv_read( mainRecordNvID(idx), sizeof ( gapBondRec_t ), &bondRec ) == SUCCESS)
  1041. && (osal_isbufset( bondRec.publicAddr, 0xFF, B_ADDR_LEN ) == FALSE) )
  1042. {
  1043. // Update the state of the bonded device.
  1044. uint8 stateFlags = bondRec.stateFlags;
  1045. if ( set )
  1046. {
  1047. stateFlags |= state;
  1048. }
  1049. else
  1050. {
  1051. stateFlags &= ~(state);
  1052. }
  1053. if ( stateFlags != bondRec.stateFlags )
  1054. {
  1055. bondRec.stateFlags = stateFlags;
  1056. VOID osal_snv_write( mainRecordNvID(idx), sizeof ( gapBondRec_t ), &bondRec );
  1057. }
  1058. return ( TRUE );
  1059. }
  1060. return ( FALSE );
  1061. }
  1062. /*********************************************************************
  1063. * @fn gapBondMgrUpdateCharCfg
  1064. *
  1065. * @brief Update the Characteristic Configuration of the bond record.
  1066. *
  1067. * @param idx - Bond NV index
  1068. * @param attrHandle - attribute handle (0 means all handles)
  1069. * @param value - characteristic configuration value
  1070. *
  1071. * @return TRUE if NV Record exists, FALSE if NV Record is empty
  1072. */
  1073. static uint8 gapBondMgrUpdateCharCfg( uint8 idx, uint16 attrHandle, uint16 value )
  1074. {
  1075. gapBondRec_t bondRec; // Space to read a Bond record from NV
  1076. // Look for public address that is used (not all 0xFF's)
  1077. if ( ( osal_snv_read( mainRecordNvID(idx), sizeof ( gapBondRec_t ), &bondRec ) == SUCCESS )
  1078. && ( osal_isbufset( bondRec.publicAddr, 0xFF, B_ADDR_LEN ) == FALSE ) )
  1079. {
  1080. gapBondCharCfg_t charCfg[GAP_CHAR_CFG_MAX]; // Space to read a char cfg record from NV
  1081. if ( osal_snv_read( gattCfgNvID(idx), sizeof ( charCfg ), charCfg ) == SUCCESS )
  1082. {
  1083. uint8 update = FALSE;
  1084. gapBondMgrInvertCharCfgItem( charCfg );
  1085. if ( attrHandle == GATT_INVALID_HANDLE )
  1086. {
  1087. if ( osal_isbufset( (uint8 *)charCfg, 0x00, sizeof ( charCfg ) ) == FALSE )
  1088. {
  1089. // Clear all characteristic configuration for this device
  1090. VOID osal_memset( (void *)charCfg, 0x00, sizeof ( charCfg ) );
  1091. update = TRUE;
  1092. }
  1093. }
  1094. else
  1095. {
  1096. gapBondCharCfg_t *pItem = gapBondMgrFindCharCfgItem( attrHandle, charCfg );
  1097. if ( pItem == NULL )
  1098. {
  1099. // Must be a new item; ignore if the value is no operation (default)
  1100. if ( ( value == GATT_CFG_NO_OPERATION ) ||
  1101. ( ( pItem = gapBondMgrFindCharCfgItem( GATT_INVALID_HANDLE, charCfg ) ) == NULL ) )
  1102. {
  1103. return ( FALSE ); // No empty entry found
  1104. }
  1105. pItem->attrHandle = attrHandle;
  1106. }
  1107. if ( pItem->value != value )
  1108. {
  1109. // Update characteristic configuration
  1110. pItem->value = (uint8)value;
  1111. if ( value == GATT_CFG_NO_OPERATION )
  1112. {
  1113. // Erease the item
  1114. pItem->attrHandle = GATT_INVALID_HANDLE;
  1115. }
  1116. update = TRUE;
  1117. }
  1118. }
  1119. // Update the characteristic configuration of the bonded device.
  1120. if ( update )
  1121. {
  1122. gapBondMgrInvertCharCfgItem( charCfg );
  1123. VOID osal_snv_write( gattCfgNvID(idx), sizeof( charCfg ), charCfg );
  1124. }
  1125. }
  1126. return ( TRUE );
  1127. }
  1128. return ( FALSE );
  1129. }
  1130. /*********************************************************************
  1131. * @fn gapBondMgrFindCharCfgItem
  1132. *
  1133. * @brief Find the Characteristic Configuration for a given attribute.
  1134. * Uses the attribute handle to search the charactersitic
  1135. * configuration table of a bonded device.
  1136. *
  1137. * @param attrHandle - attribute handle.
  1138. * @param charCfgTbl - characteristic configuration table.
  1139. *
  1140. * @return pointer to the found item. NULL, otherwise.
  1141. */
  1142. static gapBondCharCfg_t *gapBondMgrFindCharCfgItem( uint16 attrHandle,
  1143. gapBondCharCfg_t *charCfgTbl )
  1144. {
  1145. for ( uint8 i = 0; i < GAP_CHAR_CFG_MAX; i++ )
  1146. {
  1147. if ( charCfgTbl[i].attrHandle == attrHandle )
  1148. {
  1149. return ( &(charCfgTbl[i]) );
  1150. }
  1151. }
  1152. return ( (gapBondCharCfg_t *)NULL );
  1153. }
  1154. /*********************************************************************
  1155. * @fn gapBondMgrFindCharCfgItem
  1156. *
  1157. * @brief Invert the Characteristic Configuration for a given client.
  1158. *
  1159. * @param charCfgTbl - characteristic configuration table.
  1160. *
  1161. * @return none.
  1162. */
  1163. static void gapBondMgrInvertCharCfgItem( gapBondCharCfg_t *charCfgTbl )
  1164. {
  1165. for ( uint8 i = 0; i < GAP_CHAR_CFG_MAX; i++ )
  1166. {
  1167. charCfgTbl[i].attrHandle = ~(charCfgTbl[i].attrHandle);
  1168. charCfgTbl[i].value = ~(charCfgTbl[i].value);
  1169. }
  1170. }
  1171. /*********************************************************************
  1172. * @fn gapBondMgrAddBond
  1173. *
  1174. * @brief Save a bond from a GAP Auth Complete Event
  1175. *
  1176. * @param pBondRec - basic bond record
  1177. * @param pLocalLTK - LTK used by this device during pairing
  1178. * @param pDevLTK - LTK used by the connected device during pairing
  1179. * @param pIRK - IRK used by the connected device during pairing
  1180. * @param pSRK - SRK used by the connected device during pairing
  1181. * @param signCounter - Sign counter used by the connected device during pairing
  1182. *
  1183. * @return TRUE, if done processing bond record. FALSE, otherwise.
  1184. */
  1185. static uint8 gapBondMgrAddBond( gapBondRec_t *pBondRec, gapAuthCompleteEvent_t *pPkt )
  1186. {
  1187. // See if this is a new bond record
  1188. if ( pAuthEvt == NULL )
  1189. {
  1190. // Make sure we have bonding info
  1191. if ( ( pBondRec == NULL ) || ( pPkt == NULL ) )
  1192. {
  1193. return ( TRUE );
  1194. }
  1195. // First see if we already have an existing bond for this device
  1196. bondIdx = gapBondMgrFindAddr( pBondRec->publicAddr );
  1197. if ( bondIdx >= GAP_BONDINGS_MAX )
  1198. {
  1199. bondIdx = gapBondMgrFindEmpty();
  1200. }
  1201. }
  1202. if ( bondIdx < GAP_BONDINGS_MAX )
  1203. {
  1204. // See if this is a new bond record
  1205. if ( pAuthEvt == NULL )
  1206. {
  1207. gapBondCharCfg_t charCfg[GAP_CHAR_CFG_MAX];
  1208. // Save the main information
  1209. VOID osal_snv_write( mainRecordNvID(bondIdx), sizeof ( gapBondRec_t ), pBondRec );
  1210. // Write out FF's over the charactersitic configuration entry, to overwrite
  1211. // any previous bond data that may have been stored
  1212. VOID osal_memset( charCfg, 0xFF, sizeof ( charCfg ) );
  1213. VOID osal_snv_write( gattCfgNvID(bondIdx), sizeof ( charCfg ), charCfg );
  1214. // Update Bond RAM Shadow just with the newly added bond entry
  1215. VOID osal_memcpy( &(bonds[bondIdx]), pBondRec, sizeof ( gapBondRec_t ) );
  1216. // Keep the OSAL message to store the security keys later - will be freed then
  1217. pAuthEvt = pPkt;
  1218. }
  1219. else
  1220. {
  1221. // If available, save the LTK information
  1222. if ( pAuthEvt->pSecurityInfo )
  1223. {
  1224. VOID osal_snv_write( localLTKNvID(bondIdx), sizeof ( gapBondLTK_t ), pAuthEvt->pSecurityInfo );
  1225. pAuthEvt->pSecurityInfo = NULL;
  1226. }
  1227. // If availabe, save the connected device's LTK information
  1228. else if ( pAuthEvt->pDevSecInfo )
  1229. {
  1230. VOID osal_snv_write( devLTKNvID(bondIdx), sizeof ( gapBondLTK_t ), pAuthEvt->pDevSecInfo );
  1231. pAuthEvt->pDevSecInfo = NULL;
  1232. }
  1233. // If available, save the connected device's IRK
  1234. else if ( pAuthEvt->pIdentityInfo )
  1235. {
  1236. VOID osal_snv_write( devIRKNvID(bondIdx), KEYLEN, pAuthEvt->pIdentityInfo->irk );
  1237. pAuthEvt->pIdentityInfo = NULL;
  1238. }
  1239. // If available, save the connected device's Signature information
  1240. else if ( pAuthEvt->pSigningInfo )
  1241. {
  1242. VOID osal_snv_write( devCSRKNvID(bondIdx), KEYLEN, pAuthEvt->pSigningInfo->srk );
  1243. VOID osal_snv_write( devSignCounterNvID(bondIdx), sizeof ( uint32 ), &(pAuthEvt->pSigningInfo->signCounter) );
  1244. pAuthEvt->pSigningInfo = NULL;
  1245. }
  1246. else
  1247. {
  1248. if ( autoSyncWhiteList )
  1249. {
  1250. gapBondMgr_SyncWhiteList();
  1251. }
  1252. // Update the GAP Privacy Flag Properties
  1253. gapBondSetupPrivFlag();
  1254. return ( TRUE );
  1255. }
  1256. }
  1257. // We have more info to store
  1258. return ( FALSE );
  1259. }
  1260. return ( TRUE );
  1261. }
  1262. /*********************************************************************
  1263. * @fn gapBondMgrGetStateFlags
  1264. *
  1265. * @brief Gets the state flags field of a bond record in NV
  1266. *
  1267. * @param idx
  1268. *
  1269. * @return stateFlags field
  1270. */
  1271. static uint8 gapBondMgrGetStateFlags( uint8 idx )
  1272. {
  1273. gapBondRec_t bondRec;
  1274. if ( osal_snv_read( mainRecordNvID(idx), sizeof ( gapBondRec_t ), &bondRec ) == SUCCESS )
  1275. {
  1276. return ( bondRec.stateFlags );
  1277. }
  1278. return ( 0 );
  1279. }
  1280. /*********************************************************************
  1281. * @fn gapBondMgrGetPublicAddr
  1282. *
  1283. * @brief Copy the public Address from a bonding record
  1284. *
  1285. * @param idx - Bond record index
  1286. * @param pAddr - a place to put the public address from NV
  1287. *
  1288. * @return SUCCESS if successful.
  1289. * Otherwise failure.
  1290. */
  1291. static bStatus_t gapBondMgrGetPublicAddr( uint8 idx, uint8 *pAddr )
  1292. {
  1293. bStatus_t stat; // return value
  1294. gapBondRec_t bondRec; // Work space for main bond record
  1295. // Check parameters
  1296. if ( (idx >= GAP_BONDINGS_MAX) || (pAddr == NULL) )
  1297. {
  1298. return ( INVALIDPARAMETER );
  1299. }
  1300. stat = osal_snv_read( mainRecordNvID(idx), sizeof ( gapBondRec_t ), &bondRec );
  1301. if ( stat == SUCCESS )
  1302. {
  1303. VOID osal_memcpy( pAddr, bondRec.publicAddr, B_ADDR_LEN );
  1304. }
  1305. return ( stat );
  1306. }
  1307. /*********************************************************************
  1308. * @fn gapBondMgrFindReconnectAddr
  1309. *
  1310. * @brief Look through the bonding entries to find a
  1311. * reconnection address.
  1312. *
  1313. * @param pReconnectAddr - device address to look for
  1314. *
  1315. * @return index to found bonding (0 - (GAP_BONDINGS_MAX-1),
  1316. * GAP_BONDINGS_MAX if no empty entries
  1317. */
  1318. static uint8 gapBondMgrFindReconnectAddr( uint8 *pReconnectAddr )
  1319. {
  1320. // Item doesn't exist, so create all the items
  1321. for ( uint8 idx = 0; idx < GAP_BONDINGS_MAX; idx++ )
  1322. {
  1323. // compare reconnection address
  1324. if ( osal_memcmp( bonds[idx].reconnectAddr, pReconnectAddr, B_ADDR_LEN ) )
  1325. {
  1326. return ( idx ); // Found it
  1327. }
  1328. }
  1329. return ( GAP_BONDINGS_MAX );
  1330. }
  1331. /*********************************************************************
  1332. * @fn gapBondMgrFindAddr
  1333. *
  1334. * @brief Look through the bonding entries to find an address.
  1335. *
  1336. * @param pDevAddr - device address to look for
  1337. *
  1338. * @return index to empty bonding (0 - (GAP_BONDINGS_MAX-1),
  1339. * GAP_BONDINGS_MAX if no empty entries
  1340. */
  1341. static uint8 gapBondMgrFindAddr( uint8 *pDevAddr )
  1342. {
  1343. // Item doesn't exist, so create all the items
  1344. for ( uint8 idx = 0; idx < GAP_BONDINGS_MAX; idx++ )
  1345. {
  1346. // Read in NV Main Bond Record and compare public address
  1347. if ( osal_memcmp( bonds[idx].publicAddr, pDevAddr, B_ADDR_LEN ) )
  1348. {
  1349. return ( idx ); // Found it
  1350. }
  1351. }
  1352. return ( GAP_BONDINGS_MAX );
  1353. }
  1354. /*********************************************************************
  1355. * @fn gapBondMgrResolvePrivateAddr
  1356. *
  1357. * @brief Look through the NV bonding entries to resolve a private
  1358. * address.
  1359. *
  1360. * @param pDevAddr - device address to look for
  1361. *
  1362. * @return index to found bonding (0 - (GAP_BONDINGS_MAX-1),
  1363. * GAP_BONDINGS_MAX if no entry found
  1364. */
  1365. static uint8 gapBondMgrResolvePrivateAddr( uint8 *pDevAddr )
  1366. {
  1367. for ( uint8 idx = 0; idx < GAP_BONDINGS_MAX; idx++ )
  1368. {
  1369. uint8 IRK[KEYLEN];
  1370. // Read in NV IRK Record and compare resovable address
  1371. if ( osal_snv_read( devIRKNvID(idx), KEYLEN, IRK ) == SUCCESS )
  1372. {
  1373. if ( ( osal_isbufset( IRK, 0xFF, KEYLEN ) == FALSE ) &&
  1374. ( GAP_ResolvePrivateAddr( IRK, pDevAddr ) == SUCCESS ) )
  1375. {
  1376. return ( idx ); // Found it
  1377. }
  1378. }
  1379. }
  1380. return ( GAP_BONDINGS_MAX );
  1381. }
  1382. /*********************************************************************
  1383. * @fn gapBondMgrReadBonds
  1384. *
  1385. * @brief Read through NV and store them in RAM.
  1386. *
  1387. * @param none
  1388. *
  1389. * @return none
  1390. */
  1391. static void gapBondMgrReadBonds( void )
  1392. {
  1393. for ( uint8 idx = 0; idx < GAP_BONDINGS_MAX; idx++ )
  1394. {
  1395. // See if the entry exists in NV
  1396. if ( osal_snv_read( mainRecordNvID(idx), sizeof( gapBondRec_t ), &(bonds[idx]) ) != SUCCESS )
  1397. {
  1398. // Can't read the entry, assume that it doesn't exist
  1399. VOID osal_memset( bonds[idx].publicAddr, 0xFF, B_ADDR_LEN );
  1400. VOID osal_memset( bonds[idx].reconnectAddr, 0xFF, B_ADDR_LEN );
  1401. bonds[idx].stateFlags = 0;
  1402. }
  1403. }
  1404. if ( autoSyncWhiteList )
  1405. {
  1406. gapBondMgr_SyncWhiteList();
  1407. }
  1408. // Update the GAP Privacy Flag Properties
  1409. gapBondSetupPrivFlag();
  1410. }
  1411. /*********************************************************************
  1412. * @fn gapBondMgrFindEmpty
  1413. *
  1414. * @brief Look through the bonding NV entries to find an empty.
  1415. *
  1416. * @param none
  1417. *
  1418. * @return index to empty bonding (0 - (GAP_BONDINGS_MAX-1),
  1419. * GAP_BONDINGS_MAX if no empty entries
  1420. */
  1421. static uint8 gapBondMgrFindEmpty( void )
  1422. {
  1423. // Item doesn't exist, so create all the items
  1424. for ( uint8 idx = 0; idx < GAP_BONDINGS_MAX; idx++ )
  1425. {
  1426. // Look for public address of all 0xFF's
  1427. if ( osal_isbufset( bonds[idx].publicAddr, 0xFF, B_ADDR_LEN ) )
  1428. {
  1429. return ( idx ); // Found one
  1430. }
  1431. }
  1432. return ( GAP_BONDINGS_MAX );
  1433. }
  1434. /*********************************************************************
  1435. * @fn gapBondMgrBondTotal
  1436. *
  1437. * @brief Look through the bonding NV entries calculate the number
  1438. * entries.
  1439. *
  1440. * @param none
  1441. *
  1442. * @return total number of bonds found
  1443. */
  1444. static uint8 gapBondMgrBondTotal( void )
  1445. {
  1446. uint8 numBonds = 0;
  1447. // Item doesn't exist, so create all the items
  1448. for ( uint8 idx = 0; idx < GAP_BONDINGS_MAX; idx++ )
  1449. {
  1450. // Look for public address that are not 0xFF's
  1451. if ( osal_isbufset( bonds[idx].publicAddr, 0xFF, B_ADDR_LEN ) == FALSE )
  1452. {
  1453. numBonds++; // Found one
  1454. }
  1455. }
  1456. return ( numBonds );
  1457. }
  1458. /*********************************************************************
  1459. * @fn gapBondMgrEraseAllBondings
  1460. *
  1461. * @brief Write all 0xFF's to all of the bonding entries
  1462. *
  1463. * @param none
  1464. *
  1465. * @return SUCCESS if successful.
  1466. * Otherwise, NV_OPER_FAILED for failure.
  1467. */
  1468. static bStatus_t gapBondMgrEraseAllBondings( void )
  1469. {
  1470. bStatus_t stat = SUCCESS; // return value
  1471. // Item doesn't exist, so create all the items
  1472. for ( uint8 idx = 0; (idx < GAP_BONDINGS_MAX) && (stat == SUCCESS); idx++ )
  1473. {
  1474. // Erasing will write/create a bonding entry
  1475. stat = gapBondMgrEraseBonding( idx );
  1476. }
  1477. return ( stat );
  1478. }
  1479. /*********************************************************************
  1480. * @fn gapBondMgrEraseBonding
  1481. *
  1482. * @brief Write all 0xFF's to the complete bonding record
  1483. *
  1484. * @param idx - bonding index
  1485. *
  1486. * @return SUCCESS if successful.
  1487. * Otherwise, NV_OPER_FAILED for failure.
  1488. */
  1489. static bStatus_t gapBondMgrEraseBonding( uint8 idx )
  1490. {
  1491. bStatus_t ret;
  1492. gapBondRec_t bondRec;
  1493. if ( idx == bondIdx )
  1494. {
  1495. // Stop ongoing bond store process to prevent any invalid data be written.
  1496. osal_clear_event( gapBondMgr_TaskID, GAP_BOND_SYNC_CC_EVT );
  1497. osal_clear_event( gapBondMgr_TaskID, GAP_BOND_SAVE_REC_EVT );
  1498. gapBondFreeAuthEvt();
  1499. }
  1500. // First see if bonding record exists in NV, then write all 0xFF's to it
  1501. if ( ( osal_snv_read( mainRecordNvID(idx), sizeof ( gapBondRec_t ), &bondRec ) == SUCCESS )
  1502. && (osal_isbufset( bondRec.publicAddr, 0xFF, B_ADDR_LEN ) == FALSE) )
  1503. {
  1504. gapBondLTK_t ltk;
  1505. gapBondCharCfg_t charCfg[GAP_CHAR_CFG_MAX];
  1506. VOID osal_memset( &bondRec, 0xFF, sizeof ( gapBondRec_t ) );
  1507. VOID osal_memset( &ltk, 0xFF, sizeof ( gapBondLTK_t ) );
  1508. VOID osal_memset( charCfg, 0xFF, sizeof ( charCfg ) );
  1509. // Write out FF's over the entire bond entry.
  1510. ret = osal_snv_write( mainRecordNvID(idx), sizeof ( gapBondRec_t ), &bondRec );
  1511. ret |= osal_snv_write( localLTKNvID(idx), sizeof ( gapBondLTK_t ), &ltk );
  1512. ret |= osal_snv_write( devLTKNvID(idx), sizeof ( gapBondLTK_t ), &ltk );
  1513. ret |= osal_snv_write( devIRKNvID(idx), KEYLEN, ltk.LTK );
  1514. ret |= osal_snv_write( devCSRKNvID(idx), KEYLEN, ltk.LTK );
  1515. ret |= osal_snv_write( devSignCounterNvID(idx), sizeof ( uint32 ), ltk.LTK );
  1516. // Write out FF's over the charactersitic configuration entry.
  1517. ret |= osal_snv_write( gattCfgNvID(idx), sizeof ( charCfg ), charCfg );
  1518. }
  1519. else
  1520. {
  1521. ret = SUCCESS;
  1522. }
  1523. return ( ret );
  1524. }
  1525. /*********************************************************************
  1526. * @brief Task Initialization function.
  1527. *
  1528. * Internal function defined in gapbondmgr.h.
  1529. */
  1530. void GAPBondMgr_Init( uint8 task_id )
  1531. {
  1532. gapBondMgr_TaskID = task_id; // Save task ID
  1533. // Setup Bond RAM Shadow
  1534. gapBondMgrReadBonds();
  1535. }
  1536. /*********************************************************************
  1537. * @brief Task Event Processor function.
  1538. *
  1539. * Internal function defined in gapbondmgr.h.
  1540. */
  1541. uint16 GAPBondMgr_ProcessEvent( uint8 task_id, uint16 events )
  1542. {
  1543. VOID task_id; // OSAL required parameter that isn't used in this function
  1544. if ( events & SYS_EVENT_MSG )
  1545. {
  1546. uint8 *pMsg;
  1547. if ( (pMsg = osal_msg_receive( gapBondMgr_TaskID )) != NULL )
  1548. {
  1549. if ( gapBondMgr_ProcessOSALMsg( (osal_event_hdr_t *)pMsg ) )
  1550. {
  1551. // Release the OSAL message
  1552. VOID osal_msg_deallocate( pMsg );
  1553. }
  1554. }
  1555. // return unprocessed events
  1556. return (events ^ SYS_EVENT_MSG);
  1557. }
  1558. if ( events & GAP_BOND_SAVE_REC_EVT )
  1559. {
  1560. // Save bonding record in NV
  1561. if ( gapBondMgrAddBond( NULL, NULL ) )
  1562. {
  1563. // Notify our task to update NV with CCC values stored in GATT database
  1564. osal_set_event( gapBondMgr_TaskID, GAP_BOND_SYNC_CC_EVT );
  1565. return (events ^ GAP_BOND_SAVE_REC_EVT);
  1566. }
  1567. return ( GAP_BOND_SAVE_REC_EVT );
  1568. }
  1569. if ( events & GAP_BOND_SYNC_CC_EVT )
  1570. {
  1571. // Update NV to have same CCC values as GATT database
  1572. // Note: pAuthEvt is a global variable used for deferring the storage
  1573. if ( gapBondMgr_SyncCharCfg( pAuthEvt->connectionHandle ) )
  1574. {
  1575. if ( pGapBondCB && pGapBondCB->pairStateCB )
  1576. {
  1577. // Assume SUCCESS since we got this far.
  1578. pGapBondCB->pairStateCB( pAuthEvt->connectionHandle, GAPBOND_PAIRING_STATE_COMPLETE, SUCCESS );
  1579. }
  1580. // We're done storing bond record and CCC values in NV
  1581. gapBondFreeAuthEvt();
  1582. return (events ^ GAP_BOND_SYNC_CC_EVT);
  1583. }
  1584. return ( GAP_BOND_SYNC_CC_EVT );
  1585. }
  1586. // Discard unknown events
  1587. return 0;
  1588. }
  1589. /*********************************************************************
  1590. * @fn gapBondMgr_ProcessOSALMsg
  1591. *
  1592. * @brief Process an incoming task message.
  1593. *
  1594. * @param pMsg - message to process
  1595. *
  1596. * @return TRUE if safe to deallocate incoming message, FALSE otherwise.
  1597. */
  1598. static uint8 gapBondMgr_ProcessOSALMsg( osal_event_hdr_t *pMsg )
  1599. {
  1600. uint8 safeToDealloc = TRUE;
  1601. switch ( pMsg->event )
  1602. {
  1603. case GAP_MSG_EVENT:
  1604. safeToDealloc = GAPBondMgr_ProcessGAPMsg( (gapEventHdr_t *)pMsg );
  1605. break;
  1606. case GATT_MSG_EVENT:
  1607. gapBondMgr_ProcessGATTMsg( (gattMsgEvent_t *)pMsg );
  1608. break;
  1609. case GATT_SERV_MSG_EVENT:
  1610. gapBondMgr_ProcessGATTServMsg( (gattEventHdr_t *)pMsg );
  1611. break;
  1612. default:
  1613. break;
  1614. }
  1615. return ( safeToDealloc );
  1616. }
  1617. /*********************************************************************
  1618. * @fn GAPBondMgr_CheckNVLen
  1619. *
  1620. * @brief This function will check the length of an NV Item.
  1621. *
  1622. * @param id - NV ID.
  1623. * @param len - lengths in bytes of item.
  1624. *
  1625. * @return SUCCESS or FAILURE
  1626. */
  1627. uint8 GAPBondMgr_CheckNVLen( uint8 id, uint8 len )
  1628. {
  1629. uint8 stat = FAILURE;
  1630. // Convert to index
  1631. switch ( (id - BLE_NVID_GAP_BOND_START) % GAP_BOND_REC_IDS )
  1632. {
  1633. case GAP_BOND_REC_ID_OFFSET:
  1634. if ( len == sizeof ( gapBondRec_t ) )
  1635. {
  1636. stat = SUCCESS;
  1637. }
  1638. break;
  1639. case GAP_BOND_LOCAL_LTK_OFFSET:
  1640. case GAP_BOND_DEV_LTK_OFFSET:
  1641. if ( len == sizeof ( gapBondLTK_t ) )
  1642. {
  1643. stat = SUCCESS;
  1644. }
  1645. break;
  1646. case GAP_BOND_DEV_IRK_OFFSET:
  1647. case GAP_BOND_DEV_CSRK_OFFSET:
  1648. if ( len == KEYLEN )
  1649. {
  1650. stat = SUCCESS;
  1651. }
  1652. break;
  1653. case GAP_BOND_DEV_SIGN_COUNTER_OFFSET:
  1654. if ( len == sizeof ( uint32 ) )
  1655. {
  1656. stat = SUCCESS;
  1657. }
  1658. break;
  1659. default:
  1660. break;
  1661. }
  1662. return ( stat );
  1663. }
  1664. /*********************************************************************
  1665. * @fn gapBondMgr_ProcessGATTMsg
  1666. *
  1667. * @brief Process an incoming GATT message.
  1668. *
  1669. * @param pMsg - pointer to received message
  1670. *
  1671. * @return none
  1672. */
  1673. static void gapBondMgr_ProcessGATTMsg( gattMsgEvent_t *pMsg )
  1674. {
  1675. // Process the GATT message
  1676. switch ( pMsg->method )
  1677. {
  1678. case ATT_HANDLE_VALUE_CFM:
  1679. // Clear Service Changed flag for this client
  1680. VOID GAPBondMgr_ServiceChangeInd( pMsg->connHandle, 0x00 );
  1681. break;
  1682. default:
  1683. // Unknown message
  1684. break;
  1685. }
  1686. }
  1687. /*********************************************************************
  1688. * @fn gapBondMgr_ProcessGATTServMsg
  1689. *
  1690. * @brief Process an incoming GATT Server App message.
  1691. *
  1692. * @param pMsg - pointer to received message
  1693. *
  1694. * @return none
  1695. */
  1696. static void gapBondMgr_ProcessGATTServMsg( gattEventHdr_t *pMsg )
  1697. {
  1698. // Process the GATT Server App message
  1699. switch ( pMsg->method )
  1700. {
  1701. case GATT_CLIENT_CHAR_CFG_UPDATED_EVENT:
  1702. {
  1703. gattClientCharCfgUpdatedEvent_t *pEvent = (gattClientCharCfgUpdatedEvent_t *)pMsg;
  1704. VOID GAPBondMgr_UpdateCharCfg( pEvent->connHandle, pEvent->attrHandle, pEvent->value );
  1705. }
  1706. break;
  1707. default:
  1708. // Unknown message
  1709. break;
  1710. }
  1711. }
  1712. /*********************************************************************
  1713. * @fn gapBondMgrSendServiceChange
  1714. *
  1715. * @brief Tell the GATT that a service change is needed.
  1716. *
  1717. * @param pLinkItem - pointer to connection information
  1718. *
  1719. * @return none
  1720. */
  1721. static void gapBondMgrSendServiceChange( linkDBItem_t *pLinkItem )
  1722. {
  1723. VOID GATTServApp_SendServiceChangedInd( pLinkItem->connectionHandle,
  1724. gapBondMgr_TaskID );
  1725. }
  1726. /*********************************************************************
  1727. * @fn gapBondSetupPrivFlag
  1728. *
  1729. * @brief Setup the GAP Privacy Flag properties.
  1730. *
  1731. * @param none
  1732. *
  1733. * @return none
  1734. */
  1735. static void gapBondSetupPrivFlag( void )
  1736. {
  1737. uint8 privFlagProp;
  1738. if ( gapBondMgrBondTotal() > 1 )
  1739. {
  1740. privFlagProp = GATT_PROP_READ;
  1741. }
  1742. else
  1743. {
  1744. privFlagProp = GATT_PROP_READ | GATT_PROP_WRITE;
  1745. }
  1746. // Setup the
  1747. VOID GGS_SetParameter( GGS_PERI_PRIVACY_FLAG_PROPS, sizeof ( uint8 ), &privFlagProp );
  1748. }
  1749. /*********************************************************************
  1750. * @fn gapBondMgrAuthenticate
  1751. *
  1752. * @brief Initiate authentication
  1753. *
  1754. * @param connHandle - connection handle
  1755. * @param addrType - peer address type
  1756. * @param pPairReq - Enter these parameters if the Pairing Request was already received.
  1757. * NULL, if waiting for Pairing Request or if initiating.
  1758. *
  1759. * @return none
  1760. */
  1761. static void gapBondMgrAuthenticate( uint16 connHandle, uint8 addrType,
  1762. gapPairingReq_t *pPairReq )
  1763. {
  1764. gapAuthParams_t params;
  1765. VOID osal_memset( &params, 0, sizeof ( gapAuthParams_t ) );
  1766. // Setup the pairing parameters
  1767. params.connectionHandle = connHandle;
  1768. params.secReqs.ioCaps = gapBond_IOCap;
  1769. params.secReqs.oobAvailable = gapBond_OOBDataFlag;
  1770. params.secReqs.maxEncKeySize = gapBond_KeySize;
  1771. params.secReqs.keyDist.sEncKey = (gapBond_KeyDistList & GAPBOND_KEYDIST_SENCKEY) ? TRUE : FALSE;
  1772. params.secReqs.keyDist.sIdKey = (gapBond_KeyDistList & GAPBOND_KEYDIST_SIDKEY) ? TRUE : FALSE;
  1773. params.secReqs.keyDist.mEncKey = (gapBond_KeyDistList & GAPBOND_KEYDIST_MENCKEY) ? TRUE : FALSE;
  1774. params.secReqs.keyDist.mIdKey = (gapBond_KeyDistList & GAPBOND_KEYDIST_MIDKEY) ? TRUE : FALSE;
  1775. params.secReqs.keyDist.mSign = (gapBond_KeyDistList & GAPBOND_KEYDIST_MSIGN) ? TRUE : FALSE;
  1776. params.secReqs.keyDist.sSign = (gapBond_KeyDistList & GAPBOND_KEYDIST_SSIGN) ? TRUE : FALSE;
  1777. // Is bond manager setup for OOB data?
  1778. if ( gapBond_OOBDataFlag )
  1779. {
  1780. VOID osal_memcpy( params.secReqs.oob, gapBond_OOBData, KEYLEN );
  1781. }
  1782. if ( gapBond_Bonding && addrType != ADDRTYPE_PUBLIC )
  1783. {
  1784. // Force a slave ID key
  1785. params.secReqs.keyDist.sIdKey = TRUE;
  1786. }
  1787. params.secReqs.authReq |= (gapBond_Bonding) ? SM_AUTH_STATE_BONDING : 0;
  1788. params.secReqs.authReq |= (gapBond_MITM) ? SM_AUTH_STATE_AUTHENTICATED : 0;
  1789. VOID GAP_Authenticate( &params, pPairReq );
  1790. }
  1791. #if ( HOST_CONFIG & PERIPHERAL_CFG )
  1792. /*********************************************************************
  1793. * @fn gapBondMgrSlaveSecurityReq
  1794. *
  1795. * @brief Send a slave security request
  1796. *
  1797. * @param connHandle - connection handle
  1798. *
  1799. * @return none
  1800. */
  1801. static void gapBondMgrSlaveSecurityReq( uint16 connHandle )
  1802. {
  1803. uint8 authReq = 0;
  1804. authReq |= (gapBond_Bonding) ? SM_AUTH_STATE_BONDING : 0;
  1805. authReq |= (gapBond_MITM) ? SM_AUTH_STATE_AUTHENTICATED : 0;
  1806. VOID GAP_SendSlaveSecurityRequest( connHandle, authReq );
  1807. }
  1808. #endif
  1809. /*********************************************************************
  1810. * @fn gapBondMgrBondReq
  1811. *
  1812. * @brief Initiate a GAP bond request
  1813. *
  1814. * @param connHandle - connection handle
  1815. * @param idx - NV index of bond entry
  1816. * @param stateFlags - bond state flags
  1817. * @param role - master or slave role
  1818. * @param startEncryption - whether or not to start encryption
  1819. *
  1820. * @return none
  1821. */
  1822. static void gapBondMgrBondReq( uint16 connHandle, uint8 idx, uint8 stateFlags,
  1823. uint8 role, uint8 startEncryption )
  1824. {
  1825. smSecurityInfo_t ltk;
  1826. osalSnvId_t nvId;
  1827. if ( role == GAP_PROFILE_CENTRAL )
  1828. {
  1829. nvId = devLTKNvID( idx );
  1830. }
  1831. else
  1832. {
  1833. nvId = localLTKNvID( idx );
  1834. }
  1835. // Initialize the NV structures
  1836. VOID osal_memset( &ltk, 0, sizeof ( smSecurityInfo_t ) );
  1837. if ( osal_snv_read( nvId, sizeof ( smSecurityInfo_t ), &ltk ) == SUCCESS )
  1838. {
  1839. if ( (ltk.keySize >= MIN_ENC_KEYSIZE) && (ltk.keySize <= MAX_ENC_KEYSIZE) )
  1840. {
  1841. VOID GAP_Bond( connHandle,
  1842. ((stateFlags & GAP_BONDED_STATE_AUTHENTICATED) ? TRUE : FALSE),
  1843. &ltk, startEncryption );
  1844. }
  1845. }
  1846. }
  1847. /*********************************************************************
  1848. * @fn gapBondMgr_SyncWhiteList
  1849. *
  1850. * @brief syncronize the White List with the bonds
  1851. *
  1852. * @param none
  1853. *
  1854. * @return none
  1855. */
  1856. static void gapBondMgr_SyncWhiteList( void )
  1857. {
  1858. //erase the White List
  1859. VOID HCI_LE_ClearWhiteListCmd();
  1860. // Write bond addresses into the White List
  1861. for( uint8 i = 0; i < GAP_BONDINGS_MAX; i++)
  1862. {
  1863. // Make sure empty addresses are not added to the White List
  1864. if ( osal_isbufset( bonds[i].publicAddr, 0xFF, B_ADDR_LEN ) == FALSE )
  1865. {
  1866. VOID HCI_LE_AddWhiteListCmd( HCI_PUBLIC_DEVICE_ADDRESS, bonds[i].publicAddr );
  1867. }
  1868. }
  1869. }
  1870. /*********************************************************************
  1871. * @fn gapBondMgr_SyncCharCfg
  1872. *
  1873. * @brief Update the Bond Manager to have the same configurations as
  1874. * the GATT database.
  1875. *
  1876. * @param connHandle - the current connection handle to find client configurations for
  1877. *
  1878. * @return TRUE if sync done. FALSE, otherwise.
  1879. */
  1880. static uint8 gapBondMgr_SyncCharCfg( uint16 connHandle )
  1881. {
  1882. static gattAttribute_t *pAttr = NULL;
  1883. static uint16 service;
  1884. // Only attributes with attribute handles between and including the Starting
  1885. // Handle parameter and the Ending Handle parameter that match the requested
  1886. // attribute type and the attribute value will be returned.
  1887. // All attribute types are effectively compared as 128-bit UUIDs,
  1888. // even if a 16-bit UUID is provided in this request or defined
  1889. // for an attribute.
  1890. if ( pAttr == NULL )
  1891. {
  1892. pAttr = GATT_FindHandleUUID( GATT_MIN_HANDLE, GATT_MAX_HANDLE,
  1893. clientCharCfgUUID, ATT_BT_UUID_SIZE, &service );
  1894. }
  1895. if ( pAttr != NULL )
  1896. {
  1897. uint8 len;
  1898. uint8 attrVal[ATT_BT_UUID_SIZE];
  1899. // It is not possible to use this request on an attribute that has a value
  1900. // that is longer than 2.
  1901. if ( GATTServApp_ReadAttr( connHandle, pAttr, service, attrVal,
  1902. &len, 0, ATT_BT_UUID_SIZE ) == SUCCESS )
  1903. {
  1904. uint16 value = BUILD_UINT16(attrVal[0], attrVal[1]);
  1905. if ( value != GATT_CFG_NO_OPERATION )
  1906. {
  1907. // NV must be updated to meet configuration of the database
  1908. VOID GAPBondMgr_UpdateCharCfg( connHandle, pAttr->handle, value );
  1909. }
  1910. }
  1911. // Try to find the next attribute
  1912. pAttr = GATT_FindNextAttr( pAttr, GATT_MAX_HANDLE, service, NULL );
  1913. }
  1914. return ( pAttr == NULL );
  1915. }
  1916. /*********************************************************************
  1917. * @fn gapBondFreeAuthEvt
  1918. *
  1919. * @brief Free GAP Authentication Complete event.
  1920. *
  1921. * @param none
  1922. *
  1923. * @return none
  1924. */
  1925. static void gapBondFreeAuthEvt( void )
  1926. {
  1927. if ( pAuthEvt != NULL )
  1928. {
  1929. // Release the OSAL message
  1930. VOID osal_msg_deallocate( (uint8 *)pAuthEvt );
  1931. pAuthEvt = NULL;
  1932. }
  1933. bondIdx = GAP_BONDINGS_MAX;
  1934. }
  1935. #endif // ( CENTRAL_CFG | PERIPHERAL_CFG )
  1936. /*********************************************************************
  1937. *********************************************************************/