C

The next code is based on language C. This code allow us to send an receive data.

To access the libraries of the BLE API and ALPWISE stack library it is required to include these files in our code.

/* system header files */
#include <stdio.h>
/* additional interface header files */
#include "FreeRTOS.h"
#include "timers.h"

/* own header files */
#include "BCDS_CmdProcessor.h"
#include "BCDS_Assert.h"

//#include "BCDS_Ble.h"
#include "BCDS_BlePeripheral.h"
#include "BCDS_BidirectionalService.h"
#include "BCDS_SensorServices.h"
#include "semphr.h"

We are going to define some variables, in this case are Semaphores, and also notice that have global access. And also we define some constant that would help us to make the timeout.

/* constant definitions ***************************************************** */

#define BLE_START_SYNC_TIMEOUT        UINT32_C(5000)
#define BLE_WAKEUP_SYNC_TIMEOUT       UINT32_C(5000)
#define BLE_SEND_TIMEOUT                 UINT32_C(1000)

/* local variables ********************************************************** */

static SemaphoreHandle_t BleStartSyncSemphr = NULL;
static SemaphoreHandle_t BleWakeUpSyncSemphr = NULL;
static SemaphoreHandle_t SendCompleteSync = NULL;

We need to define some function so we could set up the service. We need to define the incoming data and read request, and also the sending process of every message sent to the remote client.

BleDataReceivedCallback - would help us to copy the data that the XDK received via BLE into a buffer. If the message is to long, it will be cut off. Finally, the received data would be printed.

BleDataSentCallback function only releases a semaphore that handles synchroninzing multiple sending processes. This function is called everytime a message is done being sent.

/* local functions ********************************************************** */

static void TransmitBleData(void)
{
    Retcode_T sendingReturnValue = BidirectionalService_SendData(
            (uint8_t*) "Hello Client!\0",
            (uint8_t) sizeof("Hello Client!\0") - 1);
    if (sendingReturnValue == RETCODE_OK) {
        xSemaphoreTake(SendCompleteSync, BLE_SEND_TIMEOUT);
    }
}

static void BleDataReceivedCallBack(uint8_t *rxBuffer, uint8_t rxDataLength)
{
    uint8_t bleReceiveBuff[UINT8_C(21)];
    {
        memset(bleReceiveBuff, 0, sizeof(bleReceiveBuff));
        memcpy(bleReceiveBuff, rxBuffer, rxDataLength < UINT8_C(21) ? rxDataLength : UINT8_C(21) - 1); 
        printf("Received data: %s \n", bleReceiveBuff); 
    } 
} 

static void BleDataSentCallback(Retcode_T sendStatus) { 
    BCDS_UNUSED(sendStatus); 
    xSemaphoreGive(SendCompleteSync); 
}

The BLE library would give use some peripheral events, such as device connects, disconnects, etc. For this we need to define callback function. This function has two inputs, the event itself, and data that belongs to the event. The events hadthe corresponding data type.

The first two events occur during the starting up process. In these cases the semaphores, that were previously taken, will be given back. In the case of connection events, the remote client’s address will be printed. In disconnection events, a simple message will be printed.

static void BleEventCallBack(BlePeripheral_Event_T event, void * data) { 
    switch (event) { 

        case BLE_PERIPHERAL_STARTED: 
            xSemaphoreGive( BleStartSyncSemphr ); 
            break; 

        case BLE_PERIPHERAL_WAKEUP_SUCCEEDED: 
            xSemaphoreGive( BleWakeUpSyncSemphr ); 
            break; 

        case BLE_PERIPHERAL_CONNECTED: { 
            Ble_RemoteDeviceAddress_T *remoteAddress; 
            remoteAddress = (Ble_RemoteDeviceAddress_T*) data; 
            printf("Device connected: %02x:%02x:%02x:%02x:%02x:%02x \r\n", remoteAddress->Addr[0], remoteAddress->Addr[1], remoteAddress->Addr[2],
                        remoteAddress->Addr[3], remoteAddress->Addr[4], remoteAddress->Addr[5]);
        }
        break;

    case BLE_PERIPHERAL_DISCONNECTED:
        printf("Device Disconnected: \r\n");
        break;

    default:
        break;
    }
}

static Retcode_T CreateServiceCallback(void)
{
    BidirectionalService_Init(BleDataReceivedCallBack, BleDataSentCallback);
    SensorServices_Init(NULL, NULL);
    BidirectionalService_Register();
    SensorServices_Register();
    return RETCODE_OK;
}

In this part of the code are listed the functions that we need to called to get the BLE peripheral up and running, using all the funcitons that have previously defined.

/* global functions ********************************************************* */

void BleInit(void){
    BleStartSyncSemphr = xSemaphoreCreateBinary();
    BleWakeUpSyncSemphr = xSemaphoreCreateBinary();
    SendCompleteSync = xSemaphoreCreateBinary();

    BlePeripheral_Initialize(BleEventCallBack, CreateServiceCallback);
    BlePeripheral_SetDeviceName((uint8_t*) "XDK BLE Guide");
    if(RETCODE_OK == BlePeripheral_Start()) {
    xSemaphoreTake(BleStartSyncSemphr, BLE_START_SYNC_TIMEOUT);
    }
    if(RETCODE_OK == BlePeripheral_Wakeup()) {
    xSemaphoreTake(BleWakeUpSyncSemphr, BLE_WAKEUP_SYNC_TIMEOUT);
    }
}

/**
 * @brief This is a template function where the user can write his custom application.
 *
 */
void appInitSystem(void * CmdProcessorHandle, uint32_t param2)
{
    if (CmdProcessorHandle == NULL)
    {
        printf("Command processor handle is null \n\r");
        assert(false);
    }
    BCDS_UNUSED(param2);
    vTaskDelay(5000);
    BleInit();
    TransmitBleData();
}

Last updated

Was this helpful?