Lorenzo Invidia / Mbed OS ble-star-mbed

Dependencies:   MQTT target_st_bluenrg

Fork of ble-star-mbed by Lorenzo Invidia

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BleMasterService.cpp Source File

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 /*----------------------------------------------------------------------------*/