//*** Private method that actually sends data ***// int wifi_send_data(int ch, const uint8_t* data, int size){ int cmd_buf_size = MD_BUF_SIZE; char *cmd; int timeout = 7; //wait 7 seconds to transmit the data //allocate memory cmd = core_malloc(cmd_buf_size); snprintf(cmd,cmd_buf_size,"AT+CIPSEND=%d,%d\r\n",ch,size); data_tx_status=TX_PENDING; rx_wait=true; resp_buf_idx = 0; memset(resp_buf,0x0,RESP_BUF_SIZE); memset(wifi_rx_buf,0x0,WIFI_RX_BUF_SIZE); //to make debugging easier wifi_rx_buf_idx=0; usart_serial_write_packet(WIFI_UART,(uint8_t*)cmd,strlen(cmd)); delay_ms(250); //wait for module to be ready to accept data usart_serial_write_packet(WIFI_UART,(uint8_t*)data,size); //now wait for the data to be sent while(timeout>0){ //start the timer tc_start(TC0, 0); //when timer expires, return what we have in the buffer rx_wait=true; //reset the wait flag while(rx_wait && data_tx_status!=TX_SUCCESS); tc_stop(TC0,0); //the success flag is set *before* we receive the server's response //core_process_wifi_data receives the response but discards it if(data_tx_status==TX_SUCCESS){ data_tx_status=TX_IDLE; rx_wait = false; //free memory core_free(cmd); return TX_SUCCESS; } timeout--; } //check if this is a timeout error if(strlen((char*)resp_buf)==0){ printf("timeout error\n"); core_log("timeout error"); data_tx_status = TX_TIMEOUT; } //an error occured, see if it is due to a module reset else if(strcmp((char*)resp_buf,"\r\nready\r\n")==0){ //module reset itself!!! printf("detected module reset\n"); core_log("module reset"); data_tx_status = TX_ERR_MODULE_RESET; } else { data_tx_status=TX_ERROR; core_log("TX error:"); core_log((char*)resp_buf); data_tx_status = TX_ERROR; } //free memory core_free(cmd); return data_tx_status; }
static void moninj_ttlset(int channel, int mode) { rtio_moninj_inj_chan_sel_write(channel); switch(mode) { case MONINJ_TTL_MODE_EXP: rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_ENABLE); rtio_moninj_inj_value_write(0); break; case MONINJ_TTL_MODE_1: rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_O); rtio_moninj_inj_value_write(1); rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_OE); rtio_moninj_inj_value_write(1); rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_ENABLE); rtio_moninj_inj_value_write(1); break; case MONINJ_TTL_MODE_0: rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_O); rtio_moninj_inj_value_write(0); rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_OE); rtio_moninj_inj_value_write(1); rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_ENABLE); rtio_moninj_inj_value_write(1); break; case MONINJ_TTL_MODE_IN: rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_OE); rtio_moninj_inj_value_write(0); rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_ENABLE); rtio_moninj_inj_value_write(1); break; default: core_log("unknown TTL mode %d\n", mode); break; } }
void signal_handler(int signum) { core_log("core", LOG_NOTICE, 1111, "signal received"); module_vtable_msg_input* vt_i = core_messaging_handlers_input(); module_vtable_msg_output* vt_o = core_messaging_handlers_output(); // === setup termination g_mutex_lock(g_lck_termination); g_termination = TRUE; g_mutex_unlock(g_lck_termination); // === signal wake-ups to all handlers // forward push if (vt_i->terminate_blocking != NULL) vt_i->terminate_blocking(THREAD_TYPE_FORWARD_PUSH); // forward pull if (g_lck_forward_pull != NULL) { g_mutex_lock(g_lck_forward_pull); g_cond_signal(g_cnd_forward_pull); g_mutex_unlock(g_lck_forward_pull); } if (vt_i->terminate_blocking != NULL) vt_i->terminate_blocking(THREAD_TYPE_FORWARD_PULL); // forward receiver g_mutex_lock(g_lck_forward_receive); g_cond_signal(g_cnd_forward_receive); g_mutex_unlock(g_lck_forward_receive); if (vt_o->terminate_blocking != NULL) vt_o->terminate_blocking(THREAD_TYPE_FORWARD_RECV); // feedback push if (vt_o->terminate_blocking != NULL) vt_o->terminate_blocking(THREAD_TYPE_FEEDBACK_PUSH); // feedback pull if (g_lck_feedback_pull != NULL) { g_mutex_lock(g_lck_feedback_pull); g_cond_signal(g_cnd_feedback_pull); g_mutex_unlock(g_lck_feedback_pull); } if (vt_o->terminate_blocking != NULL) vt_o->terminate_blocking(THREAD_TYPE_FEEDBACK_PULL); // feedback receiver g_mutex_lock(g_lck_feedback_receive); g_cond_signal(g_cnd_feedback_receive); g_mutex_unlock(g_lck_feedback_receive); if (vt_i->terminate_blocking != NULL) vt_i->terminate_blocking(THREAD_TYPE_FEEDBACK_RECV); // trash receiver g_mutex_lock(g_lck_trash_receive); g_cond_signal(g_cnd_trash_receive); g_mutex_unlock(g_lck_trash_receive); }
/** * This function outputs an error message to the error logging file. * * @param fmt The format string like in "printf". * @param ... The arguments for the format like in "printf". */ void core_error(char *fmt, ...) { va_list args; va_start(args, fmt); core_log(core_file_error, fmt, args); va_end(args); }
gboolean core_config_isset(gchar* group, gchar* option) { module_vtable_config* tbl = core_config_provider(); if (tbl->isset != NULL) return tbl->isset(group, option); else { core_log("core", LOG_CRIT, 1111, "Function 'isset' not defined in config module!"); return FALSE; } }
gchar* core_config_get_text(gchar* group, gchar* option) { module_vtable_config* tbl = core_config_provider(); if (tbl->get_text != NULL) return tbl->get_text(group, option); else { core_log("core", LOG_CRIT, 1111, "Function 'get_text' not defined in config module!"); return NULL; } }
void moninj_init(void) { listen_pcb = udp_new(); if(!listen_pcb) { core_log("Failed to create UDP listening PCB\n"); return; } udp_bind(listen_pcb, IP_ADDR_ANY, 3250); udp_recv(listen_pcb, moninj_recv, NULL); }
static void moninj_monitor(const ip_addr_t *addr, u16_t port) { struct monitor_reply reply; int i; struct pbuf *reply_p; reply.ttl_levels = 0; reply.ttl_oes = 0; reply.ttl_overrides = 0; for(i=0;i<CONFIG_RTIO_REGULAR_TTL_COUNT;i++) { rtio_moninj_mon_chan_sel_write(i); rtio_moninj_mon_probe_sel_write(0); rtio_moninj_mon_value_update_write(1); if(rtio_moninj_mon_value_read()) reply.ttl_levels |= 1LL << i; rtio_moninj_mon_probe_sel_write(1); rtio_moninj_mon_value_update_write(1); if(rtio_moninj_mon_value_read()) reply.ttl_oes |= 1LL << i; rtio_moninj_inj_chan_sel_write(i); rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_ENABLE); if(rtio_moninj_inj_value_read()) reply.ttl_overrides |= 1LL << i; } #if ((defined CONFIG_RTIO_DDS_COUNT) && (CONFIG_RTIO_DDS_COUNT > 0)) int j; reply.dds_rtio_first_channel = CONFIG_RTIO_FIRST_DDS_CHANNEL; reply.dds_channels_per_bus = CONFIG_DDS_CHANNELS_PER_BUS; for(j=0;j<CONFIG_RTIO_DDS_COUNT;j++) { rtio_moninj_mon_chan_sel_write(CONFIG_RTIO_FIRST_DDS_CHANNEL+j); for(i=0;i<CONFIG_DDS_CHANNELS_PER_BUS;i++) { rtio_moninj_mon_probe_sel_write(i); rtio_moninj_mon_value_update_write(1); reply.dds_ftws[CONFIG_DDS_CHANNELS_PER_BUS*j+i] = rtio_moninj_mon_value_read(); } } #else reply.dds_rtio_first_channel = 0; reply.dds_channels_per_bus = 0; #endif reply_p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct monitor_reply), PBUF_RAM); if(!reply_p) { core_log("Failed to allocate pbuf for monitor reply\n"); return; } memcpy(reply_p->payload, &reply, sizeof(struct monitor_reply)); udp_sendto(listen_pcb, reply_p, addr, port); pbuf_free(reply_p); }
int mon_data(int argc, char **argv){ FIL fil; power_pkt pkt; FRESULT fr; UINT r; if(argc!=2){ printf("specify [read] or [erase]\n"); return -1; } if(strcmp(argv[1],"read")==0){ //print the data out to STDOUT fr = f_open(&fil, DATA_FILE, FA_READ); if(fr){ printf("error reading data: %d\n",(int)fr); return -1; } while(f_read(&fil, &pkt, sizeof(pkt), &r)==0){ if(r==0) //all done break; if(r!=sizeof(pkt)){ core_log("corrupt data buffer"); break; } while(!udi_cdc_is_tx_ready()); //wait for buffer //data is binary so write directly to the USB buffer udi_cdc_write_buf(&pkt,sizeof(pkt)); } f_close(&fil); memset(&pkt,'x',sizeof(pkt)); //set up termination string while(!udi_cdc_is_tx_ready()); //wait for buffer udi_cdc_write_buf(&pkt,sizeof(pkt)); //send it return 0; } else if(strcmp(argv[1],"erase")==0){ fs_erase_data(); if(wemo_config.echo) printf("erased data\n"); return 0; } else{ printf("specify [read] or [erase]\n"); return -1; } //shouldn't get here return 0; }
int watchdog_set(int ms) { int i, id; id = -1; for(i=0;i<MAX_WATCHDOGS;i++) if(!watchdogs[i].active) { id = i; break; } if(id < 0) { core_log("WARNING: Failed to add watchdog\n"); return id; } watchdogs[id].active = 1; watchdogs[id].threshold = clock_get_ms() + ms; return id; }
gboolean core_config_provider_init() { GError* err; ConfigModuleFunc entry; // load config module module_loaded* module = core_module_load(MODULE_TYPE_CONFIG, g_hash_table_lookup(g_options, "config"), &err); if (module == NULL) return FALSE; // find ConfigModule g_module_symbol(module->module, "ConfigModule", (gpointer*) &entry); if (entry == NULL) { core_log("core", LOG_CRIT, 1111, (gchar*) g_module_error()); return FALSE; } // get vtable from module module->vtable = (module_vtable*) entry(); // setup module as config_provider g_provider_config = module; return TRUE; }
void monitor(void){ uint32_t prev_tick=0; //allocate memory for buffers and flush them cmd_buf = membag_alloc(CMD_BUF_SIZE); if(!cmd_buf) core_panic(); memset(cmd_buf,0x0,CMD_BUF_SIZE); //initialize the power packet buffers tx_pkt = &power_pkts[0]; cur_pkt = &power_pkts[1]; //both are empty tx_pkt->status = POWER_PKT_EMPTY; cur_pkt->status = POWER_PKT_EMPTY; //initialize runtime configs wemo_config.echo = false; wemo_config.debug_level = DEBUG_ERROR; wemo_config.collect_data = true; //collect power data //check if we are on USB if(gpio_pin_is_high(VBUS_PIN)){ rgb_led_set(LED_LT_BLUE,0); //don't start wifi because we are configuring b_wifi_enabled=false; //don't collect power data wemo_config.collect_data = false; } //check if the plug is in calibrate mode if(wemo_config.calibrate){ //start the calibration PWM pwm_channel_enable_interrupt(PWM,CAL_PWM_CHANNEL,CAL_PWM_CHANNEL); pwm_channel_enable(PWM,CAL_PWM_CHANNEL); //don't start wifi because we are in calibration mode b_wifi_enabled=false; wemo_config.standalone = true; wemo_config.collect_data = false; //indicate cal mode with a purple LED rgb_led_set(LED_PURPLE,0); } //check if reset is pressed if(gpio_pin_is_low(BUTTON_PIN)){ //erase the configs memset(wemo_config.nilm_id,0x0,MAX_CONFIG_LEN); memset(wemo_config.nilm_ip_addr,0x0,MAX_CONFIG_LEN); memset(wemo_config.wifi_ssid,0x0,MAX_CONFIG_LEN); memset(wemo_config.wifi_pwd,0x0,MAX_CONFIG_LEN); //save the erased config fs_write_config(); core_log("erased config"); //erase the stored data //spin until button is released rgb_led_set(LED_ORANGE,500); while(gpio_pin_is_low(BUTTON_PIN)); rgb_led_set(LED_ORANGE,0); //disable blink } //setup WIFI if(b_wifi_enabled){ if(wifi_init()!=0){ rgb_led_set(LED_PURPLE,0); } else{ //good to go! turn light green rgb_led_set(LED_LT_GREEN,0); } } //initialize the wifi_rx buffer and flag wifi_rx_buf_full = false; memset(wifi_rx_buf,0x0,WIFI_RX_BUF_SIZE); while (1) { //***** SYS TICK ACTIONS ****** if(sys_tick!=prev_tick){ //check if there is a valid wemo sample if(wemo_sample.valid==true && wemo_config.collect_data){ core_log_power_data(&wemo_sample); } wemo_read_power(); wdt_restart(WDT); prev_tick = sys_tick; } //check for pending data from the Internet if(wifi_rx_buf_full){ core_process_wifi_data(); wifi_rx_buf_full=false; } //see if we have any commands to run if(cmd_buf_full){ runcmd(cmd_buf); // run it //clear the buffer cmd_buf_idx = 0; memset(cmd_buf,0x0,CMD_BUF_SIZE); if(wemo_config.echo) printf("\r> "); //print the prompt cmd_buf_full=false; } } }
///////////////////////// // core_log_power_data // Add a power_sample to the current power_pkt // When the pkt is full switch to the other pkt // (ping pong buffer). Throws an error if the // next buffer is not empty (still being TX'd) void core_log_power_data(power_sample *sample){ static int wemo_sample_idx = 0; static int dropped_pkt_count = 0; //reset wifi when this reaches MAX_DROPPED_PACKETS power_pkt *tmp_pkt; //check for error conditions switch(cur_pkt->status){ case POWER_PKT_EMPTY: if(wemo_sample_idx!=0){ printf("Error, empty packet but nonzero index\n"); return; } //set the timestamp for the packet with the first one rtc_get_time_str(cur_pkt->timestamp,PKT_TIMESTAMP_BUF_SIZE); break; case POWER_PKT_TX_IN_PROG: printf("Error, this packet is still being transmitted\n"); return; case POWER_PKT_TX_FAIL: printf("Error, this packet failed TX and isn't clean\n"); break; case POWER_PKT_READY: if(wemo_config.debug_level>=DEBUG_WARN) printf("Transmit this packet first!\n"); //see if the other buffer is ready, if so set this up for //transmission and start filling the other one if(tx_pkt->status==POWER_PKT_EMPTY){ tmp_pkt = cur_pkt; cur_pkt = tx_pkt; tx_pkt = tmp_pkt; wemo_sample_idx = 0; } return; } cur_pkt->status = POWER_PKT_FILLING; cur_pkt->vrms[wemo_sample_idx] = sample->vrms; cur_pkt->irms[wemo_sample_idx] = sample->irms; cur_pkt->watts[wemo_sample_idx] = sample->watts; cur_pkt->pavg[wemo_sample_idx] = sample->pavg; cur_pkt->freq[wemo_sample_idx] = sample->freq; cur_pkt->pf[wemo_sample_idx] = sample->pf; cur_pkt->kwh[wemo_sample_idx] = sample->kwh; wemo_sample_idx++; if(wemo_sample_idx==PKT_SIZE){ cur_pkt->status=POWER_PKT_READY; //save the packet to disk fs_write_power_pkt(cur_pkt); //see if we can switch buffers if(tx_pkt->status==POWER_PKT_EMPTY){ tmp_pkt = cur_pkt; cur_pkt = tx_pkt; tx_pkt = tmp_pkt; //reset dropped packet counter b/c successful transmission dropped_pkt_count = 0; } else { //other buffer is being TX'd, erase this one and refill cur_pkt->status=POWER_PKT_EMPTY; //if this happens [MAX_DROPPED_PACKETS] times in a row, reset the wifi //***Disable this for SmartEE since we aren't necessarily pinging it for data // all the time, if you set up a daemon to monitor the plugs, then this can be // enabled to act as a type of watchdog reset on the wifi *** if(dropped_pkt_count++ > MAX_DROPPED_PACKETS){ dropped_pkt_count = 0; core_log("lost NILM, load off and resetting WiFi"); printf("lost NILM, load off and resetting WiFi"); //turn off relay for safety (since we lost control of the plug) gpio_set_pin_low(RELAY_PIN); //restart the wifi wifi_init(); } //if(wemo_config.debug_level>=DEBUG_WARN) //printf("dropped packet before TX'd\n"); } //start filling the new buffer wemo_sample_idx = 0; } }
void core_process_wifi_data(void){ int BUF_SIZE=XL_BUF_SIZE; char *buf; int chan_num, data_size, r; unsigned int red,green,blue, blink; unsigned int yr,mo,dt,dw,hr,mn,sc; int time_buf_size = MD_BUF_SIZE; char *time_buf; //match against the data if(strlen(wifi_rx_buf)>BUF_SIZE){ printf("can't process rx'd packet, too large\n"); core_log("can't process rx'd packet, too large"); return; } //allocate memory buf = core_malloc(BUF_SIZE); r=sscanf(wifi_rx_buf,"\r\n+IPD,%d,%d:%s", &chan_num, &data_size, buf); if(r!=3){ printf("rx'd corrupt data, ignoring\n"); core_log("rx'd corrupt data, ignoring\n"); //free memory core_free(buf); return; } if(wemo_config.debug_level>DEBUG_INFO) printf("Got [%d] bytes on channel [%d]\n", data_size, chan_num); //discard responses from the NILM to power logging packets, but keep the response //if another core function has requested some data, this is done with the callback //function. The requesting core function registers a callback and this function calls //it and then resets the callback to NULL if(chan_num==4){ //close the socket wifi_send_cmd("AT+CIPCLOSE=4","Unlink",buf,BUF_SIZE,1); //execute the callback if(tx_callback!=NULL){ (*tx_callback)(wifi_rx_buf); tx_callback=NULL; } //clear the server buffer memset(wifi_rx_buf,0x0,WIFI_RX_BUF_SIZE); //free memory core_free(buf); return; } /////////////////// //this data must be inbound to the server port, process the command // // RELAY ON if(strcmp(buf,"relay_on")==0){ gpio_set_pin_high(RELAY_PIN); printf("relay ON\n"); //return "OK" to indicate success wifi_send_txt(0,"OK"); } // RELAY OFF else if(strcmp(buf,"relay_off")==0){ gpio_set_pin_low(RELAY_PIN); printf("relay OFF\n"); //return "OK" to indicate success wifi_send_txt(0,"OK"); } // LED SET else if(strstr(buf,"set_led")==buf){ if(sscanf(buf,"set_led_%u_%u_%u_%u.",&red,&green,&blue,&blink)!=4){ core_log("corrupt led_set request"); } else { rgb_led_set(red,green,blue,blink); if(wemo_config.echo) printf("set led: [%u, %u, %u, %u]\n",red,green,blue,blink); wifi_send_txt(0,"OK"); } } // RTC SET else if(strstr(buf,"set_rtc")==buf){ if(sscanf(buf,"set_rtc_%u_%u_%u_%u_%u_%u_%u.", &yr,&mo,&dt,&dw,&hr,&mn,&sc)!=7){ core_log("corrupt rtc_set request"); } else { if(i2c_rtc_set_time(sc,mn,hr,dw,dt,mo,yr)!=0) printf("error setting RTC\n"); else{ time_buf = membag_alloc(time_buf_size); if(time_buf==NULL) core_panic(); rtc_get_time_str(time_buf,time_buf_size); if(wemo_config.echo) printf("wifi set rtc to: %s\n",time_buf); core_log("wifi set rtc"); membag_free(time_buf); wifi_send_txt(0,"OK"); } } } // SEND DATA else if(strcmp(buf,"send_data")==0){ if(tx_pkt->status!=POWER_PKT_READY){ r = wifi_send_txt(chan_num,"error: no data"); if(r==TX_ERR_MODULE_RESET) while(wifi_init()!=0); //fail!!! anger!!!! reset the module } else { //send the data r=wifi_send_raw(chan_num,(uint8_t*)tx_pkt,sizeof(*tx_pkt)); if(r==TX_ERR_MODULE_RESET){ while(wifi_init()!=0); //fail!! anger!!! reset the module } else { //clear out the packet so we can start again memset(tx_pkt,0,sizeof(*tx_pkt)); tx_pkt->status=POWER_PKT_EMPTY; if(wemo_config.debug_level>=DEBUG_INFO) printf("sent data\n"); } } } else{ printf("unknown command: %s\n",buf); wifi_send_txt(chan_num,"error: unknown command"); //free memory core_free(buf); return; } //clear the server buffer memset(wifi_rx_buf,0x0,WIFI_RX_BUF_SIZE); //free the memory core_free(buf); return; }
int main(gint argc, gchar* argv[]) { GError* err = NULL; // initialize core_log("core", LOG_NOTICE, 1111, "initializing core"); core_init(); // determine essential things core_log("core", LOG_INFO, 1111, "checking environment"); if (!core_options_environment(&err)) { core_log("core", LOG_ERR, 1111, err->message); g_error_free(err); core_destroy(); return 2; } // treat cmd-line options core_log("core", LOG_INFO, 1111, "parsing command line"); if (!core_options_treat(argc, argv, &err)) { core_log("core", LOG_ERR, 1111, err->message); g_error_free(err); core_destroy(); return 3; } // init config provider core_log("core", LOG_INFO, 1111, "initializing configuration"); if (!core_config_provider_init()) { core_log("core", LOG_CRIT, 1111, "cannot initialize config provider"); core_destroy(); return 4; } // do config preloading core_log("core", LOG_INFO, 1111, "loading configuration"); core_config_preload(); // init logger provider core_log("core", LOG_INFO, 1111, "initializing log provider"); if (!core_log_provider_init()) { core_log("core", LOG_ERR, 1111, "cannot initialize log provider"); core_config_provider_destroy(); core_destroy(); return 1111; } core_log("core", LOG_INFO, 1111, "logging system initialized"); // init queue provider core_log("core", LOG_INFO, 1111, "initializing queue provider"); if (!core_queue_provider_init(&err)) { core_log("core", LOG_CRIT, 1111, "cannot initialize queue provider"); g_error_free(err); core_log_provider_destroy(); core_config_provider_destroy(); core_destroy(); return 5; } // load message handling modules core_log("core", LOG_INFO, 1111, "initializing msg input module"); if (!core_messaging_module_init(MODULE_TYPE_MESSAGE_INPUT, &err)) { core_log("core", LOG_ERR, 1111, err->message); g_error_free(err); core_queue_provider_destroy(); core_log_provider_destroy(); core_config_provider_destroy(); core_destroy(); return 6; } core_log("core", LOG_INFO, 1111, "initializing msg output module"); if (!core_messaging_module_init(MODULE_TYPE_MESSAGE_OUTPUT, &err)) { core_log("core", LOG_ERR, 1111, err->message); g_error_free(err); core_queue_provider_destroy(); core_log_provider_destroy(); core_config_provider_destroy(); core_destroy(); return 7; } core_log("core", LOG_INFO, 1111, "initializing msg trash module"); if (!core_messaging_module_init(MODULE_TYPE_MESSAGE_TRASH, &err)) { core_log("core", LOG_ERR, 1111, err->message); g_error_free(err); core_queue_provider_destroy(); core_log_provider_destroy(); core_config_provider_destroy(); core_destroy(); return 8; } // init messaging framework core_log("core", LOG_INFO, 1111, "initializing messaging"); core_messaging_init(); // start messaging framework core_log("core", LOG_NOTICE, 1111, "starting messaging"); core_messaging_start(); // destroy messaging framework core_log("core", LOG_INFO, 1111, "destroying messaging"); core_messaging_destroy(); // destroy queue provider core_log("core", LOG_INFO, 1111, "destroying queue provider"); core_queue_provider_destroy(); // destroy log provider core_log("core", LOG_INFO, 1111, "destroying logging provider"); core_log_provider_destroy(); // destroy config core_log("core", LOG_INFO, 1111, "destroying config provider"); core_config_provider_destroy(); // do cleanup (options & modules) core_log("core", LOG_INFO, 1111, "destroying core"); core_destroy(); return 0; }
static card_action_t card_aquatic(card_evt_t evt) { /* Place an element of your choice onto any sea tile or wetland tile. Place up to 4 species from your gene pool onto that tile. */ card_action_t action = CARD_ACTION_NEXT; player_t* p_player = core_get()->active_player; core_t* p_core = core_get(); static int species_used = 0; switch (evt) { case CARD_EVT_START: species_used = 0; p_core->available_elements = core_get_available_bag_elements(); core_net_send(p_player->id, NET_CMD_SERVER_SELECT_ELEMENT, NULL); break; case CARD_EVT_ELEMENT: core_net_send(p_player->id, NET_CMD_SERVER_SELECT_BOARD_ELEMENT, NULL); break; case CARD_EVT_BOARD_ELEMENT: { uint8_t board_element = p_core->board_element_selection; element_t* p_element = &p_core->board_elements[board_element]; TRC_DBG(core, "%s put element %d at board element position (%d,%d)", p_player->name, p_core->element_selection, p_element->x, p_element->y); p_element->element = p_core->element_selection; core_net_broadcast(NET_CMD_SERVER_ELEMENT_UPDATE, p_element); core_net_send(p_player->id, NET_CMD_SERVER_SELECT_BOARD_TILE, NULL); break; } case CARD_EVT_BOARD_TILE: { tile_t* p_tile = &p_core->board_tiles[p_core->board_tile_selection]; species_used++; p_player->gene_pool--; p_tile->species[p_player->animal]++; p_tile->used = 1; core_net_broadcast(NET_CMD_SERVER_TILE_UPDATE, p_tile); core_net_broadcast(NET_CMD_SERVER_PLAYER_UPDATE, p_player); core_log(p_player, "added 1 species to tile (%d,%d)", p_tile->x, p_tile->y); TRC_DBG(core, "%s added 1 species to tile (%d,%d)", p_player->name, p_tile->x, p_tile->y); if ((species_used < 4) && (p_player->gene_pool > 0)) { core_net_send(p_player->id, NET_CMD_SERVER_SELECT_BOARD_TILE, NULL); } else { action = CARD_ACTION_DONE; } break; } case CARD_EVT_DONE: action = CARD_ACTION_DONE; break; default: break; } if (action == CARD_ACTION_DONE) { /* Clear used tile */ tile_t* p_tile = &p_core->board_tiles[p_core->board_tile_selection]; p_tile->used = 0; core_net_broadcast(NET_CMD_SERVER_TILE_UPDATE, p_tile); } return action; }
int wifi_init(void){ uint32_t BUF_SIZE = MD_BUF_SIZE; uint8_t tmp; //dummy var for flushing UART int r; //return value from wifi_send_cmd (length of resp) char *buf; char *tx_buf; //allocate static buffers if they are not NULL if(resp_buf==NULL){ resp_buf=core_malloc(RESP_BUF_SIZE); } if(resp_complete_buf==NULL){ resp_complete_buf=core_malloc(RESP_COMPLETE_BUF_SIZE); } if(wifi_rx_buf==NULL){ wifi_rx_buf = core_malloc(WIFI_RX_BUF_SIZE); } //if we are standalone, don't do anything if(wemo_config.standalone){ printf("warning: wifi_init called in standalone mode\n"); return 0; } //initialize the memory buf = core_malloc(BUF_SIZE); tx_buf = core_malloc(BUF_SIZE); //set up the UART static usart_serial_options_t usart_options = { .baudrate = WIFI_UART_BAUDRATE, .charlength = WIFI_UART_CHAR_LENGTH, .paritytype = WIFI_UART_PARITY, .stopbits = WIFI_UART_STOP_BITS }; gpio_configure_pin(PIO_PA9_IDX, (PIO_PERIPH_A | PIO_DEFAULT)); gpio_configure_pin(PIO_PA10_IDX, (PIO_PERIPH_A | PIO_DEFAULT)); pmc_enable_periph_clk(ID_WIFI_UART); sysclk_enable_peripheral_clock(ID_WIFI_UART); usart_serial_init(WIFI_UART,&usart_options); //flush any existing data while(usart_serial_is_rx_ready(WIFI_UART)){ usart_serial_getchar(WIFI_UART,&tmp); } // Trigger from timer 0 pmc_enable_periph_clk(ID_TC0); tc_init(TC0, 0, // channel 0 TC_CMR_TCCLKS_TIMER_CLOCK5 // source clock (CLOCK5 = Slow Clock) | TC_CMR_CPCTRG // up mode with automatic reset on RC match | TC_CMR_WAVE // waveform mode | TC_CMR_ACPA_CLEAR // RA compare effect: clear | TC_CMR_ACPC_SET // RC compare effect: set ); TC0->TC_CHANNEL[0].TC_RA = 0; // doesn't matter TC0->TC_CHANNEL[0].TC_RC = 64000; // sets frequency: 32kHz/32000 = 1 Hz NVIC_ClearPendingIRQ(TC0_IRQn); NVIC_SetPriority(TC0_IRQn,1);//high priority NVIC_EnableIRQ(TC0_IRQn); tc_enable_interrupt(TC0, 0, TC_IER_CPCS); //reset the module if(wifi_send_cmd("AT+RST","ready",buf,BUF_SIZE,8)==0){ printf("Error reseting ESP8266\n"); //free memory core_free(buf); core_free(tx_buf); return -1; } //set to mode STA if(wifi_send_cmd("AT+CWMODE=1","OK",buf,BUF_SIZE,8)==0){ printf("Error setting ESP8266 mode\n"); core_free(buf); core_free(tx_buf); return 0; } //try to join the specified network snprintf(tx_buf,BUF_SIZE,"AT+CWJAP=\"%s\",\"%s\"", wemo_config.wifi_ssid,wemo_config.wifi_pwd); if((r=wifi_send_cmd(tx_buf,"OK",buf,BUF_SIZE,10))==0){ printf("no response to CWJAP\n"); //free memory core_free(buf); core_free(tx_buf); return -1; } //check for errors if( (r<1) || (strcmp(&buf[r-1],"OK")!=0)){ snprintf(tx_buf,BUF_SIZE,"failed to join network [%s]: [%s]\n",wemo_config.wifi_ssid, buf); printf(tx_buf); core_log(tx_buf); //free memory core_free(buf); core_free(tx_buf); return -1; } //see if we have an IP address wifi_send_cmd("AT+CIFSR","OK",buf,BUF_SIZE,5); if(strstr(buf,"ERROR")==buf){ printf("error getting IP address\n"); //free the memory core_free(tx_buf); core_free(buf); return -1; } //try to parse the response into an IP address //expect 4 octets but *not* 0.0.0.0 int a1,a2,a3,a4; if(!(sscanf(buf,"+CIFSR:STAIP,\"%d.%d.%d.%d\"",&a1,&a2,&a3,&a4)==4 && a1!=0)){ printf("error, bad address: %s\n",buf); //free the memory core_free(tx_buf); core_free(buf); return -1; } //save the IP to our config snprintf(buf,BUF_SIZE,"%d.%d.%d.%d",a1,a2,a3,a4); memset(wemo_config.ip_addr,0x0,MAX_CONFIG_LEN); strcpy(wemo_config.ip_addr,buf); //set the mode to multiple connection wifi_send_cmd("AT+CIPMUX=1","OK",buf,BUF_SIZE,2); //start a server on port 1336 wifi_send_cmd("AT+CIPSERVER=1,1336","OK",buf,BUF_SIZE,2); //if we know the NILM IP address, send it our IP if(strlen(wemo_config.nilm_ip_addr)!=0){ if(wifi_send_ip()==TX_ERR_MODULE_RESET){ return TX_ERR_MODULE_RESET; } } else { //get the NILM IP address from the manager //once we know the NILM address we send it ours core_get_nilm_ip_addr(); } //log the event snprintf(buf,BUF_SIZE,"Joined [%s] with IP [%s]", wemo_config.wifi_ssid,wemo_config.ip_addr); printf("\n%s\n",buf); core_log(buf); //free the memory core_free(tx_buf); core_free(buf); return 0; }