/* * Returns TRUE if FS was found * align must be a power of two */ static bool myspiffs_set_cfg(spiffs_config *cfg, int align, int offset, bool force_create) { cfg->phys_erase_block = INTERNAL_FLASH_SECTOR_SIZE; // according to datasheet cfg->log_page_size = LOG_PAGE_SIZE; // as we said cfg->hal_read_f = my_spiffs_read; cfg->hal_write_f = my_spiffs_write; cfg->hal_erase_f = my_spiffs_erase; if (!myspiffs_set_location(cfg, align, offset, LOG_BLOCK_SIZE)) { if (!myspiffs_set_location(cfg, align, offset, LOG_BLOCK_SIZE_SMALL_FS)) { return FALSE; } } NODE_DBG("fs.start:%x,max:%x\n",cfg->phys_addr,cfg->phys_size); #ifdef SPIFFS_USE_MAGIC_LENGTH if (force_create) { return TRUE; } int size = SPIFFS_probe_fs(cfg); if (size > 0 && size < cfg->phys_size) { NODE_DBG("Overriding size:%x\n",size); cfg->phys_size = size; } if (size > 0) { return TRUE; } return FALSE; #else return TRUE; #endif }
static void deliver_publish(lmqtt_userdata * mud, uint8_t* message, int length) { NODE_DBG("enter deliver_publish.\n"); if(mud == NULL) return; mqtt_event_data_t event_data; event_data.topic_length = length; event_data.topic = mqtt_get_publish_topic(message, &event_data.topic_length); event_data.data_length = length; event_data.data = mqtt_get_publish_data(message, &event_data.data_length); if(mud->cb_message_ref == LUA_NOREF) return; if(mud->self_ref == LUA_NOREF) return; if(mud->L == NULL) return; if(event_data.topic && (event_data.topic_length > 0)){ lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->cb_message_ref); lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->self_ref); // pass the userdata to callback func in lua lua_pushlstring(mud->L, event_data.topic, event_data.topic_length); } else { NODE_DBG("get wrong packet.\n"); return; } if(event_data.data && (event_data.data_length > 0)){ lua_pushlstring(mud->L, event_data.data, event_data.data_length); lua_call(mud->L, 3, 0); } else { lua_call(mud->L, 2, 0); } NODE_DBG("leave deliver_publish.\n"); }
// CGI dispatcher for the http server // int ICACHE_FLASH_ATTR http_server_cgi_execute(http_connection * conn){ NODE_DBG("http_execute_cgi"); //request is finished and we should start sending response //if not final, cgi should not expect data to be sent uint8_t final = conn->state==HTTPD_STATE_BODY_END; if(conn->cgi.done) return 0; //Any CGI function already attached? if(conn->cgi.function!=NULL){ NODE_DBG("Executing previous cgi "); int r; r=conn->cgi.function(conn); NODE_DBG("Cgi return is %d", r); if(r==HTTPD_CGI_DONE){ conn->cgi.function=NULL; //mark for destruction conn->cgi.done=1; } if(final) http_send_response(conn); if(r==HTTPD_CGI_MORE ||r==HTTPD_CGI_DONE){ return 0; } }
// Lua: ip = wifi.ap.dhcp.config() static int wifi_ap_dhcp_config( lua_State* L ) { if (!lua_istable(L, 1)) return luaL_error( L, "wrong arg type" ); struct dhcps_lease lease; uint32_t ip; ip = parse_key(L, "start"); if (ip == 0) return luaL_error( L, "wrong arg type" ); lease.start_ip = ip; NODE_DBG(IPSTR, IP2STR(&lease.start_ip)); NODE_DBG("\n"); // use configured max_connection to determine end struct softap_config config; wifi_softap_get_config(&config); lease.end_ip = lease.start_ip; ip4_addr4(&lease.end_ip) += config.max_connection - 1; char temp[64]; c_sprintf(temp, IPSTR, IP2STR(&lease.start_ip)); lua_pushstring(L, temp); c_sprintf(temp, IPSTR, IP2STR(&lease.end_ip)); lua_pushstring(L, temp); // note: DHCP max range = 101 from start_ip to end_ip wifi_softap_dhcps_stop(); wifi_softap_set_dhcps_lease(&lease); wifi_softap_dhcps_start(); return 2; }
// Lua: wifi.sta.config(ssid, password) static int wifi_station_config( lua_State* L ) { size_t sl, pl; struct station_config sta_conf; int i; const char *ssid = luaL_checklstring( L, 1, &sl ); if (sl>32 || ssid == NULL) return luaL_error( L, "ssid:<32" ); const char *password = luaL_checklstring( L, 2, &pl ); if (pl>64 || password == NULL) return luaL_error( L, "pwd:<64" ); c_memset(sta_conf.ssid, 0, 32); c_memset(sta_conf.password, 0, 64); c_memset(sta_conf.bssid, 0, 6); c_memcpy(sta_conf.ssid, ssid, sl); c_memcpy(sta_conf.password, password, pl); sta_conf.bssid_set = 0; NODE_DBG(sta_conf.ssid); NODE_DBG(" %d\n", sl); NODE_DBG(sta_conf.password); NODE_DBG(" %d\n", pl); wifi_station_set_config(&sta_conf); wifi_station_set_auto_connect(true); wifi_station_disconnect(); wifi_station_connect(); // station_check_connect(0); return 0; }
static int ICACHE_FLASH_ATTR on_url(http_parser *parser, const char *url, size_t length) { NODE_DBG("\nhttp_parser url: "); #ifdef DEVELOP_VERSION nprintf(url,length); #endif NODE_DBG("http_parser method: %d",parser->method); //grab the connection http_connection * conn = (http_connection *)parser->data; conn->state=HTTPD_STATE_ON_URL; //set state os_memcpy(conn->url,url,length); //copy url to connection info conn->url[length]=0; //null terminate string http_parse_url(conn); //execute cgi http_execute_cgi(conn); return 0; }
// Lua: mqtt:close() // client disconnect and unref itself static int mqtt_socket_close( lua_State* L ) { NODE_DBG("enter mqtt_socket_close.\n"); int i = 0; lmqtt_userdata *mud = NULL; mud = (lmqtt_userdata *)luaL_checkudata(L, 1, "mqtt.socket"); luaL_argcheck(L, mud, 1, "mqtt.socket expected"); if(mud == NULL) return 0; if(mud->pesp_conn == NULL) return 0; // call mqtt_disconnect() mud->mqtt_state.auto_reconnect = 0; // stop auto reconnect. if(mud->secure){ if(mud->pesp_conn->proto.tcp->remote_port || mud->pesp_conn->proto.tcp->local_port) espconn_secure_disconnect(mud->pesp_conn); } else { if(mud->pesp_conn->proto.tcp->remote_port || mud->pesp_conn->proto.tcp->local_port) espconn_disconnect(mud->pesp_conn); } NODE_DBG("leave mqtt_socket_close.\n"); return 0; }
int ICACHE_FLASH_ATTR http_SET_HEADER(http_connection *c,const char * header,const char * value){ NODE_DBG("Setting header: %s : %s",header,value); int j=0; while(c->output.headers[j].key!=NULL && j< MAX_HEADERS){ if(os_strcmp(c->output.headers[j].key,header)==0){ //header already on the list, overwrite if(c->output.headers[j].value!=NULL){ os_free(c->output.headers[j].value); } break; } j++; } if(j==MAX_HEADERS) return 0; c->output.headers[j].key=header; c->output.headers[j].value=(char *) os_malloc(strlen(value)+1); if(c->output.headers[j].value==NULL){ NODE_DBG("Failed to alloc header memory"); return 0; } os_strcpy(c->output.headers[j].value,value); return 1; }
void myspiffs_mount() { spiffs_config cfg; #ifdef SPIFFS_FIXED_LOCATION cfg.phys_addr = SPIFFS_FIXED_LOCATION; #else cfg.phys_addr = ( u32_t )platform_flash_get_first_free_block_address( NULL ); #endif cfg.phys_addr += 0x3000; cfg.phys_addr &= 0xFFFFC000; // align to 4 sector. cfg.phys_size = INTERNAL_FLASH_SIZE - ( ( u32_t )cfg.phys_addr - INTERNAL_FLASH_START_ADDRESS ); cfg.phys_erase_block = INTERNAL_FLASH_SECTOR_SIZE; // according to datasheet cfg.log_block_size = INTERNAL_FLASH_SECTOR_SIZE; // let us not complicate things cfg.log_page_size = LOG_PAGE_SIZE; // as we said NODE_DBG("fs.start:%x,max:%x\n",cfg.phys_addr,cfg.phys_size); cfg.hal_read_f = my_spiffs_read; cfg.hal_write_f = my_spiffs_write; cfg.hal_erase_f = my_spiffs_erase; int res = SPIFFS_mount(&fs, &cfg, spiffs_work_buf, spiffs_fds, sizeof(spiffs_fds), #if SPIFFS_CACHE spiffs_cache, sizeof(spiffs_cache), #else 0, 0, #endif // myspiffs_check_callback); 0); NODE_DBG("mount res: %i\n", res); }
/****************************************************************************** * FunctionName : user_init * Description : entry of user application, init user function here * Parameters : none * Returns : none *******************************************************************************/ void user_init(void) { system_update_cpu_freq(160); //overclock :) uart_init(BIT_RATE_115200,BIT_RATE_115200); NODE_DBG("User Init"); uint32_t size = flash_get_size_byte(); NODE_DBG("Flash size %d",size); config_wifi(); relay_init(); init_dns(); init_http_server(); //uncomment to send data to mqtt broker //mqtt_app_init(); //uncomment if you have sensors intalled //sensors_init(); #ifdef DEVELOP_VERSION //arm timer os_memset(&heapTimer,0,sizeof(os_timer_t)); os_timer_disarm(&heapTimer); os_timer_setfn(&heapTimer, (os_timer_func_t *)heapTimerCb, NULL); os_timer_arm(&heapTimer, 5000, 1); #endif }
static void ICACHE_FLASH_ATTR http_wifi_api_scan_callback(void *arg, STATUS status){ int n; struct bss_info *bss_link = (struct bss_info *)arg; NODE_DBG("Wifi Scan Done, status: %d", status); if (status!=OK) { wifi_status.scanning=0; return; } //Clear prev ap data if needed. if (wifi_status.scan_result.ap!=NULL) { for (n=0; n<wifi_status.scan_result.ap_count; n++) os_free(wifi_status.scan_result.ap[n]); os_free(wifi_status.scan_result.ap); } //Count amount of access points found. n=0; while (bss_link != NULL) { bss_link = bss_link->next.stqe_next; n++; } //Allocate memory for access point data wifi_status.scan_result.ap=(ap **)os_malloc(sizeof(ap *)*n); wifi_status.scan_result.ap_count=n; NODE_DBG("Scan done: found %d APs", n); //Copy access point data to the static struct n=0; bss_link = (struct bss_info *)arg; while (bss_link != NULL) { if (n>=wifi_status.scan_result.ap_count) { //This means the bss_link changed under our nose. Shouldn't happen! //Break because otherwise we will write in unallocated memory. NODE_DBG("Huh? I have more than the allocated %d aps!", wifi_status.scan_result.ap_count); break; } //Save the ap data. if(strlen(bss_link->ssid)>0){ wifi_status.scan_result.ap[n]=(ap *)os_malloc(sizeof(ap)); wifi_status.scan_result.ap[n]->rssi=bss_link->rssi; wifi_status.scan_result.ap[n]->enc=bss_link->authmode; wifi_status.scan_result.ap[n]->channel=bss_link->channel; strncpy(wifi_status.scan_result.ap[n]->ssid, (char*)bss_link->ssid, 32); n++; } else{ wifi_status.scan_result.ap_count--; } bss_link = bss_link->next.stqe_next; } //We're done. wifi_status.scanning=0; }
static int ICACHE_FLASH_ATTR on_header_value(http_parser *parser, const char *at, size_t length) { NODE_DBG("http_parser header value: "); nprintf(at,length); //grab the connection http_connection * conn = (http_connection *)parser->data; int i=0; while(conn->headers[i].key!=NULL){ if(conn->headers[i].save==1){ NODE_DBG("saving header"); conn->headers[i].value=(char *) os_malloc(length+1); os_memcpy(conn->headers[i].value,at,length); conn->headers[i].value[length]=0; //terminate string; conn->headers[i].save=0; break; } i++; } return 0; }
static bool flash_rom_set_size_type(uint8_t size_code) { // Dangerous, here are dinosaur infested!!!!! // Reboot required!!! // If you don't know what you're doing, your nodemcu may turn into stone ... NODE_DBG("\nBEGIN SET FLASH HEADER\n"); esp_image_header_t *hdr = (esp_image_header_t *)malloc (SPI_FLASH_SEC_SIZE); if (!hdr) return false; if (ESP_OK == spi_flash_read (FLASH_HDR_ADDR, (uint32_t *)hdr, SPI_FLASH_SEC_SIZE)) { hdr->spi_size = size_code; if (ESP_OK == spi_flash_erase_sector (FLASH_HDR_ADDR / SPI_FLASH_SEC_SIZE)) { NODE_DBG("\nERASE SUCCESS\n"); } if (ESP_OK == spi_flash_write(FLASH_HDR_ADDR, (uint32_t *)hdr, SPI_FLASH_SEC_SIZE)) { NODE_DBG("\nWRITE SUCCESS, %u\n", size_code); } } free (hdr); NODE_DBG("\nEND SET FLASH HEADER\n"); return true; }
RO_FILE* f_open(const char *fileName){ const char *fName = fileName; if(*fName=='/') //skip leading / fName++; NODE_DBG("Trying to open file %s ",fName); NODE_DBG("FS Location %p ",ro_file_system); NODE_DBG("FS data Location %p ",rofs_data); int i=0; while(i<ro_file_system.count){ const RO_FILE_ENTRY *entry = &ro_file_system.files[i]; NODE_DBG("Checking %s",entry->name); if(os_strcmp(fName,entry->name)==0){ RO_FILE *f = (RO_FILE*)os_malloc(sizeof(RO_FILE)); f->file = entry; f->readPos=0; return f; } i++; } return NULL; }
static int handle_post_command(const coap_endpoint_t *ep, coap_rw_buffer_t *scratch, const coap_packet_t *inpkt, coap_packet_t *outpkt, uint8_t id_hi, uint8_t id_lo) { if (inpkt->payload.len == 0) return coap_make_response(scratch, outpkt, NULL, 0, id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_BAD_REQUEST, COAP_CONTENTTYPE_TEXT_PLAIN); if (inpkt->payload.len > 0) { lua_Load *load = &gLoad; if(load->line_position == 0){ coap_buffer_to_string(load->line, load->len,&inpkt->payload); load->line_position = c_strlen(load->line)+1; // load->line[load->line_position-1] = '\n'; // load->line[load->line_position] = 0; // load->line_position++; load->done = 1; NODE_DBG("Get command:\n"); NODE_DBG_(load->line); // buggy here NODE_DBG("\nResult(if any):\n"); /* os_timer_disarm(&lua_timer); os_timer_setfn(&lua_timer, (os_timer_func_t *)dojob, load); os_timer_arm(&lua_timer, READLINE_INTERVAL, 0); // no repeat */ set_lua_dojob(load); } return coap_make_response(scratch, outpkt, NULL, 0, id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_CONTENT, COAP_CONTENTTYPE_TEXT_PLAIN); } }
static int ICACHE_FLASH_ATTR on_header_field(http_parser *parser, const char *at, size_t length) { NODE_DBG("http_parser header: "); #ifdef DEVELOP_VERSION nprintf(at,length); #endif //grab the connection http_connection * conn = (http_connection *)parser->data; int i=0; while(conn->headers[i].key!=NULL){ if(os_strncmp(conn->headers[i].key,at,length)==0){ NODE_DBG("marking header to save"); //match header //turn on save header conn->headers[i].save=1; break; } i++; } return 0; }
static void mqtt_socket_connected(void *arg) { NODE_DBG("enter mqtt_socket_connected.\n"); struct espconn *pesp_conn = arg; if(pesp_conn == NULL) return; lmqtt_userdata *mud = (lmqtt_userdata *)pesp_conn->reverse; if(mud == NULL) return; mud->connected = true; espconn_regist_recvcb(pesp_conn, mqtt_socket_received); espconn_regist_sentcb(pesp_conn, mqtt_socket_sent); espconn_regist_disconcb(pesp_conn, mqtt_socket_disconnected); uint8_t temp_buffer[MQTT_BUF_SIZE]; // call mqtt_connect() to start a mqtt connect stage. mqtt_msg_init(&mud->mqtt_state.mqtt_connection, temp_buffer, MQTT_BUF_SIZE); mqtt_message_t* temp_msg = mqtt_msg_connect(&mud->mqtt_state.mqtt_connection, mud->mqtt_state.connect_info); NODE_DBG("Send MQTT connection infomation, data len: %d, d[0]=%d \r\n", temp_msg->length, temp_msg->data[0]); mud->event_timeout = MQTT_SEND_TIMEOUT; // not queue this message. should send right now. or should enqueue this before head. if(mud->secure) espconn_secure_sent(pesp_conn, temp_msg->data, temp_msg->length); else espconn_sent(pesp_conn, temp_msg->data, temp_msg->length); mud->keep_alive_tick = 0; mud->connState = MQTT_CONNECT_SENDING; NODE_DBG("leave mqtt_socket_connected.\n"); return; }
/** * @brief Wifi ap scan over callback to display. * @param arg: contain the aps information * @param status: scan over status * @retval None */ static void wifi_scan_done(void *arg, STATUS status) { uint8 ssid[33]; char temp[128]; if(wifi_scan_succeed == LUA_NOREF) return; if(arg == NULL) return; lua_rawgeti(gL, LUA_REGISTRYINDEX, wifi_scan_succeed); if (status == OK) { struct bss_info *bss_link = (struct bss_info *)arg; bss_link = bss_link->next.stqe_next;//ignore first lua_newtable( gL ); while (bss_link != NULL) { c_memset(ssid, 0, 33); if (c_strlen(bss_link->ssid) <= 32) { c_memcpy(ssid, bss_link->ssid, c_strlen(bss_link->ssid)); } else { c_memcpy(ssid, bss_link->ssid, 32); } if(getap_output_format==1) //use new format(BSSID : SSID, RSSI, Authmode, Channel) { c_sprintf(temp,"%s,%d,%d,%d", ssid, bss_link->rssi, bss_link->authmode, bss_link->channel); lua_pushstring(gL, temp); NODE_DBG(MACSTR" : %s\n",MAC2STR(bss_link->bssid) , temp); c_sprintf(temp,MACSTR, MAC2STR(bss_link->bssid)); lua_setfield( gL, -2, temp); } else//use old format(SSID : Authmode, RSSI, BSSID, Channel) { c_sprintf(temp,"%d,%d,"MACSTR",%d", bss_link->authmode, bss_link->rssi, MAC2STR(bss_link->bssid),bss_link->channel); lua_pushstring(gL, temp); lua_setfield( gL, -2, ssid ); NODE_DBG("%s : %s\n", ssid, temp); } bss_link = bss_link->next.stqe_next; } } else { lua_newtable( gL ); } lua_call(gL, 1, 0); if(wifi_scan_succeed != LUA_NOREF) { luaL_unref(gL, LUA_REGISTRYINDEX, wifi_scan_succeed); wifi_scan_succeed = LUA_NOREF; } }
static void mqtt_socket_disconnected(void *arg) // tcp only { NODE_DBG("enter mqtt_socket_disconnected.\n"); struct espconn *pesp_conn = arg; bool call_back = false; if(pesp_conn == NULL) return; lmqtt_userdata *mud = (lmqtt_userdata *)pesp_conn->reverse; if(mud == NULL) return; os_timer_disarm(&mud->mqttTimer); if(mud->connected){ // call back only called when socket is from connection to disconnection. mud->connected = false; if((mud->L != NULL) && (mud->cb_disconnect_ref != LUA_NOREF) && (mud->self_ref != LUA_NOREF)) { lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->cb_disconnect_ref); lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->self_ref); // pass the userdata(client) to callback func in lua call_back = true; } } if(mud->mqtt_state.auto_reconnect){ mud->pesp_conn->reverse = mud; mud->pesp_conn->type = ESPCONN_TCP; mud->pesp_conn->state = ESPCONN_NONE; mud->connected = false; mud->pesp_conn->proto.tcp->remote_port = mud->mqtt_state.port; mud->pesp_conn->proto.tcp->local_port = espconn_port(); espconn_regist_connectcb(mud->pesp_conn, mqtt_socket_connected); espconn_regist_reconcb(mud->pesp_conn, mqtt_socket_reconnected); socket_connect(pesp_conn); } else { if(mud->pesp_conn){ 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; } if(mud->L == NULL) return; lua_gc(mud->L, LUA_GCSTOP, 0); if(mud->self_ref != LUA_NOREF){ // TODO: should we unref the client and delete it? luaL_unref(mud->L, LUA_REGISTRYINDEX, mud->self_ref); mud->self_ref = LUA_NOREF; // unref this, and the mqtt.socket userdata will delete it self } lua_gc(mud->L, LUA_GCRESTART, 0); } if((mud->L != NULL) && call_back){ lua_call(mud->L, 1, 0); } NODE_DBG("leave mqtt_socket_disconnected.\n"); }
// Lua: compile(filename) -- compile lua file into lua bytecode, and save to .lc static int node_compile( lua_State* L ) { Proto* f; int file_fd = FS_OPEN_OK - 1; size_t len; const char *fname = luaL_checklstring( L, 1, &len ); if ( len > FS_NAME_MAX_LENGTH ) return luaL_error(L, "filename too long"); char output[FS_NAME_MAX_LENGTH]; c_strcpy(output, fname); // check here that filename end with ".lua". if (len < 4 || (c_strcmp( output + len - 4, ".lua") != 0) ) return luaL_error(L, "not a .lua file"); output[c_strlen(output) - 2] = 'c'; output[c_strlen(output) - 1] = '\0'; NODE_DBG(output); NODE_DBG("\n"); if (luaL_loadfsfile(L, fname) != 0) { return luaL_error(L, lua_tostring(L, -1)); } f = toproto(L, -1); int stripping = 1; /* strip debug information? */ file_fd = fs_open(output, fs_mode2flag("w+")); if (file_fd < FS_OPEN_OK) { return luaL_error(L, "cannot open/write to file"); } lua_lock(L); int result = luaU_dump(L, f, writer, &file_fd, stripping); lua_unlock(L); if (fs_flush(file_fd) < 0) { // result codes aren't propagated by flash_fs.h // overwrite Lua error, like writer() does in case of a file io error result = 1; } fs_close(file_fd); file_fd = FS_OPEN_OK - 1; if (result == LUA_ERR_CC_INTOVERFLOW) { return luaL_error(L, "value too big or small for target integer type"); } if (result == LUA_ERR_CC_NOTINTEGER) { return luaL_error(L, "target lua_Number is integral but fractional value found"); } if (result == 1) { // result status generated by writer() or fs_flush() fail return luaL_error(L, "writing to file failed"); } return 0; }
int ICACHE_FLASH_ATTR http_relay_api_toggle(http_connection *c) { NODE_DBG("http_wifi_api_get_status"); //wait for whole body if(c->state <HTTPD_STATE_BODY_END) return HTTPD_CGI_MORE; //parse json cJSON * root = cJSON_Parse(c->body.data); if(root==NULL) goto badrequest; cJSON * relay = cJSON_GetObjectItem(root,"relay"); if(relay==NULL) goto badrequest; int relayNumber = relay->valueint; cJSON_Delete(root); if(relayNumber<0 || relayNumber >=relay_count()){ http_response_BAD_REQUEST(c); NODE_DBG("Wrong relay"); return HTTPD_CGI_DONE; } else{ //valid relay unsigned status = relay_get_state(relayNumber); status = relay_toggle_state(relayNumber); //write headers http_SET_HEADER(c,HTTP_CONTENT_TYPE,JSON_CONTENT_TYPE); http_response_OK(c); //create json root = cJSON_CreateObject(); cJSON_AddNumberToObject(root,"relay",relayNumber); cJSON_AddNumberToObject(root,"state",status); http_write_json(c,root); //delete json struct cJSON_Delete(root); return HTTPD_CGI_DONE; } badrequest: http_response_BAD_REQUEST(c); return HTTPD_CGI_DONE; }
// Lua: socket:dns( string, function(socket, ip) ) static int net_dns( lua_State* L, const char* mt ) { NODE_DBG("net_dns is called.\n"); bool isserver = false; struct espconn *pesp_conn = NULL; lnet_userdata *nud; size_t l; nud = (lnet_userdata *)luaL_checkudata(L, 1, mt); luaL_argcheck(L, nud, 1, "Server/Socket expected"); if(nud==NULL){ NODE_DBG("userdata is nil.\n"); return 0; } 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_send.\n"); return 0; } if(nud->pesp_conn == NULL){ NODE_DBG("nud->pesp_conn is NULL.\n"); return 0; } pesp_conn = nud->pesp_conn; 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); } const char *domain = luaL_checklstring( L, 2, &l ); if (l>128 || domain == NULL) return luaL_error( L, "need <128 domain" ); if (lua_type(L, 3) == LUA_TFUNCTION || lua_type(L, 3) == LUA_TLIGHTFUNCTION){ lua_pushvalue(L, 3); // copy argument (func) to the top of stack if(nud->cb_dns_found_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_dns_found_ref); nud->cb_dns_found_ref = luaL_ref(L, LUA_REGISTRYINDEX); } host_ip.addr = 0; if(ESPCONN_OK == espconn_gethostbyname(pesp_conn, domain, &host_ip, net_dns_found)) net_dns_found(domain, &host_ip, pesp_conn); // ip is returned in host_ip. return 0; }
int ICACHE_FLASH_ATTR http_relay_api_toggle(http_connection *c) { NODE_DBG("http_wifi_api_get_status"); //wait for whole body if(c->state <HTTPD_STATE_BODY_END) return HTTPD_CGI_MORE; int ret = json_count_token(c->body.data,c->body.len); jsonPair fields[1]={ { .key="relay", .value=NULL } }; if(json_parse(&fields[0],1,c->body.data,c->body.len)){ int relayNumber = atoi(fields[0].value); if(relayNumber<0 || relayNumber >=relay_count()){ http_response_BAD_REQUEST(c); NODE_DBG("Wrong relay"); return HTTPD_CGI_DONE; } unsigned status = relay_get_state(relayNumber); status = relay_toggle_state(relayNumber); //write headers http_SET_HEADER(c,HTTP_CONTENT_TYPE,JSON_CONTENT_TYPE); http_response_OK(c); write_json_object_start(c); write_json_pair_int(c,"relay",relayNumber); write_json_list_separator(c); write_json_pair_int(c,"state",status); write_json_object_end(c); return HTTPD_CGI_DONE; } else{ http_response_BAD_REQUEST(c); return HTTPD_CGI_DONE; } http_response_BAD_REQUEST(c); return HTTPD_CGI_DONE; }
char * ICACHE_FLASH_ATTR http_url_get_query_param(http_connection *c,char* param){ NODE_DBG("http_url_get_query_param"); if(!(c->url_parsed.field_set & (1<<UF_QUERY))) //return null if there's no query at all return NULL; //find field char *start = c->url + c->url_parsed.field_data[UF_QUERY].off; char * end = start + c->url_parsed.field_data[UF_QUERY].len -1; char *param_search = (char*)os_malloc(strlen(param)+2); os_strcpy(param_search,param); os_strcat(param_search,"="); NODE_DBG("search for : %s",param_search); char *ret=NULL; start--; //to start at ? while(start<=end){ NODE_DBG("char : %c",*start); if(*start == '?' || *start == '&' || *start=='\0'){ NODE_DBG("Is match?"); start++; //check param name, case insensitive if(os_strcasecmp(param_search,start)==0){ NODE_DBG("yes"); //match start +=strlen(param_search); ret = start; //0 end string while(*start!='\0' && *start!='&') start++; *start='\0'; break; } } start++; } os_free(param_search); return ret; }
// Lua: wifi.ap.config(table) static int wifi_ap_config( lua_State* L ) { struct softap_config config; size_t len; wifi_softap_get_config(&config); if (!lua_istable(L, 1)) return luaL_error( L, "wrong arg type" ); lua_getfield(L, 1, "ssid"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isstring(L, -1) ) // deal with the ssid string { const char *ssid = luaL_checklstring( L, -1, &len ); if(len>32) return luaL_error( L, "ssid:<32" ); c_memset(config.ssid, 0, 32); c_memcpy(config.ssid, ssid, len); config.ssid_len = len; config.ssid_hidden = 0; NODE_DBG(config.ssid); NODE_DBG("\n"); } else return luaL_error( L, "wrong arg type" ); } else return luaL_error( L, "wrong arg type" ); lua_getfield(L, 1, "pwd"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isstring(L, -1) ) // deal with the password string { const char *pwd = luaL_checklstring( L, -1, &len ); if(len>64) return luaL_error( L, "pwd:<64" ); c_memset(config.password, 0, 64); c_memcpy(config.password, pwd, len); config.authmode = AUTH_WPA_WPA2_PSK; NODE_DBG(config.password); NODE_DBG("\n"); } else return luaL_error( L, "wrong arg type" ); } else{ config.authmode = AUTH_OPEN; } config.max_connection = 4; wifi_softap_set_config(&config); // system_restart(); return 0; }
void task_lua(os_event_t *e){ char* lua_argv[] = { (char *)"lua", (char *)"-i", NULL }; NODE_DBG("Task task_lua started.\n"); switch(e->sig){ case SIG_LUA: NODE_DBG("SIG_LUA received.\n"); lua_main( 2, lua_argv ); break; default: break; } }
static void net_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) { NODE_DBG("net_dns_found is called.\n"); struct espconn *pesp_conn = arg; if(pesp_conn == NULL){ NODE_DBG("pesp_conn null.\n"); return; } lnet_userdata *nud = (lnet_userdata *)pesp_conn->reverse; if(nud == NULL){ NODE_DBG("nud null.\n"); return; } if(nud->cb_dns_found_ref == LUA_NOREF){ NODE_DBG("cb_dns_found_ref null.\n"); return; } if(ipaddr == NULL) { NODE_ERR( "DNS Fail!\n" ); return; } // ipaddr->addr is a uint32_t ip char ip_str[20]; c_memset(ip_str, 0, sizeof(ip_str)); if(host_ip.addr == 0 && ipaddr->addr != 0) { c_sprintf(ip_str, IPSTR, IP2STR(&(ipaddr->addr))); } if(nud->self_ref == LUA_NOREF){ NODE_DBG("self_ref null.\n"); return; } lua_rawgeti(gL, LUA_REGISTRYINDEX, nud->cb_dns_found_ref); // the callback function lua_rawgeti(gL, LUA_REGISTRYINDEX, nud->self_ref); // pass the userdata(conn) to callback func in lua lua_pushstring(gL, ip_str); // the ip para lua_call(gL, 2, 0); if((pesp_conn->type == ESPCONN_TCP && pesp_conn->proto.tcp->remote_port == 0) || (pesp_conn->type == ESPCONN_UDP && pesp_conn->proto.udp->remote_port == 0) ){ lua_gc(gL, LUA_GCSTOP, 0); if(nud->self_ref != LUA_NOREF){ luaL_unref(gL, LUA_REGISTRYINDEX, nud->self_ref); nud->self_ref = LUA_NOREF; // unref this, and the net.socket userdata will delete it self } lua_gc(gL, LUA_GCRESTART, 0); } }
static int writer(lua_State* L, const void* p, size_t size, void* u) { UNUSED(L); int file_fd = *( (int *)u ); if ((FS_OPEN_OK - 1) == file_fd) return 1; NODE_DBG("get fd:%d,size:%d\n", file_fd, size); if (size != 0 && (size != fs_write(file_fd, (const char *)p, size)) ) return 1; NODE_DBG("write fd:%d,size:%d\n", file_fd, size); return 0; }
void test_spiffs() { char buf[12]; // Surely, I've mounted spiffs before entering here spiffs_file fd = SPIFFS_open(&fs, "my_file", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0); if (SPIFFS_write(&fs, fd, (u8_t *)"Hello world", 12) < 0) NODE_DBG("errno %i\n", SPIFFS_errno(&fs)); SPIFFS_close(&fs, fd); fd = SPIFFS_open(&fs, "my_file", SPIFFS_RDWR, 0); if (SPIFFS_read(&fs, fd, (u8_t *)buf, 12) < 0) NODE_DBG("errno %i\n", SPIFFS_errno(&fs)); SPIFFS_close(&fs, fd); NODE_DBG("--> %s <--\n", buf); }
static int ICACHE_FLASH_ATTR ws_app_msg_received(http_connection *c){ NODE_DBG("Webscoket app msg received %p",c); struct ws_app_context *context = (struct ws_app_context*)c->reverse; ws_frame *msg = (ws_frame *)c->cgi.argument; if(msg==NULL) return HTTP_WS_CGI_MORE; //just ignore and move on if(msg->SIZE <=0) return HTTP_WS_CGI_MORE; //just ignore and move on char * s = msg->DATA; char *last = s+msg->SIZE; //os_printf("%.*s", msg->SIZE, msg->DATA); #ifdef DEVELOP_VERSION uart_write(UART0, msg->DATA,msg->SIZE); #endif hdlc_tx_frame( msg->DATA, msg->SIZE); return HTTP_WS_CGI_MORE; }