CAN to BLE translator - and back

Dependencies:   BLE_API CANnucleo X_NUCLEO_IDB0XA1 mbed

Revision:
1:43ff0e4d56cc
Parent:
0:345c72cbcd60
--- a/main.cpp	Thu Apr 07 14:19:45 2016 +0000
+++ b/main.cpp	Thu Apr 07 14:36:30 2016 +0000
@@ -1,18 +1,30 @@
 #include "mbed.h"
 #include "ble/BLE.h"
 #include "CAN.h"
-#define TARGET_NUCLEO_F072RB 1
 
+#define TARGET_NUCLEO_F072RB 1
 #define   LED_PIN   PA_5
 
+#define BLE_GATT_CHAR_PROPERTIES_NOTIFY 0x10
+
 uint8_t CANId2BLESlot(unsigned int   id);
 unsigned int BLESlot2CANId(uint8_t   id);
 void onMsgReceived(void);
 void initCAN(void);
 
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params);
+void writeCharCallback(const GattWriteCallbackParams  *params);
+void bleInitComplete(BLE::InitializationCompleteCallbackContext *params);
+void onBleInitError(BLE &ble, ble_error_t error);
+void initBLE(void);
+
+
 DigitalOut      led(LED_PIN);
 
 
+const static char     DEVICE_NAME[]        = "STNucleo - RGM - FM";
+static const uint16_t uuid16_list[]        = {0xFFFF};
+
 //const unsigned int RX_ID = 0x10;
 //const unsigned int TX_ID = 0x11;
 
@@ -31,8 +43,24 @@
 CANMessage      rxMsg;
 CANMessage      txMsg;
 
+BLE ble;
+
+uint16_t customServiceUUID  = 0xA000; // service UUID
+uint16_t readCharUUID       = 0xA001; // read characteristic UUID
+uint16_t writeCharUUID      = 0xA002; // write characteristic UUID
+
+static uint8_t readValue[128] = {0};
+ReadOnlyArrayGattCharacteristic<uint8_t,  sizeof(readValue)> readChar(readCharUUID, readValue, BLE_GATT_CHAR_PROPERTIES_NOTIFY , NULL,0); //aggiunto il BLE_GATT_CHAR_PROPERTIES_NOTIFY => appena arriva lo rimanda
+
+static uint8_t writeValue[128] = {0};
+WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(writeValue)> writeChar(writeCharUUID, writeValue);
+
+GattCharacteristic *characteristics[] = {&readChar, &writeChar};
+GattService         customService(customServiceUUID, characteristics,  sizeof(characteristics) / sizeof(GattCharacteristic *));
+
+
 volatile bool   CANmsgAvailable = false;
-
+volatile bool   BLExmit = false;
 
 int main()
 {
@@ -49,10 +77,12 @@
             led=!led.read();
             timerA.start();
         }
-        if(timerB.read()>=1.0) {
+        if(timerB.read()>=0.1) {
             timerB.stop();
             timerB.reset();
-            //led=!led.read();
+
+            if(ble.getGapState().connected) BLExmit=true;
+
             timerB.start();
         }
         if(CANmsgAvailable) {
@@ -74,11 +104,12 @@
                 }
                 printf("\r\n");
                 canWrPointer=255;
+            } else {
+                printf("CAN message %#x dropped because BLE read\r\n",rxMsg.id);
             }
-            else
-            {
-                 printf("CAN message %#x dropped because BLE read\r\n",rxMsg.id);
-            }
+        }
+        if(BLExmit) {
+            BLExmit=false;
         }
     }
 }
@@ -88,6 +119,45 @@
     can.attach(&onMsgReceived, CAN::RxIrq);     // attach 'CAN receive-complete' interrupt handler
     printf("\r\nCAN started at 500kbps\r\n");
 }
+void initBLE(void)
+{
+    BLE::Instance().init(bleInitComplete);
+}
+void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
+{
+    BLE&        ble   = params->ble;
+    ble_error_t error = params->error;
+
+    if (error != BLE_ERROR_NONE) {
+        onBleInitError(ble, error);
+        return;
+    }
+
+    if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
+        return;
+    }
+
+    ble.gap().onDisconnection(disconnectionCallback);
+
+    /* Setup primary service. */
+
+    /* Setup advertising. */
+    printf("Setup of Advertising\r\n");
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
+    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+    ble.gap().setAdvertisingInterval(1000); /* 1000ms */
+    ble.gap().startAdvertising();
+    ble.onDataWritten(writeCharCallback);
+    ble.addService(customService);
+}
+void onBleInitError(BLE &ble, ble_error_t error)
+{
+    (void)ble;
+    (void)error;
+    /* Initialization error handling should go here */
+}
 void onMsgReceived(void)
 {
     CANmsgAvailable = true;
@@ -156,4 +226,31 @@
             break;
     }
     return retval;
-}
\ No newline at end of file
+}
+
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
+{
+    (void)params;
+    printf("\r\nTarget loss... wait for reconnection \r\n");
+
+    BLE::Instance().gap().startAdvertising(); // restart advertising
+}
+
+void writeCharCallback(const GattWriteCallbackParams  *params)
+{
+    /*
+    int terminale=params->len;
+    // check to see what characteristic was written, by handle
+    if(params->handle  == writeChar.getValueHandle()) {
+        daerdata[0]=terminale;
+
+        printf("\n\r Data received: length = %d, data = ",terminale);
+        for(int x=0; x < terminale; x++) {
+            printf("%c",params->data[x]);
+            daerdata[x+1]=params->data[x];
+        }
+
+        ble.updateCharacteristicValue(readChar.getValueHandle(),daerdata,terminale+1);
+
+    }*/
+}