diff --git a/README.rst b/README.rst index 2cadca2..b985fa5 100644 --- a/README.rst +++ b/README.rst @@ -1,3 +1,25 @@ +export IDF_TOOLS_PATH=/home/msp/bis/work/esp/toolchain +export ADF_PATH=/home/msp/bis/work/esp/esp-adf +export IDF_PATH=/home/msp/bis/work/esp/esp-idf-v4.4.2 +. $ADF_PATH/esp-idf/export.sh + +configuring: enter menuconfig "Component config", choose "Bluetooth" enter menu Bluetooth, choose "Classic Bluetooth" and "SPP Profile" +idf.py menuconfig +idf.py build +idf.py -p /dev/ttyUSB0 flash monitor +idf.py -p /dev/ttyUSB0 monitor + +docs: +https://gitdemo.readthedocs.io/en/latest/build-system.html +https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/linux-macos-setup.html + +file:///home/msp/Downloads/WBT101-06A-ClassicBluetooth-Basic-1.pdf +https://people.csail.mit.edu/albert/bluez-intro/c404.html + +DOLIST +move to TCP? +list of MAC addrs (same as for BT?) + diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 7f070fd..7325437 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -49,6 +49,8 @@ set(COMPONENT_SRCS "espd.c pdmain.c \ ../pd/src/x_vexp.c \ ../pd/src/x_vexp_fun.c \ ../pd/src/x_vexp_if.c \ +../wifi/wifi.c \ +../wifi/net.c \ ") diff --git a/main/bluetooth.c b/main/bluetooth.c new file mode 100644 index 0000000..58bd521 --- /dev/null +++ b/main/bluetooth.c @@ -0,0 +1,210 @@ +#ifdef PD_USE_BLUETOOTH +#include "espd.h" +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_log.h" +#include "esp_bt.h" +#include "esp_bt_main.h" +#include "esp_gap_bt_api.h" +#include "esp_bt_device.h" +#include "esp_spp_api.h" + + +/* -------------------- bluetooth ------------------ */ + +static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_CB; +static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_AUTHENTICATE; +static const esp_spp_role_t role_slave = ESP_SPP_ROLE_SLAVE; + +static uint32_t pd_bt_writehandle; + +void pd_bt_writeback(unsigned char *s, int length) +{ +#if 1 + if (pd_bt_writehandle) + { + if (esp_spp_write(pd_bt_writehandle, length, s) != ESP_OK) + ESP_LOGI(TAG, "bt writeback error"); + } + else ESP_LOGI(TAG, "writeback: not open"); +#endif +} + + +static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) +{ + switch (event) { + case ESP_SPP_INIT_EVT: + ESP_LOGI(TAG, "ESP_SPP_INIT_EVT"); + esp_bt_dev_set_device_name("pure_data"); +#ifdef ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE + esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); +#else + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); +#endif + esp_spp_start_srv(sec_mask,role_slave, 0, "pd_server"); + break; + case ESP_SPP_DISCOVERY_COMP_EVT: + ESP_LOGI(TAG, "ESP_SPP_DISCOVERY_COMP_EVT"); + break; + case ESP_SPP_OPEN_EVT: + ESP_LOGI(TAG, "ESP_SPP_OPEN_EVT"); + break; + case ESP_SPP_CLOSE_EVT: + pd_bt_writehandle = 0; + ESP_LOGI(TAG, "ESP_SPP_CLOSE_EVT"); + break; + case ESP_SPP_START_EVT: + ESP_LOGI(TAG, "ESP_SPP_START_EVT"); + break; + case ESP_SPP_CL_INIT_EVT: + ESP_LOGI(TAG, "ESP_SPP_CL_INIT_EVT"); + break; + case ESP_SPP_DATA_IND_EVT: + +#if 0 + if (param->data_ind.len > 2) + ESP_LOGI(TAG, "ESP_SPP_DATA_IND_EVT len=%d handle=%d", + param->data_ind.len, param->data_ind.handle); + { + char foo[80]; + int len = (param->data_ind.len > 79 ? 79 : param->data_ind.len); + memcpy(foo, param->data_ind.data, len); + foo[len] = 0; + ESP_LOGI(TAG, "message %s", foo); + } +#endif + pd_fromhost((char *)(param->data_ind.data), param->data_ind.len); + + break; + case ESP_SPP_CONG_EVT: + ESP_LOGI(TAG, "ESP_SPP_CONG_EVT"); + break; + case ESP_SPP_WRITE_EVT: + ESP_LOGI(TAG, "ESP_SPP_WRITE_EVT"); + break; + case ESP_SPP_SRV_OPEN_EVT: + pd_bt_writehandle = param->write.handle; + // ((struct spp_open_evt_param *)param)->handle; + ESP_LOGI(TAG, "ESP_SPP_SRV_OPEN_EVT"); + break; + default: + break; + } +} + +void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) +{ + switch (event) { + case ESP_BT_GAP_AUTH_CMPL_EVT:{ + if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) { + ESP_LOGI(TAG, "authentication success: %s", param->auth_cmpl.device_name); + esp_log_buffer_hex(TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN); + } else { + ESP_LOGE(TAG, "authentication failed, status:%d", param->auth_cmpl.stat); + } + break; + } + case ESP_BT_GAP_PIN_REQ_EVT:{ + ESP_LOGI(TAG, "ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit); + if (param->pin_req.min_16_digit) { + ESP_LOGI(TAG, "Input pin code: 0000 0000 0000 0000"); + esp_bt_pin_code_t pin_code = {0}; + esp_bt_gap_pin_reply(param->pin_req.bda, true, 16, pin_code); + } else { + ESP_LOGI(TAG, "Input pin code: 1234"); + esp_bt_pin_code_t pin_code; + pin_code[0] = '1'; + pin_code[1] = '2'; + pin_code[2] = '3'; + pin_code[3] = '4'; + esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code); + } + break; + } + +#if (CONFIG_BT_SSP_ENABLED == true) + case ESP_BT_GAP_CFM_REQ_EVT: + ESP_LOGI(TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val); + esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true); + break; + case ESP_BT_GAP_KEY_NOTIF_EVT: + ESP_LOGI(TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey); + break; + case ESP_BT_GAP_KEY_REQ_EVT: + ESP_LOGI(TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!"); + break; +#endif + + default: { + ESP_LOGI(TAG, "event: %d", event); + break; + } + } + return; +} + +void bt_init( void) +{ + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK( ret ); + + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE)); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) { + ESP_LOGE(TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + + if ((ret = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) { + ESP_LOGE(TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + + if ((ret = esp_bluedroid_init()) != ESP_OK) { + ESP_LOGE(TAG, "%s initialize bluedroid failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + + if ((ret = esp_bluedroid_enable()) != ESP_OK) { + ESP_LOGE(TAG, "%s enable bluedroid failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + + if ((ret = esp_bt_gap_register_callback(esp_bt_gap_cb)) != ESP_OK) { + ESP_LOGE(TAG, "%s gap register failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + + if ((ret = esp_spp_register_callback(esp_spp_cb)) != ESP_OK) { + ESP_LOGE(TAG, "%s spp register failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + + if ((ret = esp_spp_init(esp_spp_mode)) != ESP_OK) { + ESP_LOGE(TAG, "%s spp init failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + +#if (CONFIG_BT_SSP_ENABLED == true) + /* Set default parameters for Secure Simple Pairing */ + esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE; + esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO; + esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t)); +#endif + + /* + * Set default parameters for Legacy Pairing + * Use variable pin, input pin code when pairing + */ + esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_VARIABLE; + esp_bt_pin_code_t pin_code; + esp_bt_gap_set_pin(pin_type, 0, pin_code); +} +#endif /* PD_USE_BLUETOOTH */ diff --git a/main/espd.c b/main/espd.c index 185d0fe..6978ef3 100644 --- a/main/espd.c +++ b/main/espd.c @@ -7,6 +7,7 @@ CONDITIONS OF ANY KIND, either express or implied. */ +#include "espd.h" #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -21,11 +22,6 @@ #include "mp3_decoder.h" #include "filter_resample.h" #include "board.h" -#include "esp_bt.h" -#include "esp_bt_main.h" -#include "esp_gap_bt_api.h" -#include "esp_bt_device.h" -#include "esp_spp_api.h" #include "esp_peripherals.h" #include "periph_sdcard.h" #include "nvs.h" @@ -36,9 +32,8 @@ static const char *TAG = "ESPD"; extern void pdmain_tick( void); void pdmain_init( void); -void pd_bt_poll( void); -void bt_init( void); + void sd_init( void); #define INCHANS 1 @@ -77,7 +72,57 @@ void senddacs( void) ESP_LOGE(TAG, "error writing"); } -void pd_bt_writeback(unsigned char *s, int length); +/* queue from host. Need to make this a proper RTOS queue */ +void *getbytes(size_t nbytes); +void freebytes(void *x, size_t nbytes); +void *resizebytes(void *x, size_t oldsize, size_t newsize); +static char *pd_bt_buf; +static int pd_bt_size; +static SemaphoreHandle_t pd_bt_mutex; +#include + + /* enqueue a message from host to Pd */ +void pd_fromhost(char *data, size_t size) +{ + if (!pd_bt_buf) + pd_bt_buf = getbytes(0); + if (!pd_bt_mutex) + pd_bt_mutex = xSemaphoreCreateMutex(); + while (xSemaphoreTake(pd_bt_mutex, 1) != pdTRUE) + ; + pd_bt_buf = (char *)resizebytes(pd_bt_buf, pd_bt_size, pd_bt_size+size); + memcpy(pd_bt_buf + pd_bt_size, data, size); + pd_bt_size += size; + xSemaphoreGive(pd_bt_mutex); + ESP_LOGI(TAG, "fromhost %d", size); +} + + /* dispatch messages enqueued above */ +void pd_pollhost( void) +{ + int lastchar; + if (!pd_bt_mutex) + pd_bt_mutex = xSemaphoreCreateMutex(); + if (xSemaphoreTake(pd_bt_mutex, 0) != pdTRUE) + return; + + /* only interpret this text if terminated by a semicolon */ + lastchar = pd_bt_size-1; + while (lastchar >= 0 && isspace((int)(pd_bt_buf[lastchar]))) + lastchar--; + if (lastchar > 2) + ESP_LOGI(TAG, "last %d %c", lastchar, pd_bt_buf[lastchar]); + + if (lastchar >= 3 && pd_bt_buf[lastchar] == ';' && + pd_bt_buf[lastchar-1] != '\\') + { + ESP_LOGI(TAG, "send it"); + pd_sendmsg(pd_bt_buf, pd_bt_size); + pd_bt_buf = (char *)resizebytes(pd_bt_buf, pd_bt_size, 0); + pd_bt_size = 0; + } + xSemaphoreGive(pd_bt_mutex); +} void pdmain_print( const char *s) { @@ -85,11 +130,14 @@ void pdmain_print( const char *s) strncpy(y, s, 79); y[79]=0; ESP_LOGI(TAG, "post %d: %s", strlen(y), y); +#ifdef PD_USE_BLUETOOTH if (strlen(y) > 0) pd_bt_writeback((unsigned char *)y, strlen(y)); +#endif } void trymem(int foo); +void net_alive( void); /* allow deprecated form if new one unavailable */ #ifndef I2S_COMM_FORMAT_STAND_I2S @@ -126,7 +174,9 @@ void app_main(void) i2s_set_pin(I2S_NUM_0, &i2s_pin_cfg); i2s_mclk_gpio_select(I2S_NUM_0, GPIO_NUM_0); +#ifdef PD_USE_BLUETOOTH bt_init(); +#endif sd_init(); ESP_LOGI(TAG, "[ 2 ] now write some shit"); @@ -141,253 +191,13 @@ void app_main(void) ESP_LOGI(TAG, "tick"); } */ - pd_bt_poll(); + pd_pollhost(); pdmain_tick(); senddacs(); + net_alive(); } } -/* -------------------- bluetooth and SD card ------------------ */ -/* queue from bluetooth. Need to make this a proper RTOS queue */ -static char *pd_bt_buf; -static int pd_bt_size; -static SemaphoreHandle_t pd_bt_mutex; - -void *getbytes(size_t nbytes); -void freebytes(void *x, size_t nbytes); -void *resizebytes(void *x, size_t oldsize, size_t newsize); -#include -void pd_sendmsg(char *buf, int bufsize); - -void pd_bt_dispatch(char *data, size_t size) -{ - if (!pd_bt_buf) - pd_bt_buf = getbytes(0); - if (!pd_bt_mutex) - pd_bt_mutex = xSemaphoreCreateMutex(); - while (xSemaphoreTake(pd_bt_mutex, 1) != pdTRUE) - ; - pd_bt_buf = (char *)resizebytes(pd_bt_buf, pd_bt_size, pd_bt_size+size); - memcpy(pd_bt_buf + pd_bt_size, data, size); - pd_bt_size += size; - xSemaphoreGive(pd_bt_mutex); -} - -void pd_bt_poll( void) -{ - int lastchar; - if (!pd_bt_mutex) - pd_bt_mutex = xSemaphoreCreateMutex(); - if (xSemaphoreTake(pd_bt_mutex, 0) != pdTRUE) - return; - - /* only interpret this text if terminated by a semicolon */ - lastchar = pd_bt_size-1; - while (lastchar >= 0 && isspace((int)(pd_bt_buf[lastchar]))) - lastchar--; - if (lastchar >= 3 && pd_bt_buf[lastchar] == ';' && - pd_bt_buf[lastchar-1] != '\\') - { - pd_sendmsg(pd_bt_buf, pd_bt_size); - pd_bt_buf = (char *)resizebytes(pd_bt_buf, pd_bt_size, 0); - pd_bt_size = 0; - } - xSemaphoreGive(pd_bt_mutex); -} - -static uint32_t pd_bt_writehandle; - -void pd_bt_writeback(unsigned char *s, int length) -{ -#if 1 - if (pd_bt_writehandle) - { - if (esp_spp_write(pd_bt_writehandle, length, s) != ESP_OK) - ESP_LOGI(TAG, "bt writeback error"); - } - else ESP_LOGI(TAG, "writeback: not open"); -#endif -} - -static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_CB; -static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_AUTHENTICATE; -static const esp_spp_role_t role_slave = ESP_SPP_ROLE_SLAVE; - -static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) -{ - switch (event) { - case ESP_SPP_INIT_EVT: - ESP_LOGI(TAG, "ESP_SPP_INIT_EVT"); - esp_bt_dev_set_device_name("pure_data"); -#ifdef ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE - esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); -#else - esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); -#endif - esp_spp_start_srv(sec_mask,role_slave, 0, "pd_server"); - break; - case ESP_SPP_DISCOVERY_COMP_EVT: - ESP_LOGI(TAG, "ESP_SPP_DISCOVERY_COMP_EVT"); - break; - case ESP_SPP_OPEN_EVT: - ESP_LOGI(TAG, "ESP_SPP_OPEN_EVT"); - break; - case ESP_SPP_CLOSE_EVT: - pd_bt_writehandle = 0; - ESP_LOGI(TAG, "ESP_SPP_CLOSE_EVT"); - break; - case ESP_SPP_START_EVT: - ESP_LOGI(TAG, "ESP_SPP_START_EVT"); - break; - case ESP_SPP_CL_INIT_EVT: - ESP_LOGI(TAG, "ESP_SPP_CL_INIT_EVT"); - break; - case ESP_SPP_DATA_IND_EVT: - -#if 0 - if (param->data_ind.len > 2) - ESP_LOGI(TAG, "ESP_SPP_DATA_IND_EVT len=%d handle=%d", - param->data_ind.len, param->data_ind.handle); - { - char foo[80]; - int len = (param->data_ind.len > 79 ? 79 : param->data_ind.len); - memcpy(foo, param->data_ind.data, len); - foo[len] = 0; - ESP_LOGI(TAG, "message %s", foo); - } -#endif - pd_bt_dispatch((char *)(param->data_ind.data), param->data_ind.len); - - break; - case ESP_SPP_CONG_EVT: - ESP_LOGI(TAG, "ESP_SPP_CONG_EVT"); - break; - case ESP_SPP_WRITE_EVT: - ESP_LOGI(TAG, "ESP_SPP_WRITE_EVT"); - break; - case ESP_SPP_SRV_OPEN_EVT: - pd_bt_writehandle = param->write.handle; - // ((struct spp_open_evt_param *)param)->handle; - ESP_LOGI(TAG, "ESP_SPP_SRV_OPEN_EVT"); - break; - default: - break; - } -} - -void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) -{ - switch (event) { - case ESP_BT_GAP_AUTH_CMPL_EVT:{ - if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) { - ESP_LOGI(TAG, "authentication success: %s", param->auth_cmpl.device_name); - esp_log_buffer_hex(TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN); - } else { - ESP_LOGE(TAG, "authentication failed, status:%d", param->auth_cmpl.stat); - } - break; - } - case ESP_BT_GAP_PIN_REQ_EVT:{ - ESP_LOGI(TAG, "ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit); - if (param->pin_req.min_16_digit) { - ESP_LOGI(TAG, "Input pin code: 0000 0000 0000 0000"); - esp_bt_pin_code_t pin_code = {0}; - esp_bt_gap_pin_reply(param->pin_req.bda, true, 16, pin_code); - } else { - ESP_LOGI(TAG, "Input pin code: 1234"); - esp_bt_pin_code_t pin_code; - pin_code[0] = '1'; - pin_code[1] = '2'; - pin_code[2] = '3'; - pin_code[3] = '4'; - esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code); - } - break; - } - -#if (CONFIG_BT_SSP_ENABLED == true) - case ESP_BT_GAP_CFM_REQ_EVT: - ESP_LOGI(TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val); - esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true); - break; - case ESP_BT_GAP_KEY_NOTIF_EVT: - ESP_LOGI(TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey); - break; - case ESP_BT_GAP_KEY_REQ_EVT: - ESP_LOGI(TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!"); - break; -#endif - - default: { - ESP_LOGI(TAG, "event: %d", event); - break; - } - } - return; -} - -void bt_init( void) -{ - esp_err_t ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); - } - ESP_ERROR_CHECK( ret ); - - ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE)); - - esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); - if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) { - ESP_LOGE(TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret)); - return; - } - - if ((ret = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) { - ESP_LOGE(TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret)); - return; - } - - if ((ret = esp_bluedroid_init()) != ESP_OK) { - ESP_LOGE(TAG, "%s initialize bluedroid failed: %s\n", __func__, esp_err_to_name(ret)); - return; - } - - if ((ret = esp_bluedroid_enable()) != ESP_OK) { - ESP_LOGE(TAG, "%s enable bluedroid failed: %s\n", __func__, esp_err_to_name(ret)); - return; - } - - if ((ret = esp_bt_gap_register_callback(esp_bt_gap_cb)) != ESP_OK) { - ESP_LOGE(TAG, "%s gap register failed: %s\n", __func__, esp_err_to_name(ret)); - return; - } - - if ((ret = esp_spp_register_callback(esp_spp_cb)) != ESP_OK) { - ESP_LOGE(TAG, "%s spp register failed: %s\n", __func__, esp_err_to_name(ret)); - return; - } - - if ((ret = esp_spp_init(esp_spp_mode)) != ESP_OK) { - ESP_LOGE(TAG, "%s spp init failed: %s\n", __func__, esp_err_to_name(ret)); - return; - } - -#if (CONFIG_BT_SSP_ENABLED == true) - /* Set default parameters for Secure Simple Pairing */ - esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE; - esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO; - esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t)); -#endif - - /* - * Set default parameters for Legacy Pairing - * Use variable pin, input pin code when pairing - */ - esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_VARIABLE; - esp_bt_pin_code_t pin_code; - esp_bt_gap_set_pin(pin_type, 0, pin_code); -} void sd_init( void) { @@ -399,4 +209,10 @@ void sd_init( void) // Initialize SD Card peripheral audio_board_sdcard_init(set, SD_MODE_1_LINE); +#ifdef PD_USE_WIFI + ESP_LOGI(TAG, "[ 1a ] start network"); + wifi_init(); + net_init(); +#endif + ESP_LOGI(TAG, "[ 1b ] done starting network"); } diff --git a/main/espd.h b/main/espd.h new file mode 100644 index 0000000..cc4afb9 --- /dev/null +++ b/main/espd.h @@ -0,0 +1,31 @@ +/* #define PD_USE_BLUETOOTH */ +#define PD_USE_WIFI + + +/* task priorities */ +#define PRIORITY_WIFI 2 + +#if !defined(CONFIG_LOCALE_NUMBER) || (CONFIG_LOCALE_NUMBER==0) +#define CONFIG_ESP_WIFI_SSID "Fios-3BR2s" +#define CONFIG_ESP_WIFI_PASSWORD "aid24rushed63fin" +#define CONFIG_ESP_WIFI_SENDADDR "192.168.1.177" +#define CONFIG_ESP_WIFI_SENDPORT 4498 +#define CONFIG_ESP_WIFI_LISTENPORT 4499 +#endif + +#include +void pd_sendmsg(char *buf, int bufsize); +void pd_fromhost(char *data, size_t size); + +#ifdef PD_USE_BLUETOOTH +void pd_bt_poll( void); +void bt_init( void); +void pd_bt_writeback(unsigned char *s, int length); +#endif + +#ifdef PD_USE_WIFI +void wifi_init(void); /* wifi.c - manage 802.11 connection */ +void net_init( void); /* init */ +void net_alive( void); /* send keep-alive packet if needed */ +void net_sendudp(void *msg, int len, int port); /* send whatev */ +#endif diff --git a/wifi/net.c b/wifi/net.c new file mode 100644 index 0000000..578fc61 --- /dev/null +++ b/wifi/net.c @@ -0,0 +1,118 @@ +#include "../main/espd.h" +#ifdef PD_USE_WIFI +#include "freertos/FreeRTOS.h" +#include "esp_log.h" +#include "esp_timer.h" +#include "sdkconfig.h" +#include "esp_mac.h" + +/* lwip (lightweight IP") for sockets: */ +#include "lwip/err.h" +#include "lwip/sockets.h" +#include "lwip/sys.h" +#include + +#include +#include + +static const char *TAG = "net"; + +void udpreceivertask(void *z) +{ + char rx_buffer[4000]; + int ip_protocol = 0; + struct sockaddr_in dest_addr; + + dest_addr.sin_addr.s_addr = htonl(INADDR_ANY); + dest_addr.sin_family = AF_INET; + dest_addr.sin_port = htons(CONFIG_ESP_WIFI_LISTENPORT); + ip_protocol = IPPROTO_IP; + + int rcv_sock = socket(AF_INET, SOCK_DGRAM, ip_protocol); + if (rcv_sock < 0) { + ESP_LOGE(TAG, "Unable to create socket: errno %d", errno); + return; + } + + int err = bind(rcv_sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr)); + if (err < 0) { + ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno); + } + ESP_LOGI(TAG, "Waiting for data"); + + while (1) + { + int len = recv(rcv_sock, rx_buffer, sizeof(rx_buffer) - 1, 0); + + if (len < 0) { + ESP_LOGE(TAG, "recvfrom failed: errno %d", errno); + vTaskDelay(5000 / portTICK_PERIOD_MS); + continue; + } + else if (len == 0) + { + ESP_LOGE(TAG, "unexpected EOF on socket"); + vTaskDelay(500 / portTICK_PERIOD_MS); + } + else + { + rx_buffer[len] = 0; + ESP_LOGI(TAG, "rcv: %s", rx_buffer); + pd_fromhost(rx_buffer, strlen(rx_buffer)); + } + } +} + +static int xyz_sock; +static struct sockaddr_in xyz_dest_addr; + +void net_init( void) +{ + /* socket to send over -- could use same one? */ + xyz_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); + + xyz_dest_addr.sin_addr.s_addr = inet_addr(CONFIG_ESP_WIFI_SENDADDR); + xyz_dest_addr.sin_family = AF_INET; + /* this will get overridden later: */ + xyz_dest_addr.sin_port = htons(CONFIG_ESP_WIFI_SENDPORT); + + xTaskCreate(udpreceivertask, "udprcv", 6000, NULL, PRIORITY_WIFI, NULL); +} + +static int64_t whensent; + +void net_sendudp(void *msg, int len, int port) +{ + int err; + xyz_dest_addr.sin_port = htons(port); + err = sendto(xyz_sock, msg, len, 0, + (struct sockaddr *)&xyz_dest_addr, sizeof(xyz_dest_addr)); + if (err < 0) { + static int errorcount; + errorcount++; + if (errorcount < 10 || (errorcount < 100 && !(errorcount%10)) + || !(errorcount%100)) + { + ESP_LOGE(TAG, "net send error count %d", errno); + } + } + else whensent = esp_timer_get_time(); +} + +extern char wifi_mac[]; +/* esp_err_t esp_base_mac_addr_get(uint8_t *mac); */ + +void net_alive( void) +{ + int elapsed = esp_timer_get_time() - whensent; + if (elapsed > 1000000) + { + char buf[80]; + uint8_t mac[6]; + esp_base_mac_addr_get(&mac); + sprintf(buf, "alive %02x:%02x:%02x:%02x:%02x:%02x;\n", + mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]); + net_sendudp(buf, strlen(buf), CONFIG_ESP_WIFI_SENDPORT); + } +} +#endif /* PD_USE_WIFI */ diff --git a/wifi/wifi.c b/wifi/wifi.c new file mode 100644 index 0000000..1684e79 --- /dev/null +++ b/wifi/wifi.c @@ -0,0 +1,160 @@ +/* WiFi station Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include "../main/espd.h" +#ifdef PD_USE_WIFI +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "esp_system.h" +#include "esp_wifi.h" +#include "esp_event.h" +#include "esp_log.h" +#include "nvs_flash.h" + +#include "lwip/err.h" +#include "lwip/sys.h" + +#define EXAMPLE_ESP_MAXIMUM_RETRY 5 + +/* FreeRTOS event group to signal when we are connected*/ +static EventGroupHandle_t s_wifi_event_group; + +/* The event group allows multiple bits for each event, but we only care about two events: + * - we are connected to the AP with an IP + * - we failed to connect after the maximum amount of retries */ +#define WIFI_CONNECTED_BIT BIT0 +#define WIFI_FAIL_BIT BIT1 + +static const char *TAG = "wifi station"; +static int s_retry_num = 0; +char wifi_mac[80]; + +static void event_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) +{ + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { + esp_wifi_connect(); + } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { + if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) { + esp_wifi_connect(); + s_retry_num++; + ESP_LOGI(TAG, "retry to connect to the AP"); + } else { + xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); + } + ESP_LOGI(TAG,"connect to the AP fail"); + } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { + ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; + ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); + s_retry_num = 0; + xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + } +} + +void wifi_init_sta(void) +{ + s_wifi_event_group = xEventGroupCreate(); + + ESP_ERROR_CHECK(esp_netif_init()); + + ESP_ERROR_CHECK(esp_event_loop_create_default()); + esp_netif_create_default_wifi_sta(); + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + + esp_event_handler_instance_t instance_any_id; + esp_event_handler_instance_t instance_got_ip; + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &event_handler, + NULL, + &instance_any_id)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, + IP_EVENT_STA_GOT_IP, + &event_handler, + NULL, + &instance_got_ip)); + + wifi_config_t wifi_config = { + .sta = { + .ssid = CONFIG_ESP_WIFI_SSID, + .password = CONFIG_ESP_WIFI_PASSWORD, + /* Setting a password implies station will connect to all security modes including WEP/WPA. + * However these modes are deprecated and not advisable to be used. Incase your Access point + * doesn't support WPA2, these mode can be enabled by commenting below line */ + /* .threshold.authmode = WIFI_AUTH_WPA2_PSK, */ + + .pmf_cfg = { + .capable = true, + .required = false + }, + }, + }; + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); + ESP_ERROR_CHECK(esp_wifi_start() ); + ESP_ERROR_CHECK(esp_wifi_get_config(WIFI_IF_STA, &wifi_config) ); + + ESP_LOGI(TAG, "wifi_init_sta finished, MAC %02x:%02x:%02x:%02x:%02x:%02x", + wifi_config.sta.bssid[0], + wifi_config.sta.bssid[1], + wifi_config.sta.bssid[2], + wifi_config.sta.bssid[3], + wifi_config.sta.bssid[4], + wifi_config.sta.bssid[5]); + sprintf(wifi_mac, "%02x:%02x:%02x:%02x:%02x:%02x", + wifi_config.sta.bssid[0], + wifi_config.sta.bssid[1], + wifi_config.sta.bssid[2], + wifi_config.sta.bssid[3], + wifi_config.sta.bssid[4], + wifi_config.sta.bssid[5]); + + /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum + * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */ + EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, + WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, + pdFALSE, + pdFALSE, + portMAX_DELAY); + + /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually + * happened. */ + if (bits & WIFI_CONNECTED_BIT) { + ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", + CONFIG_ESP_WIFI_SSID, CONFIG_ESP_WIFI_PASSWORD); + } else if (bits & WIFI_FAIL_BIT) { + ESP_LOGE(TAG, "Failed to connect to SSID:%s, password:%s", + CONFIG_ESP_WIFI_SSID, CONFIG_ESP_WIFI_PASSWORD); + } else { + ESP_LOGE(TAG, "UNEXPECTED EVENT"); + } + + /* The event will not be processed after unregister */ + ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip)); + ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id)); + vEventGroupDelete(s_wifi_event_group); +} + +void wifi_init(void) +{ + //Initialize NVS + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); + wifi_init_sta(); +} +#endif /* PD_USE_WIFI */