diff --git a/README.md b/README.md index e9add25..545c0bb 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,11 @@ CANbus to http bridge using esp32. It's purpose is to be a bridge between a CAN-Bus and a HTTP-Server. -![slide0001](https://user-images.githubusercontent.com/6020549/124377885-62528d00-dce9-11eb-8995-265a249d968d.jpg) +![slide0001](https://user-images.githubusercontent.com/6020549/125028569-3ce7c980-e0c3-11eb-8450-6aabb9a564d6.jpg) +![slide0002](https://user-images.githubusercontent.com/6020549/125028561-3b1e0600-e0c3-11eb-81bc-670b8b510847.jpg) You can visualize CAN-Frame using a visualization library such as Matplotlib. - -![slide0002](https://user-images.githubusercontent.com/6020549/124377889-65e61400-dce9-11eb-8ff0-4aad3f55eefc.jpg) - -I inspired from [here](https://github.com/c3re/can2mqtt). +![slide0003](https://user-images.githubusercontent.com/6020549/125028566-3c4f3300-e0c3-11eb-8f16-bf86126a75c2.jpg) # Software requirement esp-idf v4.2-dev-2243 or later. @@ -100,7 +98,13 @@ idf.py flash ![config-can](https://user-images.githubusercontent.com/6020549/123870665-a05c5380-d96d-11eb-89b1-78a274bfd957.jpg) ## WiFi Setting -![config-wifi](https://user-images.githubusercontent.com/6020549/123870681-a81bf800-d96d-11eb-8637-66295408b055.jpg) +![config-wifi-1](https://user-images.githubusercontent.com/6020549/125028704-73254900-e0c3-11eb-9a44-25482d7a08be.jpg) + +You can use static IP. +![config-wifi-2](https://user-images.githubusercontent.com/6020549/125028738-80423800-e0c3-11eb-984f-9dc4f892bdb6.jpg) + +Connect using mDNS. +![config-wifi-3](https://user-images.githubusercontent.com/6020549/125028763-89cba000-e0c3-11eb-921d-9baca5ec58d4.jpg) ## HTTP Server Setting ![config-http](https://user-images.githubusercontent.com/6020549/123873614-b5d37c80-d971-11eb-8ead-827f52aed982.jpg) @@ -111,8 +115,8 @@ The file can2http.csv has three columns. In the first column you need to specify the CAN Frame type. The CAN frame type is either S(Standard frame) or E(Extended frame). In the second column you have to specify the CAN-ID as a __hexdecimal number__. -In the last column you have to specify the HTTP-POST-Path. -Each CAN-ID and each HTTP-POST-Path is allowed to appear only once in the whole file. +In the last column you have to specify the HTTP-POST-Path of external HTTP server. +Each CAN-ID is allowed to appear only once in the whole file. ``` S,101,/post @@ -121,20 +125,39 @@ S,103,/post E,103,/post ``` -When a Standard CAN frame with ID 0x101 is received, POST with the "/post" PATH. -When a Extended CAN frame with ID 0x101 is received, POST with the "/post" PATH. - -# POST Parameter Example -``` -{'canid':257, 'frame': 'standard', 'data': [1,2,3,4,5,6,7,8]} -{'canid':257, 'frame': 'extended', 'data': [1,2,3,4,5,6,7,8]} -{'canid':259, 'frame': 'standard', 'data': [1,2,3,4,5,6,7,8]} -{'canid':259, 'frame': 'extended', 'data': [1,2,3,4,5,6,7,8]} -``` - When a CAN frame with ID 0x101 is received, POST with the 'canid':257. When a CAN frame with ID 0x103 is received, POST with the 'canid':259. +POST Parameter Example: +``` +{"canid":257, "frame": "standard", "data": [16, 17, 18]} +{"canid":257, "frame": "extended", "data": [16, 17, 18]} +{"canid":259, "frame": "standard", "data": [16, 17, 18]} +{"canid":259, "frame": "extended", "data": [16, 17, 18]} +``` + +# Definition from HTTP to CANbus +When HTTP POST is received, it is sent by CANBus according to csv/http2can.csv. +Other than this, it is the same as csv/can2http.csv. +In the last column you have to specify the HTTP-POST-Path of built-in HTTP server. + +``` +S,201,/receive +E,201,/receive +S,203,/receive +E,203,/receive +``` + +When receiving the {"canid": 513, "frame": "standard", "data": [16, 17, 18]}, send the Standard CAN frame with ID 0x201. +When receiving the {"canid": 515, "frame": "extended", "data": [16, 17, 18]}, send the Extended CAN frame with ID 0x201. + + +# Send message using curl +``` +$ curl -X POST -H "Content-Type: application/json" -d '{"canid": 513, "frame": "standard", "data": [16, 17, 18]}' http://esp32-server.local:8000/api/twai/send + +$ curl -X POST -H "Content-Type: application/json" -d '{"canid": 513, "frame": "extended", "data": [16, 17, 18]}' http://esp32-server.local:8000/api/twai/send +``` # HTTP Server Using Tornado ``` diff --git a/csv/can2http.csv b/csv/can2http.csv index df7422e..e4e8e53 100644 --- a/csv/can2http.csv +++ b/csv/can2http.csv @@ -2,8 +2,8 @@ #In the first column you need to specify the CAN Frame type. #The CAN frame type is either S(Standard frame) or E(Extended frame). #In the second column you have to specify the CAN-ID as a __hexdecimal number__. -#In the last column you have to specify the HTTP-Path. -#Each CAN-ID and each HTTP-Path is allowed to appear only once in the whole file. +#In the last column you have to specify the PATH of external web server. +#Each CAN-ID is allowed to appear only once in the whole file. S,101,/post E,101,/post diff --git a/csv/http2can.csv b/csv/http2can.csv new file mode 100644 index 0000000..3d2970b --- /dev/null +++ b/csv/http2can.csv @@ -0,0 +1,11 @@ +#The file mqtt2can.csv has three columns. +#In the first column you need to specify the CAN Frame type. +#The CAN frame type is either S(Standard frame) or E(Extended frame). +#In the second column you have to specify the CAN-ID as a __hexdecimal number__. +#In the last column you have to specify the PATH of built-in web server. +#Each CAN-ID is allowed to appear only once in the whole file. + +S,201,/receive +E,201,/receive +S,203,/receive +E,203,/receive diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 2103cc0..56a880f 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,4 +1,4 @@ -set(COMPONENT_SRCS "main.c" "http_post.c" "twai.c") +set(COMPONENT_SRCS "main.c" "http_post.c" "http_server.c" "twai.c") set(COMPONENT_ADD_INCLUDEDIRS ".") register_component() diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index 0bb7aa0..8f1dbec 100644 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -90,6 +90,39 @@ menu "Application Configuration" help Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent. + config MDNS_HOSTNAME + string "mDNS Hostname" + default "esp32-server" + help + The mDNS host name used by the ESP32. + + config STATIC_IP + bool "Enable Static IP Address" + default false + help + Enable Static IP Address. + + config STATIC_IP_ADDRESS + depends on STATIC_IP + string "Static IP Address" + default "192.168.10.100" + help + Static IP Address for Station. + + config STATIC_GW_ADDRESS + depends on STATIC_IP + string "Static GW Address" + default "192.168.10.1" + help + Static GW Address for Station. + + config STATIC_NM_ADDRESS + depends on STATIC_IP + string "Static Netmask" + default "255.255.255.0" + help + Static Netmask for Station. + endmenu menu "HTTP Server Setting" diff --git a/main/http_post.c b/main/http_post.c index 9a7f0b8..a76a2a8 100644 --- a/main/http_post.c +++ b/main/http_post.c @@ -22,7 +22,7 @@ static const char *TAG = "HTTP"; -extern QueueHandle_t xQueue_http; +extern QueueHandle_t xQueue_http_client; esp_err_t _http_event_handler(esp_http_client_event_t *evt) { @@ -151,7 +151,7 @@ void http_client_task(void *pvParameters) ESP_LOGI(TAG, "Start HTTP Client: http://%s:%d", CONFIG_WEB_SERVER, CONFIG_WEB_PORT); FRAME_t frameBuf; while (1) { - xQueueReceive(xQueue_http, &frameBuf, portMAX_DELAY); + xQueueReceive(xQueue_http_client, &frameBuf, portMAX_DELAY); ESP_LOGI(TAG, "canid=%x ext=%d topic=[%s]", frameBuf.canid, frameBuf.ext, frameBuf.topic); for(int i=0;i +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "esp_log.h" +#include "esp_err.h" +#include "esp_vfs.h" +#include "esp_spiffs.h" +#include "esp_http_server.h" +#include "cJSON.h" +#include "driver/twai.h" + +#include "twai.h" + +static const char *TAG = "SERVER"; +//static SemaphoreHandle_t ctrl_task_sem; + +extern QueueHandle_t xQueue_twai_tx; +extern TOPIC_t *subscribe; +extern int16_t nsubscribe; + +#define SCRATCH_BUFSIZE (1024) + +typedef struct rest_server_context { + char base_path[ESP_VFS_PATH_MAX + 1]; // Not used in this project + char scratch[SCRATCH_BUFSIZE]; +} rest_server_context_t; + + +/* Handler for roor get handler */ +static esp_err_t root_get_handler(httpd_req_t *req) +{ + ESP_LOGI(TAG, "root_get_handler req->uri=[%s]", req->uri); + for(int index=0;index"); + + httpd_resp_sendstr_chunk(req, ""); + httpd_resp_sendstr_chunk(req, ""); + + char chunk[64]; + for(int index=0;index"); + sprintf(chunk, "", frameType); + httpd_resp_sendstr_chunk(req, chunk); + sprintf(chunk, "", subscribe[index].canid); + httpd_resp_sendstr_chunk(req, chunk); + sprintf(chunk, "", subscribe[index].topic); + httpd_resp_sendstr_chunk(req, chunk); + httpd_resp_sendstr_chunk(req, ""); + } + + /* Finish the table */ + httpd_resp_sendstr_chunk(req, "
Frame TypeFrame IDHTTP Path
%16s%x%s
"); + + /* Send remaining chunk of HTML file to complete it */ + httpd_resp_sendstr_chunk(req, ""); + + /* Send empty chunk to signal HTTP response completion */ + httpd_resp_sendstr_chunk(req, NULL); + + return ESP_OK; +} + +/* Handler for getting system information handler */ +// curl 'http://esp32-server.local:8000/api/system/info' | python -m json.tool +static esp_err_t system_info_get_handler(httpd_req_t *req) +{ + ESP_LOGI(TAG, "system_info_get_handler req->uri=[%s]", req->uri); + httpd_resp_set_type(req, "application/json"); + cJSON *root = cJSON_CreateObject(); + esp_chip_info_t chip_info; + esp_chip_info(&chip_info); + cJSON_AddStringToObject(root, "version", IDF_VER); + cJSON_AddNumberToObject(root, "cores", chip_info.cores); + //const char *sys_info = cJSON_Print(root); + char *sys_info = cJSON_Print(root); + httpd_resp_sendstr(req, sys_info); + // Buffers returned by cJSON_Print must be freed by the caller. + // Please use the proper API (cJSON_free) rather than directly calling stdlib free. + cJSON_free(sys_info); + cJSON_Delete(root); + return ESP_OK; +} + + +// Create array +cJSON *Create_array_of_anything(cJSON **objects,int array_num) +{ + cJSON *prev = 0; + cJSON *root; + root = cJSON_CreateArray(); + for (int i=0;ichild=objects[i]; + } else { + prev->next=objects[i]; + objects[i]->prev=prev; + } + prev=objects[i]; + } + return root; +} + +char *JSON_Types(int type) { + if (type == cJSON_Invalid) return ("cJSON_Invalid"); + if (type == cJSON_False) return ("cJSON_False"); + if (type == cJSON_True) return ("cJSON_True"); + if (type == cJSON_NULL) return ("cJSON_NULL"); + if (type == cJSON_Number) return ("cJSON_Number"); + if (type == cJSON_String) return ("cJSON_String"); + if (type == cJSON_Array) return ("cJSON_Array"); + if (type == cJSON_Object) return ("cJSON_Object"); + if (type == cJSON_Raw) return ("cJSON_Raw"); + return NULL; +} + +/* Handler for twai send handler */ +// curl -X POST -H "Content-Type: application/json" -d '{"canid": 513, "frame": "standard", "data": [11, 12, 13, 14]}' http://esp32-server.local:8000/api/twai/send +static esp_err_t twai_send_handler(httpd_req_t *req) +{ + ESP_LOGI(TAG, "twai_send_handler req->uri=[%s]", req->uri); + int total_len = req->content_len; + int cur_len = 0; + char *buf = ((rest_server_context_t *)(req->user_ctx))->scratch; + int received = 0; + if (total_len >= SCRATCH_BUFSIZE) { + /* Respond with 500 Internal Server Error */ + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "content too long"); + return ESP_FAIL; + } + while (cur_len < total_len) { + received = httpd_req_recv(req, buf + cur_len, total_len); + if (received <= 0) { + /* Respond with 500 Internal Server Error */ + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to post control value"); + return ESP_FAIL; + } + cur_len += received; + } + buf[total_len] = '\0'; + ESP_LOGI(TAG, "buf=[%s]", buf); + + + bool parse = true; + cJSON *root = cJSON_Parse(buf); + + // Search canid item + int32_t canid = 0; + cJSON* state = cJSON_GetObjectItem(root, "canid"); + if (state) { + canid = cJSON_GetObjectItem(root, "canid")->valueint; + ESP_LOGI(TAG, "canid=%x", canid); + } else { + ESP_LOGE(TAG, "canid item not found"); + parse = false; + } + + // Search frame item + char frameStr[12]; + uint16_t frame = 0; + state = cJSON_GetObjectItem(root, "frame"); + if (state) { + strcpy(frameStr, cJSON_GetObjectItem(root,"frame")->valuestring); + ESP_LOGI(TAG, "frameStr=[%s]", frameStr); + if (strcmp(frameStr, "standard") != 0 && strcmp(frameStr, "extended") != 0 ) { + ESP_LOGE(TAG, "frame item not correct"); + parse = false; + } else { + if (strcmp(frameStr, "standard") == 0) frame = STANDARD_FRAME; + if (strcmp(frameStr, "extended") == 0) frame = EXTENDED_FRAME; + } + } else { + ESP_LOGE(TAG, "frame item not found"); + parse = false; + } + + // Search data item + int16_t data_len; + char data_value[8]; + state = cJSON_GetObjectItem(root, "data"); + if (state) { + cJSON *data_array = cJSON_GetObjectItem(root,"data"); + ESP_LOGI(TAG, "data_array->type=%s", JSON_Types(data_array->type)); + if (data_array->type == cJSON_Array) { + int data_array_size = cJSON_GetArraySize(data_array); + ESP_LOGI(TAG, "data_array_size=%d", data_array_size); + bool data_valid = true; + data_len = data_array_size; + for (int i=0;itype=%s", JSON_Types(array->type)); + uint16_t data_int = array->valueint; + ESP_LOGI(TAG, "data_int[%d]=%x", i, data_int); + if (data_int <= 0xff) { + data_value[i] = data_int; + } else { + ESP_LOGE(TAG, "data too large"); + data_valid = false; + } + } // end for + if (data_valid == false) { + parse = false; + } + } else { + ESP_LOGE(TAG, "data item not array"); + parse = false; + } // end if + + + } else { + ESP_LOGE(TAG, "data item not found"); + parse = false; + } + + cJSON_Delete(root); + + // JSON parse success. Send twai data. + if (parse) { + ESP_LOGI(TAG, "twai_send_handler frame=%d canid=%x data_len=%d", frame, canid, data_len); + ESP_LOG_BUFFER_HEX(TAG, data_value, data_len); + bool isMatch = false; + for(int index=0;index= 4 && ESP_IDF_VERSION_MINOR >= 1 + ESP_LOGI(TAG,"ESP-IDF esp_netif"); + ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); - esp_netif_create_default_wifi_sta(); + esp_netif_t *netif = esp_netif_create_default_wifi_sta(); +#else + ESP_LOGI(TAG,"ESP-IDF tcpip_adapter"); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); +#endif + +#if CONFIG_STATIC_IP + + ESP_LOGI(TAG, "CONFIG_STATIC_IP_ADDRESS=[%s]",CONFIG_STATIC_IP_ADDRESS); + ESP_LOGI(TAG, "CONFIG_STATIC_GW_ADDRESS=[%s]",CONFIG_STATIC_GW_ADDRESS); + ESP_LOGI(TAG, "CONFIG_STATIC_NM_ADDRESS=[%s]",CONFIG_STATIC_NM_ADDRESS); + +#if ESP_IDF_VERSION_MAJOR >= 4 && ESP_IDF_VERSION_MINOR >= 1 + /* Stop DHCP client */ + ESP_ERROR_CHECK(esp_netif_dhcpc_stop(netif)); + ESP_LOGI(TAG, "Stop DHCP Services"); + + /* Set STATIC IP Address */ + esp_netif_ip_info_t ip_info; + memset(&ip_info, 0 , sizeof(esp_netif_ip_info_t)); + ip_info.ip.addr = ipaddr_addr(CONFIG_STATIC_IP_ADDRESS); + ip_info.netmask.addr = ipaddr_addr(CONFIG_STATIC_NM_ADDRESS); + ip_info.gw.addr = ipaddr_addr(CONFIG_STATIC_GW_ADDRESS);; + esp_netif_set_ip_info(netif, &ip_info); + +#else + /* Stop DHCP client */ + tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA); + ESP_LOGI(TAG, "Stop DHCP Services"); + + /* Set STATIC IP Address */ + tcpip_adapter_ip_info_t ip_info; + memset(&ip_info, 0 , sizeof(tcpip_adapter_ip_info_t)); + ip_info.ip.addr = ipaddr_addr(CONFIG_STATIC_IP_ADDRESS); + ip_info.netmask.addr = ipaddr_addr(CONFIG_STATIC_NM_ADDRESS); + ip_info.gw.addr = ipaddr_addr(CONFIG_STATIC_GW_ADDRESS);; + tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info); +#endif + + /* + I referred from here. + https://www.esp32.com/viewtopic.php?t=5380 + if we should not be using DHCP (for example we are using static IP addresses), + then we need to instruct the ESP32 of the locations of the DNS servers manually. + Google publicly makes available two name servers with the addresses of 8.8.8.8 and 8.8.4.4. + */ + + ip_addr_t d; + d.type = IPADDR_TYPE_V4; + d.u_addr.ip4.addr = 0x08080808; //8.8.8.8 dns + dns_setserver(0, &d); + d.u_addr.ip4.addr = 0x08080404; //8.8.4.4 dns + dns_setserver(1, &d); + +#endif 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)); + ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)); + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL)); 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 - }, + .password = CONFIG_ESP_WIFI_PASSWORD }, }; ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); @@ -154,19 +197,27 @@ bool wifi_init_sta(void) if (bits & WIFI_CONNECTED_BIT) { ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", CONFIG_ESP_WIFI_SSID, CONFIG_ESP_WIFI_PASSWORD); - ret = true; } else if (bits & WIFI_FAIL_BIT) { ESP_LOGI(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); - return ret; +} + +void initialise_mdns(void) +{ + //initialize mDNS + ESP_ERROR_CHECK( mdns_init() ); + //set mDNS hostname (required if you want to advertise services) + ESP_ERROR_CHECK( mdns_hostname_set(CONFIG_MDNS_HOSTNAME) ); + ESP_LOGI(TAG, "mdns hostname set to: [%s]", CONFIG_MDNS_HOSTNAME); + +#if 0 + //set default mDNS instance name + ESP_ERROR_CHECK( mdns_instance_name_set("ESP32 with mDNS") ); +#endif } esp_err_t mountSPIFFS(char * partition_label, char * base_path) { @@ -326,6 +377,7 @@ void dump_table(TOPIC_t *topics, int16_t ntopic) } void http_client_task(void *pvParameters); +void http_server_task(void *pvParameters); void twai_task(void *pvParameters); void app_main() @@ -338,10 +390,9 @@ void app_main() } ESP_ERROR_CHECK(ret); - // WiFi initialize - if (wifi_init_sta() == false) { - while(1) vTaskDelay(10); - } + ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); + wifi_init_sta(); + initialise_mdns(); // Install and start TWAI driver ESP_LOGI(TAG, "%s",BITRATE); @@ -364,8 +415,10 @@ void app_main() } // Create Queue - xQueue_http = xQueueCreate( 10, sizeof(FRAME_t) ); - configASSERT( xQueue_http ); + xQueue_http_client = xQueueCreate( 10, sizeof(FRAME_t) ); + configASSERT( xQueue_http_client ); + xQueue_twai_tx = xQueueCreate( 10, sizeof(twai_message_t) ); + configASSERT( xQueue_twai_tx ); // build publish table ret = build_table(&publish, "/spiffs/can2http.csv", &npublish); @@ -375,6 +428,22 @@ void app_main() } dump_table(publish, npublish); - xTaskCreate(http_client_task, "http", 1024*6, NULL, 2, NULL); + // build subscribe table + ret = build_table(&subscribe, "/spiffs/http2can.csv", &nsubscribe); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "build subscribe table fail"); + while(1) { vTaskDelay(1); } + } + dump_table(subscribe, nsubscribe); + + /* Get the local IP address */ + tcpip_adapter_ip_info_t ip_info; + ESP_ERROR_CHECK(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info)); + + char cparam0[64]; + sprintf(cparam0, "%s", ip4addr_ntoa(&ip_info.ip)); + xTaskCreate(http_server_task, "server", 1024*6, (void *)cparam0, 2, NULL); + + xTaskCreate(http_client_task, "client", 1024*6, NULL, 2, NULL); xTaskCreate(twai_task, "twai_rx", 1024*6, NULL, 2, NULL); } diff --git a/main/twai.c b/main/twai.c index e68fced..47786de 100644 --- a/main/twai.c +++ b/main/twai.c @@ -22,8 +22,8 @@ static const char *TAG = "TWAI"; -extern QueueHandle_t xQueue_http; -//extern QueueHandle_t xQueue_twai_tx; +extern QueueHandle_t xQueue_http_client; +extern QueueHandle_t xQueue_twai_tx; extern TOPIC_t *publish; extern int16_t npublish; @@ -36,9 +36,9 @@ void twai_task(void *pvParameters) dump_table(publish, npublish); twai_message_t rx_msg; + twai_message_t tx_msg; FRAME_t frameBuf; while (1) { - //esp_err_t ret = twai_receive(&rx_msg, pdMS_TO_TICKS(1)); esp_err_t ret = twai_receive(&rx_msg, pdMS_TO_TICKS(10)); if (ret == ESP_OK) { ESP_LOGD(TAG,"twai_receive identifier=0x%x flags=0x%x data_length_code=%d", @@ -49,8 +49,8 @@ void twai_task(void *pvParameters) ESP_LOGD(TAG, "ext=%x rtr=%x", ext, rtr); #if CONFIG_ENABLE_PRINT - if (ext == 0) { - printf("Standard ID: 0x%03x ", rx_msg.identifier); + if (ext == STANDARD_FRAME) { + printf("Standard ID: 0x%03x ", rx_msg.identifier); } else { printf("Extended ID: 0x%08x", rx_msg.identifier); } @@ -73,6 +73,7 @@ void twai_task(void *pvParameters) ESP_LOGI(TAG, "publish[%d] frame=%d canid=0x%x topic=[%s] topic_len=%d", index, publish[index].frame, publish[index].canid, publish[index].topic, publish[index].topic_len); strcpy(frameBuf.topic, publish[index].topic); + frameBuf.command = CMD_RECEIVE; frameBuf.topic_len = publish[index].topic_len; frameBuf.canid = rx_msg.identifier; frameBuf.ext = ext; @@ -85,20 +86,39 @@ void twai_task(void *pvParameters) for(int i=0;i