ppsp_serv.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899
  1. /**************************************************************************************************
  2. Filename: ppsp_serv.c
  3. Revised:
  4. Revision:
  5. Description: This file contains the Simple GATT profile sample GATT service
  6. profile for use with the BLE sample application.
  7. **************************************************************************************************/
  8. /*********************************************************************
  9. * INCLUDES
  10. */
  11. #include "bcomdef.h"
  12. #include "OSAL.h"
  13. #include "linkdb.h"
  14. #include "att.h"
  15. #include "gatt.h"
  16. #include "gatt_uuid.h"
  17. #include "gattservapp.h"
  18. #include "gapbondmgr.h"
  19. #include "ppsp_serv.h"
  20. #include "log.h"
  21. /*********************************************************************
  22. * MACROS
  23. */
  24. /*********************************************************************
  25. * CONSTANTS
  26. */
  27. /*********************************************************************
  28. * TYPEDEFS
  29. */
  30. /*********************************************************************
  31. * GLOBAL VARIABLES
  32. */
  33. // Simple GATT Profile Service UUID: 0xFFF0
  34. CONST uint8 __ppsp_serv_serv_uuid[ATT_BT_UUID_SIZE] = {
  35. LO_UINT16(PPSP_SERV_CFGS_SERV_FEB3_UUID), HI_UINT16(PPSP_SERV_CFGS_SERV_FEB3_UUID)
  36. };
  37. // Characteristic 1 UUID: 0xFFF1
  38. CONST uint8 __ppsp_serv_char_ffd4_uuid[ATT_BT_UUID_SIZE] = {
  39. LO_UINT16(PPSP_SERV_CFGS_CHAR_FED4_UUID), HI_UINT16(PPSP_SERV_CFGS_CHAR_FED4_UUID)
  40. };
  41. // Characteristic 2 UUID: 0xFFF2
  42. CONST uint8 __ppsp_serv_char_ffd5_uuid[ATT_BT_UUID_SIZE] = {
  43. LO_UINT16(PPSP_SERV_CFGS_CHAR_FED5_UUID), HI_UINT16(PPSP_SERV_CFGS_CHAR_FED5_UUID)
  44. };
  45. // Characteristic 3 UUID: 0xFFF3
  46. CONST uint8 __ppsp_serv_char_ffd6_uuid[ATT_BT_UUID_SIZE] = {
  47. LO_UINT16(PPSP_SERV_CFGS_CHAR_FED6_UUID), HI_UINT16(PPSP_SERV_CFGS_CHAR_FED6_UUID)
  48. };
  49. // Characteristic 4 UUID: 0xFFF4
  50. CONST uint8 __ppsp_serv_char_ffd7_uuid[ATT_BT_UUID_SIZE] = {
  51. LO_UINT16(PPSP_SERV_CFGS_CHAR_FED7_UUID), HI_UINT16(PPSP_SERV_CFGS_CHAR_FED7_UUID)
  52. };
  53. // Characteristic 5 UUID: 0xFFF5
  54. CONST uint8 __ppsp_serv_char_ffd8_uuid[ATT_BT_UUID_SIZE] = {
  55. LO_UINT16(PPSP_SERV_CFGS_CHAR_FED8_UUID), HI_UINT16(PPSP_SERV_CFGS_CHAR_FED8_UUID)
  56. };
  57. /*********************************************************************
  58. * EXTERNAL VARIABLES
  59. */
  60. /*********************************************************************
  61. * EXTERNAL FUNCTIONS
  62. */
  63. /*********************************************************************
  64. * LOCAL VARIABLES
  65. */
  66. static ppsp_serv_appl_CBs_t *simpleProfile_AppCBs = NULL;
  67. /*********************************************************************
  68. * Profile Attributes - variables
  69. */
  70. // Simple Profile Service attribute
  71. static CONST gattAttrType_t
  72. __ppsp_serv_serv = { ATT_BT_UUID_SIZE, __ppsp_serv_serv_uuid };
  73. // Simple Profile Characteristic 1 Properties
  74. static uint8
  75. __ppsp_serv_char_ffd4_prop = GATT_PROP_READ;
  76. // Characteristic 1 Value
  77. static uint8
  78. __ppsp_serv_char_ffd4_para[PPSP_SERV_CFGS_CHAR_FED4_DLEN];
  79. static uint8
  80. __ppsp_serv_char_ffd4_para_size = 0;
  81. // Simple Profile Characteristic 1 User Description
  82. static uint8
  83. __ppsp_serv_char_ffd4_desc[] = "READ\0";
  84. // Simple Profile Characteristic 2 Properties
  85. static uint8
  86. __ppsp_serv_char_ffd5_prop = GATT_PROP_WRITE;
  87. // Characteristic 2 Value
  88. static uint8
  89. __ppsp_serv_char_ffd5_para[PPSP_SERV_CFGS_CHAR_FED5_DLEN];
  90. // Simple Profile Characteristic 2 User Description
  91. static uint8
  92. __ppsp_serv_char_ffd5_desc[] = "WRITE\0";
  93. // Simple Profile Characteristic 3 Properties
  94. static uint8
  95. __ppsp_serv_char_ffd6_prop = GATT_PROP_READ | GATT_PROP_INDICATE;
  96. // Characteristic 3 Value
  97. static uint8
  98. __ppsp_serv_char_ffd6_para[PPSP_SERV_CFGS_CHAR_FED6_DLEN];
  99. static uint8
  100. __ppsp_serv_char_ffd6_para_size = 0;
  101. // Simple Profile Characteristic 4 Configuration Each client has its own
  102. // instantiation of the Client Characteristic Configuration. Reads of the
  103. // Client Characteristic Configuration only shows the configuration for
  104. // that client and writes only affect the configuration of that client.
  105. static gattCharCfg_t
  106. __ppsp_serv_char_ffd6_cfgs[GATT_MAX_NUM_CONN];
  107. // Simple Profile Characteristic 3 User Description
  108. static uint8
  109. __ppsp_serv_char_ffd6_desc[] = "INDICATE\0";
  110. // Simple Profile Characteristic 4 Properties
  111. static uint8
  112. __ppsp_serv_char_ffd7_prop = GATT_PROP_WRITE_NO_RSP;
  113. // Characteristic 4 Value
  114. static uint8
  115. __ppsp_serv_char_ffd7_para[PPSP_SERV_CFGS_CHAR_FED7_DLEN];
  116. // Simple Profile Characteristic 4 User Description
  117. static uint8
  118. __ppsp_serv_char_ffd7_desc[] = "WRITE_WITH_NO_RESP\0";
  119. // Simple Profile Characteristic 5 Properties
  120. static uint8
  121. __ppsp_serv_char_ffd8_prop = GATT_PROP_READ | GATT_PROP_NOTIFY; // to change to write only, HZF
  122. // Characteristic 5 Value
  123. static uint8
  124. __ppsp_serv_char_ffd8_para[PPSP_SERV_CFGS_CHAR_FED8_DLEN];
  125. static uint8
  126. __ppsp_serv_char_ffd8_para_size = 0;
  127. // Simple Profile Characteristic 1 Configuration Each client has its own
  128. // instantiation of the Client Characteristic Configuration. Reads of the
  129. // Client Characteristic Configuration only shows the configuration for
  130. // that client and writes only affect the configuration of that client.
  131. static gattCharCfg_t __ppsp_serv_char_ffd8_cfgs[GATT_MAX_NUM_CONN];
  132. // Simple Profile Characteristic 5 User Description
  133. static uint8
  134. __ppsp_serv_char_ffd8_desc[] = "NOTIFY\0";
  135. /*********************************************************************
  136. * Profile Attributes - Table
  137. */
  138. static gattAttribute_t simpleProfileAttrTbl[] =
  139. {
  140. // Simple Profile Service
  141. {
  142. { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
  143. GATT_PERMIT_READ, /* permissions */
  144. 0, /* handle */
  145. (uint8 *)&__ppsp_serv_serv /* pValue */
  146. },
  147. // Characteristic 1 Declaration
  148. {
  149. { ATT_BT_UUID_SIZE, characterUUID },
  150. GATT_PERMIT_READ,
  151. 0,
  152. &__ppsp_serv_char_ffd4_prop
  153. },
  154. // Characteristic Value 1
  155. {
  156. { ATT_BT_UUID_SIZE, __ppsp_serv_char_ffd4_uuid },
  157. GATT_PERMIT_READ | GATT_PERMIT_WRITE,
  158. 0,
  159. __ppsp_serv_char_ffd4_para
  160. },
  161. // Characteristic 1 User Description
  162. /* {
  163. { ATT_BT_UUID_SIZE, charUserDescUUID },
  164. GATT_PERMIT_READ,
  165. 0,
  166. __ppsp_serv_char_FFD4_desc
  167. }, */
  168. // Characteristic 2 Declaration
  169. {
  170. { ATT_BT_UUID_SIZE, characterUUID },
  171. GATT_PERMIT_READ,
  172. 0,
  173. &__ppsp_serv_char_ffd5_prop
  174. },
  175. // Characteristic Value 2
  176. {
  177. { ATT_BT_UUID_SIZE, __ppsp_serv_char_ffd5_uuid },
  178. GATT_PERMIT_READ | GATT_PERMIT_WRITE,
  179. 0,
  180. __ppsp_serv_char_ffd5_para
  181. },
  182. // Characteristic 2 User Description
  183. /* {
  184. { ATT_BT_UUID_SIZE, charUserDescUUID },
  185. GATT_PERMIT_READ,
  186. 0,
  187. __ppsp_serv_char_FFD5_desc
  188. }, */
  189. // Characteristic 3 Declaration
  190. {
  191. { ATT_BT_UUID_SIZE, characterUUID },
  192. GATT_PERMIT_READ,
  193. 0,
  194. &__ppsp_serv_char_ffd6_prop
  195. },
  196. // Characteristic Value 3
  197. {
  198. { ATT_BT_UUID_SIZE, __ppsp_serv_char_ffd6_uuid },
  199. GATT_PERMIT_READ | GATT_PERMIT_WRITE,
  200. 0,
  201. __ppsp_serv_char_ffd6_para
  202. },
  203. // Characteristic 3 configuration
  204. {
  205. { ATT_BT_UUID_SIZE, clientCharCfgUUID },
  206. GATT_PERMIT_READ | GATT_PERMIT_WRITE,
  207. 0,
  208. (uint8 *)__ppsp_serv_char_ffd6_cfgs
  209. },
  210. // Characteristic 3 User Description
  211. /* {
  212. { ATT_BT_UUID_SIZE, charUserDescUUID },
  213. GATT_PERMIT_READ,
  214. 0,
  215. __ppsp_serv_char_FFD6_desc
  216. }, */
  217. // Characteristic 4 Declaration
  218. {
  219. { ATT_BT_UUID_SIZE, characterUUID },
  220. GATT_PERMIT_READ,
  221. 0,
  222. &__ppsp_serv_char_ffd7_prop
  223. },
  224. // Characteristic Value 4
  225. {
  226. { ATT_BT_UUID_SIZE, __ppsp_serv_char_ffd7_uuid },
  227. GATT_PERMIT_READ | GATT_PERMIT_WRITE,
  228. 0,
  229. __ppsp_serv_char_ffd7_para
  230. },
  231. // Characteristic 4 User Description
  232. /* {
  233. { ATT_BT_UUID_SIZE, charUserDescUUID },
  234. GATT_PERMIT_READ,
  235. 0,
  236. __ppsp_serv_char_FFD7_desc
  237. }, */
  238. // Characteristic 5 Declaration
  239. {
  240. { ATT_BT_UUID_SIZE, characterUUID },
  241. GATT_PERMIT_READ,
  242. 0,
  243. &__ppsp_serv_char_ffd8_prop
  244. },
  245. // Characteristic Value 5
  246. {
  247. { ATT_BT_UUID_SIZE, __ppsp_serv_char_ffd8_uuid },
  248. GATT_PERMIT_READ | GATT_PERMIT_WRITE,
  249. 0,
  250. __ppsp_serv_char_ffd8_para
  251. },
  252. // Characteristic 5 configuration
  253. {
  254. { ATT_BT_UUID_SIZE, clientCharCfgUUID },
  255. GATT_PERMIT_READ | GATT_PERMIT_WRITE,
  256. 0,
  257. (uint8 *)__ppsp_serv_char_ffd8_cfgs
  258. },
  259. // Characteristic 5 User Description
  260. /* {
  261. { ATT_BT_UUID_SIZE, charUserDescUUID },
  262. GATT_PERMIT_READ,
  263. 0,
  264. __ppsp_serv_char_FFD8_desc
  265. }, */
  266. };
  267. /*********************************************************************
  268. * LOCAL FUNCTIONS
  269. */
  270. static uint8
  271. ppsp_serv_get_attr( uint16 connHandle, gattAttribute_t *pAttr,
  272. uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen );
  273. static bStatus_t
  274. ppsp_serv_set_attr( uint16 connHandle, gattAttribute_t *pAttr,
  275. uint8 *pValue, uint8 len, uint16 offset );
  276. static void
  277. ppsp_serv_hdlr_conn_stat( uint16 connHandle, uint8 changeType );
  278. // static bStatus_t send_notity_indication( gattCharCfg_t *charCfgTbl, uint8 *pValue,
  279. // uint8 authenticated, gattAttribute_t *attrTbl,
  280. // uint16 numAttrs, uint8 taskId,uint8 dlen);
  281. /*********************************************************************
  282. * @fn simpleProfile_ReadAttrCB
  283. *
  284. * @brief Read an attribute.
  285. *
  286. * @param connHandle - connection message was received on
  287. * @param pAttr - pointer to attribute
  288. * @param pValue - pointer to data to be read
  289. * @param pLen - length of data to be read
  290. * @param offset - offset of the first octet to be read
  291. * @param maxLen - maximum length of data to be read
  292. *
  293. * @return Success or Failure
  294. */
  295. static uint8 ppsp_serv_get_attr( uint16 connHandle, gattAttribute_t *pAttr,
  296. uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen )
  297. {
  298. bStatus_t status = SUCCESS;
  299. // LOG("[PANDA][ENT] %s len:%d, offs:%d, max:%d \r\n", __func__, *pLen, offset, maxLen);
  300. // printf("[PANDA][INF] mtu:%d", ATT_GetCurrentMTUSize());
  301. // If attribute permissions require authorization to read, return error
  302. if ( gattPermitAuthorRead( pAttr->permissions ) ) {
  303. // Insufficient authorization
  304. return ( ATT_ERR_INSUFFICIENT_AUTHOR );
  305. }
  306. // Make sure it's not a blob operation (no attributes in the profile are long)
  307. // if ( 0 < offset ) {
  308. // return ( ATT_ERR_ATTR_NOT_LONG );
  309. // }
  310. if ( pAttr->type.len == ATT_BT_UUID_SIZE ) {
  311. // 16-bit UUID
  312. uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
  313. // LOG("[PANDA][INF] uuid:%x \r\n", uuid);
  314. uint16 gsiz = offset + 1; // size of read
  315. uint16 ssiz = 0; // size of left
  316. switch ( uuid ) {
  317. // No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;
  318. // gattserverapp handles those reads
  319. case PPSP_SERV_CFGS_CHAR_FED4_UUID: {
  320. ssiz = PPSP_SERV_CFGS_CHAR_FED4_DLEN - gsiz;
  321. *pLen = ssiz > maxLen ? maxLen : ssiz;
  322. VOID osal_memcpy( pValue, pAttr->pValue + offset, *pLen );
  323. }
  324. break;
  325. case PPSP_SERV_CFGS_CHAR_FED5_UUID: {
  326. ssiz = PPSP_SERV_CFGS_CHAR_FED5_DLEN - gsiz;
  327. *pLen = ssiz > maxLen ? maxLen : ssiz;
  328. VOID osal_memcpy( pValue, pAttr->pValue + offset, *pLen );
  329. }
  330. break;
  331. case PPSP_SERV_CFGS_CHAR_FED6_UUID: {
  332. ssiz = PPSP_SERV_CFGS_CHAR_FED6_DLEN - gsiz;
  333. *pLen = ssiz > maxLen ? maxLen : ssiz;
  334. //osal_memcpy( pValue, pAttr->pValue + offset, *pLen );
  335. osal_memcpy( pValue, pAttr->pValue, *pLen = __ppsp_serv_char_ffd6_para_size );
  336. }
  337. break;
  338. case PPSP_SERV_CFGS_CHAR_FED7_UUID: {
  339. ssiz = PPSP_SERV_CFGS_CHAR_FED7_DLEN - gsiz;
  340. *pLen = ssiz > maxLen ? maxLen : ssiz;
  341. VOID osal_memcpy( pValue, pAttr->pValue + offset, *pLen );
  342. }
  343. break;
  344. case PPSP_SERV_CFGS_CHAR_FED8_UUID: {
  345. ssiz = PPSP_SERV_CFGS_CHAR_FED8_DLEN - gsiz;
  346. *pLen = ssiz > maxLen ? maxLen : ssiz;
  347. // VOID osal_memcpy( pValue, pAttr->pValue + offset, *pLen );
  348. osal_memcpy( pValue, pAttr->pValue, *pLen = __ppsp_serv_char_ffd8_para_size );
  349. }
  350. break;
  351. default:
  352. // Should never get here! (characteristics 3 and 4 do not have read permissions)
  353. *pLen = 0;
  354. status = ATT_ERR_ATTR_NOT_FOUND;
  355. break;
  356. }
  357. } else {
  358. // 128-bit UUID
  359. *pLen = 0;
  360. status = ATT_ERR_INVALID_HANDLE;
  361. }
  362. return ( status );
  363. }
  364. /*********************************************************************
  365. * @fn simpleProfile_WriteAttrCB
  366. *
  367. * @brief Validate attribute data prior to a write operation
  368. *
  369. * @param connHandle - connection message was received on
  370. * @param pAttr - pointer to attribute
  371. * @param pValue - pointer to data to be written
  372. * @param len - length of data
  373. * @param offset - offset of the first octet to be written
  374. *
  375. * @return Success or Failure
  376. */
  377. // TODO: test this function
  378. static bStatus_t ppsp_serv_set_attr( uint16 connHandle, gattAttribute_t *pAttr,
  379. uint8 *pValue, uint8 len, uint16 offset )
  380. {
  381. bStatus_t status = SUCCESS;
  382. uint8 upda_para = 0xFF;
  383. // LOG("[PANDA][ENT] %s: len:%d, offs:%d \n\r", __func__, len, offset);
  384. // printf("[PANDA][ENT] %s: len:%d, offs:%d \n\r", __func__, len, offset);
  385. // LOG("[PANDA][INF] mtu:%d", ATT_GetCurrentMTUSize());
  386. // LOG("\r\n[DUMP] >> "); for ( int itr0 = 0; itr0 < len; itr0 += 1 ) LOG("%02x,", pValue[itr0]); LOG("[DUMP] << \r\n");
  387. // If attribute permissions require authorization to write, return error
  388. if ( gattPermitAuthorWrite( pAttr->permissions ) ) {
  389. // Insufficient authorization
  390. return ( ATT_ERR_INSUFFICIENT_AUTHOR );
  391. }
  392. // Make sure it's not a blob operation (no attributes in the profile are long)
  393. // if ( 0 < offset ) {
  394. // return ( ATT_ERR_ATTR_NOT_LONG );
  395. // }
  396. if ( pAttr->type.len == ATT_BT_UUID_SIZE ) {
  397. // 16-bit UUID
  398. uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
  399. switch ( uuid ) {
  400. case PPSP_SERV_CFGS_CHAR_FED4_UUID: {
  401. if ( PPSP_SERV_CFGS_CHAR_FED4_DLEN <= offset ) {
  402. status = ATT_ERR_INVALID_VALUE_SIZE;
  403. } else {
  404. // Write the value
  405. VOID osal_memcpy( pAttr->pValue + offset, pValue, len );
  406. upda_para = PPSP_SERV_CFGS_CHAR_FFD4_INDX;
  407. }
  408. }
  409. break;
  410. case PPSP_SERV_CFGS_CHAR_FED5_UUID: {
  411. if ( PPSP_SERV_CFGS_CHAR_FED5_DLEN <= offset ) {
  412. status = ATT_ERR_INVALID_VALUE_SIZE;
  413. } else {
  414. // Write the value
  415. VOID osal_memcpy( pAttr->pValue + offset, pValue, PPSP_SERV_CFGS_CHAR_FED5_DLEN );
  416. upda_para = PPSP_SERV_CFGS_CHAR_FFD5_INDX;
  417. }
  418. }
  419. break;
  420. case PPSP_SERV_CFGS_CHAR_FED6_UUID: {
  421. if ( PPSP_SERV_CFGS_CHAR_FED6_DLEN <= offset ) {
  422. status = ATT_ERR_INVALID_VALUE_SIZE;
  423. } else {
  424. // Write the value
  425. VOID osal_memcpy( pAttr->pValue + offset, pValue, PPSP_SERV_CFGS_CHAR_FED6_DLEN );
  426. upda_para = PPSP_SERV_CFGS_CHAR_FFD6_INDX;
  427. }
  428. }
  429. break;
  430. case PPSP_SERV_CFGS_CHAR_FED7_UUID: {
  431. if ( PPSP_SERV_CFGS_CHAR_FED7_DLEN <= offset ) {
  432. status = ATT_ERR_INVALID_VALUE_SIZE;
  433. } else {
  434. // Write the value
  435. VOID osal_memcpy( pAttr->pValue + offset, pValue, PPSP_SERV_CFGS_CHAR_FED7_DLEN );
  436. upda_para = PPSP_SERV_CFGS_CHAR_FFD7_INDX;
  437. }
  438. }
  439. break;
  440. case PPSP_SERV_CFGS_CHAR_FED8_UUID: {
  441. if ( PPSP_SERV_CFGS_CHAR_FED8_DLEN <= offset ) {
  442. status = ATT_ERR_INVALID_VALUE_SIZE;
  443. } else {
  444. // Write the value
  445. VOID osal_memcpy( pAttr->pValue + offset, pValue, PPSP_SERV_CFGS_CHAR_FED8_DLEN );
  446. upda_para = PPSP_SERV_CFGS_CHAR_FFD8_INDX;
  447. }
  448. }
  449. break;
  450. case GATT_CLIENT_CHAR_CFG_UUID: {
  451. // Validate/Write Temperature measurement setting
  452. if ( pAttr->handle == simpleProfileAttrTbl[7].handle ) {
  453. // LOG("[PANDA][INF] CHAR FED6 CFGS: %d \n\r", *pValue);
  454. uint16 valu;
  455. if ( 0 != *pValue ) valu = 0x02;
  456. else valu = 0x00;
  457. status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, (uint8*)&valu, sizeof(valu),
  458. offset, GATT_CLIENT_CFG_INDICATE );
  459. } else
  460. if ( pAttr->handle == simpleProfileAttrTbl[12].handle ) {
  461. // LOG("[PANDA][INF] CHAR FED8 CFGS: %d \n\r", *pValue);
  462. status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, 2,
  463. offset, GATT_CLIENT_CFG_NOTIFY );
  464. }
  465. }
  466. break;
  467. default:
  468. // Should never get here! (characteristics 2 and 4 do not have write permissions)
  469. status = ATT_ERR_ATTR_NOT_FOUND;
  470. break;
  471. }
  472. } else {
  473. // 128-bit UUID
  474. status = ATT_ERR_INVALID_HANDLE;
  475. }
  476. // If a charactersitic value changed then callback function to notify application of change
  477. if ( upda_para != 0xFF &&
  478. NULL != simpleProfile_AppCBs &&
  479. NULL != simpleProfile_AppCBs->char_upda ) {
  480. simpleProfile_AppCBs->char_upda( upda_para, len );
  481. }
  482. return ( status );
  483. }
  484. /*********************************************************************
  485. * @fn simpleProfile_HandleConnStatusCB
  486. *
  487. * @brief Simple Profile link status change handler function.
  488. *
  489. * @param conn_hdle - connection handle
  490. * @param changeType - type of change
  491. *
  492. * @return none
  493. */
  494. static void ppsp_serv_hdlr_conn_stat( uint16 conn_hdle, uint8 chng_type )
  495. {
  496. // Make sure this is not loopback connection
  497. if ( conn_hdle != LOOPBACK_CONNHANDLE ) {
  498. // Reset Client Char Config if connection has dropped
  499. if ( ( chng_type == LINKDB_STATUS_UPDATE_REMOVED ) ||
  500. ( ( chng_type == LINKDB_STATUS_UPDATE_STATEFLAGS ) &&
  501. ( !linkDB_Up( conn_hdle ) ) ) ) {
  502. GATTServApp_InitCharCfg( conn_hdle, __ppsp_serv_char_ffd6_cfgs );
  503. GATTServApp_InitCharCfg( conn_hdle, __ppsp_serv_char_ffd8_cfgs );
  504. ppsp_impl_ack_conn(0); // ack upper impl loss of connection
  505. }
  506. }
  507. }
  508. /*********************************************************************
  509. * PROFILE CALLBACKS
  510. */
  511. // Simple Profile Service Callbacks
  512. CONST gattServiceCBs_t ppspCBs =
  513. {
  514. ppsp_serv_get_attr, // Read callback function pointer
  515. ppsp_serv_set_attr, // Write callback function pointer
  516. NULL, // Authorization callback function pointer
  517. };
  518. /*********************************************************************
  519. * PUBLIC FUNCTIONS
  520. */
  521. /*********************************************************************
  522. * @fn SimpleProfile_AddService
  523. *
  524. * @brief Initializes the Simple Profile service by registering
  525. * GATT attributes with the GATT server.
  526. *
  527. * @param services - services to add. This is a bit map and can
  528. * contain more than one service.
  529. *
  530. * @return Success or Failure
  531. */
  532. bStatus_t ppsp_serv_add_serv(uint32 serv)
  533. {
  534. uint8 status = SUCCESS;
  535. // Initialize Client Characteristic Configuration attributes
  536. GATTServApp_InitCharCfg( INVALID_CONNHANDLE, __ppsp_serv_char_ffd6_cfgs );
  537. GATTServApp_InitCharCfg( INVALID_CONNHANDLE, __ppsp_serv_char_ffd8_cfgs );
  538. // Register with Link DB to receive link status change callback
  539. VOID linkDB_Register( ppsp_serv_hdlr_conn_stat );
  540. if ( serv & PPSP_SERV_CFGS_SERV_FEB3_MASK )
  541. {
  542. // Register GATT attribute list and CBs with GATT Server App
  543. status = GATTServApp_RegisterService( simpleProfileAttrTbl,
  544. GATT_NUM_ATTRS( simpleProfileAttrTbl ),
  545. &ppspCBs );
  546. }
  547. // for (int i = 0; i < PPSP_SERV_CFGS_CHAR_FED4_DLEN; i++)
  548. // {
  549. // __ppsp_serv_char_FFD4_para[i] =i;
  550. // }
  551. return ( status );
  552. }
  553. /*********************************************************************
  554. * @fn SimpleProfile_RegisterAppCBs
  555. *
  556. * @brief Registers the application callback function. Only call
  557. * this function once.
  558. *
  559. * @param callbacks - pointer to application callbacks.
  560. *
  561. * @return SUCCESS or bleAlreadyInRequestedMode
  562. */
  563. bStatus_t ppsp_serv_reg_appl( ppsp_serv_appl_CBs_t *appCallbacks )
  564. {
  565. if ( appCallbacks ) {
  566. simpleProfile_AppCBs = appCallbacks;
  567. return ( SUCCESS );
  568. }
  569. else
  570. {
  571. return ( bleAlreadyInRequestedMode );
  572. }
  573. }
  574. /*********************************************************************
  575. * @fn SimpleProfile_SetParameter
  576. *
  577. * @brief Set a Simple Profile parameter.
  578. *
  579. * @param param - Profile parameter ID
  580. * @param len - length of data to right
  581. * @param value - pointer to data to write. This is dependent on
  582. * the parameter ID and WILL be cast to the appropriate
  583. * data type (example: data type of uint16 will be cast to
  584. * uint16 pointer).
  585. *
  586. * @return bStatus_t
  587. */
  588. bStatus_t ppsp_serv_set_para( uint8 para, uint8 leng, void *valu )
  589. {
  590. // LOG("[PANDA][ENT] %s: para:%d, leng:%d, valu:%x \n\r", __func__, para, leng, valu);
  591. // LOG("\r\n[DUMP] >> "); for ( int itr0 = 0; itr0 < leng; itr0 += 1 ) LOG("%02x,", ((uint8*)valu)[itr0]); LOG("[DUMP] << \r\n");
  592. bStatus_t ret = SUCCESS;
  593. switch ( para ) {
  594. case PPSP_SERV_CFGS_CHAR_FFD4_INDX: {
  595. if ( leng <= PPSP_SERV_CFGS_CHAR_FED4_DLEN ) {
  596. osal_memcpy(__ppsp_serv_char_ffd4_para, valu, __ppsp_serv_char_ffd4_para_size = leng);
  597. } else {
  598. ret = bleInvalidRange;
  599. }
  600. }
  601. break;
  602. // case PPSP_SERV_CFGS_CHAR_2_INDX:
  603. // if ( len <= PPSP_SERV_CFGS_CHAR_2_DLEN )
  604. // {
  605. // osal_memcpy(__ppsp_serv_char_2_para, value, len);
  606. // }
  607. // else
  608. // {
  609. // ret = bleInvalidRange;
  610. // }
  611. // break;
  612. // case PPSP_SERV_CFGS_CHAR_3_INDX:
  613. // if ( len == sizeof ( uint16 ) )
  614. // {
  615. // // simpleProfileChar3 = (*(uint8 *)value) << 8 | *((uint8 *)value + 1);
  616. // }
  617. // else
  618. // {
  619. // ret = bleInvalidRange;
  620. // }
  621. // break;
  622. case PPSP_SERV_CFGS_CHAR_FFD6_INDX: {
  623. uint16 cfgs = GATTServApp_ReadCharCfg( 0, __ppsp_serv_char_ffd6_cfgs );
  624. if ( GATT_CLIENT_CFG_INDICATE == cfgs ) {
  625. if ( leng <= PPSP_SERV_CFGS_CHAR_FED6_DLEN ) {
  626. osal_memcpy( __ppsp_serv_char_ffd6_para, valu, __ppsp_serv_char_ffd6_para_size = leng );
  627. // send Noti/Indi if enabled
  628. GATTServApp_ProcessCharCfg( __ppsp_serv_char_ffd6_cfgs,
  629. __ppsp_serv_char_ffd6_para,
  630. FALSE,
  631. simpleProfileAttrTbl,
  632. GATT_NUM_ATTRS( simpleProfileAttrTbl ),
  633. INVALID_TASK_ID );
  634. /* send_notity_indication( __ppsp_serv_char_ffd6_cfgs,
  635. __ppsp_serv_char_ffd6_para,
  636. FALSE,
  637. simpleProfileAttrTbl,
  638. GATT_NUM_ATTRS( simpleProfileAttrTbl ),
  639. INVALID_TASK_ID,__ppsp_serv_char_ffd6_para_size ); */
  640. } else {
  641. ret = bleInvalidRange;
  642. }
  643. }
  644. }
  645. break;
  646. // case PPSP_SERV_CFGS_CHAR_5_INDX:
  647. // if ( leng == sizeof ( uint8 ) )
  648. // {
  649. // // simpleProfileChar5 = *((uint8*)value);
  650. // }
  651. // else
  652. // {
  653. // ret = bleInvalidRange;
  654. // }
  655. // break;
  656. case PPSP_SERV_CFGS_CHAR_FFD8_INDX: {
  657. uint16 cfgs = GATTServApp_ReadCharCfg( 0, __ppsp_serv_char_ffd8_cfgs );
  658. if ( GATT_CLIENT_CFG_NOTIFY == cfgs ) {
  659. if ( leng <= PPSP_SERV_CFGS_CHAR_FED8_DLEN ) {
  660. osal_memcpy( __ppsp_serv_char_ffd8_para, valu, __ppsp_serv_char_ffd8_para_size = leng );
  661. // send Noti/Indi if enabled
  662. GATTServApp_ProcessCharCfg( __ppsp_serv_char_ffd8_cfgs,
  663. __ppsp_serv_char_ffd8_para,
  664. FALSE,
  665. simpleProfileAttrTbl,
  666. GATT_NUM_ATTRS( simpleProfileAttrTbl ),
  667. INVALID_TASK_ID );
  668. /* send_notity_indication( __ppsp_serv_char_ffd8_cfgs,
  669. __ppsp_serv_char_ffd8_para,
  670. FALSE,
  671. simpleProfileAttrTbl,
  672. GATT_NUM_ATTRS( simpleProfileAttrTbl ),
  673. INVALID_TASK_ID,__ppsp_serv_char_ffd8_para_size ); */
  674. } else {
  675. ret = bleInvalidRange;
  676. }
  677. }
  678. }
  679. break;
  680. default:
  681. ret = INVALIDPARAMETER;
  682. break;
  683. }
  684. return ( ret );
  685. }
  686. /*********************************************************************
  687. * @fn SimpleProfile_GetParameter
  688. *
  689. * @brief Get a Simple Profile parameter.
  690. *
  691. * @param param - Profile parameter ID
  692. * @param value - pointer to data to put. This is dependent on
  693. * the parameter ID and WILL be cast to the appropriate
  694. * data type (example: data type of uint16 will be cast to
  695. * uint16 pointer).
  696. *
  697. * @return bStatus_t
  698. */
  699. bStatus_t ppsp_serv_get_para( uint8 para, void *valu, uint8 leng )
  700. {
  701. bStatus_t ret = SUCCESS;
  702. switch ( para ) {
  703. case PPSP_SERV_CFGS_CHAR_FFD4_INDX:
  704. VOID osal_memcpy( valu, __ppsp_serv_char_ffd4_para, leng );
  705. break;
  706. case PPSP_SERV_CFGS_CHAR_FFD5_INDX:
  707. VOID osal_memcpy( valu, __ppsp_serv_char_ffd5_para, leng );
  708. break;
  709. case PPSP_SERV_CFGS_CHAR_FFD6_INDX:
  710. // *((uint16*)value) = simpleProfileChar3;
  711. break;
  712. case PPSP_SERV_CFGS_CHAR_FFD7_INDX:
  713. VOID osal_memcpy( valu, __ppsp_serv_char_ffd7_para, leng );
  714. break;
  715. case PPSP_SERV_CFGS_CHAR_FFD8_INDX:
  716. // *((uint8*)value) = simpleProfileChar5;
  717. break;
  718. default:
  719. ret = INVALIDPARAMETER;
  720. break;
  721. }
  722. return ( ret );
  723. }
  724. /* static bStatus_t send_notity_indication( gattCharCfg_t *charCfgTbl, uint8 *pValue,
  725. uint8 authenticated, gattAttribute_t *attrTbl,
  726. uint16 numAttrs, uint8 taskId,uint8 dlen)
  727. {
  728. bStatus_t status = SUCCESS;
  729. for ( uint8 i = 0; i < GATT_MAX_NUM_CONN; i++ )
  730. {
  731. gattCharCfg_t *pItem = &(charCfgTbl[i]);
  732. if ( ( pItem->connHandle != INVALID_CONNHANDLE ) &&
  733. ( pItem->value != GATT_CFG_NO_OPERATION ) )
  734. {
  735. gattAttribute_t *pAttr;
  736. // Find the characteristic value attribute
  737. pAttr = GATTServApp_FindAttr( attrTbl, numAttrs, pValue );
  738. if ( pAttr != NULL )
  739. {
  740. attHandleValueNoti_t noti;
  741. // If the attribute value is longer than (ATT_MTU - 3) octets, then
  742. // only the first (ATT_MTU - 3) octets of this attributes value can
  743. // be sent in a notification.
  744. if ( GATTServApp_ReadAttr( pItem->connHandle, pAttr,
  745. GATT_SERVICE_HANDLE( attrTbl ), noti.value,
  746. &noti.len, 0, (g_ATT_MTU_SIZE-3) ) == SUCCESS )
  747. {
  748. noti.handle = pAttr->handle;
  749. if(dlen)
  750. noti.len=dlen;
  751. if ( pItem->value & GATT_CLIENT_CFG_NOTIFY )
  752. {
  753. status |= GATT_Notification( pItem->connHandle, &noti, authenticated );
  754. }
  755. if ( pItem->value & GATT_CLIENT_CFG_INDICATE )
  756. {
  757. status |= GATT_Indication( pItem->connHandle, (attHandleValueInd_t *)&noti,
  758. authenticated, taskId );
  759. }
  760. }
  761. }
  762. }
  763. } // for
  764. return ( status );
  765. } */
  766. /*********************************************************************
  767. *********************************************************************/