#include "project.h" void ICACHE_FLASH_ATTR user_esp_platform_init(void) { os_sprintf(iot_version,"%s%d.%d.%dt%d(%s)",VERSION_TYPE,IOT_VERSION_MAJOR,\ IOT_VERSION_MINOR,IOT_VERSION_REVISION,device_type,UPGRADE_FALG); os_printf("IOT VERSION = %s\n",iot_version); system_param_load(ESP_PARAM_START_SEC, 0, &esp_param, sizeof(esp_param)); struct rst_info *rtc_info = system_get_rst_info(); os_printf("reset reason: %x\n", rtc_info->reason); if (rtc_info->reason == REASON_WDT_RST || rtc_info->reason == REASON_EXCEPTION_RST || rtc_info->reason == REASON_SOFT_WDT_RST) { if (rtc_info->reason == REASON_EXCEPTION_RST) { os_printf("Fatal exception (%d):\n", rtc_info->exccause); } os_printf("epc1=0x%08x, epc2=0x%08x, epc3=0x%08x, excvaddr=0x%08x, depc=0x%08x\n", rtc_info->epc1, rtc_info->epc2, rtc_info->epc3, rtc_info->excvaddr, rtc_info->depc); } /***add by tzx for saving ip_info to avoid dhcp_client start****/ struct dhcp_client_info dhcp_info; struct ip_info sta_info; system_rtc_mem_read(64,&dhcp_info,sizeof(struct dhcp_client_info)); if(dhcp_info.flag == 0x01 ) { if (true == wifi_station_dhcpc_status()) { wifi_station_dhcpc_stop(); } sta_info.ip = dhcp_info.ip_addr; sta_info.gw = dhcp_info.gw; sta_info.netmask = dhcp_info.netmask; if ( true != wifi_set_ip_info(STATION_IF,&sta_info)) { os_printf("set default ip wrong\n"); } } os_memset(&dhcp_info,0,sizeof(struct dhcp_client_info)); system_rtc_mem_write(64,&dhcp_info,sizeof(struct rst_info)); #if AP_CACHE wifi_station_ap_number_set(AP_CACHE_NUMBER); #endif #if 0 { char sofap_mac[6] = {0x16, 0x34, 0x56, 0x78, 0x90, 0xab}; char sta_mac[6] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab}; struct ip_info info; wifi_set_macaddr(SOFTAP_IF, sofap_mac); wifi_set_macaddr(STATION_IF, sta_mac); IP4_ADDR(&info.ip, 192, 168, 3, 200); IP4_ADDR(&info.gw, 192, 168, 3, 1); IP4_ADDR(&info.netmask, 255, 255, 255, 0); wifi_set_ip_info(STATION_IF, &info); IP4_ADDR(&info.ip, 10, 10, 10, 1); IP4_ADDR(&info.gw, 10, 10, 10, 1); IP4_ADDR(&info.netmask, 255, 255, 255, 0); wifi_set_ip_info(SOFTAP_IF, &info); } #endif if (esp_param.activeflag != 1) { #ifdef SOFTAP_ENCRYPT struct softap_config config; char password[33]; char macaddr[6]; wifi_softap_get_config(&config); wifi_get_macaddr(SOFTAP_IF, macaddr); os_memset(config.password, 0, sizeof(config.password)); os_sprintf(password, MACSTR "_%s", MAC2STR(macaddr), PASSWORD); os_memcpy(config.password, password, os_strlen(password)); config.authmode = AUTH_WPA_WPA2_PSK; wifi_softap_set_config(&config); #endif wifi_set_opmode(STATIONAP_MODE); } #if PLUG_DEVICE user_plug_init(); #elif LIGHT_DEVICE user_light_init(); #elif SENSOR_DEVICE user_sensor_init(esp_param.activeflag); #endif if (wifi_get_opmode() != SOFTAP_MODE) { os_timer_disarm(&client_timer); os_timer_setfn(&client_timer, (os_timer_func_t *)user_esp_platform_check_ip, 1); os_timer_arm(&client_timer, 100, 0); } } #if 0 /****************************************************************************** * Copyright 2013-2014 Espressif Systems (Wuxi) * * FileName: esp_platform.c * * Description: The client mode configration. * Check your hardware connection with the host while use this mode. * * Modification history: * 2014/5/09, v1.0 create this file. *******************************************************************************/ #include "ets_sys.h" #include "os_type.h" #include "mem.h" #include "osapi.h" #include "user_interface.h" #include "espconn.h" #include "esp_platform.h" #include "iot_version.h" #include "upgrade.h" #if ESP_PLATFORM #define ESP_DEBUG #ifdef ESP_DEBUG #define ESP_DBG os_printf #else #define ESP_DBG #endif #define ACTIVE_FRAME "{\"nonce\": %d,\"path\": \"/v1/device/activate/\", \"method\": \"POST\", \"body\": {\"encrypt_method\": \"PLAIN\", \"token\": \"%s\", \"bssid\": \""MACSTR"\",\"rom_version\":\"%s\"}, \"meta\": {\"Authorization\": \"token %s\"}}\n" #if PLUG_DEVICE #include "plug.h" #define RESPONSE_FRAME "{\"status\": 200, \"datapoint\": {\"x\": %d}, \"nonce\": %d, \"deliver_to_device\": true}\n" #define FIRST_FRAME "{\"nonce\": %d, \"path\": \"/v1/device/identify\", \"method\": \"GET\",\"meta\": {\"Authorization\": \"token %s\"}}\n" #elif LIGHT_DEVICE #include "light.h" #define RESPONSE_FRAME "{\"status\": 200,\"nonce\": %d, \"datapoint\": {\"x\": %d,\"y\": %d,\"z\": %d,\"k\": %d,\"l\": %d},\"deliver_to_device\":true}\n" #define FIRST_FRAME "{\"nonce\": %d, \"path\": \"/v1/device/identify\", \"method\": \"GET\",\"meta\": {\"Authorization\": \"token %s\"}}\n" #elif SENSOR_DEVICE #include "sensor.h" #if HUMITURE_SUB_DEVICE #define UPLOAD_FRAME "{\"nonce\": %d, \"path\": \"/v1/datastreams/tem_hum/datapoint/\", \"method\": \"POST\", \ \"body\": {\"datapoint\": {\"x\": %s%d.%02d,\"y\": %d.%02d}}, \"meta\": {\"Authorization\": \"token %s\"}}\n" #elif FLAMMABLE_GAS_SUB_DEVICE #define UPLOAD_FRAME "{\"nonce\": %d, \"path\": \"/v1/datastreams/flammable_gas/datapoint/\", \"method\": \"POST\", \ \"body\": {\"datapoint\": {\"x\": %d.%03d}}, \"meta\": {\"Authorization\": \"token %s\"}}\n" #endif LOCAL uint32 count = 0; #endif #define UPGRADE_FRAME "{\"path\": \"/v1/messages/\", \"method\": \"POST\", \"meta\": {\"Authorization\": \"token %s\"},\ \"get\":{\"action\":\"%s\"},\"body\":{\"pre_rom_version\":\"%s\",\"rom_version\":\"%s\"}}\n" #if PLUG_DEVICE || LIGHT_DEVICE #define BEACON_FRAME "{\"path\": \"/v1/ping/\", \"method\": \"POST\",\"meta\": {\"Authorization\": \"token %s\"}}\n" #define RPC_RESPONSE_FRAME "{\"status\": 200, \"nonce\": %d, \"deliver_to_device\": true}\n" #define TIMER_FRAME "{\"body\": {}, \"get\":{\"is_humanize_format_simple\":\"true\"},\"meta\": {\"Authorization\": \"Token %s\"},\"path\": \"/v1/device/timers/\",\"post\":{},\"method\": \"GET\"}\n" #define pheadbuffer "Connection: keep-alive\r\n\ Cache-Control: no-cache\r\n\ User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36 \r\n\ Accept: */*\r\n\ Authorization: token %s\r\n\ Accept-Encoding: gzip,deflate,sdch\r\n\ Accept-Language: zh-CN,zh;q=0.8\r\n\r\n" LOCAL uint8 ping_status; LOCAL os_timer_t beacon_timer; #endif #ifdef USE_DNS ip_addr_t esp_server_ip; #endif LOCAL struct espconn user_conn; LOCAL struct _esp_tcp user_tcp; LOCAL os_timer_t client_timer; struct esp_platform_saved_param esp_param; LOCAL uint8 device_status; LOCAL uint8 device_recon_count = 0; LOCAL uint32 active_nonce = 0; LOCAL uint8 iot_version[20] = {0}; struct rst_info rtc_info; void user_esp_platform_check_ip(uint8 reset_flag); /****************************************************************************** * FunctionName : user_esp_platform_get_token * Description : get the espressif's device token * Parameters : token -- the parame point which write the flash * Returns : none *******************************************************************************/ void ICACHE_FLASH_ATTR user_esp_platform_get_token(uint8_t *token) { if (token == NULL) { return; } os_memcpy(token, esp_param.token, sizeof(esp_param.token)); } /****************************************************************************** * FunctionName : user_esp_platform_set_token * Description : save the token for the espressif's device * Parameters : token -- the parame point which write the flash * Returns : none *******************************************************************************/ void ICACHE_FLASH_ATTR user_esp_platform_set_token(uint8_t *token) { if (token == NULL) { return; } esp_param.activeflag = 0; os_memcpy(esp_param.token, token, os_strlen(token)); system_param_save_with_protect(ESP_PARAM_START_SEC, &esp_param, sizeof(esp_param)); } /****************************************************************************** * FunctionName : user_esp_platform_set_active * Description : set active flag * Parameters : activeflag -- 0 or 1 * Returns : none *******************************************************************************/ void ICACHE_FLASH_ATTR user_esp_platform_set_active(uint8 activeflag) { esp_param.activeflag = activeflag; system_param_save_with_protect(ESP_PARAM_START_SEC, &esp_param, sizeof(esp_param)); } void ICACHE_FLASH_ATTR user_esp_platform_set_connect_status(uint8 status) { device_status = status; } /****************************************************************************** * FunctionName : user_esp_platform_get_connect_status * Description : get each connection step's status * Parameters : none * Returns : status *******************************************************************************/ uint8 ICACHE_FLASH_ATTR user_esp_platform_get_connect_status(void) { uint8 status = wifi_station_get_connect_status(); if (status == STATION_GOT_IP) { status = (device_status == 0) ? DEVICE_CONNECTING : device_status; } ESP_DBG("status %d\n", status); return status; } /****************************************************************************** * FunctionName : user_esp_platform_parse_nonce * Description : parse the device nonce * Parameters : pbuffer -- the recivce data point * Returns : the nonce *******************************************************************************/ int ICACHE_FLASH_ATTR user_esp_platform_parse_nonce(char *pbuffer) { char *pstr = NULL; char *pparse = NULL; char noncestr[11] = {0}; int nonce = 0; pstr = (char *)os_strstr(pbuffer, "\"nonce\": "); if (pstr != NULL) { pstr += 9; pparse = (char *)os_strstr(pstr, ","); if (pparse != NULL) { os_memcpy(noncestr, pstr, pparse - pstr); } else { pparse = (char *)os_strstr(pstr, "}"); if (pparse != NULL) { os_memcpy(noncestr, pstr, pparse - pstr); } else { pparse = (char *)os_strstr(pstr, "]"); if (pparse != NULL) { os_memcpy(noncestr, pstr, pparse - pstr); } else { return 0; } } } nonce = atoi(noncestr); } return nonce; } /****************************************************************************** * FunctionName : user_esp_platform_get_info * Description : get and update the espressif's device status * Parameters : pespconn -- the espconn used to connect with host * pbuffer -- prossing the data point * Returns : none *******************************************************************************/ void ICACHE_FLASH_ATTR user_esp_platform_get_info(struct espconn *pconn, uint8 *pbuffer) { char *pbuf = NULL; int nonce = 0; pbuf = (char *)os_zalloc(packet_size); nonce = user_esp_platform_parse_nonce(pbuffer); if (pbuf != NULL) { #if PLUG_DEVICE os_sprintf(pbuf, RESPONSE_FRAME, user_plug_get_status(), nonce); #elif LIGHT_DEVICE uint32 white_val; white_val = (PWM_CHANNEL>LIGHT_COLD_WHITE?user_light_get_duty(LIGHT_COLD_WHITE):0); os_sprintf(pbuf, RESPONSE_FRAME, nonce, user_light_get_period(), user_light_get_duty(LIGHT_RED), user_light_get_duty(LIGHT_GREEN), user_light_get_duty(LIGHT_BLUE),white_val );//50); #endif ESP_DBG("%s\n", pbuf); #ifdef CLIENT_SSL_ENABLE espconn_secure_sent(pconn, pbuf, os_strlen(pbuf)); #else espconn_sent(pconn, pbuf, os_strlen(pbuf)); #endif os_free(pbuf); pbuf = NULL; } } /****************************************************************************** * FunctionName : user_esp_platform_set_info * Description : prossing the data and controling the espressif's device * Parameters : pespconn -- the espconn used to connect with host * pbuffer -- prossing the data point * Returns : none *******************************************************************************/ void ICACHE_FLASH_ATTR user_esp_platform_set_info(struct espconn *pconn, uint8 *pbuffer) { #if PLUG_DEVICE char *pstr = NULL; pstr = (char *)os_strstr(pbuffer, "plug-status"); if (pstr != NULL) { pstr = (char *)os_strstr(pbuffer, "body"); if (pstr != NULL) { if (os_strncmp(pstr + 27, "1", 1) == 0) { user_plug_set_status(0x01); } else if (os_strncmp(pstr + 27, "0", 1) == 0) { user_plug_set_status(0x00); } } } #elif LIGHT_DEVICE char *pstr = NULL; char *pdata = NULL; char *pbuf = NULL; char recvbuf[10]; uint16 length = 0; uint32 data = 0; static uint32 rr,gg,bb,cw,ww,period; ww=0; cw=0; extern uint8 light_sleep_flg; pstr = (char *)os_strstr(pbuffer, "\"path\": \"/v1/datastreams/light/datapoint/\""); if (pstr != NULL) { pstr = (char *)os_strstr(pbuffer, "{\"datapoint\": "); if (pstr != NULL) { pbuf = (char *)os_strstr(pbuffer, "}}"); length = pbuf - pstr; length += 2; pdata = (char *)os_zalloc(length + 1); os_memcpy(pdata, pstr, length); pstr = (char *)os_strchr(pdata, 'x'); if (pstr != NULL) { pstr += 4; pbuf = (char *)os_strchr(pstr, ','); if (pbuf != NULL) { length = pbuf - pstr; os_memset(recvbuf, 0, 10); os_memcpy(recvbuf, pstr, length); data = atoi(recvbuf); period = data; //user_light_set_period(data); } } pstr = (char *)os_strchr(pdata, 'y'); if (pstr != NULL) { pstr += 4; pbuf = (char *)os_strchr(pstr, ','); if (pbuf != NULL) { length = pbuf - pstr; os_memset(recvbuf, 0, 10); os_memcpy(recvbuf, pstr, length); data = atoi(recvbuf); rr=data; os_printf("r: %d\r\n",rr); //user_light_set_duty(data, 0); } } pstr = (char *)os_strchr(pdata, 'z'); if (pstr != NULL) { pstr += 4; pbuf = (char *)os_strchr(pstr, ','); if (pbuf != NULL) { length = pbuf - pstr; os_memset(recvbuf, 0, 10); os_memcpy(recvbuf, pstr, length); data = atoi(recvbuf); gg=data; os_printf("g: %d\r\n",gg); //user_light_set_duty(data, 1); } } pstr = (char *)os_strchr(pdata, 'k'); if (pstr != NULL) { pstr += 4;; pbuf = (char *)os_strchr(pstr, ','); if (pbuf != NULL) { length = pbuf - pstr; os_memset(recvbuf, 0, 10); os_memcpy(recvbuf, pstr, length); data = atoi(recvbuf); bb=data; os_printf("b: %d\r\n",bb); //user_light_set_duty(data, 2); } } pstr = (char *)os_strchr(pdata, 'l'); if (pstr != NULL) { pstr += 4;; pbuf = (char *)os_strchr(pstr, ','); if (pbuf != NULL) { length = pbuf - pstr; os_memset(recvbuf, 0, 10); os_memcpy(recvbuf, pstr, length); data = atoi(recvbuf); cw=data; ww=data; os_printf("cw: %d\r\n",cw); os_printf("ww:%d\r\n",ww); //chg //user_light_set_duty(data, 2); } } os_free(pdata); } } if((rr|gg|bb|cw|ww) == 0){ if(light_sleep_flg==0){ } }else{ if(light_sleep_flg==1){ os_printf("modem sleep en\r\n"); wifi_set_sleep_type(MODEM_SLEEP_T); light_sleep_flg =0; } } light_set_aim(rr,gg,bb,cw,ww,period); //user_light_restart(); #endif user_esp_platform_get_info(pconn, pbuffer); } /****************************************************************************** * FunctionName : user_esp_platform_reconnect * Description : reconnect with host after get ip * Parameters : pespconn -- the espconn used to reconnect with host * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR user_esp_platform_reconnect(struct espconn *pespconn) { ESP_DBG("user_esp_platform_reconnect\n"); user_esp_platform_check_ip(0); } /****************************************************************************** * FunctionName : user_esp_platform_discon_cb * Description : disconnect successfully with the host * Parameters : arg -- Additional argument to pass to the callback function * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR user_esp_platform_discon_cb(void *arg) { struct espconn *pespconn = arg; struct ip_info ipconfig; struct dhcp_client_info dhcp_info; ESP_DBG("user_esp_platform_discon_cb\n"); #if (PLUG_DEVICE || LIGHT_DEVICE) os_timer_disarm(&beacon_timer); #endif if (pespconn == NULL) { return; } pespconn->proto.tcp->local_port = espconn_port(); #if (PLUG_DEVICE || SENSOR_DEVICE) user_link_led_output(1); #endif #if SENSOR_DEVICE #ifdef SENSOR_DEEP_SLEEP if (wifi_get_opmode() == STATION_MODE) { /***add by tzx for saving ip_info to avoid dhcp_client start****/ wifi_get_ip_info(STATION_IF, &ipconfig); dhcp_info.ip_addr = ipconfig.ip; dhcp_info.netmask = ipconfig.netmask; dhcp_info.gw = ipconfig.gw ; dhcp_info.flag = 0x01; os_printf("dhcp_info.ip_addr = %d\n",dhcp_info.ip_addr); system_rtc_mem_write(64,&dhcp_info,sizeof(struct dhcp_client_info)); user_sensor_deep_sleep_enter(); } else { os_timer_disarm(&client_timer); os_timer_setfn(&client_timer, (os_timer_func_t *)user_esp_platform_reconnect, pespconn); os_timer_arm(&client_timer, SENSOR_DEEP_SLEEP_TIME / 1000, 0); } #else os_timer_disarm(&client_timer); os_timer_setfn(&client_timer, (os_timer_func_t *)user_esp_platform_reconnect, pespconn); os_timer_arm(&client_timer, 1000, 0); #endif #else user_esp_platform_reconnect(pespconn); #endif } /****************************************************************************** * FunctionName : user_esp_platform_discon * Description : A new incoming connection has been disconnected. * Parameters : espconn -- the espconn used to disconnect with host * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR user_esp_platform_discon(struct espconn *pespconn) { ESP_DBG("user_esp_platform_discon\n"); #if (PLUG_DEVICE || SENSOR_DEVICE) user_link_led_output(1); #endif #ifdef CLIENT_SSL_ENABLE espconn_secure_disconnect(pespconn); #else espconn_disconnect(pespconn); #endif } /****************************************************************************** * FunctionName : user_esp_platform_sent_cb * Description : Data has been sent successfully and acknowledged by the remote host. * Parameters : arg -- Additional argument to pass to the callback function * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR user_esp_platform_sent_cb(void *arg) { struct espconn *pespconn = arg; ESP_DBG("user_esp_platform_sent_cb\n"); } /****************************************************************************** * FunctionName : user_esp_platform_sent * Description : Processing the application data and sending it to the host * Parameters : pespconn -- the espconn used to connetion with the host * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR user_esp_platform_sent(struct espconn *pespconn) { uint8 devkey[token_size] = {0}; uint32 nonce; char *pbuf = (char *)os_zalloc(packet_size); os_memcpy(devkey, esp_param.devkey, 40); if (esp_param.activeflag == 0xFF) { esp_param.activeflag = 0; } if (pbuf != NULL) { if (esp_param.activeflag == 0) { uint8 token[token_size] = {0}; uint8 bssid[6]; active_nonce = os_random(); os_memcpy(token, esp_param.token, 40); wifi_get_macaddr(STATION_IF, bssid); os_sprintf(pbuf, ACTIVE_FRAME, active_nonce, token, MAC2STR(bssid),iot_version, devkey); } #if SENSOR_DEVICE #if HUMITURE_SUB_DEVICE else { #if 0 uint16 tp, rh; uint8 data[4]; if (user_mvh3004_read_th(data)) { rh = data[0] << 8 | data[1]; tp = data[2] << 8 | data[3]; } #else uint16 tp, rh; uint8 *data; uint32 tp_t, rh_t; data = (uint8 *)user_mvh3004_get_poweron_th(); rh = data[0] << 8 | data[1]; tp = data[2] << 8 | data[3]; #endif tp_t = (tp >> 2) * 165 * 100 / (16384 - 1); rh_t = (rh & 0x3fff) * 100 * 100 / (16384 - 1); if (tp_t >= 4000) { os_sprintf(pbuf, UPLOAD_FRAME, count, "", tp_t / 100 - 40, tp_t % 100, rh_t / 100, rh_t % 100, devkey); } else { tp_t = 4000 - tp_t; os_sprintf(pbuf, UPLOAD_FRAME, count, "-", tp_t / 100, tp_t % 100, rh_t / 100, rh_t % 100, devkey); } } #elif FLAMMABLE_GAS_SUB_DEVICE else { uint32 adc_value = system_adc_read(); os_sprintf(pbuf, UPLOAD_FRAME, count, adc_value / 1024, adc_value * 1000 / 1024, devkey); } #endif #else else { nonce = os_random(); os_sprintf(pbuf, FIRST_FRAME, nonce , devkey); } #endif ESP_DBG("%s\n", pbuf); #ifdef CLIENT_SSL_ENABLE espconn_secure_sent(pespconn, pbuf, os_strlen(pbuf)); #else espconn_sent(pespconn, pbuf, os_strlen(pbuf)); #endif os_free(pbuf); } } #if PLUG_DEVICE || LIGHT_DEVICE /****************************************************************************** * FunctionName : user_esp_platform_sent_beacon * Description : sent beacon frame for connection with the host is activate * Parameters : pespconn -- the espconn used to connetion with the host * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR user_esp_platform_sent_beacon(struct espconn *pespconn) { if (pespconn == NULL) { return; } if (pespconn->state == ESPCONN_CONNECT) { if (esp_param.activeflag == 0) { ESP_DBG("please check device is activated.\n"); user_esp_platform_sent(pespconn); } else { uint8 devkey[token_size] = {0}; os_memcpy(devkey, esp_param.devkey, 40); ESP_DBG("user_esp_platform_sent_beacon %u\n", system_get_time()); if (ping_status == 0) { ESP_DBG("user_esp_platform_sent_beacon sent fail!\n"); user_esp_platform_discon(pespconn); } else { char *pbuf = (char *)os_zalloc(packet_size); if (pbuf != NULL) { os_sprintf(pbuf, BEACON_FRAME, devkey); #ifdef CLIENT_SSL_ENABLE espconn_secure_sent(pespconn, pbuf, os_strlen(pbuf)); #else espconn_sent(pespconn, pbuf, os_strlen(pbuf)); #endif ping_status = 0; os_timer_arm(&beacon_timer, BEACON_TIME, 0); os_free(pbuf); } } } } else { ESP_DBG("user_esp_platform_sent_beacon sent fail!\n"); user_esp_platform_discon(pespconn); } } /****************************************************************************** * FunctionName : user_platform_rpc_set_rsp * Description : response the message to server to show setting info is received * Parameters : pespconn -- the espconn used to connetion with the host * nonce -- mark the message received from server * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR user_platform_rpc_set_rsp(struct espconn *pespconn, int nonce) { char *pbuf = (char *)os_zalloc(packet_size); if (pespconn == NULL) { return; } os_sprintf(pbuf, RPC_RESPONSE_FRAME, nonce); ESP_DBG("%s\n", pbuf); #ifdef CLIENT_SSL_ENABLE espconn_secure_sent(pespconn, pbuf, os_strlen(pbuf)); #else espconn_sent(pespconn, pbuf, os_strlen(pbuf)); #endif os_free(pbuf); } /****************************************************************************** * FunctionName : user_platform_timer_get * Description : get the timers from server * Parameters : pespconn -- the espconn used to connetion with the host * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR user_platform_timer_get(struct espconn *pespconn) { uint8 devkey[token_size] = {0}; char *pbuf = (char *)os_zalloc(packet_size); os_memcpy(devkey, esp_param.devkey, 40); if (pespconn == NULL) { return; } os_sprintf(pbuf, TIMER_FRAME, devkey); ESP_DBG("%s\n", pbuf); #ifdef CLIENT_SSL_ENABLE espconn_secure_sent(pespconn, pbuf, os_strlen(pbuf)); #else espconn_sent(pespconn, pbuf, os_strlen(pbuf)); #endif os_free(pbuf); } /****************************************************************************** * FunctionName : user_esp_platform_upgrade_cb * Description : Processing the downloaded data from the server * Parameters : pespconn -- the espconn used to connetion with the host * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR user_esp_platform_upgrade_rsp(void *arg) { struct upgrade_server_info *server = arg; struct espconn *pespconn = server->pespconn; uint8 devkey[41] = {0}; uint8 *pbuf = NULL; char *action = NULL; os_memcpy(devkey, esp_param.devkey, 40); pbuf = (char *)os_zalloc(packet_size); if (server->upgrade_flag == true) { ESP_DBG("user_esp_platform_upgarde_successfully\n"); action = "device_upgrade_success"; os_sprintf(pbuf, UPGRADE_FRAME, devkey, action, server->pre_version, server->upgrade_version); ESP_DBG("%s\n",pbuf); #ifdef CLIENT_SSL_ENABLE espconn_secure_sent(pespconn, pbuf, os_strlen(pbuf)); #else espconn_sent(pespconn, pbuf, os_strlen(pbuf)); #endif if (pbuf != NULL) { os_free(pbuf); pbuf = NULL; } } else { ESP_DBG("user_esp_platform_upgrade_failed\n"); action = "device_upgrade_failed"; os_sprintf(pbuf, UPGRADE_FRAME, devkey, action,server->pre_version, server->upgrade_version); ESP_DBG("%s\n",pbuf); #ifdef CLIENT_SSL_ENABLE espconn_secure_sent(pespconn, pbuf, os_strlen(pbuf)); #else espconn_sent(pespconn, pbuf, os_strlen(pbuf)); #endif if (pbuf != NULL) { os_free(pbuf); pbuf = NULL; } } os_free(server->url); server->url = NULL; os_free(server); server = NULL; } /****************************************************************************** * FunctionName : user_esp_platform_upgrade_begin * Description : Processing the received data from the server * Parameters : pespconn -- the espconn used to connetion with the host * server -- upgrade param * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR user_esp_platform_upgrade_begin(struct espconn *pespconn, struct upgrade_server_info *server) { uint8 user_bin[9] = {0}; uint8 devkey[41] = {0}; server->pespconn = pespconn; os_memcpy(devkey, esp_param.devkey, 40); os_memcpy(server->ip, pespconn->proto.tcp->remote_ip, 4); #ifdef UPGRADE_SSL_ENABLE server->port = 443; #else server->port = 80; #endif server->check_cb = user_esp_platform_upgrade_rsp; server->check_times = 120000; if (server->url == NULL) { server->url = (uint8 *)os_zalloc(512); } if (system_upgrade_userbin_check() == UPGRADE_FW_BIN1) { os_memcpy(user_bin, "user2.bin", 10); } else if (system_upgrade_userbin_check() == UPGRADE_FW_BIN2) { os_memcpy(user_bin, "user1.bin", 10); } os_sprintf(server->url, "GET /v1/device/rom/?action=download_rom&version=%s&filename=%s HTTP/1.0\r\nHost: "IPSTR":%d\r\n"pheadbuffer"", server->upgrade_version, user_bin, IP2STR(server->ip), server->port, devkey); ESP_DBG("%s\n",server->url); #ifdef UPGRADE_SSL_ENABLE if (system_upgrade_start_ssl(server) == false) { #else if (system_upgrade_start(server) == false) { #endif ESP_DBG("upgrade is already started\n"); } } #endif /****************************************************************************** * FunctionName : user_esp_platform_recv_cb * Description : Processing the received data from the server * Parameters : arg -- Additional argument to pass to the callback function * pusrdata -- The received data (or NULL when the connection has been closed!) * length -- The length of received data * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR user_esp_platform_recv_cb(void *arg, char *pusrdata, unsigned short length) { char *pstr = NULL; LOCAL char pbuffer[1024 * 2] = {0}; struct espconn *pespconn = arg; ESP_DBG("user_esp_platform_recv_cb %s\n", pusrdata); #if (PLUG_DEVICE || LIGHT_DEVICE) os_timer_disarm(&beacon_timer); #endif if (length == 1460) { os_memcpy(pbuffer, pusrdata, length); } else { struct espconn *pespconn = (struct espconn *)arg; os_memcpy(pbuffer + os_strlen(pbuffer), pusrdata, length); if ((pstr = (char *)os_strstr(pbuffer, "\"activate_status\": ")) != NULL && user_esp_platform_parse_nonce(pbuffer) == active_nonce) { if (os_strncmp(pstr + 19, "1", 1) == 0) { ESP_DBG("device activates successful.\n"); device_status = DEVICE_ACTIVE_DONE; esp_param.activeflag = 1; system_param_save_with_protect(ESP_PARAM_START_SEC, &esp_param, sizeof(esp_param)); user_esp_platform_sent(pespconn); if(LIGHT_DEVICE){ system_restart(); } } else { ESP_DBG("device activates failed.\n"); device_status = DEVICE_ACTIVE_FAIL; } } #if (PLUG_DEVICE || LIGHT_DEVICE) else if ((pstr = (char *)os_strstr(pbuffer, "\"action\": \"sys_upgrade\"")) != NULL) { if ((pstr = (char *)os_strstr(pbuffer, "\"version\":")) != NULL) { struct upgrade_server_info *server = NULL; int nonce = user_esp_platform_parse_nonce(pbuffer); user_platform_rpc_set_rsp(pespconn, nonce); server = (struct upgrade_server_info *)os_zalloc(sizeof(struct upgrade_server_info)); os_memcpy(server->upgrade_version, pstr + 12, 16); server->upgrade_version[15] = '\0'; os_sprintf(server->pre_version,"%s%d.%d.%dt%d(%s)",VERSION_TYPE,IOT_VERSION_MAJOR,\ IOT_VERSION_MINOR,IOT_VERSION_REVISION,device_type,UPGRADE_FALG); user_esp_platform_upgrade_begin(pespconn, server); } } else if ((pstr = (char *)os_strstr(pbuffer, "\"action\": \"sys_reboot\"")) != NULL) { os_timer_disarm(&client_timer); os_timer_setfn(&client_timer, (os_timer_func_t *)system_upgrade_reboot, NULL); os_timer_arm(&client_timer, 1000, 0); } else if ((pstr = (char *)os_strstr(pbuffer, "/v1/device/timers/")) != NULL) { int nonce = user_esp_platform_parse_nonce(pbuffer); user_platform_rpc_set_rsp(pespconn, nonce); os_timer_disarm(&client_timer); os_timer_setfn(&client_timer, (os_timer_func_t *)user_platform_timer_get, pespconn); os_timer_arm(&client_timer, 2000, 0); } else if ((pstr = (char *)os_strstr(pbuffer, "\"method\": ")) != NULL) { if (os_strncmp(pstr + 11, "GET", 3) == 0) { user_esp_platform_get_info(pespconn, pbuffer); } else if (os_strncmp(pstr + 11, "POST", 4) == 0) { user_esp_platform_set_info(pespconn, pbuffer); } } else if ((pstr = (char *)os_strstr(pbuffer, "ping success")) != NULL) { ESP_DBG("ping success\n"); ping_status = 1; } else if ((pstr = (char *)os_strstr(pbuffer, "send message success")) != NULL) { } else if ((pstr = (char *)os_strstr(pbuffer, "timers")) != NULL) { user_platform_timer_start(pusrdata , pespconn); } #elif SENSOR_DEVICE else if ((pstr = (char *)os_strstr(pbuffer, "\"status\":")) != NULL) { if (os_strncmp(pstr + 10, "200", 3) != 0) { ESP_DBG("message upload failed.\n"); } else { count++; ESP_DBG("message upload sucessful.\n"); } os_timer_disarm(&client_timer); os_timer_setfn(&client_timer, (os_timer_func_t *)user_esp_platform_discon, pespconn); os_timer_arm(&client_timer, 10, 0); } #endif else if ((pstr = (char *)os_strstr(pbuffer, "device")) != NULL) { #if PLUG_DEVICE || LIGHT_DEVICE user_platform_timer_get(pespconn); #elif SENSOR_DEVICE #endif } os_memset(pbuffer, 0, sizeof(pbuffer)); } #if (PLUG_DEVICE || LIGHT_DEVICE) os_timer_arm(&beacon_timer, BEACON_TIME, 0); #endif } #if AP_CACHE /****************************************************************************** * FunctionName : user_esp_platform_ap_change * Description : add the user interface for changing to next ap ID. * Parameters : * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR user_esp_platform_ap_change(void) { uint8 current_id; uint8 i = 0; ESP_DBG("user_esp_platform_ap_is_changing\n"); current_id = wifi_station_get_current_ap_id(); ESP_DBG("current ap id =%d\n", current_id); if (current_id == AP_CACHE_NUMBER - 1) { i = 0; } else { i = current_id + 1; } while (wifi_station_ap_change(i) != true) { i++; if (i == AP_CACHE_NUMBER - 1) { i = 0; } } /* just need to re-check ip while change AP */ device_recon_count = 0; os_timer_disarm(&client_timer); os_timer_setfn(&client_timer, (os_timer_func_t *)user_esp_platform_check_ip, NULL); os_timer_arm(&client_timer, 100, 0); } #endif LOCAL bool ICACHE_FLASH_ATTR user_esp_platform_reset_mode(void) { if (wifi_get_opmode() == STATION_MODE) { wifi_set_opmode(STATIONAP_MODE); } #if AP_CACHE /* delay 5s to change AP */ os_timer_disarm(&client_timer); os_timer_setfn(&client_timer, (os_timer_func_t *)user_esp_platform_ap_change, NULL); os_timer_arm(&client_timer, 5000, 0); return true; #endif return false; } /****************************************************************************** * FunctionName : user_esp_platform_recon_cb * Description : The connection had an error and is already deallocated. * Parameters : arg -- Additional argument to pass to the callback function * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR user_esp_platform_recon_cb(void *arg, sint8 err) { struct espconn *pespconn = (struct espconn *)arg; ESP_DBG("user_esp_platform_recon_cb\n"); #if (PLUG_DEVICE || LIGHT_DEVICE) os_timer_disarm(&beacon_timer); #endif #if (PLUG_DEVICE || SENSOR_DEVICE) user_link_led_output(1); #endif if (++device_recon_count == 5) { device_status = DEVICE_CONNECT_SERVER_FAIL; if (user_esp_platform_reset_mode()) { return; } } #if SENSOR_DEVICE #ifdef SENSOR_DEEP_SLEEP if (wifi_get_opmode() == STATION_MODE) { user_esp_platform_reset_mode(); //user_sensor_deep_sleep_enter(); } else { os_timer_disarm(&client_timer); os_timer_setfn(&client_timer, (os_timer_func_t *)user_esp_platform_reconnect, pespconn); os_timer_arm(&client_timer, 1000, 0); } #else os_timer_disarm(&client_timer); os_timer_setfn(&client_timer, (os_timer_func_t *)user_esp_platform_reconnect, pespconn); os_timer_arm(&client_timer, 1000, 0); #endif #else os_timer_disarm(&client_timer); os_timer_setfn(&client_timer, (os_timer_func_t *)user_esp_platform_reconnect, pespconn); os_timer_arm(&client_timer, 1000, 0); #endif } /****************************************************************************** * FunctionName : user_esp_platform_connect_cb * Description : A new incoming connection has been connected. * Parameters : arg -- Additional argument to pass to the callback function * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR user_esp_platform_connect_cb(void *arg) { struct espconn *pespconn = arg; ESP_DBG("user_esp_platform_connect_cb\n"); if (wifi_get_opmode() == STATIONAP_MODE ) { wifi_set_opmode(STATION_MODE); } #if (PLUG_DEVICE || SENSOR_DEVICE) user_link_led_timer_done(); #endif device_recon_count = 0; espconn_regist_recvcb(pespconn, user_esp_platform_recv_cb); espconn_regist_sentcb(pespconn, user_esp_platform_sent_cb); user_esp_platform_sent(pespconn); } /****************************************************************************** * FunctionName : user_esp_platform_connect * Description : The function given as the connect with the host * Parameters : espconn -- the espconn used to connect the connection * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR user_esp_platform_connect(struct espconn *pespconn) { ESP_DBG("user_esp_platform_connect\n"); #ifdef CLIENT_SSL_ENABLE espconn_secure_connect(pespconn); #else espconn_connect(pespconn); #endif } #ifdef USE_DNS /****************************************************************************** * FunctionName : user_esp_platform_dns_found * Description : dns found callback * Parameters : name -- pointer to the name that was looked up. * ipaddr -- pointer to an ip_addr_t containing the IP address of * the hostname, or NULL if the name could not be found (or on any * other error). * callback_arg -- a user-specified callback argument passed to * dns_gethostbyname * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR user_esp_platform_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) { struct espconn *pespconn = (struct espconn *)arg; if (ipaddr == NULL) { ESP_DBG("user_esp_platform_dns_found NULL\n"); if (++device_recon_count == 5) { device_status = DEVICE_CONNECT_SERVER_FAIL; user_esp_platform_reset_mode(); } return; } ESP_DBG("user_esp_platform_dns_found %d.%d.%d.%d\n", *((uint8 *)&ipaddr->addr), *((uint8 *)&ipaddr->addr + 1), *((uint8 *)&ipaddr->addr + 2), *((uint8 *)&ipaddr->addr + 3)); if (esp_server_ip.addr == 0 && ipaddr->addr != 0) { os_timer_disarm(&client_timer); esp_server_ip.addr = ipaddr->addr; os_memcpy(pespconn->proto.tcp->remote_ip, &ipaddr->addr, 4); pespconn->proto.tcp->local_port = espconn_port(); #ifdef CLIENT_SSL_ENABLE pespconn->proto.tcp->remote_port = 8443; #else pespconn->proto.tcp->remote_port = 8000; #endif #if (PLUG_DEVICE || LIGHT_DEVICE) ping_status = 1; #endif espconn_regist_connectcb(pespconn, user_esp_platform_connect_cb); espconn_regist_disconcb(pespconn, user_esp_platform_discon_cb); espconn_regist_reconcb(pespconn, user_esp_platform_recon_cb); user_esp_platform_connect(pespconn); } } /****************************************************************************** * FunctionName : user_esp_platform_dns_check_cb * Description : 1s time callback to check dns found * Parameters : arg -- Additional argument to pass to the callback function * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR user_esp_platform_dns_check_cb(void *arg) { struct espconn *pespconn = arg; ESP_DBG("user_esp_platform_dns_check_cb\n"); espconn_gethostbyname(pespconn, ESP_DOMAIN, &esp_server_ip, user_esp_platform_dns_found); os_timer_arm(&client_timer, 1000, 0); } LOCAL void ICACHE_FLASH_ATTR user_esp_platform_start_dns(struct espconn *pespconn) { esp_server_ip.addr = 0; espconn_gethostbyname(pespconn, ESP_DOMAIN, &esp_server_ip, user_esp_platform_dns_found); os_timer_disarm(&client_timer); os_timer_setfn(&client_timer, (os_timer_func_t *)user_esp_platform_dns_check_cb, pespconn); os_timer_arm(&client_timer, 1000, 0); } #endif #if LIGHT_DEVICE void user_mdns_conf() { struct ip_info ipconfig; wifi_get_ip_info(STATION_IF, &ipconfig); struct mdns_info *info = (struct mdns_info *)os_zalloc(sizeof(struct mdns_info)); info->host_name = "espressif_light_demo"; info->ipAddr= ipconfig.ip.addr; //sation ip info->server_name = "espLight"; info->server_port = 80; info->txt_data[0] = "version = 1.0.1"; espconn_mdns_init(info); } #endif /****************************************************************************** * FunctionName : user_esp_platform_check_ip * Description : espconn struct parame init when get ip addr * Parameters : none * Returns : none *******************************************************************************/ void ICACHE_FLASH_ATTR user_esp_platform_check_ip(uint8 reset_flag) { struct ip_info ipconfig; os_timer_disarm(&client_timer); wifi_get_ip_info(STATION_IF, &ipconfig); if (wifi_station_get_connect_status() == STATION_GOT_IP && ipconfig.ip.addr != 0) { #if (PLUG_DEVICE || SENSOR_DEVICE) user_link_led_timer_init(); #endif //*************************** #if LIGHT_DEVICE user_mdns_conf(); #endif //*************************** user_conn.proto.tcp = &user_tcp; user_conn.type = ESPCONN_TCP; user_conn.state = ESPCONN_NONE; device_status = DEVICE_CONNECTING; if (reset_flag) { device_recon_count = 0; } #if (PLUG_DEVICE || LIGHT_DEVICE) os_timer_disarm(&beacon_timer); os_timer_setfn(&beacon_timer, (os_timer_func_t *)user_esp_platform_sent_beacon, &user_conn); #endif #ifdef USE_DNS user_esp_platform_start_dns(&user_conn); #else const char esp_server_ip[4] = {114, 215, 177, 97}; os_memcpy(user_conn.proto.tcp->remote_ip, esp_server_ip, 4); user_conn.proto.tcp->local_port = espconn_port(); #ifdef CLIENT_SSL_ENABLE user_conn.proto.tcp->remote_port = 8443; #else user_conn.proto.tcp->remote_port = 8000; #endif espconn_regist_connectcb(&user_conn, user_esp_platform_connect_cb); espconn_regist_reconcb(&user_conn, user_esp_platform_recon_cb); user_esp_platform_connect(&user_conn); #endif } else { /* if there are wrong while connecting to some AP, then reset mode */ if ((wifi_station_get_connect_status() == STATION_WRONG_PASSWORD || wifi_station_get_connect_status() == STATION_NO_AP_FOUND || wifi_station_get_connect_status() == STATION_CONNECT_FAIL)) { user_esp_platform_reset_mode(); } else { os_timer_setfn(&client_timer, (os_timer_func_t *)user_esp_platform_check_ip, NULL); os_timer_arm(&client_timer, 100, 0); } } } /****************************************************************************** * FunctionName : user_esp_platform_init * Description : device parame init based on espressif platform * Parameters : none * Returns : none *******************************************************************************/ void ICACHE_FLASH_ATTR user_esp_platform_init(void) { os_sprintf(iot_version,"%s%d.%d.%dt%d(%s)",VERSION_TYPE,IOT_VERSION_MAJOR,\ IOT_VERSION_MINOR,IOT_VERSION_REVISION,device_type,UPGRADE_FALG); os_printf("IOT VERSION = %s\n",iot_version); system_param_load(ESP_PARAM_START_SEC, 0, &esp_param, sizeof(esp_param)); struct rst_info *rtc_info = system_get_rst_info(); os_printf("reset reason: %x\n", rtc_info->reason); if (rtc_info->reason == REASON_WDT_RST || rtc_info->reason == REASON_EXCEPTION_RST || rtc_info->reason == REASON_SOFT_WDT_RST) { if (rtc_info->reason == REASON_EXCEPTION_RST) { os_printf("Fatal exception (%d):\n", rtc_info->exccause); } os_printf("epc1=0x%08x, epc2=0x%08x, epc3=0x%08x, excvaddr=0x%08x, depc=0x%08x\n", rtc_info->epc1, rtc_info->epc2, rtc_info->epc3, rtc_info->excvaddr, rtc_info->depc); } /***add by tzx for saving ip_info to avoid dhcp_client start****/ struct dhcp_client_info dhcp_info; struct ip_info sta_info; system_rtc_mem_read(64,&dhcp_info,sizeof(struct dhcp_client_info)); if(dhcp_info.flag == 0x01 ) { if (true == wifi_station_dhcpc_status()) { wifi_station_dhcpc_stop(); } sta_info.ip = dhcp_info.ip_addr; sta_info.gw = dhcp_info.gw; sta_info.netmask = dhcp_info.netmask; if ( true != wifi_set_ip_info(STATION_IF,&sta_info)) { os_printf("set default ip wrong\n"); } } os_memset(&dhcp_info,0,sizeof(struct dhcp_client_info)); system_rtc_mem_write(64,&dhcp_info,sizeof(struct rst_info)); #if AP_CACHE wifi_station_ap_number_set(AP_CACHE_NUMBER); #endif #if 0 { char sofap_mac[6] = {0x16, 0x34, 0x56, 0x78, 0x90, 0xab}; char sta_mac[6] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab}; struct ip_info info; wifi_set_macaddr(SOFTAP_IF, sofap_mac); wifi_set_macaddr(STATION_IF, sta_mac); IP4_ADDR(&info.ip, 192, 168, 3, 200); IP4_ADDR(&info.gw, 192, 168, 3, 1); IP4_ADDR(&info.netmask, 255, 255, 255, 0); wifi_set_ip_info(STATION_IF, &info); IP4_ADDR(&info.ip, 10, 10, 10, 1); IP4_ADDR(&info.gw, 10, 10, 10, 1); IP4_ADDR(&info.netmask, 255, 255, 255, 0); wifi_set_ip_info(SOFTAP_IF, &info); } #endif if (esp_param.activeflag != 1) { #ifdef SOFTAP_ENCRYPT struct softap_config config; char password[33]; char macaddr[6]; wifi_softap_get_config(&config); wifi_get_macaddr(SOFTAP_IF, macaddr); os_memset(config.password, 0, sizeof(config.password)); os_sprintf(password, MACSTR "_%s", MAC2STR(macaddr), PASSWORD); os_memcpy(config.password, password, os_strlen(password)); config.authmode = AUTH_WPA_WPA2_PSK; wifi_softap_set_config(&config); #endif wifi_set_opmode(STATIONAP_MODE); } #if PLUG_DEVICE user_plug_init(); #elif LIGHT_DEVICE user_light_init(); #elif SENSOR_DEVICE user_sensor_init(esp_param.activeflag); #endif if (wifi_get_opmode() != SOFTAP_MODE) { os_timer_disarm(&client_timer); os_timer_setfn(&client_timer, (os_timer_func_t *)user_esp_platform_check_ip, 1); os_timer_arm(&client_timer, 100, 0); } } #endif #endif