OTAprofile.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /********************************** (C) COPYRIGHT *******************************
  2. * File Name : OTAprofile.C
  3. * Author : WCH
  4. * Version : V1.0
  5. * Date : 2018/12/10
  6. * Description : OTA upgrade Bluetooth communication interface
  7. *********************************************************************************
  8. * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
  9. * Attention: This software (modified or not) and binary are used for
  10. * microcontroller manufactured by Nanjing Qinheng Microelectronics.
  11. *******************************************************************************/
  12. /*********************************************************************
  13. * INCLUDES
  14. */
  15. #include "CONFIG.h"
  16. #include "OTAprofile.h"
  17. #include "debug.h"
  18. #include "ota.h"
  19. /*********************************************************************
  20. * MACROS
  21. */
  22. /*********************************************************************
  23. * CONSTANTS
  24. */
  25. /*********************************************************************
  26. * TYPEDEFS
  27. */
  28. /*********************************************************************
  29. * GLOBAL VARIABLES
  30. */
  31. // Simple GATT Profile Service UUID: 0xFFF0
  32. const uint8_t OTAProfileServUUID[ATT_BT_UUID_SIZE] = {
  33. LO_UINT16(OTAPROFILE_SERV_UUID), HI_UINT16(OTAPROFILE_SERV_UUID)};
  34. // Characteristic 1 UUID: 0xFFF1
  35. const uint8_t OTAProfilechar1UUID[ATT_BT_UUID_SIZE] = {
  36. LO_UINT16(OTAPROFILE_CHAR_UUID), HI_UINT16(OTAPROFILE_CHAR_UUID)};
  37. /*********************************************************************
  38. * EXTERNAL VARIABLES
  39. */
  40. /*********************************************************************
  41. * EXTERNAL FUNCTIONS
  42. */
  43. /*********************************************************************
  44. * LOCAL VARIABLES
  45. */
  46. static OTAProfileCBs_t *OTAProfile_AppCBs = NULL;
  47. /*********************************************************************
  48. * Profile Attributes - variables
  49. */
  50. // Simple Profile Service attribute
  51. static const gattAttrType_t OTAProfileService = {ATT_BT_UUID_SIZE, OTAProfileServUUID};
  52. // Simple Profile Characteristic 1 Properties
  53. static uint8_t OTAProfileCharProps = GATT_PROP_READ | GATT_PROP_WRITE | GATT_PROP_WRITE_NO_RSP;
  54. // Characteristic 1 Value
  55. static uint8_t OTAProfileChar = 0;
  56. // Simple Profile Characteristic 1 User Description
  57. static uint8_t OTAProfileCharUserDesp[12] = "OTA Channel";
  58. // write and read buffer
  59. static uint8_t OTAProfileReadLen;
  60. static uint8_t OTAProfileReadBuf[IAP_LEN];
  61. static uint8_t OTAProfileWriteLen;
  62. static uint8_t OTAProfileWriteBuf[IAP_LEN];
  63. /*********************************************************************
  64. * Profile Attributes - Table
  65. */
  66. static gattAttribute_t OTAProfileAttrTbl[4] = {
  67. // Simple Profile Service
  68. {
  69. {ATT_BT_UUID_SIZE, primaryServiceUUID}, /* type */
  70. GATT_PERMIT_READ, /* permissions */
  71. 0, /* handle */
  72. (uint8_t *)&OTAProfileService /* pValue */
  73. },
  74. // Characteristic Declaration
  75. {
  76. {ATT_BT_UUID_SIZE, characterUUID},
  77. GATT_PERMIT_READ,
  78. 0,
  79. &OTAProfileCharProps},
  80. // Characteristic Value
  81. {
  82. {ATT_BT_UUID_SIZE, OTAProfilechar1UUID},
  83. GATT_PERMIT_READ | GATT_PERMIT_WRITE,
  84. 0,
  85. &OTAProfileChar},
  86. // Characteristic User Description
  87. {
  88. {ATT_BT_UUID_SIZE, charUserDescUUID},
  89. GATT_PERMIT_READ,
  90. 0,
  91. OTAProfileCharUserDesp},
  92. };
  93. /*********************************************************************
  94. * LOCAL FUNCTIONS
  95. */
  96. static bStatus_t OTAProfile_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
  97. uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen, uint8_t method);
  98. static bStatus_t OTAProfile_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
  99. uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method);
  100. /*********************************************************************
  101. * PROFILE CALLBACKS
  102. */
  103. // OTA Profile Service Callbacks
  104. gattServiceCBs_t OTAProfileCBs = {
  105. OTAProfile_ReadAttrCB, // Read callback function pointer
  106. OTAProfile_WriteAttrCB, // Write callback function pointer
  107. NULL // Authorization callback function pointer
  108. };
  109. /*********************************************************************
  110. * PUBLIC FUNCTIONS
  111. */
  112. /*********************************************************************
  113. * @fn OTAProfile_AddService
  114. *
  115. * @brief OTA Profile initialization
  116. *
  117. * @param services - Service control
  118. *
  119. * @return Initialization state
  120. */
  121. bStatus_t OTAProfile_AddService(uint32_t services)
  122. {
  123. uint8_t status = SUCCESS;
  124. if(services & OTAPROFILE_SERVICE)
  125. {
  126. // Register GATT attribute list and CBs with GATT Server App
  127. status = GATTServApp_RegisterService(OTAProfileAttrTbl,
  128. GATT_NUM_ATTRS(OTAProfileAttrTbl),
  129. GATT_MAX_ENCRYPT_KEY_SIZE,
  130. &OTAProfileCBs);
  131. }
  132. return (status);
  133. }
  134. /*********************************************************************
  135. * @fn OTAProfile_RegisterAppCBs
  136. *
  137. * @brief OTA Profile read and write recovery function registration
  138. *
  139. * @param appCallbacks - Function structure pointer
  140. *
  141. * @return Function execution status
  142. */
  143. bStatus_t OTAProfile_RegisterAppCBs(OTAProfileCBs_t *appCallbacks)
  144. {
  145. if(appCallbacks)
  146. {
  147. OTAProfile_AppCBs = appCallbacks;
  148. return (SUCCESS);
  149. }
  150. else
  151. {
  152. return (bleAlreadyInRequestedMode);
  153. }
  154. }
  155. /*********************************************************************
  156. * @fn OTAProfile_ReadAttrCB
  157. *
  158. * @brief Read an attribute.
  159. *
  160. * @param connHandle - connection message was received on
  161. * @param pAttr - pointer to attribute
  162. * @param pValue - pointer to data to be read
  163. * @param pLen - length of data to be read
  164. * @param offset - offset of the first octet to be read
  165. * @param maxLen - maximum length of data to be read
  166. *
  167. * @return Success or Failure
  168. */
  169. static bStatus_t OTAProfile_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
  170. uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen, uint8_t method)
  171. {
  172. bStatus_t status = SUCCESS;
  173. if(pAttr->type.len == ATT_BT_UUID_SIZE)
  174. {
  175. // 16-bit UUID
  176. uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
  177. switch(uuid)
  178. {
  179. case OTAPROFILE_CHAR_UUID:
  180. {
  181. *pLen = 0;
  182. if(OTAProfileReadLen)
  183. {
  184. *pLen = OTAProfileReadLen;
  185. tmos_memcpy(pValue, OTAProfileReadBuf, OTAProfileReadLen);
  186. OTAProfileReadLen = 0;
  187. if(OTAProfile_AppCBs && OTAProfile_AppCBs->pfnOTAProfileRead)
  188. {
  189. OTAProfile_AppCBs->pfnOTAProfileRead(OTAPROFILE_CHAR);
  190. }
  191. }
  192. break;
  193. }
  194. default:
  195. {
  196. // Should never get here! (characteristics 3 and 4 do not have read permissions)
  197. *pLen = 0;
  198. status = ATT_ERR_ATTR_NOT_FOUND;
  199. break;
  200. }
  201. }
  202. }
  203. else
  204. {
  205. // 128-bit UUID
  206. *pLen = 0;
  207. status = ATT_ERR_INVALID_HANDLE;
  208. }
  209. return (status);
  210. }
  211. /*********************************************************************
  212. * @fn OTAProfile_WriteAttrCB
  213. *
  214. * @brief Validate attribute data prior to a write operation
  215. *
  216. * @param connHandle - connection message was received on
  217. * @param pAttr - pointer to attribute
  218. * @param pValue - pointer to data to be written
  219. * @param len - length of data
  220. * @param offset - offset of the first octet to be written
  221. *
  222. * @return Success or Failure
  223. */
  224. static bStatus_t OTAProfile_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
  225. uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method)
  226. {
  227. bStatus_t status = SUCCESS;
  228. //uint8_t notifyApp = 0xFF;
  229. if(pAttr->type.len == ATT_BT_UUID_SIZE)
  230. {
  231. // 16-bit UUID
  232. uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
  233. switch(uuid)
  234. {
  235. case OTAPROFILE_CHAR_UUID:
  236. {
  237. //Write the value
  238. if(status == SUCCESS)
  239. {
  240. uint16_t i;
  241. uint8_t *p_rec_buf;
  242. OTAProfileWriteLen = len;
  243. p_rec_buf = pValue;
  244. for(i = 0; i < OTAProfileWriteLen; i++)
  245. OTAProfileWriteBuf[i] = p_rec_buf[i];
  246. }
  247. break;
  248. }
  249. default:
  250. // Should never get here! (characteristics 2 and 4 do not have write permissions)
  251. status = ATT_ERR_ATTR_NOT_FOUND;
  252. break;
  253. }
  254. }
  255. else
  256. {
  257. // 128-bit UUID
  258. status = ATT_ERR_INVALID_HANDLE;
  259. }
  260. if(OTAProfileWriteLen && OTAProfile_AppCBs && OTAProfile_AppCBs->pfnOTAProfileWrite)
  261. {
  262. OTAProfile_AppCBs->pfnOTAProfileWrite(OTAPROFILE_CHAR, OTAProfileWriteBuf, OTAProfileWriteLen);
  263. OTAProfileWriteLen = 0;
  264. }
  265. return (status);
  266. }
  267. /*********************************************************************
  268. * @fn OTAProfile_SendData
  269. *
  270. * @brief OTA Profile channel send data
  271. *
  272. * @param paramID - OTA channel selection
  273. * @param p_data - Data pointer
  274. * @param send_len - Send data length
  275. *
  276. * @return Function execution status
  277. */
  278. bStatus_t OTAProfile_SendData(unsigned char paramID, unsigned char *p_data, unsigned char send_len)
  279. {
  280. bStatus_t status = SUCCESS;
  281. /* Data length exceeds range */
  282. if(send_len > 20)
  283. return 0xfe;
  284. OTAProfileReadLen = send_len;
  285. tmos_memcpy(OTAProfileReadBuf, p_data, OTAProfileReadLen);
  286. return status;
  287. }
  288. /*********************************************************************
  289. *********************************************************************/