Skip to content

Commit 67f6ce2

Browse files
adding bluetooth vhci in command handler
1 parent 11257e4 commit 67f6ce2

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
@@ -2506,6 +2506,227 @@ int pref_getType(const uint8_t command[], uint8_t response[]) {
25062506
return 6;
25072507
}
25082508

2509+
/*
2510+
* BLE vHCI API
2511+
*/
2512+
#include "esp_bt.h"
2513+
2514+
#define TO_HOST_BUF_SIZE 256 // bytes
2515+
static RingbufHandle_t buf_handle = NULL;
2516+
static SemaphoreHandle_t vhci_send_sem = NULL;
2517+
2518+
static void controller_rcv_pkt_ready() {
2519+
if (vhci_send_sem) {
2520+
xSemaphoreGive(vhci_send_sem);
2521+
}
2522+
}
2523+
2524+
/*
2525+
* The following callback is called when the bt controller has some data available
2526+
* this data is put into a queue that is then consumed by calling ble_read
2527+
*/
2528+
static int host_rcv_pkt(uint8_t *data, uint16_t len) {
2529+
if(buf_handle == NULL) {
2530+
ets_printf("failed host_rcv_pkt\n");
2531+
return ESP_FAIL;
2532+
}
2533+
2534+
UBaseType_t res = xRingbufferSend(buf_handle, data, len, pdMS_TO_TICKS(2000)); // TODO verify xTicksToWait value
2535+
2536+
if (res != pdTRUE) {
2537+
ets_printf("unable to send data to ring buffer\n");
2538+
}
2539+
return ESP_OK;
2540+
}
2541+
2542+
static esp_bt_controller_config_t btControllerConfig = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
2543+
static esp_vhci_host_callback_t vhciHostCb = {
2544+
controller_rcv_pkt_ready,
2545+
host_rcv_pkt
2546+
};
2547+
2548+
int ble_begin(const uint8_t command[], uint8_t response[]) {
2549+
//[0] CMD_START < 0xE0 >
2550+
//[1] Command < 1 byte >
2551+
2552+
esp_err_t ret = ESP_OK;
2553+
2554+
if((ret = esp_bt_controller_init(&btControllerConfig)) != ESP_OK) {
2555+
ets_printf("failed esp_bt_controller_init %s\n", esp_err_to_name(ret));
2556+
2557+
goto exit;
2558+
}
2559+
2560+
while (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE);
2561+
2562+
if((ret = esp_bt_controller_enable(ESP_BT_MODE_BLE)) != ESP_OK) {
2563+
ets_printf("failed esp_bt_controller_enable %s\n", esp_err_to_name(ret));
2564+
2565+
goto exit;
2566+
}
2567+
2568+
if((buf_handle = xRingbufferCreate(TO_HOST_BUF_SIZE, RINGBUF_TYPE_BYTEBUF)) == NULL) {
2569+
ret = ESP_ERR_NO_MEM;
2570+
ets_printf("failed xRingbufferCreate\n");
2571+
2572+
goto exit;
2573+
}
2574+
2575+
vhci_send_sem = xSemaphoreCreateBinary();
2576+
if (vhci_send_sem == NULL) {
2577+
ets_printf("Failed to create VHCI send sem\n");
2578+
ret = ESP_ERR_NO_MEM;
2579+
goto exit;
2580+
}
2581+
xSemaphoreGive(vhci_send_sem);
2582+
2583+
esp_bt_sleep_enable();
2584+
2585+
esp_vhci_host_register_callback(&vhciHostCb);
2586+
2587+
exit:
2588+
response[2] = 1; // number of parameters
2589+
response[3] = 1; // length of first parameter
2590+
response[4] = ret;
2591+
2592+
return 6;
2593+
}
2594+
2595+
int ble_end(const uint8_t command[], uint8_t response[]) {
2596+
//[0] CMD_START < 0xE0 >
2597+
//[1] Command < 1 byte >
2598+
2599+
esp_bt_controller_disable();
2600+
esp_bt_controller_deinit();
2601+
2602+
if(buf_handle != NULL) {
2603+
vRingbufferDelete(buf_handle);
2604+
}
2605+
2606+
if (vhci_send_sem != NULL) {
2607+
/* Dummy take and give sema before deleting it */
2608+
xSemaphoreTake(vhci_send_sem, pdMS_TO_TICKS(2000));
2609+
xSemaphoreGive(vhci_send_sem);
2610+
vSemaphoreDelete(vhci_send_sem);
2611+
vhci_send_sem = NULL;
2612+
}
2613+
2614+
response[2] = 1; // number of parameters
2615+
response[3] = 1; // length of first parameter
2616+
response[4] = 1;
2617+
2618+
return 6;
2619+
}
2620+
2621+
int ble_available(const uint8_t command[], uint8_t response[]) {
2622+
//[0] CMD_START < 0xE0 >
2623+
//[1] Command < 1 byte >
2624+
uint16_t available = 0;
2625+
if(buf_handle != NULL) {
2626+
available = TO_HOST_BUF_SIZE - xRingbufferGetCurFreeSize(buf_handle);
2627+
}
2628+
2629+
response[2] = 1; // number of parameters
2630+
response[3] = 2; // length of first parameter
2631+
response[4] = (available >> 8) & 0xff;
2632+
response[5] = (available >> 0) & 0xff;
2633+
2634+
return 7;
2635+
}
2636+
2637+
int ble_peek(const uint8_t command[], uint8_t response[]) {
2638+
//[0] CMD_START < 0xE0 >
2639+
//[1] Command < 1 byte >
2640+
//[2] N args < 1 byte >
2641+
//[3] the number 2 < 1 byte >
2642+
//[4..5] size < 2 byte >
2643+
// this could be useless xQueuePeek
2644+
uint8_t nargs = command[2];
2645+
// if nargs != 1 -> error
2646+
size_t res = 0;
2647+
// uint16_t size = ntohs(*((uint16_t *) &command[4]));
2648+
uint16_t size = *((uint16_t *) &command[4]);
2649+
uint8_t* received = nullptr;
2650+
2651+
if(size > TO_HOST_BUF_SIZE - xRingbufferGetCurFreeSize(buf_handle)) {
2652+
size = 0;
2653+
goto exit;
2654+
}
2655+
2656+
received = (uint8_t*)xRingbufferReceiveUpTo(buf_handle, &res, pdMS_TO_TICKS(2000), size);
2657+
2658+
memcpy(&response[5], received, res);
2659+
2660+
exit:
2661+
response[2] = 1; // number of parameters
2662+
response[3] = (size >> 8) & 0xff;
2663+
response[4] = (size >> 0) & 0xff;
2664+
2665+
return 6 + res;
2666+
}
2667+
2668+
int ble_read(const uint8_t command[], uint8_t response[]) {
2669+
//[0] CMD_START < 0xE0 >
2670+
//[1] Command < 1 byte >
2671+
//[2] N args < 1 byte >
2672+
//[3] the number 2 < 1 byte >
2673+
//[4..5] size < 2 byte >
2674+
uint8_t nargs = command[2];
2675+
// if nargs != 1 -> error
2676+
size_t res = 0;
2677+
// uint16_t size = ntohs(*((uint16_t *) &command[4]));
2678+
uint16_t size = *((uint16_t *) &command[4]);
2679+
uint8_t* received = nullptr;
2680+
2681+
if(size > TO_HOST_BUF_SIZE - xRingbufferGetCurFreeSize(buf_handle)) {
2682+
size = 0;
2683+
goto exit;
2684+
}
2685+
2686+
received = (uint8_t*)xRingbufferReceiveUpTo(buf_handle, &res, pdMS_TO_TICKS(2000), size);
2687+
2688+
memcpy(&response[5], received, res);
2689+
2690+
vRingbufferReturnItem(buf_handle, received);
2691+
2692+
exit:
2693+
response[2] = 1; // number of parameters
2694+
response[3] = (size >> 8) & 0xff;
2695+
response[4] = (size >> 0) & 0xff;
2696+
2697+
return 6 + res;
2698+
}
2699+
2700+
int ble_write(const uint8_t command[], uint8_t response[]) {
2701+
//[0] CMD_START < 0xE0 >
2702+
//[1] Command < 1 byte >
2703+
//[2] N args < 1 byte >
2704+
//[3..4] size < 2 byte >
2705+
//[4..4+size] buffer < size byte >
2706+
2707+
uint8_t nargs = command[2];
2708+
// if nargs != 1 -> error
2709+
2710+
uint16_t size = ntohs(*((uint16_t *) &command[3]));
2711+
2712+
while(!esp_vhci_host_check_send_available()) { // TODO add timeout
2713+
// TODO delay
2714+
}
2715+
2716+
if (vhci_send_sem && xSemaphoreTake(vhci_send_sem, pdMS_TO_TICKS(2000)) == pdTRUE) {
2717+
esp_vhci_host_send_packet((uint8_t*)&command[5], size);
2718+
}
2719+
2720+
response[2] = 1; // number of parameters
2721+
response[3] = 2; // length of first parameter
2722+
response[4] = (size >> 0) & 0xff;
2723+
response[5] = (size >> 8) & 0xff;
2724+
2725+
return 7;
2726+
}
2727+
2728+
2729+
25092730
typedef int (*CommandHandlerType)(const uint8_t command[], uint8_t response[]);
25102731

25112732
const CommandHandlerType commandHandlers[] = {
@@ -2522,7 +2743,15 @@ const CommandHandlerType commandHandlers[] = {
25222743
disconnect, NULL, getIdxRSSI, getIdxEnct, reqHostByName, getHostByName, startScanNetworks, getFwVersion, NULL, sendUDPdata, getRemoteData, getTime, getIdxBSSID, getIdxChannel, ping, getSocket,
25232744

25242745
// 0x40 -> 0x4f
2525-
setEnt, NULL, NULL, NULL, sendDataTcp, getDataBufTcp, insertDataBuf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2746+
setEnt, NULL, NULL, NULL, sendDataTcp, getDataBufTcp, insertDataBuf, NULL, NULL, NULL,
2747+
2748+
// BLE functions 0x4a -> 0x4f
2749+
ble_begin, // 0x4a
2750+
ble_end, // 0x4b
2751+
ble_available, // 0x4c
2752+
ble_peek, // 0x4d
2753+
ble_read, // 0x4e
2754+
ble_write, // 0x4f
25262755

25272756
// 0x50 -> 0x54
25282757
setPinMode, setDigitalWrite, setAnalogWrite, getDigitalRead, getAnalogRead,

0 commit comments

Comments
 (0)