Test
Revision 79:9f3aca04de4e, committed 2019-01-31
- Comitter:
- HelGast95
- Date:
- Thu Jan 31 12:55:00 2019 +0000
- Parent:
- 78:bb7e309408a2
- Child:
- 80:5e52c5847273
- Commit message:
- Primera version de GATT Server
Changed in this revision
| source/TOFService.h | Show annotated file Show diff for this revision Revisions of this file |
| source/main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/TOFService.h Thu Jan 31 12:55:00 2019 +0000
@@ -0,0 +1,44 @@
+#ifndef __BLE_TOF_SERVICE_H__
+#define __BLE_TOF_SERVICE_H__
+
+#include "ble/BLE.h"
+
+class TOFService {
+ public:
+ const static uint8_t TOF_CHAR_ARRAY_SIZE = 100;
+ const static uint16_t CUSTOM_TOF_SERVICE_UUID = 0xA000;
+ const static uint16_t TOF_CHAR_WRITE_CHARACTERISTIC_UUID = 0xA001;
+
+ TOFService(BLE& _ble) :
+ ble(_ble),
+ //writeCharArrayCharacteristic(TOF_CHAR_WRITE_CHARACTERISTIC_UUID, writeValue)
+ writeCharArrayCharacteristic(TOF_CHAR_WRITE_CHARACTERISTIC_UUID, writeBuffer, 1, 100,
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES)
+ {
+ static bool serviceAdded = false; /* We should only ever need to add the information service once. */
+ if (serviceAdded) {
+ return;
+ }
+
+ GattCharacteristic *charTable[] = {&writeCharArrayCharacteristic};
+
+ GattService TOFService(CUSTOM_TOF_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+
+ ble.gattServer().addService(TOFService);
+ serviceAdded = true;
+ }
+
+ GattAttribute::Handle_t getValueHandle() const {
+ return writeCharArrayCharacteristic.getValueHandle();
+ }
+
+ private:
+ BLE& ble;
+
+ uint8_t writeBuffer[TOF_CHAR_ARRAY_SIZE];
+
+ //WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(writeBuffer)> writeCharArrayCharacteristic;
+ GattCharacteristic writeCharArrayCharacteristic;
+};
+
+#endif /* #ifndef __BLE_TOF_SERVICE_H__*/
\ No newline at end of file
--- a/source/main.cpp Tue Jan 29 09:26:59 2019 +0000
+++ b/source/main.cpp Thu Jan 31 12:55:00 2019 +0000
@@ -1,5 +1,6 @@
#define END_OF_JSON 0xFE
-#define MAC_FILTER 0x8E
+#define MAC_FILTER 0x8E
+#define VERBOSE_MODE 1 // Habilita la generacion de logs por el puerto USB
#include "mbed.h"
#include "picojson.h"
@@ -8,30 +9,44 @@
/* Librerías para BLE - Servicio GATT */
#include "ble/BLE.h"
#include "ble/Gap.h"
+#include "TOFService.h"
#include "ble/DiscoveredCharacteristic.h"
#include "ble/DiscoveredService.h"
+const static char DEVICE_NAME[] = "BLE_CONTROLLER";
+static const uint16_t uuid16_list[] = {TOFService::CUSTOM_TOF_SERVICE_UUID};
+
bool serviceDiscovered = false;
char finalCharacterJSON = END_OF_JSON;
typedef struct {
- string id; /* Id */
- float voltaje; /* Voltaje */
+ string MAC; /* Dirección MAC */
+ float ToF; /* Tiempo de vuelo */
} BLEdata_t;
DigitalOut led3Test(LED3);
DigitalOut led4BLE(LED4);
Serial pcSerial(USBTX, USBRX); // Abrimos conexión serial con el puerto USB
-DiscoveredCharacteristic testServiceptr;
+
+TOFService* tofService;
EventQueue eventQueue;
Queue<BLEdata_t, 32> BLEqueue;
MemoryPool<BLEdata_t, 32> BLEmpool;
-Thread threadLED(osPriorityAboveNormal1, 400);
+Thread threadLED(osPriorityAboveNormal1, 1000);
Thread threadSerial(osPriorityAboveNormal2, 2500);
Thread threadBLE(osPriorityRealtime3, 1000);
+template<typename arg>
+void printLog(const char * log, arg data) {
+ if(VERBOSE_MODE) printf(log, data);
+}
+
+void printLog(const char * log) {
+ if(VERBOSE_MODE) printf(log);
+}
+
/**
* Thread encargado de parpadear un LED continuamente
*/
@@ -58,110 +73,64 @@
* 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;
-
while(true) {
-
// Esperamos a un mensaje en la cola
picojson::object json;
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);
- json["Event"] = picojson::value(event);
-
- str = picojson::value(json).serialize();
-
- // Convertimos el string a char *
- strncpy(tmp, str.c_str(), sizeof(tmp));
- strncat(tmp, &finalCharacterJSON, sizeof(finalCharacterJSON)); // Añadimos el caracter al final
- tmp[sizeof(tmp) - 1] = 0;
-
- sendCharArrayToSerial(tmp, &pcSerial);
-
- wait(10);
+ osEvent evt = BLEqueue.get();
+ if (evt.status == osEventMessage) {
+ BLEdata_t *BLEdata = (BLEdata_t*)evt.value.p;
+
+ BLEmpool.free(BLEdata);
+
+ int type = rand() % 4;
+ event["idEvent"] = picojson::value(BLEdata->MAC);
+ 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);
+ json["Event"] = picojson::value(event);
+
+ str = picojson::value(json).serialize();
+
+ // Convertimos el string a char *
+ strncpy(tmp, str.c_str(), sizeof(tmp));
+ strncat(tmp, &finalCharacterJSON, sizeof(finalCharacterJSON)); // Añadimos el caracter al final
+ tmp[sizeof(tmp) - 1] = 0;
+
+ sendCharArrayToSerial(tmp, &pcSerial);
+ }
}
}
-void scanCallback(const Gap::AdvertisementCallbackParams_t *params) {
- if (params->peerAddr[0] != MAC_FILTER) 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 disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) {
+ printLog("Desconectado. Se comienza la fase de Advertising de nuevo\r\n");
+ BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising();
}
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);
- }
+ printLog("Conectado al servidor\r\n");
}
-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]);
+void writeCharCallback(const GattWriteCallbackParams *params) {
+ if(params->handle == tofService->getValueHandle()) {
+ char toChar [TOFService::TOF_CHAR_ARRAY_SIZE + 1];
+ printLog("Data received: length = %d, data = 0x", params->len);
+ for(int x=0; x < params->len; x++) {
+ toChar[x] = (char) params->data[x];
+ printLog("%x", params->data[x]);
}
- //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);
+ toChar[params->len] = '\0';
+ string str(toChar);
+ printLog("\n\r");
+ printLog("Dato parseado a string: %s\n\r", str);
}
}
@@ -169,7 +138,7 @@
* 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");
+ printLog("Ha ocurrido un error al inicializar la configuracion del BLE\n");
}
void printMacAddress() {
@@ -177,39 +146,39 @@
Gap::AddressType_t addr_type;
Gap::Address_t address;
BLE::Instance().gap().getAddress(&addr_type, address);
- printf("DEVICE MAC ADDRESS: ");
+ printLog("DEVICE MAC ADDRESS: ");
for (int i = 5; i >= 1; i--){
- printf("%02x:", address[i]);
+ printLog("%02x:", address[i]);
}
- printf("%02x\r\n", address[0]);
+ printLog("%02x\r\n", address[0]);
}
/**
* Callback triggered when the ble initialization process has finished
*/
-void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
-{
- BLE& ble = params->ble;
+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().onDisconnection(disconnectionCallback);
ble.gap().onConnection(connectionCallback);
- ble.gap().onDisconnection(disconnectionCallback);
+ ble.gattServer().onDataWritten(writeCharCallback);
+
+ tofService = new TOFService(ble);
+
+ /* 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::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); // 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.
- ble.gattClient().onDataRead(onDataReadClientCallback);
-
- ble.gap().setScanParams(500, 400);
- ble.gap().startScan(scanCallback);
+ /* Start advertising */
+ ble.gap().startAdvertising();
}
void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
@@ -217,16 +186,7 @@
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);
@@ -237,10 +197,10 @@
int main() {
srand(time(NULL));
threadLED.start(callback(blinkLED3));
- //threadBLE.start(callback(BLEServiceManagment));
- threadSerial.start(callback(sendJsonOverSerial));
+ threadBLE.start(callback(BLEServiceManagment));
+ //threadSerial.start(callback(sendJsonOverSerial));
threadLED.join();
threadBLE.join();
- threadSerial.join();
+ //threadSerial.join();
}
\ No newline at end of file