Skip to content

Commit 35d7730

Browse files
adding bluetooth vhci in command handler
1 parent 7bb7962 commit 35d7730

File tree

1 file changed

+228
-1
lines changed

1 file changed

+228
-1
lines changed

main/CommandHandler.cpp

Lines changed: 228 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2072,6 +2072,225 @@ int socket_getpeername(const uint8_t command[], uint8_t response[])
20722072
return 14;
20732073
}
20742074

2075+
/*
2076+
* BLE vHCI API
2077+
*/
2078+
#include "esp_bt.h"
2079+
2080+
#define TO_HOST_BUF_SIZE 256 // bytes
2081+
static RingbufHandle_t buf_handle = NULL;
2082+
static SemaphoreHandle_t vhci_send_sem = NULL;
2083+
2084+
static void controller_rcv_pkt_ready() {
2085+
if (vhci_send_sem) {
2086+
xSemaphoreGive(vhci_send_sem);
2087+
}
2088+
}
2089+
2090+
/*
2091+
* The following callback is called when the bt controller has some data available
2092+
* this data is put into a queue that is then consumed by calling ble_read
2093+
*/
2094+
static int host_rcv_pkt(uint8_t *data, uint16_t len) {
2095+
if(buf_handle == NULL) {
2096+
ets_printf("failed host_rcv_pkt\n");
2097+
return ESP_FAIL;
2098+
}
2099+
2100+
UBaseType_t res = xRingbufferSend(buf_handle, data, len, pdMS_TO_TICKS(2000)); // TODO verify xTicksToWait value
2101+
2102+
if (res != pdTRUE) {
2103+
ets_printf("unable to send data to ring buffer\n");
2104+
}
2105+
return ESP_OK;
2106+
}
2107+
2108+
static esp_bt_controller_config_t btControllerConfig = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
2109+
static esp_vhci_host_callback_t vhciHostCb = {
2110+
controller_rcv_pkt_ready,
2111+
host_rcv_pkt
2112+
};
2113+
2114+
int ble_begin(const uint8_t command[], uint8_t response[]) {
2115+
//[0] CMD_START < 0xE0 >
2116+
//[1] Command < 1 byte >
2117+
2118+
esp_err_t ret = ESP_OK;
2119+
2120+
if((ret = esp_bt_controller_init(&btControllerConfig)) != ESP_OK) {
2121+
ets_printf("failed esp_bt_controller_init %s\n", esp_err_to_name(ret));
2122+
2123+
goto exit;
2124+
}
2125+
2126+
while (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE);
2127+
2128+
if((ret = esp_bt_controller_enable(ESP_BT_MODE_BLE)) != ESP_OK) {
2129+
ets_printf("failed esp_bt_controller_enable %s\n", esp_err_to_name(ret));
2130+
2131+
goto exit;
2132+
}
2133+
2134+
if((buf_handle = xRingbufferCreate(TO_HOST_BUF_SIZE, RINGBUF_TYPE_BYTEBUF)) == NULL) {
2135+
ret = ESP_ERR_NO_MEM;
2136+
ets_printf("failed xRingbufferCreate\n");
2137+
2138+
goto exit;
2139+
}
2140+
2141+
vhci_send_sem = xSemaphoreCreateBinary();
2142+
if (vhci_send_sem == NULL) {
2143+
ets_printf("Failed to create VHCI send sem\n");
2144+
ret = ESP_ERR_NO_MEM;
2145+
goto exit;
2146+
}
2147+
xSemaphoreGive(vhci_send_sem);
2148+
2149+
esp_bt_sleep_enable();
2150+
2151+
esp_vhci_host_register_callback(&vhciHostCb);
2152+
2153+
exit:
2154+
response[2] = 1; // number of parameters
2155+
response[3] = 1; // length of first parameter
2156+
response[4] = ret;
2157+
2158+
return 6;
2159+
}
2160+
2161+
int ble_end(const uint8_t command[], uint8_t response[]) {
2162+
//[0] CMD_START < 0xE0 >
2163+
//[1] Command < 1 byte >
2164+
2165+
esp_bt_controller_disable();
2166+
esp_bt_controller_deinit();
2167+
2168+
if(buf_handle != NULL) {
2169+
vRingbufferDelete(buf_handle);
2170+
}
2171+
2172+
if (vhci_send_sem != NULL) {
2173+
/* Dummy take and give sema before deleting it */
2174+
xSemaphoreTake(vhci_send_sem, pdMS_TO_TICKS(2000));
2175+
xSemaphoreGive(vhci_send_sem);
2176+
vSemaphoreDelete(vhci_send_sem);
2177+
vhci_send_sem = NULL;
2178+
}
2179+
2180+
response[2] = 1; // number of parameters
2181+
response[3] = 1; // length of first parameter
2182+
response[4] = 1;
2183+
2184+
return 6;
2185+
}
2186+
2187+
int ble_available(const uint8_t command[], uint8_t response[]) {
2188+
//[0] CMD_START < 0xE0 >
2189+
//[1] Command < 1 byte >
2190+
uint16_t available = 0;
2191+
if(buf_handle != NULL) {
2192+
available = TO_HOST_BUF_SIZE - xRingbufferGetCurFreeSize(buf_handle);
2193+
}
2194+
2195+
response[2] = 1; // number of parameters
2196+
response[3] = 2; // length of first parameter
2197+
response[4] = (available >> 8) & 0xff;
2198+
response[5] = (available >> 0) & 0xff;
2199+
2200+
return 7;
2201+
}
2202+
2203+
int ble_peek(const uint8_t command[], uint8_t response[]) {
2204+
//[0] CMD_START < 0xE0 >
2205+
//[1] Command < 1 byte >
2206+
//[2] N args < 1 byte >
2207+
//[3] the number 2 < 1 byte >
2208+
//[4..5] size < 2 byte >
2209+
// this could be useless xQueuePeek
2210+
uint8_t nargs = command[2];
2211+
// if nargs != 1 -> error
2212+
size_t res = 0;
2213+
// uint16_t size = ntohs(*((uint16_t *) &command[4]));
2214+
uint16_t size = *((uint16_t *) &command[4]);
2215+
uint8_t* received = nullptr;
2216+
2217+
if(size > TO_HOST_BUF_SIZE - xRingbufferGetCurFreeSize(buf_handle)) {
2218+
size = 0;
2219+
goto exit;
2220+
}
2221+
2222+
received = (uint8_t*)xRingbufferReceiveUpTo(buf_handle, &res, pdMS_TO_TICKS(2000), size);
2223+
2224+
memcpy(&response[5], received, res);
2225+
2226+
exit:
2227+
response[2] = 1; // number of parameters
2228+
response[3] = (size >> 8) & 0xff;
2229+
response[4] = (size >> 0) & 0xff;
2230+
2231+
return 6 + res;
2232+
}
2233+
2234+
int ble_read(const uint8_t command[], uint8_t response[]) {
2235+
//[0] CMD_START < 0xE0 >
2236+
//[1] Command < 1 byte >
2237+
//[2] N args < 1 byte >
2238+
//[3] the number 2 < 1 byte >
2239+
//[4..5] size < 2 byte >
2240+
uint8_t nargs = command[2];
2241+
// if nargs != 1 -> error
2242+
size_t res = 0;
2243+
// uint16_t size = ntohs(*((uint16_t *) &command[4]));
2244+
uint16_t size = *((uint16_t *) &command[4]);
2245+
uint8_t* received = nullptr;
2246+
2247+
if(size > TO_HOST_BUF_SIZE - xRingbufferGetCurFreeSize(buf_handle)) {
2248+
size = 0;
2249+
goto exit;
2250+
}
2251+
2252+
received = (uint8_t*)xRingbufferReceiveUpTo(buf_handle, &res, pdMS_TO_TICKS(2000), size);
2253+
2254+
memcpy(&response[5], received, res);
2255+
2256+
vRingbufferReturnItem(buf_handle, received);
2257+
2258+
exit:
2259+
response[2] = 1; // number of parameters
2260+
response[3] = (size >> 8) & 0xff;
2261+
response[4] = (size >> 0) & 0xff;
2262+
2263+
return 6 + res;
2264+
}
2265+
2266+
int ble_write(const uint8_t command[], uint8_t response[]) {
2267+
//[0] CMD_START < 0xE0 >
2268+
//[1] Command < 1 byte >
2269+
//[2] N args < 1 byte >
2270+
//[3..4] size < 2 byte >
2271+
//[4..4+size] buffer < size byte >
2272+
2273+
uint8_t nargs = command[2];
2274+
// if nargs != 1 -> error
2275+
2276+
uint16_t size = ntohs(*((uint16_t *) &command[3]));
2277+
2278+
while(!esp_vhci_host_check_send_available()) { // TODO add timeout
2279+
// TODO delay
2280+
}
2281+
2282+
if (vhci_send_sem && xSemaphoreTake(vhci_send_sem, pdMS_TO_TICKS(2000)) == pdTRUE) {
2283+
esp_vhci_host_send_packet((uint8_t*)&command[5], size);
2284+
}
2285+
2286+
response[2] = 1; // number of parameters
2287+
response[3] = 2; // length of first parameter
2288+
response[4] = (size >> 0) & 0xff;
2289+
response[5] = (size >> 8) & 0xff;
2290+
2291+
return 7;
2292+
}
2293+
20752294
typedef int (*CommandHandlerType)(const uint8_t command[], uint8_t response[]);
20762295

20772296
const CommandHandlerType commandHandlers[] = {
@@ -2088,7 +2307,15 @@ const CommandHandlerType commandHandlers[] = {
20882307
disconnect, NULL, getIdxRSSI, getIdxEnct, reqHostByName, getHostByName, startScanNetworks, getFwVersion, NULL, sendUDPdata, getRemoteData, getTime, getIdxBSSID, getIdxChannel, ping, getSocket,
20892308

20902309
// 0x40 -> 0x4f
2091-
setEnt, NULL, NULL, NULL, sendDataTcp, getDataBufTcp, insertDataBuf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2310+
setEnt, NULL, NULL, NULL, sendDataTcp, getDataBufTcp, insertDataBuf, NULL, NULL, NULL,
2311+
2312+
// BLE functions 0x4a -> 0x4f
2313+
ble_begin, // 0x4a
2314+
ble_end, // 0x4b
2315+
ble_available, // 0x4c
2316+
ble_peek, // 0x4d
2317+
ble_read, // 0x4e
2318+
ble_write, // 0x4f
20922319

20932320
// 0x50 -> 0x5f
20942321
setPinMode, setDigitalWrite, setAnalogWrite, getDigitalRead, getAnalogRead, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,

0 commit comments

Comments
 (0)