Test

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #define END_OF_JSON          0xFE
00002 #define VERBOSE_MODE            1  // Habilita la generacion de logs por el puerto USB      
00003 
00004 #include "mbed.h"
00005 #include "picojson.h"
00006 #include "stats_report.h"
00007 
00008 /* Librerías para BLE - Servicio GATT */
00009 #include "ble/BLE.h"
00010 #include "ble/Gap.h"
00011 #include "TOFService.h"
00012 #include "ble/DiscoveredCharacteristic.h"
00013 #include "ble/DiscoveredService.h"
00014 
00015 const static char     DEVICE_NAME[]        = "BLE_CONTROLLER";
00016 static const uint16_t uuid16_list[]        = {TOFService::CUSTOM_TOF_SERVICE_UUID};
00017 
00018 bool serviceDiscovered     = false;
00019 char finalCharacterJSON    = END_OF_JSON;
00020 
00021 typedef struct {
00022     string           MAC1;       /* Dirección MAC1*/
00023     string           MAC2;       /* Dirección MAC2*/
00024     double            ToF;       /* Tiempo de vuelo*/
00025 } BLEdata_t;
00026 
00027 typedef struct {
00028     string           hazardousDevice;       /* MAC dispositvo peligroso */
00029     string            affectedDevice;       /* MAC dispositivo afectado */
00030     uint8_t                     type;       /* Tipo de evento           */
00031 } JSONdata_t;
00032 
00033 DigitalOut led3Test(LED3);
00034 DigitalOut led4BLE(LED4);
00035 Serial pcSerial(USBTX, USBRX); // Abrimos conexión serial con el puerto USB
00036 
00037 TOFService* tofService;
00038 
00039 EventQueue eventQueue;
00040 Queue<JSONdata_t, 32> JSONqueue;
00041 Queue<BLEdata_t, 32> BLEqueue;
00042 Mail<BLEdata_t, 16> BLEMail;
00043 
00044 Thread threadLED(osPriorityAboveNormal1, 400);
00045 Thread threadSerial(osPriorityAboveNormal2, 2500);
00046 Thread threadBLE(osPriorityRealtime3, 2500);
00047 Thread threadCalculateEvent(osPriorityRealtime2, 1500);
00048 
00049 template<typename arg>
00050 void printLog(const char * log, arg data) {
00051     if(VERBOSE_MODE) printf(log, data);
00052 }
00053 
00054 void printLog(const char * log) {
00055     if(VERBOSE_MODE) printf(log);
00056 }
00057 
00058 /**
00059  * Thread encargado de parpadear un LED continuamente
00060  */
00061 void blinkLED3() {
00062     while(true) {
00063         led3Test = !led3Test;
00064         wait(0.8);
00065     }
00066 }
00067 
00068 /**
00069  * Método encargado de enviar un string por el puerto serie char a char
00070  */
00071 void sendCharArrayToSerial(char const *array, Serial *serial) {
00072     uint32_t i = 0;
00073     while(array[i] != '\0') {
00074         serial->putc(array[i]);
00075         i++;
00076     }
00077     serial->putc('\0');
00078 }
00079 
00080 /**
00081  * Thread encargado de calcular el tipo de evento a enviar
00082  */
00083 void calculateEvent() {
00084     while(true) {
00085         printLog("Leo evento de BLEMail\r\n");
00086         osEvent evt = BLEMail.get();
00087         printLog("Evento leido de BLEMail\r\n");
00088         if (evt.status == osEventMail) {
00089             BLEdata_t *dataIn = (BLEdata_t*) evt.value.p;
00090             printLog("ToF: %s\r\n", dataIn->ToF);
00091             printLog("Se obtiene puntero de BLEdata\r\n");
00092             
00093             JSONdata_t event;
00094             printLog("Se declara objeto JSONdata_t\r\n");
00095             if(dataIn->ToF > 1.0) {
00096                 printLog("Evento de tipo 1\r\n");
00097                 event.hazardousDevice = dataIn->MAC1;
00098                 event.affectedDevice  = dataIn->MAC2;
00099                 event.type            = 1; 
00100             } else { // Keep Alive
00101                 event.type            = 0;
00102                 event.hazardousDevice = dataIn->MAC1;
00103             }
00104             BLEMail.free(dataIn);
00105             printLog("Se va a escribir en la cola de JSON\r\n");
00106             JSONqueue.put(&event);
00107             printLog("Evento enviado a JSON\r\n");
00108         }
00109     }
00110 }
00111 
00112 /**
00113  * Thread encargado de enviar JSONs por el puerto serie
00114  */
00115 void sendJsonOverSerial() {
00116     char tmp[512]; // Vble auxiliar para el tratamiento de cadenas de char.
00117     string str;
00118     while(true) {
00119         // Esperamos a un mensaje en la cola
00120         picojson::object json;
00121         picojson::object event;
00122         picojson::object extraInfo;
00123         
00124         osEvent evt = JSONqueue.get();
00125         if (evt.status == osEventMessage) {
00126             JSONdata_t *data = (JSONdata_t*) evt.value.p;
00127 
00128             int id = rand() % 1000;
00129             event["idEvent"] = picojson::value((double) id);
00130             event["type"] = picojson::value((double) data->type);
00131             //str = "E9:ED:F4:AC:BF:8E";
00132             extraInfo["hazardousDevice"] = picojson::value(data->hazardousDevice);
00133             //str = "D5:62:12:BF:B8:45";
00134             
00135             if(data->type != 0) extraInfo["affectedDevice"] = picojson::value(data->affectedDevice);
00136             event["extraInfo"] = picojson::value(extraInfo);
00137             json["Event"] = picojson::value(event);
00138             
00139             str = picojson::value(json).serialize();
00140                        
00141             // Convertimos el string a char *
00142             strncpy(tmp, str.c_str(), sizeof(tmp));
00143             strncat(tmp, &finalCharacterJSON, sizeof(finalCharacterJSON)); // Añadimos el caracter al final
00144             tmp[sizeof(tmp) - 1] = 0;
00145             
00146             sendCharArrayToSerial(tmp, &pcSerial);
00147         }
00148     }
00149 }
00150 
00151 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) {
00152     printLog("Desconectado. Se comienza la fase de Advertising de nuevo\r\n");
00153     BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising();
00154 }
00155 
00156 void connectionCallback(const Gap::ConnectionCallbackParams_t *params) {
00157     printLog("Conectado al servidor\r\n");    
00158 }
00159 
00160 void parseRawJSONToQueue(string JSONsource) {
00161     picojson::value v;
00162     string err, MAC1, MAC2;
00163     BLEdata_t *data = BLEMail.alloc();;
00164     
00165     picojson::parse(v, JSONsource.c_str(), JSONsource.c_str() + strlen(JSONsource.c_str()), &err);
00166     printLog("res error? %s\r\n", err);
00167     
00168     printLog("ToF %f\r\n", v.get("TOF").get<double>());
00169     
00170     MAC1 = v.get("MAC1").get<string>();
00171     MAC2 = v.get("MAC2").get<string>();
00172     
00173     printLog("MAC1 en string: %s", MAC1);
00174     printLog("MAC2 en string: %s", MAC2);
00175     data->ToF  = v.get("TOF").get<double>();
00176     
00177     printLog("Se leen los datos del JSON\r\n");
00178     
00179     printLog("ToF = %f", data->ToF);
00180     printLog(" MAC1 = %s", data->MAC1);
00181     printLog(" MAC2 = %s\r\n", data->MAC2);
00182     
00183     BLEMail.put(data);
00184     
00185     printLog("Se introduce dato en BLEqueue\r\n");
00186 }
00187 
00188 void writeCharCallback(const GattWriteCallbackParams *params) {
00189     if(params->handle == tofService->getValueHandle()) {
00190         char toChar [TOFService::TOF_CHAR_ARRAY_SIZE];
00191         printLog("Data received: length = %d, data = 0x", params->len);
00192         for(int x=0; x < params->len; x++) {
00193             toChar[x] = (char) params->data[x];
00194             printLog("%x", params->data[x]);
00195         }
00196         //toChar[params->len] = '\0';
00197         printLog("\n\r");
00198         
00199         printLog("Cadena: %s\n\r", toChar);
00200         string str(toChar);
00201         eventQueue.call(parseRawJSONToQueue, str);
00202     }
00203 }
00204 
00205 /**
00206  * Esta función se llama si ha habido algún error en el proceso de inicialización del BLE
00207  */
00208 void onBleInitError(BLE &ble, ble_error_t error) {
00209     printLog("Ha ocurrido un error al inicializar la configuracion del BLE\n");
00210 }
00211 
00212 /**
00213  * Callback triggered when the ble initialization process has finished
00214  */
00215 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) {
00216     BLE &ble          = params->ble;
00217     ble_error_t error = params->error;
00218     
00219     if (error != BLE_ERROR_NONE) {
00220         return;
00221     }
00222 
00223     ble.gap().onDisconnection(disconnectionCallback);
00224     ble.gap().onConnection(connectionCallback);
00225     ble.gattServer().onDataWritten(writeCharCallback);
00226     
00227     tofService = new TOFService(ble);
00228     
00229     /* Setup advertising */
00230     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); // BLE only, no classic BT
00231     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); // advertising type
00232     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); // add name
00233     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); // UUID's broadcast in advertising packet
00234     ble.gap().setAdvertisingInterval(100); // 100ms.
00235 
00236     /* Start advertising */
00237     ble.gap().startAdvertising();
00238 }
00239 
00240 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
00241     BLE &ble = BLE::Instance();
00242     eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
00243 } 
00244 
00245 void BLEServiceManagment() {
00246     BLE &ble = BLE::Instance();
00247     ble.onEventsToProcess(scheduleBleEventsProcessing); 
00248     ble.init(bleInitComplete);
00249     
00250     eventQueue.dispatch_forever();
00251 }
00252 
00253 int main() { 
00254     srand(time(NULL));
00255     threadLED.start(callback(blinkLED3));
00256     threadBLE.start(callback(BLEServiceManagment));
00257     threadSerial.start(callback(sendJsonOverSerial));
00258     threadCalculateEvent.start(callback(calculateEvent));
00259             
00260     threadLED.join();
00261     threadBLE.join();
00262     threadSerial.join();
00263     threadCalculateEvent.join();
00264 }