Skip to content

Commit fe3647d

Browse files
andreagilardonipennam
authored andcommitted
adding bluetooth vhci in command handler
1 parent 597ecac commit fe3647d

File tree

1 file changed

+230
-1
lines changed

1 file changed

+230
-1
lines changed

main/CommandHandler.cpp

Lines changed: 230 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2600,6 +2600,227 @@ int pref_getType(const uint8_t command[], uint8_t response[]) {
26002600
return 6;
26012601
}
26022602

2603+
/*
2604+
* BLE vHCI API
2605+
*/
2606+
#include "esp_bt.h"
2607+
2608+
#define TO_HOST_BUF_SIZE 256 // bytes
2609+
static RingbufHandle_t buf_handle = NULL;
2610+
static SemaphoreHandle_t vhci_send_sem = NULL;
2611+
2612+
static void controller_rcv_pkt_ready() {
2613+
if (vhci_send_sem) {
2614+
xSemaphoreGive(vhci_send_sem);
2615+
}
2616+
}
2617+
2618+
/*
2619+
* The following callback is called when the bt controller has some data available
2620+
* this data is put into a queue that is then consumed by calling ble_read
2621+
*/
2622+
static int host_rcv_pkt(uint8_t *data, uint16_t len) {
2623+
if(buf_handle == NULL) {
2624+
ets_printf("failed host_rcv_pkt\n");
2625+
return ESP_FAIL;
2626+
}
2627+
2628+
UBaseType_t res = xRingbufferSend(buf_handle, data, len, pdMS_TO_TICKS(2000)); // TODO verify xTicksToWait value
2629+
2630+
if (res != pdTRUE) {
2631+
ets_printf("unable to send data to ring buffer\n");
2632+
}
2633+
return ESP_OK;
2634+
}
2635+
2636+
static esp_bt_controller_config_t btControllerConfig = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
2637+
static esp_vhci_host_callback_t vhciHostCb = {
2638+
controller_rcv_pkt_ready,
2639+
host_rcv_pkt
2640+
};
2641+
2642+
int ble_begin(const uint8_t command[], uint8_t response[]) {
2643+
//[0] CMD_START < 0xE0 >
2644+
//[1] Command < 1 byte >
2645+
2646+
esp_err_t ret = ESP_OK;
2647+
2648+
if((ret = esp_bt_controller_init(&btControllerConfig)) != ESP_OK) {
2649+
ets_printf("failed esp_bt_controller_init %s\n", esp_err_to_name(ret));
2650+
2651+
goto exit;
2652+
}
2653+
2654+
while (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE);
2655+
2656+
if((ret = esp_bt_controller_enable(ESP_BT_MODE_BLE)) != ESP_OK) {
2657+
ets_printf("failed esp_bt_controller_enable %s\n", esp_err_to_name(ret));
2658+
2659+
goto exit;
2660+
}
2661+
2662+
if((buf_handle = xRingbufferCreate(TO_HOST_BUF_SIZE, RINGBUF_TYPE_BYTEBUF)) == NULL) {
2663+
ret = ESP_ERR_NO_MEM;
2664+
ets_printf("failed xRingbufferCreate\n");
2665+
2666+
goto exit;
2667+
}
2668+
2669+
vhci_send_sem = xSemaphoreCreateBinary();
2670+
if (vhci_send_sem == NULL) {
2671+
ets_printf("Failed to create VHCI send sem\n");
2672+
ret = ESP_ERR_NO_MEM;
2673+
goto exit;
2674+
}
2675+
xSemaphoreGive(vhci_send_sem);
2676+
2677+
esp_bt_sleep_enable();
2678+
2679+
esp_vhci_host_register_callback(&vhciHostCb);
2680+
2681+
exit:
2682+
response[2] = 1; // number of parameters
2683+
response[3] = 1; // length of first parameter
2684+
response[4] = ret;
2685+
2686+
return 6;
2687+
}
2688+
2689+
int ble_end(const uint8_t command[], uint8_t response[]) {
2690+
//[0] CMD_START < 0xE0 >
2691+
//[1] Command < 1 byte >
2692+
2693+
esp_bt_controller_disable();
2694+
esp_bt_controller_deinit();
2695+
2696+
if(buf_handle != NULL) {
2697+
vRingbufferDelete(buf_handle);
2698+
}
2699+
2700+
if (vhci_send_sem != NULL) {
2701+
/* Dummy take and give sema before deleting it */
2702+
xSemaphoreTake(vhci_send_sem, pdMS_TO_TICKS(2000));
2703+
xSemaphoreGive(vhci_send_sem);
2704+
vSemaphoreDelete(vhci_send_sem);
2705+
vhci_send_sem = NULL;
2706+
}
2707+
2708+
response[2] = 1; // number of parameters
2709+
response[3] = 1; // length of first parameter
2710+
response[4] = 1;
2711+
2712+
return 6;
2713+
}
2714+
2715+
int ble_available(const uint8_t command[], uint8_t response[]) {
2716+
//[0] CMD_START < 0xE0 >
2717+
//[1] Command < 1 byte >
2718+
uint16_t available = 0;
2719+
if(buf_handle != NULL) {
2720+
available = TO_HOST_BUF_SIZE - xRingbufferGetCurFreeSize(buf_handle);
2721+
}
2722+
2723+
response[2] = 1; // number of parameters
2724+
response[3] = 2; // length of first parameter
2725+
response[4] = (available >> 8) & 0xff;
2726+
response[5] = (available >> 0) & 0xff;
2727+
2728+
return 7;
2729+
}
2730+
2731+
int ble_peek(const uint8_t command[], uint8_t response[]) {
2732+
//[0] CMD_START < 0xE0 >
2733+
//[1] Command < 1 byte >
2734+
//[2] N args < 1 byte >
2735+
//[3] the number 2 < 1 byte >
2736+
//[4..5] size < 2 byte >
2737+
// this could be useless xQueuePeek
2738+
uint8_t nargs = command[2];
2739+
// if nargs != 1 -> error
2740+
size_t res = 0;
2741+
// uint16_t size = ntohs(*((uint16_t *) &command[4]));
2742+
uint16_t size = *((uint16_t *) &command[4]);
2743+
uint8_t* received = nullptr;
2744+
2745+
if(size > TO_HOST_BUF_SIZE - xRingbufferGetCurFreeSize(buf_handle)) {
2746+
size = 0;
2747+
goto exit;
2748+
}
2749+
2750+
received = (uint8_t*)xRingbufferReceiveUpTo(buf_handle, &res, pdMS_TO_TICKS(2000), size);
2751+
2752+
memcpy(&response[5], received, res);
2753+
2754+
exit:
2755+
response[2] = 1; // number of parameters
2756+
response[3] = (size >> 8) & 0xff;
2757+
response[4] = (size >> 0) & 0xff;
2758+
2759+
return 6 + res;
2760+
}
2761+
2762+
int ble_read(const uint8_t command[], uint8_t response[]) {
2763+
//[0] CMD_START < 0xE0 >
2764+
//[1] Command < 1 byte >
2765+
//[2] N args < 1 byte >
2766+
//[3] the number 2 < 1 byte >
2767+
//[4..5] size < 2 byte >
2768+
uint8_t nargs = command[2];
2769+
// if nargs != 1 -> error
2770+
size_t res = 0;
2771+
// uint16_t size = ntohs(*((uint16_t *) &command[4]));
2772+
uint16_t size = *((uint16_t *) &command[4]);
2773+
uint8_t* received = nullptr;
2774+
2775+
if(size > TO_HOST_BUF_SIZE - xRingbufferGetCurFreeSize(buf_handle)) {
2776+
size = 0;
2777+
goto exit;
2778+
}
2779+
2780+
received = (uint8_t*)xRingbufferReceiveUpTo(buf_handle, &res, pdMS_TO_TICKS(2000), size);
2781+
2782+
memcpy(&response[5], received, res);
2783+
2784+
vRingbufferReturnItem(buf_handle, received);
2785+
2786+
exit:
2787+
response[2] = 1; // number of parameters
2788+
response[3] = (size >> 8) & 0xff;
2789+
response[4] = (size >> 0) & 0xff;
2790+
2791+
return 6 + res;
2792+
}
2793+
2794+
int ble_write(const uint8_t command[], uint8_t response[]) {
2795+
//[0] CMD_START < 0xE0 >
2796+
//[1] Command < 1 byte >
2797+
//[2] N args < 1 byte >
2798+
//[3..4] size < 2 byte >
2799+
//[4..4+size] buffer < size byte >
2800+
2801+
uint8_t nargs = command[2];
2802+
// if nargs != 1 -> error
2803+
2804+
uint16_t size = ntohs(*((uint16_t *) &command[3]));
2805+
2806+
while(!esp_vhci_host_check_send_available()) { // TODO add timeout
2807+
// TODO delay
2808+
}
2809+
2810+
if (vhci_send_sem && xSemaphoreTake(vhci_send_sem, pdMS_TO_TICKS(2000)) == pdTRUE) {
2811+
esp_vhci_host_send_packet((uint8_t*)&command[5], size);
2812+
}
2813+
2814+
response[2] = 1; // number of parameters
2815+
response[3] = 2; // length of first parameter
2816+
response[4] = (size >> 0) & 0xff;
2817+
response[5] = (size >> 8) & 0xff;
2818+
2819+
return 7;
2820+
}
2821+
2822+
2823+
26032824
typedef int (*CommandHandlerType)(const uint8_t command[], uint8_t response[]);
26042825

26052826
const CommandHandlerType commandHandlers[] = {
@@ -2616,7 +2837,15 @@ const CommandHandlerType commandHandlers[] = {
26162837
disconnect, NULL, getIdxRSSI, getIdxEnct, reqHostByName, getHostByName, startScanNetworks, getFwVersion, NULL, sendUDPdata, getRemoteData, getTime, getIdxBSSID, getIdxChannel, ping, getSocket,
26172838

26182839
// 0x40 -> 0x4f
2619-
setEnt, NULL, NULL, NULL, sendDataTcp, getDataBufTcp, insertDataBuf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2840+
setEnt, NULL, NULL, NULL, sendDataTcp, getDataBufTcp, insertDataBuf, NULL, NULL, NULL,
2841+
2842+
// BLE functions 0x4a -> 0x4f
2843+
ble_begin, // 0x4a
2844+
ble_end, // 0x4b
2845+
ble_available, // 0x4c
2846+
ble_peek, // 0x4d
2847+
ble_read, // 0x4e
2848+
ble_write, // 0x4f
26202849

26212850
// 0x50 -> 0x54
26222851
setPinMode, setDigitalWrite, setAnalogWrite, getDigitalRead, getAnalogRead,

0 commit comments

Comments
 (0)