Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: MQTT target_st_bluenrg
Fork of ble-star-mbed by
BleMasterService.cpp
00001 #include <BleMasterService.h> 00002 #include <cstdint> 00003 #include <cstdio> 00004 #include <cstring> 00005 #include "../inc/BleMasterService.h" 00006 #include "../inc/BleSlaveService.h" 00007 00008 EventQueue eventQ(/* event count */ 128 * EVENTS_EVENT_SIZE); 00009 00010 /* 1 to disable reading after master disconnection */ 00011 uint8_t discFlag = 0; 00012 00013 00014 /* This var defines the central role 00015 * 0 if master 00016 * 1 if slave */ 00017 uint8_t role = 1; 00018 00019 00020 00021 /* Flag to indicate that the characteristic read is completed successful 00022 * 1 successful 00023 * 0 or anything else failed */ 00024 uint8_t readCompleted; 00025 00026 00027 00028 /* Flag to indicate if the device discovery is completed successful 00029 * 1 successful 00030 * 0 or anything else failed */ 00031 uint8_t discoveryCompleted; 00032 00033 00034 /* Flag to indicate if the ch descriptor write is completed successful 00035 * 1 successful 00036 * 0 or anything else failed */ 00037 uint8_t writeDescriptorCompleted = 1; 00038 00039 00040 /* Flag to indicate if the advertising is completed 00041 * 1 completed 00042 * 0 or anything else not completed */ 00043 uint8_t advEnds = 1; 00044 00045 00046 /* Flag to indicate if a change of notification is pending 00047 * 1 pending 00048 * 0 or anything else not pending */ 00049 uint8_t notificationPending = 0; 00050 00051 00052 00053 /* Flag to indicate if the ble stack is busy 00054 * 1 busy 00055 * 0 or anything else not busy */ 00056 uint8_t stackBusy = 0; 00057 00058 00059 00060 /* Connection Parameters struct */ 00061 Gap::ConnectionParams_t connection_parameters = { 00062 0x0032, // min connection interval 00063 0x0087, // max connection interval 00064 0, // slave latency 00065 0x0C80 // connection supervision timeout 00066 }; 00067 00068 00069 00070 /* Header pointer of the DiscoveredCharacteristic list */ 00071 DiscoveredCharacteristicNode * headCharacteristic[MAX_NUM_OF_NODES]; 00072 DiscoveredCharacteristicNode * tmp[MAX_NUM_OF_NODES]; 00073 00074 /* Primary Service UUID expected from Sensor demo peripherals */ 00075 UUID::ShortUUIDBytes_t GENERIC_ACCESS_PROFILE_UUID = 0x1800; 00076 UUID::ShortUUIDBytes_t GENERIC_ATTRIBUTE_PROFILE_UUID = 0x1801; 00077 00078 /* Services UUID */ 00079 UUID::LongUUIDBytes_t HARDWARE_SERVICE_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0xb4,0x9a,0xe1,0x11,0x01,0x00,0x00,0x00,0x00,0x00}; 00080 UUID::LongUUIDBytes_t CONFIG_SERVICE_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0xb4,0x9a,0xe1,0x11,0x0F,0x00,0x00,0x00,0x00,0x00}; 00081 UUID::LongUUIDBytes_t SOFTWARE_SERVICE_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0xb4,0x9a,0xe1,0x11,0x02,0x00,0x00,0x00,0x00,0x00}; 00082 00083 /* Characteristics UUID */ 00084 UUID::LongUUIDBytes_t ENVIRONMENTAL_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x1d,0x00}; 00085 UUID::LongUUIDBytes_t ENVIRONMENTAL_ST_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x14,0x00}; 00086 UUID::LongUUIDBytes_t ACCGYROMAG_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0xE0,0x00}; 00087 UUID::LongUUIDBytes_t SFUSION_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x01,0x00,0x00}; 00088 UUID::LongUUIDBytes_t LED_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x00,0x20}; 00089 UUID::LongUUIDBytes_t WAKEUP_EVENT_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x04,0x00,0x00}; 00090 UUID::LongUUIDBytes_t MIC_EVENT_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x00,0x04}; 00091 UUID::LongUUIDBytes_t PROXIMITY_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x00,0x02}; 00092 UUID::LongUUIDBytes_t LUX_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x00,0x01}; 00093 UUID::LongUUIDBytes_t CONFIG_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x0F,0x00,0x02,0x00,0x00,0x00}; 00094 00095 extern uint8_t wifi_data[256]; 00096 extern uint8_t new_data; 00097 extern uint8_t *data; 00098 extern uint8_t wifi_present; 00099 00100 char print_msg_buff[512]; 00101 00102 uint8_t attribute_value[20]; 00103 uint8_t star_attr_value[256]; 00104 00105 00106 00107 PeripheralDevices_t perDevs; 00108 extern SlaveDevice_t slaveDev; 00109 extern ChangeNotificationQueue notifyQ, *notifyP; 00110 00111 /* Private variable set in discoveryTerminationCallback and used 00112 * in connectionProcess for enabling notification */ 00113 uint8_t customDev_v; 00114 00115 00116 00117 /*----------------------------------------------------------------------------*/ 00118 00119 00120 00121 /* Initialize the struct where all peripheral devices are stored */ 00122 void initProcess(void) { 00123 //printf("\rinitProcess\n");//DEBUG 00124 00125 //Init the lists of characteristics 00126 for(int i=0; i<MAX_NUM_OF_NODES; i++){ 00127 headCharacteristic[i] = NULL; 00128 tmp[i] = NULL; 00129 } 00130 00131 00132 00133 /* The first char read */ 00134 readCompleted = 1; 00135 00136 /* No discovery started */ 00137 discoveryCompleted = 1; 00138 00139 00140 perDevs.discovery_enabled = true; 00141 perDevs.device_found = false; 00142 perDevs.connDevices = 0; 00143 perDevs.discDevices = 0; 00144 perDevs.connDeviceIdx = 0; 00145 perDevs.readDeviceIdx = 0; 00146 00147 for(unsigned i=0;i<MAX_NUM_OF_NODES;i++){ 00148 perDevs.devInfo[i].dev_v = 0; 00149 perDevs.connection_handle[i] = 0; 00150 perDevs.is_connected[i] = false; 00151 perDevs.is_disconnected[i] = true; 00152 perDevs.is_unconnectable[i] = false; 00153 perDevs.gen_access_profile_handle[i].start_h = 0; 00154 perDevs.gen_access_profile_handle[i].end_h = 0; 00155 perDevs.gen_attribute_profile_handle[i].start_h = 0; 00156 perDevs.gen_attribute_profile_handle[i].end_h = 0; 00157 perDevs.hardware_service_handle[i].start_h = 0; 00158 perDevs.hardware_service_handle[i].end_h = 0; 00159 perDevs.software_service_handle[i].start_h = 0; 00160 perDevs.software_service_handle[i].end_h = 0; 00161 perDevs.led_char_read[i] = 0; 00162 perDevs.wup_char_read[i] = 0; 00163 perDevs.mic_char_read[i] = 0; 00164 perDevs.prx_char_read[i] = 0; 00165 perDevs.agm_char_read[i] = 0; 00166 perDevs.sfusion_char_read[i] = 0; 00167 perDevs.wup_event[i] = 0; 00168 perDevs.mic_event[i] = 0; 00169 perDevs.prx_on[i] = 0; 00170 perDevs.agm_on[i] = 0; 00171 perDevs.sfusion_on[i] = 0; 00172 } 00173 00174 perDevs.mic_event_enabled = 0; 00175 perDevs.prx_event_enabled = 0; 00176 perDevs.agm_event_enabled = 0; 00177 perDevs.sfusion_event_enabled = 0; 00178 perDevs.acc_event_enabled = 0; 00179 perDevs.gyr_event_enabled = 0; 00180 perDevs.mag_event_enabled = 0; 00181 perDevs.status = CONN_INIT; 00182 } 00183 /*----------------------------------------------------------------------------*/ 00184 00185 00186 00187 /* Called every 10 seconds to return the current status */ 00188 void checkStatus(){ 00189 if ((perDevs.status != 10) && (perDevs.status != 11) && (perDevs.status != 12) && (perDevs.status != 13) && (perDevs.status != 14) 00190 && (perDevs.status != 15) && (perDevs.status != 16) && (perDevs.status != 17) && (perDevs.status != 18) 00191 && (perDevs.status != 19) && (perDevs.status != 20) && (perDevs.status != 21)){ 00192 printf("\r\nCurrent Status (stat: %d) (read: %s) (write: %s)\n", perDevs.status, (readCompleted == 1 ? "completed" : "pending"),(writeDescriptorCompleted == 1 ? "completed" : "pending")); 00193 } 00194 } 00195 /*----------------------------------------------------------------------------*/ 00196 00197 00198 00199 /* Print out device MAC address to the console*/ 00200 void printMacAddress() 00201 { 00202 Gap::AddressType_t addr_type; 00203 Gap::Address_t address; 00204 BLE::Instance().gap().getAddress(&addr_type, address); 00205 printf("\rBLE CENTRAL MAC ADDRESS: "); 00206 for (int i = 5; i >= 1; i--){ 00207 printf("%02x:", address[i]); 00208 } 00209 printf("%02x\n\n", address[0]); 00210 } 00211 /*----------------------------------------------------------------------------*/ 00212 00213 00214 void connectionProcess(void){ 00215 00216 00217 00218 00219 00220 if ( perDevs.status == CONN_INIT ) { 00221 if ( (perDevs.connDevices < MAX_NUM_OF_NODES) && (perDevs.discovery_enabled) ) { 00222 /* Start discovery of new peripheral nodes and connect them */ 00223 //startDiscovery(); 00224 if (notificationPending == 0) 00225 eventQ.call(startDiscovery); 00226 } 00227 else { 00228 perDevs.status = DEVICE_CONNECTED; 00229 } 00230 00231 }//if 00232 00233 00234 00235 00236 00237 00238 if ( perDevs.status == DEVICE_DISCOVERY_COMPLETE ) { 00239 if ( perDevs.device_found == true ) { 00240 /* Establishing connection with a peripheral device */ 00241 perDevs.status = START_DEVICE_CONNECTION; 00242 eventQ.call(connectPeripheral); 00243 //connectPeripheral(); 00244 }else { 00245 perDevs.status = DEVICE_NOT_FOUND; 00246 } 00247 }//if 00248 00249 00250 00251 00252 00253 00254 // if all devices are connected or no devices are discovered start reading 00255 if ((perDevs.status == DEVICE_CONNECTED) || (perDevs.status == DEVICE_NOT_FOUND) ){ 00256 00257 if (perDevs.device_found == true) { 00258 perDevs.status = DISCOVERABLE_MODE_SET; 00259 perDevs.device_found = false; 00260 } 00261 00262 else { 00263 perDevs.readDeviceIdx = perDevs.connDevices+perDevs.discDevices-1; 00264 perDevs.status = READ_INIT; 00265 } 00266 00267 }//if-main 00268 00269 00270 00271 00272 00273 00274 if (perDevs.status == DISCOVERABLE_MODE_SET) { 00275 /* Search for all services */ 00276 perDevs.status = START_SERVICE_DISCOVERY; 00277 eventQ.call(discoverServices); 00278 }//if 00279 00280 00281 00282 00283 00284 00285 if ( ((perDevs.status == ENABLE_ME1_LED_NOTIFICATIONS) || 00286 (perDevs.status == ENABLE_ME1_WUP_NOTIFICATIONS)) && (writeDescriptorCompleted == 1) ) { 00287 00288 writeDescriptorCompleted =0; 00289 /* Enabling notifications on peripheral node */ 00290 uint8_t i = perDevs.connDeviceIdx; 00291 uint16_t connection_handle = perDevs.connection_handle[i]; 00292 enableNotifications(connection_handle, i, customDev_v, 1); 00293 }//if 00294 00295 00296 00297 00298 00299 00300 00301 if (perDevs.status == NOTIFICATIONS_ENABLED) { 00302 if (!perDevs.is_disconnected[perDevs.connDeviceIdx]) { 00303 perDevs.is_connected[perDevs.connDeviceIdx] = true; 00304 perDevs.connDeviceIdx++; 00305 perDevs.connDevices++; 00306 } 00307 00308 perDevs.readDeviceIdx = perDevs.connDevices-1; 00309 perDevs.status = READ_INIT; 00310 }//if 00311 00312 00313 00314 00315 00316 /* Start reading process */ 00317 eventQ.call(readingProcess); 00318 00319 } 00320 /*----------------------------------------------------------------------------*/ 00321 00322 00323 00324 /* Method called in advertingCallback when a device is found */ 00325 void saveDeviceFound (uint8_t adv_type, BLEProtocol::AddressBytes_t addr, 00326 uint8_t data_length, const uint8_t* data_RSSI, uint8_t pos, uint8_t dev_v, 00327 uint8_t wup_event, uint8_t mic_event, uint8_t prx_event, 00328 uint8_t agm_event, uint8_t sfusion_event){ 00329 00330 perDevs.devInfo[pos].dev_v = dev_v; 00331 perDevs.wup_event[pos] = wup_event; 00332 perDevs.mic_event[pos] = mic_event; 00333 perDevs.prx_event[pos] = prx_event; 00334 perDevs.agm_event[pos] = agm_event; 00335 perDevs.sfusion_event[pos] = sfusion_event; 00336 memcpy(perDevs.devInfo[pos].bdaddr, addr, 6); 00337 } 00338 /*----------------------------------------------------------------------------*/ 00339 00340 00341 00342 00343 /* Function called to connect a peripheral */ 00344 void connectPeripheral(void){ 00345 00346 ble_error_t e1; 00347 BLE& ble = BLE::Instance(); 00348 00349 00350 /* if 1 to enable */ 00351 #if 0 00352 ble_error_t e0 = ble.gap().stopScan(); 00353 if (e0 != BLE_ERROR_NONE){ 00354 printf("\r\nError while stopping scan\n"); 00355 } 00356 #endif 00357 00358 uint8_t index; 00359 index = perDevs.connDeviceIdx; 00360 00361 printf("\r\nClient create connection with peripheral %d at pos %d\n", 00362 perDevs.connDevices+1, index+1); 00363 00364 //Connect as master (0) 00365 role = 0; 00366 00367 00368 e1 = ble.gap().connect(perDevs.devInfo[index].bdaddr, BLEProtocol::AddressType::RANDOM_STATIC, &connection_parameters, NULL); 00369 00370 if (e1 != BLE_ERROR_NONE){ 00371 printf("\r\nError (%d) while connecting per %d (%02x%02x) (stat: %d) (read: %s) (write: %s)\n", e1, index+1, 00372 perDevs.devInfo[index].bdaddr[NODE_ID_B2], perDevs.devInfo[index].bdaddr[NODE_ID_B1], perDevs.status, 00373 (readCompleted == 1 ? "completed" : "pending"),(writeDescriptorCompleted == 1 ? "completed" : "pending")); 00374 00375 00376 perDevs.is_unconnectable[index] = true; 00377 //perDevs.is_unconnectable[index] = false; 00378 00379 perDevs.device_found = false; 00380 perDevs.status = DEVICE_NOT_FOUND; 00381 }//if-error 00382 } 00383 /*----------------------------------------------------------------------------*/ 00384 00385 00386 00387 00388 /* Function called on disconnection event */ 00389 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { 00390 //printf("\r\ndisconnectionCallback (%d)\n", perDevs.status);//DEBUG 00391 BLE& ble = BLE::Instance(); 00392 00393 uint8_t i; 00394 00395 // current handle 00396 uint16_t handle = params->handle; 00397 00398 00399 00400 00401 00402 for (unsigned i=0; i<MAX_NUM_OF_NODES; i++) { 00403 00404 //if-MAIN 00405 if (handle == perDevs.connection_handle[i]){ 00406 00407 //Delete its DCList 00408 deleteDCNList(headCharacteristic[i]); 00409 headCharacteristic[i] = NULL; 00410 tmp[i] = NULL; 00411 00412 if (perDevs.is_disconnected[i] == true){ 00413 perDevs.is_unconnectable[i] = true; 00414 00415 printf("\r\nPeripheral 0x%02x%02x disconnected (%d Ch in DCList)\n", 00416 perDevs.devInfo[i].bdaddr[NODE_ID_B2], perDevs.devInfo[i].bdaddr[NODE_ID_B1], countElements(headCharacteristic[i])); 00417 00418 }else { 00419 perDevs.is_disconnected[i] = true; 00420 perDevs.is_unconnectable[i] = false; 00421 00422 00423 if (perDevs.is_connected[i] == true){ 00424 00425 perDevs.connDevices--; 00426 //disconnected_devices 00427 perDevs.discDevices++; 00428 perDevs.is_connected[i] = false; 00429 } 00430 00431 /* Notify device disconnection to client */ 00432 perDevs.status = READING_DISCONNECTION; 00433 00434 readCharacteristicCallback(nullGattReadCallbackP(perDevs.connection_handle[i])); 00435 00436 00437 notifyMaster(slaveDev.notification_data.data_length, slaveDev.notification_data.attribute_value, 00438 slaveDev.notification_data.attribute_handle); 00439 perDevs.status = CONN_INIT; 00440 00441 00442 printf("\r\nPeripheral 0x%02x%02x disconnected (%d still connected) (%d Ch in DCList)\n", 00443 perDevs.devInfo[i].bdaddr[NODE_ID_B2], perDevs.devInfo[i].bdaddr[NODE_ID_B1], 00444 perDevs.connDevices, countElements(headCharacteristic[i])); 00445 }//if-else 00446 break; 00447 00448 }//if-MAIN 00449 }//for 00450 00451 00452 00453 /* SLAVE ROLE */ 00454 if (handle == slaveDev.conn_handle) { 00455 printf("\r\nMaster disconnected (adv: %d - status %d)\n", ble.gap().getState().advertising, perDevs.status);//DEBUG 00456 00457 /* Disable reading after master disconnection */ 00458 //discFlag = 1; 00459 00460 00461 00462 slaveDev.is_discoverable = true; 00463 slaveDev.is_connected = false; 00464 slaveDev.conn_handle = 0; 00465 slaveDev.star_data_char_notify = 0; 00466 00467 for (i=0; i<MAX_NUM_OF_NODES; i++) { 00468 perDevs.led_char_read[i] = 0; 00469 perDevs.wup_char_read[i] = 0; 00470 perDevs.mic_char_read[i] = 0; 00471 perDevs.prx_char_read[i] = 0; 00472 perDevs.agm_char_read[i] = 0; 00473 perDevs.sfusion_char_read[i] = 0; 00474 perDevs.prx_on[i] = 0; 00475 perDevs.agm_on[i] = 0; 00476 perDevs.sfusion_on[i] = 0; 00477 }//for 00478 00479 perDevs.discovery_enabled = true; 00480 perDevs.status = DISABLE_NOTIFICATIONS; 00481 00482 00483 //setSlaveDiscoverable();//DEBUG_only 00484 00485 }//SLAVE-ROLE 00486 00487 } 00488 /*----------------------------------------------------------------------------*/ 00489 00490 00491 00492 00493 /* Function called on connection */ 00494 void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { 00495 //printf("\r\n----> connectionCallback\n\n");//DEBUG 00496 00497 BLE& ble = BLE::Instance(); 00498 00499 static const size_t ADDR_LEN = 6; 00500 //the current address 00501 BLEProtocol::AddressBytes_t tempAddr; 00502 //fill the address 00503 for(unsigned i=0;i<ADDR_LEN;i++) { 00504 tempAddr[i]=params->peerAddr[i]; 00505 } 00506 00507 // connection handle 00508 uint16_t handle = params ->handle; 00509 00510 //ROLE uint8_t role 00511 // 0 = master 00512 // 1 = slave 00513 00514 uint8_t index = perDevs.connDeviceIdx; 00515 00516 00517 00518 00519 /* MASTER ROLE */ 00520 if (role == 0) { 00521 00522 if (perDevs.is_unconnectable[index] == false) { 00523 perDevs.connection_handle[index] = handle; 00524 perDevs.is_disconnected[index] = false; 00525 00526 printf("\r\nConnected to peripheral: [%02x %02x %02x %02x %02x %02x] (%d/%d - 0x%04x) (role: %s)\n", 00527 tempAddr[5], tempAddr[4], tempAddr[3], tempAddr[2], 00528 tempAddr[1], tempAddr[0], index+1, perDevs.connDevices+1, handle, (role == 1 ? "slave" : "master")); 00529 00530 perDevs.status = DEVICE_CONNECTED; 00531 00532 } else { 00533 perDevs.is_unconnectable[index] = false; 00534 perDevs.device_found = false; 00535 perDevs.status = DEVICE_NOT_FOUND; 00536 } 00537 00538 }//if-MASTER 00539 00540 00541 00542 00543 /* SLAVE ROLE */ 00544 if (role == 1) { 00545 //When connected the adv seams disabled 00546 slaveDev.conn_handle = handle; 00547 slaveDev.is_connected = true; 00548 slaveDev.is_discoverable = false; 00549 00550 00551 printf("\r\nConnected to master: [%02x %02x %02x %02x %02x %02x] (role: %s)\n", 00552 tempAddr[5], tempAddr[4], tempAddr[3], tempAddr[2], 00553 tempAddr[1], tempAddr[0], (role == 1 ? "slave" : "master")); 00554 00555 }//if-SLAVE 00556 00557 00558 role = 1; 00559 00560 } 00561 /*----------------------------------------------------------------------------*/ 00562 00563 00564 00565 00566 /* Service discovery */ 00567 void discoverServices(void){ 00568 00569 BLE& ble = BLE::Instance(); 00570 uint8_t index = perDevs.connDeviceIdx; 00571 uint16_t conn_handle = perDevs.connection_handle[index]; 00572 ble_error_t e0; 00573 00574 printf("\r\nDiscovering services for peripheral %d (0x%04x)\n", index+1, conn_handle); 00575 00576 if (perDevs.is_disconnected[index]){ 00577 printf("\r\nPeripheral %d (0x%04x) disconnected\n", index+1, conn_handle); 00578 eventQ.call(setNewStatus); 00579 00580 }else { 00581 ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback); 00582 e0 = ble.gattClient().launchServiceDiscovery(conn_handle, serviceDiscoveryCallback, 00583 characteristicDiscoveryCallback); 00584 if (e0 != BLE_ERROR_NONE){ 00585 printf("\r\nError while discovering primary services (error: %d)\n", e0); 00586 eventQ.call(setNewStatus); 00587 } 00588 }//if-else 00589 00590 } 00591 /*----------------------------------------------------------------------------*/ 00592 00593 00594 00595 00596 void onStopScan(Gap::TimeoutSource_t t){ 00597 //printf("\r\nScanning ends\n");//DEBUG 00598 00599 00600 if (perDevs.status == DEVICE_FOUND) { 00601 perDevs.device_found = true; 00602 } 00603 else { 00604 perDevs.device_found = false; 00605 } 00606 perDevs.status = DEVICE_DISCOVERY_COMPLETE; 00607 printf("\r\nDevice Discovery Complete (%d)\n", perDevs.status); 00608 00609 discoveryCompleted = 1; 00610 00611 } 00612 /*----------------------------------------------------------------------------*/ 00613 00614 00615 00616 void startDiscovery(void) { 00617 //printf("\r\nstartDiscovery - status: %d\n", perDevs.status);//DEBUG 00618 00619 00620 00621 00622 BLE &ble = BLE::Instance(); 00623 ble_error_t e1; 00624 00625 00626 //if-MAIN 00627 if ((perDevs.status == CONN_INIT) && (discoveryCompleted == 1) && (advEnds == 1)){ 00628 00629 discoveryCompleted = 0; 00630 00631 /* if 1 to enable 00632 * if 0 default because of the adv timer setup */ 00633 #if 0 00634 if ((slaveDev.is_connected == false) && (slaveDev.is_discoverable == true)){ 00635 //printf("\r\nslaveDev.is_discoverable == true\n");//DEBUG 00636 00637 ble_error_t e0; 00638 e0= ble.gap().stopAdvertising(); 00639 if ( e0 == BLE_ERROR_NONE ) { 00640 }else { 00641 printf("\r\nERROR stopping advertising\n");//DEBUG 00642 } 00643 slaveDev.is_discoverable = false; 00644 }//stopAdv 00645 #endif 00646 00647 /* MASTER ROLE */ 00648 perDevs.status = START_DEVICE_DISCOVERY; 00649 printf("\r\nStart Device Discovery (%d)\n", perDevs.status); 00650 00651 e1 = ble.gap().startScan(advertisementCallback); 00652 00653 if ( e1 == BLE_ERROR_NONE ) { 00654 //printf("\r\nScan started correctly\n");//DEBUG 00655 }else { 00656 //perDevs.status = DEVICE_DISCOVERY_COMPLETE; 00657 //discoveryCompleted = 1; 00658 00659 /* Set the same timeout */ 00660 eventQ.call_in(3000, scanTimeOut); 00661 } 00662 00663 }//if-MAIN 00664 } 00665 /*----------------------------------------------------------------------------*/ 00666 00667 00668 void scanTimeOut(void){ 00669 if (perDevs.status == DEVICE_FOUND) { 00670 perDevs.device_found = true; 00671 } 00672 else { 00673 perDevs.device_found = false; 00674 } 00675 perDevs.status = DEVICE_DISCOVERY_COMPLETE; 00676 printf("\r\nDevice Discovery Complete (%d)\n", perDevs.status); 00677 00678 discoveryCompleted = 1; 00679 } 00680 /*----------------------------------------------------------------------------*/ 00681 00682 00683 00684 00685 /* Function called as response of advertising */ 00686 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) { //defined in Gap.h 00687 00688 static const size_t ADDR_LEN = 6; 00689 //the current address 00690 BLEProtocol::AddressBytes_t tempAddr; 00691 //fill the address 00692 for(unsigned i=0;i<ADDR_LEN;i++) { 00693 tempAddr[i]=params->peerAddr[i]; 00694 } 00695 00696 00697 uint8_t alreadyIn = 1; 00698 uint8_t index, i; 00699 uint8_t found_zero_pos = 0; 00700 BLEProtocol::AddressBytes_t zeroAddr; 00701 memset(zeroAddr, 0, 6); 00702 00703 00704 if (perDevs.status != DEVICE_FOUND) { 00705 00706 //initial per data 00707 uint8_t peripheral_v; 00708 uint8_t wup_event = 0; 00709 uint8_t mic_event = 0; 00710 uint8_t prx_event = 0; 00711 uint8_t agm_event = 0; 00712 uint8_t sfusion_event = 0; 00713 00714 uint8_t peripheral_name_len = params->advertisingData[3]; 00715 const uint8_t * manuf_data = params->advertisingData+4+peripheral_name_len; 00716 uint32_t features = 0; 00717 00718 if ((manuf_data[1] == MANUF_SPECIFIC_TYPE) && ((manuf_data[3] == STM32_NUCLEO) 00719 || (manuf_data[3] == SENSOR_TILE) || (manuf_data[3] == BLUE_COIN)) && (peripheral_name_len == 8)) { 00720 00721 features = (manuf_data[4]<<24) | (manuf_data[5]<<16) | (manuf_data[6]<<8) | manuf_data[7]; 00722 wup_event = (features & FEATURE_MASK_WAKEUP_EVENTS) >> WUP_POS; 00723 mic_event = (features & FEATURE_MASK_MIC) >> MIC_POS; 00724 prx_event = (features & FEATURE_MASK_PROX) >> PRX_POS; 00725 agm_event = (features & FEATURE_MASK_ACC) >> ACC_POS; 00726 sfusion_event = (features & FEATURE_MASK_SENSORFUSION) >> SFUS_POS; 00727 00728 00729 /* Switch the kind of node */ 00730 if (mic_event) { 00731 peripheral_v = NODE_AM1; 00732 00733 }else if (prx_event) { 00734 peripheral_v = NODE_FL1; 00735 00736 }else { 00737 peripheral_v = NODE_ME1; 00738 } 00739 00740 00741 for (i=0; i<MAX_NUM_OF_NODES; i++) { 00742 if (perDevs.is_disconnected[i]) { 00743 if (memcmp(zeroAddr, perDevs.devInfo[i].bdaddr, 6)==0) { 00744 if (!found_zero_pos) { 00745 index = i; 00746 perDevs.connDeviceIdx = i; 00747 found_zero_pos = 1; 00748 alreadyIn = 0; 00749 } 00750 00751 }else if (memcmp(tempAddr, perDevs.devInfo[i].bdaddr, 6)==0) { 00752 index = i; 00753 perDevs.connDeviceIdx = i; 00754 alreadyIn = 0; 00755 perDevs.discDevices--; 00756 break; 00757 00758 }else { 00759 if (!found_zero_pos) { 00760 index = i; 00761 perDevs.connDeviceIdx = i; 00762 alreadyIn = 0; 00763 } 00764 } 00765 }//perDevs.is_disconnected[i] 00766 }//for 00767 00768 if ((!alreadyIn) && (perDevs.connDevices < MAX_NUM_OF_NODES)) { 00769 00770 /* Save the found peripheral device in the struct containing all the found peripheral devices */ 00771 saveDeviceFound(params->type, tempAddr, params->advertisingDataLen, params->advertisingData, index, 00772 peripheral_v, wup_event, mic_event, prx_event, agm_event, sfusion_event); 00773 00774 perDevs.status = DEVICE_FOUND; 00775 00776 switch(peripheral_v){ 00777 case 0x01: /* MOTENV1 */ 00778 printf("\r\nPeripheral (MOTENV) %d inserted [%02x %02x %02x %02x %02x %02x] \n", perDevs.connDevices+1, 00779 tempAddr[5], tempAddr[4], tempAddr[3], tempAddr[2], tempAddr[1], tempAddr[0]); 00780 break; 00781 00782 case 0x02: /* FLIGHT1 */ 00783 printf("\r\nPeripheral (FLIGHT) %d inserted [%02x %02x %02x %02x %02x %02x] \n", perDevs.connDevices+1, 00784 tempAddr[5], tempAddr[4], tempAddr[3], tempAddr[2], tempAddr[1], tempAddr[0]); 00785 break; 00786 00787 case 0x03: /* ALLMEMS1 */ 00788 printf("\r\nPeripheral (ALLMEMS) %d inserted [%02x %02x %02x %02x %02x %02x] \n", perDevs.connDevices+1, 00789 tempAddr[5], tempAddr[4], tempAddr[3], tempAddr[2], tempAddr[1], tempAddr[0]); 00790 break; 00791 } 00792 00793 }//IF-alreadyIn 00794 }//IF-ST-hw 00795 }//IF-!DEVICE_FOUND 00796 } 00797 /*----------------------------------------------------------------------------*/ 00798 00799 00800 00801 00802 /* Function called after the discovery of a service */ 00803 void serviceDiscoveryCallback(const DiscoveredService *service) { 00804 //printf("\r\n\n----> serviceDiscoveryCallback\n\n");//DEBUG 00805 printf("\r\n"); 00806 00807 00808 //printf("\r\nstatus: SERVICE_DISCOVERED\n\n"); 00809 perDevs.status = SERVICE_DISCOVERED; 00810 00811 //length of the long uuid 00812 unsigned uuidLength = UUID::LENGTH_OF_LONG_UUID; //16 00813 //pointer to the current service uuid 00814 const uint8_t * pointerToUUID = service->getUUID().getBaseUUID(); 00815 //temp long array 00816 UUID::LongUUIDBytes_t tempUUID; 00817 //temp short array 00818 UUID::ShortUUIDBytes_t shortTempUUID; 00819 00820 00821 /* Switch the known services */ 00822 //create the temp array 00823 for (unsigned i=0;i<uuidLength;i++){ 00824 tempUUID[i]=pointerToUUID[i]; 00825 } 00826 00827 00828 00829 /* Switch the known services */ 00830 // HARDWARE_SERVICE_UUID 00831 if ((memcmp(tempUUID, HARDWARE_SERVICE_UUID, uuidLength)) == 0){ 00832 printf("\r\nHARDWARE service: [ "); 00833 00834 for (unsigned i = 0; i < uuidLength; i++) { 00835 printf("%02x ", tempUUID[i]); 00836 } 00837 00838 //handles 00839 perDevs.hardware_service_handle[perDevs.connDeviceIdx].start_h = service->getStartHandle(); 00840 perDevs.hardware_service_handle[perDevs.connDeviceIdx].end_h = service->getEndHandle(); 00841 00842 //status HW 00843 perDevs.status = START_HARDWARE_SERV_CHARS_DISCOVERY; 00844 //prinft("\r\nstatus = START_HARDWARE_SERV_CHARS_DISCOVERY\n"); 00845 00846 00847 00848 00849 00850 00851 // CONFIG_SERVICE_UUID 00852 }else if ((memcmp(tempUUID, CONFIG_SERVICE_UUID, uuidLength)) == 0){ 00853 printf("\r\nCFG service: [ "); 00854 00855 for (unsigned i = 0; i < uuidLength; i++) { 00856 printf("%02x ", tempUUID[i]); 00857 } 00858 00859 //handles 00860 perDevs.configuration_service_handle[perDevs.connDeviceIdx].start_h = service->getStartHandle(); 00861 perDevs.configuration_service_handle[perDevs.connDeviceIdx].end_h = service->getEndHandle(); 00862 00863 //status CFG 00864 perDevs.status = START_CONFIGURATION_SERV_CHARS_DISCOVERY; 00865 //prinft("\r\nstatus = START_CONFIGURATION_SERV_CHARS_DISCOVERY\n"); 00866 00867 00868 00869 00870 00871 // SOFTWARE_SERVICE_UUID 00872 }else if ((memcmp(tempUUID, SOFTWARE_SERVICE_UUID, uuidLength)) == 0){ 00873 printf("\r\nSOFTWARE service: [ "); 00874 00875 for (unsigned i = 0; i < uuidLength; i++) { 00876 printf("%02x ", tempUUID[i]); 00877 } 00878 00879 //handles 00880 perDevs.software_service_handle[perDevs.connDeviceIdx].start_h = service->getStartHandle(); 00881 perDevs.software_service_handle[perDevs.connDeviceIdx].end_h = service->getEndHandle(); 00882 00883 //status SW 00884 perDevs.status = START_SOFTWARE_SERV_CHARS_DISCOVERY; 00885 //prinft("\r\nstatus = START_SOFTWARE_SERV_CHARS_DISCOVERY\n"); 00886 00887 00888 00889 00890 00891 // Short UUID services 00892 } else if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { 00893 //get the short uuid 00894 shortTempUUID = service->getUUID().getShortUUID(); 00895 // printf("\r\n\n\nS UUID [ %x ", service->getUUID().getShortUUID());//DEBUG 00896 00897 00898 00899 00900 00901 00902 00903 // GENERIC_ACCESS_PROFILE_UUID 00904 if (shortTempUUID == GENERIC_ACCESS_PROFILE_UUID) { 00905 printf("\r\nGeneric Access Profile (GAP): [ %x ", shortTempUUID); 00906 00907 //handles 00908 perDevs.gen_access_profile_handle[perDevs.connDeviceIdx].start_h = service->getStartHandle(); 00909 perDevs.gen_access_profile_handle[perDevs.connDeviceIdx].end_h = service->getEndHandle(); 00910 00911 00912 00913 00914 00915 00916 00917 // GENERIC_ATTRIBUTE_PROFILE_UUID 00918 } else if (shortTempUUID == GENERIC_ATTRIBUTE_PROFILE_UUID) { 00919 printf("\r\nGeneric Attribute Profile (GATT): [ %x ", shortTempUUID); 00920 00921 //handles 00922 perDevs.gen_attribute_profile_handle[perDevs.connDeviceIdx].start_h = service->getStartHandle(); 00923 perDevs.gen_attribute_profile_handle[perDevs.connDeviceIdx].end_h = service->getEndHandle(); 00924 00925 00926 00927 00928 00929 00930 // UNKNOWN short service 00931 } else { 00932 printf("\r\nUNKNOWN service: [ %x", shortTempUUID); 00933 } 00934 00935 00936 00937 00938 00939 00940 // UNKNOWN long service 00941 } else { 00942 printf("\r\nUNKNOWN service: [ "); 00943 00944 for (unsigned i = 0; i < uuidLength; i++) { 00945 printf("%02x ", tempUUID[i]); 00946 } 00947 } 00948 00949 00950 00951 00952 printf("]"); 00953 printf("\r\n\n"); 00954 } 00955 /*----------------------------------------------------------------------------*/ 00956 00957 00958 00959 00960 00961 /* Function called after the discovery of a characteristic */ 00962 void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) { 00963 //printf("\r----> characteristicDiscoveryCallback\n\n");//DEBUG 00964 00965 //current characteristic handles 00966 uint16_t declHandle = characteristicP->getDeclHandle(); //identify chars 00967 uint16_t valueHandle = characteristicP->getValueHandle(); 00968 00969 00970 //-----> index of current device 00971 uint8_t idx = perDevs.connDeviceIdx; 00972 00973 //Prepend the DiscoveredCharacteristic into the list 00974 headCharacteristic[idx] = prependDCNode(headCharacteristic[idx], characteristicP); 00975 00976 00977 00978 //length of the long uuid 00979 unsigned uuidLength = UUID::LENGTH_OF_LONG_UUID; //16 00980 //pointer to the current service uuid 00981 const uint8_t * pointerToUUID = characteristicP->getUUID().getBaseUUID(); 00982 //temp array 00983 UUID::LongUUIDBytes_t tempUUID; 00984 00985 //create the temp uuid array 00986 for (unsigned i=0;i<uuidLength;i++){ 00987 tempUUID[i]=pointerToUUID[i]; 00988 } 00989 00990 00991 00992 00993 00994 00995 00996 /* switch the known characteristic */ 00997 // ENVIRONMENTAL_CHAR_UUID 00998 // ENVIRONMENTAL_ST_CHAR_UUID 00999 if (((memcmp(tempUUID, ENVIRONMENTAL_CHAR_UUID, uuidLength)) == 0) || 01000 ((memcmp(tempUUID, ENVIRONMENTAL_ST_CHAR_UUID, uuidLength)) == 0)){ 01001 01002 //HW 01003 perDevs.status = HARDWARE_SERV_CHARS_DISCOVERED; 01004 01005 // Set the handle 01006 perDevs.environmental_char_handle[idx] = declHandle; 01007 01008 printf("\r\n - Enviromental Ch: [ "); 01009 01010 for (unsigned i = 0; i < uuidLength; i++) { 01011 printf("%02x ", pointerToUUID[i]); 01012 } 01013 01014 01015 01016 01017 01018 01019 01020 // ACCGYROMAG_CHAR_UUID 01021 }else if ((memcmp(tempUUID, ACCGYROMAG_CHAR_UUID, uuidLength)) == 0){ 01022 01023 //HW 01024 perDevs.status = HARDWARE_SERV_CHARS_DISCOVERED; 01025 // Set the handle 01026 perDevs.agm_char_handle[idx] = declHandle; 01027 01028 01029 printf("\r\n - Acc-Gyro-Mag Ch: [ "); 01030 01031 for (unsigned i = 0; i < uuidLength; i++) { 01032 printf("%02x ", pointerToUUID[i]); 01033 } 01034 01035 01036 01037 01038 01039 01040 01041 // SFUSION_CHAR_UUID 01042 }else if ((memcmp(tempUUID, SFUSION_CHAR_UUID, uuidLength)) == 0){ 01043 01044 //SW 01045 perDevs.status = SOFTWARE_SERV_CHARS_DISCOVERED; 01046 01047 //Set the handle 01048 perDevs.sfusion_char_handle[idx] = declHandle; 01049 //Init value 01050 perDevs.sfusion_char_read[idx] = 0; 01051 perDevs.sfusion_on[idx] = 0; 01052 01053 01054 01055 printf("\r\n - SFusion Ch: [ "); 01056 01057 for (unsigned i = 0; i < uuidLength; i++) { 01058 printf("%02x ", pointerToUUID[i]); 01059 } 01060 01061 01062 01063 01064 01065 01066 // LED_CHAR_UUID 01067 }else if ((memcmp(tempUUID, LED_CHAR_UUID, uuidLength)) == 0){ 01068 01069 //HW 01070 perDevs.status = HARDWARE_SERV_CHARS_DISCOVERED; 01071 01072 // Set the handle 01073 perDevs.led_char_handle[idx] = declHandle; 01074 // Init value 01075 perDevs.led_char_read[idx] = 0; 01076 printf("\r\n - Led Ch: [ "); 01077 01078 for (unsigned i = 0; i < uuidLength; i++) { 01079 printf("%02x ", pointerToUUID[i]); 01080 } 01081 01082 01083 01084 01085 01086 // WAKEUP_EVENT_CHAR_UUID 01087 }else if ((memcmp(tempUUID, WAKEUP_EVENT_CHAR_UUID, uuidLength)) == 0){ 01088 01089 //HW 01090 perDevs.status = HARDWARE_SERV_CHARS_DISCOVERED; 01091 01092 // Set the handle 01093 perDevs.wup_char_handle[idx] = declHandle; 01094 // Init value 01095 perDevs.wup_char_read[idx] = 0; 01096 printf("\r\n - Wakeup Event Ch: [ "); 01097 01098 for (unsigned i = 0; i < uuidLength; i++) { 01099 printf("%02x ", pointerToUUID[i]); 01100 } 01101 01102 01103 01104 01105 01106 01107 // MIC_EVENT_CHAR_UUID 01108 }else if ((memcmp(tempUUID, MIC_EVENT_CHAR_UUID, uuidLength)) == 0){ 01109 01110 //HW 01111 perDevs.status = HARDWARE_SERV_CHARS_DISCOVERED; 01112 01113 // Set the handle 01114 perDevs.mic_char_handle[idx] = declHandle; 01115 // Init value 01116 perDevs.mic_char_read[idx] = 0; 01117 printf("\r\n - Mic Event Ch: [ "); 01118 01119 for (unsigned i = 0; i < uuidLength; i++) { 01120 printf("%02x ", pointerToUUID[i]); 01121 } 01122 01123 01124 01125 01126 01127 // PROXIMITY_CHAR_UUID 01128 }else if ((memcmp(tempUUID, PROXIMITY_CHAR_UUID, uuidLength)) == 0){ 01129 01130 //HW 01131 perDevs.status = HARDWARE_SERV_CHARS_DISCOVERED; 01132 01133 // Set the handle 01134 perDevs.prx_char_handle[idx] = declHandle; 01135 // Init value 01136 perDevs.prx_char_read[idx] = 0; 01137 perDevs.prx_on[idx] = 0; 01138 printf("\r\n - Proximity Ch: [ "); 01139 01140 for (unsigned i = 0; i < uuidLength; i++) { 01141 printf("%02x ", pointerToUUID[i]); 01142 } 01143 01144 01145 01146 01147 01148 01149 // LUX_CHAR_UUID 01150 }else if ((memcmp(tempUUID, LUX_CHAR_UUID, uuidLength)) == 0){ 01151 01152 //HW 01153 perDevs.status = HARDWARE_SERV_CHARS_DISCOVERED; 01154 01155 // Set the handle 01156 perDevs.lux_char_handle[idx] = declHandle; 01157 01158 01159 printf("\r\n - Lux Ch: [ "); 01160 01161 for (unsigned i = 0; i < uuidLength; i++) { 01162 printf("%02x ", pointerToUUID[i]); 01163 } 01164 01165 01166 01167 01168 01169 01170 // CONFIG_CHAR_UUID 01171 }else if ((memcmp(tempUUID, CONFIG_CHAR_UUID, uuidLength)) == 0){ 01172 01173 //CFG 01174 perDevs.status = CONFIGURATION_SERV_CHARS_DISCOVERED; 01175 01176 01177 // Set the handle 01178 perDevs.cfg_char_handle[idx] = declHandle; 01179 01180 printf("\r\n - Config Ch: [ "); 01181 01182 for (unsigned i = 0; i < uuidLength; i++) { 01183 printf("%02x ", pointerToUUID[i]); 01184 } 01185 01186 01187 01188 01189 01190 // UNKNOWN 01191 }else { 01192 01193 printf("\r\n - Unknown Ch: [ "); 01194 01195 for (unsigned i = 0; i < uuidLength; i++) { 01196 printf("%02x ", pointerToUUID[i]); 01197 } 01198 } 01199 01200 01201 01202 01203 printf("] "); 01204 printf("(declH 0x%04x), r: %x\n", declHandle, (uint8_t)characteristicP->getProperties().read()); 01205 } 01206 /*----------------------------------------------------------------------------*/ 01207 01208 01209 01210 /* Function called when discovery is terminated */ 01211 void discoveryTerminationCallback(Gap::Handle_t connectionHandle) { 01212 //printf("\r----> discoveryTerminationCallback\n\n");//DEBUG 01213 01214 uint8_t * pointerToCustomDev_v; 01215 pointerToCustomDev_v = &customDev_v; 01216 01217 uint8_t idx = perDevs.connDeviceIdx; //idx 01218 01219 printf("\r\n\n%d characteristics discovered and added into the DCList \n", countElements(headCharacteristic[idx])); 01220 printf("\r\nTerminated SERVICE DISCOVERY for Handle 0x%04x\n\n", connectionHandle); 01221 01222 01223 01224 01225 ////Enable notifications after the discovery of the configuration characteristics 01226 ////------------ 01227 if (!perDevs.is_disconnected[perDevs.connDeviceIdx]) { 01228 *pointerToCustomDev_v = perDevs.devInfo[perDevs.connDeviceIdx].dev_v; 01229 01230 if (perDevs.devInfo[perDevs.connDeviceIdx].dev_v == NODE_ME1) { 01231 perDevs.status = ENABLE_ME1_LED_NOTIFICATIONS; 01232 01233 }else if (perDevs.devInfo[perDevs.connDeviceIdx].dev_v == NODE_AM1) { 01234 perDevs.status = NOTIFICATIONS_ENABLED; 01235 01236 }else if (perDevs.devInfo[perDevs.connDeviceIdx].dev_v == NODE_FL1) { 01237 perDevs.status = NOTIFICATIONS_ENABLED; 01238 } 01239 } else { 01240 perDevs.status = NOTIFICATIONS_ENABLED; 01241 } 01242 01243 01244 ////------------ 01245 01246 01247 } 01248 /*----------------------------------------------------------------------------*/ 01249 01250 01251 /* Method called when there is a notification from the sever */ 01252 void onNotificationCallback(const GattHVXCallbackParams* event){ 01253 //printf("\r\nonNotificationCallback\n");//DEBUG 01254 01255 /* GATT Notification params */ 01256 uint16_t conn_handle = event->connHandle; 01257 uint16_t attr_handle = event->handle; 01258 uint8_t attr_len = event->len; 01259 uint8_t *attr_value = (uint8_t *)event->data; 01260 01261 01262 int32_t tmp = 0; 01263 uint8_t tmp_data[256]; 01264 uint8_t notify = 0; 01265 tBDAddr devAddr; 01266 uint8_t index; 01267 uint16_t slave_attr_handle; 01268 static uint8_t wupevt_value = 0; 01269 01270 /* Retrieving the peripheral device index and address from the connection handle */ 01271 getDeviceFromConnHandle(conn_handle, &index, devAddr); 01272 slave_attr_handle = slaveDev.star_data_char_handle; 01273 01274 01275 01276 /* Build buffer in JSON format */ 01277 if (attr_handle == perDevs.wup_char_handle[index]+1) { 01278 01279 /** 01280 * The motion is detected when a WakeUp event notification is received. 01281 * The received data is composed by 2 bytes for the tstamp + 2 bytes 01282 * for the value. Since we transmit only information about the detected 01283 * motion, we don't care of the last 2 bytes. 01284 */ 01285 if (attr_len != TSTAMP_LEN+2) 01286 printf("\r\n(NC)WUP Warning: received data length is %d (while expecting %d)\n", attr_len, (TSTAMP_LEN+2)); 01287 01288 wupevt_value = !wupevt_value; 01289 tmp = wupevt_value; 01290 sprintf((char *)wifi_data, "\"WUpEvt_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); 01291 notify = 1; 01292 01293 /* 01294 * Modify the attribute value according to the following format: 01295 * Timestamp | Node ID | WakeUp Type ID | 01296 * 2 bytes | 2 bytes | 1 byte | 01297 */ 01298 Create_New_Attr_Value(attr_value, devAddr, WUP_TYPE_ID, NULL, WUP_DATA_LEN); 01299 01300 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { 01301 perDevs.status = ALL_DATA_READ; 01302 01303 if ((stackBusy == 0) && (writeDescriptorCompleted ==1)){ 01304 notifyMaster(ATTR_HEAD_LEN+WUP_DATA_LEN, star_attr_value, slave_attr_handle); 01305 }else { 01306 return; 01307 } 01308 01309 } 01310 01311 01312 } else if (attr_handle == perDevs.mic_char_handle[index]+1) { 01313 01314 /* The level in dB (the mic level is detected when a mic event notification is received) */ 01315 /* The Sensor Tile board has only Mic1 so it sends 3 bytes */ 01316 if ((attr_len != TSTAMP_LEN+(2*MIC_DATA_LEN)) && (attr_len != TSTAMP_LEN+MIC_DATA_LEN)) 01317 printf("\r\n(NC)MIC Warning: received data length is %d (while expecting %d or %d)\n", attr_len, (TSTAMP_LEN+MIC_DATA_LEN), (TSTAMP_LEN+(2*MIC_DATA_LEN))); 01318 01319 tmp = attr_value[2]; 01320 sprintf((char *)wifi_data, "\"Mic1_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); 01321 /* We do not send the audio level from Mic2 anyway */ 01322 //tmp = attr_value[3]; 01323 //sprintf((char *)tmp_data, ",\"Mic2_0x%02x%02x\":%d", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); 01324 //strcat((char *)wifi_data, (char *)tmp_data); 01325 notify = 1; 01326 01327 /* 01328 * Modify the attribute value according to the following format: 01329 * Timestamp | Node ID | MIC Event Type ID | value | 01330 * 2 bytes | 2 bytes | 1 byte | 1 byte | 01331 */ 01332 Create_New_Attr_Value(attr_value, devAddr, MICLEVEL_TYPE_ID, attr_value+TSTAMP_LEN, MIC_DATA_LEN); 01333 01334 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { 01335 perDevs.status = ALL_DATA_READ; 01336 if ((stackBusy == 0) && (writeDescriptorCompleted ==1)){ 01337 notifyMaster(ATTR_HEAD_LEN+MIC_DATA_LEN, star_attr_value, slave_attr_handle); 01338 }else { 01339 return; 01340 } 01341 } 01342 01343 01344 } else if (attr_handle == perDevs.prx_char_handle[index]+1) { 01345 /* the distance value (in mm) */ 01346 if (attr_len != TSTAMP_LEN+PRX_DATA_LEN) 01347 printf("\r\n(NC)PRX Warning: received data length is %d (while expecting %d)\n", attr_len, (TSTAMP_LEN+PRX_DATA_LEN)); 01348 01349 tmp = (attr_value[3]<<8) | attr_value[2]; 01350 sprintf((char *)wifi_data, "\"PRX_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); 01351 notify = 1; 01352 01353 /* 01354 * Modify the attribute value according to the following format: 01355 * Timestamp | Node ID | Proximity Type ID | value | 01356 * 2 bytes | 2 bytes | 1 byte | 2 bytes | 01357 */ 01358 Create_New_Attr_Value(attr_value, devAddr, PRX_TYPE_ID, attr_value+TSTAMP_LEN, PRX_DATA_LEN); /* Timestamp, Node ID, Proximity Type ID, data, len */ 01359 01360 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { 01361 perDevs.status = ALL_DATA_READ; 01362 if ((stackBusy == 0) && (writeDescriptorCompleted ==1)){ 01363 notifyMaster(ATTR_HEAD_LEN+PRX_DATA_LEN, star_attr_value, slave_attr_handle); 01364 }else { 01365 return; 01366 } 01367 } 01368 01369 01370 } else if (attr_handle == perDevs.agm_char_handle[index]+1) { 01371 uint8_t type_id; 01372 uint8_t data_len; 01373 uint8_t value_offset; 01374 01375 /* Acc values in mg, Gyro values in dps, Mag values in mGa */ 01376 if (attr_len != TSTAMP_LEN+MEMS_DATA_LEN) 01377 printf("\r\n(NC)AGM Warning: received data length is %d (while expecting %d)\n", attr_len, (TSTAMP_LEN+MEMS_DATA_LEN)); 01378 01379 if (perDevs.acc_event_enabled) { 01380 Build_MEMS_Packet(attr_value+2, "Acc", devAddr, INT_VALUE); 01381 type_id = ACC_TYPE_ID; 01382 data_len = ACC_DATA_LEN; 01383 value_offset = TSTAMP_LEN; 01384 01385 } else if (perDevs.gyr_event_enabled) { 01386 Build_MEMS_Packet(attr_value+8, "Gyr", devAddr, FLOAT_VALUE); 01387 type_id = GYR_TYPE_ID; 01388 data_len = GYR_DATA_LEN; 01389 value_offset = TSTAMP_LEN+ACC_DATA_LEN; 01390 01391 } else if (perDevs.mag_event_enabled) { 01392 Build_MEMS_Packet(attr_value+14, "Mag", devAddr, INT_VALUE); 01393 type_id = MAG_TYPE_ID; 01394 data_len = MAG_DATA_LEN; 01395 value_offset = TSTAMP_LEN+ACC_DATA_LEN+GYR_DATA_LEN; 01396 } 01397 notify = 1; 01398 01399 /* 01400 * Modify the attribute value according to the following format: 01401 * Timestamp | Node ID | Acc/Gyro/Mag Type ID | value | 01402 * 2 bytes | 2 bytes | 1 byte | 6 bytes | 01403 */ 01404 Create_New_Attr_Value(attr_value, devAddr, type_id, attr_value+value_offset, data_len); 01405 01406 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && (perDevs.agm_on[index])) { 01407 perDevs.status = NOTIFICATIONS_DATA_READ; 01408 if ((stackBusy == 0) && (writeDescriptorCompleted ==1)){ 01409 notifyMaster(ATTR_HEAD_LEN+data_len, star_attr_value, slave_attr_handle); 01410 }else { 01411 return; 01412 } 01413 01414 } else { 01415 perDevs.status = ALL_DATA_READ; 01416 } 01417 01418 01419 01420 } else if (attr_handle == perDevs.sfusion_char_handle[index]+1) { 01421 01422 /* Quaternion values */ 01423 tmp = (int8_t)attr_value[3]<<8 | attr_value[2]; 01424 sprintf((char *)wifi_data, "\"Q1_0x%02x%02x\":%s0.%.4d; ", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], (tmp<0 ? "-" : ""), (tmp<0 ? -tmp : tmp)); 01425 tmp = (int8_t)attr_value[5]<<8 | attr_value[4]; 01426 sprintf((char *)tmp_data, "\"Q2_0x%02x%02x\":%s0.%.4d; ", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], (tmp<0 ? "-" : ""), (tmp<0 ? -tmp : tmp)); 01427 strcat((char *)wifi_data, (char *)tmp_data); 01428 tmp = (int8_t)attr_value[7]<<8 | attr_value[6]; 01429 sprintf((char *)tmp_data, "\"Q3_0x%02x%02x\":%s0.%.4d; ", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], (tmp<0 ? "-" : ""), (tmp<0 ? -tmp : tmp)); 01430 strcat((char *)wifi_data, (char *)tmp_data); 01431 notify = 1; 01432 01433 /* 01434 * Modify the attribute value according to the following format: 01435 * Timestamp | Node ID | SFusion Type ID | value | 01436 * 2 bytes | 2 bytes | 1 byte | 6 bytes | 01437 */ 01438 Create_New_Attr_Value(attr_value, devAddr, SFUSION_TYPE_ID, attr_value+TSTAMP_LEN, SFUSION_DATA_LEN); 01439 01440 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && (perDevs.sfusion_on[index])) { 01441 perDevs.status = NOTIFICATIONS_DATA_READ; 01442 if ((stackBusy == 0) && (writeDescriptorCompleted ==1)){ 01443 notifyMaster(ATTR_HEAD_LEN+SFUSION_DATA_LEN, star_attr_value, slave_attr_handle); 01444 }else { 01445 return; 01446 } 01447 perDevs.sfusion_char_read[index] = 1; 01448 01449 } else { 01450 perDevs.status = ALL_DATA_READ; 01451 } 01452 } else if (attr_handle == perDevs.environmental_char_handle[index]+1) { 01453 /* P value in mBar, H value in percentage, T2 and T1 values in Celtius degree */ 01454 if (attr_len != TSTAMP_LEN+ENV_DATA_LEN) 01455 printf("\r\n(NC)SFUSION Warning: received data length is %d (while expecting %d)\n", attr_len, (TSTAMP_LEN+ENV_DATA_LEN)); 01456 01457 tmp = (attr_value[5]<<24) | (attr_value[4]<<16) | (attr_value[3]<<8) | attr_value[2]; 01458 sprintf((char *)wifi_data, "\"Pressure_0x%02x%02x\":%ld.%ld,", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp/100, tmp%100); 01459 tmp = (attr_value[7]<<8) | attr_value[6]; 01460 sprintf((char *)tmp_data, "\"Humidity_0x%02x%02x\":%ld.%ld,", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp/10, tmp%10); 01461 strcat((char *)wifi_data, (char *)tmp_data); 01462 01463 /* Showing only one Temperature from the same peripheral node */ 01464 //tmp = (attr_value[9]<<8) | attr_value[8]; 01465 //sprintf((char *)tmp_data, "\"Temperature2_0x%02x%02x\":%d.%d,", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp/10, tmp%10); 01466 //strcat((char *)wifi_data, (char *)tmp_data); 01467 tmp = (attr_value[11]<<8) | attr_value[10]; 01468 sprintf((char *)tmp_data, "\"Temperature1_0x%02x%02x\":%ld.%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp/10, tmp%10); 01469 strcat((char *)wifi_data, (char *)tmp_data); 01470 notify = 1; 01471 01472 /* 01473 * Modify the attribute value according to the following format: 01474 * Tstamp | Node ID | P Type ID | value | H Type ID | value | T Type ID | value | T Type ID | value | 01475 * 2 bytes | 2 bytes | 1 byte | 4 bytes | 1 byte | 2 bytes | 1 byte | 2 bytes | 1 byte | 2 bytes | 01476 */ 01477 Create_New_Attr_Value(attr_value, devAddr, PRESS_TYPE_ID, attr_value+TSTAMP_LEN, attr_len-TSTAMP_LEN); 01478 01479 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { 01480 if ((stackBusy == 0) && (writeDescriptorCompleted ==1)){ 01481 notifyMaster(ATTR_HEAD_LEN+PRESS_DATA_LEN+(3*TYPE_ID_LEN)+HUM_DATA_LEN+(2*TEMP_DATA_LEN), 01482 star_attr_value, slave_attr_handle); 01483 }else { 01484 return; 01485 } 01486 } 01487 01488 01489 } else if (attr_handle == perDevs.led_char_handle[index]+1) { 01490 /* the status (0x01 = ON, 0x00 = OFF) */ 01491 if (attr_len != TSTAMP_LEN+LED_DATA_LEN) 01492 printf("\r\n(NC)LED Warning: received data length is %d (while expecting %d)\n", attr_len, (TSTAMP_LEN+LED_DATA_LEN)); 01493 01494 tmp = attr_value[2]; 01495 sprintf((char *)wifi_data, "\"LED_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); 01496 notify = 1; 01497 01498 /* 01499 * Modify the attribute value according to the following format: 01500 * Timestamp | Node ID | LED Type ID | value | 01501 * 2 bytes | 2 bytes | 1 byte | 1 byte | 01502 */ 01503 Create_New_Attr_Value(attr_value, devAddr, LED_TYPE_ID, attr_value+TSTAMP_LEN, LED_DATA_LEN); 01504 01505 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { 01506 if (perDevs.led_char_read[index]==1) { 01507 perDevs.status = ALL_DATA_READ; 01508 } 01509 if ((stackBusy == 0) && (writeDescriptorCompleted ==1)){ 01510 notifyMaster(ATTR_HEAD_LEN+LED_DATA_LEN, star_attr_value, slave_attr_handle); 01511 }else { 01512 return; 01513 } 01514 } 01515 01516 01517 } else if (attr_handle == perDevs.lux_char_handle[index]+1) { 01518 /* Lux value */ 01519 if (attr_len != TSTAMP_LEN+LUX_DATA_LEN) 01520 printf("\r\n(NC)LUX Warning: received data length is %d (while expecting %d)\n", attr_len, (TSTAMP_LEN+LUX_DATA_LEN)); 01521 01522 tmp = (attr_value[3]<<8) | attr_value[2]; 01523 sprintf((char *)wifi_data, "\"LUX_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); 01524 notify = 1; 01525 01526 /* 01527 * Modify the attribute value according to the following format: 01528 * Timestamp | Node ID | LUX Type ID | value | 01529 * 2 bytes | 2 bytes | 1 byte | 2 bytes | 01530 */ 01531 Create_New_Attr_Value(attr_value, devAddr, LUX_TYPE_ID, attr_value+TSTAMP_LEN, LUX_DATA_LEN); 01532 01533 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { 01534 if ((stackBusy == 0) && (writeDescriptorCompleted ==1)){ 01535 notifyMaster(ATTR_HEAD_LEN+LUX_DATA_LEN, star_attr_value, slave_attr_handle); 01536 }else { 01537 return; 01538 } 01539 } 01540 01541 01542 }//if-else-MAIN 01543 01544 if (notify == 1) { 01545 strcat((char *)wifi_data, "\n"); 01546 01547 if (discoveryCompleted == 1){ 01548 printf("\r\nNOTIFICATION => %s", (char *)wifi_data); /* print locally the buffer in JSON format */ 01549 } 01550 01551 data = wifi_data; 01552 if ((attr_handle!=perDevs.sfusion_char_handle[index]+1) && (attr_handle!=perDevs.agm_char_handle[index]+1)) 01553 new_data = 1; 01554 }//notify=1 01555 01556 if (readCompleted != 1){ 01557 readCompleted = 1; 01558 } 01559 01560 } 01561 /*----------------------------------------------------------------------------*/ 01562 01563 01564 01565 /** 01566 * @brief Enable characteristic notifications 01567 * @param Connection Handle 01568 * @param Position of the peripheral in the struct containing all peripherals 01569 * @param Peripheral node type 01570 * @param uint8_t indicating if the notification has to be enabled (1) or disabled (0) 01571 * @retval None 01572 */ 01573 void enableNotifications(uint16_t conn_handle, uint8_t index, uint8_t dev_v, uint8_t set_mode) { 01574 //printf("\r\nenableNotifications\n");//DEBUG 01575 01576 01577 uint16_t attr_handle; 01578 uint8_t attr_value[6]={0,0,0,0,0,0}; 01579 uint8_t attr_len; 01580 01581 01582 const char * event_type; 01583 01584 switch (perDevs.status) { 01585 case ENABLE_ME1_LED_NOTIFICATIONS: 01586 { 01587 event_type = "LED"; 01588 attr_handle = perDevs.led_char_handle[index] + 2; 01589 } 01590 break; 01591 01592 case ENABLE_ME1_WUP_NOTIFICATIONS: 01593 { 01594 event_type = "WUPEVT"; 01595 01596 //Enable/Disable the WakeUp notifications on the Motenv1 01597 setNotificationProperty(conn_handle, index, FEATURE_MASK_WAKEUP_EVENTS, WAKEUP_NOTIFICATION_CMD, set_mode); 01598 01599 attr_handle = perDevs.wup_char_handle[index] + 2; 01600 } 01601 break; 01602 default: 01603 break; 01604 } 01605 01606 attr_value[0] = set_mode; 01607 attr_len = 2; 01608 01609 01610 if (perDevs.status == ENABLE_ME1_LED_NOTIFICATIONS){ 01611 writeDescriptorCompleted=0; 01612 printf("\r\n%s notifications set to %d for periph %d (0x%04x)\n", event_type, set_mode, index+1, conn_handle); 01613 writeCharacDescriptor(conn_handle, attr_handle, attr_len, attr_value); 01614 01615 } 01616 01617 if ((perDevs.status == ENABLE_ME1_WUP_NOTIFICATIONS)/* && (writeDescriptorCompleted == 1)*/){ 01618 writeDescriptorCompleted=0; 01619 printf("\r\n%s notifications set to %d for periph %d (0x%04x)\n", event_type, set_mode, index+1, conn_handle); 01620 writeCharacDescriptor(conn_handle, attr_handle, attr_len, attr_value); 01621 } 01622 01623 } 01624 /*----------------------------------------------------------------------------*/ 01625 01626 01627 01628 /* Method called after a periph descriptor is written */ 01629 void perDescriptorWrittenCallback(const GattWriteCallbackParams* event){ 01630 //printf("\r\nperDescriptorWrittenCallback\n");//DEBUG 01631 01632 writeDescriptorCompleted = 1; 01633 eventQ.call(setNewStatus); 01634 //writeDescriptorCompleted = 1; 01635 } 01636 /*----------------------------------------------------------------------------*/ 01637 01638 01639 01640 /* Write a characteristic descriptor */ 01641 //cmd == GattClient::GATT_OP_WRITE_REQ 01642 void writeCharacDescriptor(uint16_t conn_handle, uint16_t attr_handle, uint8_t attr_len, 01643 uint8_t* attr_value){ 01644 01645 ble_error_t error = BLE::Instance().gattClient().write( GattClient::GATT_OP_WRITE_REQ, 01646 conn_handle, 01647 attr_handle, 01648 attr_len, 01649 attr_value ); 01650 01651 if (error != BLE_ERROR_NONE){ 01652 printf("\r\nWrite charac descriptor failed!\n"); 01653 writeDescriptorCompleted = 1; 01654 } 01655 } 01656 /*----------------------------------------------------------------------------*/ 01657 01658 01659 01660 01661 01662 /* Get error */ 01663 ble_error_t writeCharacDescriptorWithError(uint16_t conn_handle, uint16_t attr_handle, uint8_t attr_len, 01664 uint8_t* attr_value){ 01665 01666 ble_error_t error = BLE::Instance().gattClient().write( GattClient::GATT_OP_WRITE_REQ, 01667 conn_handle, 01668 attr_handle, 01669 attr_len, 01670 attr_value ); 01671 return error; 01672 } 01673 /*----------------------------------------------------------------------------*/ 01674 01675 01676 01677 01678 /* Write a characteristic value without waiting for any response */ 01679 //cmd == GATT_OP_WRITE_CMD 01680 void writeCharacValueWithoutResp(uint16_t conn_handle, uint16_t attr_handle, uint8_t attr_len, 01681 uint8_t* attr_value){ 01682 01683 ble_error_t error = BLE::Instance().gattClient().write( GattClient::GATT_OP_WRITE_CMD, 01684 conn_handle, 01685 attr_handle, 01686 attr_len, 01687 attr_value ); 01688 01689 if (error != BLE_ERROR_NONE){ 01690 printf("\r\nWrite charac descriptor wo resp failed!\n"); 01691 writeDescriptorCompleted = 1; 01692 } 01693 } 01694 /*----------------------------------------------------------------------------*/ 01695 01696 01697 01698 01699 /* Get error */ 01700 ble_error_t writeCharacValueWithoutRespWithError(uint16_t conn_handle, uint16_t attr_handle, uint8_t attr_len, 01701 uint8_t* attr_value){ 01702 01703 ble_error_t error = BLE::Instance().gattClient().write( GattClient::GATT_OP_WRITE_CMD, 01704 conn_handle, 01705 attr_handle, 01706 attr_len, 01707 attr_value ); 01708 return error; 01709 01710 } 01711 /*----------------------------------------------------------------------------*/ 01712 01713 01714 01715 01716 /** 01717 * @brief This function builds a Jason format string 01718 * @param attribute value 01719 * @param string indicating the data type (Acc, Gyr or Mag) 01720 * @param address of the device 01721 * @param data type (integer or float) 01722 * @retval None 01723 */ 01724 void Build_MEMS_Packet(uint8_t *attr_value, char *data_type, tBDAddr devAddr, uint8_t num_type){ 01725 01726 int32_t tmp = 0; 01727 uint8_t tmp_data[256]; 01728 const char* sign = ""; 01729 char axes[3] = {'X','Y','Z'}; 01730 uint8_t i, j = 0; 01731 01732 for (i=0; i<5; i++) { 01733 tmp = ((int8_t)attr_value[i+1]<<8) | attr_value[i]; 01734 01735 if (num_type==1) { 01736 if (i==0) { 01737 sprintf((char *)wifi_data, "\"%s%c_0x%02x%02x\":%ld; ", data_type, axes[j], devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); 01738 01739 } else { 01740 sprintf((char *)tmp_data, "\"%s%c_0x%02x%02x\":%ld; ", data_type, axes[j], devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); 01741 strcat ((char *)wifi_data, (char *)tmp_data); 01742 } 01743 01744 } else { 01745 sign = (tmp < 0) ? "-" : ""; 01746 tmp = (tmp < 0) ? (-tmp) : (tmp); 01747 if (i==0) { 01748 sprintf((char *)wifi_data, "\"%s%c_0x%02x%02x\":%s%ld.%ld; ", data_type, axes[j], devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], sign, tmp/10, tmp%10); 01749 01750 } else { 01751 sprintf((char *)tmp_data, "\"%s%c_0x%02x%02x\":%s%ld.%ld; ", data_type, axes[j], devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], sign, tmp/10, tmp%10); 01752 strcat ((char *)wifi_data, (char *)tmp_data); 01753 } 01754 }//if-MAIN 01755 01756 i++; 01757 j++; 01758 01759 }//for 01760 } 01761 /*----------------------------------------------------------------------------*/ 01762 01763 01764 /** 01765 * @brief This function creates, from an attribute value received from a 01766 * peripheral node, a new attribute value to be sent to the client 01767 * @param tstamp Timestamp 01768 * @param data_type_id Data Type ID 01769 * @param devAddr Device address 01770 * @param data_length Data Length 01771 * @retval None 01772 */ 01773 void Create_New_Attr_Value (uint8_t *tstamp, tBDAddr devAddr, uint8_t data_type_id, uint8_t *data, uint8_t data_length){ 01774 //printf("\r\nCreate_New_Attr_Value\n");//DEBUG 01775 01776 01777 01778 uint8_t* new_attr_value = star_attr_value; 01779 01780 memcpy(new_attr_value, tstamp, TSTAMP_LEN); /* Timestamp */ 01781 new_attr_value += TSTAMP_LEN; 01782 01783 memcpy(new_attr_value, devAddr+NODE_ID_OFFSET, NODE_ID_LEN); /* Node ID */ 01784 new_attr_value += NODE_ID_LEN; 01785 01786 memcpy(new_attr_value, &data_type_id, TYPE_ID_LEN); /* Data Type ID */ 01787 new_attr_value += TYPE_ID_LEN; 01788 01789 switch(data_type_id) 01790 { 01791 01792 // 01793 case PRESS_TYPE_ID: 01794 { 01795 memcpy(new_attr_value, data, PRESS_DATA_LEN); /* Pressure value */ 01796 new_attr_value += PRESS_DATA_LEN; 01797 data += PRESS_DATA_LEN; 01798 01799 if (data_length == ENV_DATA_LEN_LONG-TSTAMP_LEN) { 01800 data_type_id = HUM_TYPE_ID; 01801 01802 memcpy(new_attr_value, &data_type_id, TYPE_ID_LEN); /* Humidity Type ID */ 01803 new_attr_value += TYPE_ID_LEN; 01804 01805 memcpy(new_attr_value, data, HUM_DATA_LEN); /* Humidity value */ 01806 new_attr_value += HUM_DATA_LEN; 01807 data += HUM_DATA_LEN; 01808 data_type_id = TEMP_TYPE_ID; 01809 01810 memcpy(new_attr_value, &data_type_id, TYPE_ID_LEN); /* Temperature Type ID */ 01811 new_attr_value += TYPE_ID_LEN; 01812 01813 memcpy(new_attr_value, data, TEMP_DATA_LEN); /* Temperature value */ 01814 new_attr_value += TEMP_DATA_LEN; 01815 data += TEMP_DATA_LEN; 01816 01817 memcpy(new_attr_value, &data_type_id, TYPE_ID_LEN); /* Temperature Type ID */ 01818 new_attr_value += TYPE_ID_LEN; 01819 memcpy(new_attr_value, data, TEMP_DATA_LEN); /* Temperature value */ 01820 } 01821 01822 else { /* Sensor Tile */ 01823 data_type_id = TEMP_TYPE_ID; 01824 memcpy(new_attr_value, &data_type_id, TYPE_ID_LEN); /* Temperature Type ID */ 01825 new_attr_value += TYPE_ID_LEN; 01826 memcpy(new_attr_value, data, TEMP_DATA_LEN); /* Temperature value */ 01827 } 01828 } 01829 break; 01830 case LED_TYPE_ID: 01831 case MICLEVEL_TYPE_ID: 01832 { 01833 memcpy(new_attr_value, data, ONE_BYTE_LEN); /* LED or MIC value */ 01834 } 01835 break; 01836 case PRX_TYPE_ID: 01837 case LUX_TYPE_ID: 01838 { 01839 memcpy(new_attr_value, data, TWO_BYTES_LEN); /* LUX or PRX value */ 01840 } 01841 break; 01842 case ACC_TYPE_ID: 01843 { 01844 memcpy(new_attr_value, data, X_DATA_LEN); /* ACC value */ 01845 new_attr_value += X_DATA_LEN; 01846 data += X_DATA_LEN; 01847 memcpy(new_attr_value, data, Y_DATA_LEN); 01848 new_attr_value += Y_DATA_LEN; 01849 data += Y_DATA_LEN; 01850 memcpy(new_attr_value, data, Z_DATA_LEN); 01851 new_attr_value += Z_DATA_LEN; 01852 data += Z_DATA_LEN; 01853 if (data_length == MEMS_DATA_LEN) { 01854 data_type_id = GYR_TYPE_ID; 01855 memcpy(new_attr_value, &data_type_id, TYPE_ID_LEN); /* GYR Type ID */ 01856 new_attr_value += TYPE_ID_LEN; 01857 memcpy(new_attr_value, data, X_DATA_LEN); /* GYR value */ 01858 new_attr_value += X_DATA_LEN; 01859 data += X_DATA_LEN; 01860 memcpy(new_attr_value, data, Y_DATA_LEN); 01861 new_attr_value += Y_DATA_LEN; 01862 data += Y_DATA_LEN; 01863 memcpy(new_attr_value, data, Z_DATA_LEN); 01864 new_attr_value += Z_DATA_LEN; 01865 data += Z_DATA_LEN; 01866 01867 data_type_id = MAG_TYPE_ID; 01868 memcpy(new_attr_value, &data_type_id, TYPE_ID_LEN); /* MAG Type ID */ 01869 new_attr_value += TYPE_ID_LEN; 01870 memcpy(new_attr_value, data, X_DATA_LEN); /* MAG value */ 01871 new_attr_value += X_DATA_LEN; 01872 data += X_DATA_LEN; 01873 memcpy(new_attr_value, data, Y_DATA_LEN); 01874 new_attr_value += Y_DATA_LEN; 01875 data += Y_DATA_LEN; 01876 memcpy(new_attr_value, data, Z_DATA_LEN); 01877 } 01878 } 01879 break; 01880 case GYR_TYPE_ID: 01881 case MAG_TYPE_ID: 01882 case SFUSION_TYPE_ID: 01883 { 01884 memcpy(new_attr_value, data, X_DATA_LEN); /* X or Q1 value */ 01885 new_attr_value += X_DATA_LEN; 01886 data += X_DATA_LEN; 01887 memcpy(new_attr_value, data, Y_DATA_LEN); /* Y or Q2 value */ 01888 new_attr_value += Y_DATA_LEN; 01889 data += Y_DATA_LEN; 01890 memcpy(new_attr_value, data, Z_DATA_LEN); /* Z or Q3 value */ 01891 } 01892 break; 01893 default: 01894 break; 01895 } 01896 } 01897 /*----------------------------------------------------------------------------*/ 01898 01899 01900 01901 /* Method called after the reading of a characteristic */ 01902 void readCharacteristicCallback(const GattReadCallbackParams *response) { 01903 //printf("\r\nreadCharacteristicCallback - status (%d)\n\n", perDevs.status);//DEBUG 01904 01905 01906 01907 uint16_t handle = response->connHandle; 01908 uint8_t data_length = response->len; 01909 uint8_t * attr_value = (uint8_t *)response->data; 01910 01911 01912 int32_t tmp = 0; 01913 uint8_t tmp_data[256]; 01914 uint8_t index; 01915 tBDAddr devAddr; 01916 uint16_t attribute_handle; //slave 01917 uint8_t new_buffer = 0; 01918 getDeviceFromConnHandle(handle, &index, devAddr); 01919 01920 01921 /* Building the buffer in JSON format */ 01922 switch (perDevs.status) { 01923 01924 case READING_ENVIRONMENTAL: 01925 { 01926 /* P in mBar, H in percentage, T2 and T1 value in Celtius degree */ 01927 if ((data_length != ENV_DATA_LEN_LONG) && (data_length != ENV_DATA_LEN_SHORT)) { 01928 printf("\rENV Warning: received data length is %d (while expecting %d or %d) - status=%d\n\n", data_length, (ENV_DATA_LEN_LONG), (ENV_DATA_LEN_SHORT), perDevs.status); 01929 } 01930 else { 01931 tmp = (attr_value[5]<<24) | (attr_value[4]<<16) | (attr_value[3]<<8) | attr_value[2]; 01932 sprintf((char *)wifi_data, "\"Pressure_0x%02x%02x\":%ld.%ld,", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp/100, tmp%100); 01933 if (data_length == ENV_DATA_LEN_LONG) { 01934 tmp = (attr_value[7]<<8) | attr_value[6]; 01935 sprintf((char *)tmp_data, "\"Humidity_0x%02x%02x\":%ld.%ld,", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp/10, tmp%10); 01936 strcat((char *)wifi_data, (char *)tmp_data); 01937 //Showing only one Temperature from the same peripheral node 01938 //tmp = (attr_value[9]<<8) | attr_value[8]; 01939 //sprintf((char *)tmp_data, "\"Temperature2_0x%02x%02x\":%ld.%ld,", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp/10, tmp%10); 01940 //strcat((char *)wifi_data, (char *)tmp_data); 01941 tmp = (attr_value[11]<<8) | attr_value[10]; 01942 sprintf((char *)tmp_data, "\"Temperature1_0x%02x%02x\":%ld.%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp/10, tmp%10); 01943 strcat((char *)wifi_data, (char *)tmp_data); 01944 } 01945 else { /* ENV_DATA_LEN_SHORT (that is when using the Sensor Tile) */ 01946 tmp = (attr_value[7]<<8) | attr_value[6]; 01947 sprintf((char *)tmp_data, "\"Temperature1_0x%02x%02x\":%ld.%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp/10, tmp%10); 01948 strcat((char *)wifi_data, (char *)tmp_data); 01949 } 01950 01951 01952 01953 01954 attribute_handle = slaveDev.star_data_char_handle; 01955 01956 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { 01957 /* 01958 * Modify the attribute value according to the following format: 01959 * Tstamp | Node ID | P Type ID | value | H Type ID | value | T Type ID | value | T Type ID | value | 01960 * 2 bytes | 2 bytes | 1 byte | 4 bytes | 1 byte | 2 bytes | 1 byte | 2 bytes | 1 byte | 2 bytes | 01961 */ 01962 Create_New_Attr_Value(attr_value, devAddr, PRESS_TYPE_ID, attr_value+TSTAMP_LEN, data_length-TSTAMP_LEN); 01963 if (data_length == ENV_DATA_LEN_LONG) { 01964 slaveDev.notification_data.data_length = ATTR_HEAD_LEN+PRESS_DATA_LEN+(3*TYPE_ID_LEN)+HUM_DATA_LEN+(2*TEMP_DATA_LEN); 01965 } 01966 else { /* ENV_DATA_LEN_SHORT (that is when using the Sensor Tile) */ 01967 slaveDev.notification_data.data_length = ATTR_HEAD_LEN+PRESS_DATA_LEN+TYPE_ID_LEN+TEMP_DATA_LEN; 01968 } 01969 01970 slaveDev.notification_data.attribute_value = star_attr_value; 01971 memcpy(slaveDev.notification_data.devAddr, devAddr, 6); 01972 slaveDev.notification_data.attribute_handle = attribute_handle; 01973 } 01974 01975 new_buffer = 1; 01976 } 01977 } 01978 break; 01979 01980 01981 01982 case READING_LED: 01983 { 01984 /* the status (0=OFF, 1=ON) */ 01985 if (data_length != TSTAMP_LEN+LED_DATA_LEN) { 01986 printf("\rLED Warning: received data length is %d (while expecting %d) - status=%d\n\n", data_length, (TSTAMP_LEN+LED_DATA_LEN), perDevs.status); 01987 } 01988 else { 01989 tmp = attr_value[2]; 01990 sprintf((char *)wifi_data, "\"LED_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); 01991 01992 01993 attribute_handle = slaveDev.star_data_char_handle; 01994 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { 01995 /* 01996 * Modify the attribute value according to the following format: 01997 * Timestamp | Node ID | LED Type ID | value | 01998 * 2 bytes | 2 bytes | 1 byte | 1 byte | 01999 */ 02000 Create_New_Attr_Value(attr_value, devAddr, LED_TYPE_ID, attr_value+TSTAMP_LEN, LED_DATA_LEN); 02001 02002 slaveDev.notification_data.data_length = ATTR_HEAD_LEN+LED_DATA_LEN; 02003 slaveDev.notification_data.attribute_value = star_attr_value; 02004 memcpy(slaveDev.notification_data.devAddr, devAddr, 6); 02005 slaveDev.notification_data.attribute_handle = attribute_handle; 02006 } 02007 new_buffer = 1; 02008 } 02009 } 02010 break; 02011 02012 02013 02014 case READING_MIC: 02015 { 02016 tmp = 0; /* fake value used to just notify the mic presence */ 02017 sprintf((char *)wifi_data, "\"Mic1_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); 02018 02019 attribute_handle = slaveDev.star_data_char_handle; 02020 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { 02021 uint8_t val = tmp; 02022 /* 02023 * Modify the attribute value according to the following format: 02024 * Timestamp | Node ID | MIC Type ID | value | 02025 * 2 bytes | 2 bytes | 1 byte | 1 byte | 02026 */ 02027 // STORE_LE_16(star_attr_value, (HAL_GetTick()>>3)); /* Timestamp */ 02028 Create_New_Attr_Value(attr_value, devAddr, MICLEVEL_TYPE_ID, &val, MIC_DATA_LEN); 02029 02030 slaveDev.notification_data.data_length = ATTR_HEAD_LEN+MIC_DATA_LEN; 02031 slaveDev.notification_data.attribute_value = star_attr_value; 02032 memcpy(slaveDev.notification_data.devAddr, devAddr, 6); 02033 slaveDev.notification_data.attribute_handle = attribute_handle; 02034 } 02035 new_buffer = 1; 02036 } 02037 break; 02038 02039 02040 02041 case READING_LUX: 02042 { 02043 /* Lux value */ 02044 if (data_length != TSTAMP_LEN+LUX_DATA_LEN) { 02045 printf("\rLUX Warning: received data length is %d (while expecting %d) - status=%d\n\n", data_length, (TSTAMP_LEN+LUX_DATA_LEN), perDevs.status); 02046 } 02047 else { 02048 tmp = (attr_value[3]<<8) | attr_value[2]; 02049 sprintf((char *)wifi_data, "\"LUX_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); 02050 02051 attribute_handle = slaveDev.star_data_char_handle; 02052 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { 02053 /* 02054 * Modify the attribute value according to the following format: 02055 * Timestamp | Node ID | LUX Type ID | value | 02056 * 2 bytes | 2 bytes | 1 byte | 2 bytes | 02057 */ 02058 Create_New_Attr_Value(attr_value, devAddr, LUX_TYPE_ID, attr_value+TSTAMP_LEN, LUX_DATA_LEN); 02059 02060 slaveDev.notification_data.data_length = ATTR_HEAD_LEN+LUX_DATA_LEN; 02061 slaveDev.notification_data.attribute_value = star_attr_value; 02062 memcpy(slaveDev.notification_data.devAddr, devAddr, 6); 02063 slaveDev.notification_data.attribute_handle = attribute_handle; 02064 } 02065 new_buffer = 1; 02066 } 02067 } 02068 break; 02069 02070 02071 02072 case READING_PRX: 02073 { 02074 /* the distance value in mm */ 02075 tmp = 0; /* fake value used to just notify the prx presence */ 02076 sprintf((char *)wifi_data, "\"PRX_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); 02077 02078 attribute_handle = slaveDev.star_data_char_handle; 02079 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { 02080 uint8_t val[PRX_DATA_LEN]; 02081 memcpy((void *)val, (void *)tmp, sizeof(val)); 02082 /* 02083 * Modify the attribute value according to the following format: 02084 * Timestamp | Node ID | Proximity Type ID | value | 02085 * 2 bytes | 2 bytes | 1 byte | 2 bytes | 02086 */ 02087 Create_New_Attr_Value(attr_value, devAddr, PRX_TYPE_ID, val, PRX_DATA_LEN); 02088 02089 slaveDev.notification_data.data_length = ATTR_HEAD_LEN+PRX_DATA_LEN; 02090 slaveDev.notification_data.attribute_value = star_attr_value; 02091 memcpy(slaveDev.notification_data.devAddr, devAddr, 6); 02092 slaveDev.notification_data.attribute_handle = attribute_handle; 02093 } 02094 new_buffer = 1; 02095 } 02096 break; 02097 02098 02099 02100 case READING_DISCONNECTION: 02101 { 02102 /* Device disconnected */ 02103 attribute_handle = slaveDev.star_data_char_handle; 02104 /* 02105 * Modify the attribute value according to the following format: 02106 * Timestamp | Node ID | Status Type ID | 02107 * 2 bytes | 2 bytes | 1 byte | 02108 */ 02109 Create_New_Attr_Value(attr_value, devAddr, STATUS_TYPE_ID, NULL, STATUS_DATA_LEN); 02110 02111 slaveDev.notification_data.data_length = ATTR_HEAD_LEN+STATUS_DATA_LEN; 02112 slaveDev.notification_data.attribute_value = star_attr_value; 02113 memcpy(slaveDev.notification_data.devAddr, devAddr, 6); 02114 slaveDev.notification_data.attribute_handle = attribute_handle; 02115 02116 new_buffer = 1; 02117 } 02118 break; 02119 02120 02121 02122 case READING_AGM: 02123 { 02124 /* the acceleration value in mg */ 02125 tmp = 0; /* fake value used to just notify the agm presence */ 02126 sprintf((char *)wifi_data, "\"AGM_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); 02127 02128 attribute_handle = slaveDev.star_data_char_handle; 02129 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { 02130 uint8_t val[MEMS_DATA_LEN]; 02131 memcpy((void *)val, (void *)tmp, sizeof(val)); 02132 /* 02133 * Modify the attribute value according to the following format: 02134 * Timestamp | Node ID | ACC Type ID | value | GYR Type ID | value | MAG Type ID | value | 02135 * 2 bytes | 2 bytes | 1 byte | 6 bytes | 1 byte | 6 bytes | 1 byte | 6 bytes | 02136 */ 02137 Create_New_Attr_Value(attr_value, devAddr, ACC_TYPE_ID, val, MEMS_DATA_LEN); 02138 02139 slaveDev.notification_data.data_length = ATTR_HEAD_LEN+ACC_DATA_LEN+(2*TYPE_ID_LEN)+GYR_DATA_LEN+MAG_DATA_LEN; 02140 slaveDev.notification_data.attribute_value = star_attr_value; 02141 memcpy(slaveDev.notification_data.devAddr, devAddr, 6); 02142 slaveDev.notification_data.attribute_handle = attribute_handle; 02143 } 02144 new_buffer = 1; 02145 } 02146 break; 02147 02148 02149 02150 case READING_SFUSION: 02151 { 02152 /* the mems sensor fusion value */ 02153 tmp = 0; /* fake value used to just notify the sensor fusion presence */ 02154 sprintf((char *)wifi_data, "\"SFUSION_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); 02155 02156 attribute_handle = slaveDev.star_data_char_handle; 02157 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { 02158 uint8_t val[3]; 02159 memcpy((void *)val, (void *)tmp, sizeof(val)); 02160 /* 02161 * Modify the attribute value according to the following format: 02162 * Timestamp | Node ID | SFUSION Type ID | value | 02163 * 2 bytes | 2 bytes | 1 byte | 6 bytes | 02164 */ 02165 Create_New_Attr_Value(attr_value, devAddr, SFUSION_TYPE_ID, val, SFUSION_DATA_LEN); 02166 02167 slaveDev.notification_data.data_length = ATTR_HEAD_LEN+SFUSION_DATA_LEN; 02168 slaveDev.notification_data.attribute_value = star_attr_value; 02169 memcpy(slaveDev.notification_data.devAddr, devAddr, 6); 02170 slaveDev.notification_data.attribute_handle = attribute_handle; 02171 } 02172 new_buffer = 1; 02173 } 02174 break; 02175 02176 02177 02178 default: 02179 break; 02180 02181 } 02182 02183 02184 02185 if (new_buffer == 1){ 02186 strcat((char *)wifi_data, "\n"); 02187 printf("\r\n%s", (char *)wifi_data); /* print locally the buffer in JSON format */ 02188 02189 data = wifi_data; 02190 new_data = 1; 02191 } 02192 02193 02194 /* Enable notification here because a reading operation was pending */ 02195 if (notificationPending == 1){ 02196 readCompleted = 1; 02197 Change_Notification_Status(notifyP->att_data, notifyP->attr_value, notifyP->conn_handle, notifyP->i, notifyP->feature_mask, notifyP->frequency); 02198 }else { 02199 readCompleted = 1; 02200 setNewStatus(); 02201 } 02202 } 02203 /*----------------------------------------------------------------------------*/ 02204 02205 02206 02207 /* This function retrieves the peripheral device index and address 02208 * from the connection handle */ 02209 void getDeviceFromConnHandle(uint16_t handle, uint8_t *index, tBDAddr devAddr){ 02210 //printf("\r\ngetDeviceFromConnHandle\n\n");//DEBUG 02211 02212 uint8_t i; 02213 02214 for (i=0; i<MAX_NUM_OF_NODES; i++){ 02215 if (perDevs.connection_handle[i] == handle){ 02216 memcpy(devAddr, perDevs.devInfo[i].bdaddr, 6); 02217 *index = i; 02218 break; 02219 } 02220 } 02221 } 02222 /*----------------------------------------------------------------------------*/ 02223 02224 02225 /* Create a null gatt read pointer */ 02226 GattReadCallbackParams * nullGattReadCallbackP(uint16_t connection_handle){ 02227 GattReadCallbackParams gattReadCallbackParamsStruct, *pointer; 02228 pointer = &gattReadCallbackParamsStruct; 02229 02230 pointer->connHandle = connection_handle; 02231 pointer->len = 0; 02232 //pointer->data = NULL; 02233 pointer->data = 0; 02234 02235 return pointer; 02236 02237 } 02238 /*----------------------------------------------------------------------------*/ 02239 02240 02241 02242 void readingProcess(void) { 02243 //printf("\r\nreadingProcess - status: %d - connDevices: %d\n", perDevs.status, perDevs.connDevices);//DEBUG 02244 02245 02246 /* This index defines which peripheral is going to be read */ 02247 uint8_t i = perDevs.readDeviceIdx; 02248 //fetch the current connection handle 02249 uint16_t connHandle = perDevs.connection_handle[i]; 02250 02251 02252 02253 02254 if ((perDevs.status == NOTIFICATIONS_DATA_READ) && (perDevs.sfusion_event_enabled) && (!perDevs.sfusion_char_read[i])){ 02255 perDevs.status = ALL_DATA_READ; 02256 } 02257 02258 02259 02260 //READ_INIT 02261 if ((perDevs.status == READ_INIT)) { 02262 if (perDevs.connDevices > 0) { 02263 slaveDev.is_discoverable = true; 02264 perDevs.status = ALL_DATA_READ; 02265 if (!perDevs.is_disconnected[i]) { 02266 switch (perDevs.devInfo[i].dev_v) { 02267 case NODE_ME1: 02268 case NODE_AM1: 02269 case NODE_FL1: 02270 /* start to read sensors data from environmental */ 02271 02272 if ((perDevs.mic_event_enabled) || (perDevs.prx_event_enabled) || (perDevs.agm_event_enabled) 02273 || (perDevs.sfusion_event_enabled) || (discFlag)){ 02274 //printf("\r\nNotification event enabled, skip reading\n");//DEBUG 02275 02276 } else { 02277 perDevs.status = READING_ENVIRONMENTAL; 02278 } 02279 break; 02280 default: 02281 break; 02282 } 02283 } 02284 } else { 02285 perDevs.status = CONN_INIT; 02286 } 02287 }//if-READ_INIT 02288 02289 02290 02291 02292 02293 02294 //ENVIRONMENTAL 02295 if ((perDevs.status == READING_ENVIRONMENTAL) && (readCompleted == 1) && (writeDescriptorCompleted ==1)) { 02296 //reading is starting 02297 readCompleted = 0; 02298 //fetch the characteristic declHandle 02299 uint16_t declHandle = perDevs.environmental_char_handle[i]; 02300 //current data pointer 02301 DiscoveredCharacteristic c = searchDCNode(headCharacteristic[i], declHandle)->data; 02302 //pass characteristic and connection handle 02303 readSensorData(c, connHandle, i); 02304 02305 02306 }//if-ENVIRONMENTAL 02307 02308 02309 02310 02311 02312 02313 02314 //NOTIFY_ENV_TO_CLIENT 02315 if ((perDevs.status == NOTIFY_ENV_TO_CLIENT) && (readCompleted == 1) && (writeDescriptorCompleted ==1)) { 02316 notifyMaster(slaveDev.notification_data.data_length, slaveDev.notification_data.attribute_value, 02317 slaveDev.notification_data.attribute_handle); 02318 eventQ.call(setNewStatus); 02319 }//if-NOTIFY_ENV_TO_CLIENT 02320 02321 02322 02323 02324 02325 02326 02327 //READING_LED 02328 if ((perDevs.status == READING_LED) && (readCompleted == 1) && (writeDescriptorCompleted ==1)) { 02329 //reading is starting 02330 readCompleted = 0; 02331 //fetch the characteristic declHandle 02332 uint16_t declHandle = perDevs.led_char_handle[i]; 02333 //current data pointer 02334 DiscoveredCharacteristic c = searchDCNode(headCharacteristic[i], declHandle)->data; 02335 //pass characteristic and connection handle 02336 readSensorData(c, connHandle, i); 02337 } 02338 02339 02340 02341 02342 02343 02344 //NOTIFY_LED_TO_CLIENT 02345 if ((perDevs.status == NOTIFY_LED_TO_CLIENT) && (readCompleted == 1) && (writeDescriptorCompleted ==1)) { 02346 notifyMaster(slaveDev.notification_data.data_length, slaveDev.notification_data.attribute_value, 02347 slaveDev.notification_data.attribute_handle); 02348 eventQ.call(setNewStatus); 02349 }//if-NOTIFY_LED_TO_CLIENT 02350 02351 02352 02353 02354 02355 02356 //READING_LUX 02357 if ((perDevs.status == READING_LUX) && (readCompleted == 1) && (writeDescriptorCompleted ==1)) { 02358 //reading is starting 02359 readCompleted = 0; 02360 //fetch the characteristic declHandle 02361 uint16_t declHandle = perDevs.lux_char_handle[i]; 02362 //current data pointer 02363 DiscoveredCharacteristic c = searchDCNode(headCharacteristic[i], declHandle)->data; 02364 //pass characteristic and connection handle 02365 readSensorData(c, connHandle, i); 02366 }//if-READING_LUX 02367 02368 02369 02370 02371 02372 02373 //NOTIFY_LUX_TO_CLIENT 02374 if ((perDevs.status == NOTIFY_LUX_TO_CLIENT) && (readCompleted == 1) && (writeDescriptorCompleted ==1)) { 02375 notifyMaster(slaveDev.notification_data.data_length, slaveDev.notification_data.attribute_value, 02376 slaveDev.notification_data.attribute_handle); 02377 eventQ.call(setNewStatus); 02378 }//if-NOTIFY_LUX_TO_CLIENT 02379 02380 02381 02382 02383 02384 02385 02386 //READING_MIC 02387 if ((perDevs.status == READING_MIC) && (readCompleted == 1) && (writeDescriptorCompleted ==1)){ 02388 //reading is starting 02389 readCompleted = 0; 02390 HAL_Delay(300); 02391 /* Sending a 0 value to master just to notify the MIC sensor presence */ 02392 readCharacteristicCallback(nullGattReadCallbackP(connHandle)); 02393 02394 perDevs.status = NOTIFY_MIC_TO_CLIENT; 02395 notifyMaster(slaveDev.notification_data.data_length, slaveDev.notification_data.attribute_value, 02396 slaveDev.notification_data.attribute_handle); 02397 eventQ.call(setNewStatus); 02398 }//if-READING_MIC 02399 02400 02401 02402 02403 02404 02405 //READING_PRX 02406 if ((perDevs.status == READING_PRX) && (readCompleted == 1) && (writeDescriptorCompleted ==1)) { 02407 //reading is starting 02408 readCompleted = 0; 02409 HAL_Delay(300); 02410 /* Sending a 0 value to master just to notify the PRX sensor presence */ 02411 readCharacteristicCallback(nullGattReadCallbackP(connHandle)); 02412 02413 perDevs.status = NOTIFY_PRX_TO_CLIENT; 02414 notifyMaster(slaveDev.notification_data.data_length, slaveDev.notification_data.attribute_value, 02415 slaveDev.notification_data.attribute_handle); 02416 eventQ.call(setNewStatus); 02417 }//if-READING_PRX 02418 02419 02420 02421 02422 02423 02424 02425 //READING_AGM 02426 if ((perDevs.status == READING_AGM) && (readCompleted == 1) && (writeDescriptorCompleted ==1)) { 02427 //reading is starting 02428 readCompleted = 0; 02429 HAL_Delay(300); 02430 /* Sending a 0 value to master just to notify the AGM sensors presence */ 02431 readCharacteristicCallback(nullGattReadCallbackP(connHandle)); 02432 02433 perDevs.status = NOTIFY_AGM_TO_CLIENT; 02434 notifyMaster(slaveDev.notification_data.data_length, slaveDev.notification_data.attribute_value, 02435 slaveDev.notification_data.attribute_handle); 02436 eventQ.call(setNewStatus); 02437 }//if-READING_AGM 02438 02439 02440 02441 02442 02443 02444 //READING_SFUSION 02445 if ((perDevs.status == READING_SFUSION) && (readCompleted == 1) && (writeDescriptorCompleted ==1)) { 02446 //reading is starting 02447 readCompleted = 0; 02448 HAL_Delay(300); 02449 /* Sending a 0 value to master just to notify the SFusion feature presence */ 02450 readCharacteristicCallback(nullGattReadCallbackP(connHandle)); 02451 02452 perDevs.status = NOTIFY_SFUSION_TO_CLIENT; 02453 notifyMaster(slaveDev.notification_data.data_length, slaveDev.notification_data.attribute_value, 02454 slaveDev.notification_data.attribute_handle); 02455 eventQ.call(setNewStatus); 02456 }//if-READING_SFUSION 02457 02458 02459 02460 02461 02462 02463 02464 02465 02466 //ALL_DATA_READ 02467 if ((perDevs.status == ALL_DATA_READ) && (readCompleted == 1) && (writeDescriptorCompleted ==1)) { 02468 if (i>0) { 02469 perDevs.readDeviceIdx--; 02470 }//i>0 02471 02472 perDevs.status = READ_INIT; 02473 02474 if ((slaveDev.is_connected == false) && (slaveDev.is_discoverable == true)) { 02475 #if ENABLE_MEMS 02476 disableAllNotifications(); /* Called here to disable the SFUSION notifications */ 02477 #endif 02478 setSlaveDiscoverable(); 02479 } 02480 // All peripherals are read! 02481 if (i==0) { 02482 perDevs.status = CONN_INIT; 02483 }//i=0 02484 }//if-ALL_DATA_READ 02485 02486 02487 02488 02489 02490 02491 02492 //DISABLE_NOTIFICATIONS 02493 if ((perDevs.status == DISABLE_NOTIFICATIONS) && (readCompleted == 1) && (writeDescriptorCompleted ==1)) { 02494 //printf("\r\nperDevs.status == DISABLE_NOTIFICATIONS\n");//DEBUG 02495 disableAllNotifications(); 02496 perDevs.status = ALL_DATA_READ; 02497 perDevs.readDeviceIdx = i; 02498 02499 }//if-DISABLE_NOTIFICATIONS 02500 02501 02502 02503 02504 02505 /* Start connection process */ 02506 //eventQ.call(connectionProcess); 02507 02508 } 02509 /*----------------------------------------------------------------------------*/ 02510 02511 02512 02513 /* This method reads the characteristic in input */ 02514 void readSensorData(const DiscoveredCharacteristic &characteristic, uint16_t connection_handle, uint8_t index){ 02515 //printf("\r\nreadSensorData\n");//DEBUG 02516 02517 ble_error_t error; 02518 02519 if (!perDevs.is_disconnected[index] && characteristic.getDeclHandle()){ 02520 error = characteristic.read(); 02521 02522 if (error != BLE_ERROR_NONE){ 02523 printf("\r\nUnable to read data from periph %d (err %d, cHndl 0x%04x - dHdl 0x%04x)\n", index+1, 02524 error, connection_handle, characteristic.getDeclHandle()); 02525 eventQ.call(setNewStatus); 02526 readCompleted = 1; 02527 }//if-failed 02528 02529 } else { 02530 eventQ.call(setNewStatus); 02531 }//if-else 02532 } 02533 /*----------------------------------------------------------------------------*/ 02534 02535 02536 02537 /* Set the new status */ 02538 void setNewStatus(void) { 02539 //printf("\r\nsetNewStatus\n");//DEBUG 02540 02541 02542 uint8_t i = perDevs.readDeviceIdx; 02543 02544 02545 //Switch status 02546 switch (perDevs.status) { 02547 02548 02549 02550 02551 02552 // 02553 case ENABLE_ME1_LED_NOTIFICATIONS: 02554 if (perDevs.wup_event[perDevs.connDeviceIdx]) { 02555 perDevs.status = ENABLE_ME1_WUP_NOTIFICATIONS; 02556 }else { 02557 perDevs.status = NOTIFICATIONS_ENABLED; 02558 } 02559 break; 02560 02561 02562 02563 02564 02565 02566 // 02567 case ENABLE_ME1_WUP_NOTIFICATIONS: 02568 perDevs.status = NOTIFICATIONS_ENABLED; 02569 break; 02570 02571 02572 02573 02574 02575 02576 02577 // 02578 case READING_ENVIRONMENTAL: 02579 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { 02580 perDevs.status = NOTIFY_ENV_TO_CLIENT; 02581 }else { 02582 if ((perDevs.devInfo[i].dev_v == NODE_FL1) && (perDevs.prx_on[i]==0)) { 02583 perDevs.status = READING_LUX; 02584 }else { 02585 perDevs.status = ALL_DATA_READ; 02586 } 02587 }//if-MAIN 02588 break; 02589 02590 02591 02592 02593 02594 02595 02596 02597 // 02598 case NOTIFY_ENV_TO_CLIENT: 02599 02600 //NODE_FL1 02601 if (perDevs.devInfo[i].dev_v == NODE_FL1) { 02602 02603 if (perDevs.prx_on[i]==0) { 02604 perDevs.status = READING_LUX; 02605 } 02606 else if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && 02607 (perDevs.prx_event[i]) && (!perDevs.prx_char_read[i])) { 02608 perDevs.status = READING_PRX; 02609 } 02610 02611 #if ENABLE_MEMS 02612 else if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && 02613 (perDevs.agm_event[i]) && (!perDevs.agm_char_read[i])) { 02614 perDevs.status = READING_AGM; 02615 } 02616 else if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && 02617 (perDevs.sfusion_event[i]) && (!perDevs.sfusion_char_read[i])) { 02618 perDevs.status = READING_SFUSION; 02619 } 02620 #endif 02621 else { 02622 perDevs.status = ALL_DATA_READ; 02623 } 02624 }//if-NODE_FL1 02625 02626 02627 //NODE_ME1 02628 else if (perDevs.devInfo[i].dev_v == NODE_ME1) { 02629 if (!perDevs.led_char_read[i]) { 02630 perDevs.status = READING_LED; 02631 } 02632 #if ENABLE_MEMS 02633 else if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && 02634 (perDevs.agm_event[i]) && (!perDevs.agm_char_read[i])) { 02635 perDevs.status = READING_AGM; 02636 } 02637 else if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && 02638 (perDevs.sfusion_event[i]) && (!perDevs.sfusion_char_read[i])) { 02639 perDevs.status = READING_SFUSION; 02640 } 02641 #endif 02642 else { 02643 perDevs.status = ALL_DATA_READ; 02644 } 02645 }//if-NODE_ME1 02646 02647 02648 //NODE_AM1 02649 else if (perDevs.devInfo[i].dev_v == NODE_AM1) { 02650 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && 02651 (perDevs.mic_event[i]) && (!perDevs.mic_char_read[i])) { 02652 perDevs.status = READING_MIC; 02653 } 02654 #if ENABLE_MEMS 02655 else if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && 02656 (perDevs.agm_event[i]) && (!perDevs.agm_char_read[i])) { 02657 perDevs.status = READING_AGM; 02658 } 02659 else if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && 02660 (perDevs.sfusion_event[i]) && (!perDevs.sfusion_char_read[i])) { 02661 perDevs.status = READING_SFUSION; 02662 } 02663 #endif 02664 else { 02665 perDevs.status = ALL_DATA_READ; 02666 } 02667 }//if-NODE_AM1 02668 break; 02669 02670 02671 02672 02673 02674 02675 02676 // 02677 case READING_LED: 02678 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { 02679 perDevs.status = NOTIFY_LED_TO_CLIENT; 02680 }else { 02681 perDevs.status = ALL_DATA_READ; 02682 } 02683 break; 02684 02685 02686 02687 02688 02689 02690 02691 // 02692 case NOTIFY_LED_TO_CLIENT: 02693 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && 02694 (!perDevs.led_char_read[i])) { 02695 perDevs.led_char_read[i] = 1; 02696 } 02697 #if ENABLE_MEMS 02698 else if (perDevs.agm_event[i]) { 02699 perDevs.status = READING_AGM; 02700 } 02701 #endif 02702 else { 02703 perDevs.status = ALL_DATA_READ; 02704 } 02705 break; 02706 02707 02708 02709 02710 02711 02712 02713 02714 // 02715 case READING_LUX: 02716 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { 02717 perDevs.status = NOTIFY_LUX_TO_CLIENT; 02718 }else { 02719 perDevs.status = ALL_DATA_READ; 02720 } 02721 break; 02722 02723 02724 02725 02726 02727 02728 02729 02730 // 02731 case NOTIFY_LUX_TO_CLIENT: 02732 if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && 02733 (perDevs.prx_event[i]) && (!perDevs.prx_char_read[i])) { 02734 perDevs.status = READING_PRX; 02735 }else { 02736 perDevs.status = ALL_DATA_READ; 02737 } 02738 break; 02739 02740 02741 02742 02743 02744 02745 02746 // 02747 case NOTIFY_MIC_TO_CLIENT: 02748 perDevs.mic_char_read[i] = 1; 02749 02750 #if ENABLE_MEMS 02751 if (perDevs.agm_event[i]) { 02752 perDevs.status = READING_AGM; 02753 } 02754 else if (perDevs.sfusion_event[i]) { 02755 perDevs.status = READING_SFUSION; 02756 }else { 02757 perDevs.status = ALL_DATA_READ; 02758 } 02759 #else 02760 perDevs.status = ALL_DATA_READ; 02761 #endif 02762 break; 02763 02764 02765 02766 02767 02768 02769 02770 // 02771 case NOTIFY_PRX_TO_CLIENT: 02772 perDevs.prx_char_read[i] = 1; 02773 02774 #if ENABLE_MEMS 02775 if (perDevs.agm_event[i]) { 02776 perDevs.status = READING_AGM; 02777 } 02778 else if (perDevs.sfusion_event[i]) { 02779 perDevs.status = READING_SFUSION; 02780 }else { 02781 perDevs.status = ALL_DATA_READ; 02782 } 02783 #else 02784 perDevs.status = ALL_DATA_READ; 02785 #endif 02786 break; 02787 02788 02789 02790 02791 02792 02793 02794 // 02795 case NOTIFY_AGM_TO_CLIENT: 02796 perDevs.agm_char_read[i] = 1; 02797 if (perDevs.sfusion_event[i]) { 02798 perDevs.status = READING_SFUSION; 02799 }else { 02800 perDevs.status = ALL_DATA_READ; 02801 } 02802 break; 02803 02804 02805 02806 02807 02808 // 02809 case NOTIFY_SFUSION_TO_CLIENT: 02810 perDevs.sfusion_char_read[i] = 1; 02811 perDevs.status = ALL_DATA_READ; 02812 break; 02813 02814 02815 02816 // 02817 default: 02818 break; 02819 } 02820 } 02821 /*----------------------------------------------------------------------------*/ 02822 02823 02824 02825 /* Creating a new DiscoveredCharacteristicNode */ 02826 DiscoveredCharacteristicNode * createDCNode(const DiscoveredCharacteristic &ch, DiscoveredCharacteristicNode *next){ 02827 02828 DiscoveredCharacteristicNode *newNode = (DiscoveredCharacteristicNode *)malloc(sizeof(DiscoveredCharacteristicNode)); 02829 02830 if(newNode == NULL){ 02831 printf("\r\nError creating a new node\n\n"); 02832 } 02833 newNode->data = ch; 02834 newNode->next = next; 02835 02836 return newNode; 02837 } 02838 /*----------------------------------------------------------------------------*/ 02839 02840 02841 02842 /* Prepend a DiscoveredCharacteristicNode */ 02843 DiscoveredCharacteristicNode * prependDCNode(DiscoveredCharacteristicNode *head, const DiscoveredCharacteristic *characteristic){ 02844 02845 DiscoveredCharacteristicNode * newNode = createDCNode(*characteristic, head); 02846 head = newNode; 02847 02848 return head; 02849 } 02850 /*----------------------------------------------------------------------------*/ 02851 02852 02853 02854 /* Append a DiscoveredCharacteristicNode */ 02855 DiscoveredCharacteristicNode * appendDCNode(DiscoveredCharacteristicNode *head, const DiscoveredCharacteristic *characteristic){ 02856 02857 DiscoveredCharacteristicNode * cursor = head; 02858 // find the last node 02859 while(cursor->next != NULL){ 02860 cursor = cursor->next; 02861 } 02862 02863 DiscoveredCharacteristicNode * newNode = createDCNode(*characteristic, NULL); 02864 cursor->next = newNode; 02865 02866 return head; 02867 } 02868 /*----------------------------------------------------------------------------*/ 02869 02870 02871 02872 /* Number of DiscoveredCharacteristic nodes */ 02873 int countElements(DiscoveredCharacteristicNode *head){ 02874 02875 DiscoveredCharacteristicNode * cursor = head; 02876 02877 int c=0; 02878 //cursor because starts from 0 02879 while (cursor != NULL){ 02880 c++; 02881 cursor = cursor->next; 02882 } 02883 02884 return c; 02885 } 02886 /*----------------------------------------------------------------------------*/ 02887 02888 02889 02890 /* Search for a DiscoveredCharacteristic node by declaration handle */ 02891 DiscoveredCharacteristicNode * searchDCNode(DiscoveredCharacteristicNode *head, uint16_t declHandle) { 02892 02893 DiscoveredCharacteristicNode * cursor = head; 02894 02895 while(cursor != NULL){ 02896 02897 // search for declaration handle 02898 if(cursor->data.getDeclHandle() == declHandle){ 02899 return cursor; 02900 } 02901 cursor = cursor->next; 02902 } 02903 return NULL; 02904 } 02905 /*----------------------------------------------------------------------------*/ 02906 02907 02908 02909 /* Delete the DCN list */ 02910 void deleteDCNList(DiscoveredCharacteristicNode *head){ 02911 02912 DiscoveredCharacteristicNode * cursor, *tmp; 02913 02914 if (head != NULL){ 02915 cursor = head->next; 02916 head->next = NULL; 02917 02918 while(cursor != NULL) { 02919 tmp = cursor->next; 02920 free(cursor); 02921 cursor = tmp; 02922 } 02923 } 02924 } 02925 /*----------------------------------------------------------------------------*/
Generated on Wed Jul 27 2022 08:13:19 by
1.7.2
