![](/media/cache/profiles/profile2.jpg.50x50_q85.jpg)
This software setup a central node of a star topology network
Dependencies: MQTT target_st_bluenrg
Fork of ble-star-mbed by
Diff: source/BleMasterService.cpp
- Revision:
- 0:1902469bdd2d
- Child:
- 1:110b5e896bc9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/BleMasterService.cpp Tue Feb 20 11:21:41 2018 +0000 @@ -0,0 +1,3081 @@ +#include <BleMasterService.h> +#include <cstdint> +#include <cstdio> +#include <cstring> +#include "../inc/BleMasterService.h" +#include "../inc/BleSlaveService.h" + +EventQueue eventQ(/* event count */ 128 * EVENTS_EVENT_SIZE); + +/* This var defines the central role + * 0 if master + * 1 if slave */ +uint8_t role = 1; + + + +/* Flag to indicate that the characteristic read is completed successful + * 1 successful + * 0 or anything else failed */ +uint8_t readCompleted; + + + + +/* Flag to indicate if the device discovery is completed successful + * 1 successful + * 0 or anything else failed */ +uint8_t discoveryCompleted; + + +/* Flag to indicate if the ch descriptor write is completed successful + * 1 successful + * 0 or anything else failed */ +uint8_t writeDescriptorCompleted = 1; + + +/* Flag to indicate if the advertising is completed + * 1 completed + * 0 or anything else not completed */ +uint8_t advEnds = 1; + + +/* Flag to indicate if a change of notification is pending + * 1 pending + * 0 or anything else not pending */ +uint8_t notificationPending = 0; + + +/* Header pointer of the DiscoveredCharacteristic list */ +DiscoveredCharacteristicNode * headCharacteristic[MAX_NUM_OF_NODES]; +DiscoveredCharacteristicNode * tmp[MAX_NUM_OF_NODES]; + +/* Primary Service UUID expected from Sensor demo peripherals */ +UUID::ShortUUIDBytes_t GENERIC_ACCESS_PROFILE_UUID = 0x1800; +UUID::ShortUUIDBytes_t GENERIC_ATTRIBUTE_PROFILE_UUID = 0x1801; + +/* Services UUID */ +UUID::LongUUIDBytes_t HARDWARE_SERVICE_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0xb4,0x9a,0xe1,0x11,0x01,0x00,0x00,0x00,0x00,0x00}; +UUID::LongUUIDBytes_t CONFIG_SERVICE_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0xb4,0x9a,0xe1,0x11,0x0F,0x00,0x00,0x00,0x00,0x00}; +UUID::LongUUIDBytes_t SOFTWARE_SERVICE_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0xb4,0x9a,0xe1,0x11,0x02,0x00,0x00,0x00,0x00,0x00}; + +/* Characteristics UUID */ +UUID::LongUUIDBytes_t ENVIRONMENTAL_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x1d,0x00}; +UUID::LongUUIDBytes_t ENVIRONMENTAL_ST_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x14,0x00}; +UUID::LongUUIDBytes_t ACCGYROMAG_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0xE0,0x00}; +UUID::LongUUIDBytes_t SFUSION_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x01,0x00,0x00}; +UUID::LongUUIDBytes_t LED_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x00,0x20}; +UUID::LongUUIDBytes_t WAKEUP_EVENT_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x04,0x00,0x00}; +UUID::LongUUIDBytes_t MIC_EVENT_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x00,0x04}; +UUID::LongUUIDBytes_t PROXIMITY_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x00,0x02}; +UUID::LongUUIDBytes_t LUX_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x00,0x01}; +UUID::LongUUIDBytes_t CONFIG_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x0F,0x00,0x02,0x00,0x00,0x00}; + +/*----- -----*/ +uint8_t wifi_data[256]; +uint8_t new_data = 0; +uint8_t *data; +uint8_t wifi_present; + +char print_msg_buff[512]; +//UART_HandleTypeDef UartMsgHandle; + +//uint16_t connection_handle = 0; + +uint8_t attribute_value[20]; +uint8_t star_attr_value[256]; + + + +PeripheralDevices_t perDevs; +extern SlaveDevice_t slaveDev; +extern ChangeNotificationQueue notifyQ, *notifyP; + +/* Private variable set in discoveryTerminationCallback and used + * in connectionProcess for enabling notification */ +uint8_t customDev_v; + + + +/*----------------------------------------------------------------------------*/ + + + +/* Initialize the struct where all peripheral devices are stored */ +void initProcess(void) { + //printf("\rinitProcess\n");//DEBUG + + //Init the lists of characteristics + for(int i=0; i<MAX_NUM_OF_NODES; i++){ + headCharacteristic[i] = NULL; + tmp[i] = NULL; + } + + + + /* The first char read */ + readCompleted = 1; + + /* No discovery started */ + discoveryCompleted = 1; + + + perDevs.discovery_enabled = true; + perDevs.device_found = false; + perDevs.connDevices = 0; + perDevs.discDevices = 0; + perDevs.connDeviceIdx = 0; + perDevs.readDeviceIdx = 0; + + for(unsigned i=0;i<MAX_NUM_OF_NODES;i++){ + perDevs.devInfo[i].dev_v = 0; + perDevs.connection_handle[i] = 0; + perDevs.is_connected[i] = false; + perDevs.is_disconnected[i] = true; + perDevs.is_unconnectable[i] = false; + perDevs.gen_access_profile_handle[i].start_h = 0; + perDevs.gen_access_profile_handle[i].end_h = 0; + perDevs.gen_attribute_profile_handle[i].start_h = 0; + perDevs.gen_attribute_profile_handle[i].end_h = 0; + perDevs.hardware_service_handle[i].start_h = 0; + perDevs.hardware_service_handle[i].end_h = 0; + perDevs.software_service_handle[i].start_h = 0; + perDevs.software_service_handle[i].end_h = 0; + perDevs.led_char_read[i] = 0; + perDevs.wup_char_read[i] = 0; + perDevs.mic_char_read[i] = 0; + perDevs.prx_char_read[i] = 0; + perDevs.agm_char_read[i] = 0; + perDevs.sfusion_char_read[i] = 0; + perDevs.wup_event[i] = 0; + perDevs.mic_event[i] = 0; + perDevs.prx_on[i] = 0; + perDevs.agm_on[i] = 0; + perDevs.sfusion_on[i] = 0; + } + + perDevs.mic_event_enabled = 0; + perDevs.prx_event_enabled = 0; + perDevs.agm_event_enabled = 0; + perDevs.sfusion_event_enabled = 0; + perDevs.acc_event_enabled = 0; + perDevs.gyr_event_enabled = 0; + perDevs.mag_event_enabled = 0; + perDevs.status = CONN_INIT; +} +/*----------------------------------------------------------------------------*/ + + + +/* Called every 10 seconds to return the current status */ +void checkStatus(){ + if ((perDevs.status != 10) && (perDevs.status != 11) && (perDevs.status != 12) && (perDevs.status != 13) && (perDevs.status != 14) + && (perDevs.status != 15) && (perDevs.status != 16) && (perDevs.status != 17) && (perDevs.status != 18) + && (perDevs.status != 19) && (perDevs.status != 20) && (perDevs.status != 21)){ + printf("\r\nCurrent Status (status: %d) (read: %s) (write: %s)\n", perDevs.status, (readCompleted == 1 ? "completed" : "pending"),(writeDescriptorCompleted == 1 ? "completed" : "pending")); + } +} +/*----------------------------------------------------------------------------*/ + + + +/* Print out device MAC address to the console*/ +void printMacAddress() +{ + Gap::AddressType_t addr_type; + Gap::Address_t address; + BLE::Instance().gap().getAddress(&addr_type, address); + printf("\rBLE CENTRAL MAC ADDRESS: "); + for (int i = 5; i >= 1; i--){ + printf("%02x:", address[i]); + } + printf("%02x\n\n", address[0]); +} +/*----------------------------------------------------------------------------*/ + + +void connectionProcess(void){ + //printf("\r\nconnectionProcess(%d)\n", perDevs.status);//DEBUG + + + + + if ( perDevs.status == CONN_INIT ) { + if ( (perDevs.connDevices < MAX_NUM_OF_NODES) && (perDevs.discovery_enabled) ) { + //printf("\r\nIF 1\n");//DEBUG + /* Start discovery of new peripheral nodes and connect them */ + startDiscovery(); + } + else { + perDevs.status = DEVICE_CONNECTED; + //printf("\r\nstatus: DEVICE_CONNECTED\n");//DEBUG + } + + }//if + + + + + + + if ( perDevs.status == DEVICE_DISCOVERY_COMPLETE ) { + //printf("\r\nDEVICE_DISCOVERY_COMPLETE\n");//DEBUG + if ( perDevs.device_found == true ) { + /* Establishing connection with a peripheral device */ + perDevs.status = START_DEVICE_CONNECTION; + //printf("\r\n\nstatus: START_DEVICE_CONNECTION\n");//DEBUG + connectPeripheral(); + }else { + perDevs.status = DEVICE_NOT_FOUND; + //printf("\r\n\nstatus: DEVICE_NOT_FOUND (%d)\n", DEVICE_NOT_FOUND);//DEBUG + } + }//if + + + + + + + // if all devices are connected or no devices are discovered start reading + if ((perDevs.status == DEVICE_CONNECTED) || (perDevs.status == DEVICE_NOT_FOUND) ){ + //printf("\r\nDEVICE_CONNECTED or DEVICE_NOT_FOUND\n");//DEBUG + + + if (perDevs.device_found == true) { + perDevs.status = DISCOVERABLE_MODE_SET; + perDevs.device_found = false; + } + + //perDevs.device_found == false -- start reading + else { + perDevs.readDeviceIdx = perDevs.connDevices+perDevs.discDevices-1; + perDevs.status = READ_INIT; + //printf("\r\nstatus: READ_INIT (%u)\n", READ_INIT); + } + + }//if-main + + + + + + + if (perDevs.status == DISCOVERABLE_MODE_SET) { + /* Search for all services */ + perDevs.status = START_SERVICE_DISCOVERY; + eventQ.call(discoverServices); + }//if + + + + + + + if ( ((perDevs.status == ENABLE_ME1_LED_NOTIFICATIONS) || + (perDevs.status == ENABLE_ME1_WUP_NOTIFICATIONS)) && (writeDescriptorCompleted == 1) ) { + + writeDescriptorCompleted =0; + /* Enabling notifications on peripheral node */ + uint8_t i = perDevs.connDeviceIdx; + uint16_t connection_handle = perDevs.connection_handle[i]; + enableNotifications(connection_handle, i, customDev_v, 1); + }//if + + + + + + + + if (perDevs.status == NOTIFICATIONS_ENABLED) { + if (!perDevs.is_disconnected[perDevs.connDeviceIdx]) { + perDevs.is_connected[perDevs.connDeviceIdx] = true; + perDevs.connDeviceIdx++; + perDevs.connDevices++; + //printf("\r\nConnected Devices %d\n", perDevs.connDevices);//DEBUG + } + + perDevs.readDeviceIdx = perDevs.connDevices-1; + perDevs.status = READ_INIT; + }//if + + + + + + /* Start reading process */ + eventQ.call(readingProcess); + //eventQ.call(connectionProcess);//DEBUG_ONLY /* Call in loop coonnectionProcess */ +} +/*----------------------------------------------------------------------------*/ + + + +/* Method called in advertingCallback when a device is found */ +void saveDeviceFound (uint8_t adv_type, BLEProtocol::AddressBytes_t addr, + uint8_t data_length, const uint8_t* data_RSSI, uint8_t pos, uint8_t dev_v, + uint8_t wup_event, uint8_t mic_event, uint8_t prx_event, + uint8_t agm_event, uint8_t sfusion_event){ + + perDevs.devInfo[pos].dev_v = dev_v; + perDevs.wup_event[pos] = wup_event; + perDevs.mic_event[pos] = mic_event; + perDevs.prx_event[pos] = prx_event; + perDevs.agm_event[pos] = agm_event; + perDevs.sfusion_event[pos] = sfusion_event; + memcpy(perDevs.devInfo[pos].bdaddr, addr, 6); +} +/*----------------------------------------------------------------------------*/ + + + + +/* Function called to connect a peripheral */ +void connectPeripheral(void){ + + ble_error_t e0, e1; + BLE& ble = BLE::Instance(); + + +/* if 1 to enable */ +#if 1 + e0 = ble.gap().stopScan(); + if (e0 != BLE_ERROR_NONE){ + printf("\r\nError while stopping scan\n"); + } +#endif + + uint8_t index; + index = perDevs.connDeviceIdx; + + printf("\r\nClient create connection with peripheral %d at pos %d\n", + perDevs.connDevices+1, index+1); + + //Connect as master (0) + role = 0; + + + e1 = ble.gap().connect(perDevs.devInfo[index].bdaddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL); + + + if (e1 != BLE_ERROR_NONE){ + printf("Error while starting connection with peripheral %d (%02x%02x).\n", + index+1, perDevs.devInfo[index].bdaddr[NODE_ID_B2], perDevs.devInfo[index].bdaddr[NODE_ID_B1]); + perDevs.is_unconnectable[index] = true; + } +} +/*----------------------------------------------------------------------------*/ + + + + +/* Function called on disconnection event */ +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { + //printf("\r\ndisconnectionCallback (%d)\n", perDevs.status);//DEBUG + BLE& ble = BLE::Instance(); + + uint8_t i; + + // current handle + uint16_t handle = params->handle; + + + + + + for (unsigned i=0; i<MAX_NUM_OF_NODES; i++) { + + //if-MAIN + if (handle == perDevs.connection_handle[i]){ + //printf("\r\n\nif (handle == perDevs.connection_handle[i]) - BleMasterService.cpp\n\n");//DEBUG + + //Delete its DCList + deleteDCNList(headCharacteristic[i]); + headCharacteristic[i] = NULL; + tmp[i] = NULL; + + if (perDevs.is_disconnected[i] == true){ + perDevs.is_unconnectable[i] = true; + + printf("\r\nPeripheral 0x%02x%02x disconnected (%d Ch in DCList)\n", + perDevs.devInfo[i].bdaddr[NODE_ID_B2], perDevs.devInfo[i].bdaddr[NODE_ID_B1], countElements(headCharacteristic[i])); + + }else { + perDevs.is_disconnected[i] = true; + perDevs.is_unconnectable[i] = false; + + + if (perDevs.is_connected[i] == true){ + //printf("\r\nperDevs.is_connected[i] = true - connDevices: %d\n", perDevs.connDevices);//DEBUG + + perDevs.connDevices--; + //disconnected_devices + perDevs.discDevices++; + perDevs.is_connected[i] = false; + } + + /* Notify device disconnection to client */ + perDevs.status = READING_DISCONNECTION; + + readCharacteristicCallback(nullGattReadCallbackP(perDevs.connection_handle[i])); + + + notifyMaster(slaveDev.notification_data.data_length, slaveDev.notification_data.attribute_value, + slaveDev.notification_data.attribute_handle); + perDevs.status = CONN_INIT; + + + printf("\r\nPeripheral 0x%02x%02x disconnected (%d still connected) (%d Ch in DCList)\n", + perDevs.devInfo[i].bdaddr[NODE_ID_B2], perDevs.devInfo[i].bdaddr[NODE_ID_B1], + perDevs.connDevices, countElements(headCharacteristic[i])); + }//if-else + break; + + }//if-MAIN + }//for + + + + /* SLAVE ROLE */ + if (handle == slaveDev.conn_handle) { + printf("\r\nMaster disconnected (adv: %d - status %d)\n", ble.gap().getState().advertising, perDevs.status);//DEBUG + + + slaveDev.is_discoverable = true; + slaveDev.is_connected = false; + slaveDev.conn_handle = 0; + slaveDev.star_data_char_notify = 0; + + for (i=0; i<MAX_NUM_OF_NODES; i++) { + perDevs.led_char_read[i] = 0; + perDevs.wup_char_read[i] = 0; + perDevs.mic_char_read[i] = 0; + perDevs.prx_char_read[i] = 0; + perDevs.agm_char_read[i] = 0; + perDevs.sfusion_char_read[i] = 0; + perDevs.prx_on[i] = 0; + perDevs.agm_on[i] = 0; + perDevs.sfusion_on[i] = 0; + }//for + + perDevs.discovery_enabled = true; + perDevs.status = DISABLE_NOTIFICATIONS; + + + //setSlaveDiscoverable();//DEBUG_only + + }//SLAVE-ROLE + +} +/*----------------------------------------------------------------------------*/ + + + + +/* Function called on connection */ +void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { + //printf("\r\n----> connectionCallback\n\n");//DEBUG + + BLE& ble = BLE::Instance(); + + static const size_t ADDR_LEN = 6; + //the current address + BLEProtocol::AddressBytes_t tempAddr; + //fill the address + for(unsigned i=0;i<ADDR_LEN;i++) { + tempAddr[i]=params->peerAddr[i]; + } + + // connection handle + uint16_t handle = params ->handle; + + //ROLE uint8_t role + // 0 = master + // 1 = slave + + uint8_t index = perDevs.connDeviceIdx; + + + + + /* MASTER ROLE */ + if (role == 0) { + + if (perDevs.is_unconnectable[index] == false) { + perDevs.connection_handle[index] = handle; + perDevs.is_disconnected[index] = false; + + printf("\r\n\nConnected to peripheral: [%02x %02x %02x %02x %02x %02x] (%d/%d - 0x%04x) (role: %s)\n", + tempAddr[5], tempAddr[4], tempAddr[3], tempAddr[2], + tempAddr[1], tempAddr[0], index+1, perDevs.connDevices+1, handle, (role == 1 ? "slave" : "master")); + + perDevs.status = DEVICE_CONNECTED; + + } else { + perDevs.is_unconnectable[index] = false; + perDevs.device_found = false; + perDevs.status = DEVICE_NOT_FOUND; + } + + }//if-MASTER + + + + + /* SLAVE ROLE */ + if (role == 1) { + //When connected the adv seams disabled + slaveDev.conn_handle = handle; + slaveDev.is_connected = true; + slaveDev.is_discoverable = false; + + + printf("\r\n\nConnected to master: [%02x %02x %02x %02x %02x %02x] (role: %s) (adv: %d)\n", + tempAddr[5], tempAddr[4], tempAddr[3], tempAddr[2], + tempAddr[1], tempAddr[0], (role == 1 ? "slave" : "master"), ble.gap().getState().advertising); + + }//if-SLAVE + + + role = 1; + +} +/*----------------------------------------------------------------------------*/ + + + + +/* Service discovery */ +void discoverServices(void){ + + BLE& ble = BLE::Instance(); + uint8_t index = perDevs.connDeviceIdx; + uint16_t conn_handle = perDevs.connection_handle[index]; + ble_error_t e0; + + printf("\r\nDiscovering services for peripheral %d (0x%04x)\n", index+1, conn_handle); + + if (perDevs.is_disconnected[index]){ + printf("\r\nPeripheral %d (0x%04x) disconnected\n", index+1, conn_handle); + eventQ.call(setNewStatus); + + }else { + ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback); + e0 = ble.gattClient().launchServiceDiscovery(conn_handle, serviceDiscoveryCallback, + characteristicDiscoveryCallback); + if (e0 != BLE_ERROR_NONE){ + printf("\r\nError while discovering primary services (error: %d)\n", e0); + eventQ.call(setNewStatus); + } + }//if-else + +} +/*----------------------------------------------------------------------------*/ + + + + +void onStopScan(Gap::TimeoutSource_t t){ + //printf("\r\nScanning ends\n");//DEBUG + + + if (perDevs.status == DEVICE_FOUND) { + perDevs.device_found = true; + } + else { + perDevs.device_found = false; + } + perDevs.status = DEVICE_DISCOVERY_COMPLETE; + printf("\r\nDevice Discovery Complete (%d)\n", perDevs.status); + + //HAL_Delay(100); + + discoveryCompleted = 1; + +} +/*----------------------------------------------------------------------------*/ + + + +void startDiscovery(void) { + //printf("\r\nstartDiscovery - status: %d\n", perDevs.status);//DEBUG + + + + + BLE &ble = BLE::Instance(); + ble_error_t e1; + + +//if-MAIN + if ((perDevs.status == CONN_INIT) && (discoveryCompleted == 1) && (advEnds == 1)){ + + discoveryCompleted = 0; + + /* if 1 to enable + * if 0 default because of the adv timer setup */ + +#if 0 + if ((slaveDev.is_connected == false) && (slaveDev.is_discoverable == true)){ + //printf("\r\nslaveDev.is_discoverable == true\n");//DEBUG + + ble_error_t e0; + e0= ble.gap().stopAdvertising(); + if ( e0 == BLE_ERROR_NONE ) { + }else { + printf("\r\nERROR stopping advertising\n");//DEBUG + } + slaveDev.is_discoverable = false; + }//stopAdv +#endif + + + + /* MASTER ROLE */ + perDevs.status = START_DEVICE_DISCOVERY; + printf("\r\nStart Device Discovery (%d)\n", perDevs.status); + + e1 = ble.gap().startScan(advertisementCallback); + + if ( e1 == BLE_ERROR_NONE ) { + //printf("\r\nScan started correctly\n");//DEBUG + }else { + printf("\r\nERROR starting scan (err: %d stat: %d)\n", e1, perDevs.status);//DEBUG + //doing something + return; + } + + }//if-MAIN +} +/*----------------------------------------------------------------------------*/ + + + + +/* Function called as response of advertising */ +void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) { //defined in Gap.h + //printf("\r----> advertisementCallback\n");//DEBUG + + static const size_t ADDR_LEN = 6; + //the current address + BLEProtocol::AddressBytes_t tempAddr; + //fill the address + for(unsigned i=0;i<ADDR_LEN;i++) { + tempAddr[i]=params->peerAddr[i]; + } + + + uint8_t alreadyIn = 1; + uint8_t index; + //uint8_t i; + uint8_t found_zero_pos = 0; + BLEProtocol::AddressBytes_t zeroAddr; + memset(zeroAddr, 0, 6); + + + +if (perDevs.status != DEVICE_FOUND) { + + + for (uint8_t i = 0; i < params->advertisingDataLen; ++i) { + + const uint8_t record_length = params->advertisingData[i]; + if (record_length == 0) { + continue; + } + const uint8_t type = params->advertisingData[i + 1]; + const uint8_t* value = params->advertisingData + i + 2; + const uint8_t value_length = record_length - 1; + + + + + + + + /* Switch because per NAMES */ + if(type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { + + + + /* Switch the peripheral nodes */ + + // M O T E N V + if (((value_length == sizeof(NODE_MOTENV)-1) && (memcmp(value, NODE_MOTENV, value_length) == 0))) { + //printf("\r(If statement 1)\n\n");//DEBUG + + + + //initial per data + uint8_t peripheral_v; + uint8_t wup_event = 0; + uint8_t mic_event = 0; + uint8_t prx_event = 0; + uint8_t agm_event = 0; + uint8_t sfusion_event = 0; + + uint8_t peripheral_name_len = params->advertisingData[3]; + const uint8_t * manuf_data = params->advertisingData+4+peripheral_name_len; + uint32_t features = 0; + + + features = (manuf_data[4]<<24) | (manuf_data[5]<<16) | (manuf_data[6]<<8) | manuf_data[7]; + wup_event = (features & FEATURE_MASK_WAKEUP_EVENTS) >> WUP_POS; + mic_event = (features & FEATURE_MASK_MIC) >> MIC_POS; + prx_event = (features & FEATURE_MASK_PROX) >> PRX_POS; + agm_event = (features & FEATURE_MASK_ACC) >> ACC_POS; + sfusion_event = (features & FEATURE_MASK_SENSORFUSION) >> SFUS_POS; + peripheral_v = NODE_ME1;//MOTENV + + + for (i=0; i<MAX_NUM_OF_NODES; i++) { + if (perDevs.is_disconnected[i]) { + if (memcmp(zeroAddr, perDevs.devInfo[i].bdaddr, 6)==0) { + if (!found_zero_pos) { + index = i; + perDevs.connDeviceIdx = i; + found_zero_pos = 1; + alreadyIn = 0; + } + } + else if (memcmp(tempAddr, perDevs.devInfo[i].bdaddr, 6)==0) { + index = i; + perDevs.connDeviceIdx = i; + alreadyIn = 0; + perDevs.discDevices--; + break; + } + else { + if (!found_zero_pos) { + index = i; + perDevs.connDeviceIdx = i; + alreadyIn = 0; + } + } + } + }//for + + + if ((!alreadyIn) && (perDevs.connDevices < MAX_NUM_OF_NODES)) { + + + /* Save the found peripheral device in the struct containing all the found peripheral devices */ + saveDeviceFound(params->type, tempAddr, params->advertisingDataLen, params->advertisingData, index, + peripheral_v, wup_event, mic_event, prx_event, agm_event, sfusion_event); + + perDevs.status = DEVICE_FOUND; + + printf("\r\nPeripheral %d inserted (%02x%02x%02x%02x%02x%02x) \n", perDevs.connDevices+1, + tempAddr[5], tempAddr[4], tempAddr[3], tempAddr[2], tempAddr[1], tempAddr[0]); + + }//if-alreadyIn + + + }//IF-MOTENV + + + + + // F L I G H T + if ((value_length == sizeof(NODE_FLIGHT)-1) && (memcmp(value, NODE_FLIGHT, value_length) == 0)) { + //printf("\r(If statement 2)\n\n");//DEBUG + + + + //initial per data + uint8_t peripheral_v; + uint8_t wup_event = 0; + uint8_t mic_event = 0; + uint8_t prx_event = 0; + uint8_t agm_event = 0; + uint8_t sfusion_event = 0; + + uint8_t peripheral_name_len = params->advertisingData[3]; + const uint8_t * manuf_data = params->advertisingData+4+peripheral_name_len; + uint32_t features = 0; + + + features = (manuf_data[4]<<24) | (manuf_data[5]<<16) | (manuf_data[6]<<8) | manuf_data[7]; + wup_event = (features & FEATURE_MASK_WAKEUP_EVENTS) >> WUP_POS; + mic_event = (features & FEATURE_MASK_MIC) >> MIC_POS; + prx_event = (features & FEATURE_MASK_PROX) >> PRX_POS; + agm_event = (features & FEATURE_MASK_ACC) >> ACC_POS; + sfusion_event = (features & FEATURE_MASK_SENSORFUSION) >> SFUS_POS; + peripheral_v = NODE_FL1;//FLIGHT + + + + for (i=0; i<MAX_NUM_OF_NODES; i++) { + if (perDevs.is_disconnected[i]) { + if (memcmp(zeroAddr, perDevs.devInfo[i].bdaddr, 6)==0) { + if (!found_zero_pos) { + index = i; + perDevs.connDeviceIdx = i; + found_zero_pos = 1; + alreadyIn = 0; + } + } + else if (memcmp(tempAddr, perDevs.devInfo[i].bdaddr, 6)==0) { + index = i; + perDevs.connDeviceIdx = i; + alreadyIn = 0; + perDevs.discDevices--; + break; + } + else { + if (!found_zero_pos) { + index = i; + perDevs.connDeviceIdx = i; + alreadyIn = 0; + } + } + } + }//for + + + if ((!alreadyIn) && (perDevs.connDevices < MAX_NUM_OF_NODES)) { + + + /* Save the found peripheral device in the struct containing all the found peripheral devices */ + saveDeviceFound(params->type, tempAddr, params->advertisingDataLen, params->advertisingData, index, + peripheral_v, wup_event, mic_event, prx_event, agm_event, sfusion_event); + + perDevs.status = DEVICE_FOUND; + + printf("\r\nPeripheral %d inserted (%02x%02x%02x%02x%02x%02x) \n", perDevs.connDevices+1, + tempAddr[5], tempAddr[4], tempAddr[3], tempAddr[2], tempAddr[1], tempAddr[0]); + }//if-alreadyIn + + }//IF-FLIGHT + + + + + + + + // A L L M E M S + if ((value_length == sizeof(NODE_ALLMEMS)-1) && (memcmp(value, NODE_ALLMEMS, value_length) == 0)){ + //printf("\r(If statement 3)\n\n");//DEBUG + + + + //initial per data + uint8_t peripheral_v; + uint8_t wup_event = 0; + uint8_t mic_event = 0; + uint8_t prx_event = 0; + uint8_t agm_event = 0; + uint8_t sfusion_event = 0; + + uint8_t peripheral_name_len = params->advertisingData[3]; + const uint8_t * manuf_data = params->advertisingData+4+peripheral_name_len; + uint32_t features = 0; + + + features = (manuf_data[4]<<24) | (manuf_data[5]<<16) | (manuf_data[6]<<8) | manuf_data[7]; + wup_event = (features & FEATURE_MASK_WAKEUP_EVENTS) >> WUP_POS; + mic_event = (features & FEATURE_MASK_MIC) >> MIC_POS; + prx_event = (features & FEATURE_MASK_PROX) >> PRX_POS; + agm_event = (features & FEATURE_MASK_ACC) >> ACC_POS; + sfusion_event = (features & FEATURE_MASK_SENSORFUSION) >> SFUS_POS; + peripheral_v = NODE_AM1;//ALLMEMS + + + for (i=0; i<MAX_NUM_OF_NODES; i++) { + if (perDevs.is_disconnected[i]) { + //printf("\r\n\n if(perDevs.is_disconnected[i])\n\n");//DEBUG + if (memcmp(zeroAddr, perDevs.devInfo[i].bdaddr, 6)==0) { + //printf("\r\n\n if(memcmp(zeroAddr, perDevs.devInfo[i].bdaddr, 6)==0)\n\n");//DEBUG + if (!found_zero_pos) { + //printf("\r\n\n if(!found_zero_pos)\n\n");//DEBUG + index = i; + perDevs.connDeviceIdx = i; + found_zero_pos = 1; + alreadyIn = 0; + } + } + else if (memcmp(tempAddr, perDevs.devInfo[i].bdaddr, 6)==0) { + //printf("\r\n\n else if(memcmp(tempAddr, perDevs.devInfo[i].bdaddr, 6)==0)\n\n");//DEBUG + index = i; + perDevs.connDeviceIdx = i; + alreadyIn = 0; + perDevs.discDevices--; + break; + } + else { + //printf("\r\n\n else - ROW 514\n\n");//DEBUG + if (!found_zero_pos) { + //printf("\r\n\n if(!found_zero_pos)\n\n");//DEBUG + index = i; + perDevs.connDeviceIdx = i; + alreadyIn = 0; + } + } + } + }//for + + + if ((!alreadyIn) && (perDevs.connDevices < MAX_NUM_OF_NODES)) { + + + /* Save the found peripheral device in the struct containing all the found peripheral devices */ + saveDeviceFound(params->type, tempAddr, params->advertisingDataLen, params->advertisingData, index, + peripheral_v, wup_event, mic_event, prx_event, agm_event, sfusion_event); + + perDevs.status = DEVICE_FOUND; + + + printf("\r\nPeripheral %d inserted (%02x%02x%02x%02x%02x%02x) \n", perDevs.connDevices+1, + tempAddr[5], tempAddr[4], tempAddr[3], tempAddr[2], tempAddr[1], tempAddr[0]); + + }//if-alreadyIn + + + }//IF-ALLMEMS + + + }//IF-typeCOMPLETE_LOCAL_NAME + + + i += record_length; + }//for-MAIN + +}//if status != DEVICE_FOUND + +} +/*----------------------------------------------------------------------------*/ + + + + +/* Function called after the discovery of a service */ +void serviceDiscoveryCallback(const DiscoveredService *service) { + //printf("\r\n\n----> serviceDiscoveryCallback\n\n");//DEBUG + printf("\r\n"); + + + //printf("\r\nstatus: SERVICE_DISCOVERED\n\n"); + perDevs.status = SERVICE_DISCOVERED; + + //length of the long uuid + unsigned uuidLength = UUID::LENGTH_OF_LONG_UUID; //16 + //pointer to the current service uuid + const uint8_t * pointerToUUID = service->getUUID().getBaseUUID(); + //temp long array + UUID::LongUUIDBytes_t tempUUID; + //temp short array + UUID::ShortUUIDBytes_t shortTempUUID; + + + /* Switch the known services */ + //create the temp array + for (unsigned i=0;i<uuidLength;i++){ + tempUUID[i]=pointerToUUID[i]; + } + + + + /* Switch the known services */ + // HARDWARE_SERVICE_UUID + if ((memcmp(tempUUID, HARDWARE_SERVICE_UUID, uuidLength)) == 0){ + printf("\r\nHARDWARE service: [ "); + + for (unsigned i = 0; i < uuidLength; i++) { + printf("%02x ", tempUUID[i]); + } + + //handles + perDevs.hardware_service_handle[perDevs.connDeviceIdx].start_h = service->getStartHandle(); + perDevs.hardware_service_handle[perDevs.connDeviceIdx].end_h = service->getEndHandle(); + + //status HW + perDevs.status = START_HARDWARE_SERV_CHARS_DISCOVERY; + //prinft("\r\nstatus = START_HARDWARE_SERV_CHARS_DISCOVERY\n"); + + + + + + + // CONFIG_SERVICE_UUID + }else if ((memcmp(tempUUID, CONFIG_SERVICE_UUID, uuidLength)) == 0){ + printf("\r\nCFG service: [ "); + + for (unsigned i = 0; i < uuidLength; i++) { + printf("%02x ", tempUUID[i]); + } + + //handles + perDevs.configuration_service_handle[perDevs.connDeviceIdx].start_h = service->getStartHandle(); + perDevs.configuration_service_handle[perDevs.connDeviceIdx].end_h = service->getEndHandle(); + + //status CFG + perDevs.status = START_CONFIGURATION_SERV_CHARS_DISCOVERY; + //prinft("\r\nstatus = START_CONFIGURATION_SERV_CHARS_DISCOVERY\n"); + + + + + + // SOFTWARE_SERVICE_UUID + }else if ((memcmp(tempUUID, SOFTWARE_SERVICE_UUID, uuidLength)) == 0){ + printf("\r\nSOFTWARE service: [ "); + + for (unsigned i = 0; i < uuidLength; i++) { + printf("%02x ", tempUUID[i]); + } + + //handles + perDevs.software_service_handle[perDevs.connDeviceIdx].start_h = service->getStartHandle(); + perDevs.software_service_handle[perDevs.connDeviceIdx].end_h = service->getEndHandle(); + + //status SW + perDevs.status = START_SOFTWARE_SERV_CHARS_DISCOVERY; + //prinft("\r\nstatus = START_SOFTWARE_SERV_CHARS_DISCOVERY\n"); + + + + + + // Short UUID services + } else if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { + //get the short uuid + shortTempUUID = service->getUUID().getShortUUID(); +// printf("\r\n\n\nS UUID [ %x ", service->getUUID().getShortUUID());//DEBUG + + + + + + + + // GENERIC_ACCESS_PROFILE_UUID + if (shortTempUUID == GENERIC_ACCESS_PROFILE_UUID) { + printf("\r\nGeneric Access Profile (GAP): [ %x ", shortTempUUID); + + //handles + perDevs.gen_access_profile_handle[perDevs.connDeviceIdx].start_h = service->getStartHandle(); + perDevs.gen_access_profile_handle[perDevs.connDeviceIdx].end_h = service->getEndHandle(); + + + + + + + + // GENERIC_ATTRIBUTE_PROFILE_UUID + } else if (shortTempUUID == GENERIC_ATTRIBUTE_PROFILE_UUID) { + printf("\r\nGeneric Attribute Profile (GATT): [ %x ", shortTempUUID); + + //handles + perDevs.gen_attribute_profile_handle[perDevs.connDeviceIdx].start_h = service->getStartHandle(); + perDevs.gen_attribute_profile_handle[perDevs.connDeviceIdx].end_h = service->getEndHandle(); + + + + + + + // UNKNOWN short service + } else { + printf("\r\nUNKNOWN service: [ %x", shortTempUUID); + } + + + + + + + // UNKNOWN long service + } else { + printf("\r\nUNKNOWN service: [ "); + + for (unsigned i = 0; i < uuidLength; i++) { + printf("%02x ", tempUUID[i]); + } + } + + + + + printf("]"); + printf("\r\n\n"); +} +/*----------------------------------------------------------------------------*/ + + + + + +/* Function called after the discovery of a characteristic */ +void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) { + //printf("\r----> characteristicDiscoveryCallback\n\n");//DEBUG + + //current characteristic handles + uint16_t declHandle = characteristicP->getDeclHandle(); //identify chars + uint16_t valueHandle = characteristicP->getValueHandle(); + + + //-----> index of current device + uint8_t idx = perDevs.connDeviceIdx; + //printf("\r\nconnDeviceIdx: %d\n", idx);//DEBUG + + //Prepend the DiscoveredCharacteristic into the list + headCharacteristic[idx] = prependDCNode(headCharacteristic[idx], characteristicP); + + + + //length of the long uuid + unsigned uuidLength = UUID::LENGTH_OF_LONG_UUID; //16 + //pointer to the current service uuid + const uint8_t * pointerToUUID = characteristicP->getUUID().getBaseUUID(); + //temp array + UUID::LongUUIDBytes_t tempUUID; + + //create the temp uuid array + for (unsigned i=0;i<uuidLength;i++){ + tempUUID[i]=pointerToUUID[i]; + } + + + + + + + + /* switch the known characteristic */ + // ENVIRONMENTAL_CHAR_UUID + // ENVIRONMENTAL_ST_CHAR_UUID + if (((memcmp(tempUUID, ENVIRONMENTAL_CHAR_UUID, uuidLength)) == 0) || + ((memcmp(tempUUID, ENVIRONMENTAL_ST_CHAR_UUID, uuidLength)) == 0)){ + + //HW + perDevs.status = HARDWARE_SERV_CHARS_DISCOVERED; + //printf("\r\nstatus = HARDWARE_SERV_CHARS_DISCOVERED\n\n"); + + + // Set the handle + perDevs.environmental_char_handle[idx] = declHandle; + + printf("\r\n - Enviromental Ch: [ "); + + for (unsigned i = 0; i < uuidLength; i++) { + printf("%02x ", pointerToUUID[i]); + } + + + + + + + + // ACCGYROMAG_CHAR_UUID + }else if ((memcmp(tempUUID, ACCGYROMAG_CHAR_UUID, uuidLength)) == 0){ + + //HW + perDevs.status = HARDWARE_SERV_CHARS_DISCOVERED; + //printf("\r\nstatus = HARDWARE_SERV_CHARS_DISCOVERED\n\n"); + + // Set the handle + perDevs.agm_char_handle[idx] = declHandle; + + + printf("\r\n - Acc-Gyro-Mag Ch: [ "); + + for (unsigned i = 0; i < uuidLength; i++) { + printf("%02x ", pointerToUUID[i]); + } + + + + + + + + // SFUSION_CHAR_UUID + }else if ((memcmp(tempUUID, SFUSION_CHAR_UUID, uuidLength)) == 0){ + + //SW + perDevs.status = SOFTWARE_SERV_CHARS_DISCOVERED; + //printf("\r\nstatus = SOFTWARE_SERV_CHARS_DISCOVERED\n\n"); + + //Set the handle + perDevs.sfusion_char_handle[idx] = declHandle; + //Init value + perDevs.sfusion_char_read[idx] = 0; + perDevs.sfusion_on[idx] = 0; + + + + printf("\r\n - SFusion Ch: [ "); + + for (unsigned i = 0; i < uuidLength; i++) { + printf("%02x ", pointerToUUID[i]); + } + + + + + + + // LED_CHAR_UUID + }else if ((memcmp(tempUUID, LED_CHAR_UUID, uuidLength)) == 0){ + + //HW + perDevs.status = HARDWARE_SERV_CHARS_DISCOVERED; + //printf("\r\nstatus = HARDWARE_SERV_CHARS_DISCOVERED\n\n"); + + // Set the handle + perDevs.led_char_handle[idx] = declHandle; + // Init value + perDevs.led_char_read[idx] = 0; + printf("\r\n - Led Ch: [ "); + + for (unsigned i = 0; i < uuidLength; i++) { + printf("%02x ", pointerToUUID[i]); + } + + + + + + // WAKEUP_EVENT_CHAR_UUID + }else if ((memcmp(tempUUID, WAKEUP_EVENT_CHAR_UUID, uuidLength)) == 0){ + + //HW + perDevs.status = HARDWARE_SERV_CHARS_DISCOVERED; + //printf("\r\nstatus = HARDWARE_SERV_CHARS_DISCOVERED\n\n"); + + // Set the handle + perDevs.wup_char_handle[idx] = declHandle; + // Init value + perDevs.wup_char_read[idx] = 0; + printf("\r\n - Wakeup Event Ch: [ "); + + for (unsigned i = 0; i < uuidLength; i++) { + printf("%02x ", pointerToUUID[i]); + } + + + + + + + // MIC_EVENT_CHAR_UUID + }else if ((memcmp(tempUUID, MIC_EVENT_CHAR_UUID, uuidLength)) == 0){ + + //HW + perDevs.status = HARDWARE_SERV_CHARS_DISCOVERED; + //printf("\r\nstatus = HARDWARE_SERV_CHARS_DISCOVERED\n\n"); + + // Set the handle + perDevs.mic_char_handle[idx] = declHandle; + // Init value + perDevs.mic_char_read[idx] = 0; + printf("\r\n - Mic Event Ch: [ "); + + for (unsigned i = 0; i < uuidLength; i++) { + printf("%02x ", pointerToUUID[i]); + } + + + + + + // PROXIMITY_CHAR_UUID + }else if ((memcmp(tempUUID, PROXIMITY_CHAR_UUID, uuidLength)) == 0){ + + //HW + perDevs.status = HARDWARE_SERV_CHARS_DISCOVERED; + //printf("\r\nstatus = HARDWARE_SERV_CHARS_DISCOVERED\n\n"); + + // Set the handle + perDevs.prx_char_handle[idx] = declHandle; + // Init value + perDevs.prx_char_read[idx] = 0; + perDevs.prx_on[idx] = 0; + printf("\r\n - Proximity Ch: [ "); + + for (unsigned i = 0; i < uuidLength; i++) { + printf("%02x ", pointerToUUID[i]); + } + + + + + + + // LUX_CHAR_UUID + }else if ((memcmp(tempUUID, LUX_CHAR_UUID, uuidLength)) == 0){ + + //HW + perDevs.status = HARDWARE_SERV_CHARS_DISCOVERED; + //printf("\r\nstatus = HARDWARE_SERV_CHARS_DISCOVERED\n\n"); + + // Set the handle + perDevs.lux_char_handle[idx] = declHandle; + + + printf("\r\n - Lux Ch: [ "); + + for (unsigned i = 0; i < uuidLength; i++) { + printf("%02x ", pointerToUUID[i]); + } + + + + + + + // CONFIG_CHAR_UUID + }else if ((memcmp(tempUUID, CONFIG_CHAR_UUID, uuidLength)) == 0){ + + //CFG + perDevs.status = CONFIGURATION_SERV_CHARS_DISCOVERED; + //printf("\r\nstatus = CONFIGURATION_SERV_CHARS_DISCOVERED\n\n"); + + + // Set the handle + perDevs.cfg_char_handle[idx] = declHandle; + + printf("\r\n - Config Ch: [ "); + + for (unsigned i = 0; i < uuidLength; i++) { + printf("%02x ", pointerToUUID[i]); + } + + + + + + // UNKNOWN + }else { + + printf("\r\n - Unknown Ch: [ "); + + for (unsigned i = 0; i < uuidLength; i++) { + printf("%02x ", pointerToUUID[i]); + } + } + + + + + printf("] "); + printf("(declH 0x%04x), r: %x\n", declHandle, (uint8_t)characteristicP->getProperties().read()); +} +/*----------------------------------------------------------------------------*/ + + + +/* Function called when discovery is terminated */ +void discoveryTerminationCallback(Gap::Handle_t connectionHandle) { + //printf("\r----> discoveryTerminationCallback\n\n");//DEBUG + + uint8_t * pointerToCustomDev_v; + pointerToCustomDev_v = &customDev_v; + + uint8_t idx = perDevs.connDeviceIdx; //idx + + printf("\r\n\n%d characteristics discovered and added into the DCList \n", countElements(headCharacteristic[idx])); + printf("\r\nTerminated SERVICE DISCOVERY for Handle 0x%04x\n\n", connectionHandle); + + + + +////Enable notifications after the discovery of the configuration characteristics +////------------ + if (!perDevs.is_disconnected[perDevs.connDeviceIdx]) { + *pointerToCustomDev_v = perDevs.devInfo[perDevs.connDeviceIdx].dev_v; + + if (perDevs.devInfo[perDevs.connDeviceIdx].dev_v == NODE_ME1) { + perDevs.status = ENABLE_ME1_LED_NOTIFICATIONS; + + }else if (perDevs.devInfo[perDevs.connDeviceIdx].dev_v == NODE_AM1) { + perDevs.status = NOTIFICATIONS_ENABLED; + + }else if (perDevs.devInfo[perDevs.connDeviceIdx].dev_v == NODE_FL1) { + perDevs.status = NOTIFICATIONS_ENABLED; + } + } else { + perDevs.status = NOTIFICATIONS_ENABLED; + } + + +////------------ + + +} +/*----------------------------------------------------------------------------*/ + + +/* Method called when there is a notification from the sever */ +void onNotificationCallback(const GattHVXCallbackParams* event){ + //printf("\r\nonNotificationCallback\n");//DEBUG + + /* GATT Notification params */ + uint16_t conn_handle = event->connHandle; + uint16_t attr_handle = event->handle; + uint8_t attr_len = event->len; + uint8_t *attr_value = (uint8_t *)event->data; + + + int32_t tmp = 0; + uint8_t tmp_data[256]; + uint8_t notify = 0; + tBDAddr devAddr; + uint8_t index; + uint16_t slave_attr_handle; + static uint8_t wupevt_value = 0; + + /* Retrieving the peripheral device index and address from the connection handle */ + getDeviceFromConnHandle(conn_handle, &index, devAddr); + slave_attr_handle = slaveDev.star_data_char_handle; + + + + /* Build buffer in JSON format */ + if (attr_handle == perDevs.wup_char_handle[index]+1) { + + /** + * The motion is detected when a WakeUp event notification is received. + * The received data is composed by 2 bytes for the tstamp + 2 bytes + * for the value. Since we transmit only information about the detected + * motion, we don't care of the last 2 bytes. + */ + if (attr_len != TSTAMP_LEN+2) + printf("\r\n(NC)WUP Warning: received data length is %d (while expecting %d)\n", attr_len, (TSTAMP_LEN+2)); + + wupevt_value = !wupevt_value; + tmp = wupevt_value; + sprintf((char *)wifi_data, "\"WUpEvt_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); + notify = 1; + + /* + * Modify the attribute value according to the following format: + * Timestamp | Node ID | WakeUp Type ID | + * 2 bytes | 2 bytes | 1 byte | + */ + Create_New_Attr_Value(attr_value, devAddr, WUP_TYPE_ID, NULL, WUP_DATA_LEN); + + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { + perDevs.status = ALL_DATA_READ; + notifyMaster(ATTR_HEAD_LEN+WUP_DATA_LEN, star_attr_value, slave_attr_handle); + } + + + } else if (attr_handle == perDevs.mic_char_handle[index]+1) { + + /* The level in dB (the mic level is detected when a mic event notification is received) */ + /* The Sensor Tile board has only Mic1 so it sends 3 bytes */ + if ((attr_len != TSTAMP_LEN+(2*MIC_DATA_LEN)) && (attr_len != TSTAMP_LEN+MIC_DATA_LEN)) + 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))); + + tmp = attr_value[2]; + sprintf((char *)wifi_data, "\"Mic1_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); + /* We do not send the audio level from Mic2 anyway */ + //tmp = attr_value[3]; + //sprintf((char *)tmp_data, ",\"Mic2_0x%02x%02x\":%d", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); + //strcat((char *)wifi_data, (char *)tmp_data); + notify = 1; + + /* + * Modify the attribute value according to the following format: + * Timestamp | Node ID | MIC Event Type ID | value | + * 2 bytes | 2 bytes | 1 byte | 1 byte | + */ + Create_New_Attr_Value(attr_value, devAddr, MICLEVEL_TYPE_ID, attr_value+TSTAMP_LEN, MIC_DATA_LEN); + + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { + perDevs.status = ALL_DATA_READ; + notifyMaster(ATTR_HEAD_LEN+MIC_DATA_LEN, star_attr_value, slave_attr_handle); + } + + + } else if (attr_handle == perDevs.prx_char_handle[index]+1) { + /* the distance value (in mm) */ + if (attr_len != TSTAMP_LEN+PRX_DATA_LEN) + printf("\r\n(NC)PRX Warning: received data length is %d (while expecting %d)\n", attr_len, (TSTAMP_LEN+PRX_DATA_LEN)); + + tmp = (attr_value[3]<<8) | attr_value[2]; + sprintf((char *)wifi_data, "\"PRX_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); + notify = 1; + + /* + * Modify the attribute value according to the following format: + * Timestamp | Node ID | Proximity Type ID | value | + * 2 bytes | 2 bytes | 1 byte | 2 bytes | + */ + 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 */ + + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { + perDevs.status = ALL_DATA_READ; + notifyMaster(ATTR_HEAD_LEN+PRX_DATA_LEN, star_attr_value, slave_attr_handle); + } + + + } else if (attr_handle == perDevs.agm_char_handle[index]+1) { + uint8_t type_id; + uint8_t data_len; + uint8_t value_offset; + + /* Acc values in mg, Gyro values in dps, Mag values in mGa */ + if (attr_len != TSTAMP_LEN+MEMS_DATA_LEN) + printf("\r\n(NC)AGM Warning: received data length is %d (while expecting %d)\n", attr_len, (TSTAMP_LEN+MEMS_DATA_LEN)); + + if (perDevs.acc_event_enabled) { + Build_MEMS_Packet(attr_value+2, "Acc", devAddr, INT_VALUE); + type_id = ACC_TYPE_ID; + data_len = ACC_DATA_LEN; + value_offset = TSTAMP_LEN; + + } else if (perDevs.gyr_event_enabled) { + Build_MEMS_Packet(attr_value+8, "Gyr", devAddr, FLOAT_VALUE); + type_id = GYR_TYPE_ID; + data_len = GYR_DATA_LEN; + value_offset = TSTAMP_LEN+ACC_DATA_LEN; + + } else if (perDevs.mag_event_enabled) { + Build_MEMS_Packet(attr_value+14, "Mag", devAddr, INT_VALUE); + type_id = MAG_TYPE_ID; + data_len = MAG_DATA_LEN; + value_offset = TSTAMP_LEN+ACC_DATA_LEN+GYR_DATA_LEN; + } + notify = 1; + + /* + * Modify the attribute value according to the following format: + * Timestamp | Node ID | Acc/Gyro/Mag Type ID | value | + * 2 bytes | 2 bytes | 1 byte | 6 bytes | + */ + Create_New_Attr_Value(attr_value, devAddr, type_id, attr_value+value_offset, data_len); + + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && (perDevs.agm_on[index])) { + perDevs.status = NOTIFICATIONS_DATA_READ; + notifyMaster(ATTR_HEAD_LEN+data_len, star_attr_value, slave_attr_handle); + + } else { + perDevs.status = ALL_DATA_READ; + } + + + + } else if (attr_handle == perDevs.sfusion_char_handle[index]+1) { + + /* Quaternion values */ + tmp = (int8_t)attr_value[3]<<8 | attr_value[2]; + sprintf((char *)wifi_data, "\"Q1_0x%02x%02x\":%s0.%.4d; ", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], (tmp<0 ? "-" : ""), (tmp<0 ? -tmp : tmp)); + tmp = (int8_t)attr_value[5]<<8 | attr_value[4]; + sprintf((char *)tmp_data, "\"Q2_0x%02x%02x\":%s0.%.4d; ", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], (tmp<0 ? "-" : ""), (tmp<0 ? -tmp : tmp)); + strcat((char *)wifi_data, (char *)tmp_data); + tmp = (int8_t)attr_value[7]<<8 | attr_value[6]; + sprintf((char *)tmp_data, "\"Q3_0x%02x%02x\":%s0.%.4d; ", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], (tmp<0 ? "-" : ""), (tmp<0 ? -tmp : tmp)); + strcat((char *)wifi_data, (char *)tmp_data); + notify = 1; + + /* + * Modify the attribute value according to the following format: + * Timestamp | Node ID | SFusion Type ID | value | + * 2 bytes | 2 bytes | 1 byte | 6 bytes | + */ + Create_New_Attr_Value(attr_value, devAddr, SFUSION_TYPE_ID, attr_value+TSTAMP_LEN, SFUSION_DATA_LEN); + + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && (perDevs.sfusion_on[index])) { + perDevs.status = NOTIFICATIONS_DATA_READ; + notifyMaster(ATTR_HEAD_LEN+SFUSION_DATA_LEN, star_attr_value, slave_attr_handle); + perDevs.sfusion_char_read[index] = 1; + + } else { + perDevs.status = ALL_DATA_READ; + } + } else if (attr_handle == perDevs.environmental_char_handle[index]+1) { + /* P value in mBar, H value in percentage, T2 and T1 values in Celtius degree */ + if (attr_len != TSTAMP_LEN+ENV_DATA_LEN) + printf("\r\n(NC)SFUSION Warning: received data length is %d (while expecting %d)\n", attr_len, (TSTAMP_LEN+ENV_DATA_LEN)); + + tmp = (attr_value[5]<<24) | (attr_value[4]<<16) | (attr_value[3]<<8) | attr_value[2]; + sprintf((char *)wifi_data, "\"Pressure_0x%02x%02x\":%ld.%ld,", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp/100, tmp%100); + tmp = (attr_value[7]<<8) | attr_value[6]; + sprintf((char *)tmp_data, "\"Humidity_0x%02x%02x\":%ld.%ld,", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp/10, tmp%10); + strcat((char *)wifi_data, (char *)tmp_data); + + /* Showing only one Temperature from the same peripheral node */ + //tmp = (attr_value[9]<<8) | attr_value[8]; + //sprintf((char *)tmp_data, "\"Temperature2_0x%02x%02x\":%d.%d,", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp/10, tmp%10); + //strcat((char *)wifi_data, (char *)tmp_data); + tmp = (attr_value[11]<<8) | attr_value[10]; + sprintf((char *)tmp_data, "\"Temperature1_0x%02x%02x\":%ld.%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp/10, tmp%10); + strcat((char *)wifi_data, (char *)tmp_data); + notify = 1; + + /* + * Modify the attribute value according to the following format: + * Tstamp | Node ID | P Type ID | value | H Type ID | value | T Type ID | value | T Type ID | value | + * 2 bytes | 2 bytes | 1 byte | 4 bytes | 1 byte | 2 bytes | 1 byte | 2 bytes | 1 byte | 2 bytes | + */ + Create_New_Attr_Value(attr_value, devAddr, PRESS_TYPE_ID, attr_value+TSTAMP_LEN, attr_len-TSTAMP_LEN); + + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { + notifyMaster(ATTR_HEAD_LEN+PRESS_DATA_LEN+(3*TYPE_ID_LEN)+HUM_DATA_LEN+(2*TEMP_DATA_LEN), + star_attr_value, slave_attr_handle); + } + + + } else if (attr_handle == perDevs.led_char_handle[index]+1) { + /* the status (0x01 = ON, 0x00 = OFF) */ + if (attr_len != TSTAMP_LEN+LED_DATA_LEN) + printf("\r\n(NC)LED Warning: received data length is %d (while expecting %d)\n", attr_len, (TSTAMP_LEN+LED_DATA_LEN)); + + tmp = attr_value[2]; + sprintf((char *)wifi_data, "\"LED_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); + notify = 1; + + /* + * Modify the attribute value according to the following format: + * Timestamp | Node ID | LED Type ID | value | + * 2 bytes | 2 bytes | 1 byte | 1 byte | + */ + Create_New_Attr_Value(attr_value, devAddr, LED_TYPE_ID, attr_value+TSTAMP_LEN, LED_DATA_LEN); + + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { + if (perDevs.led_char_read[index]==1) { + perDevs.status = ALL_DATA_READ; + } + notifyMaster(ATTR_HEAD_LEN+LED_DATA_LEN, star_attr_value, slave_attr_handle); + } + + + } else if (attr_handle == perDevs.lux_char_handle[index]+1) { + /* Lux value */ + if (attr_len != TSTAMP_LEN+LUX_DATA_LEN) + printf("\r\n(NC)LUX Warning: received data length is %d (while expecting %d)\n", attr_len, (TSTAMP_LEN+LUX_DATA_LEN)); + + tmp = (attr_value[3]<<8) | attr_value[2]; + sprintf((char *)wifi_data, "\"LUX_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); + notify = 1; + + /* + * Modify the attribute value according to the following format: + * Timestamp | Node ID | LUX Type ID | value | + * 2 bytes | 2 bytes | 1 byte | 2 bytes | + */ + Create_New_Attr_Value(attr_value, devAddr, LUX_TYPE_ID, attr_value+TSTAMP_LEN, LUX_DATA_LEN); + + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { + notifyMaster(ATTR_HEAD_LEN+LUX_DATA_LEN, star_attr_value, slave_attr_handle); + } + + + }//if-else-MAIN + + if (notify == 1) { + strcat((char *)wifi_data, "\n"); + + if (discoveryCompleted == 1){ + printf("\r\nNOTIFICATION => %s", (char *)wifi_data); /* print locally the buffer in JSON format */ + } + + data = wifi_data; + if ((attr_handle!=perDevs.sfusion_char_handle[index]+1) && (attr_handle!=perDevs.agm_char_handle[index]+1)) + new_data = 1; + }//notify=1 + + if (readCompleted != 1){ + readCompleted = 1; + } + +} +/*----------------------------------------------------------------------------*/ + + + +/** + * @brief Enable characteristic notifications + * @param Connection Handle + * @param Position of the peripheral in the struct containing all peripherals + * @param Peripheral node type + * @param uint8_t indicating if the notification has to be enabled (1) or disabled (0) + * @retval None + */ +void enableNotifications(uint16_t conn_handle, uint8_t index, uint8_t dev_v, uint8_t set_mode) { +//printf("\r\nenableNotifications\n");//DEBUG + + + uint16_t attr_handle; + uint8_t attr_value[6]={0,0,0,0,0,0}; + uint8_t attr_len; + + + const char * event_type; + + switch (perDevs.status) { + case ENABLE_ME1_LED_NOTIFICATIONS: + { + event_type = "LED"; + attr_handle = perDevs.led_char_handle[index] + 2; + } + break; + + case ENABLE_ME1_WUP_NOTIFICATIONS: + { + event_type = "WUPEVT"; + + // Enable/Disable the WakeUp notifications on the Motenv1 + setNotificationProperty(conn_handle, index, FEATURE_MASK_WAKEUP_EVENTS, WAKEUP_NOTIFICATION_CMD, set_mode); + + attr_handle = perDevs.wup_char_handle[index] + 2; + } + break; + default: + break; + } + + attr_value[0] = set_mode; + attr_len = 2; + + + if (perDevs.status == ENABLE_ME1_LED_NOTIFICATIONS){ + writeDescriptorCompleted=0; + printf("\r\n%s notifications set to %d for periph %d (0x%04x)\n", event_type, set_mode, index+1, conn_handle); + writeCharacDescriptor(conn_handle, attr_handle, attr_len, attr_value); + + } + + if ((perDevs.status == ENABLE_ME1_WUP_NOTIFICATIONS)/* && (writeDescriptorCompleted == 1)*/){ + writeDescriptorCompleted=0; + printf("\r\n%s notifications set to %d for periph %d (0x%04x)\n", event_type, set_mode, index+1, conn_handle); + writeCharacDescriptor(conn_handle, attr_handle, attr_len, attr_value); + } + +} +/*----------------------------------------------------------------------------*/ + + + +/* Method called after a periph descriptor is written */ +void perDescriptorWrittenCallback(const GattWriteCallbackParams* event){ + //printf("\r\nperDescriptorWrittenCallback\n");//DEBUG + + setNewStatus(); + writeDescriptorCompleted = 1; +} +/*----------------------------------------------------------------------------*/ + + + +/* Write a characteristic descriptor */ +//cmd == GattClient::GATT_OP_WRITE_REQ +void writeCharacDescriptor(uint16_t conn_handle, uint16_t attr_handle, uint8_t attr_len, + uint8_t* attr_value){ + + ble_error_t error = BLE::Instance().gattClient().write( GattClient::GATT_OP_WRITE_REQ, + conn_handle, + attr_handle, + attr_len, + attr_value ); + + if (error != BLE_ERROR_NONE){ + printf("\r\nWrite charac descriptor failed!\n"); + writeDescriptorCompleted = 1; + } +} +/*----------------------------------------------------------------------------*/ + + + + + +/* Get error */ +ble_error_t writeCharacDescriptorWithError(uint16_t conn_handle, uint16_t attr_handle, uint8_t attr_len, + uint8_t* attr_value){ + + ble_error_t error = BLE::Instance().gattClient().write( GattClient::GATT_OP_WRITE_REQ, + conn_handle, + attr_handle, + attr_len, + attr_value ); + return error; +} +/*----------------------------------------------------------------------------*/ + + + + +/* Write a characteristic value without waiting for any response */ +//cmd == GATT_OP_WRITE_CMD +void writeCharacValueWithoutResp(uint16_t conn_handle, uint16_t attr_handle, uint8_t attr_len, + uint8_t* attr_value){ + + ble_error_t error = BLE::Instance().gattClient().write( GattClient::GATT_OP_WRITE_CMD, + conn_handle, + attr_handle, + attr_len, + attr_value ); + + if (error != BLE_ERROR_NONE){ + printf("\r\nWrite charac descriptor wo resp failed!\n"); + writeDescriptorCompleted = 1; + } +} +/*----------------------------------------------------------------------------*/ + + + + +/* Get error */ +ble_error_t writeCharacValueWithoutRespWithError(uint16_t conn_handle, uint16_t attr_handle, uint8_t attr_len, + uint8_t* attr_value){ + + ble_error_t error = BLE::Instance().gattClient().write( GattClient::GATT_OP_WRITE_CMD, + conn_handle, + attr_handle, + attr_len, + attr_value ); + return error; + +} +/*----------------------------------------------------------------------------*/ + + + + +/** + * @brief This function builds a Jason format string + * @param attribute value + * @param string indicating the data type (Acc, Gyr or Mag) + * @param address of the device + * @param data type (integer or float) + * @retval None + */ +void Build_MEMS_Packet(uint8_t *attr_value, char *data_type, tBDAddr devAddr, uint8_t num_type){ + + int32_t tmp = 0; + uint8_t tmp_data[256]; + const char* sign = ""; + char axes[3] = {'X','Y','Z'}; + uint8_t i, j = 0; + + for (i=0; i<5; i++) { + tmp = ((int8_t)attr_value[i+1]<<8) | attr_value[i]; + + if (num_type==1) { + if (i==0) { + sprintf((char *)wifi_data, "\"%s%c_0x%02x%02x\":%ld; ", data_type, axes[j], devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); + + } else { + sprintf((char *)tmp_data, "\"%s%c_0x%02x%02x\":%ld; ", data_type, axes[j], devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); + strcat ((char *)wifi_data, (char *)tmp_data); + } + + } else { + sign = (tmp < 0) ? "-" : ""; + tmp = (tmp < 0) ? (-tmp) : (tmp); + if (i==0) { + 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); + + } else { + 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); + strcat ((char *)wifi_data, (char *)tmp_data); + } + }//if-MAIN + + i++; + j++; + + }//for +} +/*----------------------------------------------------------------------------*/ + + +/** + * @brief This function creates, from an attribute value received from a + * peripheral node, a new attribute value to be sent to the client + * @param tstamp Timestamp + * @param data_type_id Data Type ID + * @param devAddr Device address + * @param data_length Data Length + * @retval None + */ +void Create_New_Attr_Value (uint8_t *tstamp, tBDAddr devAddr, uint8_t data_type_id, uint8_t *data, uint8_t data_length){ + //printf("\r\nCreate_New_Attr_Value\n");//DEBUG + + + + uint8_t* new_attr_value = star_attr_value; + + memcpy(new_attr_value, tstamp, TSTAMP_LEN); /* Timestamp */ + new_attr_value += TSTAMP_LEN; + + memcpy(new_attr_value, devAddr+NODE_ID_OFFSET, NODE_ID_LEN); /* Node ID */ + new_attr_value += NODE_ID_LEN; + + memcpy(new_attr_value, &data_type_id, TYPE_ID_LEN); /* Data Type ID */ + new_attr_value += TYPE_ID_LEN; + + switch(data_type_id) + { + + // + case PRESS_TYPE_ID: + { + memcpy(new_attr_value, data, PRESS_DATA_LEN); /* Pressure value */ + new_attr_value += PRESS_DATA_LEN; + data += PRESS_DATA_LEN; + + if (data_length == ENV_DATA_LEN_LONG-TSTAMP_LEN) { + data_type_id = HUM_TYPE_ID; + + memcpy(new_attr_value, &data_type_id, TYPE_ID_LEN); /* Humidity Type ID */ + new_attr_value += TYPE_ID_LEN; + + memcpy(new_attr_value, data, HUM_DATA_LEN); /* Humidity value */ + new_attr_value += HUM_DATA_LEN; + data += HUM_DATA_LEN; + data_type_id = TEMP_TYPE_ID; + + memcpy(new_attr_value, &data_type_id, TYPE_ID_LEN); /* Temperature Type ID */ + new_attr_value += TYPE_ID_LEN; + + memcpy(new_attr_value, data, TEMP_DATA_LEN); /* Temperature value */ + new_attr_value += TEMP_DATA_LEN; + data += TEMP_DATA_LEN; + + memcpy(new_attr_value, &data_type_id, TYPE_ID_LEN); /* Temperature Type ID */ + new_attr_value += TYPE_ID_LEN; + memcpy(new_attr_value, data, TEMP_DATA_LEN); /* Temperature value */ + } + + else { /* Sensor Tile */ + data_type_id = TEMP_TYPE_ID; + memcpy(new_attr_value, &data_type_id, TYPE_ID_LEN); /* Temperature Type ID */ + new_attr_value += TYPE_ID_LEN; + memcpy(new_attr_value, data, TEMP_DATA_LEN); /* Temperature value */ + } + } + break; + case LED_TYPE_ID: + case MICLEVEL_TYPE_ID: + { + memcpy(new_attr_value, data, ONE_BYTE_LEN); /* LED or MIC value */ + } + break; + case PRX_TYPE_ID: + case LUX_TYPE_ID: + { + memcpy(new_attr_value, data, TWO_BYTES_LEN); /* LUX or PRX value */ + } + break; + case ACC_TYPE_ID: + { + memcpy(new_attr_value, data, X_DATA_LEN); /* ACC value */ + new_attr_value += X_DATA_LEN; + data += X_DATA_LEN; + memcpy(new_attr_value, data, Y_DATA_LEN); + new_attr_value += Y_DATA_LEN; + data += Y_DATA_LEN; + memcpy(new_attr_value, data, Z_DATA_LEN); + new_attr_value += Z_DATA_LEN; + data += Z_DATA_LEN; + if (data_length == MEMS_DATA_LEN) { + data_type_id = GYR_TYPE_ID; + memcpy(new_attr_value, &data_type_id, TYPE_ID_LEN); /* GYR Type ID */ + new_attr_value += TYPE_ID_LEN; + memcpy(new_attr_value, data, X_DATA_LEN); /* GYR value */ + new_attr_value += X_DATA_LEN; + data += X_DATA_LEN; + memcpy(new_attr_value, data, Y_DATA_LEN); + new_attr_value += Y_DATA_LEN; + data += Y_DATA_LEN; + memcpy(new_attr_value, data, Z_DATA_LEN); + new_attr_value += Z_DATA_LEN; + data += Z_DATA_LEN; + + data_type_id = MAG_TYPE_ID; + memcpy(new_attr_value, &data_type_id, TYPE_ID_LEN); /* MAG Type ID */ + new_attr_value += TYPE_ID_LEN; + memcpy(new_attr_value, data, X_DATA_LEN); /* MAG value */ + new_attr_value += X_DATA_LEN; + data += X_DATA_LEN; + memcpy(new_attr_value, data, Y_DATA_LEN); + new_attr_value += Y_DATA_LEN; + data += Y_DATA_LEN; + memcpy(new_attr_value, data, Z_DATA_LEN); + } + } + break; + case GYR_TYPE_ID: + case MAG_TYPE_ID: + case SFUSION_TYPE_ID: + { + memcpy(new_attr_value, data, X_DATA_LEN); /* X or Q1 value */ + new_attr_value += X_DATA_LEN; + data += X_DATA_LEN; + memcpy(new_attr_value, data, Y_DATA_LEN); /* Y or Q2 value */ + new_attr_value += Y_DATA_LEN; + data += Y_DATA_LEN; + memcpy(new_attr_value, data, Z_DATA_LEN); /* Z or Q3 value */ + } + break; + default: + break; + } +} +/*----------------------------------------------------------------------------*/ + + + +/* Method called after the reading of a characteristic */ +void readCharacteristicCallback(const GattReadCallbackParams *response) { + //printf("\r\nreadCharacteristicCallback - status (%d)\n\n", perDevs.status);//DEBUG + + + + uint16_t handle = response->connHandle; + uint8_t data_length = response->len; + uint8_t * attr_value = (uint8_t *)response->data; + + + int32_t tmp = 0; + uint8_t tmp_data[256]; + uint8_t index; + tBDAddr devAddr; + uint16_t attribute_handle; //slave + uint8_t new_buffer = 0; + getDeviceFromConnHandle(handle, &index, devAddr); + + + /* Building the buffer in JSON format */ + switch (perDevs.status) { + + case READING_ENVIRONMENTAL: + { + /* P in mBar, H in percentage, T2 and T1 value in Celtius degree */ + if ((data_length != ENV_DATA_LEN_LONG) && (data_length != ENV_DATA_LEN_SHORT)) { + 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); + } + else { + tmp = (attr_value[5]<<24) | (attr_value[4]<<16) | (attr_value[3]<<8) | attr_value[2]; + sprintf((char *)wifi_data, "\"Pressure_0x%02x%02x\":%ld.%ld,", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp/100, tmp%100); + if (data_length == ENV_DATA_LEN_LONG) { + tmp = (attr_value[7]<<8) | attr_value[6]; + sprintf((char *)tmp_data, "\"Humidity_0x%02x%02x\":%ld.%ld,", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp/10, tmp%10); + strcat((char *)wifi_data, (char *)tmp_data); + //Showing only one Temperature from the same peripheral node + //tmp = (attr_value[9]<<8) | attr_value[8]; + //sprintf((char *)tmp_data, "\"Temperature2_0x%02x%02x\":%ld.%ld,", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp/10, tmp%10); + //strcat((char *)wifi_data, (char *)tmp_data); + tmp = (attr_value[11]<<8) | attr_value[10]; + sprintf((char *)tmp_data, "\"Temperature1_0x%02x%02x\":%ld.%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp/10, tmp%10); + strcat((char *)wifi_data, (char *)tmp_data); + } + else { /* ENV_DATA_LEN_SHORT (that is when using the Sensor Tile) */ + tmp = (attr_value[7]<<8) | attr_value[6]; + sprintf((char *)tmp_data, "\"Temperature1_0x%02x%02x\":%ld.%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp/10, tmp%10); + strcat((char *)wifi_data, (char *)tmp_data); + } + + + + + attribute_handle = slaveDev.star_data_char_handle; + + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { + /* + * Modify the attribute value according to the following format: + * Tstamp | Node ID | P Type ID | value | H Type ID | value | T Type ID | value | T Type ID | value | + * 2 bytes | 2 bytes | 1 byte | 4 bytes | 1 byte | 2 bytes | 1 byte | 2 bytes | 1 byte | 2 bytes | + */ + Create_New_Attr_Value(attr_value, devAddr, PRESS_TYPE_ID, attr_value+TSTAMP_LEN, data_length-TSTAMP_LEN); + if (data_length == ENV_DATA_LEN_LONG) { + slaveDev.notification_data.data_length = ATTR_HEAD_LEN+PRESS_DATA_LEN+(3*TYPE_ID_LEN)+HUM_DATA_LEN+(2*TEMP_DATA_LEN); + } + else { /* ENV_DATA_LEN_SHORT (that is when using the Sensor Tile) */ + slaveDev.notification_data.data_length = ATTR_HEAD_LEN+PRESS_DATA_LEN+TYPE_ID_LEN+TEMP_DATA_LEN; + } + + slaveDev.notification_data.attribute_value = star_attr_value; + memcpy(slaveDev.notification_data.devAddr, devAddr, 6); + slaveDev.notification_data.attribute_handle = attribute_handle; + } + + new_buffer = 1; + } + } + break; + + + + case READING_LED: + { + /* the status (0=OFF, 1=ON) */ + if (data_length != TSTAMP_LEN+LED_DATA_LEN) { + printf("\rLED Warning: received data length is %d (while expecting %d) - status=%d\n\n", data_length, (TSTAMP_LEN+LED_DATA_LEN), perDevs.status); + } + else { + tmp = attr_value[2]; + sprintf((char *)wifi_data, "\"LED_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); + + + attribute_handle = slaveDev.star_data_char_handle; + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { + /* + * Modify the attribute value according to the following format: + * Timestamp | Node ID | LED Type ID | value | + * 2 bytes | 2 bytes | 1 byte | 1 byte | + */ + Create_New_Attr_Value(attr_value, devAddr, LED_TYPE_ID, attr_value+TSTAMP_LEN, LED_DATA_LEN); + + slaveDev.notification_data.data_length = ATTR_HEAD_LEN+LED_DATA_LEN; + slaveDev.notification_data.attribute_value = star_attr_value; + memcpy(slaveDev.notification_data.devAddr, devAddr, 6); + slaveDev.notification_data.attribute_handle = attribute_handle; + } + new_buffer = 1; + } + } + break; + + + + case READING_MIC: + { + tmp = 0; /* fake value used to just notify the mic presence */ + sprintf((char *)wifi_data, "\"Mic1_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); + + attribute_handle = slaveDev.star_data_char_handle; + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { + uint8_t val = tmp; + /* + * Modify the attribute value according to the following format: + * Timestamp | Node ID | MIC Type ID | value | + * 2 bytes | 2 bytes | 1 byte | 1 byte | + */ + // STORE_LE_16(star_attr_value, (HAL_GetTick()>>3)); /* Timestamp */ + Create_New_Attr_Value(attr_value, devAddr, MICLEVEL_TYPE_ID, &val, MIC_DATA_LEN); + + slaveDev.notification_data.data_length = ATTR_HEAD_LEN+MIC_DATA_LEN; + slaveDev.notification_data.attribute_value = star_attr_value; + memcpy(slaveDev.notification_data.devAddr, devAddr, 6); + slaveDev.notification_data.attribute_handle = attribute_handle; + } + new_buffer = 1; + } + break; + + + + case READING_LUX: + { + /* Lux value */ + if (data_length != TSTAMP_LEN+LUX_DATA_LEN) { + printf("\rLUX Warning: received data length is %d (while expecting %d) - status=%d\n\n", data_length, (TSTAMP_LEN+LUX_DATA_LEN), perDevs.status); + } + else { + tmp = (attr_value[3]<<8) | attr_value[2]; + sprintf((char *)wifi_data, "\"LUX_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); + + attribute_handle = slaveDev.star_data_char_handle; + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { + /* + * Modify the attribute value according to the following format: + * Timestamp | Node ID | LUX Type ID | value | + * 2 bytes | 2 bytes | 1 byte | 2 bytes | + */ + Create_New_Attr_Value(attr_value, devAddr, LUX_TYPE_ID, attr_value+TSTAMP_LEN, LUX_DATA_LEN); + + slaveDev.notification_data.data_length = ATTR_HEAD_LEN+LUX_DATA_LEN; + slaveDev.notification_data.attribute_value = star_attr_value; + memcpy(slaveDev.notification_data.devAddr, devAddr, 6); + slaveDev.notification_data.attribute_handle = attribute_handle; + } + new_buffer = 1; + } + } + break; + + + + case READING_PRX: + { + /* the distance value in mm */ + tmp = 0; /* fake value used to just notify the prx presence */ + sprintf((char *)wifi_data, "\"PRX_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); + +// if (attr_value == NULL){ +// printf("\r\nattr_value == NULL\n"); +// }else{ +// printf("\r\nattr_value != NULL\n"); +// } + + attribute_handle = slaveDev.star_data_char_handle; + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { + uint8_t val[PRX_DATA_LEN]; + memcpy((void *)val, (void *)tmp, sizeof(val)); + /* + * Modify the attribute value according to the following format: + * Timestamp | Node ID | Proximity Type ID | value | + * 2 bytes | 2 bytes | 1 byte | 2 bytes | + */ + Create_New_Attr_Value(attr_value, devAddr, PRX_TYPE_ID, val, PRX_DATA_LEN); + + slaveDev.notification_data.data_length = ATTR_HEAD_LEN+PRX_DATA_LEN; + slaveDev.notification_data.attribute_value = star_attr_value; + memcpy(slaveDev.notification_data.devAddr, devAddr, 6); + slaveDev.notification_data.attribute_handle = attribute_handle; + } + new_buffer = 1; + } + break; + + + + case READING_DISCONNECTION: + { + /* Device disconnected */ + attribute_handle = slaveDev.star_data_char_handle; + /* + * Modify the attribute value according to the following format: + * Timestamp | Node ID | Status Type ID | + * 2 bytes | 2 bytes | 1 byte | + */ + Create_New_Attr_Value(attr_value, devAddr, STATUS_TYPE_ID, NULL, STATUS_DATA_LEN); + + slaveDev.notification_data.data_length = ATTR_HEAD_LEN+STATUS_DATA_LEN; + slaveDev.notification_data.attribute_value = star_attr_value; + memcpy(slaveDev.notification_data.devAddr, devAddr, 6); + slaveDev.notification_data.attribute_handle = attribute_handle; + + new_buffer = 1; + } + break; + + + + case READING_AGM: + { + /* the acceleration value in mg */ + tmp = 0; /* fake value used to just notify the agm presence */ + sprintf((char *)wifi_data, "\"AGM_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); + + attribute_handle = slaveDev.star_data_char_handle; + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { + uint8_t val[MEMS_DATA_LEN]; + memcpy((void *)val, (void *)tmp, sizeof(val)); + /* + * Modify the attribute value according to the following format: + * Timestamp | Node ID | ACC Type ID | value | GYR Type ID | value | MAG Type ID | value | + * 2 bytes | 2 bytes | 1 byte | 6 bytes | 1 byte | 6 bytes | 1 byte | 6 bytes | + */ + Create_New_Attr_Value(attr_value, devAddr, ACC_TYPE_ID, val, MEMS_DATA_LEN); + + slaveDev.notification_data.data_length = ATTR_HEAD_LEN+ACC_DATA_LEN+(2*TYPE_ID_LEN)+GYR_DATA_LEN+MAG_DATA_LEN; + slaveDev.notification_data.attribute_value = star_attr_value; + memcpy(slaveDev.notification_data.devAddr, devAddr, 6); + slaveDev.notification_data.attribute_handle = attribute_handle; + } + new_buffer = 1; + } + break; + + + + case READING_SFUSION: + { + /* the mems sensor fusion value */ + tmp = 0; /* fake value used to just notify the sensor fusion presence */ + sprintf((char *)wifi_data, "\"SFUSION_0x%02x%02x\":%ld", devAddr[NODE_ID_B2], devAddr[NODE_ID_B1], tmp); + + attribute_handle = slaveDev.star_data_char_handle; + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { + uint8_t val[3]; + memcpy((void *)val, (void *)tmp, sizeof(val)); + /* + * Modify the attribute value according to the following format: + * Timestamp | Node ID | SFUSION Type ID | value | + * 2 bytes | 2 bytes | 1 byte | 6 bytes | + */ + Create_New_Attr_Value(attr_value, devAddr, SFUSION_TYPE_ID, val, SFUSION_DATA_LEN); + + slaveDev.notification_data.data_length = ATTR_HEAD_LEN+SFUSION_DATA_LEN; + slaveDev.notification_data.attribute_value = star_attr_value; + memcpy(slaveDev.notification_data.devAddr, devAddr, 6); + slaveDev.notification_data.attribute_handle = attribute_handle; + } + new_buffer = 1; + } + break; + + + + default: + break; + + } + + + + if (new_buffer == 1){ + strcat((char *)wifi_data, "\n"); + printf("\r\n%s", (char *)wifi_data); /* print locally the buffer in JSON format */ + + data = wifi_data; + new_data = 1; + } + + + if (notificationPending == 1){ + readCompleted = 1; + Change_Notification_Status(notifyP->att_data, notifyP->attr_value, notifyP->conn_handle, notifyP->i, notifyP->feature_mask, notifyP->frequency); + notificationPending = 0; + } + + setNewStatus(); + readCompleted = 1; +} +/*----------------------------------------------------------------------------*/ + + + +/* This function retrieves the peripheral device index and address + * from the connection handle */ +void getDeviceFromConnHandle(uint16_t handle, uint8_t *index, tBDAddr devAddr){ + + //printf("\r\ngetDeviceFromConnHandle\n\n");//DEBUG + + uint8_t i; + + for (i=0; i<MAX_NUM_OF_NODES; i++){ + if (perDevs.connection_handle[i] == handle){ + memcpy(devAddr, perDevs.devInfo[i].bdaddr, 6); + *index = i; + break; + } + } +} +/*----------------------------------------------------------------------------*/ + + +/* Create a null gatt read pointer */ +GattReadCallbackParams * nullGattReadCallbackP(uint16_t connection_handle){ + GattReadCallbackParams gattReadCallbackParamsStruct, *pointer; + pointer = &gattReadCallbackParamsStruct; + + pointer->connHandle = connection_handle; + pointer->len = 0; + pointer->data = NULL; + + return pointer; + +} +/*----------------------------------------------------------------------------*/ + + + +void readingProcess(void) { + //printf("\r\nreadingProcess - status: %d - connDevices: %d\n", perDevs.status, perDevs.connDevices);//DEBUG + + + /* This index defines which peripheral is going to be read */ + uint8_t i = perDevs.readDeviceIdx; + //fetch the current connection handle + uint16_t connHandle = perDevs.connection_handle[i]; + + + + + if ((perDevs.status == NOTIFICATIONS_DATA_READ) && (perDevs.sfusion_event_enabled) && (!perDevs.sfusion_char_read[i])){ + perDevs.status = ALL_DATA_READ; + } + + + + //READ_INIT + if ((perDevs.status == READ_INIT)) { + if (perDevs.connDevices > 0) { + slaveDev.is_discoverable = true; + //printf("\r\nperDevs.connDevices > 0 (i=%d)\n", i);//DEBUG + perDevs.status = ALL_DATA_READ; + if (!perDevs.is_disconnected[i]) { + //printf("\r\n!perDevs.is_disconnected\n");//DEBUG + switch (perDevs.devInfo[i].dev_v) { + case NODE_ME1: + case NODE_AM1: + case NODE_FL1: + /* start to read sensors data from environmental */ + + if ((perDevs.mic_event_enabled) || (perDevs.prx_event_enabled) || (perDevs.agm_event_enabled) + || (perDevs.sfusion_event_enabled)){ + //printf("\r\nNotification event enabled, skip reading\n");//DEBUG + } else { + perDevs.status = READING_ENVIRONMENTAL; + } + break; + default: + break; + } + } + } else { + //printf("\r\nconnDevices: %d - status = CONN_INIT - ELSE readingProces\n", perDevs.connDevices);//DEBUG + perDevs.status = CONN_INIT; + } + }//if-READ_INIT + + + + + + + //ENVIRONMENTAL + if ((perDevs.status == READING_ENVIRONMENTAL) && (readCompleted == 1)) { + //reading is starting + readCompleted = 0; + //fetch the characteristic declHandle + uint16_t declHandle = perDevs.environmental_char_handle[i]; + //current data pointer + DiscoveredCharacteristic c = searchDCNode(headCharacteristic[i], declHandle)->data; + //pass characteristic and connection handle + readSensorData(c, connHandle, i); + + + }//if-ENVIRONMENTAL + + + + + + + + //NOTIFY_ENV_TO_CLIENT + if ((perDevs.status == NOTIFY_ENV_TO_CLIENT) && (writeDescriptorCompleted ==1)) { + //printf("\r\nNOTIFY_ENV_TO_CLIENT\n");//DEBUG + notifyMaster(slaveDev.notification_data.data_length, slaveDev.notification_data.attribute_value, + slaveDev.notification_data.attribute_handle); + eventQ.call(setNewStatus); + }//if-NOTIFY_ENV_TO_CLIENT + + + + + + + + //READING_LED + if ((perDevs.status == READING_LED) && (readCompleted == 1)) { + //reading is starting + readCompleted = 0; + //fetch the characteristic declHandle + uint16_t declHandle = perDevs.led_char_handle[i]; + //current data pointer + DiscoveredCharacteristic c = searchDCNode(headCharacteristic[i], declHandle)->data; + //pass characteristic and connection handle + readSensorData(c, connHandle, i); + } + + + + + + + //NOTIFY_LED_TO_CLIENT + if ((perDevs.status == NOTIFY_LED_TO_CLIENT) && (writeDescriptorCompleted ==1)) { + notifyMaster(slaveDev.notification_data.data_length, slaveDev.notification_data.attribute_value, + slaveDev.notification_data.attribute_handle); + eventQ.call(setNewStatus); + }//if-NOTIFY_LED_TO_CLIENT + + + + + + + //READING_LUX + if ((perDevs.status == READING_LUX) && (readCompleted == 1)) { + //reading is starting + readCompleted = 0; + //fetch the characteristic declHandle + uint16_t declHandle = perDevs.lux_char_handle[i]; + //current data pointer + DiscoveredCharacteristic c = searchDCNode(headCharacteristic[i], declHandle)->data; + //pass characteristic and connection handle + readSensorData(c, connHandle, i); + }//if-READING_LUX + + + + + + + //NOTIFY_LUX_TO_CLIENT + if ((perDevs.status == NOTIFY_LUX_TO_CLIENT) && (writeDescriptorCompleted ==1)) { + notifyMaster(slaveDev.notification_data.data_length, slaveDev.notification_data.attribute_value, + slaveDev.notification_data.attribute_handle); + eventQ.call(setNewStatus); + }//if-NOTIFY_LUX_TO_CLIENT + + + + + + + + //READING_MIC + if ((perDevs.status == READING_MIC) && (readCompleted == 1)){ + //reading is starting + readCompleted = 0; + HAL_Delay(300); + /* Sending a 0 value to master just to notify the MIC sensor presence */ + readCharacteristicCallback(nullGattReadCallbackP(connHandle)); + + perDevs.status = NOTIFY_MIC_TO_CLIENT; + notifyMaster(slaveDev.notification_data.data_length, slaveDev.notification_data.attribute_value, + slaveDev.notification_data.attribute_handle); + eventQ.call(setNewStatus); + }//if-READING_MIC + + + + + + + //READING_PRX + if ((perDevs.status == READING_PRX) && (readCompleted == 1) && (writeDescriptorCompleted ==1)) { + //reading is starting + readCompleted = 0; + HAL_Delay(300); + /* Sending a 0 value to master just to notify the PRX sensor presence */ + readCharacteristicCallback(nullGattReadCallbackP(connHandle)); + + perDevs.status = NOTIFY_PRX_TO_CLIENT; + notifyMaster(slaveDev.notification_data.data_length, slaveDev.notification_data.attribute_value, + slaveDev.notification_data.attribute_handle); + eventQ.call(setNewStatus); + }//if-READING_PRX + + + + + + + + //READING_AGM + if ((perDevs.status == READING_AGM) && (readCompleted == 1) && (writeDescriptorCompleted ==1)) { + //reading is starting + readCompleted = 0; + HAL_Delay(300); + /* Sending a 0 value to master just to notify the AGM sensors presence */ + readCharacteristicCallback(nullGattReadCallbackP(connHandle)); + + perDevs.status = NOTIFY_AGM_TO_CLIENT; + notifyMaster(slaveDev.notification_data.data_length, slaveDev.notification_data.attribute_value, + slaveDev.notification_data.attribute_handle); + eventQ.call(setNewStatus); + }//if-READING_AGM + + + + + + + //READING_SFUSION + if ((perDevs.status == READING_SFUSION) && (readCompleted == 1) && (writeDescriptorCompleted ==1)) { + //reading is starting + readCompleted = 0; + HAL_Delay(300); + /* Sending a 0 value to master just to notify the SFusion feature presence */ + readCharacteristicCallback(nullGattReadCallbackP(connHandle)); + + perDevs.status = NOTIFY_SFUSION_TO_CLIENT; + notifyMaster(slaveDev.notification_data.data_length, slaveDev.notification_data.attribute_value, + slaveDev.notification_data.attribute_handle); + eventQ.call(setNewStatus); + }//if-READING_SFUSION + + + + + + + + + + //ALL_DATA_READ + if ((perDevs.status == ALL_DATA_READ) && (readCompleted == 1) && (writeDescriptorCompleted ==1)) { + //printf("\r\nstatus: ALL_DATA_READ (%d)\n", perDevs.status);//DEBUG + if (i>0) { + perDevs.readDeviceIdx--; + } + perDevs.status = READ_INIT; + //printf("\r\nstatus: READ_INIT (%d) - readingProcess\n", perDevs.status);//DEBUG + + + // All peripherals are read! + if (i==0) { + + if ((slaveDev.is_connected == false) && (slaveDev.is_discoverable == true)) { +#if ENABLE_MEMS + disableAllNotifications(); /* Called here to disable the SFUSION notifications */ +#endif + setSlaveDiscoverable(); + + } else { + perDevs.status = CONN_INIT; + }//if-else-adv + + }//if-i=0 + }//if-ALL_DATA_READ + + + + + + + + //DISABLE_NOTIFICATIONS + if ((perDevs.status == DISABLE_NOTIFICATIONS) && (readCompleted == 1) && (writeDescriptorCompleted ==1)) { + //printf("\r\nperDevs.status == DISABLE_NOTIFICATIONS\n");//DEBUG + disableAllNotifications(); + perDevs.status = ALL_DATA_READ; + perDevs.readDeviceIdx = i; + + }//if-DISABLE_NOTIFICATIONS + + + + + + /* Start connection process */ + eventQ.call(connectionProcess); + +} +/*----------------------------------------------------------------------------*/ + + + +/* This method reads the characteristic in input */ +void readSensorData(const DiscoveredCharacteristic &characteristic, uint16_t connection_handle, uint8_t index){ + //printf("\r\nreadSensorData\n");//DEBUG + + ble_error_t error; + + + + + if (!perDevs.is_disconnected[index] && characteristic.getDeclHandle()){ +// printf("\r\n\nReading sensor data from periph %d (0x%04x - 0x%04x) - status=%d\n", index+1, +// connection_handle, characteristic.getDeclHandle(), perDevs.status);//DEBUG + + error = characteristic.read(); + + if (error != BLE_ERROR_NONE){ + printf("\r\n\nUnable to read data from periph %d (err %d, cHndl 0x%04x - dHdl 0x%04x)\n", index+1, + error, connection_handle, characteristic.getDeclHandle()); + + eventQ.call(setNewStatus); + readCompleted = 1; + }//if-failed + + + } else { + eventQ.call(setNewStatus); + + }//if-else-isConnected + +} +/*----------------------------------------------------------------------------*/ + + + +/* Set the new status */ +void setNewStatus(void) { + //printf("\r\nsetNewStatus\n");//DEBUG + + + uint8_t i = perDevs.readDeviceIdx; + + + //Switch status + switch (perDevs.status) { + + + + + + // + case ENABLE_ME1_LED_NOTIFICATIONS: + if (perDevs.wup_event[perDevs.connDeviceIdx]) { + perDevs.status = ENABLE_ME1_WUP_NOTIFICATIONS; + }else { + perDevs.status = NOTIFICATIONS_ENABLED; + } + break; + + + + + + + // + case ENABLE_ME1_WUP_NOTIFICATIONS: + perDevs.status = NOTIFICATIONS_ENABLED; + break; + + + + + + + + // + case READING_ENVIRONMENTAL: + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { + perDevs.status = NOTIFY_ENV_TO_CLIENT; + }else { + if ((perDevs.devInfo[i].dev_v == NODE_FL1) && (perDevs.prx_on[i]==0)) { + perDevs.status = READING_LUX; + }else { + //printf("\r\nstatus = ALL_DATA_READ (setNewStatus)\n"); + perDevs.status = ALL_DATA_READ; + } + }//if-MAIN + break; + + + + + + + + + // + case NOTIFY_ENV_TO_CLIENT: + + //NODE_FL1 + if (perDevs.devInfo[i].dev_v == NODE_FL1) { + + if (perDevs.prx_on[i]==0) { + perDevs.status = READING_LUX; + } + else if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && + (perDevs.prx_event[i]) && (!perDevs.prx_char_read[i])) { + //printf("\r\n----->if\n");//DEBUG + perDevs.status = READING_PRX; + } + +#if ENABLE_MEMS + else if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && + (perDevs.agm_event[i]) && (!perDevs.agm_char_read[i])) { + perDevs.status = READING_AGM; + } + else if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && + (perDevs.sfusion_event[i]) && (!perDevs.sfusion_char_read[i])) { + perDevs.status = READING_SFUSION; + } +#endif + else { + perDevs.status = ALL_DATA_READ; + } + }//if-NODE_FL1 + + + //NODE_ME1 + else if (perDevs.devInfo[i].dev_v == NODE_ME1) { + if (!perDevs.led_char_read[i]) { + perDevs.status = READING_LED; + } +#if ENABLE_MEMS + else if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && + (perDevs.agm_event[i]) && (!perDevs.agm_char_read[i])) { + perDevs.status = READING_AGM; + } + else if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && + (perDevs.sfusion_event[i]) && (!perDevs.sfusion_char_read[i])) { + perDevs.status = READING_SFUSION; + } +#endif + else { + perDevs.status = ALL_DATA_READ; + } + }//if-NODE_ME1 + + + //NODE_AM1 + else if (perDevs.devInfo[i].dev_v == NODE_AM1) { + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && + (perDevs.mic_event[i]) && (!perDevs.mic_char_read[i])) { + perDevs.status = READING_MIC; + } +#if ENABLE_MEMS + else if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && + (perDevs.agm_event[i]) && (!perDevs.agm_char_read[i])) { + perDevs.status = READING_AGM; + } + else if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && + (perDevs.sfusion_event[i]) && (!perDevs.sfusion_char_read[i])) { + perDevs.status = READING_SFUSION; + } +#endif + else { + perDevs.status = ALL_DATA_READ; + } + }//if-NODE_AM1 + break; + + + + + + + + // + case READING_LED: + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { + perDevs.status = NOTIFY_LED_TO_CLIENT; + }else { + perDevs.status = ALL_DATA_READ; + } + break; + + + + + + + + // + case NOTIFY_LED_TO_CLIENT: + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && + (!perDevs.led_char_read[i])) { + perDevs.led_char_read[i] = 1; + } +#if ENABLE_MEMS + else if (perDevs.agm_event[i]) { + perDevs.status = READING_AGM; + } +#endif + else { + perDevs.status = ALL_DATA_READ; + } + break; + + + + + + + + + // + case READING_LUX: + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify)) { + perDevs.status = NOTIFY_LUX_TO_CLIENT; + }else { + perDevs.status = ALL_DATA_READ; + } + break; + + + + + + + + + // + case NOTIFY_LUX_TO_CLIENT: + //printf("NOTIFY_LUX_TO_CLIENT");//DEBUG + if ((slaveDev.is_connected) && (slaveDev.star_data_char_notify) && + (perDevs.prx_event[i]) && (!perDevs.prx_char_read[i])) { + //printf("IF-LUX");//DEBUG + perDevs.status = READING_PRX; + }else { + perDevs.status = ALL_DATA_READ; + } + break; + + + + + + + + // + case NOTIFY_MIC_TO_CLIENT: + perDevs.mic_char_read[i] = 1; + +#if ENABLE_MEMS + if (perDevs.agm_event[i]) { + perDevs.status = READING_AGM; + } + else if (perDevs.sfusion_event[i]) { + perDevs.status = READING_SFUSION; + }else { + perDevs.status = ALL_DATA_READ; + } +#else + perDevs.status = ALL_DATA_READ; +#endif + break; + + + + + + + + // + case NOTIFY_PRX_TO_CLIENT: + perDevs.prx_char_read[i] = 1; + +#if ENABLE_MEMS + if (perDevs.agm_event[i]) { + perDevs.status = READING_AGM; + } + else if (perDevs.sfusion_event[i]) { + perDevs.status = READING_SFUSION; + }else { + perDevs.status = ALL_DATA_READ; + } +#else + perDevs.status = ALL_DATA_READ; +#endif + break; + + + + + + + + // + case NOTIFY_AGM_TO_CLIENT: + perDevs.agm_char_read[i] = 1; + if (perDevs.sfusion_event[i]) { + perDevs.status = READING_SFUSION; + }else { + perDevs.status = ALL_DATA_READ; + } + break; + + + + + + // + case NOTIFY_SFUSION_TO_CLIENT: + perDevs.sfusion_char_read[i] = 1; + perDevs.status = ALL_DATA_READ; + break; + + + + // + default: + break; + } +} +/*----------------------------------------------------------------------------*/ + + + +/* Creating a new DiscoveredCharacteristicNode */ +DiscoveredCharacteristicNode * createDCNode(const DiscoveredCharacteristic &ch, DiscoveredCharacteristicNode *next){ + + DiscoveredCharacteristicNode *newNode = (DiscoveredCharacteristicNode *)malloc(sizeof(DiscoveredCharacteristicNode)); + + if(newNode == NULL){ + printf("\r\nError creating a new node\n\n"); + } + newNode->data = ch; + newNode->next = next; + + return newNode; +} +/*----------------------------------------------------------------------------*/ + + + +/* Prepend a DiscoveredCharacteristicNode */ +DiscoveredCharacteristicNode * prependDCNode(DiscoveredCharacteristicNode *head, const DiscoveredCharacteristic *characteristic){ + + DiscoveredCharacteristicNode * newNode = createDCNode(*characteristic, head); + head = newNode; + + return head; +} +/*----------------------------------------------------------------------------*/ + + + +/* Append a DiscoveredCharacteristicNode */ +DiscoveredCharacteristicNode * appendDCNode(DiscoveredCharacteristicNode *head, const DiscoveredCharacteristic *characteristic){ + + DiscoveredCharacteristicNode * cursor = head; + // find the last node + while(cursor->next != NULL){ + cursor = cursor->next; + } + + DiscoveredCharacteristicNode * newNode = createDCNode(*characteristic, NULL); + cursor->next = newNode; + + return head; +} +/*----------------------------------------------------------------------------*/ + + + +/* Number of DiscoveredCharacteristic nodes */ +int countElements(DiscoveredCharacteristicNode *head){ + + DiscoveredCharacteristicNode * cursor = head; + + int c=0; + //cursor because starts from 0 + while (cursor != NULL){ + c++; + cursor = cursor->next; + } + + return c; +} +/*----------------------------------------------------------------------------*/ + + + +/* Search for a DiscoveredCharacteristic node by declaration handle */ +DiscoveredCharacteristicNode * searchDCNode(DiscoveredCharacteristicNode *head, uint16_t declHandle) { + + DiscoveredCharacteristicNode * cursor = head; + + while(cursor != NULL){ + + // search for declaration handle + if(cursor->data.getDeclHandle() == declHandle){ + return cursor; + } + cursor = cursor->next; + } + return NULL; +} +/*----------------------------------------------------------------------------*/ + + + +/* Delete the DCN list */ +void deleteDCNList(DiscoveredCharacteristicNode *head){ + + DiscoveredCharacteristicNode * cursor, *tmp; + + if (head != NULL){ + cursor = head->next; + head->next = NULL; + + while(cursor != NULL) { + tmp = cursor->next; + free(cursor); + cursor = tmp; + } + } +} +/*----------------------------------------------------------------------------*/