peripheral.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833
  1. /********************************** (C) COPYRIGHT *******************************
  2. * File Name : peripheral.C
  3. * Author : WCH
  4. * Version : V1.0
  5. * Date : 2018/12/10
  6. * Description : Peripheral slave multi-connection application,
  7. * initialize broadcast connection parameters, then broadcast,
  8. * after connecting to the host, request to update connection parameters,
  9. * and transmit data through custom services
  10. *********************************************************************************
  11. * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
  12. * Attention: This software (modified or not) and binary are used for
  13. * microcontroller manufactured by Nanjing Qinheng Microelectronics.
  14. *******************************************************************************/
  15. /*********************************************************************
  16. * INCLUDES
  17. */
  18. #include "CONFIG.h"
  19. #include "devinfoservice.h"
  20. #include "gattprofile.h"
  21. #include "peripheral.h"
  22. /*********************************************************************
  23. * MACROS
  24. */
  25. /*********************************************************************
  26. * CONSTANTS
  27. */
  28. // How often to perform periodic event
  29. #define SBP_PERIODIC_EVT_PERIOD 1600
  30. // How often to perform read rssi event
  31. #define SBP_READ_RSSI_EVT_PERIOD 3200
  32. // Parameter update delay
  33. #define SBP_PARAM_UPDATE_DELAY 6400
  34. // PHY update delay
  35. #define SBP_PHY_UPDATE_DELAY 2400
  36. // What is the advertising interval when device is discoverable (units of 625us, 80=50ms)
  37. #define DEFAULT_ADVERTISING_INTERVAL 80
  38. // Limited discoverable mode advertises for 30.72s, and then stops
  39. // General discoverable mode advertises indefinitely
  40. #define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL
  41. // Minimum connection interval (units of 1.25ms, 6=7.5ms)
  42. #define DEFAULT_DESIRED_MIN_CONN_INTERVAL 6
  43. // Maximum connection interval (units of 1.25ms, 100=125ms)
  44. #define DEFAULT_DESIRED_MAX_CONN_INTERVAL 1000
  45. // Slave latency to use parameter update
  46. #define DEFAULT_DESIRED_SLAVE_LATENCY 0
  47. // Supervision timeout value (units of 10ms, 100=1s)
  48. #define DEFAULT_DESIRED_CONN_TIMEOUT 100
  49. // Company Identifier: WCH
  50. #define WCH_COMPANY_ID 0x07D7
  51. /*********************************************************************
  52. * TYPEDEFS
  53. */
  54. /*********************************************************************
  55. * GLOBAL VARIABLES
  56. */
  57. /*********************************************************************
  58. * EXTERNAL VARIABLES
  59. */
  60. /*********************************************************************
  61. * EXTERNAL FUNCTIONS
  62. */
  63. /*********************************************************************
  64. * LOCAL VARIABLES
  65. */
  66. static uint8_t Peripheral_TaskID = INVALID_TASK_ID; // Task ID for internal task/event processing
  67. // GAP - SCAN RSP data (max size = 31 bytes)
  68. static uint8_t scanRspData[] = {
  69. // complete name
  70. 0x09, // length of this data
  71. GAP_ADTYPE_LOCAL_NAME_COMPLETE,
  72. 'L', 'O', 'C', 'K', 'B', 'A', 'S', 'E',
  73. // connection interval range
  74. 0x05, // length of this data
  75. GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
  76. LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL), // 100ms
  77. HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
  78. LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL), // 1s
  79. HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
  80. // Tx power level
  81. 0x02, // length of this data
  82. GAP_ADTYPE_POWER_LEVEL,
  83. 0 // 0dBm
  84. };
  85. // GAP - Advertisement data (max size = 31 bytes, though this is
  86. // best kept short to conserve power while advertising)
  87. static uint8_t advertData[] = {
  88. // Flags; this sets the device to use limited discoverable
  89. // mode (advertises for 30 seconds at a time) instead of general
  90. // discoverable mode (advertises indefinitely)
  91. 0x02, // length of this data
  92. GAP_ADTYPE_FLAGS,
  93. DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
  94. // service UUID, to notify central devices what services are included
  95. // in this peripheral
  96. 0x03, // length of this data
  97. GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all
  98. LO_UINT16(SIMPLEPROFILE_SERV_UUID),
  99. HI_UINT16(SIMPLEPROFILE_SERV_UUID),
  100. //指向制造商自定义的数据
  101. 0x0D,
  102. GAP_ADTYPE_MANUFACTURER_SPECIFIC,
  103. 0xD7, 0x07, 0xFF, 0x01,
  104. SOFTWARE_VERSION, 0x01,
  105. 0xFF, 0xFF, 0xFF,
  106. 0xFF, 0xFF, 0xFF
  107. };
  108. // GAP GATT Attributes
  109. static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "LOCKBASE";
  110. // Connection item list
  111. static peripheralConnItem_t peripheralConnList;
  112. static uint8_t peripheralMTU = ATT_MTU_SIZE;
  113. static download_ble_data_func download_ble_data = NULL;
  114. static download_ble_data_func download_ble_file = NULL;
  115. static ble_connect_func ble_connect = NULL;
  116. /*********************************************************************
  117. * LOCAL FUNCTIONS
  118. */
  119. static void Peripheral_ProcessTMOSMsg(tmos_event_hdr_t *pMsg);
  120. static void peripheralStateNotificationCB(gapRole_States_t newState, gapRoleEvent_t *pEvent);
  121. static void performPeriodicTask(void);
  122. static void simpleProfileChangeCB(uint8_t paramID, uint8_t *pValue, uint16_t len);
  123. static void peripheralParamUpdateCB(uint16_t connHandle, uint16_t connInterval,
  124. uint16_t connSlaveLatency, uint16_t connTimeout);
  125. static void peripheralInitConnItem(peripheralConnItem_t *peripheralConnList);
  126. static void peripheralRssiCB(uint16_t connHandle, int8_t rssi);
  127. static void peripheralChar4Notify(uint8_t *pValue, uint16_t len);
  128. /*********************************************************************
  129. * PROFILE CALLBACKS
  130. */
  131. // GAP Role Callbacks
  132. static gapRolesCBs_t Peripheral_PeripheralCBs = {
  133. peripheralStateNotificationCB, // Profile State Change Callbacks
  134. peripheralRssiCB, // When a valid RSSI is read from controller (not used by application)
  135. peripheralParamUpdateCB
  136. };
  137. // Broadcast Callbacks
  138. static gapRolesBroadcasterCBs_t Broadcaster_BroadcasterCBs = {
  139. NULL, // Not used in peripheral role
  140. NULL // Receive scan request callback
  141. };
  142. // GAP Bond Manager Callbacks
  143. static gapBondCBs_t Peripheral_BondMgrCBs = {
  144. NULL, // Passcode callback (not used by application)
  145. NULL, // Pairing / Bonding state Callback (not used by application)
  146. NULL // oob callback
  147. };
  148. // Simple GATT Profile Callbacks
  149. static simpleProfileCBs_t Peripheral_SimpleProfileCBs = {
  150. simpleProfileChangeCB // Characteristic value change callback
  151. };
  152. /*********************************************************************
  153. * PUBLIC FUNCTIONS
  154. */
  155. /*********************************************************************
  156. * @fn Peripheral_Init
  157. *
  158. * @brief Initialization function for the Peripheral App Task.
  159. * This is called during initialization and should contain
  160. * any application specific initialization (ie. hardware
  161. * initialization/setup, table initialization, power up
  162. * notificaiton ... ).
  163. *
  164. * @param task_id - the ID assigned by TMOS. This ID should be
  165. * used to send messages and set timers.
  166. *
  167. * @return none
  168. */
  169. void Peripheral_Init(void)
  170. {
  171. Peripheral_TaskID = TMOS_ProcessEventRegister(Peripheral_ProcessEvent);
  172. // Setup the GAP Peripheral Role Profile
  173. {
  174. uint8_t initial_advertising_enable = TRUE;
  175. uint16_t desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
  176. uint16_t desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
  177. advertData[sizeof(advertData) - 6] = MacAddr[0];
  178. advertData[sizeof(advertData) - 5] = MacAddr[1];
  179. advertData[sizeof(advertData) - 4] = MacAddr[2];
  180. advertData[sizeof(advertData) - 3] = MacAddr[3];
  181. advertData[sizeof(advertData) - 2] = MacAddr[4];
  182. advertData[sizeof(advertData) - 1] = MacAddr[5];
  183. // Set the GAP Role Parameters
  184. GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initial_advertising_enable);
  185. GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), scanRspData);
  186. GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
  187. GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t), &desired_min_interval);
  188. GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t), &desired_max_interval);
  189. }
  190. // Set the GAP Characteristics
  191. GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
  192. {
  193. uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
  194. // Set advertising interval
  195. GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, advInt);
  196. GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, advInt);
  197. // Enable scan req notify
  198. GAP_SetParamValue(TGAP_ADV_SCAN_REQ_NOTIFY, ENABLE);
  199. }
  200. // Setup the GAP Bond Manager
  201. {
  202. uint32_t passkey = 0; // passkey "000000"
  203. uint8_t pairMode = GAPBOND_PAIRING_MODE_NO_PAIRING;//GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
  204. uint8_t mitm = TRUE;
  205. uint8_t bonding = FALSE;
  206. uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
  207. GAPBondMgr_SetParameter(GAPBOND_PERI_DEFAULT_PASSCODE, sizeof(uint32_t), &passkey);
  208. GAPBondMgr_SetParameter(GAPBOND_PERI_PAIRING_MODE, sizeof(uint8_t), &pairMode);
  209. GAPBondMgr_SetParameter(GAPBOND_PERI_MITM_PROTECTION, sizeof(uint8_t), &mitm);
  210. GAPBondMgr_SetParameter(GAPBOND_PERI_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
  211. GAPBondMgr_SetParameter(GAPBOND_PERI_BONDING_ENABLED, sizeof(uint8_t), &bonding);
  212. }
  213. // Initialize GATT attributes
  214. GGS_AddService(GATT_ALL_SERVICES); // GAP
  215. GATTServApp_AddService(GATT_ALL_SERVICES); // GATT attributes
  216. DevInfo_AddService(); // Device Information Service
  217. SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile
  218. // Setup the SimpleProfile Characteristic Values
  219. {
  220. uint8_t charValue1[SIMPLEPROFILE_CHAR1_LEN] = {1};
  221. uint8_t charValue2[SIMPLEPROFILE_CHAR2_LEN] = {0};
  222. uint8_t charValue3[SIMPLEPROFILE_CHAR3_LEN] = {0};
  223. uint8_t charValue4[SIMPLEPROFILE_CHAR4_LEN] = {0};
  224. #if(DEBUG == DEBUG_UART_BLE)
  225. uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = {1, 2, 3, 4, 5};
  226. #endif
  227. SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, SIMPLEPROFILE_CHAR1_LEN, charValue1);
  228. SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, SIMPLEPROFILE_CHAR2_LEN, charValue2);
  229. SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, SIMPLEPROFILE_CHAR3_LEN, charValue3);
  230. SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, SIMPLEPROFILE_CHAR4_LEN, charValue4);
  231. #if(DEBUG == DEBUG_UART_BLE)
  232. SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN, charValue5);
  233. #endif
  234. }
  235. // Init Connection Item
  236. peripheralInitConnItem(&peripheralConnList);
  237. // Register callback with SimpleGATTprofile
  238. SimpleProfile_RegisterAppCBs(&Peripheral_SimpleProfileCBs);
  239. // Register receive scan request callback
  240. GAPRole_BroadcasterSetCB(&Broadcaster_BroadcasterCBs);
  241. // Setup a delayed profile startup
  242. tmos_set_event(Peripheral_TaskID, SBP_START_DEVICE_EVT);
  243. }
  244. /*********************************************************************
  245. * @fn peripheralInitConnItem
  246. *
  247. * @brief Init Connection Item
  248. *
  249. * @param peripheralConnList -
  250. *
  251. * @return NULL
  252. */
  253. static void peripheralInitConnItem(peripheralConnItem_t *peripheralConnList)
  254. {
  255. peripheralConnList->connHandle = GAP_CONNHANDLE_INIT;
  256. peripheralConnList->connInterval = 0;
  257. peripheralConnList->connSlaveLatency = 0;
  258. peripheralConnList->connTimeout = 0;
  259. }
  260. /*********************************************************************
  261. * @fn Peripheral_ProcessEvent
  262. *
  263. * @brief Peripheral Application Task event processor. This function
  264. * is called to process all events for the task. Events
  265. * include timers, messages and any other user defined events.
  266. *
  267. * @param task_id - The TMOS assigned task ID.
  268. * @param events - events to process. This is a bit map and can
  269. * contain more than one event.
  270. *
  271. * @return events not processed
  272. */
  273. uint16_t Peripheral_ProcessEvent(uint8_t task_id, uint16_t events)
  274. {
  275. // VOID task_id; // TMOS required parameter that isn't used in this function
  276. if(events & SYS_EVENT_MSG)
  277. {
  278. uint8_t *pMsg;
  279. if((pMsg = tmos_msg_receive(Peripheral_TaskID)) != NULL)
  280. {
  281. Peripheral_ProcessTMOSMsg((tmos_event_hdr_t *)pMsg);
  282. // Release the TMOS message
  283. tmos_msg_deallocate(pMsg);
  284. }
  285. // return unprocessed events
  286. return (events ^ SYS_EVENT_MSG);
  287. }
  288. if(events & SBP_START_DEVICE_EVT)
  289. {
  290. // Start the Device
  291. GAPRole_PeripheralStartDevice(Peripheral_TaskID, &Peripheral_BondMgrCBs, &Peripheral_PeripheralCBs);
  292. return (events ^ SBP_START_DEVICE_EVT);
  293. }
  294. if(events & SBP_PERIODIC_EVT)
  295. {
  296. // Restart timer
  297. if(SBP_PERIODIC_EVT_PERIOD)
  298. {
  299. tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD);
  300. }
  301. // Perform periodic application task
  302. performPeriodicTask();
  303. return (events ^ SBP_PERIODIC_EVT);
  304. }
  305. if(events & SBP_PARAM_UPDATE_EVT)
  306. {
  307. // Send connect param update request
  308. GAPRole_PeripheralConnParamUpdateReq(peripheralConnList.connHandle,
  309. DEFAULT_DESIRED_MIN_CONN_INTERVAL,
  310. DEFAULT_DESIRED_MAX_CONN_INTERVAL,
  311. DEFAULT_DESIRED_SLAVE_LATENCY,
  312. DEFAULT_DESIRED_CONN_TIMEOUT,
  313. Peripheral_TaskID);
  314. return (events ^ SBP_PARAM_UPDATE_EVT);
  315. }
  316. if(events & SBP_PHY_UPDATE_EVT)
  317. {
  318. // start phy update
  319. PRINT("PHY Update %x...\n", GAPRole_UpdatePHY(peripheralConnList.connHandle, 0, GAP_PHY_BIT_LE_2M,
  320. GAP_PHY_BIT_LE_2M, 0));
  321. return (events ^ SBP_PHY_UPDATE_EVT);
  322. }
  323. if(events & SBP_READ_RSSI_EVT)
  324. {
  325. GAPRole_ReadRssiCmd(peripheralConnList.connHandle);
  326. tmos_start_task(Peripheral_TaskID, SBP_READ_RSSI_EVT, SBP_READ_RSSI_EVT_PERIOD);
  327. return (events ^ SBP_READ_RSSI_EVT);
  328. }
  329. // Discard unknown events
  330. return 0;
  331. }
  332. /*********************************************************************
  333. * @fn Peripheral_ProcessGAPMsg
  334. *
  335. * @brief Process an incoming task message.
  336. *
  337. * @param pMsg - message to process
  338. *
  339. * @return none
  340. */
  341. static void Peripheral_ProcessGAPMsg(gapRoleEvent_t *pEvent)
  342. {
  343. switch(pEvent->gap.opcode)
  344. {
  345. case GAP_SCAN_REQUEST_EVENT:
  346. {
  347. // PRINT("Receive scan req from %x %x %x %x %x %x ..\n", pEvent->scanReqEvt.scannerAddr[0],
  348. // pEvent->scanReqEvt.scannerAddr[1], pEvent->scanReqEvt.scannerAddr[2], pEvent->scanReqEvt.scannerAddr[3],
  349. // pEvent->scanReqEvt.scannerAddr[4], pEvent->scanReqEvt.scannerAddr[5]);
  350. break;
  351. }
  352. case GAP_PHY_UPDATE_EVENT:
  353. {
  354. PRINT("Phy update Rx:%x Tx:%x ..\n", pEvent->linkPhyUpdate.connRxPHYS, pEvent->linkPhyUpdate.connTxPHYS);
  355. break;
  356. }
  357. default:
  358. break;
  359. }
  360. }
  361. /*********************************************************************
  362. * @fn Peripheral_ProcessTMOSMsg
  363. *
  364. * @brief Process an incoming task message.
  365. *
  366. * @param pMsg - message to process
  367. *
  368. * @return none
  369. */
  370. static void Peripheral_ProcessTMOSMsg(tmos_event_hdr_t *pMsg)
  371. {
  372. switch(pMsg->event)
  373. {
  374. case GAP_MSG_EVENT:
  375. {
  376. Peripheral_ProcessGAPMsg((gapRoleEvent_t *)pMsg);
  377. break;
  378. }
  379. case GATT_MSG_EVENT:
  380. {
  381. gattMsgEvent_t *pMsgEvent;
  382. pMsgEvent = (gattMsgEvent_t *)pMsg;
  383. if(pMsgEvent->method == ATT_MTU_UPDATED_EVENT)
  384. {
  385. peripheralMTU = pMsgEvent->msg.exchangeMTUReq.clientRxMTU;
  386. PRINT("mtu exchange: %d\n", pMsgEvent->msg.exchangeMTUReq.clientRxMTU);
  387. }
  388. break;
  389. }
  390. default:
  391. break;
  392. }
  393. }
  394. /*********************************************************************
  395. * @fn Peripheral_LinkEstablished
  396. *
  397. * @brief Process link established.
  398. *
  399. * @param pEvent - event to process
  400. *
  401. * @return none
  402. */
  403. static void Peripheral_LinkEstablished(gapRoleEvent_t *pEvent)
  404. {
  405. gapEstLinkReqEvent_t *event = (gapEstLinkReqEvent_t *)pEvent;
  406. // See if already connected
  407. if(peripheralConnList.connHandle != GAP_CONNHANDLE_INIT)
  408. {
  409. GAPRole_TerminateLink(pEvent->linkCmpl.connectionHandle);
  410. PRINT("Connection max...\n");
  411. }
  412. else
  413. {
  414. peripheralConnList.connHandle = event->connectionHandle;
  415. peripheralConnList.connInterval = event->connInterval;
  416. peripheralConnList.connSlaveLatency = event->connLatency;
  417. peripheralConnList.connTimeout = event->connTimeout;
  418. // Set timer for periodic event
  419. tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD);
  420. // Set timer for param update event
  421. tmos_start_task(Peripheral_TaskID, SBP_PARAM_UPDATE_EVT, SBP_PARAM_UPDATE_DELAY);
  422. // Start read rssi
  423. tmos_start_task(Peripheral_TaskID, SBP_READ_RSSI_EVT, SBP_READ_RSSI_EVT_PERIOD);
  424. PRINT("Conn %x - Int %x \n", event->connectionHandle, event->connInterval);
  425. }
  426. }
  427. /*********************************************************************
  428. * @fn Peripheral_LinkTerminated
  429. *
  430. * @brief Process link terminated.
  431. *
  432. * @param pEvent - event to process
  433. *
  434. * @return none
  435. */
  436. static void Peripheral_LinkTerminated(gapRoleEvent_t *pEvent)
  437. {
  438. gapTerminateLinkEvent_t *event = (gapTerminateLinkEvent_t *)pEvent;
  439. if(event->connectionHandle == peripheralConnList.connHandle)
  440. {
  441. peripheralConnList.connHandle = GAP_CONNHANDLE_INIT;
  442. peripheralConnList.connInterval = 0;
  443. peripheralConnList.connSlaveLatency = 0;
  444. peripheralConnList.connTimeout = 0;
  445. tmos_stop_task(Peripheral_TaskID, SBP_PERIODIC_EVT);
  446. tmos_stop_task(Peripheral_TaskID, SBP_READ_RSSI_EVT);
  447. // Restart advertising
  448. {
  449. uint8_t advertising_enable = TRUE;
  450. GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advertising_enable);
  451. }
  452. }
  453. else
  454. {
  455. PRINT("ERR..\n");
  456. }
  457. }
  458. /*********************************************************************
  459. * @fn peripheralRssiCB
  460. *
  461. * @brief RSSI callback.
  462. *
  463. * @param connHandle - connection handle
  464. * @param rssi - RSSI
  465. *
  466. * @return none
  467. */
  468. static void peripheralRssiCB(uint16_t connHandle, int8_t rssi)
  469. {
  470. // PRINT("RSSI -%d dB Conn %x \n", -rssi, connHandle);
  471. }
  472. /*********************************************************************
  473. * @fn peripheralParamUpdateCB
  474. *
  475. * @brief Parameter update complete callback
  476. *
  477. * @param connHandle - connect handle
  478. * connInterval - connect interval
  479. * connSlaveLatency - connect slave latency
  480. * connTimeout - connect timeout
  481. *
  482. * @return none
  483. */
  484. static void peripheralParamUpdateCB(uint16_t connHandle, uint16_t connInterval,
  485. uint16_t connSlaveLatency, uint16_t connTimeout)
  486. {
  487. if(connHandle == peripheralConnList.connHandle)
  488. {
  489. peripheralConnList.connInterval = connInterval;
  490. peripheralConnList.connSlaveLatency = connSlaveLatency;
  491. peripheralConnList.connTimeout = connTimeout;
  492. PRINT("Update %x - Int %x \n", connHandle, connInterval);
  493. }
  494. else
  495. {
  496. PRINT("ERR..\n");
  497. }
  498. }
  499. /*********************************************************************
  500. * @fn peripheralStateNotificationCB
  501. *
  502. * @brief Notification from the profile of a state change.
  503. *
  504. * @param newState - new state
  505. *
  506. * @return none
  507. */
  508. static void peripheralStateNotificationCB(gapRole_States_t newState, gapRoleEvent_t *pEvent)
  509. {
  510. switch(newState & GAPROLE_STATE_ADV_MASK)
  511. {
  512. case GAPROLE_STARTED:
  513. PRINT("Initialized..\n");
  514. break;
  515. case GAPROLE_ADVERTISING:
  516. if(pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT)
  517. {
  518. Peripheral_LinkTerminated(pEvent);
  519. PRINT("Disconnected.. Reason:%x\n", pEvent->linkTerminate.reason);
  520. PRINT("Advertising..\n");
  521. if(ble_connect != NULL)
  522. {
  523. ble_connect(false);
  524. }
  525. }
  526. else if(pEvent->gap.opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT)
  527. {
  528. PRINT("Advertising..\n");
  529. }
  530. break;
  531. case GAPROLE_CONNECTED:
  532. if(pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT)
  533. {
  534. Peripheral_LinkEstablished(pEvent);
  535. PRINT("Connected..\n");
  536. if(ble_connect != NULL)
  537. {
  538. ble_connect(true);
  539. }
  540. }
  541. break;
  542. case GAPROLE_CONNECTED_ADV:
  543. if(pEvent->gap.opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT)
  544. {
  545. PRINT("Connected Advertising..\n");
  546. }
  547. break;
  548. case GAPROLE_WAITING:
  549. if(pEvent->gap.opcode == GAP_END_DISCOVERABLE_DONE_EVENT)
  550. {
  551. PRINT("Waiting for advertising..\n");
  552. }
  553. else if(pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT)
  554. {
  555. Peripheral_LinkTerminated(pEvent);
  556. PRINT("Disconnected.. Reason:%x\n", pEvent->linkTerminate.reason);
  557. if(ble_connect != NULL)
  558. {
  559. ble_connect(false);
  560. }
  561. }
  562. else if(pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT)
  563. {
  564. if(pEvent->gap.hdr.status != SUCCESS)
  565. {
  566. PRINT("Waiting for advertising..\n");
  567. }
  568. else
  569. {
  570. PRINT("Error..\n");
  571. }
  572. }
  573. else
  574. {
  575. PRINT("Error..%x\n", pEvent->gap.opcode);
  576. }
  577. break;
  578. case GAPROLE_ERROR:
  579. PRINT("Error..\n");
  580. break;
  581. default:
  582. break;
  583. }
  584. }
  585. /*********************************************************************
  586. * @fn performPeriodicTask
  587. *
  588. * @brief Perform a periodic application task. This function gets
  589. * called every five seconds as a result of the SBP_PERIODIC_EVT
  590. * TMOS event. In this example, the value of the third
  591. * characteristic in the SimpleGATTProfile service is retrieved
  592. * from the profile, and then copied into the value of the
  593. * the fourth characteristic.
  594. *
  595. * @param none
  596. *
  597. * @return none
  598. */
  599. static void performPeriodicTask(void)
  600. {
  601. // uint8_t notiData[SIMPLEPROFILE_CHAR4_LEN] = {0x88};
  602. // peripheralChar4Notify(notiData, SIMPLEPROFILE_CHAR4_LEN);
  603. }
  604. /*********************************************************************
  605. * @fn peripheralChar4Notify
  606. *
  607. * @brief Prepare and send simpleProfileChar4 notification
  608. *
  609. * @param pValue - data to notify
  610. * len - length of data
  611. *
  612. * @return none
  613. */
  614. static void peripheralChar4Notify(uint8_t *pValue, uint16_t len)
  615. {
  616. attHandleValueNoti_t noti;
  617. if(len > (peripheralMTU - 3))
  618. {
  619. PRINT("Too large noti\n");
  620. return;
  621. }
  622. noti.len = len;
  623. noti.pValue = GATT_bm_alloc(peripheralConnList.connHandle, ATT_HANDLE_VALUE_NOTI, noti.len, NULL, 0);
  624. if(noti.pValue)
  625. {
  626. tmos_memcpy(noti.pValue, pValue, noti.len);
  627. if(simpleProfileChar4_Notify(peripheralConnList.connHandle, &noti) != SUCCESS)
  628. {
  629. GATT_bm_free((gattMsg_t *)&noti, ATT_HANDLE_VALUE_NOTI);
  630. }
  631. }
  632. }
  633. #if(DEBUG == DEBUG_UART_BLE)
  634. /*********************************************************************
  635. * @fn peripheralChar5Notify
  636. *
  637. * @brief Prepare and send simpleProfileChar4 notification
  638. *
  639. * @param pValue - data to notify
  640. * len - length of data
  641. *
  642. * @return none
  643. */
  644. static void peripheralChar5Notify(uint8_t *pValue, uint16_t len)
  645. {
  646. attHandleValueNoti_t noti;
  647. if(len > (peripheralMTU - 3))
  648. {
  649. // PRINT("Too large noti\n");
  650. return;
  651. }
  652. noti.len = len;
  653. noti.pValue = GATT_bm_alloc(peripheralConnList.connHandle, ATT_HANDLE_VALUE_NOTI, noti.len, NULL, 0);
  654. if(noti.pValue)
  655. {
  656. tmos_memcpy(noti.pValue, pValue, noti.len);
  657. if(simpleProfileChar5_Notify(peripheralConnList.connHandle, &noti) != SUCCESS)
  658. {
  659. GATT_bm_free((gattMsg_t *)&noti, ATT_HANDLE_VALUE_NOTI);
  660. }
  661. }
  662. }
  663. #endif
  664. void Jump_OTA(void);
  665. /*********************************************************************
  666. * @fn simpleProfileChangeCB
  667. *
  668. * @brief Callback from SimpleBLEProfile indicating a value change
  669. *
  670. * @param paramID - parameter ID of the value that was changed.
  671. * pValue - pointer to data that was changed
  672. * len - length of data
  673. *
  674. * @return none
  675. */
  676. static void simpleProfileChangeCB(uint8_t paramID, uint8_t *pValue, uint16_t len)
  677. {
  678. switch(paramID)
  679. {
  680. case SIMPLEPROFILE_CHAR1:
  681. {
  682. if(download_ble_file != NULL)
  683. {
  684. download_ble_file(pValue, len);
  685. }
  686. break;
  687. }
  688. case SIMPLEPROFILE_CHAR3:
  689. {
  690. if(download_ble_file != NULL)
  691. {
  692. download_ble_file(pValue, len);
  693. }
  694. break;
  695. }
  696. case SIMPLEPROFILE_CHAR4:
  697. {
  698. if(download_ble_data != NULL)
  699. {
  700. download_ble_data(pValue, len);
  701. }
  702. break;
  703. }
  704. default:
  705. // should not reach here!
  706. break;
  707. }
  708. }
  709. #if(DEBUG == DEBUG_UART_BLE)
  710. void debug_ble_tx_data(uint8_t *data, uint16_t length)
  711. {
  712. peripheralChar5Notify(data, length);
  713. }
  714. #endif
  715. void ble_data_send(uint8_t *data, int len)
  716. {
  717. peripheralChar4Notify(data, len);
  718. }
  719. void set_download_ble_data_func(download_ble_data_func func)
  720. {
  721. download_ble_data = func;
  722. }
  723. void set_download_ble_file_func(download_ble_data_func func)
  724. {
  725. download_ble_file = func;
  726. }
  727. void set_ble_connect_evtfunc(ble_connect_func func)
  728. {
  729. ble_connect = func;
  730. }
  731. /*********************************************************************
  732. *********************************************************************/