device_manager_central.c 104 KB

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