LOCAL void set_state(CONNECTION_STATE state) { mConnectionState = state; if(state != CS_DISCONNECT) { if(dhmem_isblock()) { mNeedRecover = 1; return; } } switch(state) { case CS_DISCONNECT: start_resolve_dh_server(); break; case CS_GETINFO: case CS_REGISTER: case CS_POLL: { const sint8 cr = espconn_connect(&mDHConnector); if(cr == ESPCONN_ISCONN) return; if(cr != ESPCONN_OK) { dhesperrors_espconn_result("Connector espconn_connect failed:", cr); arm_repeat_timer(RETRY_CONNECTION_INTERVAL_MS); } break; } default: dhdebug("ASSERT: set_state wrong state %d", mConnectionState); } }
LOCAL void network_connect_cb(void *arg) { HTTP_REQUEST *request; switch(mConnectionState) { case CS_GETINFO: request = &mInfoRequest; dhdebug("Send info request..."); break; case CS_REGISTER: request = &mRegisterRequest; dhdebug("Send register request..."); break; case CS_POLL: request = &mPollRequest; dhdebug("Send poll request..."); break; default: dhdebug("ASSERT: networkConnectCb wrong state %d", mConnectionState); } int res; if( (res = espconn_send(&mDHConnector, request->data, request->len)) != ESPCONN_OK) { mConnectionState = CS_DISCONNECT; dhesperrors_espconn_result("network_connect_cb failed:", res); espconn_disconnect(&mDHConnector); } else { dhstatistic_add_bytes_sent(request->len); } }
LOCAL void ICACHE_FLASH_ATTR senderConnectCb(void *arg) { int res; if( (res = espconn_send(&mDHSender, mSenderRequest.data, mSenderRequest.len)) != ESPCONN_OK) { dhesperrors_espconn_result("sender espconn_send failed:", res); espconn_disconnect(&mDHSender); } else { dhstatistic_add_bytes_sent(mSenderRequest.len); } }
LOCAL void ICACHE_FLASH_ATTR start_resolve_dh_server() { static ip_addr_t ip; const char *server = dhrequest_current_server(); char host[os_strlen(server) + 1]; const char *fr = server; while(*fr != ':') { fr++; if(*fr == 0) { fr = 0; break; } } if(fr) { fr++; if(*fr != '/') fr = 0; } if (fr) { while (*fr == '/') fr++; int i = 0; while (*fr != '/' && *fr != ':' && *fr != 0) host[i++] = *fr++; // read port if present int port = 0; if(*fr == ':') { unsigned char d; fr++; while ( (d = *fr - 0x30) < 10) { fr++; port = port*10 + d; if(port > 0xFFFF) break; } } if(port && port < 0xFFFF) mDHConnector.proto.tcp->remote_port = port; else if (os_strncmp(dhrequest_current_server(), "https", 5) == 0) mDHConnector.proto.tcp->remote_port = 443; // HTTPS default port else mDHConnector.proto.tcp->remote_port = 80; //HTTP default port host[i] = 0; dhdebug("Resolving %s", host); err_t r = espconn_gethostbyname(&mDHConnector, host, &ip, resolve_cb); if(r == ESPCONN_OK) { resolve_cb(host, &ip, NULL); } else if(r != ESPCONN_INPROGRESS) { dhesperrors_espconn_result("Resolving failed:", r); arm_repeat_timer(RETRY_CONNECTION_INTERVAL_MS); } } else { dhdebug("Can not find scheme in server url"); } }
LOCAL void ICACHE_FLASH_ATTR dhsender_next(void *arg) { if(mStopped) return; if(mSenderTook == 0) { if(dhsender_queue_take(&mSenderRequest, &isCurrentNotification)) mSenderTook = DHSENDER_RETRY_COUNT; else return; } sint8 cr = espconn_connect(&mDHSender); if(cr == ESPCONN_ISCONN) { return; } else if (cr != ESPCONN_OK) { dhesperrors_espconn_result("Sender espconn_connect failed:", cr); dhsender_arm_timer(RETRY_CONNECTION_INTERVAL_MS); } else { dhdebug("Sender start"); } }
LOCAL void ICACHE_FLASH_ATTR senderErrorCb(void *arg, sint8 err) { dhesperrors_espconn_result("Sender error occurred:", err); decrementSenderTook(); dhsender_arm_timer(RETRY_CONNECTION_INTERVAL_MS); dhstatistic_inc_network_errors_count(); }
LOCAL void ICACHE_FLASH_ATTR check_send_res(sint8 res) { if(res) dhesperrors_espconn_result("espconn_send returned: %d", res); }
LOCAL void network_error_cb(void *arg, sint8 err) { dhesperrors_espconn_result("Connector error occurred:", err); mConnectionState = CS_DISCONNECT; arm_repeat_timer(RETRY_CONNECTION_INTERVAL_MS); dhstatistic_inc_network_errors_count(); }