Test
source/main.cpp
- Committer:
- HelGast95
- Date:
- 2019-01-24
- Revision:
- 76:596c9924e51b
- Parent:
- 75:6606a580ebc4
- Child:
- 77:48c622bf903f
File content as of revision 76:596c9924e51b:
#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() {
char tmp[512]; // 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
picojson::object event;
picojson::object extraInfo;
int type = rand() % 3;
int idEvent = rand() % 500;
event["idEvent"] = picojson::value((double) idEvent);
event["type"] = picojson::value((double) type);
str = "E9:ED:F4:AC:BF:8E";
extraInfo["hazardousDevice"] = picojson::value(str);
str = "D5:62:12:BF:B8:45";
if(type != 0) extraInfo["affectedDevice"] = picojson::value(str);
event["extraInfo"] = picojson::value(extraInfo);
//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(2);
}
}
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");
BLEdata_t *BLEdata = BLEmpool.alloc();
int r = rand() % 500;
char str[12];
sprintf(str, "%d", r);
BLEdata->id = str;
uint16_t tensionaux;
tensionaux = ((response->data[1]) << 8) + (response->data[0]);
BLEdata->voltaje = (tensionaux * 1.0 )/100;
BLEqueue.put(BLEdata);
}
}
/**
* 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();
}