void ICACHE_FLASH_ATTR REST_Setup(CmdPacket *cmd) { CmdRequest req; uint32_t port, security; int32_t err = -1; // error code in case of failure // start parsing the command cmdRequest(&req, cmd); if(cmdGetArgc(&req) != 3) goto fail; err--; // get the hostname uint16_t len = cmdArgLen(&req); if (len > 128) goto fail; // safety check err--; uint8_t *rest_host = (uint8_t*)os_zalloc(len + 1); if (cmdPopArg(&req, rest_host, len)) goto fail; err--; rest_host[len] = 0; // get the port if (cmdPopArg(&req, (uint8_t*)&port, 2)) { os_free(rest_host); goto fail; } err--; // get the security mode if (cmdPopArg(&req, (uint8_t*)&security, 1)) { os_free(rest_host); goto fail; } err--; // clear connection structures the first time if (restNum == 0xff) { os_memset(restClient, 0, MAX_REST * sizeof(RestClient)); restNum = 0; } // allocate a connection structure RestClient *client = restClient + restNum; uint8_t clientNum = restNum; restNum = (restNum+1)%MAX_REST; // free any data structure that may be left from a previous connection if (client->header) os_free(client->header); if (client->content_type) os_free(client->content_type); if (client->user_agent) os_free(client->user_agent); if (client->data) os_free(client->data); if (client->pCon) { if (client->pCon->proto.tcp) os_free(client->pCon->proto.tcp); os_free(client->pCon); } os_memset(client, 0, sizeof(RestClient)); DBG("REST: setup #%d host=%s port=%ld security=%ld\n", clientNum, rest_host, port, security); client->resp_cb = cmd->value; client->host = (char *)rest_host; client->port = port; client->security = security; client->header = (char*)os_zalloc(4); client->header[0] = 0; client->content_type = (char*)os_zalloc(22); os_sprintf((char *)client->content_type, "x-www-form-urlencoded"); client->user_agent = (char*)os_zalloc(9); os_sprintf((char *)client->user_agent, "esp-link"); client->pCon = (struct espconn *)os_zalloc(sizeof(struct espconn)); client->pCon->proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp)); client->pCon->type = ESPCONN_TCP; client->pCon->state = ESPCONN_NONE; client->pCon->proto.tcp->local_port = espconn_port(); client->pCon->proto.tcp->remote_port = client->port; client->pCon->reverse = client; cmdResponseStart(CMD_RESP_V, clientNum, 0); cmdResponseEnd(); return; fail: cmdResponseStart(CMD_RESP_V, err, 0); cmdResponseEnd(); return; }
/** * Create a new socket. * if `ipAddress == 0`, creates a server otherwise creates a client (and automatically connects). Returns >=0 on success. */ int net_ESP8266_BOARD_createSocket( JsNetwork *net, //!< The Network we are going to use to create the socket. uint32_t ipAddress, //!< The address of the partner of the socket or 0 if we are to be a server. unsigned short port //!< The port number that the partner is listening upon. ) { os_printf("> net_ESP8266_BOARD_createSocket: host: %d.%d.%d.%d, port:%d \n", ((char *)(&ipAddress))[0], ((char *)(&ipAddress))[1], ((char *)(&ipAddress))[2], ((char *)(&ipAddress))[3], port); bool isServer = (ipAddress == 0); struct socketData *pSocketData = allocateNewSocket(); if (pSocketData == NULL) { // No free socket os_printf("< net_ESP8266_BOARD_createSocket: No free sockets\n"); return -1; } int newSocket = pSocketData->socketId; pSocketData->pEspconn = (struct espconn *)os_malloc(sizeof(struct espconn)); assert(pSocketData->pEspconn); struct espconn *pEspconn = pSocketData->pEspconn; pEspconn->type = ESPCONN_TCP; pEspconn->state = ESPCONN_NONE; pEspconn->proto.tcp = (esp_tcp *)os_malloc(sizeof(esp_tcp)); pEspconn->reverse = pSocketData; assert(pEspconn->proto.tcp != NULL); os_memset(pEspconn->proto.tcp, 0, sizeof(esp_tcp)); // NOTE: We must not call these functions until AFTER we have allocated storage // for the 'esp_tcp' structure. espconn_regist_disconcb(pEspconn, esp8266_callback_disconnectCB); espconn_regist_reconcb(pEspconn, esp8266_callback_reconnectCB); espconn_regist_sentcb(pEspconn, esp8266_callback_sentCB); espconn_regist_recvcb(pEspconn, esp8266_callback_recvCB); espconn_regist_write_finish(pEspconn, esp8266_callback_writeFinishedCB); struct ip_info ipconfig; wifi_get_ip_info(STATION_IF, &ipconfig); // Get the local IP address os_memcpy(pEspconn->proto.tcp->local_ip, &ipconfig.ip, 4); // If we are not a server ... if (isServer == false) { pSocketData->state = SOCKET_STATE_CONNECTING; pSocketData->creationType = SOCKET_CREATED_OUTBOUND; pEspconn->proto.tcp->remote_port = port; pEspconn->proto.tcp->local_port = espconn_port(); *(uint32 *)(pEspconn->proto.tcp->remote_ip) = ipAddress; // Ensure that we have flagged this socket as NOT connected pSocketData->isConnected = false; espconn_regist_connectcb(pEspconn, esp8266_callback_connectCB_outbound); // Make a call to espconn_connect. int rc = espconn_connect(pEspconn); if (rc != 0) { os_printf("Err: net_ESP8266_BOARD_createSocket -> espconn_connect returned: %d. Using local port: %d\n", rc, pEspconn->proto.tcp->local_port); setSocketInError(newSocket, "espconn_connect", rc); } } // If the ipAddress IS 0 ... then we are a server. else { // We are going to set ourselves up as a server pSocketData->state = SOCKET_STATE_IDLE; pSocketData->creationType = SOCKET_CREATED_SERVER; pEspconn->proto.tcp->local_port = port; espconn_regist_connectcb(pEspconn, esp8266_callback_connectCB_inbound); // Make a call to espconn_accept int rc = espconn_accept(pEspconn); if (rc != 0) { os_printf("Err: net_ESP8266_BOARD_createSocket -> espconn_accept returned: %d. Using local port: %d\n", rc, pEspconn->proto.tcp->local_port); setSocketInError(newSocket, "espconn_accept", rc); } } dumpEspConn(pEspconn); os_printf("< net_ESP8266_BOARD_createSocket, socket=%d\n", newSocket); return newSocket; }
uint32_t ICACHE_FLASH_ATTR REST_Setup(CmdPacket *cmd) { CmdRequest req; uint32_t port, security; // start parsing the command CMD_Request(&req, cmd); if(CMD_GetArgc(&req) != 3) return 0; // get the hostname uint16_t len = CMD_ArgLen(&req); if (len > 128) return 0; // safety check uint8_t *rest_host = (uint8_t*)os_zalloc(len + 1); if (CMD_PopArg(&req, rest_host, len)) return 0; rest_host[len] = 0; // get the port if (CMD_PopArg(&req, (uint8_t*)&port, 4)) { os_free(rest_host); return 0; } // get the security mode if (CMD_PopArg(&req, (uint8_t*)&security, 4)) { os_free(rest_host); return 0; } // clear connection structures the first time if (restNum == 0xff) { os_memset(restClient, 0, MAX_REST * sizeof(RestClient)); restNum = 0; } // allocate a connection structure RestClient *client = restClient + restNum; uint8_t clientNum = restNum; restNum = (restNum+1)%MAX_REST; // free any data structure that may be left from a previous connection if (client->header) os_free(client->header); if (client->content_type) os_free(client->content_type); if (client->user_agent) os_free(client->user_agent); if (client->data) os_free(client->data); if (client->pCon) { if (client->pCon->proto.tcp) os_free(client->pCon->proto.tcp); os_free(client->pCon); } os_memset(client, 0, sizeof(RestClient)); #ifdef CMDREST_DBG os_printf("REST: setup #%d host=%s port=%ld security=%ld\n", clientNum, rest_host, port, security); #endif client->resp_cb = cmd->callback; client->host = (char *)rest_host; client->port = port; client->security = security; client->header = (char*)os_zalloc(4); client->header[0] = 0; client->content_type = (char*)os_zalloc(22); os_sprintf((char *)client->content_type, "x-www-form-urlencoded"); client->user_agent = (char*)os_zalloc(9); os_sprintf((char *)client->user_agent, "esp-link"); client->pCon = (struct espconn *)os_zalloc(sizeof(struct espconn)); client->pCon->proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp)); client->pCon->type = ESPCONN_TCP; client->pCon->state = ESPCONN_NONE; client->pCon->proto.tcp->local_port = espconn_port(); client->pCon->proto.tcp->remote_port = client->port; client->pCon->reverse = client; return REST_CB | (uint32_t)clientNum; }
// Lua: server:listen( port, ip, function(con) ) // Lua: socket:connect( port, ip, function(con) ) static int net_start( lua_State* L, const char* mt ) { NODE_DBG("net_start is called.\n"); struct espconn *pesp_conn = NULL; lnet_userdata *nud; unsigned port; size_t il; bool isserver = false; ip_addr_t ipaddr; const char *domain; uint8_t stack = 1; if (mt!=NULL && c_strcmp(mt, "net.server")==0) isserver = true; else if (mt!=NULL && c_strcmp(mt, "net.socket")==0) isserver = false; else { NODE_DBG("wrong metatable for net_start.\n"); return 0; } nud = (lnet_userdata *)luaL_checkudata(L, stack, mt); luaL_argcheck(L, nud, stack, "Server/Socket expected"); stack++; if(nud==NULL){ NODE_DBG("userdata is nil.\n"); return 0; } pesp_conn = nud->pesp_conn; port = luaL_checkinteger( L, stack ); stack++; if( pesp_conn->type == ESPCONN_TCP ) { if(isserver) pesp_conn->proto.tcp->local_port = port; else{ pesp_conn->proto.tcp->remote_port = port; pesp_conn->proto.tcp->local_port = espconn_port(); } NODE_DBG("TCP port is set: %d.\n", port); } else if (pesp_conn->type == ESPCONN_UDP) { if(isserver) pesp_conn->proto.udp->local_port = port; else{ pesp_conn->proto.udp->remote_port = port; pesp_conn->proto.udp->local_port = espconn_port(); } NODE_DBG("UDP port is set: %d.\n", port); } if( lua_isstring(L,stack) ) // deal with the domain string { domain = luaL_checklstring( L, stack, &il ); stack++; if (domain == NULL) { if(isserver) domain = "0.0.0.0"; else domain = "127.0.0.1"; } ipaddr.addr = ipaddr_addr(domain); if( pesp_conn->type == ESPCONN_TCP ) { if(isserver) c_memcpy(pesp_conn->proto.tcp->local_ip, &ipaddr.addr, 4); else c_memcpy(pesp_conn->proto.tcp->remote_ip, &ipaddr.addr, 4); NODE_DBG("TCP ip is set: "); NODE_DBG(IPSTR, IP2STR(&ipaddr.addr)); NODE_DBG("\n"); } else if (pesp_conn->type == ESPCONN_UDP) { if(isserver) c_memcpy(pesp_conn->proto.udp->local_ip, &ipaddr.addr, 4); else c_memcpy(pesp_conn->proto.udp->remote_ip, &ipaddr.addr, 4); NODE_DBG("UDP ip is set: "); NODE_DBG(IPSTR, IP2STR(&ipaddr.addr)); NODE_DBG("\n"); } } // call back function when a connection is obtained, tcp only if ( pesp_conn->type == ESPCONN_TCP ) { if (lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION){ lua_pushvalue(L, stack); // copy argument (func) to the top of stack if(isserver) // for tcp server connected callback { if(tcpserver_cb_connect_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, tcpserver_cb_connect_ref); tcpserver_cb_connect_ref = luaL_ref(L, LUA_REGISTRYINDEX); } else { if(nud->cb_connect_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_connect_ref); nud->cb_connect_ref = luaL_ref(L, LUA_REGISTRYINDEX); } } } if(!isserver || pesp_conn->type == ESPCONN_UDP){ // self_ref is only needed by socket userdata, or udp server lua_pushvalue(L, 1); // copy to the top of stack if(nud->self_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->self_ref); nud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); } if( pesp_conn->type == ESPCONN_TCP ) { if(isserver){ // no secure server support for now espconn_regist_connectcb(pesp_conn, net_server_connected); // tcp server, SSL is not supported #ifdef CLIENT_SSL_ENABLE // if(nud->secure) // espconn_secure_accept(pesp_conn); // else #endif espconn_accept(pesp_conn); // if it's a server, no need to dns. espconn_regist_time(pesp_conn, tcp_server_timeover, 0); } else{ espconn_regist_connectcb(pesp_conn, net_socket_connected); espconn_regist_reconcb(pesp_conn, net_socket_reconnected); #ifdef CLIENT_SSL_ENABLE if(nud->secure){ if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port) espconn_secure_disconnect(pesp_conn); // espconn_secure_connect(pesp_conn); } else #endif { if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port) espconn_disconnect(pesp_conn); // espconn_connect(pesp_conn); } } } else if (pesp_conn->type == ESPCONN_UDP) { espconn_regist_recvcb(pesp_conn, net_socket_received); espconn_regist_sentcb(pesp_conn, net_socket_sent); if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port) espconn_delete(pesp_conn); if(isserver) espconn_create(pesp_conn); // if it's a server, no need to dns. } if(!isserver){ if((ipaddr.addr == IPADDR_NONE) && (c_memcmp(domain,"255.255.255.255",16) != 0)) { host_ip.addr = 0; dns_reconn_count = 0; if(ESPCONN_OK == espconn_gethostbyname(pesp_conn, domain, &host_ip, socket_dns_found)){ socket_dns_found(domain, &host_ip, pesp_conn); // ip is returned in host_ip. } } else { socket_connect(pesp_conn); } } return 0; }
void ICACHE_FLASH_ATTR mesh_enable_cb(int8_t res) { MESH_DEMO_PRINT("mesh_enable_cb\n"); if (res == MESH_OP_FAILURE) { MESH_DEMO_PRINT("enable mesh fail, re-enable\n"); espconn_mesh_enable(mesh_enable_cb, MESH_ONLINE); return; } if (espconn_mesh_get_usr_context() && espconn_mesh_is_root() && res == MESH_LOCAL_SUC) goto TEST_SCENARIO; /* * try to estable user virtual connect * user can to use the virtual connect to sent packet to any node, server or mobile. * if you want to sent packet to one node in mesh, please build p2p packet * if you want to sent packet to server/mobile, please build normal packet (uincast packet) * if you want to sent bcast/mcast packet, please build bcast/mcast packet */ MESH_DEMO_MEMSET(&g_ser_conn, 0 ,sizeof(g_ser_conn)); MESH_DEMO_MEMSET(&ser_tcp, 0, sizeof(ser_tcp)); MESH_DEMO_MEMCPY(ser_tcp.remote_ip, server_ip, sizeof(server_ip)); ser_tcp.remote_port = server_port; ser_tcp.local_port = espconn_port(); g_ser_conn.proto.tcp = &ser_tcp; if (espconn_regist_connectcb(&g_ser_conn, esp_mesh_demo_con_cb)) { MESH_DEMO_PRINT("regist con_cb err\n"); espconn_mesh_disable(NULL); return; } if (espconn_regist_recvcb(&g_ser_conn, esp_recv_entrance)) { MESH_DEMO_PRINT("regist recv_cb err\n"); espconn_mesh_disable(NULL); return; } /* * regist the other callback * sent_cb, reconnect_cb, disconnect_cb * if you donn't need the above cb, you donn't need to register them. */ if (espconn_mesh_connect(&g_ser_conn)) { MESH_DEMO_PRINT("connect err\n"); if (espconn_mesh_is_root()) espconn_mesh_enable(mesh_enable_cb, MESH_LOCAL); else espconn_mesh_enable(mesh_enable_cb, MESH_ONLINE); return; } TEST_SCENARIO: mesh_device_list_init(); mesh_topo_test_init(); mesh_json_mcast_test_init(); mesh_json_bcast_test_init(); mesh_json_p2p_test_init(); }
// initialize the custom stuff that goes beyond esp-link void user_init() { // Initialize the GPIO subsystem. gpio_init(); /* ====================================== */ /* UART */ /* ====================================== */ // Initialize UART0 and UART1 /* NOTE: UART1 and I2S share same GPIO. Cannot use simultaneously. */ uart_init( BIT_RATE_115200, BIT_RATE_115200 ); // uart0_sendStr( "\nUART0 - USED TO PROGRAM THE MODULE\n" ); os_printf("\n===================\nUART1 - DEBUG OUPUT\n===================\n"); /* NOTE: PWM CANNOT BE USED SIMULTANEOUSLY WITH HW TIMER */ #if 0 /* ====================================== */ /* PWM */ /* ====================================== */ uint32 pwm_period = 1000; uint32 pwm_duty[PWM_CHANNEL] = {0}; uint32 io_info[][3] = { {PWM_0_OUT_IO_MUX,PWM_0_OUT_IO_FUNC,PWM_0_OUT_IO_NUM}, {PWM_1_OUT_IO_MUX,PWM_1_OUT_IO_FUNC,PWM_1_OUT_IO_NUM}, }; /* PIN FUNCTION INIT FOR PWM OUTPUT */ pwm_init(pwm_period, pwm_duty, PWM_CHANNEL, io_info); /* set pwm_duty cycle */ pwm_set_duty (14185, 0); pwm_set_duty (22222, 1); // todo: explain why 22222 is the highest possible value /* start PWM */ pwm_start(); // NOTE: PWM causes spikes in other GPIOs #endif /* ====================================== */ /* GPIO INTERRPUT */ /* ====================================== */ /* Set GPIO12 in GPIO mode */ PIN_FUNC_SELECT( PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12 ); /* Set GPIO12 as input */ GPIO_DIS_OUTPUT( GPIO_ID_PIN(12) ); /* Disable all GPIO interrupts */ ETS_GPIO_INTR_DISABLE(); /* Set a GPIO callback function */ ETS_GPIO_INTR_ATTACH( gpioCallback, NULL ); /* Configure the type of edge */ gpio_pin_intr_state_set( GPIO_ID_PIN(12), GPIO_PIN_INTR_ANYEDGE ); ETS_GPIO_INTR_ENABLE(); /* ====================================== */ /* SOFTWARE TIMER */ /* ====================================== */ // Set GPIO0 to output mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0); //Set GPIO0 low gpio_output_set(0, RELAY_PIN, RELAY_PIN, 0); /* disarm timer */ os_timer_disarm((ETSTimer*)&some_timer); /* set callback */ os_timer_setfn((ETSTimer*)&some_timer, (os_timer_func_t *) softwareTimerCallback, NULL); /* arm the timer -> os_timer_arm(<pointer>, <period in ms>, <fire periodically>) */ os_timer_arm((ETSTimer*)&some_timer, 10, 1); /* ====================================== */ /* OS TASK */ /* ====================================== */ /* setup OS task */ // system_os_task(user_procTask, user_procTaskPrio, user_procTaskQueue, user_procTaskQueueLen); /* send a message to OS task (fire task) */ // system_os_post(user_procTaskPrio, 0, 0 ); /* ====================================== */ /* HARDWARE TIMER */ /* ====================================== */ /* The hardware timer is used to indicate when a complete IR message frame should have * arrived in order to process the received data and calculate the IR command. * * It is configured in "one-shot" mode. It is started when the beginning of an * IR message frame is detected and stopped after the complete message frame has been read. * This means that the duration of the HW timer should be longer than the duration of * the longest message frame. In the NEC IR tranmission protocol all message frames have * a duration of approximately 67.5ms. */ /* load the HW TIMER */ uint32 ticks = usToTicks(70000); // 70ms RTC_REG_WRITE(FRC1_LOAD_ADDRESS, ticks); /* register callback function */ ETS_FRC_TIMER1_INTR_ATTACH( hwTimerCallback, NULL ); /* enable interrupts */ TM1_EDGE_INT_ENABLE(); ETS_FRC1_INTR_ENABLE(); /* don't start timer yet */ /* the timer is started inside the GPIO INT callback */ /* ====================================== */ /* UDP SERVER */ /* ====================================== */ /* usage: echo <data> | nc -wl -u <ip address> <port> * example: echo "foo" | nc -w1 -u 192.168.1.187 7777 */ /* allocate space for server */ pUdpServer = (struct espconn *) os_zalloc(sizeof(struct espconn)); /* clear allocated memory */ ets_memset(pUdpServer, 0, sizeof(struct espconn)); /* create the server */ espconn_create(pUdpServer); /* set the type of server */ pUdpServer->type = ESPCONN_UDP; /* allocate memory for UDP settings */ pUdpServer->proto.udp = (esp_udp *) os_zalloc(sizeof(esp_udp)); /* set the port that the server will be listening to */ pUdpServer->proto.udp->local_port = 7777; /* register the callback */ espconn_regist_recvcb(pUdpServer, udpServerRxCb); /* start listening */ if (espconn_create(pUdpServer)) { while (1) { os_printf("Error creating a UDP server\n"); } } /* ====================================== */ /* WIFI */ /* ====================================== */ wifi_set_opmode(STATION_MODE); wifi_station_get_config_default(&stconf); // os_strncpy((char*) stconf.ssid, "TP-LINK_2.4GHz_FC2E51", 32); // os_strncpy((char*) stconf.password, "tonytony", 64); os_strncpy((char*) stconf.ssid, "WLAN-PUB", 32); os_strncpy((char*) stconf.password, "", 64); // os_strncpy((char*) stconf.ssid, "MAD air", 32); // os_strncpy((char*) stconf.password, "glioninlog", 64); stconf.bssid_set = 0; wifi_station_set_config(&stconf); // /* ====================================== */ // /* WS2812 LED STRIP */ // /* ====================================== */ // // /* NOTE: UART1 and I2S share same GPIO. Cannot use simultaneously. */ // ws2812_init(); // // /* G R B */ // uint8_t ledout[] = { // 0xff, 0x00, 0x00, //4th //// 0xff, 0x00, 0x00, //3rd //// 0x00, 0xff, 0x00, //2nd //// 0x00, 0x00, 0xff, //1st // }; // //#if 0 // os_printf("\r\nB R G: %x %x %x\r\n", ledout[0], ledout[1],ledout[2]); //#endif // // ws2812_push( ledout, sizeof( ledout ) ); /* ====================================== */ /* TCP CONNECTION */ /* ====================================== */ /* allocate space for server */ pTcpConn = (struct espconn *) os_zalloc(sizeof(struct espconn)); /* clear allocated memory */ ets_memset(pTcpConn, 0, sizeof(struct espconn)); /* set the type of connection */ pTcpConn->type = ESPCONN_TCP; /* set state to NONE */ pTcpConn->state = ESPCONN_NONE; /* allocate memory for TCP settings */ pTcpConn->proto.tcp = (esp_tcp *) os_zalloc(sizeof(esp_tcp)); /* set the port that the connection will be listening to */ pTcpConn->proto.tcp->local_port = espconn_port(); /* set the remote port and IP address */ pTcpConn->proto.tcp->remote_port = 80; os_memcpy(pTcpConn->proto.tcp->remote_ip, server_ip_address, sizeof(server_ip_address)); /* register callbacks */ espconn_regist_connectcb(pTcpConn, tcpConnCb); espconn_regist_reconcb(pTcpConn, tcpReconnCb); /* disarm timer */ os_timer_disarm((ETSTimer*)&wifi_setup_timer); /* set callback */ os_timer_setfn((ETSTimer*)&wifi_setup_timer, (os_timer_func_t *) wifiConnectTimerCb, NULL); /* arm the timer -> os_timer_arm(<pointer>, <period in ms>, <fire periodically>) */ os_timer_arm((ETSTimer*)&wifi_setup_timer, 5000, 1); return; }
/****************************************************************************** * FunctionName : initSyslog * Description : Initialize the syslog library * Parameters : syslog_host -- the syslog host (host:port) * host: IP-Addr | hostname * Returns : none *******************************************************************************/ void ICACHE_FLASH_ATTR syslog_init(char *syslog_host) { DBG("[%uµs] %s\n", WDEV_NOW(), __FUNCTION__); if (!*syslog_host) { syslog_set_status(SYSLOG_HALTED); return; } if (syslog_host == NULL) { // disable and unregister syslog handler syslog_set_status(SYSLOG_HALTED); if (syslog_espconn != NULL) { if (syslog_espconn->proto.udp) { // there's no counterpart to espconn_create... os_free(syslog_espconn->proto.udp); } os_free(syslog_espconn); } syslog_espconn = NULL; // clean up syslog queue syslog_entry_t *pse = syslogQueue; while (pse != NULL) { syslog_entry_t *next = pse->next; os_free(pse); pse = next; } syslogQueue = NULL; return; } char host[32], *port = &host[0]; os_strncpy(host, syslog_host, 32); while (*port && *port != ':') // find port delimiter port++; if (*port) { *port++ = '\0'; syslogHost.port = atoi(port); } if (syslogHost.port == 0) syslogHost.port = 514; // allocate structures, init syslog_handler if (syslog_espconn == NULL) syslog_espconn = (espconn *)os_zalloc(sizeof(espconn)); if (syslog_espconn->proto.udp == NULL) syslog_espconn->proto.udp = (esp_udp *)os_zalloc(sizeof(esp_udp)); syslog_espconn->type = ESPCONN_UDP; syslog_espconn->proto.udp->local_port = espconn_port(); // set a available port #ifdef SYSLOG_UDP_RECV espconn_regist_recvcb(syslog_espconn, syslog_udp_recv_cb); // register a udp packet receiving callback #endif espconn_regist_sentcb(syslog_espconn, syslog_udp_sent_cb); // register a udp packet sent callback syslog_task = register_usr_task(syslog_udp_send_event); syslogHost.min_heap_size = flashConfig.syslog_minheap; // the wifi_set_broadcast_if must be handled global in connection handler... // wifi_set_broadcast_if(STATIONAP_MODE); // send UDP broadcast from both station and soft-AP interface espconn_create(syslog_espconn); // create udp if (UTILS_StrToIP((const char *)host, (void*)&syslogHost.addr)) { syslog_set_status(SYSLOG_READY); } else { // we use our own espconn structure to avoid side effects... if (syslog_dnsconn == NULL) syslog_dnsconn = (espconn *)os_zalloc(sizeof(espconn)); if (syslog_dnsconn->proto.udp == NULL) syslog_dnsconn->proto.udp = (esp_udp *)os_zalloc(sizeof(esp_udp)); syslog_set_status(SYSLOG_DNSWAIT); espconn_gethostbyname(syslog_dnsconn, host, &syslogHost.addr, syslog_gethostbyname_cb); } }
// Lua: mqtt:connect( host, port, secure, auto_reconnect, function(client) ) static int mqtt_socket_connect( lua_State* L ) { NODE_DBG("enter mqtt_socket_connect.\n"); lmqtt_userdata *mud = NULL; unsigned port = 1883; size_t il; ip_addr_t ipaddr; const char *domain; int stack = 1; unsigned secure = 0, auto_reconnect = 0; int top = lua_gettop(L); mud = (lmqtt_userdata *)luaL_checkudata(L, stack, "mqtt.socket"); luaL_argcheck(L, mud, stack, "mqtt.socket expected"); stack++; if(mud == NULL) return 0; if(mud->connected){ return luaL_error(L, "already connected"); } if(mud->pesp_conn){ //TODO: should I free tcp struct directly or ask user to call close()??? mud->pesp_conn->reverse = NULL; if(mud->pesp_conn->proto.tcp) c_free(mud->pesp_conn->proto.tcp); mud->pesp_conn->proto.tcp = NULL; c_free(mud->pesp_conn); mud->pesp_conn = NULL; } struct espconn *pesp_conn = NULL; pesp_conn = mud->pesp_conn = (struct espconn *)c_zalloc(sizeof(struct espconn)); if(!pesp_conn) return luaL_error(L, "not enough memory"); pesp_conn->proto.udp = NULL; pesp_conn->proto.tcp = (esp_tcp *)c_zalloc(sizeof(esp_tcp)); if(!pesp_conn->proto.tcp){ c_free(pesp_conn); pesp_conn = mud->pesp_conn = NULL; return luaL_error(L, "not enough memory"); } // reverse is for the callback function pesp_conn->reverse = mud; pesp_conn->type = ESPCONN_TCP; pesp_conn->state = ESPCONN_NONE; mud->connected = false; if( (stack<=top) && lua_isstring(L,stack) ) // deal with the domain string { domain = luaL_checklstring( L, stack, &il ); stack++; if (domain == NULL) { domain = "127.0.0.1"; } ipaddr.addr = ipaddr_addr(domain); c_memcpy(pesp_conn->proto.tcp->remote_ip, &ipaddr.addr, 4); NODE_DBG("TCP ip is set: "); NODE_DBG(IPSTR, IP2STR(&ipaddr.addr)); NODE_DBG("\n"); } if ( (stack<=top) && lua_isnumber(L, stack) ) { port = lua_tointeger(L, stack); stack++; NODE_DBG("TCP port is set: %d.\n", port); } pesp_conn->proto.tcp->remote_port = port; pesp_conn->proto.tcp->local_port = espconn_port(); mud->mqtt_state.port = port; if ( (stack<=top) && lua_isnumber(L, stack) ) { secure = lua_tointeger(L, stack); stack++; if ( secure != 0 && secure != 1 ){ secure = 0; // default to 0 } } else { secure = 0; // default to 0 } mud->secure = secure; // save if ( (stack<=top) && lua_isnumber(L, stack) ) { auto_reconnect = lua_tointeger(L, stack); stack++; if ( auto_reconnect != 0 && auto_reconnect != 1 ){ auto_reconnect = 0; // default to 0 } } else { auto_reconnect = 0; // default to 0 } mud->mqtt_state.auto_reconnect = auto_reconnect; // call back function when a connection is obtained, tcp only if ((stack<=top) && (lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION)){ lua_pushvalue(L, stack); // copy argument (func) to the top of stack if(mud->cb_connect_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, mud->cb_connect_ref); mud->cb_connect_ref = luaL_ref(L, LUA_REGISTRYINDEX); stack++; } lua_pushvalue(L, 1); // copy userdata to the top of stack if(mud->self_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, mud->self_ref); mud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); espconn_regist_connectcb(pesp_conn, mqtt_socket_connected); espconn_regist_reconcb(pesp_conn, mqtt_socket_reconnected); os_timer_disarm(&mud->mqttTimer); os_timer_setfn(&mud->mqttTimer, (os_timer_func_t *)mqtt_socket_timer, mud); // timer started in socket_connect() if((ipaddr.addr == IPADDR_NONE) && (c_memcmp(domain,"255.255.255.255",16) != 0)) { host_ip.addr = 0; dns_reconn_count = 0; if(ESPCONN_OK == espconn_gethostbyname(pesp_conn, domain, &host_ip, socket_dns_found)){ socket_dns_found(domain, &host_ip, pesp_conn); // ip is returned in host_ip. } } else { socket_connect(pesp_conn); } NODE_DBG("leave mqtt_socket_connect.\n"); return 0; }