device_manager_peripheral.c 110 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943
  1. /* Copyright (C) 2013 Nordic Semiconductor. All Rights Reserved.
  2. *
  3. * The information contained herein is property of Nordic Semiconductor ASA.
  4. * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
  5. *
  6. * Licensees are granted free, non-transferable use of the information. NO
  7. * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
  8. * the file.
  9. *
  10. */
  11. #include "device_manager.h"
  12. #include "app_trace.h"
  13. #include "pstorage.h"
  14. #include "ble_hci.h"
  15. #include "app_error.h"
  16. #if defined ( __CC_ARM )
  17. #ifndef __ALIGN
  18. #define __ALIGN(x) __align(x) /**< Forced aligment keyword for ARM Compiler */
  19. #endif
  20. #elif defined ( __ICCARM__ )
  21. #ifndef __ALIGN
  22. #define __ALIGN(x) /**< Forced aligment keyword for IAR Compiler */
  23. #endif
  24. #elif defined ( __GNUC__ )
  25. #ifndef __ALIGN
  26. #define __ALIGN(x) __attribute__((aligned(x))) /**< Forced aligment keyword for GNU Compiler */
  27. #endif
  28. #endif
  29. #define INVALID_ADDR_TYPE 0xFF /**< Identifier for an invalid address type. */
  30. #define EDIV_INIT_VAL 0xFFFF /**< Initial value for diversifier. */
  31. /**
  32. * @defgroup device_manager_app_states Connection Manager Application States
  33. * @{
  34. */
  35. #define STATE_CONTROL_PROCEDURE_IN_PROGRESS 0x01 /**< State where a security procedure is ongoing. */
  36. #define STATE_QUEUED_CONTROL_REQUEST 0x02 /**< State where it is known if there is any queued security request or not. */
  37. /** @} */
  38. /**
  39. * @defgroup device_manager_conn_inst_states Connection Manager Connection Instances States.
  40. * @{
  41. */
  42. #define STATE_IDLE 0x01 /**< State where connection instance is free. */
  43. #define STATE_CONNECTED 0x02 /**< State where connection is successfully established. */
  44. #define STATE_PAIRING 0x04 /**< State where pairing procedure is in progress. This state is used for pairing and bonding, as pairing is needed for both. */
  45. #define STATE_BONDED 0x08 /**< State where device is bonded. */
  46. #define STATE_DISCONNECTING 0x10 /**< State where disconnection is in progress, application will be notified first, but no further active procedures on the link. */
  47. #define STATE_PAIRING_PENDING 0x20 /**< State where pairing request is pending on the link. */
  48. #define STATE_BOND_INFO_UPDATE 0x40 /**< State where information has been updated, update the flash. */
  49. #define STATE_LINK_ENCRYPTED 0x80 /**< State where link is encrypted. */
  50. /** @} */
  51. /**
  52. * @defgroup device_manager_peer_id_defines Peer Identification Information Defines.
  53. *
  54. * @brief These defines are used to know which of the peer identification is applicable for a peer.
  55. *
  56. * @details These defines are used for peer identification. Here, bit map is used because it is
  57. * possible that the application has both IRK and address for identification.
  58. * @{
  59. */
  60. #define UNASSIGNED 0xFF /**< Peer instance is unassigned/unused. */
  61. #define IRK_ENTRY 0x01 /**< Peer instance has IRK as identification information. */
  62. #define ADDR_ENTRY 0x02 /**< Peer instance has address as identification information. */
  63. #define SERVICE_CONTEXT_ENTRY 0x04 /**< Peer instance has service context set. */
  64. #define APP_CONTEXT_ENTRY 0x08 /**< Peer instance has an application context set. */
  65. /** @} */
  66. /**@brief Device store state identifiers. */
  67. typedef enum
  68. {
  69. STORE_ALL_CONTEXT, /**< Store all context. */
  70. FIRST_BOND_STORE, /**< Store bond. */
  71. UPDATE_PEER_ADDR /**< Update peer address. */
  72. } device_store_state_t;
  73. /**
  74. * @defgroup device_manager_context_offsets Context Offsets
  75. * @{
  76. *
  77. * @brief Context offsets each of the context information in persistent memory.
  78. *
  79. * @details Below is a layout showing how each how the context information is stored in persistent
  80. * memory.
  81. *
  82. * All Device context is stored in the flash as follows:
  83. * +---------+---------+---------+------------------+----------------+--------------------+
  84. * | Block / Device ID + Layout of stored information in storage block |
  85. * +---------+---------+---------+------------------+----------------+--------------------+
  86. * | Block 0 | Device 0| Peer Id | Bond Information | Service Context| Application Context|
  87. * +---------+---------+---------+------------------+----------------+--------------------+
  88. * | Block 1 | Device 1| Peer Id | Bond Information | Service Context| Application Context|
  89. * +---------+---------+---------+------------------+----------------+--------------------+
  90. * | ... | .... |
  91. * +---------+---------+---------+------------------+----------------+--------------------+
  92. * | Block N | Device N| Peer Id | Bond Information | Service Context| Application Context|
  93. * +---------+---------+---------+------------------+----------------+--------------------+
  94. *
  95. * The following defines are used to get offset of each of the components within a block.
  96. */
  97. #define PEER_ID_STORAGE_OFFSET 0 /**< Offset at which peer id is stored in the block. */
  98. #define BOND_STORAGE_OFFSET PEER_ID_SIZE /**< Offset at which bond information is stored in the block. */
  99. #define SERVICE_STORAGE_OFFSET (BOND_STORAGE_OFFSET + BOND_SIZE) /**< Offset at which service context is stored in the block. */
  100. #define APP_CONTEXT_STORAGE_OFFSET (SERVICE_STORAGE_OFFSET + SERVICE_CONTEXT_SIZE) /**< Offset at which application context is stored in the block. */
  101. /** @} */
  102. /**
  103. * @defgroup device_manager_context_size Context size.
  104. * @{
  105. *
  106. * @brief This group defines the size of each of the context information.
  107. */
  108. #define PEER_ID_SIZE (sizeof(peer_id_t)) /**< Size of peer identification information. */
  109. #define BOND_SIZE (sizeof(bond_context_t)) /**< Size of bond information. */
  110. #define DEVICE_CONTEXT_SIZE (PEER_ID_SIZE + BOND_SIZE) /**< Size of Device context, include peer identification and bond information. */
  111. #define GATTS_SERVICE_CONTEXT_SIZE (sizeof(dm_gatts_context_t)) /**< Size of GATTS service context. */
  112. #define GATTC_SERVICE_CONTEXT_SIZE (sizeof(dm_gatt_client_context_t)) /**< Size of GATTC service context. */
  113. #define SERVICE_CONTEXT_SIZE (GATTS_SERVICE_CONTEXT_SIZE + GATTC_SERVICE_CONTEXT_SIZE) /**< Combined size of GATTS and GATTC service contexts. */
  114. #define APP_CONTEXT_MIN_SIZE 4 /**< Minimum size for application context data. */
  115. #if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
  116. #define APP_CONTEXT_SIZE (sizeof(uint32_t) + DEVICE_MANAGER_APP_CONTEXT_SIZE) /**< Size of application context including length field. */
  117. #else //DEVICE_MANAGER_APP_CONTEXT_SIZE
  118. #define APP_CONTEXT_SIZE 0 /**< Size of application context. */
  119. #endif // DEVICE_MANAGER_APP_CONTEXT_SIZE
  120. #define ALL_CONTEXT_SIZE (DEVICE_CONTEXT_SIZE + SERVICE_CONTEXT_SIZE + APP_CONTEXT_SIZE) /**< Size of all contexts. */
  121. /** @} */
  122. /**
  123. * @defgroup device_manager_log Module's Log Macros
  124. *
  125. * @details Macros used for creating module logs which can be useful in understanding handling
  126. * of events or actions on API requests. These are intended for debugging purposes and
  127. * can be disabled by defining the DM_DISABLE_LOGS.
  128. *
  129. * @note That if ENABLE_DEBUG_LOG_SUPPORT is disabled, having DM_DISABLE_LOGS has no effect.
  130. * @{
  131. */
  132. #define nDM_DISABLE_LOGS /**< Enable this macro to disable any logs from this module. */
  133. #ifndef DM_DISABLE_LOGS
  134. #define DM_LOG app_trace_log /**< Used for logging details. */
  135. #define DM_ERR app_trace_log /**< Used for logging errors in the module. */
  136. #define DM_TRC app_trace_log /**< Used for getting trace of execution in the module. */
  137. #define DM_DUMP app_trace_dump /**< Used for dumping octet information to get details of bond information etc. */
  138. #else //DM_DISABLE_LOGS
  139. #define DM_DUMP(...) /**< Disables dumping of octet streams. */
  140. #define DM_LOG(...) /**< Disables detailed logs. */
  141. #define DM_ERR(...) /**< Disables error logs. */
  142. #define DM_TRC(...) /**< Disables traces. */
  143. #endif //DM_DISABLE_LOGS
  144. /** @} */
  145. /**
  146. * @defgroup device_manager_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
  147. *
  148. * @details Macros used to lock and unlock modules. Currently the SDK does not use mutexes but
  149. * framework is provided in case need arises to use an alternative architecture.
  150. * @{
  151. */
  152. #define DM_MUTEX_LOCK() SDK_MUTEX_LOCK(m_dm_mutex) /**< Lock module using mutex. */
  153. #define DM_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_dm_mutex) /**< Unlock module using mutex. */
  154. /** @} */
  155. /**
  156. * @defgroup device_manager_misc_defines Miscellaneous defines used across the module.
  157. * @{
  158. */
  159. #define DM_GATT_ATTR_SIZE 6 /**< Size of each GATT attribute to be stored persistently. */
  160. #define DM_GATT_SERVER_ATTR_MAX_SIZE ((DM_GATT_ATTR_SIZE * DM_GATT_CCCD_COUNT) + 2) /**< Maximum size of GATT attributes to be stored.*/
  161. #define DM_SERVICE_CONTEXT_COUNT (DM_PROTOCOL_CNTXT_ALL + 1) /**< Maximum number of service contexts. */
  162. #define DM_EVT_DEVICE_CONTEXT_BASE 0x20 /**< Base for device context base. */
  163. #define DM_EVT_SERVICE_CONTEXT_BASE 0x30 /**< Base for service context base. */
  164. #define DM_EVT_APP_CONTEXT_BASE 0x40 /**< Base for application context base. */
  165. #define DM_LOAD_OPERATION_ID 0x01 /**< Load operation identifier. */
  166. #define DM_STORE_OPERATION_ID 0x02 /**< Store operation identifier. */
  167. #define DM_CLEAR_OPERATION_ID 0x03 /**< Clear operation identifier. */
  168. /** @} */
  169. #define DM_GATTS_INVALID_SIZE 0xFFFFFFFF /**< Identifer for GATTS invalid size. */
  170. /**
  171. * @defgroup api_param_check API Parameters check macros.
  172. *
  173. * @details Macros for verifying parameters passed to the module in the APIs. These macros
  174. * could be mapped to nothing in the final version of the code in order to save execution
  175. * time and program size.
  176. * @{
  177. */
  178. //#define DM_DISABLE_API_PARAM_CHECK /**< Macro to disable API parameters check. */
  179. #undef NULL_PARAM_CHECK
  180. #undef VERIFY_MODULE_INITIALIZED
  181. #undef VERIFY_MODULE_INITIALIZED_VOID
  182. #undef VERIFY_APP_REGISTERED
  183. #undef VERIFY_APP_REGISTERED_VOID
  184. #undef VERIFY_CONNECTION_INSTANCE
  185. #undef VERIFY_DEVICE_INSTANCE
  186. #ifndef DM_DISABLE_API_PARAM_CHECK
  187. /**@brief Macro for verifying NULL parameters are not passed to API.
  188. *
  189. * @param[in] PARAM Parameter checked for NULL.
  190. *
  191. * @retval (NRF_ERROR_NULL | DEVICE_MANAGER_ERR_BASE) when @ref PARAM is NULL.
  192. */
  193. #define NULL_PARAM_CHECK(PARAM) \
  194. if ((PARAM) == NULL) \
  195. { \
  196. return (NRF_ERROR_NULL | DEVICE_MANAGER_ERR_BASE); \
  197. }
  198. /**@} */
  199. /**@brief Macro for verifying module's initialization status.
  200. *
  201. * @retval (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE) when module is not initialized.
  202. */
  203. #define VERIFY_MODULE_INITIALIZED() \
  204. do \
  205. { \
  206. if (!m_module_initialized) \
  207. { \
  208. return (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE); \
  209. } \
  210. } while (0)
  211. /**@brief Macro for verifying module's initialization status. Returns in case it is not initialized.
  212. */
  213. #define VERIFY_MODULE_INITIALIZED_VOID() \
  214. do \
  215. { \
  216. if (!m_module_initialized) \
  217. { \
  218. return; \
  219. } \
  220. } while (0)
  221. /**@brief Macro for verifying that the application is registered.
  222. *
  223. * @param[in] X Application instance identifier.
  224. *
  225. * @retval (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE) when module API is called without
  226. * registering an application with the module.
  227. */
  228. #define VERIFY_APP_REGISTERED(X) \
  229. do \
  230. { \
  231. if (((X) >= DEVICE_MANAGER_MAX_APPLICATIONS) || \
  232. (m_application_table[(X)].ntf_cb == NULL)) \
  233. { \
  234. return (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE); \
  235. } \
  236. } while (0)
  237. /**@brief Macro for verifying that the application is registered. Returns in case it is not
  238. * registered.
  239. *
  240. * @param[in] X Application instance identifier.
  241. */
  242. #define VERIFY_APP_REGISTERED_VOID(X) \
  243. do \
  244. { \
  245. if (((X) >= DEVICE_MANAGER_MAX_APPLICATIONS) || \
  246. (m_application_table[(X)].ntf_cb == NULL)) \
  247. { \
  248. return; \
  249. } \
  250. } while (0)
  251. /**@brief Macro for verifying connection instance is allocated.
  252. *
  253. * @param[in] X Connection instance identifier.
  254. *
  255. * @retval (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE) when connection instance is not
  256. * allocated.
  257. */
  258. #define VERIFY_CONNECTION_INSTANCE(X) \
  259. do \
  260. { \
  261. if (((X) >= DEVICE_MANAGER_MAX_CONNECTIONS) || \
  262. (m_connection_table[(X)].state == STATE_IDLE)) \
  263. { \
  264. return (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE); \
  265. } \
  266. } while (0)
  267. /**@brief Macro for verifying if device instance is allocated.
  268. *
  269. * @param[in] X Device instance identifier.
  270. *
  271. * @retval (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE) when device instance is not allocated.
  272. */
  273. #define VERIFY_DEVICE_INSTANCE(X) \
  274. do \
  275. { \
  276. if (((X) >= DEVICE_MANAGER_MAX_BONDS) || \
  277. (m_peer_table[(X)].id_bitmap == UNASSIGNED)) \
  278. { \
  279. return (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE); \
  280. } \
  281. } while (0)
  282. /**@brief Macro for verifying if device is bonded and thus can store data persistantly.
  283. *
  284. * @param[in] X Connection instance identifier.
  285. *
  286. * @retval (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE) when device is not bonded.
  287. */
  288. #define VERIFY_DEVICE_BOND(X) \
  289. do \
  290. { \
  291. if ((m_connection_table[(X)].state & STATE_BONDED) != STATE_BONDED)\
  292. { \
  293. return (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE); \
  294. } \
  295. } while (0)
  296. #else
  297. #define NULL_PARAM_CHECK(X)
  298. #define VERIFY_MODULE_INITIALIZED()
  299. #define VERIFY_MODULE_INITIALIZED_VOID()
  300. #define VERIFY_APP_REGISTERED(X)
  301. #define VERIFY_APP_REGISTERED_VOID(X)
  302. #define VERIFY_CONNECTION_INSTANCE(X)
  303. #define VERIFY_DEVICE_INSTANCE(X)
  304. #endif //DM_DISABLE_API_PARAM_CHECK
  305. /** @} */
  306. #define INVALID_CONTEXT_LEN 0xFFFFFFFF /**< Identifier for invalid context length. */
  307. /**@brief Macro for checking that application context size is greater that minimal size.
  308. *
  309. * @param[in] X Size of application context.
  310. *
  311. * @retval (NRF_ERROR_INVALID_PARAM) when size is smaller than minimun required size.
  312. */
  313. #define SIZE_CHECK_APP_CONTEXT(X) \
  314. if ((X) < (APP_CONTEXT_MIN_SIZE)) \
  315. { \
  316. return NRF_ERROR_INVALID_PARAM; \
  317. }
  318. /**
  319. * @defgroup dm_data_types Module's internal data types.
  320. *
  321. * @brief This section describes a module's internal data structures.
  322. * @{
  323. */
  324. /**@brief Peer identification information.
  325. */
  326. typedef struct
  327. {
  328. ble_gap_id_key_t peer_id; /**< IRK and/or address of peer. */
  329. uint16_t ediv; /**< Peer's encrypted diversifier. */
  330. uint8_t id_bitmap; /**< Contains information if above field is valid. */
  331. } peer_id_t;
  332. STATIC_ASSERT(sizeof(peer_id_t) % 4 == 0); /**< Check to ensure Peer identification information is a multiple of 4. */
  333. /**@brief Portion of bonding information exchanged by a device during bond creation that needs to
  334. * be stored persistently.
  335. *
  336. * @note An entry is not made in this table unless device is bonded.
  337. */
  338. typedef struct
  339. {
  340. ble_gap_enc_key_t peer_enc_key; /**< Local LTK info, central IRK and address */
  341. } bond_context_t;
  342. STATIC_ASSERT(sizeof(bond_context_t) % 4 == 0); /**< Check to ensure bond information is a multiple of 4. */
  343. /**@brief GATT Server Attributes size and data.
  344. */
  345. typedef struct
  346. {
  347. uint32_t flags; /**< Flags identifying the stored attributes. */
  348. uint32_t size; /**< Size of stored attributes. */
  349. uint8_t attributes[DM_GATT_SERVER_ATTR_MAX_SIZE]; /**< Array to hold the server attributes. */
  350. } dm_gatts_context_t;
  351. STATIC_ASSERT(sizeof(dm_gatts_context_t) % 4 == 0); /**< Check to ensure GATT Server Attributes size and data information is a multiple of 4. */
  352. /**@brief GATT Client context information. Placeholder for now.
  353. */
  354. typedef struct
  355. {
  356. void * p_dummy; /**< Placeholder, currently unused. */
  357. } dm_gatt_client_context_t;
  358. STATIC_ASSERT(sizeof(dm_gatt_client_context_t) % 4 == 0); /**< Check to ensure GATT Client context information is a multiple of 4. */
  359. STATIC_ASSERT((DEVICE_MANAGER_APP_CONTEXT_SIZE % 4) == 0); /**< Check to ensure device manager application context information is a multiple of 4. */
  360. /**@brief Connection instance definition. Maintains information with respect to an active peer.
  361. */
  362. typedef struct
  363. {
  364. ble_gap_addr_t peer_addr; /**< Peer identification information. This information is retained as long as the connection session exists, once disconnected, for non-bonded devices this information is not stored persistently. */
  365. uint16_t conn_handle; /**< Connection handle for the device. */
  366. uint8_t state; /**< Link state. */
  367. uint8_t bonded_dev_id; /**< In case the device is bonded, this points to the corresponding bonded device. This index can be used to index service and bond context as well. */
  368. } connection_instance_t;
  369. /**@brief Application instance definition. Maintains information with respect to a registered
  370. * application.
  371. */
  372. typedef struct
  373. {
  374. dm_event_cb_t ntf_cb; /**< Callback registered with the application. */
  375. ble_gap_sec_params_t sec_param; /**< Local security parameters registered by the application. */
  376. uint8_t state; /**< Application state. Currently this is used only for knowing if any security procedure is in progress and/or a security procedure is pending to be requested. */
  377. uint8_t service; /**< Service registered by the application. */
  378. } application_instance_t;
  379. /**@brief Function for performing necessary action of storing each of the service context as
  380. * registered by the application.
  381. *
  382. * @param[in] p_block_handle Storage block identifier.
  383. * @param[in] p_handle Device handle identifying device that is stored.
  384. *
  385. * @retval Operation result code.
  386. */
  387. typedef ret_code_t (* service_context_access_t)(pstorage_handle_t const * p_block_handle,
  388. dm_handle_t const * p_handle);
  389. /**@brief Function for performing necessary action of applying the context information.
  390. *
  391. * @param[in] p_handle Device handle identifying device that is stored.
  392. *
  393. * @retval Operation result code.
  394. */
  395. typedef ret_code_t (* service_context_apply_t)(dm_handle_t * p_handle);
  396. /**@brief Function for performing necessary functions of storing or updating.
  397. *
  398. * @param[in] p_dest Destination address where data is stored persistently.
  399. * @param[in] p_src Source address containing data to be stored.
  400. * @param[in] size Size of data to be stored expressed in bytes. Must be word aligned.
  401. * @param[in] offset Offset in bytes to be applied when writing to the block.
  402. *
  403. * @retval Operation result code.
  404. */
  405. typedef uint32_t (* storage_operation)(pstorage_handle_t * p_dest,
  406. uint8_t * p_src,
  407. pstorage_size_t size,
  408. pstorage_size_t offset);
  409. /** @} */
  410. /**
  411. * @defgroup dm_tables Module's internal tables.
  412. *
  413. * @brief This section describes the module's internal tables and the static global variables
  414. * needed for its functionality.
  415. * @{
  416. */
  417. #if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
  418. static uint8_t * m_app_context_table[DEVICE_MANAGER_MAX_BONDS]; /**< Table to remember application contexts of bonded devices. */
  419. #endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
  420. __ALIGN(sizeof(uint32_t))
  421. static peer_id_t m_peer_table[DEVICE_MANAGER_MAX_BONDS] ; /**< Table to maintain bonded devices' identification information, an instance is allocated in the table when a device is bonded and freed when bond information is deleted. */
  422. __ALIGN(sizeof(uint32_t))
  423. static bond_context_t m_bond_table[DEVICE_MANAGER_MAX_CONNECTIONS]; /**< Table to maintain bond information for active peers. */
  424. static dm_gatts_context_t m_gatts_table[DEVICE_MANAGER_MAX_CONNECTIONS]; /**< Table for service information for active connection instances. */
  425. static connection_instance_t m_connection_table[DEVICE_MANAGER_MAX_CONNECTIONS]; /**< Table to maintain active peer information. An instance is allocated in the table when a new connection is established and freed on disconnection. */
  426. static application_instance_t m_application_table[DEVICE_MANAGER_MAX_APPLICATIONS]; /**< Table to maintain application instances. */
  427. static pstorage_handle_t m_storage_handle; /**< Persistent storage handle for blocks requested by the module. */
  428. static uint32_t m_peer_addr_update; /**< 32-bit bitmap to remember peer device address update. */
  429. static ble_gap_id_key_t m_local_id_info; /**< ID information of central in case resolvable address is used. */
  430. static bool m_module_initialized = false; /**< State indicating if module is initialized or not. */
  431. static uint8_t m_irk_index_table[DEVICE_MANAGER_MAX_BONDS]; /**< List maintaining IRK index list. */
  432. SDK_MUTEX_DEFINE(m_dm_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */
  433. /** @} */
  434. static __INLINE ret_code_t no_service_context_store(pstorage_handle_t const * p_block_handle,
  435. dm_handle_t const * p_handle);
  436. static __INLINE ret_code_t gatts_context_store(pstorage_handle_t const * p_block_handle,
  437. dm_handle_t const * p_handle);
  438. static __INLINE ret_code_t gattc_context_store(pstorage_handle_t const * p_block_handle,
  439. dm_handle_t const * p_handle);
  440. static __INLINE ret_code_t gattsc_context_store(pstorage_handle_t const * p_block_handle,
  441. dm_handle_t const * p_handle);
  442. static __INLINE ret_code_t no_service_context_load(pstorage_handle_t const * p_block_handle,
  443. dm_handle_t const * p_handle);
  444. static __INLINE ret_code_t gatts_context_load(pstorage_handle_t const * p_block_handle,
  445. dm_handle_t const * p_handle);
  446. static __INLINE ret_code_t gattc_context_load(pstorage_handle_t const * p_block_handle,
  447. dm_handle_t const * p_handle);
  448. static __INLINE ret_code_t gattsc_context_load(pstorage_handle_t const * p_block_handle,
  449. dm_handle_t const * p_handle);
  450. static __INLINE ret_code_t no_service_context_apply(dm_handle_t * p_handle);
  451. static __INLINE ret_code_t gatts_context_apply(dm_handle_t * p_handle);
  452. static __INLINE ret_code_t gattc_context_apply(dm_handle_t * p_handle);
  453. static __INLINE ret_code_t gattsc_context_apply(dm_handle_t * p_handle);
  454. /**< Array of function pointers based on the types of service registered. */
  455. const service_context_access_t m_service_context_store[DM_SERVICE_CONTEXT_COUNT] =
  456. {
  457. no_service_context_store, /**< Dummy function, when there is no service context registered. */
  458. gatts_context_store, /**< GATT Server context store function. */
  459. gattc_context_store, /**< GATT Client context store function. */
  460. gattsc_context_store /**< GATT Server & Client context store function. */
  461. };
  462. /**< Array of function pointers based on the types of service registered. */
  463. const service_context_access_t m_service_context_load[DM_SERVICE_CONTEXT_COUNT] =
  464. {
  465. no_service_context_load, /**< Dummy function, when there is no service context registered. */
  466. gatts_context_load, /**< GATT Server context load function. */
  467. gattc_context_load, /**< GATT Client context load function. */
  468. gattsc_context_load /**< GATT Server & Client context load function. */
  469. };
  470. /**< Array of function pointers based on the types of service registered. */
  471. const service_context_apply_t m_service_context_apply[DM_SERVICE_CONTEXT_COUNT] =
  472. {
  473. no_service_context_apply, /**< Dummy function, when there is no service context registered. */
  474. gatts_context_apply, /**< GATT Server context apply function. */
  475. gattc_context_apply, /**< GATT Client context apply function. */
  476. gattsc_context_apply /**< GATT Server & Client context apply function. */
  477. };
  478. const uint32_t m_context_init_len = 0xFFFFFFFF; /**< Constant used to update the initial value for context in the flash. */
  479. /**@brief Function for setting update status for the device identified by 'index'.
  480. *
  481. * @param[in] index Device identifier.
  482. */
  483. static __INLINE void update_status_bit_set(uint32_t index)
  484. {
  485. m_peer_addr_update |= (BIT_0 << index);
  486. }
  487. /**@brief Function for resetting update status for device identified by 'index'.
  488. *
  489. * @param[in] index Device identifier.
  490. */
  491. static __INLINE void update_status_bit_reset(uint32_t index)
  492. {
  493. m_peer_addr_update &= (~((uint32_t)BIT_0 << index));
  494. }
  495. /**@brief Function for providing update status for the device identified by 'index'.
  496. *
  497. * @param[in] index Device identifier.
  498. *
  499. * @retval true if the bit is set, false otherwise.
  500. */
  501. static __INLINE bool update_status_bit_is_set(uint32_t index)
  502. {
  503. return ((m_peer_addr_update & (BIT_0 << index)) ? true : false);
  504. }
  505. /**@brief Function for initialiasing the application instance identified by 'index'.
  506. *
  507. * @param[in] index Device identifier.
  508. */
  509. static __INLINE void application_instance_init(uint32_t index)
  510. {
  511. DM_TRC("[DM]: Initializing Application Instance 0x%08X.\r\n", index);
  512. m_application_table[index].ntf_cb = NULL;
  513. m_application_table[index].state = 0x00;
  514. m_application_table[index].service = 0x00;
  515. }
  516. /**@brief Function for initialiasing the connection instance identified by 'index'.
  517. *
  518. * @param[in] index Device identifier.
  519. */
  520. static __INLINE void connection_instance_init(uint32_t index)
  521. {
  522. DM_TRC("[DM]: Initializing Connection Instance 0x%08X.\r\n", index);
  523. m_connection_table[index].state = STATE_IDLE;
  524. m_connection_table[index].conn_handle = BLE_CONN_HANDLE_INVALID;
  525. m_connection_table[index].bonded_dev_id = DM_INVALID_ID;
  526. memset(&m_connection_table[index].peer_addr, 0, sizeof (ble_gap_addr_t));
  527. }
  528. /**@brief Function for initialiasing the peer device instance identified by 'index'.
  529. *
  530. * @param[in] index Device identifier.
  531. */
  532. static __INLINE void peer_instance_init(uint32_t index)
  533. {
  534. DM_TRC("[DM]: Initializing Peer Instance 0x%08X.\r\n", index);
  535. memset(m_peer_table[index].peer_id.id_addr_info.addr, 0, BLE_GAP_ADDR_LEN);
  536. memset(m_peer_table[index].peer_id.id_info.irk, 0, BLE_GAP_SEC_KEY_LEN);
  537. //Initialize the address type to invalid.
  538. m_peer_table[index].peer_id.id_addr_info.addr_type = INVALID_ADDR_TYPE;
  539. //Initialize the identification bit map to unassigned.
  540. m_peer_table[index].id_bitmap = UNASSIGNED;
  541. // Initialize diversifier.
  542. m_peer_table[index].ediv = EDIV_INIT_VAL;
  543. //Reset the status bit.
  544. update_status_bit_reset(index);
  545. #if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
  546. //Initialize the application context for bond device.
  547. m_app_context_table[index] = NULL;
  548. #endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
  549. }
  550. /**@brief Function for searching connection instance matching the connection handle and the state
  551. * requested.
  552. *
  553. * @details Connection handle and state information is used to get a connection instance, it
  554. * is possible to ignore the connection handle by using BLE_CONN_HANDLE_INVALID.
  555. *
  556. * @param[in] conn_handle Connection handle.
  557. * @param[in] state Connection instance state.
  558. * @param[out] p_instance Connection instance.
  559. *
  560. * @retval NRF_SUCCESS Operation success.
  561. * @retval NRF_ERROR_INVALID_STATE Operation failure. Invalid state
  562. * @retval NRF_ERROR_NOT_FOUND Operation failure. Not found
  563. */
  564. static ret_code_t connection_instance_find(uint16_t conn_handle,
  565. uint8_t state,
  566. uint32_t * p_instance)
  567. {
  568. ret_code_t err_code;
  569. uint32_t index;
  570. err_code = NRF_ERROR_INVALID_STATE;
  571. for (index = 0; index < DEVICE_MANAGER_MAX_CONNECTIONS; index++)
  572. {
  573. //Search only based on the state.
  574. if (state & m_connection_table[index].state)
  575. {
  576. //Ignore the connection handle.
  577. if ((conn_handle == BLE_CONN_HANDLE_INVALID) ||
  578. (conn_handle == m_connection_table[index].conn_handle))
  579. {
  580. //Search for matching connection handle.
  581. (*p_instance) = index;
  582. err_code = NRF_SUCCESS;
  583. break;
  584. }
  585. else
  586. {
  587. err_code = NRF_ERROR_NOT_FOUND;
  588. }
  589. }
  590. }
  591. return err_code;
  592. }
  593. /**@brief Function for allocating device instance for a bonded device.
  594. *
  595. * @param[out] p_device_index Device index.
  596. * @param[in] p_addr Peer identification information.
  597. *
  598. * @retval NRF_SUCCESS Operation success.
  599. * @retval DM_DEVICE_CONTEXT_FULL Operation failure.
  600. */
  601. static __INLINE ret_code_t device_instance_allocate(uint8_t * p_device_index,
  602. ble_gap_addr_t const * p_addr)
  603. {
  604. ret_code_t err_code;
  605. uint32_t index;
  606. err_code = DM_DEVICE_CONTEXT_FULL;
  607. for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
  608. {
  609. DM_TRC("[DM]:[DI 0x%02X]: Device type 0x%02X.\r\n",
  610. index, m_peer_table[index].peer_id.id_addr_info.addr_type);
  611. DM_TRC("[DM]: Device Addr 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n",
  612. m_peer_table[index].peer_id.id_addr_info.addr[0],
  613. m_peer_table[index].peer_id.id_addr_info.addr[1],
  614. m_peer_table[index].peer_id.id_addr_info.addr[2],
  615. m_peer_table[index].peer_id.id_addr_info.addr[3],
  616. m_peer_table[index].peer_id.id_addr_info.addr[4],
  617. m_peer_table[index].peer_id.id_addr_info.addr[5]);
  618. if (m_peer_table[index].id_bitmap == UNASSIGNED)
  619. {
  620. if (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)
  621. {
  622. m_peer_table[index].id_bitmap &= (~ADDR_ENTRY);
  623. m_peer_table[index].peer_id.id_addr_info = (*p_addr);
  624. }
  625. else
  626. {
  627. m_peer_table[index].id_bitmap &= (~IRK_ENTRY);
  628. }
  629. (*p_device_index) = index;
  630. err_code = NRF_SUCCESS;
  631. DM_LOG("[DM]: Allocated device instance 0x%02X\r\n", index);
  632. break;
  633. }
  634. }
  635. return err_code;
  636. }
  637. /**@brief Function for freeing a device instance allocated for bonded device.
  638. *
  639. * @param[in] device_index Device index.
  640. *
  641. * @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
  642. */
  643. static __INLINE ret_code_t device_instance_free(uint32_t device_index)
  644. {
  645. ret_code_t err_code;
  646. pstorage_handle_t block_handle;
  647. //Get the block handle.
  648. err_code = pstorage_block_identifier_get(&m_storage_handle, device_index, &block_handle);
  649. if (err_code == NRF_SUCCESS)
  650. {
  651. DM_TRC("[DM]:[DI 0x%02X]: Freeing Instance.\r\n", device_index);
  652. //Request clearing of the block.
  653. err_code = pstorage_clear(&block_handle, ALL_CONTEXT_SIZE);
  654. if (err_code == NRF_SUCCESS)
  655. {
  656. peer_instance_init(device_index);
  657. }
  658. }
  659. return err_code;
  660. }
  661. /**@brief Function for searching for the device in the bonded device list.
  662. *
  663. * @param[in] p_addr Peer identification information.
  664. * @param[out] p_device_index Device index.
  665. *
  666. * @retval NRF_SUCCESS Operation success.
  667. * @retval NRF_ERROR_NOT_FOUND Operation failure.
  668. */
  669. static ret_code_t device_instance_find(ble_gap_addr_t const * p_addr, uint32_t * p_device_index, uint16_t ediv)
  670. {
  671. ret_code_t err_code;
  672. uint32_t index;
  673. err_code = NRF_ERROR_NOT_FOUND;
  674. if (NULL != p_addr)
  675. {
  676. DM_TRC("[DM]: Searching for device 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n",
  677. p_addr->addr[0],
  678. p_addr->addr[1],
  679. p_addr->addr[2],
  680. p_addr->addr[3],
  681. p_addr->addr[4],
  682. p_addr->addr[5]);
  683. }
  684. for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
  685. {
  686. DM_TRC("[DM]:[DI 0x%02X]: Device type 0x%02X.\r\n",
  687. index, m_peer_table[index].peer_id.id_addr_info.addr_type);
  688. DM_TRC("[DM]: Device Addr 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n",
  689. m_peer_table[index].peer_id.id_addr_info.addr[0],
  690. m_peer_table[index].peer_id.id_addr_info.addr[1],
  691. m_peer_table[index].peer_id.id_addr_info.addr[2],
  692. m_peer_table[index].peer_id.id_addr_info.addr[3],
  693. m_peer_table[index].peer_id.id_addr_info.addr[4],
  694. m_peer_table[index].peer_id.id_addr_info.addr[5]);
  695. if (((NULL == p_addr) && (ediv == m_peer_table[index].ediv)) ||
  696. ((NULL != p_addr) && (memcmp(&m_peer_table[index].peer_id.id_addr_info, p_addr, sizeof(ble_gap_addr_t)) == 0)))
  697. {
  698. DM_LOG("[DM]: Found device at instance 0x%02X\r\n", index);
  699. (*p_device_index) = index;
  700. err_code = NRF_SUCCESS;
  701. break;
  702. }
  703. }
  704. return err_code;
  705. }
  706. /**@brief Function for notifying connection manager event to the application.
  707. *
  708. * @param[in] p_handle Device handle identifying device.
  709. * @param[in] p_event Connection manager event details.
  710. * @param[in] event_result Event result code.
  711. */
  712. static __INLINE void app_evt_notify(dm_handle_t const * const p_handle,
  713. dm_event_t const * const p_event,
  714. uint32_t event_result)
  715. {
  716. dm_event_cb_t app_cb = m_application_table[0].ntf_cb;
  717. DM_MUTEX_UNLOCK();
  718. DM_TRC("[DM]: Notifying application of event 0x%02X\r\n", p_event->event_id);
  719. //No need to do any kind of return value processing thus can be supressed.
  720. UNUSED_VARIABLE(app_cb(p_handle, p_event, event_result));
  721. DM_MUTEX_LOCK();
  722. }
  723. /**@brief Function for allocating instance.
  724. *
  725. * @details The instance identifier is provided in the 'p_instance' parameter if the routine
  726. * succeeds.
  727. *
  728. * @param[out] p_instance Connection instance.
  729. *
  730. * @retval NRF_SUCCESS Operation success.
  731. * @retval NRF_ERROR_NO_MEM Operation failure. No memory.
  732. */
  733. static __INLINE uint32_t connection_instance_allocate(uint32_t * p_instance)
  734. {
  735. uint32_t err_code;
  736. DM_TRC("[DM]: Request to allocation connection instance\r\n");
  737. err_code = connection_instance_find(BLE_CONN_HANDLE_INVALID, STATE_IDLE, p_instance);
  738. if (err_code == NRF_SUCCESS)
  739. {
  740. DM_LOG("[DM]:[%02X]: Connection Instance Allocated.\r\n", (*p_instance));
  741. m_connection_table[*p_instance].state = STATE_CONNECTED;
  742. }
  743. else
  744. {
  745. DM_LOG("[DM]: No free connection instances available\r\n");
  746. err_code = NRF_ERROR_NO_MEM;
  747. }
  748. return err_code;
  749. }
  750. /**@brief Function for freeing instance. Instance identifier is provided in the parameter
  751. * 'p_instance' in case the routine succeeds.
  752. *
  753. * @param[in] p_instance Connection instance.
  754. */
  755. static __INLINE void connection_instance_free(uint32_t const * p_instance)
  756. {
  757. DM_TRC("[DM]:[CI 0x%02X]: Freeing connection instance\r\n", (*p_instance));
  758. if (m_connection_table[*p_instance].state != STATE_IDLE)
  759. {
  760. DM_LOG("[DM]:[%02X]: Freed connection instance.\r\n", (*p_instance));
  761. connection_instance_init(*p_instance);
  762. }
  763. }
  764. /**@brief Function for storage operation dummy handler.
  765. *
  766. * @param[in] p_dest Destination address where data is to be stored persistently.
  767. * @param[in] p_src Source address containing data to be stored. API assumes this to be resident
  768. * memory and no intermediate copy of data is made by the API.
  769. * @param[in] size Size of data to be stored expressed in bytes. Should be word aligned.
  770. * @param[in] offset Offset in bytes to be applied when writing to the block.
  771. * For example, if within a block of 100 bytes, application wishes to
  772. * write 20 bytes at offset of 12, then this field should be set to 12.
  773. * Should be word aligned.
  774. *
  775. * @retval NRF_SUCCESS Operation success.
  776. */
  777. static uint32_t storage_operation_dummy_handler(pstorage_handle_t * p_dest,
  778. uint8_t * p_src,
  779. pstorage_size_t size,
  780. pstorage_size_t offset)
  781. {
  782. return NRF_SUCCESS;
  783. }
  784. /**@brief Function for saving the device context persistently.
  785. *
  786. * @param[in] p_handle Device handle identifying device.
  787. * @param[in] state Device store state.
  788. */
  789. static __INLINE void device_context_store(dm_handle_t const * p_handle, device_store_state_t state)
  790. {
  791. pstorage_handle_t block_handle;
  792. storage_operation store_fn;
  793. ret_code_t err_code;
  794. DM_LOG("[DM]: --> device_context_store\r\n");
  795. err_code = pstorage_block_identifier_get(&m_storage_handle,
  796. p_handle->device_id,
  797. &block_handle);
  798. if (err_code == NRF_SUCCESS)
  799. {
  800. if ((STATE_BOND_INFO_UPDATE ==
  801. (m_connection_table[p_handle->connection_id].state & STATE_BOND_INFO_UPDATE)) ||
  802. (state == UPDATE_PEER_ADDR))
  803. {
  804. DM_LOG("[DM]:[DI %02X]:[CI %02X]: -> Updating bonding information.\r\n",
  805. p_handle->device_id, p_handle->connection_id);
  806. store_fn = pstorage_update;
  807. }
  808. else if (state == FIRST_BOND_STORE)
  809. {
  810. DM_LOG("[DM]:[DI %02X]:[CI %02X]: -> Storing bonding information.\r\n",
  811. p_handle->device_id, p_handle->connection_id);
  812. store_fn = pstorage_store;
  813. }
  814. else
  815. {
  816. DM_LOG("[DM]:[DI %02X]:[CI %02X]: -> No update in bonding information.\r\n",
  817. p_handle->device_id, p_handle->connection_id);
  818. //No operation needed.
  819. store_fn = storage_operation_dummy_handler;
  820. }
  821. //Store the peer id.
  822. err_code = store_fn(&block_handle,
  823. (uint8_t *)&m_peer_table[p_handle->device_id],
  824. PEER_ID_SIZE,
  825. PEER_ID_STORAGE_OFFSET);
  826. if ((err_code == NRF_SUCCESS) && (state != UPDATE_PEER_ADDR))
  827. {
  828. m_connection_table[p_handle->connection_id].state &= (~STATE_BOND_INFO_UPDATE);
  829. //Store the bond information.
  830. err_code = store_fn(&block_handle,
  831. (uint8_t *)&m_bond_table[p_handle->connection_id],
  832. BOND_SIZE,
  833. BOND_STORAGE_OFFSET);
  834. if (err_code != NRF_SUCCESS)
  835. {
  836. DM_ERR("[DM]:[0x%02X]:Failed to store bond information, reason 0x%08X\r\n",
  837. p_handle->device_id, err_code);
  838. }
  839. }
  840. if (state != UPDATE_PEER_ADDR)
  841. {
  842. //Store the service information
  843. err_code = m_service_context_store[m_application_table[p_handle->appl_id].service]
  844. (
  845. &block_handle,
  846. p_handle
  847. );
  848. if (err_code != NRF_SUCCESS)
  849. {
  850. //Notify application of an error event.
  851. DM_ERR("[DM]: Failed to store service context, reason %08X\r\n", err_code);
  852. }
  853. }
  854. }
  855. if (err_code != NRF_SUCCESS)
  856. {
  857. //Notify application of an error event.
  858. DM_ERR("[DM]: Failed to store device context, reason %08X\r\n", err_code);
  859. }
  860. }
  861. /**@brief Function for storing when there is no service registered.
  862. *
  863. * @param[in] p_block_handle Storage block identifier.
  864. * @param[in] p_handle Device handle identifying device that is loaded.
  865. *
  866. * @retval NRF_SUCCESS
  867. */
  868. static __INLINE ret_code_t no_service_context_store(pstorage_handle_t const * p_block_handle,
  869. dm_handle_t const * p_handle)
  870. {
  871. DM_LOG("[DM]: --> no_service_context_store\r\n");
  872. return NRF_SUCCESS;
  873. }
  874. /**@brief Function for storing GATT Server context.
  875. *
  876. * @param[in] p_block_handle Storage block identifier.
  877. * @param[in] p_handle Device handle identifying device that is stored.
  878. *
  879. * @retval NRF_SUCCESS Operation success.
  880. */
  881. static __INLINE ret_code_t gatts_context_store(pstorage_handle_t const * p_block_handle,
  882. dm_handle_t const * p_handle)
  883. {
  884. storage_operation store_fn;
  885. uint32_t attr_flags = BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS;
  886. uint16_t attr_len = DM_GATT_SERVER_ATTR_MAX_SIZE;
  887. uint8_t sys_data[DM_GATT_SERVER_ATTR_MAX_SIZE];
  888. DM_LOG("[DM]: --> gatts_context_store\r\n");
  889. uint32_t err_code = sd_ble_gatts_sys_attr_get(
  890. m_connection_table[p_handle->connection_id].conn_handle,
  891. sys_data,
  892. &attr_len,
  893. attr_flags);
  894. if (err_code == NRF_SUCCESS)
  895. {
  896. if (memcmp(m_gatts_table[p_handle->connection_id].attributes, sys_data, attr_len) == 0)
  897. {
  898. //No store operation is needed.
  899. DM_LOG("[DM]:[0x%02X]: No change in GATTS Context information.\r\n",
  900. p_handle->device_id);
  901. if ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) !=
  902. STATE_CONNECTED)
  903. {
  904. DM_LOG("[DM]:[0x%02X]: Resetting GATTS for active instance.\r\n",
  905. p_handle->connection_id);
  906. //Reset GATTS information for the current context.
  907. memset(&m_gatts_table[p_handle->connection_id], 0, sizeof(dm_gatts_context_t));
  908. }
  909. }
  910. else
  911. {
  912. if (m_gatts_table[p_handle->connection_id].size != 0)
  913. {
  914. //There is data already stored in persistent memory, therefore an update is needed.
  915. DM_LOG("[DM]:[0x%02X]: Updating stored service context\r\n", p_handle->device_id);
  916. store_fn = pstorage_update;
  917. }
  918. else
  919. {
  920. //Fresh write, a store is needed.
  921. DM_LOG("[DM]:[0x%02X]: Storing service context\r\n", p_handle->device_id);
  922. store_fn = pstorage_store;
  923. }
  924. m_gatts_table[p_handle->connection_id].flags = attr_flags;
  925. m_gatts_table[p_handle->connection_id].size = attr_len;
  926. memcpy(m_gatts_table[p_handle->connection_id].attributes, sys_data, attr_len);
  927. DM_DUMP((uint8_t *)&m_gatts_table[p_handle->connection_id], sizeof(dm_gatts_context_t));
  928. DM_LOG("[DM]:[0x%02X]: GATTS Data size 0x%08X\r\n",
  929. p_handle->device_id,
  930. m_gatts_table[p_handle->connection_id].size);
  931. //Store GATTS information.
  932. err_code = store_fn((pstorage_handle_t *)p_block_handle,
  933. (uint8_t *)&m_gatts_table[p_handle->connection_id],
  934. GATTS_SERVICE_CONTEXT_SIZE,
  935. SERVICE_STORAGE_OFFSET);
  936. if (err_code != NRF_SUCCESS)
  937. {
  938. DM_ERR("[DM]:[0x%02X]:Failed to store service context, reason 0x%08X\r\n",
  939. p_handle->device_id,
  940. err_code);
  941. }
  942. else
  943. {
  944. DM_LOG("[DM]: Service context successfully stored.\r\n");
  945. }
  946. }
  947. }
  948. return NRF_SUCCESS;
  949. }
  950. /**@brief Function for storing GATT Client context.
  951. *
  952. * @param[in] p_block_handle Storage block identifier.
  953. * @param[in] p_handle Device handle identifying device that is stored.
  954. *
  955. * @retval NRF_SUCCESS Operation success.
  956. */
  957. static __INLINE ret_code_t gattc_context_store(pstorage_handle_t const * p_block_handle,
  958. dm_handle_t const * p_handle)
  959. {
  960. DM_LOG("[DM]: --> gattc_context_store\r\n");
  961. return NRF_SUCCESS;
  962. }
  963. /**@brief Function for storing GATT Server & Client context.
  964. *
  965. * @param[in] p_block_handle Storage block identifier.
  966. * @param[in] p_handle Device handle identifying device that is stored.
  967. *
  968. * @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
  969. */
  970. static __INLINE ret_code_t gattsc_context_store(pstorage_handle_t const * p_block_handle,
  971. dm_handle_t const * p_handle)
  972. {
  973. DM_LOG("[DM]: --> gattsc_context_store\r\n");
  974. ret_code_t err_code = gatts_context_store(p_block_handle, p_handle);
  975. if (NRF_SUCCESS == err_code)
  976. {
  977. err_code = gattc_context_store(p_block_handle, p_handle);
  978. }
  979. return err_code;
  980. }
  981. /**@brief Function for loading when there is no service registered.
  982. *
  983. * @param[in] p_block_handle Storage block identifier.
  984. * @param[in] p_handle Device handle identifying device that is loaded.
  985. *
  986. * @retval NRF_SUCCESS
  987. */
  988. static __INLINE ret_code_t no_service_context_load(pstorage_handle_t const * p_block_handle,
  989. dm_handle_t const * p_handle)
  990. {
  991. DM_LOG("[DM]: --> no_service_context_load\r\n");
  992. return NRF_SUCCESS;
  993. }
  994. /**@brief Function for loading GATT Server context.
  995. *
  996. * @param[in] p_block_handle Storage block identifier.
  997. * @param[in] p_handle Device handle identifying device that is loaded.
  998. *
  999. * @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
  1000. */
  1001. static __INLINE ret_code_t gatts_context_load(pstorage_handle_t const * p_block_handle,
  1002. dm_handle_t const * p_handle)
  1003. {
  1004. DM_LOG("[DM]:[CI 0x%02X]:[DI 0x%02X]: --> gatts_context_load\r\n",
  1005. p_handle->connection_id,
  1006. p_handle->device_id);
  1007. ret_code_t err_code = pstorage_load((uint8_t *)&m_gatts_table[p_handle->connection_id],
  1008. (pstorage_handle_t *)p_block_handle,
  1009. GATTS_SERVICE_CONTEXT_SIZE,
  1010. SERVICE_STORAGE_OFFSET);
  1011. if (err_code == NRF_SUCCESS)
  1012. {
  1013. DM_LOG("[DM]:[%02X]:[Block ID 0x%08X]: Service context loaded, size 0x%08X\r\n",
  1014. p_handle->connection_id,
  1015. p_block_handle->block_id,
  1016. m_gatts_table[p_handle->connection_id].size);
  1017. DM_DUMP((uint8_t *)&m_gatts_table[p_handle->connection_id], sizeof(dm_gatts_context_t));
  1018. if (m_gatts_table[p_handle->connection_id].size == DM_GATTS_INVALID_SIZE)
  1019. {
  1020. m_gatts_table[p_handle->connection_id].size = 0;
  1021. }
  1022. }
  1023. else
  1024. {
  1025. DM_ERR("[DM]:[%02X]: Failed to load Service context, reason %08X\r\n",
  1026. p_handle->connection_id,
  1027. err_code);
  1028. }
  1029. return err_code;
  1030. }
  1031. /**@brief Function for loading GATT Client context.
  1032. *
  1033. * @param[in] p_block_handle Storage block identifier.
  1034. * @param[in] p_handle Device handle identifying device that is loaded.
  1035. *
  1036. * @retval NRF_SUCCESS
  1037. */
  1038. static __INLINE ret_code_t gattc_context_load(pstorage_handle_t const * p_block_handle,
  1039. dm_handle_t const * p_handle)
  1040. {
  1041. DM_LOG("[DM]: --> gattc_context_load\r\n");
  1042. return NRF_SUCCESS;
  1043. }
  1044. /**@brief Function for loading GATT Server & Client context.
  1045. *
  1046. * @param[in] p_block_handle Storage block identifier.
  1047. * @param[in] p_handle Device handle identifying device that is loaded.
  1048. *
  1049. * @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
  1050. */
  1051. static __INLINE ret_code_t gattsc_context_load(pstorage_handle_t const * p_block_handle,
  1052. dm_handle_t const * p_handle)
  1053. {
  1054. DM_LOG("[DM]: --> gattsc_context_load\r\n");
  1055. ret_code_t err_code = gatts_context_load(p_block_handle, p_handle);
  1056. if (NRF_SUCCESS == err_code)
  1057. {
  1058. err_code = gattc_context_load(p_block_handle, p_handle);
  1059. }
  1060. return err_code;
  1061. }
  1062. /**@brief Function for applying when there is no service registered.
  1063. *
  1064. * @param[in] p_handle Device handle identifying device that is applied.
  1065. *
  1066. * @retval NRF_SUCCESS
  1067. */
  1068. static __INLINE ret_code_t no_service_context_apply(dm_handle_t * p_handle)
  1069. {
  1070. DM_LOG("[DM]: --> no_service_context_apply\r\n");
  1071. DM_LOG("[DM]:[CI 0x%02X]: No Service context\r\n", p_handle->connection_id);
  1072. return NRF_SUCCESS;
  1073. }
  1074. /**@brief Function for applying GATT Server context.
  1075. *
  1076. * @param[in] p_handle Device handle identifying device that is applied.
  1077. *
  1078. * @retval NRF_SUCCESS On success.
  1079. * @retval DM_SERVICE_CONTEXT_NOT_APPLIED On failure.
  1080. */
  1081. static __INLINE ret_code_t gatts_context_apply(dm_handle_t * p_handle)
  1082. {
  1083. uint32_t err_code;
  1084. uint8_t * p_gatts_context = NULL;
  1085. uint16_t context_len = 0;
  1086. uint32_t context_flags = 0;
  1087. DM_LOG("[DM]: --> gatts_context_apply\r\n");
  1088. DM_LOG("[DM]:[CI 0x%02X]: State 0x%02X, Size 0x%08X\r\n",
  1089. p_handle->connection_id,
  1090. m_connection_table[p_handle->connection_id].state,
  1091. m_gatts_table[p_handle->connection_id].size);
  1092. if ((m_gatts_table[p_handle->connection_id].size != 0) &&
  1093. (
  1094. ((m_connection_table[p_handle->connection_id].state & STATE_LINK_ENCRYPTED) == STATE_LINK_ENCRYPTED) &&
  1095. ((m_connection_table[p_handle->connection_id].state & STATE_BOND_INFO_UPDATE)
  1096. != STATE_BOND_INFO_UPDATE)
  1097. )
  1098. )
  1099. {
  1100. DM_LOG("[DM]: Setting stored context.\r\n");
  1101. p_gatts_context = &m_gatts_table[p_handle->connection_id].attributes[0];
  1102. context_len = m_gatts_table[p_handle->connection_id].size;
  1103. context_flags = m_gatts_table[p_handle->connection_id].flags;
  1104. }
  1105. err_code = sd_ble_gatts_sys_attr_set(m_connection_table[p_handle->connection_id].conn_handle,
  1106. p_gatts_context,
  1107. context_len,
  1108. context_flags);
  1109. if (err_code == NRF_ERROR_INVALID_DATA)
  1110. {
  1111. // Indication that the ATT table has changed. Restore the system attributes to system
  1112. // services only and send a service changed indication if possible.
  1113. context_flags = BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS;
  1114. err_code = sd_ble_gatts_sys_attr_set(m_connection_table[p_handle->connection_id].conn_handle,
  1115. p_gatts_context,
  1116. context_len,
  1117. context_flags);
  1118. }
  1119. if (err_code != NRF_SUCCESS)
  1120. {
  1121. DM_LOG("[DM]: Failed to set system attributes, reason 0x%08X.\r\n", err_code);
  1122. err_code = DM_SERVICE_CONTEXT_NOT_APPLIED;
  1123. }
  1124. if (context_flags == BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS)
  1125. {
  1126. err_code = sd_ble_gatts_service_changed(m_connection_table[p_handle->connection_id].conn_handle,
  1127. 0x000C,
  1128. 0xFFFF);
  1129. if (err_code != NRF_SUCCESS)
  1130. {
  1131. DM_LOG("[DM]: Failed to send Service Changed indication, reason 0x%08X.\r\n", err_code);
  1132. if ((err_code != BLE_ERROR_INVALID_CONN_HANDLE) &&
  1133. (err_code != NRF_ERROR_INVALID_STATE) &&
  1134. (err_code != BLE_ERROR_NO_TX_PACKETS) &&
  1135. (err_code != NRF_ERROR_BUSY))
  1136. {
  1137. // Those errors can be expected when sending trying to send Service Changed
  1138. // Indication if the CCCD is not set to indicate. Thus set the returning error
  1139. // code to success.
  1140. err_code = NRF_SUCCESS;
  1141. }
  1142. else
  1143. {
  1144. err_code = DM_SERVICE_CONTEXT_NOT_APPLIED;
  1145. }
  1146. }
  1147. }
  1148. return err_code;
  1149. }
  1150. /**@brief Function for applying GATT Client context.
  1151. *
  1152. * @param[in] p_handle Device handle identifying device that is applied.
  1153. *
  1154. * @retval NRF_SUCCESS On success.
  1155. */
  1156. static __INLINE ret_code_t gattc_context_apply(dm_handle_t * p_handle)
  1157. {
  1158. DM_LOG("[DM]: --> gattc_context_apply\r\n");
  1159. return NRF_SUCCESS;
  1160. }
  1161. /**@brief Function for applying GATT Server & Client context.
  1162. *
  1163. * @param[in] p_handle Device handle identifying device that is applied.
  1164. *
  1165. * @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
  1166. */
  1167. static __INLINE ret_code_t gattsc_context_apply(dm_handle_t * p_handle)
  1168. {
  1169. uint32_t err_code;
  1170. DM_LOG("[DM]: --> gattsc_context_apply\r\n");
  1171. err_code = gatts_context_apply(p_handle);
  1172. if (err_code == NRF_SUCCESS)
  1173. {
  1174. err_code = gattc_context_apply(p_handle);
  1175. }
  1176. return err_code;
  1177. }
  1178. /**@brief Function for pstorage module callback.
  1179. *
  1180. * @param[in] p_handle Identifies module and block for which callback is received.
  1181. * @param[in] op_code Identifies the operation for which the event is notified.
  1182. * @param[in] result Identifies the result of flash access operation.
  1183. * NRF_SUCCESS implies, operation succeeded.
  1184. * @param[in] p_data Identifies the application data pointer. In case of store operation, this
  1185. * points to the resident source of application memory that application can now
  1186. * free or reuse. In case of clear, this is NULL as no application pointer is
  1187. * needed for this operation.
  1188. * @param[in] data_len Length of data provided by the application for the operation.
  1189. */
  1190. static void dm_pstorage_cb_handler(pstorage_handle_t * p_handle,
  1191. uint8_t op_code,
  1192. uint32_t result,
  1193. uint8_t * p_data,
  1194. uint32_t data_len)
  1195. {
  1196. VERIFY_APP_REGISTERED_VOID(0);
  1197. if (data_len > ALL_CONTEXT_SIZE)
  1198. {
  1199. //Clearing of all bonds at initialization, no event is generated.
  1200. return;
  1201. }
  1202. DM_MUTEX_LOCK();
  1203. dm_event_t dm_event;
  1204. dm_handle_t dm_handle;
  1205. dm_context_t context_data;
  1206. pstorage_handle_t block_handle;
  1207. uint32_t index_count;
  1208. uint32_t err_code;
  1209. bool app_notify = true;
  1210. err_code = dm_handle_initialize(&dm_handle);
  1211. APP_ERROR_CHECK(err_code);
  1212. dm_handle.appl_id = 0;
  1213. dm_event.event_id = 0x00;
  1214. //Construct the event which it is related to.
  1215. //Initialize context data information and length.
  1216. context_data.p_data = p_data;
  1217. context_data.len = data_len;
  1218. for (uint32_t index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
  1219. {
  1220. err_code = pstorage_block_identifier_get(&m_storage_handle, index, &block_handle);
  1221. if ((err_code == NRF_SUCCESS) &&
  1222. (
  1223. (memcmp(p_handle, &block_handle, sizeof(pstorage_handle_t)) == 0)
  1224. )
  1225. )
  1226. {
  1227. dm_handle.device_id = index;
  1228. break;
  1229. }
  1230. }
  1231. if (dm_handle.device_id != DM_INVALID_ID)
  1232. {
  1233. if (op_code == PSTORAGE_CLEAR_OP_CODE)
  1234. {
  1235. if (data_len == ALL_CONTEXT_SIZE)
  1236. {
  1237. dm_event.event_id = DM_EVT_DEVICE_CONTEXT_BASE;
  1238. }
  1239. else
  1240. {
  1241. dm_event.event_id = DM_EVT_APP_CONTEXT_BASE;
  1242. }
  1243. }
  1244. else
  1245. {
  1246. //Update or store operation.
  1247. //Context is identified based on the pointer value. Device context, application context
  1248. //and service context all have their own value range.
  1249. index_count = ((uint32_t)(p_data - (uint8_t *)m_peer_table)) / PEER_ID_SIZE;
  1250. if (index_count < DEVICE_MANAGER_MAX_BONDS)
  1251. {
  1252. dm_event.event_param.p_device_context = &context_data;
  1253. //Only the peer identification is stored, not bond information. Hence do not notify
  1254. //the application yet, unless the store operation resulted in a failure.
  1255. if ((result == NRF_SUCCESS) &&
  1256. (
  1257. (update_status_bit_is_set(dm_handle.device_id) == false)
  1258. )
  1259. )
  1260. {
  1261. app_notify = false;
  1262. }
  1263. else
  1264. {
  1265. //Reset update status since update is complete.
  1266. update_status_bit_reset(dm_handle.device_id);
  1267. //Notify application of error in storing the context.
  1268. dm_event.event_id = DM_EVT_DEVICE_CONTEXT_BASE;
  1269. }
  1270. }
  1271. else
  1272. {
  1273. index_count = ((uint32_t)(p_data - (uint8_t *)m_bond_table)) / BOND_SIZE;
  1274. if (index_count < DEVICE_MANAGER_MAX_CONNECTIONS)
  1275. {
  1276. DM_LOG("[DM]:[0x%02X]:[0x%02X]: Bond context Event\r\n",
  1277. dm_handle.device_id,
  1278. dm_handle.connection_id);
  1279. dm_event.event_param.p_device_context = &context_data;
  1280. dm_event.event_id = DM_EVT_DEVICE_CONTEXT_BASE;
  1281. dm_handle.connection_id = index_count;
  1282. ble_gap_sec_keyset_t keys_exchanged;
  1283. keys_exchanged.keys_peer.p_enc_key = NULL;
  1284. keys_exchanged.keys_peer.p_id_key = &m_local_id_info;
  1285. keys_exchanged.keys_own.p_enc_key = &m_bond_table[index_count].peer_enc_key;
  1286. keys_exchanged.keys_own.p_id_key = &m_peer_table[dm_handle.device_id].peer_id;
  1287. //Context information updated to provide the keys.
  1288. context_data.p_data = (uint8_t *)&keys_exchanged;
  1289. context_data.len = sizeof(ble_gap_sec_keyset_t);
  1290. }
  1291. else
  1292. {
  1293. index_count = ((uint32_t)(p_data - (uint8_t *)m_gatts_table)) /
  1294. GATTS_SERVICE_CONTEXT_SIZE;
  1295. if (index_count < DEVICE_MANAGER_MAX_CONNECTIONS)
  1296. {
  1297. DM_LOG("[DM]:[0x%02X]:[0x%02X]: Service context Event\r\n",
  1298. dm_handle.device_id,
  1299. dm_handle.connection_id);
  1300. //Notify application.
  1301. dm_event.event_id = DM_EVT_SERVICE_CONTEXT_BASE;
  1302. dm_handle.connection_id = index_count;
  1303. dm_handle.service_id = DM_PROTOCOL_CNTXT_GATT_SRVR_ID;
  1304. //Reset the service context now that it was successfully written to the
  1305. //application and the link is disconnected.
  1306. if ((m_connection_table[index_count].state & STATE_CONNECTED) !=
  1307. STATE_CONNECTED)
  1308. {
  1309. DM_LOG("[DM]:[0x%02X]:[0x%02X]: Resetting bond information for "
  1310. "active instance.\r\n",
  1311. dm_handle.device_id,
  1312. dm_handle.connection_id);
  1313. memset(&m_gatts_table[dm_handle.connection_id],
  1314. 0,
  1315. sizeof(dm_gatts_context_t));
  1316. }
  1317. }
  1318. else
  1319. {
  1320. DM_LOG("[DM]:[0x%02X]:[0x%02X]: App context Event\r\n",
  1321. dm_handle.device_id,
  1322. dm_handle.connection_id);
  1323. app_notify = false;
  1324. dm_event.event_id = DM_EVT_APP_CONTEXT_BASE;
  1325. #if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
  1326. if (p_data == (uint8_t *)(&m_context_init_len))
  1327. {
  1328. //Context data is deleted.
  1329. //This is a workaround to get the right event as on delete operation
  1330. //update operation is used instead of clear.
  1331. op_code = PSTORAGE_CLEAR_OP_CODE;
  1332. app_notify = true;
  1333. }
  1334. else if (m_app_context_table[dm_handle.device_id] == p_data)
  1335. {
  1336. app_notify = true;
  1337. dm_event.event_param.p_app_context = &context_data;
  1338. //Verify if the device is connected, if yes set connection instance.
  1339. for (uint32_t index = 0;
  1340. index < DEVICE_MANAGER_MAX_CONNECTIONS;
  1341. index++)
  1342. {
  1343. if (dm_handle.device_id == m_connection_table[index].bonded_dev_id)
  1344. {
  1345. dm_handle.connection_id = index;
  1346. break;
  1347. }
  1348. }
  1349. }
  1350. else
  1351. {
  1352. //No implementation needed.
  1353. }
  1354. #endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
  1355. }
  1356. }
  1357. }
  1358. }
  1359. if (app_notify == true)
  1360. {
  1361. if (op_code == PSTORAGE_CLEAR_OP_CODE)
  1362. {
  1363. dm_event.event_id |= DM_CLEAR_OPERATION_ID;
  1364. }
  1365. else if (op_code == PSTORAGE_LOAD_OP_CODE)
  1366. {
  1367. dm_event.event_id |= DM_LOAD_OPERATION_ID;
  1368. }
  1369. else
  1370. {
  1371. dm_event.event_id |= DM_STORE_OPERATION_ID;
  1372. }
  1373. dm_event.event_param.p_app_context = &context_data;
  1374. app_evt_notify(&dm_handle, &dm_event, result);
  1375. }
  1376. }
  1377. DM_MUTEX_UNLOCK();
  1378. }
  1379. ret_code_t dm_init(dm_init_param_t const * const p_init_param)
  1380. {
  1381. pstorage_module_param_t param;
  1382. pstorage_handle_t block_handle;
  1383. ret_code_t err_code;
  1384. uint32_t index;
  1385. DM_LOG("[DM]: >> dm_init.\r\n");
  1386. NULL_PARAM_CHECK(p_init_param);
  1387. SDK_MUTEX_INIT(m_dm_mutex);
  1388. DM_MUTEX_LOCK();
  1389. for (index = 0; index < DEVICE_MANAGER_MAX_APPLICATIONS; index++)
  1390. {
  1391. application_instance_init(index);
  1392. }
  1393. for (index = 0; index < DEVICE_MANAGER_MAX_CONNECTIONS; index++)
  1394. {
  1395. connection_instance_init(index);
  1396. }
  1397. memset(m_gatts_table, 0, sizeof(m_gatts_table));
  1398. //Initialization of all device instances.
  1399. for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
  1400. {
  1401. peer_instance_init(index);
  1402. m_irk_index_table[index] = DM_INVALID_ID;
  1403. }
  1404. //All context with respect to a particular device is stored contiguously.
  1405. param.block_size = ALL_CONTEXT_SIZE;
  1406. param.block_count = DEVICE_MANAGER_MAX_BONDS;
  1407. param.cb = dm_pstorage_cb_handler;
  1408. err_code = pstorage_register(&param, &m_storage_handle);
  1409. if (err_code == NRF_SUCCESS)
  1410. {
  1411. m_module_initialized = true;
  1412. if (p_init_param->clear_persistent_data == false)
  1413. {
  1414. DM_LOG("[DM]: Storage handle 0x%08X.\r\n", m_storage_handle.block_id);
  1415. //Copy bonded peer device address and IRK to RAM table.
  1416. //Bonded devices are stored in range (0,DEVICE_MANAGER_MAX_BONDS-1). The remaining
  1417. //range is for active connections that may or may not be bonded.
  1418. for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
  1419. {
  1420. err_code = pstorage_block_identifier_get(&m_storage_handle, index, &block_handle);
  1421. //Issue read request if you successfully get the block identifier.
  1422. if (err_code == NRF_SUCCESS)
  1423. {
  1424. DM_TRC("[DM]:[0x%02X]: Block handle 0x%08X.\r\n", index, block_handle.block_id);
  1425. err_code = pstorage_load((uint8_t *)&m_peer_table[index],
  1426. &block_handle,
  1427. sizeof(peer_id_t),
  1428. 0);
  1429. if (err_code != NRF_SUCCESS)
  1430. {
  1431. // In case a peer device could not be loaded successfully, rest of the
  1432. // initialization procedure are skipped and an error is sent to the
  1433. // application.
  1434. DM_ERR(
  1435. "[DM]: Failed to load peer device %08X from storage, reason %08X.\r\n",
  1436. index,
  1437. err_code);
  1438. m_module_initialized = false;
  1439. break;
  1440. }
  1441. else
  1442. {
  1443. DM_TRC("[DM]:[DI 0x%02X]: Device type 0x%02X.\r\n",
  1444. index,
  1445. m_peer_table[index].peer_id.id_addr_info.addr_type);
  1446. DM_TRC("[DM]: Device Addr 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n",
  1447. m_peer_table[index].peer_id.id_addr_info.addr[0],
  1448. m_peer_table[index].peer_id.id_addr_info.addr[1],
  1449. m_peer_table[index].peer_id.id_addr_info.addr[2],
  1450. m_peer_table[index].peer_id.id_addr_info.addr[3],
  1451. m_peer_table[index].peer_id.id_addr_info.addr[4],
  1452. m_peer_table[index].peer_id.id_addr_info.addr[5]);
  1453. }
  1454. }
  1455. else
  1456. {
  1457. //In case a peer device could not be loaded successfully, rest of the
  1458. //initialization procedure are skipped and an error is sent to the application.
  1459. DM_LOG("[DM]: Failed to get block handle for instance %08X, reason %08X.\r\n",
  1460. index,
  1461. err_code);
  1462. m_module_initialized = false;
  1463. break;
  1464. }
  1465. }
  1466. }
  1467. else
  1468. {
  1469. err_code = pstorage_clear(&m_storage_handle, (param.block_size * param.block_count));
  1470. DM_ERR("[DM]: Successfully requested clear of persistent data.\r\n");
  1471. }
  1472. }
  1473. else
  1474. {
  1475. DM_ERR("[DM]: Failed to register with storage module, reason 0x%08X.\r\n", err_code);
  1476. }
  1477. DM_MUTEX_UNLOCK();
  1478. DM_TRC("[DM]: << dm_init.\r\n");
  1479. return err_code;
  1480. }
  1481. ret_code_t dm_register(dm_application_instance_t * p_appl_instance,
  1482. dm_application_param_t const * p_appl_param)
  1483. {
  1484. VERIFY_MODULE_INITIALIZED();
  1485. NULL_PARAM_CHECK(p_appl_instance);
  1486. NULL_PARAM_CHECK(p_appl_param);
  1487. NULL_PARAM_CHECK(p_appl_param->evt_handler);
  1488. DM_MUTEX_LOCK();
  1489. DM_LOG("[DM]: >> dm_register.\r\n");
  1490. uint32_t err_code;
  1491. //Verify if an application instance is available. Currently only one instance is supported.
  1492. if (m_application_table[0].ntf_cb == NULL)
  1493. {
  1494. DM_LOG("[DM]: Application Instance allocated.\r\n");
  1495. //Mark instance as allocated.
  1496. m_application_table[0].ntf_cb = p_appl_param->evt_handler;
  1497. m_application_table[0].sec_param = p_appl_param->sec_param;
  1498. m_application_table[0].service = p_appl_param->service_type;
  1499. m_application_table[0].sec_param.kdist_peer.enc = 0;
  1500. m_application_table[0].sec_param.kdist_peer.id = 1;
  1501. m_application_table[0].sec_param.kdist_peer.sign = 0;
  1502. m_application_table[0].sec_param.kdist_own.enc = 1;
  1503. m_application_table[0].sec_param.kdist_own.id = 1;
  1504. m_application_table[0].sec_param.kdist_own.sign = 0;
  1505. //Populate application's instance variable with the assigned allocation instance.
  1506. *p_appl_instance = 0;
  1507. err_code = NRF_SUCCESS;
  1508. }
  1509. else
  1510. {
  1511. err_code = (NRF_ERROR_NO_MEM | DEVICE_MANAGER_ERR_BASE);
  1512. }
  1513. DM_MUTEX_UNLOCK();
  1514. DM_TRC("[DM]: << dm_register.\r\n");
  1515. return err_code;
  1516. }
  1517. ret_code_t dm_security_setup_req(dm_handle_t * p_handle)
  1518. {
  1519. VERIFY_MODULE_INITIALIZED();
  1520. NULL_PARAM_CHECK(p_handle);
  1521. VERIFY_APP_REGISTERED(p_handle->appl_id);
  1522. VERIFY_CONNECTION_INSTANCE(p_handle->connection_id);
  1523. DM_MUTEX_LOCK();
  1524. DM_LOG("[DM]: >> dm_security_setup_req\r\n");
  1525. uint32_t err_code = (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE);
  1526. if ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) == STATE_CONNECTED)
  1527. {
  1528. err_code = sd_ble_gap_authenticate(m_connection_table[p_handle->connection_id].conn_handle,
  1529. &m_application_table[0].sec_param);
  1530. }
  1531. DM_TRC("[DM]: << dm_security_setup_req, 0x%08X\r\n", err_code);
  1532. DM_MUTEX_UNLOCK();
  1533. return err_code;
  1534. }
  1535. ret_code_t dm_security_status_req(dm_handle_t const * p_handle,
  1536. dm_security_status_t * p_status)
  1537. {
  1538. VERIFY_MODULE_INITIALIZED();
  1539. NULL_PARAM_CHECK(p_handle);
  1540. NULL_PARAM_CHECK(p_status);
  1541. VERIFY_APP_REGISTERED(p_handle->appl_id);
  1542. VERIFY_CONNECTION_INSTANCE(p_handle->connection_id);
  1543. DM_MUTEX_LOCK();
  1544. DM_LOG("[DM]: >> dm_security_status_req\r\n");
  1545. if ((m_connection_table[p_handle->connection_id].state & STATE_PAIRING) ||
  1546. (m_connection_table[p_handle->connection_id].state & STATE_PAIRING_PENDING))
  1547. {
  1548. (*p_status) = ENCRYPTION_IN_PROGRESS;
  1549. }
  1550. else if (m_connection_table[p_handle->connection_id].state & STATE_LINK_ENCRYPTED)
  1551. {
  1552. (*p_status) = ENCRYPTED;
  1553. }
  1554. else
  1555. {
  1556. (*p_status) = NOT_ENCRYPTED;
  1557. }
  1558. DM_TRC("[DM]: << dm_security_status_req\r\n");
  1559. DM_MUTEX_UNLOCK();
  1560. return NRF_SUCCESS;
  1561. }
  1562. ret_code_t dm_whitelist_create(dm_application_instance_t const * p_handle,
  1563. ble_gap_whitelist_t * p_whitelist)
  1564. {
  1565. VERIFY_MODULE_INITIALIZED();
  1566. NULL_PARAM_CHECK(p_handle);
  1567. NULL_PARAM_CHECK(p_whitelist);
  1568. NULL_PARAM_CHECK(p_whitelist->pp_addrs);
  1569. NULL_PARAM_CHECK(p_whitelist->pp_irks);
  1570. VERIFY_APP_REGISTERED(*p_handle);
  1571. DM_MUTEX_LOCK();
  1572. DM_LOG("[DM]: >> dm_whitelist_create\r\n");
  1573. uint32_t addr_count = 0;
  1574. uint32_t irk_count = 0;
  1575. bool connected = false;
  1576. for (uint32_t index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
  1577. {
  1578. connected = false;
  1579. for (uint32_t c_index = 0; c_index < DEVICE_MANAGER_MAX_CONNECTIONS; c_index++)
  1580. {
  1581. if ((index == m_connection_table[c_index].bonded_dev_id) &&
  1582. ((m_connection_table[c_index].state & STATE_CONNECTED) == STATE_CONNECTED))
  1583. {
  1584. connected = true;
  1585. break;
  1586. }
  1587. }
  1588. if (connected == false)
  1589. {
  1590. if ((irk_count < p_whitelist->irk_count) &&
  1591. ((m_peer_table[index].id_bitmap & IRK_ENTRY) == 0))
  1592. {
  1593. p_whitelist->pp_irks[irk_count] = &m_peer_table[index].peer_id.id_info;
  1594. m_irk_index_table[irk_count] = index;
  1595. irk_count++;
  1596. }
  1597. if ((addr_count < p_whitelist->addr_count) &&
  1598. (m_peer_table[index].id_bitmap & ADDR_ENTRY) == 0)
  1599. {
  1600. p_whitelist->pp_addrs[addr_count] = &m_peer_table[index].peer_id.id_addr_info;
  1601. addr_count++;
  1602. }
  1603. }
  1604. }
  1605. p_whitelist->addr_count = addr_count;
  1606. p_whitelist->irk_count = irk_count;
  1607. DM_LOG("[DM]: Created whitelist, number of IRK = 0x%02X, number of addr = 0x%02X\r\n",
  1608. irk_count,
  1609. addr_count);
  1610. DM_TRC("[DM]: << dm_whitelist_create\r\n");
  1611. DM_MUTEX_UNLOCK();
  1612. return NRF_SUCCESS;
  1613. }
  1614. ret_code_t dm_device_add(dm_handle_t * p_handle,
  1615. dm_device_context_t const * p_context)
  1616. {
  1617. return (API_NOT_IMPLEMENTED | DEVICE_MANAGER_ERR_BASE);
  1618. }
  1619. ret_code_t dm_device_delete(dm_handle_t const * p_handle)
  1620. {
  1621. VERIFY_MODULE_INITIALIZED();
  1622. NULL_PARAM_CHECK(p_handle);
  1623. VERIFY_APP_REGISTERED(p_handle->appl_id);
  1624. VERIFY_DEVICE_INSTANCE(p_handle->device_id);
  1625. DM_MUTEX_LOCK();
  1626. DM_TRC("[DM]: >> dm_device_delete\r\n");
  1627. uint32_t err_code = device_instance_free(p_handle->device_id);
  1628. DM_TRC("[DM]: << dm_device_delete\r\n");
  1629. DM_MUTEX_UNLOCK();
  1630. return err_code;
  1631. }
  1632. ret_code_t dm_device_delete_all(dm_application_instance_t const * p_handle)
  1633. {
  1634. VERIFY_MODULE_INITIALIZED();
  1635. NULL_PARAM_CHECK(p_handle);
  1636. VERIFY_APP_REGISTERED((*p_handle));
  1637. DM_MUTEX_LOCK();
  1638. uint32_t err_code = NRF_SUCCESS;
  1639. DM_TRC("[DM]: >> dm_device_delete_all\r\n");
  1640. for (uint32_t index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
  1641. {
  1642. if (m_peer_table[index].id_bitmap != UNASSIGNED)
  1643. {
  1644. err_code = device_instance_free(index);
  1645. }
  1646. }
  1647. DM_TRC("[DM]: << dm_device_delete_all\r\n");
  1648. DM_MUTEX_UNLOCK();
  1649. return err_code;
  1650. }
  1651. ret_code_t dm_service_context_set(dm_handle_t const * p_handle,
  1652. dm_service_context_t const * p_context)
  1653. {
  1654. VERIFY_MODULE_INITIALIZED();
  1655. NULL_PARAM_CHECK(p_handle);
  1656. NULL_PARAM_CHECK(p_context);
  1657. VERIFY_APP_REGISTERED(p_handle->appl_id);
  1658. VERIFY_CONNECTION_INSTANCE(p_handle->connection_id);
  1659. VERIFY_DEVICE_INSTANCE(p_handle->device_id);
  1660. DM_MUTEX_LOCK();
  1661. DM_TRC("[DM]: >> dm_service_context_set\r\n");
  1662. if ((p_context->context_data.p_data != NULL) &&
  1663. (
  1664. (p_context->context_data.len != 0) &&
  1665. (p_context->context_data.len < DM_GATT_SERVER_ATTR_MAX_SIZE)
  1666. )
  1667. )
  1668. {
  1669. if (p_context->service_type == DM_PROTOCOL_CNTXT_GATT_SRVR_ID)
  1670. {
  1671. memcpy(m_gatts_table[p_handle->connection_id].attributes,
  1672. p_context->context_data.p_data,
  1673. p_context->context_data.len);
  1674. }
  1675. }
  1676. pstorage_handle_t block_handle;
  1677. uint32_t err_code = pstorage_block_identifier_get(&m_storage_handle,
  1678. p_handle->device_id,
  1679. &block_handle);
  1680. err_code = m_service_context_store[p_context->service_type](&block_handle, p_handle);
  1681. DM_TRC("[DM]: << dm_service_context_set\r\n");
  1682. DM_MUTEX_UNLOCK();
  1683. return err_code;
  1684. }
  1685. ret_code_t dm_service_context_get(dm_handle_t const * p_handle,
  1686. dm_service_context_t * p_context)
  1687. {
  1688. VERIFY_MODULE_INITIALIZED();
  1689. NULL_PARAM_CHECK(p_handle);
  1690. NULL_PARAM_CHECK(p_context);
  1691. VERIFY_APP_REGISTERED(p_handle->appl_id);
  1692. VERIFY_DEVICE_INSTANCE(p_handle->device_id);
  1693. if ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) != STATE_CONNECTED)
  1694. {
  1695. DM_TRC("[DM]: Device must be connected to get context. \r\n");
  1696. return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE);
  1697. }
  1698. DM_MUTEX_LOCK();
  1699. DM_TRC("[DM]: >> dm_service_context_get\r\n");
  1700. if (p_context->service_type == DM_PROTOCOL_CNTXT_GATT_SRVR_ID)
  1701. {
  1702. p_context->context_data.p_data = m_gatts_table[p_handle->connection_id].attributes;
  1703. p_context->context_data.len = m_gatts_table[p_handle->connection_id].size;
  1704. }
  1705. pstorage_handle_t block_handle;
  1706. uint32_t err_code = pstorage_block_identifier_get(&m_storage_handle,
  1707. p_handle->device_id,
  1708. &block_handle);
  1709. err_code = m_service_context_load[p_context->service_type](&block_handle, p_handle);
  1710. if (p_context->service_type == DM_PROTOCOL_CNTXT_GATT_SRVR_ID)
  1711. {
  1712. p_context->context_data.p_data = m_gatts_table[p_handle->connection_id].attributes;
  1713. p_context->context_data.len = m_gatts_table[p_handle->connection_id].size;
  1714. }
  1715. DM_TRC("[DM]: << dm_service_context_get\r\n");
  1716. DM_MUTEX_UNLOCK();
  1717. return err_code;
  1718. }
  1719. ret_code_t dm_service_context_delete(dm_handle_t const * p_handle)
  1720. {
  1721. VERIFY_MODULE_INITIALIZED();
  1722. NULL_PARAM_CHECK(p_handle);
  1723. VERIFY_APP_REGISTERED(p_handle->appl_id);
  1724. VERIFY_DEVICE_INSTANCE(p_handle->device_id);
  1725. DM_LOG("[DM]: Context delete is not supported yet.\r\n");
  1726. return (API_NOT_IMPLEMENTED | DEVICE_MANAGER_ERR_BASE);
  1727. }
  1728. ret_code_t dm_application_context_set(dm_handle_t const * p_handle,
  1729. dm_application_context_t const * p_context)
  1730. {
  1731. #if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
  1732. VERIFY_MODULE_INITIALIZED();
  1733. NULL_PARAM_CHECK(p_handle);
  1734. NULL_PARAM_CHECK(p_context);
  1735. NULL_PARAM_CHECK(p_context->p_data);
  1736. VERIFY_APP_REGISTERED(p_handle->appl_id);
  1737. VERIFY_DEVICE_INSTANCE(p_handle->device_id);
  1738. VERIFY_DEVICE_BOND(p_handle->connection_id);
  1739. SIZE_CHECK_APP_CONTEXT(p_context->len);
  1740. DM_MUTEX_LOCK();
  1741. DM_TRC("[DM]: >> dm_application_context_set\r\n");
  1742. uint32_t err_code;
  1743. uint32_t context_len;
  1744. pstorage_handle_t block_handle;
  1745. storage_operation store_fn = pstorage_store;
  1746. err_code = pstorage_block_identifier_get(&m_storage_handle,
  1747. p_handle->device_id,
  1748. &block_handle);
  1749. if (err_code == NRF_SUCCESS)
  1750. {
  1751. err_code = pstorage_load((uint8_t *)&context_len,
  1752. &block_handle,
  1753. sizeof(uint32_t),
  1754. APP_CONTEXT_STORAGE_OFFSET);
  1755. if ((err_code == NRF_SUCCESS) && (context_len != INVALID_CONTEXT_LEN))
  1756. {
  1757. //Data already exists. Need an update.
  1758. store_fn = pstorage_update;
  1759. DM_LOG("[DM]:[DI 0x%02X]: Updating existing application context, existing len 0x%08X, "
  1760. "new length 0x%08X.\r\n",
  1761. p_handle->device_id,
  1762. context_len,
  1763. p_context->len);
  1764. }
  1765. else
  1766. {
  1767. DM_LOG("[DM]: Storing application context.\r\n");
  1768. }
  1769. //Store/update context length.
  1770. err_code = store_fn(&block_handle,
  1771. (uint8_t *)(&p_context->len),
  1772. sizeof(uint32_t),
  1773. APP_CONTEXT_STORAGE_OFFSET);
  1774. if (err_code == NRF_SUCCESS)
  1775. {
  1776. //Update context data is used for application context as flash is never
  1777. //cleared if a delete of application context is called.
  1778. err_code = pstorage_update(&block_handle,
  1779. p_context->p_data,
  1780. DEVICE_MANAGER_APP_CONTEXT_SIZE,
  1781. (APP_CONTEXT_STORAGE_OFFSET + sizeof(uint32_t)));
  1782. if (err_code == NRF_SUCCESS)
  1783. {
  1784. m_app_context_table[p_handle->device_id] = p_context->p_data;
  1785. }
  1786. }
  1787. }
  1788. DM_TRC("[DM]: << dm_application_context_set\r\n");
  1789. DM_MUTEX_UNLOCK();
  1790. return err_code;
  1791. #else //DEVICE_MANAGER_APP_CONTEXT_SIZE
  1792. return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE);
  1793. #endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
  1794. }
  1795. ret_code_t dm_application_context_get(dm_handle_t const * p_handle,
  1796. dm_application_context_t * p_context)
  1797. {
  1798. #if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
  1799. VERIFY_MODULE_INITIALIZED();
  1800. NULL_PARAM_CHECK(p_handle);
  1801. NULL_PARAM_CHECK(p_context);
  1802. VERIFY_APP_REGISTERED(p_handle->appl_id);
  1803. VERIFY_DEVICE_INSTANCE(p_handle->device_id);
  1804. DM_MUTEX_LOCK();
  1805. DM_TRC("[DM]: >> dm_application_context_get\r\n");
  1806. uint32_t context_len;
  1807. uint32_t err_code;
  1808. pstorage_handle_t block_handle;
  1809. //Check if the context exists.
  1810. if (NULL == p_context->p_data)
  1811. {
  1812. p_context->p_data = m_app_context_table[p_handle->device_id];
  1813. }
  1814. else
  1815. {
  1816. m_app_context_table[p_handle->device_id] = p_context->p_data;
  1817. }
  1818. err_code = pstorage_block_identifier_get(&m_storage_handle,
  1819. p_handle->device_id,
  1820. &block_handle);
  1821. if (err_code == NRF_SUCCESS)
  1822. {
  1823. err_code = pstorage_load((uint8_t *)&context_len,
  1824. &block_handle,
  1825. sizeof(uint32_t),
  1826. APP_CONTEXT_STORAGE_OFFSET);
  1827. if ((err_code == NRF_SUCCESS) && (context_len != INVALID_CONTEXT_LEN))
  1828. {
  1829. err_code = pstorage_load(p_context->p_data,
  1830. &block_handle,
  1831. DEVICE_MANAGER_APP_CONTEXT_SIZE,
  1832. (APP_CONTEXT_STORAGE_OFFSET + sizeof(uint32_t)));
  1833. if (err_code == NRF_SUCCESS)
  1834. {
  1835. p_context->len = context_len;
  1836. }
  1837. }
  1838. else
  1839. {
  1840. err_code = DM_NO_APP_CONTEXT;
  1841. }
  1842. }
  1843. DM_TRC("[DM]: << dm_application_context_get\r\n");
  1844. DM_MUTEX_UNLOCK();
  1845. return err_code;
  1846. #else //DEVICE_MANAGER_APP_CONTEXT_SIZE
  1847. return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE);
  1848. #endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
  1849. }
  1850. ret_code_t dm_application_context_delete(const dm_handle_t * p_handle)
  1851. {
  1852. #if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
  1853. VERIFY_MODULE_INITIALIZED();
  1854. NULL_PARAM_CHECK(p_handle);
  1855. VERIFY_APP_REGISTERED(p_handle->appl_id);
  1856. VERIFY_DEVICE_INSTANCE(p_handle->device_id);
  1857. DM_MUTEX_LOCK();
  1858. DM_TRC("[DM]: >> dm_application_context_delete\r\n");
  1859. uint32_t err_code;
  1860. uint32_t context_len;
  1861. pstorage_handle_t block_handle;
  1862. err_code = pstorage_block_identifier_get(&m_storage_handle,
  1863. p_handle->device_id,
  1864. &block_handle);
  1865. if (err_code == NRF_SUCCESS)
  1866. {
  1867. err_code = pstorage_load((uint8_t *)&context_len,
  1868. &block_handle,
  1869. sizeof(uint32_t),
  1870. APP_CONTEXT_STORAGE_OFFSET);
  1871. if (context_len != m_context_init_len)
  1872. {
  1873. err_code = pstorage_update(&block_handle,
  1874. (uint8_t *)&m_context_init_len,
  1875. sizeof(uint32_t),
  1876. APP_CONTEXT_STORAGE_OFFSET);
  1877. if (err_code != NRF_SUCCESS)
  1878. {
  1879. DM_ERR("[DM]: Failed to delete application context, reason 0x%08X\r\n", err_code);
  1880. }
  1881. else
  1882. {
  1883. m_app_context_table[p_handle->device_id] = NULL;
  1884. }
  1885. }
  1886. }
  1887. DM_TRC("[DM]: << dm_application_context_delete\r\n");
  1888. DM_MUTEX_UNLOCK();
  1889. return err_code;
  1890. #else //DEVICE_MANAGER_APP_CONTEXT_SIZE
  1891. return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE);
  1892. #endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
  1893. }
  1894. ret_code_t dm_application_instance_set(dm_application_instance_t const * p_appl_instance,
  1895. dm_handle_t * p_handle)
  1896. {
  1897. VERIFY_MODULE_INITIALIZED();
  1898. NULL_PARAM_CHECK(p_handle);
  1899. NULL_PARAM_CHECK(p_appl_instance);
  1900. VERIFY_APP_REGISTERED((*p_appl_instance));
  1901. p_handle->appl_id = (*p_appl_instance);
  1902. return NRF_SUCCESS;
  1903. }
  1904. uint32_t dm_handle_initialize(dm_handle_t * p_handle)
  1905. {
  1906. NULL_PARAM_CHECK(p_handle);
  1907. p_handle->appl_id = DM_INVALID_ID;
  1908. p_handle->connection_id = DM_INVALID_ID;
  1909. p_handle->device_id = DM_INVALID_ID;
  1910. p_handle->service_id = DM_INVALID_ID;
  1911. return NRF_SUCCESS;
  1912. }
  1913. ret_code_t dm_peer_addr_set(dm_handle_t const * p_handle,
  1914. ble_gap_addr_t const * p_addr)
  1915. {
  1916. VERIFY_MODULE_INITIALIZED();
  1917. NULL_PARAM_CHECK(p_handle);
  1918. NULL_PARAM_CHECK(p_addr);
  1919. VERIFY_APP_REGISTERED(p_handle->appl_id);
  1920. VERIFY_DEVICE_INSTANCE(p_handle->device_id);
  1921. DM_MUTEX_LOCK();
  1922. DM_TRC("[DM]: >> dm_peer_addr_set\r\n");
  1923. ret_code_t err_code;
  1924. if ((p_handle->connection_id == DM_INVALID_ID) &&
  1925. (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE))
  1926. {
  1927. m_peer_table[p_handle->device_id].peer_id.id_addr_info = (*p_addr);
  1928. update_status_bit_set(p_handle->device_id);
  1929. device_context_store(p_handle, UPDATE_PEER_ADDR);
  1930. err_code = NRF_SUCCESS;
  1931. }
  1932. else
  1933. {
  1934. err_code = (NRF_ERROR_INVALID_PARAM | DEVICE_MANAGER_ERR_BASE);
  1935. }
  1936. DM_TRC("[DM]: << dm_peer_addr_set\r\n");
  1937. DM_MUTEX_UNLOCK();
  1938. return err_code;
  1939. }
  1940. ret_code_t dm_peer_addr_get(dm_handle_t const * p_handle,
  1941. ble_gap_addr_t * p_addr)
  1942. {
  1943. VERIFY_MODULE_INITIALIZED();
  1944. NULL_PARAM_CHECK(p_handle);
  1945. NULL_PARAM_CHECK(p_addr);
  1946. VERIFY_APP_REGISTERED(p_handle->appl_id);
  1947. DM_MUTEX_LOCK();
  1948. DM_TRC("[DM]: >> dm_peer_addr_get\r\n");
  1949. ret_code_t err_code;
  1950. err_code = (NRF_ERROR_NOT_FOUND | DEVICE_MANAGER_ERR_BASE);
  1951. if (p_handle->device_id == DM_INVALID_ID)
  1952. {
  1953. if ((p_handle->connection_id != DM_INVALID_ID) &&
  1954. ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) ==
  1955. STATE_CONNECTED))
  1956. {
  1957. DM_TRC("[DM]:[CI 0x%02X]: Address get for non bonded active connection.\r\n",
  1958. p_handle->connection_id);
  1959. (*p_addr) = m_connection_table[p_handle->connection_id].peer_addr;
  1960. err_code = NRF_SUCCESS;
  1961. }
  1962. }
  1963. else
  1964. {
  1965. if ((m_peer_table[p_handle->device_id].id_bitmap & ADDR_ENTRY) == 0)
  1966. {
  1967. DM_TRC("[DM]:[DI 0x%02X]: Address get for bonded device.\r\n",
  1968. p_handle->device_id);
  1969. (*p_addr) = m_peer_table[p_handle->device_id].peer_id.id_addr_info;
  1970. err_code = NRF_SUCCESS;
  1971. }
  1972. }
  1973. DM_TRC("[DM]: << dm_peer_addr_get\r\n");
  1974. DM_MUTEX_UNLOCK();
  1975. return err_code;
  1976. }
  1977. ret_code_t dm_distributed_keys_get(dm_handle_t const * p_handle,
  1978. dm_sec_keyset_t * p_key_dist)
  1979. {
  1980. VERIFY_MODULE_INITIALIZED();
  1981. NULL_PARAM_CHECK(p_handle);
  1982. NULL_PARAM_CHECK(p_key_dist);
  1983. VERIFY_APP_REGISTERED(p_handle->appl_id);
  1984. VERIFY_DEVICE_INSTANCE(p_handle->device_id);
  1985. DM_MUTEX_LOCK();
  1986. DM_TRC("[DM]: >> dm_distributed_keys_get\r\n");
  1987. ret_code_t err_code;
  1988. ble_gap_enc_key_t peer_enc_key;
  1989. pstorage_handle_t block_handle;
  1990. err_code = NRF_ERROR_NOT_FOUND;
  1991. p_key_dist->keys_central.enc_key.p_enc_key = NULL;
  1992. p_key_dist->keys_central.p_id_key = (dm_id_key_t *)&m_peer_table[p_handle->device_id].peer_id;
  1993. p_key_dist->keys_central.p_sign_key = NULL;
  1994. p_key_dist->keys_periph.p_id_key = (dm_id_key_t *)&m_local_id_info;
  1995. p_key_dist->keys_periph.p_sign_key = NULL;
  1996. p_key_dist->keys_periph.enc_key.p_enc_key = (dm_enc_key_t *)&peer_enc_key;
  1997. if ((m_peer_table[p_handle->device_id].id_bitmap & IRK_ENTRY) == 0)
  1998. {
  1999. // p_key_dist->keys_periph.p_id_key->id_addr_info.addr_type = INVALID_ADDR_TYPE;
  2000. }
  2001. err_code = pstorage_block_identifier_get(&m_storage_handle, p_handle->device_id, &block_handle);
  2002. if (err_code == NRF_SUCCESS)
  2003. {
  2004. err_code = pstorage_load((uint8_t *)&peer_enc_key,
  2005. &block_handle,
  2006. BOND_SIZE,
  2007. BOND_STORAGE_OFFSET);
  2008. if (err_code == NRF_SUCCESS)
  2009. {
  2010. p_key_dist->keys_central.enc_key.p_enc_key = NULL;
  2011. p_key_dist->keys_central.p_id_key = (dm_id_key_t *)&m_peer_table[p_handle->device_id].peer_id;
  2012. p_key_dist->keys_central.p_sign_key = NULL;
  2013. p_key_dist->keys_periph.p_id_key = (dm_id_key_t *)&m_local_id_info;
  2014. p_key_dist->keys_periph.p_sign_key = NULL;
  2015. p_key_dist->keys_periph.enc_key.p_enc_key = (dm_enc_key_t *)&peer_enc_key;
  2016. }
  2017. }
  2018. DM_TRC("[DM]: << dm_distributed_keys_get\r\n");
  2019. DM_MUTEX_UNLOCK();
  2020. return err_code;
  2021. }
  2022. /**@brief Function for loading bond information for a connection instance.
  2023. */
  2024. void bond_data_load(dm_handle_t * p_handle)
  2025. {
  2026. pstorage_handle_t block_handle;
  2027. uint32_t err_code = pstorage_block_identifier_get(&m_storage_handle,
  2028. p_handle->device_id,
  2029. &block_handle);
  2030. if (err_code == NRF_SUCCESS)
  2031. {
  2032. DM_LOG(
  2033. "[DM]:[%02X]:[Block ID 0x%08X]:Loading bond information at %p, size 0x%08X, offset 0x%08X.\r\n",
  2034. p_handle->connection_id,
  2035. block_handle.block_id,
  2036. &m_bond_table[p_handle->connection_id],
  2037. BOND_SIZE,
  2038. BOND_STORAGE_OFFSET);
  2039. err_code = pstorage_load((uint8_t *)&m_bond_table[p_handle->connection_id],
  2040. &block_handle,
  2041. BOND_SIZE,
  2042. BOND_STORAGE_OFFSET);
  2043. if (err_code != NRF_SUCCESS)
  2044. {
  2045. DM_ERR("[DM]:[%02X]: Failed to load Bond information, reason %08X\r\n",
  2046. p_handle->connection_id,
  2047. err_code);
  2048. }
  2049. DM_LOG(
  2050. "[DM]:[%02X]:Loading service context at %p, size 0x%08X, offset 0x%08X.\r\n",
  2051. p_handle->connection_id,
  2052. &m_gatts_table[p_handle->connection_id],
  2053. sizeof(dm_gatts_context_t),
  2054. SERVICE_STORAGE_OFFSET);
  2055. err_code = m_service_context_load[m_application_table[0].service](
  2056. &block_handle,
  2057. p_handle);
  2058. if (err_code != NRF_SUCCESS)
  2059. {
  2060. DM_ERR(
  2061. "[DM]:[%02X]: Failed to load service information, reason %08X\r\n",
  2062. p_handle->connection_id,
  2063. err_code);
  2064. }
  2065. }
  2066. else
  2067. {
  2068. DM_ERR("[DM]:[%02X]: Failed to get block identifier for "
  2069. "device %08X, reason %08X.\r\n", p_handle->connection_id, p_handle->device_id, err_code);
  2070. }
  2071. }
  2072. void dm_ble_evt_handler(ble_evt_t * p_ble_evt)
  2073. {
  2074. uint32_t err_code;
  2075. uint32_t index;
  2076. uint32_t device_index = DM_INVALID_ID;
  2077. bool notify_app = false;
  2078. dm_handle_t handle;
  2079. dm_event_t event;
  2080. uint32_t event_result;
  2081. ble_gap_enc_info_t * p_enc_info = NULL;
  2082. VERIFY_MODULE_INITIALIZED_VOID();
  2083. VERIFY_APP_REGISTERED_VOID(0);
  2084. DM_MUTEX_LOCK();
  2085. err_code = dm_handle_initialize(&handle);
  2086. APP_ERROR_CHECK(err_code);
  2087. event_result = NRF_SUCCESS;
  2088. err_code = NRF_SUCCESS;
  2089. event.event_param.p_gap_param = &p_ble_evt->evt.gap_evt;
  2090. event.event_paramlen = sizeof(ble_gap_evt_t);
  2091. handle.device_id = DM_INVALID_ID;
  2092. handle.appl_id = 0;
  2093. index = 0x00;
  2094. if (p_ble_evt->header.evt_id != BLE_GAP_EVT_CONNECTED)
  2095. {
  2096. err_code = connection_instance_find(p_ble_evt->evt.gap_evt.conn_handle,
  2097. STATE_CONNECTED,
  2098. &index);
  2099. if (err_code == NRF_SUCCESS)
  2100. {
  2101. handle.device_id = m_connection_table[index].bonded_dev_id;
  2102. handle.connection_id = index;
  2103. }
  2104. }
  2105. switch (p_ble_evt->header.evt_id)
  2106. {
  2107. case BLE_GAP_EVT_CONNECTED:
  2108. //Allocate connection instance for a new connection.
  2109. err_code = connection_instance_allocate(&index);
  2110. //Connection instance is successfully allocated.
  2111. if (err_code == NRF_SUCCESS)
  2112. {
  2113. //Application notification related information.
  2114. notify_app = true;
  2115. event.event_id = DM_EVT_CONNECTION;
  2116. handle.connection_id = index;
  2117. m_connection_table[index].conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
  2118. m_connection_table[index].state = STATE_CONNECTED;
  2119. m_connection_table[index].peer_addr =
  2120. p_ble_evt->evt.gap_evt.params.connected.peer_addr;
  2121. if (p_ble_evt->evt.gap_evt.params.connected.irk_match == 1)
  2122. {
  2123. if (m_irk_index_table[p_ble_evt->evt.gap_evt.params.connected.irk_match_idx] != DM_INVALID_ID)
  2124. {
  2125. device_index = m_irk_index_table[p_ble_evt->evt.gap_evt.params.connected.irk_match_idx];
  2126. err_code = NRF_SUCCESS;
  2127. }
  2128. }
  2129. else
  2130. {
  2131. //Use the device address to check if the device exists in the bonded device list.
  2132. err_code = device_instance_find(&p_ble_evt->evt.gap_evt.params.connected.peer_addr,
  2133. &device_index, EDIV_INIT_VAL);
  2134. }
  2135. if (err_code == NRF_SUCCESS)
  2136. {
  2137. m_connection_table[index].bonded_dev_id = device_index;
  2138. m_connection_table[index].state |= STATE_BONDED;
  2139. handle.device_id = device_index;
  2140. bond_data_load(&handle);
  2141. }
  2142. }
  2143. break;
  2144. case BLE_GAP_EVT_DISCONNECTED:
  2145. //Disconnection could be peer or self initiated hence disconnecting and connecting
  2146. //both states are permitted, however, connection handle must be known.
  2147. DM_LOG("[DM]: Disconnect Reason 0x%04X\r\n",
  2148. p_ble_evt->evt.gap_evt.params.disconnected.reason);
  2149. m_connection_table[index].state &= (~STATE_CONNECTED);
  2150. if ((m_connection_table[index].state & STATE_BONDED) == STATE_BONDED)
  2151. {
  2152. if ((m_connection_table[index].state & STATE_LINK_ENCRYPTED) == STATE_LINK_ENCRYPTED)
  2153. {
  2154. //Write bond information persistently.
  2155. device_context_store(&handle, STORE_ALL_CONTEXT);
  2156. }
  2157. }
  2158. else
  2159. {
  2160. //Free any allocated instances for devices that is not bonded.
  2161. if (handle.device_id != DM_INVALID_ID)
  2162. {
  2163. peer_instance_init(handle.device_id);
  2164. handle.device_id = DM_INVALID_ID;
  2165. }
  2166. }
  2167. m_connection_table[index].state = STATE_DISCONNECTING;
  2168. notify_app = true;
  2169. event.event_id = DM_EVT_DISCONNECTION;
  2170. break;
  2171. case BLE_GAP_EVT_SEC_INFO_REQUEST:
  2172. DM_LOG("[DM]: >> BLE_GAP_EVT_SEC_INFO_REQUEST\r\n");
  2173. //If the device is already bonded, respond with existing info, else NULL.
  2174. if (m_connection_table[index].bonded_dev_id == DM_INVALID_ID)
  2175. {
  2176. //Find device based on div.
  2177. err_code = device_instance_find(NULL,&device_index, p_ble_evt->evt.gap_evt.params.sec_info_request.master_id.ediv);
  2178. if (err_code == NRF_SUCCESS)
  2179. {
  2180. //Load needed bonding information.
  2181. m_connection_table[index].bonded_dev_id = device_index;
  2182. m_connection_table[index].state |= STATE_BONDED;
  2183. handle.device_id = device_index;
  2184. bond_data_load(&handle);
  2185. }
  2186. }
  2187. if (m_connection_table[index].bonded_dev_id != DM_INVALID_ID)
  2188. {
  2189. p_enc_info = &m_bond_table[index].peer_enc_key.enc_info;
  2190. DM_DUMP((uint8_t *)p_enc_info, sizeof(ble_gap_enc_info_t));
  2191. }
  2192. err_code = sd_ble_gap_sec_info_reply(p_ble_evt->evt.gap_evt.conn_handle,
  2193. p_enc_info,
  2194. &m_peer_table[index].peer_id.id_info,
  2195. NULL);
  2196. if (err_code != NRF_SUCCESS)
  2197. {
  2198. DM_ERR("[DM]:[CI %02X]:[DI %02X]: Security information response failed, reason "
  2199. "0x%08X\r\n", index, m_connection_table[index].bonded_dev_id, err_code);
  2200. }
  2201. break;
  2202. case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
  2203. DM_LOG("[DM]: >> BLE_GAP_EVT_SEC_PARAMS_REQUEST\r\n");
  2204. event.event_id = DM_EVT_SECURITY_SETUP;
  2205. m_connection_table[index].state |= STATE_PAIRING;
  2206. notify_app = true;
  2207. if (m_connection_table[index].bonded_dev_id == DM_INVALID_ID)
  2208. {
  2209. //Assign a peer index as a new bond or update existing bonds.
  2210. err_code = device_instance_allocate((uint8_t *)&device_index,
  2211. &m_connection_table[index].peer_addr);
  2212. //Allocation successful.
  2213. if (err_code == NRF_SUCCESS)
  2214. {
  2215. DM_LOG("[DM]:[CI 0x%02X]:[DI 0x%02X]: Bonded!\r\n",index, device_index);
  2216. handle.device_id = device_index;
  2217. m_connection_table[index].bonded_dev_id = device_index;
  2218. }
  2219. else
  2220. {
  2221. DM_LOG("[DM]: Security parameter request failed, reason 0x%08X.\r\n", err_code);
  2222. event_result = err_code;
  2223. notify_app = true;
  2224. }
  2225. ble_gap_sec_keyset_t keys_exchanged;
  2226. DM_LOG("[DM]: 0x%02X, 0x%02X, 0x%02X, 0x%02X\r\n",
  2227. p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_peer.enc,
  2228. p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_own.id,
  2229. p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_peer.sign,
  2230. p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.bond);
  2231. keys_exchanged.keys_peer.p_enc_key = NULL;
  2232. keys_exchanged.keys_peer.p_id_key = &m_peer_table[m_connection_table[index].bonded_dev_id].peer_id;
  2233. keys_exchanged.keys_peer.p_sign_key = NULL;
  2234. keys_exchanged.keys_peer.p_pk = NULL;
  2235. keys_exchanged.keys_own.p_enc_key = &m_bond_table[index].peer_enc_key;
  2236. keys_exchanged.keys_own.p_id_key = NULL;
  2237. keys_exchanged.keys_own.p_sign_key = NULL;
  2238. keys_exchanged.keys_own.p_pk = NULL;
  2239. err_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle,
  2240. BLE_GAP_SEC_STATUS_SUCCESS,
  2241. &m_application_table[0].sec_param,
  2242. &keys_exchanged);
  2243. if (err_code != NRF_SUCCESS)
  2244. {
  2245. DM_LOG("[DM]: Security parameter reply request failed, reason 0x%08X.\r\n", err_code);
  2246. event_result = err_code;
  2247. notify_app = false;
  2248. }
  2249. }
  2250. else
  2251. {
  2252. //Bond/key refresh.
  2253. DM_LOG("[DM]: !!! Bond/key refresh !!!\r\n");
  2254. //Set the update flag for bond data.
  2255. m_connection_table[index].state |= STATE_BOND_INFO_UPDATE;
  2256. event.event_id = DM_EVT_SECURITY_SETUP_REFRESH;
  2257. err_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle,
  2258. BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP,
  2259. NULL,
  2260. NULL);
  2261. if (err_code != NRF_SUCCESS)
  2262. {
  2263. DM_LOG("[DM]: Security parameter reply request failed, reason 0x%08X.\r\n", err_code);
  2264. event_result = err_code;
  2265. notify_app = false;
  2266. }
  2267. }
  2268. break;
  2269. case BLE_GAP_EVT_AUTH_STATUS:
  2270. {
  2271. DM_LOG("[DM]: >> BLE_GAP_EVT_AUTH_STATUS, status %08X\r\n",
  2272. p_ble_evt->evt.gap_evt.params.auth_status.auth_status);
  2273. m_application_table[0].state &= (~STATE_CONTROL_PROCEDURE_IN_PROGRESS);
  2274. m_connection_table[index].state &= (~STATE_PAIRING);
  2275. event.event_id = DM_EVT_SECURITY_SETUP_COMPLETE;
  2276. notify_app = true;
  2277. if (p_ble_evt->evt.gap_evt.params.auth_status.auth_status != BLE_GAP_SEC_STATUS_SUCCESS)
  2278. {
  2279. // In case of key refresh attempt, since this behavior is now rejected, we don't do anything here
  2280. if ((m_connection_table[index].state & STATE_BOND_INFO_UPDATE)
  2281. != STATE_BOND_INFO_UPDATE)
  2282. {
  2283. // Free the allocation as bonding failed.
  2284. ret_code_t result = device_instance_free(m_connection_table[index].bonded_dev_id);
  2285. (void) result;
  2286. event_result = p_ble_evt->evt.gap_evt.params.auth_status.auth_status;
  2287. }
  2288. }
  2289. else
  2290. {
  2291. DM_DUMP((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status,
  2292. sizeof(ble_gap_evt_auth_status_t));
  2293. DM_DUMP((uint8_t *)&m_bond_table[index], sizeof(bond_context_t));
  2294. if (p_ble_evt->evt.gap_evt.params.auth_status.bonded == 1)
  2295. {
  2296. if (handle.device_id != DM_INVALID_ID)
  2297. {
  2298. m_connection_table[index].state |= STATE_BONDED;
  2299. //IRK and/or public address is shared, update it.
  2300. if (p_ble_evt->evt.gap_evt.params.auth_status.kdist_peer.id == 1)
  2301. {
  2302. m_peer_table[handle.device_id].id_bitmap &= (~IRK_ENTRY);
  2303. }
  2304. if (m_connection_table[index].bonded_dev_id != DM_INVALID_ID)
  2305. {
  2306. DM_LOG("[DM]:[CI 0x%02X]:[DI 0x%02X]: Bonded!\r\n",
  2307. index,
  2308. handle.device_id);
  2309. if (m_connection_table[index].peer_addr.addr_type !=
  2310. BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)
  2311. {
  2312. m_peer_table[handle.device_id].peer_id.id_addr_info =
  2313. m_connection_table[index].peer_addr;
  2314. m_peer_table[handle.device_id].id_bitmap &= (~ADDR_ENTRY);
  2315. DM_DUMP((uint8_t *)&m_peer_table[handle.device_id].peer_id.id_addr_info,
  2316. sizeof(m_peer_table[handle.device_id].peer_id.id_addr_info));
  2317. }
  2318. else
  2319. {
  2320. // Here we must fetch the keys from the keyset distributed.
  2321. m_peer_table[handle.device_id].ediv = m_bond_table[index].peer_enc_key.master_id.ediv;
  2322. m_peer_table[handle.device_id].id_bitmap &= (~IRK_ENTRY);
  2323. }
  2324. device_context_store(&handle, FIRST_BOND_STORE);
  2325. }
  2326. }
  2327. }
  2328. else
  2329. {
  2330. //Pairing request, no need to touch the bonding info.
  2331. }
  2332. }
  2333. break;
  2334. }
  2335. case BLE_GAP_EVT_CONN_SEC_UPDATE:
  2336. DM_LOG("[DM]: >> BLE_GAP_EVT_CONN_SEC_UPDATE, Mode 0x%02X, Level 0x%02X\r\n",
  2337. p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm,
  2338. p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv);
  2339. if ((p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv == 1) &&
  2340. (p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm == 1) &&
  2341. ((m_connection_table[index].state & STATE_BONDED) == STATE_BONDED))
  2342. {
  2343. //Lost bond case, generate a security refresh event!
  2344. memset(m_gatts_table[index].attributes, 0, DM_GATT_SERVER_ATTR_MAX_SIZE);
  2345. event.event_id = DM_EVT_SECURITY_SETUP_REFRESH;
  2346. m_connection_table[index].state |= STATE_PAIRING_PENDING;
  2347. m_connection_table[index].state |= STATE_BOND_INFO_UPDATE;
  2348. m_application_table[0].state |= STATE_QUEUED_CONTROL_REQUEST;
  2349. }
  2350. else
  2351. {
  2352. m_connection_table[index].state |= STATE_LINK_ENCRYPTED;
  2353. event.event_id = DM_EVT_LINK_SECURED;
  2354. //Apply service context.
  2355. err_code = m_service_context_apply[m_application_table[0].service](&handle);
  2356. if (err_code != NRF_SUCCESS)
  2357. {
  2358. DM_ERR("[DM]:[CI 0x%02X]:[DI 0x%02X]: Failed to apply service context\r\n",
  2359. handle.connection_id,
  2360. handle.device_id);
  2361. event_result = DM_SERVICE_CONTEXT_NOT_APPLIED;
  2362. }
  2363. }
  2364. event_result = NRF_SUCCESS;
  2365. notify_app = true;
  2366. break;
  2367. case BLE_GATTS_EVT_SYS_ATTR_MISSING:
  2368. DM_LOG("[DM]: >> BLE_GATTS_EVT_SYS_ATTR_MISSING\r\n");
  2369. //Apply service context.
  2370. event_result = m_service_context_apply[m_application_table[0].service](&handle);
  2371. break;
  2372. case BLE_GAP_EVT_SEC_REQUEST:
  2373. DM_LOG("[DM]: >> BLE_GAP_EVT_SEC_REQUEST\r\n");
  2374. //Verify if the device is already bonded, and if it is bonded, initiate encryption.
  2375. //If the device is not bonded, an instance needs to be allocated in order to initiate
  2376. //bonding. The application have to initiate the procedure, the module will not do this
  2377. //automatically.
  2378. event.event_id = DM_EVT_SECURITY_SETUP;
  2379. notify_app = true;
  2380. break;
  2381. default:
  2382. break;
  2383. }
  2384. if (notify_app)
  2385. {
  2386. app_evt_notify(&handle, &event, event_result);
  2387. //Freeing the instance after the event is notified so the application can get the context.
  2388. if (event.event_id == DM_EVT_DISCONNECTION)
  2389. {
  2390. //Free the instance.
  2391. connection_instance_free(&index);
  2392. }
  2393. }
  2394. UNUSED_VARIABLE(err_code);
  2395. DM_MUTEX_UNLOCK();
  2396. }
  2397. ret_code_t dm_handle_get(uint16_t conn_handle, dm_handle_t * p_handle)
  2398. {
  2399. ret_code_t err_code;
  2400. uint32_t index;
  2401. NULL_PARAM_CHECK(p_handle);
  2402. VERIFY_APP_REGISTERED(p_handle->appl_id);
  2403. p_handle->device_id = DM_INVALID_ID;
  2404. err_code = NRF_ERROR_NOT_FOUND;
  2405. for (index = 0; index < DEVICE_MANAGER_MAX_CONNECTIONS; index++)
  2406. {
  2407. //Search for matching connection handle.
  2408. if (conn_handle == m_connection_table[index].conn_handle)
  2409. {
  2410. p_handle->connection_id = index;
  2411. p_handle->device_id = m_connection_table[index].bonded_dev_id;
  2412. err_code = NRF_SUCCESS;
  2413. break;
  2414. }
  2415. }
  2416. return err_code;
  2417. }