@@ -2072,6 +2072,225 @@ int socket_getpeername(const uint8_t command[], uint8_t response[])
2072
2072
return 14 ;
2073
2073
}
2074
2074
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
+
2075
2294
typedef int (*CommandHandlerType)(const uint8_t command[], uint8_t response[]);
2076
2295
2077
2296
const CommandHandlerType commandHandlers[] = {
@@ -2088,7 +2307,15 @@ const CommandHandlerType commandHandlers[] = {
2088
2307
disconnect, NULL , getIdxRSSI, getIdxEnct, reqHostByName, getHostByName, startScanNetworks, getFwVersion, NULL , sendUDPdata, getRemoteData, getTime, getIdxBSSID, getIdxChannel, ping, getSocket,
2089
2308
2090
2309
// 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
2092
2319
2093
2320
// 0x50 -> 0x5f
2094
2321
setPinMode, setDigitalWrite, setAnalogWrite, getDigitalRead, getAnalogRead, NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL ,
0 commit comments