Test

source/main.cpp

Committer:
HelGast95
Date:
2019-01-23
Revision:
75:6606a580ebc4
Parent:
74:12b9444a2fb4
Child:
76:596c9924e51b

File content as of revision 75:6606a580ebc4:

#define END_OF_JSON                 0xFE

#include "mbed.h"
#include "picojson.h"
#include "stats_report.h"

/* Librerías para BLE - Servicio GATT */
#include "ble/BLE.h"
#include "ble/Gap.h"
#include "ble/DiscoveredCharacteristic.h"
#include "ble/DiscoveredService.h"

bool serviceDiscovered = false;

typedef struct {
    string         id;       /* Id */
    float     voltaje;       /* Voltaje */
} BLEdata_t;

DigitalOut led3Test(LED3);
DigitalOut led4BLE(LED4);
Serial pcSerial(USBTX, USBRX); // Abrimos conexión serial con el puerto USB
DiscoveredCharacteristic testServiceptr;

EventQueue eventQueue;
Queue<BLEdata_t, 32> BLEqueue;
MemoryPool<BLEdata_t, 32> BLEmpool;

Thread threadLED(osPriorityAboveNormal1, 400);
Thread threadSerial(osPriorityAboveNormal2, 2500);
Thread threadBLE(osPriorityRealtime3, 1000);

/**
 * Tarea encargada de parpadear un LED continuamente
 */
void blinkLED3() {
    while(true) {
        led3Test = !led3Test;
        wait(0.8);
    }
}

/**
 * Método encargado de enviar un string por el puerto serie char a char
 */
void sendCharArrayToSerial(char const *array, Serial *serial) {
    uint32_t i = 0;
    while(array[i] != '\0') {
        serial->putc(array[i]);
        i++;
    }
    serial->putc('\0');
}

/**
 * Thread encargado de enviar JSONs por el puerto serie
 */
void sendJsonOverSerial() {
    picojson::object event;
    char tmp[50]; // Vble auxiliar para el tratamiento de cadenas de char.
    string str;
    char final = END_OF_JSON;
    
    while(true) {
        // Esperamos a un mensaje en la cola
        osEvent evt = BLEqueue.get();
        if (evt.status == osEventMessage) {
            BLEdata_t *BLEdata  = (BLEdata_t*) evt.value.p;
            
            printf("\r\nDato recibido BLE\r\n");
            event["id"] = picojson::value(BLEdata->id);
            printf("Id: %s\r\n", BLEdata->id.c_str());
            str = "Voltaje";
            event["type"] = picojson::value(str);
            event["data"] = picojson::value(BLEdata->voltaje);
    
            BLEmpool.free(BLEdata);
            
            printf("Se serializa el string\r\n");
            str = picojson::value(event).serialize();
                       
            // Convertimos el string a char *
            strncpy(tmp, str.c_str(), sizeof(tmp));
            strncat(tmp, &final, sizeof(final)); // Añadimos el caracter al final
            tmp[sizeof(tmp) - 1] = 0;
            
            printf("Se envia un evento por el puesto serie\r\n");
            sendCharArrayToSerial(tmp, &pcSerial);
        }
        
        wait(1);
    }
}

void scanCallback(const Gap::AdvertisementCallbackParams_t *params) {
    if (params->peerAddr[0] != 0x8E) return;
    printf("adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n",
           params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],
           params->rssi, params->isScanResponse, params->type);

    BLE::Instance().gap().connect(params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL);
}

void serviceDiscoveryCallback(const DiscoveredService *service) {
    if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) {
        printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle());
    } else {
        printf("S UUID-");
        const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
        for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
            printf("%02x", longUUIDBytes[i]);
        }
        printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle());
    }
}

