simplekeys.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. /**
  2. * @file
  3. * @author chipsea
  4. * @brief
  5. * @version 0.1
  6. * @date 2020-11-30
  7. * @copyright Copyright (c) 2020, CHIPSEA Co., Ltd.
  8. * @note
  9. */
  10. /**************************************************************************************************
  11. Filename: simplekey.c
  12. Revised:
  13. Revision:
  14. Description: Simple Keys Profile
  15. **************************************************************************************************/
  16. /*********************************************************************
  17. * INCLUDES
  18. */
  19. #include "bcomdef.h"
  20. #include "OSAL.h"
  21. #include "linkdb.h"
  22. #include "att.h"
  23. #include "gatt.h"
  24. #include "gatt_uuid.h"
  25. #include "gattservapp.h"
  26. #include "gapbondmgr.h"
  27. #include "simplekeys.h"
  28. /*********************************************************************
  29. * MACROS
  30. */
  31. /*********************************************************************
  32. * CONSTANTS
  33. */
  34. #define SERVAPP_NUM_ATTR_SUPPORTED 5
  35. /*********************************************************************
  36. * TYPEDEFS
  37. */
  38. /*********************************************************************
  39. * GLOBAL VARIABLES
  40. */
  41. // SK Service UUID: 0x1800
  42. CONST uint8 skServUUID[ATT_BT_UUID_SIZE] =
  43. {
  44. LO_UINT16(SK_SERV_UUID), HI_UINT16(SK_SERV_UUID)
  45. };
  46. // Key Pressed UUID: 0x1801
  47. CONST uint8 keyPressedUUID[ATT_BT_UUID_SIZE] =
  48. {
  49. LO_UINT16(SK_KEYPRESSED_UUID), HI_UINT16(SK_KEYPRESSED_UUID)
  50. };
  51. /*********************************************************************
  52. * EXTERNAL VARIABLES
  53. */
  54. /*********************************************************************
  55. * EXTERNAL FUNCTIONS
  56. */
  57. /*********************************************************************
  58. * LOCAL VARIABLES
  59. */
  60. /*********************************************************************
  61. * Profile Attributes - variables
  62. */
  63. // SK Service attribute
  64. static CONST gattAttrType_t skService = { ATT_BT_UUID_SIZE, skServUUID };
  65. // Keys Pressed Characteristic Properties
  66. static uint8 skCharProps = GATT_PROP_NOTIFY;
  67. // Key Pressed State Characteristic
  68. static uint8 skKeyPressed = 0;
  69. // Key Pressed Characteristic Configs
  70. static gattCharCfg_t skConfig[GATT_MAX_NUM_CONN];
  71. // Key Pressed Characteristic User Description
  72. static uint8 skCharUserDesp[16] = "Key Press State\0";
  73. /*********************************************************************
  74. * Profile Attributes - Table
  75. */
  76. static gattAttribute_t simplekeysAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] =
  77. {
  78. // Simple Keys Service
  79. {
  80. { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
  81. GATT_PERMIT_READ, /* permissions */
  82. 0, /* handle */
  83. (uint8 *)&skService /* pValue */
  84. },
  85. // Characteristic Declaration for Keys
  86. {
  87. { ATT_BT_UUID_SIZE, characterUUID },
  88. GATT_PERMIT_READ,
  89. 0,
  90. &skCharProps
  91. },
  92. // Characteristic Value- Key Pressed
  93. {
  94. { ATT_BT_UUID_SIZE, keyPressedUUID },
  95. 0,
  96. 0,
  97. &skKeyPressed
  98. },
  99. // Characteristic configuration
  100. {
  101. { ATT_BT_UUID_SIZE, clientCharCfgUUID },
  102. GATT_PERMIT_READ | GATT_PERMIT_WRITE,
  103. 0,
  104. (uint8 *)skConfig
  105. },
  106. // Characteristic User Description
  107. {
  108. { ATT_BT_UUID_SIZE, charUserDescUUID },
  109. GATT_PERMIT_READ,
  110. 0,
  111. skCharUserDesp
  112. },
  113. };
  114. /*********************************************************************
  115. * LOCAL FUNCTIONS
  116. */
  117. static uint8 sk_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
  118. uint8 *pValue, uint16 *pLen, uint16 offset, uint8 maxLen );
  119. static bStatus_t sk_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
  120. uint8 *pValue, uint16 len, uint16 offset );
  121. static void sk_HandleConnStatusCB( uint16 connHandle, uint8 changeType );
  122. /*********************************************************************
  123. * PROFILE CALLBACKS
  124. */
  125. // SK Service Callbacks
  126. CONST gattServiceCBs_t skCBs =
  127. {
  128. sk_ReadAttrCB, // Read callback function pointer
  129. sk_WriteAttrCB, // Write callback function pointer
  130. NULL // Authorization callback function pointer
  131. };
  132. /*********************************************************************
  133. * PUBLIC FUNCTIONS
  134. */
  135. /*********************************************************************
  136. * @fn SK_AddService
  137. *
  138. * @brief Initializes the Simple Key service by registering
  139. * GATT attributes with the GATT server.
  140. *
  141. * @param services - services to add. This is a bit map and can
  142. * contain more than one service.
  143. *
  144. * @return Success or Failure
  145. */
  146. bStatus_t SK_AddService( uint32 services )
  147. {
  148. uint8 status = SUCCESS;
  149. // Initialize Client Characteristic Configuration attributes
  150. GATTServApp_InitCharCfg( INVALID_CONNHANDLE, skConfig );
  151. // Register with Link DB to receive link status change callback
  152. VOID linkDB_Register( sk_HandleConnStatusCB );
  153. if ( services & SK_SERVICE )
  154. {
  155. // Register GATT attribute list and CBs with GATT Server App
  156. status = GATTServApp_RegisterService( simplekeysAttrTbl,
  157. GATT_NUM_ATTRS( simplekeysAttrTbl ),
  158. &skCBs );
  159. }
  160. return ( status );
  161. }
  162. /*********************************************************************
  163. * @fn SK_SetParameter
  164. *
  165. * @brief Set a Simple Key Profile parameter.
  166. *
  167. * @param param - Profile parameter ID
  168. * @param len - length of data to right
  169. * @param pValue - pointer to data to write. This is dependent on
  170. * the parameter ID and WILL be cast to the appropriate
  171. * data type (example: data type of uint16 will be cast to
  172. * uint16 pointer).
  173. *
  174. * @return bStatus_t
  175. */
  176. bStatus_t SK_SetParameter( uint8 param, uint8 len, void *pValue )
  177. {
  178. bStatus_t ret = SUCCESS;
  179. switch ( param )
  180. {
  181. case SK_KEY_ATTR:
  182. if ( len == sizeof ( uint8 ) )
  183. {
  184. skKeyPressed = *((uint8*)pValue);
  185. // See if Notification/Indication has been enabled
  186. GATTServApp_ProcessCharCfg( skConfig, &skKeyPressed, FALSE,
  187. simplekeysAttrTbl, GATT_NUM_ATTRS( simplekeysAttrTbl ),
  188. INVALID_TASK_ID );
  189. }
  190. else
  191. {
  192. ret = bleInvalidRange;
  193. }
  194. break;
  195. default:
  196. ret = INVALIDPARAMETER;
  197. break;
  198. }
  199. return ( ret );
  200. }
  201. /*********************************************************************
  202. * @fn SK_GetParameter
  203. *
  204. * @brief Get a Simple Key Profile parameter.
  205. *
  206. * @param param - Profile parameter ID
  207. * @param pValue - pointer to data to put. This is dependent on
  208. * the parameter ID and WILL be cast to the appropriate
  209. * data type (example: data type of uint16 will be cast to
  210. * uint16 pointer).
  211. *
  212. * @return bStatus_t
  213. */
  214. bStatus_t SK_GetParameter( uint8 param, void *pValue )
  215. {
  216. bStatus_t ret = SUCCESS;
  217. switch ( param )
  218. {
  219. case SK_KEY_ATTR:
  220. *((uint8*)pValue) = skKeyPressed;
  221. break;
  222. default:
  223. ret = INVALIDPARAMETER;
  224. break;
  225. }
  226. return ( ret );
  227. }
  228. /*********************************************************************
  229. * @fn sk_ReadAttrCB
  230. *
  231. * @brief Read an attribute.
  232. *
  233. * @param connHandle - connection message was received on
  234. * @param pAttr - pointer to attribute
  235. * @param pValue - pointer to data to be read
  236. * @param pLen - length of data to be read
  237. * @param offset - offset of the first octet to be read
  238. * @param maxLen - maximum length of data to be read
  239. *
  240. * @return Success or Failure
  241. */
  242. static uint8 sk_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
  243. uint8 *pValue, uint16 *pLen, uint16 offset, uint8 maxLen )
  244. {
  245. bStatus_t status = SUCCESS;
  246. // Make sure it's not a blob operation (no attributes in the profile are long
  247. if ( offset > 0 )
  248. {
  249. return ( ATT_ERR_ATTR_NOT_LONG );
  250. }
  251. if ( pAttr->type.len == ATT_BT_UUID_SIZE )
  252. {
  253. // 16-bit UUID
  254. uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
  255. switch ( uuid )
  256. {
  257. // No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;
  258. // gattserverapp handles this type for reads
  259. // simple keys characteristic does not have read permissions, but because it
  260. // can be sent as a notification, it must be included here
  261. case SK_KEYPRESSED_UUID:
  262. *pLen = 1;
  263. pValue[0] = *pAttr->pValue;
  264. break;
  265. default:
  266. // Should never get here!
  267. *pLen = 0;
  268. status = ATT_ERR_ATTR_NOT_FOUND;
  269. break;
  270. }
  271. }
  272. else
  273. {
  274. // 128-bit UUID
  275. *pLen = 0;
  276. status = ATT_ERR_INVALID_HANDLE;
  277. }
  278. return ( status );
  279. }
  280. /*********************************************************************
  281. * @fn sk_WriteAttrCB
  282. *
  283. * @brief Validate attribute data prior to a write operation
  284. *
  285. * @param connHandle - connection message was received on
  286. * @param pAttr - pointer to attribute
  287. * @param pValue - pointer to data to be written
  288. * @param len - length of data
  289. * @param offset - offset of the first octet to be written
  290. *
  291. * @return Success or Failure
  292. */
  293. static bStatus_t sk_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
  294. uint8 *pValue, uint16 len, uint16 offset )
  295. {
  296. bStatus_t status = SUCCESS;
  297. if ( pAttr->type.len == ATT_BT_UUID_SIZE )
  298. {
  299. // 16-bit UUID
  300. uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
  301. switch ( uuid )
  302. {
  303. case GATT_CLIENT_CHAR_CFG_UUID:
  304. status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
  305. offset, GATT_CLIENT_CFG_NOTIFY );
  306. break;
  307. default:
  308. // Should never get here!
  309. status = ATT_ERR_ATTR_NOT_FOUND;
  310. break;
  311. }
  312. }
  313. else
  314. {
  315. // 128-bit UUID
  316. status = ATT_ERR_INVALID_HANDLE;
  317. }
  318. return ( status );
  319. }
  320. /*********************************************************************
  321. * @fn sk_HandleConnStatusCB
  322. *
  323. * @brief Simple Keys Profile link status change handler function.
  324. *
  325. * @param connHandle - connection handle
  326. * @param changeType - type of change
  327. *
  328. * @return none
  329. */
  330. static void sk_HandleConnStatusCB( uint16 connHandle, uint8 changeType )
  331. {
  332. // Make sure this is not loopback connection
  333. if ( connHandle != LOOPBACK_CONNHANDLE )
  334. {
  335. // Reset Client Char Config if connection has dropped
  336. if ( ( changeType == LINKDB_STATUS_UPDATE_REMOVED ) ||
  337. ( ( changeType == LINKDB_STATUS_UPDATE_STATEFLAGS ) &&
  338. ( !linkDB_Up( connHandle ) ) ) )
  339. {
  340. GATTServApp_InitCharCfg( connHandle, skConfig );
  341. }
  342. }
  343. }
  344. /*********************************************************************
  345. *********************************************************************/