Firmware
Dependencies: BMI160 ADT7410 Thermistor DS1621 max32630fthr Adafruit_FeatherOLED
Diff: ble_functions.cpp
- Revision:
- 0:556294574340
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble_functions.cpp Thu Jul 09 15:56:48 2020 +0000 @@ -0,0 +1,1817 @@ +#include "functions.h" +#include "ble_functions.h" +#include "RawSerial.h" +#include <InterruptIn.h> +#include <InterruptManager.h> +#include "bmi160.h" +#include "max32630fthr.h" +#include "max3263x.h" +#include "MAX14690.h" +#include "ADT7410.h" +#include "Adafruit_SSD1306.h" +#include <BLE.h> +#include "ble/BLE.h" +#include "ble/Gap.h" +#include "ble/services/BatteryService.h" +#include "ble/blecommon.h" +#include "UUID.h" +#include "ble/gap/AdvertisingDataTypes.h" +#include "ble/gap/Types.h" +#include "SDBlockDevice.h" +#include "FATFileSystem.h" +#include <errno.h> +#include <stdio.h> +#include <time.h> +#include <stdint.h> + +extern char device_id[]; +extern unsigned short int measure_id; +extern unsigned short int log_id; + +extern Serial pan1326b; +extern DigitalOut bt_rst; + +extern volatile int conn_state; +extern bool in_BT; + +extern AnalogIn battery; + +extern DigitalOut r; +extern DigitalOut g; +extern DigitalOut b; +extern DigitalOut RGBs[]; + +extern MAX32630FTHR pegasus; + +extern ADT7410 myADT7410; +extern I2C i2cm2; +extern MAX14690 max14690; + +extern InterruptIn button; + +extern FATFileSystem fileSystem; +extern SDBlockDevice blockDevice; + +extern I2C i2c; +extern int sensor_temp; +extern Adafruit_SSD1306_I2c featherOLED; + +extern volatile int quit; +extern volatile int ble_return; +extern volatile int conn_state; +extern int counter_ble; + +extern bool error_status; +extern bool BT_error; +extern bool shipping; +extern bool pause; +extern bool init_status; +extern bool after_BT; +extern bool charge; + +extern Timeout after_BLE; +extern Timeout turnoff; +extern Timeout flipper; +extern Timeout advertise_cancel; +extern Timeout connected_cancel; +extern Ticker mess_timer; +extern Ticker ticker; +extern time_t now; +extern time_t raw; + +extern float buffer_temp; +extern struct tm current; +extern struct tm actual; + +extern struct user_config_struct user_config_para; +extern struct tm user_config_time; + +extern Timeout done_rcv; + +extern int next_state; + +extern int unsigned long t_diff; +extern int unsigned long unix_time; + +extern int default_advertise_time; +extern int default_connected_time; + +extern int alert_count; + +int ble_buff_line = 0; +char ble_buff[1024][64]; + +char response = '0'; +char messungen[7]; +int messwerte[5000]; +char logs_array[7]; +char seconds[12]; +float min_temp = 0; +float max_temp = 0; +float avr_temp = 0; +unsigned short counter_m = 0; +unsigned short counter_l = 0; +int sendLedCounter = 0; + +//const static char* SERVICE_UUID = "32372fb9-5f73-4c32-a17b-25e17f52a99a"; +static uint8_t service_data[16]; + +//const static char* CHARACTERISTIC_UUID = "1d6ba3db-d405-4034-96fc-78942ef7075f"; + +uint16_t customServiceUUID = 0xA000; +uint16_t readCharUUID = 0xA001; +uint16_t writeCharUUID = 0xA002; +uint16_t battService = 0x180F; + +const static char DEVICE_NAME[] = "Cold Chain Logger"; + +static const uint16_t uuid16_list[] = {0xFFFF}; +//static const uint8_t advData[26]; + +//UUID service_uuid = UUID(SERVICE_UUID); +//UUID characteristic_uuid = UUID(CHARACTERISTIC_UUID); + +//Gap::ConnectionParams_t fast; + +// Set Up custom Charatiristics +static uint8_t readValue[360]; +//ReadOnlyArrayGattCharacteristic<uint8_t, sizeof(readValue)> readChar(readCharUUID, readValue); +ReadOnlyArrayGattCharacteristic<uint8_t, sizeof(readValue)> readChar(readCharUUID, readValue, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY ,NULL,0); + +static uint8_t writeValue[20]; +//WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(writeValue)> writeChar(writeCharUUID, writeValue); +WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(writeValue)> writeChar(writeCharUUID, writeValue, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE ,NULL,0); + +// Set up custom service +GattCharacteristic *characteristics[] = {&readChar, &writeChar}; +GattService customService(customServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *)); + +//Battery service +uint8_t batteryLevel = 50; +static BatteryService* batteryServicePtr; + +void periodicCallback(void) +{ + b = !b; +} + +void writeLedCallback(void) +{ + b = !b; + ticker.detach(); +} + +void sendLedCallback(void) +{ + b = !b; + if(sendLedCounter == 2){ + ticker.detach(); + sendLedCounter = 0; + }else{ + sendLedCounter++; + } +} + +void clear_buffer(){ + if(response != 's'){ + counter_m = 0; + }else if(response != 'l'){ + counter_l = 0; + } + ble_buff_line = 0; + memset(&ble_buff[0][0], 0, sizeof(ble_buff)); + memset(&readValue[0], 0, sizeof(readValue)); + memset(&writeValue[0], 0, sizeof(writeValue)); +} + +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *) +{ + printf("\nDisconnection callback\n"); + clear_buffer(); + connected_cancel.detach(); + ticker.attach(periodicCallback, 0.5); + advertise_cancel.attach(&BT_false, user_config_para.advertise); + char string[] = "Bluetooth disconnected"; + write_to_sd_log_single(string); + conn_state = 0; + counter_m = 0; + counter_l = 0; + BLE::Instance(BLE::DEFAULT_INSTANCE).startAdvertising(); + printf("\nAdvertising\n"); +} + +void updateSensorValue() { + float batteryProcent = (100 / 0.271) * (battery.read() - 0.704); + if(batteryProcent > 97){ + batteryProcent = 100; + } + batteryLevel = batteryProcent; + batteryServicePtr->updateBatteryLevel(batteryProcent); +} + +void printMacAddress() +{ + Gap::AddressType_t addr_type; + Gap::Address_t address; + BLE::Instance().gap().getAddress(&addr_type, address); + printf("Device MAC address: "); + for (int i = 5; i >= 1; i--){ + printf("%02x:", address[i]); + } + printf("%02x\r\n", address[0]); +} + +void writeCharCallback(const GattWriteCallbackParams *params) +{ + printf("\nData received\n"); + //b = 1; + //ticker.attach(writeLedCallback, 0.5); + memset(&readValue[0], 0, sizeof(readValue)); + memset(&writeValue[0], 0, sizeof(writeValue)); + BLE::Instance(BLE::DEFAULT_INSTANCE).gattServer().write(readChar.getValueHandle(), params->data, params->len); + for(int i = 0; i < 15; i++){ + ble_buff[0][i + ble_buff_line] = readValue[i]; + } + printf("\n%s received (ble_buff)", ble_buff[0]); + ble_buff_line = ble_buff_line + 15; + if(readValue[0] > 0x60 && readValue[0] < 0x7a){ + response = readValue[0]; + }else if(response != 's' && response != 'l' && response != 'e' && response != 't'){ + clear_buffer(); + } + printf("\nresponse: %c\n", response); +} + +void disconnect(){ + Gap::DisconnectionReason_t res=Gap::LOCAL_HOST_TERMINATED_CONNECTION; + BLE::Instance(BLE::DEFAULT_INSTANCE).gap().disconnect(res); +} + +void whenConnected(const Gap::ConnectionCallbackParams_t *) +{ + printf("\nConnected\n"); + advertise_cancel.detach(); + ticker.detach(); + connected_cancel.attach(&disconnect, user_config_para.connected); + conn_state = 1; + if(error_status == true){ + r = 1; + } + b = 0; + response = '0'; + char string[] = "Bluetooth connected"; + write_to_sd_log_single(string); +} + +void onDataSent(unsigned count) +{ + printf("%c", ble_buff[ble_buff_line][count]); + readValue[count] = ble_buff[ble_buff_line][count]; +} + +void after_BL(){ + after_BT = false; + after_BLE.detach(); +} + +void BT_false() +{ + BLE &ble = BLE::Instance(); + in_BT = false; + b = 1; + conn_state = 0; + quit = 0; + clear_buffer(); + ticker.detach(); + advertise_cancel.detach(); + connected_cancel.detach(); + disconnect(); + wait(0.5); + if(error_status == true){ + r = 0; + } + if(shipping == true && pause == false){ + mess_timer.attach(&mess_handler, (float)user_config_para.interval); + } + after_BT = true; + after_BLE.attach(after_BL, 1); + response = '0'; +} + +void BT_true() +{ + in_BT = true; + next_state = 2; +} + +void log_count(){ + fileSystem.unmount(); + fflush(stdout); + + fileSystem.mount(&blockDevice); + FILE * log = fopen ("/fs/log.csv", "rb"); + + int ch = 0; + int lines = 0; + + while(!feof(log)){ + ch = fgetc(log); + if(ch == '\n') + { + lines++; + } + } + + log_id = lines; + + fclose(log); + fileSystem.unmount(); + + sprintf(logs_array,"%d", lines); +} + +void messdaten_count(){ + fileSystem.unmount(); + fflush(stdout); + + fileSystem.mount(&blockDevice); + FILE * messdaten = fopen ("/fs/messdaten.csv", "rb"); + + int ch = 0; + int lines = 0; + + while(!feof(messdaten)){ + ch = fgetc(messdaten); + if(ch == '\n') + { + lines++; + } + } + + fclose(messdaten); + fileSystem.unmount(); + + measure_id = lines; + + sprintf(messungen,"%d", lines); +} + +void unixtime_to_char_array(){ + tm *current; + time(&now); + current = localtime (&now); + printf ("\nDate: 20%02d-%02d-%02d %02d:%02d:%02d\r\n", current->tm_year - 100, current->tm_mon + 1, current->tm_mday, current->tm_hour, current->tm_min, current->tm_sec); + + printf("\nSekunden als Dezimal: %d\n", time(&now)); + + sprintf(seconds,"%d", time(&now)); + + printf("\nSekunden als String: %s\n", seconds); +} + +int array_to_int(int z){ + int zahl[z]; + + for(int i = 0; i < z; i++){ + zahl[i] = readValue[i]; + zahl[i] = zahl[i] - 48; + } + + unsigned long ganzes = 0; + unsigned long log = 1; + int j = z; + do{ + j--; + ganzes = ganzes + log * zahl[j]; + log = log * 10; + }while(j > 0); + + if((int)ganzes < 0){ + ganzes = 0; + } + return ganzes; +} + +void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) +{ + BLE &ble = params->ble; + ble_error_t error = params->error; + + if (error != BLE_ERROR_NONE) { + return; + } + + read_id(); + + /* Setup advertising */ + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); // BLE only, no classic BT + ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); // advertising type + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); // add name + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::DEVICE_ID, (uint8_t *)device_id, 5); // add name + //ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); // UUID's broadcast in advertising packet + ble.gap().setAdvertisingInterval(100); // 100ms. + + /* Add custom service */ + ble.gattServer().addService(customService); + + /* Add battery service */ + batteryServicePtr = new BatteryService(ble, batteryLevel); + + ble.gap().onDisconnection(disconnectionCallback); + ble.gap().onConnection(whenConnected); + ble.gattServer().onDataWritten(writeCharCallback); + ble.gattServer().onDataSent(onDataSent); + + /* Start advertising */ + ble.gap().startAdvertising(); +} + +void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { + BLE &ble = BLE::Instance(); + updateSensorValue(); +} + +void dataSentSend(){ + response = '0'; + connected_cancel.attach(&disconnect, user_config_para.connected); +} + +void dataSent(){ + //wait(1); + //b = 1; + //ticker.attach(sendLedCallback, 0.5); + response = '0'; + connected_cancel.attach(&disconnect, user_config_para.connected); +} + +void swap(int num1, int num2){ + int temp = messwerte[num1]; + messwerte[num1] = messwerte[num2]; + messwerte[num2] = temp; +} + +int partition(int left, int right, int pivot){ + int leftPointer = left - 1; + int rightPointer = right; + + while(true){ + while(messwerte[++leftPointer] < pivot){ + //do nothing + } + + while(rightPointer > 0 && messwerte[--rightPointer] > pivot){ + //do nothing + } + + if(leftPointer >= rightPointer){ + break; + }else{ + swap(leftPointer, rightPointer); + } + } + swap(leftPointer, right); + + return leftPointer; +} + +void quickSort(int left, int right){ + if(right - left <= 0){ + return; + }else{ + int pivot = messwerte[right]; + int partionPoint = partition(left, right, pivot); + quickSort(left, partionPoint - 1); + quickSort(partionPoint + 1, right); + } +} + +void BLE_handler() +{ + BLE &ble = BLE::Instance(); + b = 0; + ticker.attach(periodicCallback, 0.5); + advertise_cancel.attach(&BT_false, user_config_para.advertise); + clear_buffer(); + next_state = 0; + printf("\nBLE - ON\n"); + printf("\nAdvertising\n"); + + while( quit ) + { + ble.waitForEvent(); + ble.onEventsToProcess(scheduleBleEventsProcessing); + + while ( conn_state ) //Abfrage zum Verbindungsstatus + { + ble.waitForEvent(); + ble.onEventsToProcess(scheduleBleEventsProcessing); + + /* + if(readValue[0] == NULL){ + ble.onEventsToProcess(scheduleBleEventsProcessing); + } + */ + + switch ( response ) + { + /* + case 's': // Messwerte übertragen + { + connected_cancel.detach(); + clear_buffer(); + + unsigned int length = 0; + + connected_cancel.attach(&disconnect, user_config_para.connected); + while(readValue[0] == NULL || readValue[0] < 0x31|| readValue[0] > 0x39){ + clear_buffer(); + ble.waitForEvent(); + if(conn_state == 0){ + break; + } + } + connected_cancel.detach(); + if(conn_state == 1){ + int a = 0; + while(readValue[a] != NULL){ + a++; + } + int id = array_to_int(a); + clear_buffer(); + + fileSystem.mount(&blockDevice); + FILE * messdaten = fopen ("/fs/messdaten.csv", "rb"); + + fseek (messdaten, 0, SEEK_END); + length = ftell (messdaten); + fseek (messdaten, 0, SEEK_SET); + + if(id > measure_id){ + printf("\nMeasuremnt ID %d doesn't exist!\n", id); + char string[] = "Call of an inexistent measurement ID"; + write_to_sd_log_single(string); + + ble_buff[0][0] = '0'; + onDataSent(0); + }else{ + unsigned long ch = 0; + unsigned long lines = 0; + unsigned long i = 0; + unsigned long j = 1; + unsigned long c = 0; + + if(id == 1){ + fseek(messdaten, 0, SEEK_SET); + }else{ + while((id - 1) != lines){ + ch = fgetc(messdaten); + if(ch == '\n'){ + lines++; + } + i++; + } + fseek(messdaten, i, SEEK_SET); + c = i; + } + if(id == measure_id){ + while(fgetc(messdaten) != EOF){ + i++; + j++; + } + }else{ + while(fgetc(messdaten) != '\n'){ + i++; + j++; + } + } + fseek(messdaten, c, SEEK_SET); + fread (ble_buff[ble_buff_line], 1, j, messdaten); + + for(int l = 0; l < j; l++){ + onDataSent(l); + } + } + + fclose(messdaten); + fileSystem.unmount(); + fflush(stdout); + + dataSentSend(); + } + break; + } + */ + + case 's': // Messwerte übertragen + { + connected_cancel.detach(); + clear_buffer(); + + if(counter_m == 0){ + char string[] = "Command 's' (send measuremnts) received"; + write_to_sd_log_single(string); + } + + connected_cancel.attach(&disconnect, user_config_para.connected); + while(readValue[0] == NULL || readValue[0] < 0x31|| readValue[0] > 0x39){ + clear_buffer(); + ble.waitForEvent(); + if(conn_state == 0){ + break; + } + } + connected_cancel.detach(); + if(conn_state == 1){ + + if(counter_m == 0){ + char string1[] = "Sending measuremnts..."; + write_to_sd_log_single(string1); + } + + int a = 0; + while(readValue[a] != NULL){ + a++; + } + int id = array_to_int(a); + clear_buffer(); + + fileSystem.mount(&blockDevice); + FILE * messdaten = fopen ("/fs/messdaten.csv", "rb"); + + /* Daten senden */ + + if(id > measure_id){ + printf("\nMeasuremnt ID %d doesn't exist!\n", id); + char string[] = "Call of an inexistent measurement ID"; + write_to_sd_log_single(string); + + ble_buff[0][0] = '0'; + onDataSent(0); + }else{ + unsigned long ch = 0; + unsigned long lines = 0; + unsigned long i = 0; + unsigned long j = 1; + unsigned long c = 0; + + if(id == 1){ + fseek(messdaten, 0, SEEK_SET); + }else{ + while((id - 1) != lines){ + ch = fgetc(messdaten); + if(ch == '\n'){ + lines++; + } + i++; + } + fseek(messdaten, i, SEEK_SET); + c = i; + } + if(id == measure_id){ + while(fgetc(messdaten) != EOF){ + i++; + j++; + } + }else{ + int y = 0; + while(y < 10){ + i++; + j++; + ch = fgetc(messdaten); + if(ch == '\n'){ + y++; + } + if(ch == EOF){ + break; + } + } + i--; + j--; + } + fseek(messdaten, c, SEEK_SET); + fread (ble_buff[ble_buff_line], 1, j, messdaten); + + for(int l = 0; l < j; l++){ + onDataSent(l); + } + } + + fclose(messdaten); + fileSystem.unmount(); + fflush(stdout); + + counter_m += 10; + if(counter_m >= measure_id){ + char string2[] = "Sending measuremnts complete"; + write_to_sd_log_single(string2); + counter_m = 0; + dataSent(); + }else{ + dataSentSend(); + } + } + break; + } + + case 'g': //Config senden + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'g' (send config settings) received"; + write_to_sd_log_single(string); + + unsigned int length = 0; + + char string_1[] = "Sending config.."; + write_to_sd_log_single(string_1); + + fileSystem.mount(&blockDevice); + FILE * user_config = fopen ("/fs/user_config.csv", "rb"); + + fseek (user_config, 0, SEEK_END); + length = ftell (user_config); + fseek (user_config, 0, SEEK_SET); + + fread (ble_buff, 1, length, user_config); + + fclose(user_config); + fileSystem.unmount(); + + fflush(stdout); + + for(int i = 0; i < length; i++){ + onDataSent(i); + } + + char string_2[] = "Sending config complete"; + write_to_sd_log_single(string_2); + + dataSent(); + + break; + } + + case 'c': // Config auf Werkeinstellungen zurücksetzen + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'c' (reset config to standard) received"; + write_to_sd_log_single(string); + + if(load_standard_config() == 1){ + char string[] = "Config reseted to factory settings"; + write_to_sd_log_single(string); + + ble_buff[0][0] = '1'; + onDataSent(0); + }else{ + char string[] = "Failed to reset Config to factory settings"; + write_to_sd_log_single(string); + + ble_buff[0][0] = '0'; + onDataSent(0); + } + + dataSent(); + + break; + } + + case 'd': // Messwerte löschen + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'd' (delete measurement data) received"; + write_to_sd_log_single(string); + + if(delete_file_messdaten() == 1){ + char string_1[] = "Measuerements deleted succesfully"; + write_to_sd_log_single(string_1); + + ble_buff[0][0] = '1'; + onDataSent(0); + }else{ + char string_1[] = "Measuerements data delete failed"; + write_to_sd_log_single(string_1); + + ble_buff[0][0] = '0'; + onDataSent(0); + } + + dataSent(); + + break; + } + /* + case 'l': //Log-Datei übertragen + { + + connected_cancel.detach(); + clear_buffer(); + + unsigned int length = 0; + + connected_cancel.attach(&disconnect, user_config_para.connected); + while(readValue[0] == NULL || readValue[0] < 0x31|| readValue[0] > 0x39){ + clear_buffer(); + ble.waitForEvent(); + if(conn_state == 0){ + break; + } + } + connected_cancel.detach(); + if(conn_state == 1){ + int a = 0; + while(readValue[a] != NULL){ + a++; + } + int id = array_to_int(a); + clear_buffer(); + + fileSystem.mount(&blockDevice); + FILE * log = fopen ("/fs/log.csv", "rb"); + + fseek (log, 0, SEEK_END); + length = ftell (log); + fseek (log, 0, SEEK_SET); + + + + if(id > log_id){ + printf("\nLog ID %d doesn't exist!\n", id); + char string[] = "Call of an inexistent log ID"; + write_to_sd_log_single(string); + + ble_buff[0][0] = '0'; + onDataSent(0); + }else{ + unsigned long ch = 0; + unsigned long lines = 0; + unsigned long i = 0; + unsigned long j = 1; + unsigned long c = 0; + + if(id == 1){ + fseek(log, 0, SEEK_SET); + }else{ + while((id - 1) != lines){ + ch = fgetc(log); + if(ch == '\n'){ + lines++; + } + i++; + } + fseek(log, i, SEEK_SET); + c = i; + } + if(id == log_id){ + while(fgetc(log) != EOF){ + i++; + j++; + } + }else{ + while(fgetc(log) != '\n'){ + i++; + j++; + } + } + fseek(log, c, SEEK_SET); + fread (ble_buff[ble_buff_line], 1, j, log); + + for(int l = 0; l < j; l++){ + onDataSent(l); + } + } + + fclose(log); + fileSystem.unmount(); + fflush(stdout); + + dataSentSend(); + } + break; + } + */ + + case 'l': //Log-Datei übertragen + { + connected_cancel.detach(); + clear_buffer(); + + if(counter_l == 0){ + char string[] = "Command 'l' (send logs) received"; + write_to_sd_log_single(string); + } + + connected_cancel.attach(&disconnect, user_config_para.connected); + while(readValue[0] == NULL || readValue[0] < 0x31|| readValue[0] > 0x39){ + clear_buffer(); + ble.waitForEvent(); + if(conn_state == 0){ + break; + } + } + connected_cancel.detach(); + if(conn_state == 1){ + + if(counter_l == 0){ + char string1[] = "Sending logs..."; + write_to_sd_log_single(string1); + } + + int a = 0; + while(readValue[a] != NULL){ + a++; + } + int id = array_to_int(a); + clear_buffer(); + + fileSystem.mount(&blockDevice); + FILE * log = fopen ("/fs/log.csv", "rb"); + + /* Daten senden */ + + if(id > log_id){ + printf("\nLog ID %d doesn't exist!\n", id); + char string[] = "Call of an inexistent log ID"; + write_to_sd_log_single(string); + + ble_buff[0][0] = '0'; + onDataSent(0); + }else{ + unsigned long ch = 0; + unsigned long lines = 0; + unsigned long i = 0; + unsigned long j = 1; + unsigned long c = 0; + + if(id == 1){ + fseek(log, 0, SEEK_SET); + }else{ + while((id - 1) != lines){ + ch = fgetc(log); + if(ch == '\n'){ + lines++; + } + i++; + } + fseek(log, i, SEEK_SET); + c = i; + } + if(id == log_id){ + while(fgetc(log) != EOF){ + i++; + j++; + } + }else{ + int y = 0; + while(y < 5){ + i++; + j++; + ch = fgetc(log); + if(ch == '\n'){ + y++; + } + if(ch == EOF){ + break; + } + } + i--; + j--; + } + fseek(log, c, SEEK_SET); + fread (ble_buff[ble_buff_line], 1, j, log); + + for(int l = 0; l < j; l++){ + onDataSent(l); + } + } + + fclose(log); + fileSystem.unmount(); + fflush(stdout); + + counter_l += 5; + if(counter_l >= measure_id){ + char string2[] = "Sending logs complete"; + write_to_sd_log_single(string2); + counter_l = 0; + dataSent(); + }else{ + dataSentSend(); + } + } + break; + } + + case 'r': // Log Datei löschen + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'r' (delete log file) received"; + write_to_sd_log_single(string); + + if(delete_file_log() == 1){ + char string_1[] = "Log file deleted"; + write_to_sd_log_single(string_1); + + ble_buff[0][0] = '1'; + onDataSent(0); + }else{ + char string_1[] = "Log file delete failed"; + write_to_sd_log_single(string_1); + + ble_buff[0][0] = '0'; + onDataSent(0); + } + + dataSent(); + + break; + } + + case 'n': //Reset + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'n' (reboot) received"; + write_to_sd_log_single(string); + BT_false(); + wait(0.5); + reboot(); + break; + } + + case 'w': // Werkeinstellungen + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'w' (reset to factory settings) received"; + write_to_sd_log_single(string); + + if(delete_file_messdaten() && load_standard_config() && delete_file_log() == 1){ + char string_1[] = "System reseted to factory settings"; + write_to_sd_log_single(string_1); + + ble_buff[0][0] = '1'; + onDataSent(0); + + printf("\n__________________________\n\nColdchainlogger reseted \nto factory settings\n__________________________\n\n"); + }else{ + char string_1[] = "System reset to factory settings failed"; + write_to_sd_log_single(string_1); + + ble_buff[0][0] = '0'; + onDataSent(0); + } + + dataSent(); + + break; + } + + case 'a': // Datenaufnahme pausieren / stoppen + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'a' (pause / stop measurement) received"; + write_to_sd_log_single(string); + + mess_timer.detach(); + next_state = 0; + + if(pause == true){ + char string_1[] = "Measurement stopped"; + write_to_sd_log_single(string_1); + printf("\nMeasurement stopped\n"); + shipping = false; + + ble_buff[0][0] = '0'; + onDataSent(0); + }else{ + pause = true; + char string_1[] = "Measurement paused"; + write_to_sd_log_single(string_1); + printf("\nMeasurement puased\n"); + + ble_buff[0][0] = '1'; + onDataSent(0); + } + + mess_timer.detach(); + + dataSent(); + + break; + } + + case 'f': // Datenaufnahme starten / fortsetzen + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'f' (start / continue measurement) received"; + write_to_sd_log_single(string); + + if(shipping == false){ + char string_1[] = "Measurement started"; + write_to_sd_log_single(string_1); + shipping = true; + pause = false; + + if(user_config_para.wait_mode == 1){ + next_state = 3; + }else{ + next_state = 1; + } + printf("\nMeasurement started\n"); + + ble_buff[0][0] = '1'; + onDataSent(0); + }else{ + next_state = 1; + char string_1[] = "Measurement continued"; + write_to_sd_log_single(string_1); + printf("\nMeasurement continued\n"); + pause = false; + + ble_buff[0][0] = '0'; + onDataSent(0); + } + + dataSent(); + + break; + } + + case 'e': //Config erhalten + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'e' (receive and overwrite config) received"; + write_to_sd_log_single(string); + + connected_cancel.attach(&disconnect, user_config_para.connected); + printf("\nReady to receive new config settings\n"); + + while(readValue[0] == NULL){ + ble.waitForEvent(); + if(conn_state == 0){ + break; + } + } + memset(&readValue[0], 0, sizeof(readValue)); + memset(&writeValue[0], 0, sizeof(writeValue)); + while(readValue[0] == NULL){ + ble.waitForEvent(); + if(conn_state == 0){ + break; + } + } + connected_cancel.detach(); + if(conn_state == 1){ + char params[50]; + printf("\n%s\n", ble_buff[0]); + strcpy(params, ble_buff[0]); + + if(create_user_config(params) == 1){ + clear_buffer(); + + char string_1[] = "User config changed"; + write_to_sd_log_single(string_1); + printf("\n__________________________\n\nUser config changed\n__________________________\n\n"); + + ble_buff[0][0] = '1'; + onDataSent(0); + }else{ + clear_buffer(); + + char string_1[] = "Changing user config failed"; + write_to_sd_log_single(string_1); + printf("\n__________________________\n\n!!! Error, can't changing user config !!!\n__________________________\n\n"); + + ble_buff[0][0] = '0'; + onDataSent(0); + } + + dataSent(); + } + break; + } + + case 'x': // Verbindung beenden + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'x' (shut down bluetooth) received"; + write_to_sd_log_single(string); + + BT_false(); + char string_1[] = "Bluetooth shuted down"; + write_to_sd_log_single(string_1); + printf("\n\nBluetooth shuted down\n\n"); + + dataSentSend(); + clear_buffer(); + + break; + } + + case 'b': //Akku-Zustand + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'b' (send battery info) received"; + write_to_sd_log_single(string); + + updateSensorValue(); + int battery = (int)batteryLevel; + char bat[3]; + sprintf(bat,"%d", battery); + int i = 0; + while(bat[i] != NULL){ + ble_buff[0][i] = bat[i]; + onDataSent(i); + i++; + } + printf("\nBattery level: %d %%\n", battery); + + dataSent(); + + break; + } + + case 'm': //Speicher-Belegung + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'm' (send memmory info) received"; + write_to_sd_log_single(string); + + printf("\nTotal SD memory: %llu Bytes\n", blockDevice.size()); + + unsigned long long length = 0; + + //ID Größe + fileSystem.mount(&blockDevice); + FILE * id = fopen ("/fs/id.csv", "rb"); + + fseek (id, 0, SEEK_END); + length = ftell (id); + fseek (id, 0, SEEK_SET); + + fclose(id); + fileSystem.unmount(); + fflush(stdout); + + unsigned long long idn = length; + length = 0; + + //Log Größe + fileSystem.mount(&blockDevice); + FILE * log = fopen ("/fs/log.csv", "rb"); + + fseek (log, 0, SEEK_END); + length = ftell (log); + fseek (log, 0, SEEK_SET); + + fclose(log); + fileSystem.unmount(); + fflush(stdout); + + unsigned long long logs = length; + length = 0; + + //Messdaten Größe + fileSystem.mount(&blockDevice); + FILE * messdaten = fopen ("/fs/messdaten.csv", "rb"); + + fseek (messdaten, 0, SEEK_END); + length = ftell (messdaten); + fseek (messdaten, 0, SEEK_SET); + + fclose(messdaten); + fileSystem.unmount(); + fflush(stdout); + + unsigned long long mes = length; + length = 0; + + //Standard Config Größe + fileSystem.mount(&blockDevice); + FILE * stcf = fopen ("/fs/standard_config.csv", "rb"); + + fseek (stcf, 0, SEEK_END); + length = ftell (stcf); + fseek (stcf, 0, SEEK_SET); + + fclose(stcf); + fileSystem.unmount(); + fflush(stdout); + + unsigned long long stcfg = length; + length = 0; + + //User Config Größe + fileSystem.mount(&blockDevice); + FILE * uscf = fopen ("/fs/user_config.csv", "rb"); + + fseek (uscf, 0, SEEK_END); + length = ftell (uscf); + fseek (uscf, 0, SEEK_SET); + + fclose(uscf); + fileSystem.unmount(); + fflush(stdout); + + unsigned long long uscfg = length; + length = 0; + + printf("\nID size: %llu Bytes\n", idn); + printf("Logs size: %llu Bytes\n", logs); + printf("Standard config size: %llu Bytes\n", stcfg); + printf("User config size: %llu Bytes\n\n", uscfg); + + unsigned long long not_measuremnts = idn + logs + stcfg + uscfg; + unsigned long long actual_size = blockDevice.size() - not_measuremnts; + printf("Available SD memory (100 %%) = total SD memory - configs & id (%llu Bytes) - logs\n", not_measuremnts); + printf("Available SD memory (100 %%): %llu Bytes\n\n", actual_size); + + messdaten_count(); + printf("Measuremnts count: %s\n", messungen); + printf("Measurements size: %llu Bytes\n\n", mes); + + double hundert = 100; + double occupied = hundert / actual_size * mes; + printf("Occupied memory: %f %%\n", occupied); + + double free_mem = 100 - occupied; + printf("Available memory: %f %%\n", free_mem); + + char occ[3]; + char free[3]; + + if((int)occupied != 0){ + occupied = ceil( occupied * 100.0 ) / 100.0; + } + if((int)free_mem != 0){ + free_mem = ceil( free_mem * 100.0 ) / 100.0; + } + + sprintf(occ,"%d", (int)occupied); + sprintf(free,"%d", (int)free_mem); + + printf("OCC: %s\n", occ); + printf("FREE: %s\n", free); + + messdaten_count(); + + int i = 0; + while(i < messungen[i] != NULL){ + ble_buff[0][i] = messungen[i]; + onDataSent(i); + i++; + } + ble_buff[0][i] = 0x3B; + onDataSent(i); + i++; + int j = 0; + while(j < occ[j] != NULL){ + ble_buff[0][i] = occ[j]; + onDataSent(i); + i++; + j++; + } + ble_buff[0][i] = 0x3B; + onDataSent(i); + i++; + int c = 0; + while(c < free[c] != NULL){ + ble_buff[0][i] = free[c]; + onDataSent(i); + i++; + c++; + } + ble_buff[0][i] = 0x3B; + onDataSent(i); + i++; + dataSent(); + + break; + } + + case 'i': //ID auslesen + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'i' (send ID) received"; + write_to_sd_log_single(string); + + char string_1[] = "Sending device ID..."; + write_to_sd_log_single(string_1); + + printf("\nDevice ID: %s\n", device_id); + + int i = 0; + while(device_id[i] != NULL){ + ble_buff[0][i] = device_id[i]; + onDataSent(i); + i++; + } + + char string_2[] = "Sending device ID complete"; + write_to_sd_log_single(string_2); + + dataSent(); + + break; + } + + case 'z': //Hardware Module abfragen + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'z' (send connected devices) received"; + write_to_sd_log_single(string); + + char string_1[] = "Sending connected devices..."; + write_to_sd_log_single(string_1); + + printf("\nConnected devices: Temperature sensor\n"); + + char sensor[4] = {'0', '0', '1'}; + int i = 0; + while(sensor[i] != NULL){ + ble_buff[0][i] = sensor[i]; + onDataSent(i); + i++; + } + + char string_2[] = "Sending connected devices complete"; + write_to_sd_log_single(string_2); + + dataSent(); + + break; + } + + case 'v': // Zeit in Unixformat von Datenlogger abfragen + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'v' (send device time) received"; + write_to_sd_log_single(string); + + unixtime_to_char_array(); + for(int i = 0; i < sizeof(seconds); i++){ + ble_buff[0][i] = seconds[i]; + onDataSent(i); + } + + dataSent(); + + break; + } + + case 't': //Zeit in Unixformat an Datenlogger schicken + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 't' (receive and set device time) received"; + write_to_sd_log_single(string); + + connected_cancel.attach(&disconnect, user_config_para.connected); + printf("\nReady to receive new time settings\n"); + while(readValue[0] == NULL || readValue[0] < 0x31|| readValue[0] > 0x39){ + clear_buffer(); + ble.waitForEvent(); + if(conn_state == 0){ + break; + } + } + connected_cancel.detach(); + if(conn_state == 1){ + int a = 0; + while(readValue[a] != NULL){ + a++; + } + int new_time = array_to_int(a); + clear_buffer(); + + if(set_app_time(new_time) == 1){ + ble_buff[0][0] = '1'; + onDataSent(0); + }else{ + ble_buff[0][0] = '0'; + onDataSent(0); + } + + dataSent(); + } + break; + } + + case 'q': //Min- / Max- / Mittelwert schicken + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'q' (send min/max/average) received"; + write_to_sd_log_single(string); + + connected_cancel.detach(); + clear_buffer(); + + unsigned int length = 0; + int a = 0; + + char string_1[] = "Sending min/max/average.."; + write_to_sd_log_single(string_1); + + fileSystem.unmount(); + fflush(stdout); + + fileSystem.mount(&blockDevice); + FILE * messdaten = fopen ("/fs/messdaten.csv", "rb"); + + fseek (messdaten, 0, SEEK_END); + length = ftell (messdaten); + fseek (messdaten, 0, SEEK_SET); + + /* Daten senden */ + + unsigned long ch = 0; + unsigned short lines = 0; + unsigned long i = 0; + unsigned long j = 1; + unsigned long c = 0; + unsigned long e = 0; + + while(!feof(messdaten)){ + ch = fgetc(messdaten); + if(ch == '\n') + { + lines++; + } + } + + printf("\n%d Eintraege\n", lines); + + for(int a = 0; a < lines; a++) + { + messwerte[a] = *new int[8]; + } + + char temp[8]; + + fseek(messdaten, 0, SEEK_SET); + while(!feof(messdaten)){ + ch = fgetc(messdaten); + if(ch == '\n'){ + fseek(messdaten, i - 7, SEEK_SET); + fread (temp, 1, 7, messdaten); + messwerte[e] = atoi(temp); + memset(&temp[0], 0, sizeof(temp)); + e++; + }else if(ch == EOF){ + fseek(messdaten, i - 8, SEEK_SET); + fread (temp, 1, 8, messdaten); + messwerte[e] = atoi(temp); + memset(&temp[0], 0, sizeof(temp)); + } + i++; + } + + unsigned long summe = 0; + + for(int q = 1; q < e; q++){ + summe += messwerte[q]; + } + printf("\nSumme: %lu\n", summe); + + double avr = summe / lines; + + fclose(messdaten); + fileSystem.unmount(); + fflush(stdout); + + char string_2[] = "Sending min/max/average complete"; + write_to_sd_log_single(string_2); + + quickSort(1, lines); + + if((int)avr != 0){ + avr = ceil( avr * 100.0 ) / 100.0; + } + + char min[5]; + char max[5]; + char durch[5]; + + sprintf(min,"%d", messwerte[1]); + sprintf(max,"%d", messwerte[lines]); + sprintf(durch,"%d", (int)avr); + + printf("\n%s, %s, %s\n", min, max, durch); + + int k = 0; + while(k < min[k] != NULL){ + ble_buff[0][k] = min[k]; + onDataSent(k); + k++; + } + ble_buff[0][k] = 0x3B; + onDataSent(k); + k++; + int p = 0; + while(p < max[p] != NULL){ + ble_buff[0][k] = max[p]; + onDataSent(k); + k++; + p++; + } + ble_buff[0][k] = 0x3B; + onDataSent(k); + k++; + int z = 0; + while(z < durch[z] != NULL){ + ble_buff[0][k] = durch[z]; + onDataSent(k); + k++; + z++; + } + ble_buff[0][k] = 0x3B; + onDataSent(k); + k++; + + dataSent(); + + break; + } + + case 'j': //Anzahl der Messungen schicken + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'j' (send measurements count) received"; + write_to_sd_log_single(string); + + //Anzahl der Messdaten + messdaten_count(); + int i = 0; + while(messungen[i] != NULL){ + ble_buff[0][i] = messungen[i]; + onDataSent(i); + i++; + } + printf("\nMeasurements count: %s\n", messungen); + + dataSent(); + + break; + } + + case 'h': //Anzahl der Logs schicken + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'h' (send log count) received"; + write_to_sd_log_single(string); + + //Anzahl der Logs + log_count(); + int i = 0; + while(logs_array[i] != NULL){ + ble_buff[0][i] = logs_array[i]; + onDataSent(i); + i++; + } + printf("\nLogs count: %s\n", logs_array); + + dataSent(); + + break; + } + + case 'y': //Alarn AN / AUS - Anzahl der Meldungen + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'y' (Alert function and count) received"; + write_to_sd_log_single(string); + + if(user_config_para.alert == 1){ + printf("\nAlert function - ON\n"); + + printf("\nNumber of alerts: %d\n", alert_count); + char alerts[4]; + sprintf(alerts, "%d", alert_count); + int i = 0; + while(alerts[i] != NULL){ + ble_buff[0][i] = alerts[i]; + onDataSent(i); + i++; + } + }else{ + printf("\nAlert function - OFF\n"); + + ble_buff[0][0] = '0'; + onDataSent(0); + } + + dataSent(); + + break; + } + + case 'k': //Initialisierungsstatus auslesen + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'b' (send initialize status) received"; + write_to_sd_log_single(string); + + if(init_status == true){ + ble_buff[0][0] = '1'; + onDataSent(0); + + printf("\nInitialaze status: OK\n"); + }else{ + ble_buff[0][0] = '0'; + onDataSent(0); + + printf("\nInitialaze status: FAILED\n"); + } + + dataSent(); + + break; + } + + case 'p': //Mess-Status auslesen + { + connected_cancel.detach(); + clear_buffer(); + + char string[] = "Command 'p' (send measurement status) received"; + write_to_sd_log_single(string); + + if(shipping == true){ + ble_buff[0][0] = 1; + onDataSent(0); + + wait(1); + clear_buffer(); + + if(pause == false){ + ble_buff[0][0] = '1'; + onDataSent(0); + + printf("\nMeasuremt status = Launched\n"); + }else{ + ble_buff[0][0] = '0'; + onDataSent(0); + + printf("\nMeasuremt status = Paused\n"); + } + + }else{ + ble_buff[0][0] = '0'; + onDataSent(0); + + printf("\nMeasuremt status = Sttopped\n"); + } + + dataSent(); + + break; + } + + default: { + //clear_buffer(); + response = '0'; + break; + } + } + } + } +} \ No newline at end of file