void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) {
    printf("  C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getUUID().getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast());
    if (characteristicP->getUUID().getShortUUID() == 0xa001) { 
        testServiceptr             = *characteristicP;
        serviceDiscovered          =  true;
    }
}

void discoveryTerminationCallback(Gap::Handle_t connectionHandle) {
    printf("terminated SD for handle %u\r\n", connectionHandle);
}

void connectionCallback(const Gap::ConnectionCallbackParams_t *params) {
    if (params->role == Gap::CENTRAL) {
        BLE::Instance().gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback);
        BLE::Instance().gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, 0xA000, 0xA001);
    }
}

void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
{
    /* Si se desconecta el dispositivo, volvemos a entrar en estado Advertising*/
    printf("Desconectado. Se comienza la fase de escaneo de nuevo\n\r");
    serviceDiscovered = false;
    BLE::Instance().gap().startScan(scanCallback);
}
  
void onDataReadClientCallback(const GattReadCallbackParams *response) {
   if (response->handle == testServiceptr.getValueHandle()) {
        printf("\r\n\r\nonDataReadClientCallback: handle %u, offset %u, len %u\r\n", response->handle, response->offset, response->len);
        for (unsigned index = 0; index < response->len; index++) {
            printf("[%02x]", response->data[index]);
        }
        printf("\r\n");
        printf("Que pasa\r\n");
        
        BLEdata_t *BLEdata = BLEmpool.alloc();
        printf("Eyyyyy\r\n");
        int r = rand() % 500;
        printf("Eyyyyy1.5\r\n");
        char str[12];
        printf("Eyyyyy1.6\r\n");
        sprintf(str, "%d", r);
        printf("Eyyyyy1.7\r\n");
        BLEdata->id = str;
        printf("Eyyyyy2\r\n");
        uint16_t tensionaux;
        tensionaux = ((response->data[1]) << 8) + (response->data[0]);
        printf("Eyyyyy2.1\r\n");
        BLEdata->voltaje = (tensionaux * 1.0 )/100;
        printf("Eyyyyy2.2\r\n");
        BLEqueue.put(BLEdata);
        printf("Eyyyyy3\r\n");     
    }
}

/**
 * Esta función se llama si ha habido algún error en el proceso de inicialización del BLE
 */
void onBleInitError(BLE &ble, ble_error_t error) {
    printf("Ha ocurrido un error al inicializar la configuracion del BLE\n");
}

void printMacAddress() {
    /* Print out device MAC address to the console*/
    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]);
}

/**
 * Callback triggered when the ble initialization process has finished
 */
void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
{
    BLE&        ble   = params->ble;
    ble_error_t error = params->error;

    if (error != BLE_ERROR_NONE) {
        /* In case of error, forward the error handling to onBleInitError */
        onBleInitError(ble, error);
        return;
    }

    /* Ensure that it is the default instance of BLE */
    if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
        return;
    }
  
    ble.gap().onConnection(connectionCallback);
    ble.gap().onDisconnection(disconnectionCallback);

    ble.gattClient().onDataRead(onDataReadClientCallback);

    ble.gap().setScanParams(500, 400);
    ble.gap().startScan(scanCallback);    
}

void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
    BLE &ble = BLE::Instance();
    eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
} 

void readVoltageValue() {
    BLE &ble = BLE::Instance();
    if (serviceDiscovered && !ble.gattClient().isServiceDiscoveryActive()) {
        testServiceptr.read();
    }     
}

void BLEServiceManagment() {
    eventQueue.call_every(2000, readVoltageValue);
        
    BLE &ble = BLE::Instance();
    ble.onEventsToProcess(scheduleBleEventsProcessing); 
    ble.init(bleInitComplete);
    
    eventQueue.dispatch_forever();
}

int main() { 
    srand(time(NULL));
    threadLED.start(blinkLED3);
    threadBLE.start(BLEServiceManagment);
    threadSerial.start(sendJsonOverSerial);
            
    threadLED.join();
    threadBLE.join();
    threadSerial.join();
    
    while(true) {
        wait(100);
    }
    return 0;
}