// Main routine to initialize esp-link. void user_init(void) { // get the flash config so we know how to init things //configWipe(); // uncomment to reset the config for testing purposes bool restoreOk = configRestore(); // Init gpio pin registers gpio_init(); gpio_output_set(0, 0, 0, (1<<15)); // some people tie it to GND, gotta ensure it's disabled // init UART uart_init(flashConfig.baud_rate, 115200); logInit(); // must come after init of uart // Say hello (leave some time to cause break in TX after boot loader's msg os_delay_us(10000L); os_printf("\n\n** %s\n", esp_link_version); os_printf("Flash config restore %s\n", restoreOk ? "ok" : "*FAILED*"); // Status LEDs statusInit(); serledInit(); // Wifi wifiInit(); // init the flash filesystem with the html stuff espFsInit(&_binary_espfs_img_start); //EspFsInitResult res = espFsInit(&_binary_espfs_img_start); //os_printf("espFsInit %s\n", res?"ERR":"ok"); // mount the http handlers httpdInit(builtInUrls, 80); // init the wifi-serial transparent bridge (port 23) serbridgeInit(23, 2323); uart_add_recv_cb(&serbridgeUartCb); #ifdef SHOW_HEAP_USE os_timer_disarm(&prHeapTimer); os_timer_setfn(&prHeapTimer, prHeapTimerCb, NULL); os_timer_arm(&prHeapTimer, 10000, 1); #endif struct rst_info *rst_info = system_get_rst_info(); NOTICE("Reset cause: %d=%s", rst_info->reason, rst_codes[rst_info->reason]); NOTICE("exccause=%d epc1=0x%x epc2=0x%x epc3=0x%x excvaddr=0x%x depc=0x%x", rst_info->exccause, rst_info->epc1, rst_info->epc2, rst_info->epc3, rst_info->excvaddr, rst_info->depc); uint32_t fid = spi_flash_get_id(); NOTICE("Flash map %s, manuf 0x%02lX chip 0x%04lX", flash_maps[system_get_flash_size_map()], fid & 0xff, (fid&0xff00)|((fid>>16)&0xff)); NOTICE("** esp-link ready"); // Init SNTP service cgiServicesSNTPInit(); #ifdef MQTT NOTICE("initializing MQTT"); mqtt_client_init(); #endif NOTICE("initializing user application"); app_init(); NOTICE("Waiting for work to do..."); }
int sensorsDetect(void) { char *dirname =(char *) "/sys/class/input"; char buf[256]; char classPath[256]; int res; DIR *dir; struct dirent *de; int fd = -1; int ret = 0; memset(&buf,0,sizeof(buf)); statusInit(); dir = opendir(dirname); if (dir == NULL) return -1; while((de = readdir(dir))) { if (strncmp(de->d_name, "input", strlen("input")) != 0) { continue; } sprintf(classPath, "%s/%s", dirname, de->d_name); snprintf(buf, sizeof(buf), "%s/name", classPath); fd = open(buf, O_RDONLY); if (fd < 0) { continue; } if ((res = read(fd, buf, sizeof(buf))) < 0) { close(fd); continue; } buf[res - 1] = '\0'; #ifdef DEBUG_SENSOR ALOGD("buf:%s\n", buf); #endif ret = searchDevice(buf, classPath); close(fd); fd = -1; } closedir(dir); return 0; }
//Main routine. Initialize stdout, the I/O, filesystem and the webserver and we're done. void user_init(void) { // init gpio pins used to reset&reprogram attached microcontrollers gpio_init(); // put MCU into reset in case it interferes with serial-programming of the esp8266 //GPIO_OUTPUT_SET(MCU_RESET, 0); // init UART uart_init(BIT_RATE_115200, BIT_RATE_115200); // say hello (leave some time to cause break in TX after boot loader's msg os_delay_us(10000L); # define VERS_STR_STR(V) #V # define VERS_STR(V) VERS_STR_STR(V) os_printf("\n\nInitializing esp-link\n" VERS_STR(VERSION) "\n"); //configWipe(); if (configRestore()) os_printf("Flash config restored\n"); else os_printf("*** Flash config restore failed, using defaults ***\n"); // Status LEDs statusInit(); serledInit(); logInit(); // Wifi wifiInit(); // init the flash filesystem with the html stuff EspFsInitResult res = espFsInit(&_binary_espfs_img_start); os_printf("espFsInit(0x%08lx) returned %d\n", (uint32_t)&_binary_espfs_img_start, res); // mount the http handlers httpdInit(builtInUrls, 80); // init the wifi-serial transparent bridge (port 23) serbridgeInit(23); uart_add_recv_cb(&serbridgeUartCb); #ifdef SHOW_HEAP_USE os_timer_disarm(&prHeapTimer); os_timer_setfn(&prHeapTimer, prHeapTimerCb, NULL); os_timer_arm(&prHeapTimer, 3000, 1); #endif struct rst_info *rst_info = system_get_rst_info(); os_printf("Reset cause: %d=%s\n", rst_info->reason, rst_codes[rst_info->reason]); os_printf("exccause=%d epc1=0x%x epc2=0x%x epc3=0x%x excvaddr=0x%x depc=0x%x\n", rst_info->exccause, rst_info->epc1, rst_info->epc2, rst_info->epc3, rst_info->excvaddr, rst_info->depc); os_printf("** esp-link ready\n"); }
//Main routine. Initialize stdout, the I/O, filesystem and the webserver and we're done. void user_init(void) { // get the flash config so we know how to init things //configWipe(); // uncomment to reset the config for testing purposes bool restoreOk = configRestore(); // init gpio pin registers gpio_init(); // init UART uart_init(flashConfig.baud_rate, 115200); logInit(); // must come after init of uart // say hello (leave some time to cause break in TX after boot loader's msg os_delay_us(10000L); os_printf("\n\n** %s\n", esp_link_version); os_printf("Flash config restore %s\n", restoreOk ? "ok" : "*FAILED*"); // Status LEDs statusInit(); serledInit(); // Wifi wifiInit(); // init the flash filesystem with the html stuff espFsInit(&_binary_espfs_img_start); //EspFsInitResult res = espFsInit(&_binary_espfs_img_start); //os_printf("espFsInit %s\n", res?"ERR":"ok"); // mount the http handlers httpdInit(builtInUrls, 80); // init the wifi-serial transparent bridge (port 23) serbridgeInit(23); uart_add_recv_cb(&serbridgeUartCb); #ifdef SHOW_HEAP_USE os_timer_disarm(&prHeapTimer); os_timer_setfn(&prHeapTimer, prHeapTimerCb, NULL); os_timer_arm(&prHeapTimer, 10000, 1); #endif struct rst_info *rst_info = system_get_rst_info(); os_printf("Reset cause: %d=%s\n", rst_info->reason, rst_codes[rst_info->reason]); os_printf("exccause=%d epc1=0x%x epc2=0x%x epc3=0x%x excvaddr=0x%x depc=0x%x\n", rst_info->exccause, rst_info->epc1, rst_info->epc2, rst_info->epc3, rst_info->excvaddr, rst_info->depc); os_printf("Flash map %d, chip %08X\n", system_get_flash_size_map(), spi_flash_get_id()); os_printf("** esp-link ready\n"); }
// Cgi to change choice of pin assignments int ICACHE_FLASH_ATTR cgiPinsSet(HttpdConnData *connData) { if (connData->conn==NULL) { return HTTPD_CGI_DONE; // Connection aborted } int8_t ok = 0; int8_t reset, isp, conn, ser; bool swap, rxpup; ok |= getInt8Arg(connData, "reset", &reset); ok |= getInt8Arg(connData, "isp", &isp); ok |= getInt8Arg(connData, "conn", &conn); ok |= getInt8Arg(connData, "ser", &ser); ok |= getBoolArg(connData, "swap", &swap); ok |= getBoolArg(connData, "rxpup", &rxpup); if (ok < 0) return HTTPD_CGI_DONE; char *coll; if (ok > 0) { // check whether two pins collide uint16_t pins = 0; if (reset >= 0) pins = 1 << reset; if (isp >= 0) { if (pins & (1<<isp)) { coll = "ISP/Flash"; goto collision; } pins |= 1 << isp; } if (conn >= 0) { if (pins & (1<<conn)) { coll = "Conn LED"; goto collision; } pins |= 1 << conn; } if (ser >= 0) { if (pins & (1<<ser)) { coll = "Serial LED"; goto collision; } pins |= 1 << ser; } if (swap) { if (pins & (1<<15)) { coll = "Uart TX"; goto collision; } if (pins & (1<<13)) { coll = "Uart RX"; goto collision; } } else { if (pins & (1<<1)) { coll = "Uart TX"; goto collision; } if (pins & (1<<3)) { coll = "Uart RX"; goto collision; } } // we're good, set flashconfig flashConfig.reset_pin = reset; flashConfig.isp_pin = isp; flashConfig.conn_led_pin = conn; flashConfig.ser_led_pin = ser; flashConfig.swap_uart = swap; flashConfig.rx_pullup = rxpup; os_printf("Pins changed: reset=%d isp=%d conn=%d ser=%d swap=%d rx-pup=%d\n", reset, isp, conn, ser, swap, rxpup); // apply the changes serbridgeInitPins(); serledInit(); statusInit(); // save to flash if (configSave()) { httpdStartResponse(connData, 204); httpdEndHeaders(connData); } else { httpdStartResponse(connData, 500); httpdEndHeaders(connData); httpdSend(connData, "Failed to save config", -1); } } return HTTPD_CGI_DONE; collision: { char buff[128]; os_sprintf(buff, "Pin assignment for %s collides with another assignment", coll); errorResponse(connData, 400, buff); return HTTPD_CGI_DONE; } }
/* ... the main entry point for the wvcwopd process */ int main (int argc, char *argv[]) { void (*alarmHandler)(int); int retVal; FILE *pidfile; int iValue; double dValue; const char* sValue; int runAsDaemon = TRUE; if (argc > 1) { if (!strcmp(argv[1], "-f")) { runAsDaemon = FALSE; } } memset (&cwopWork, 0, sizeof (cwopWork)); /* ... initialize some system stuff first */ retVal = cwopSysInit (&cwopWork); if (retVal == ERROR) { radMsgLogInit (PROC_NAME_CWOP, FALSE, TRUE); radMsgLog (PRI_CATASTROPHIC, "wvcwopd init failed!"); radMsgLogExit (); exit (1); } else if (retVal == ERROR_ABORT) { exit (2); } /* ... call the global radlib system init function */ if (radSystemInit (WVIEW_SYSTEM_ID) == ERROR) { radMsgLogInit (PROC_NAME_CWOP, TRUE, TRUE); radMsgLog (PRI_CATASTROPHIC, "radSystemInit failed!"); radMsgLogExit (); exit (1); } /* ... call the radlib process init function */ if (radProcessInit (PROC_NAME_CWOP, cwopWork.fifoFile, PROC_NUM_TIMERS_CWOP, runAsDaemon, // TRUE for daemon msgHandler, evtHandler, NULL) == ERROR) { printf ("\nradProcessInit failed: %s\n\n", PROC_NAME_CWOP); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } cwopWork.myPid = getpid (); pidfile = fopen (cwopWork.pidFile, "w"); if (pidfile == NULL) { radMsgLog (PRI_CATASTROPHIC, "lock file create failed!"); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } fprintf (pidfile, "%d", getpid ()); fclose (pidfile); alarmHandler = radProcessSignalGetHandler (SIGALRM); radProcessSignalCatchAll (defaultSigHandler); radProcessSignalCatch (SIGALRM, alarmHandler); radProcessSignalRelease(SIGABRT); // get our configuration values if (wvconfigInit(FALSE) == ERROR) { radMsgLog (PRI_CATASTROPHIC, "wvconfigInit failed!"); cwopSysExit (&cwopWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // Is the CWOP daemon enabled? iValue = wvconfigGetBooleanValue(configItem_ENABLE_CWOP); if (iValue == ERROR || iValue == 0) { wvconfigExit (); radMsgLog (PRI_CATASTROPHIC, "CWOP daemon is NOT enabled - exiting..."); cwopSysExit (&cwopWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // get the wview verbosity setting if (wvutilsSetVerbosity (WV_VERBOSE_WVCWOPD) == ERROR) { wvconfigExit (); radMsgLog (PRI_CATASTROPHIC, "wvutilsSetVerbosity failed!"); cwopSysExit (&cwopWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // get the APRS call sign sValue = wvconfigGetStringValue(configItemCWOP_APRS_CALL_SIGN); if (sValue == NULL) { // we can't do without this! wvconfigExit (); radMsgLog (PRI_CATASTROPHIC, "%s failed!", configItemCWOP_APRS_CALL_SIGN); cwopSysExit (&cwopWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { wvstrncpy (cwopWork.callSign, sValue, sizeof(cwopWork.callSign)); if (sValue[strlen(sValue)-1] >= '0' && sValue[strlen(sValue)-1] <= '9') { cwopWork.callSignOffset = atoi(&sValue[strlen(sValue)-1]); } else { cwopWork.callSignOffset = (sValue[strlen(sValue)-1] % 10); } cwopWork.callSignOffset %= 10; } // get the primary APRS server sValue = wvconfigGetStringValue(configItemCWOP_APRS_SERVER1); if (sValue == NULL) { // we can't do without this! wvconfigExit (); radMsgLog (PRI_CATASTROPHIC, "%s failed!", configItemCWOP_APRS_SERVER1); cwopSysExit (&cwopWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { wvstrncpy (cwopWork.server1, sValue, sizeof(cwopWork.server1)); } // get the primary APRS port number iValue = wvconfigGetINTValue(configItemCWOP_APRS_PORTNO1); if (iValue < 0) { // we can't do without this! wvconfigExit (); radMsgLog (PRI_CATASTROPHIC, "%s failed!", configItemCWOP_APRS_PORTNO1); cwopSysExit (&cwopWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { cwopWork.portNo1 = iValue; } // get the secondary APRS server sValue = wvconfigGetStringValue(configItemCWOP_APRS_SERVER2); if (sValue == NULL) { // we can't do without this! wvconfigExit (); radMsgLog (PRI_CATASTROPHIC, "%s failed!", configItemCWOP_APRS_SERVER2); cwopSysExit (&cwopWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { wvstrncpy (cwopWork.server2, sValue, sizeof(cwopWork.server2)); } // get the primary APRS port number iValue = wvconfigGetINTValue(configItemCWOP_APRS_PORTNO2); if (iValue < 0) { // we can't do without this! wvconfigExit (); radMsgLog (PRI_CATASTROPHIC, "%s failed!", configItemCWOP_APRS_PORTNO2); cwopSysExit (&cwopWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { cwopWork.portNo2 = iValue; } // get the tertiary APRS server sValue = wvconfigGetStringValue(configItemCWOP_APRS_SERVER3); if (sValue == NULL) { // we can't do without this! wvconfigExit (); radMsgLog (PRI_CATASTROPHIC, "%s failed!", configItemCWOP_APRS_SERVER3); cwopSysExit (&cwopWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { wvstrncpy (cwopWork.server3, sValue, sizeof(cwopWork.server3)); } // get the primary APRS port number iValue = wvconfigGetINTValue(configItemCWOP_APRS_PORTNO3); if (iValue < 0) { // we can't do without this! wvconfigExit (); radMsgLog (PRI_CATASTROPHIC, "%s failed!", configItemCWOP_APRS_PORTNO3); cwopSysExit (&cwopWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { cwopWork.portNo3 = iValue; } // get the fine pitch latitude that APRS requires sValue = wvconfigGetStringValue(configItemCWOP_LATITUDE); if (sValue == NULL) { // we can't do without this! wvconfigExit (); radMsgLog (PRI_CATASTROPHIC, "%s failed!", configItemCWOP_LATITUDE); cwopSysExit (&cwopWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { wvstrncpy (cwopWork.latitude, sValue, sizeof(cwopWork.latitude)); } // get the fine pitch longitude that APRS requires sValue = wvconfigGetStringValue(configItemCWOP_LONGITUDE); if (sValue == NULL) { // we can't do without this! wvconfigExit (); radMsgLog (PRI_CATASTROPHIC, "%s failed!", configItemCWOP_LONGITUDE); cwopSysExit (&cwopWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { wvstrncpy (cwopWork.longitude, sValue, sizeof(cwopWork.longitude)); } // get the WX packet logging preference iValue = wvconfigGetBooleanValue(configItemCWOP_LOG_WX_PACKET); if (iValue <= 0) { // just disable it cwopWork.logWXPackets = 0; } else { cwopWork.logWXPackets = iValue; } wvconfigExit (); if (statusInit(cwopWork.statusFile, cwopStatusLabels) == ERROR) { radMsgLog (PRI_HIGH, "statusInit failed - exiting..."); cwopSysExit (&cwopWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } statusUpdate(STATUS_BOOTING); // wait a bit here before continuing radUtilsSleep (500); cwopWork.timer = radTimerCreate (NULL, timerHandler, NULL); if (cwopWork.timer == NULL) { statusUpdateMessage("radTimerCreate failed"); radMsgLog (PRI_HIGH, "radTimerCreate failed"); statusUpdate(STATUS_ERROR); cwopSysExit (&cwopWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } radProcessTimerStart (cwopWork.timer, CWOP_MINUTE_INTERVAL); // register with the radlib message router if (radMsgRouterInit (WVIEW_RUN_DIR) == ERROR) { statusUpdateMessage("radMsgRouterInit failed"); radMsgLog (PRI_HIGH, "radMsgRouterInit failed!"); statusUpdate(STATUS_ERROR); cwopSysExit (&cwopWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // enable message reception from the radlib router for SHUTDOWN msgs radMsgRouterMessageRegister (WVIEW_MSG_TYPE_SHUTDOWN); // wait for the wview daemon to be ready if (waitForWviewDaemon () == ERROR) { radMsgLog (PRI_HIGH, "waitForWviewDaemon failed"); statusUpdate(STATUS_ERROR); radMsgRouterExit (); cwopSysExit (&cwopWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // enable message reception from the radlib router for archive notifications radMsgRouterMessageRegister (WVIEW_MSG_TYPE_ARCHIVE_NOTIFY); // enable message reception from the radlib router for POLL msgs radMsgRouterMessageRegister (WVIEW_MSG_TYPE_POLL); radMsgLog (PRI_STATUS, "CWOP: configured to submit station %s data to:", cwopWork.callSign); radMsgLog (PRI_STATUS, "CWOP: Primary: %s:%d", cwopWork.server1, cwopWork.portNo1); radMsgLog (PRI_STATUS, "CWOP: Secondary: %s:%d", cwopWork.server2, cwopWork.portNo2); radMsgLog (PRI_STATUS, "CWOP: Tertiary: %s:%d", cwopWork.server3, cwopWork.portNo3); radMsgLog (PRI_STATUS, "CWOP: Submitting every %d minutes at offset minute: %d", cwopWork.reportInterval, cwopWork.callSignOffset); // enter normal processing cwopWork.inMainLoop = TRUE; statusUpdate(STATUS_RUNNING); statusUpdateMessage("Normal operation"); radMsgLog (PRI_STATUS, "running..."); while (!cwopWork.exiting) { // wait on something interesting if (radProcessWait (0) == ERROR) { cwopWork.exiting = TRUE; } } statusUpdateMessage("exiting normally"); radMsgLog (PRI_STATUS, "exiting normally..."); statusUpdate(STATUS_SHUTDOWN); radMsgRouterExit (); radTimerDelete (cwopWork.timer); cwopSysExit (&cwopWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (0); }
/* ... the main entry point for the daemon process */ int main (int argc, char *argv[]) { void (*alarmHandler)(int); FILE *pidfile; int iValue; double dValue; const char* sValue; int runAsDaemon = TRUE; if (argc > 1) { if (!strcmp(argv[1], "-f")) { runAsDaemon = FALSE; } } /* ... start with a clean slate */ memset (&wviewdWork, 0, sizeof (wviewdWork)); /* ... initialize some system stuff first */ if (daemonSysInit (&wviewdWork) == -1) { radMsgLogInit (PROC_NAME_DAEMON, TRUE, TRUE); radMsgLog (PRI_CATASTROPHIC, "system init failed!\n"); radMsgLogExit (); exit (1); } /* ... call the global radlib system init function */ if (radSystemInit (WVIEW_SYSTEM_ID) == ERROR) { radMsgLogInit (PROC_NAME_DAEMON, TRUE, TRUE); radMsgLog (PRI_CATASTROPHIC, "radSystemInit failed!"); radMsgLogExit (); exit (1); } /* ... call the radlib process init function */ if (radProcessInit (PROC_NAME_DAEMON, wviewdWork.fifoFile, PROC_NUM_TIMERS_DAEMON, runAsDaemon, // TRUE for daemon msgHandler, evtHandler, NULL) == ERROR) { printf ("\nradProcessInit failed: %s\n\n", PROC_NAME_DAEMON); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } wviewdWork.myPid = getpid (); pidfile = fopen (wviewdWork.pidFile, "w"); if (pidfile == NULL) { radMsgLog (PRI_CATASTROPHIC, "lock file create failed!\n"); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } fprintf (pidfile, "%d", getpid ()); fclose (pidfile); alarmHandler = radProcessSignalGetHandler (SIGALRM); radProcessSignalCatchAll (defaultSigHandler); radProcessSignalCatch (SIGALRM, alarmHandler); radProcessSignalRelease(SIGABRT); radMsgLog (PRI_STATUS, "%s starting ...", globalWviewVersionStr); radTimeGetMSSinceEpoch(); wvutilsDetectDSTInit(); // get our configuration values: if (wvconfigInit(TRUE) == ERROR) { radMsgLog (PRI_CATASTROPHIC, "config database is missing!!!\n"); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // get the wview verbosity setting if (wvutilsSetVerbosity (WV_VERBOSE_WVIEWD) == ERROR) { wvconfigExit(); radMsgLog (PRI_CATASTROPHIC, "wvutilsSetVerbosity failed!"); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } ///// STATION_INTERFACE PROCESSING BEGIN ///// sValue = wvconfigGetStringValue(configItem_STATION_STATION_TYPE); if (sValue == NULL) { radMsgLog (PRI_MEDIUM, "no station type given, defaulting to 'VantagePro'..."); strcpy (wviewdWork.stationType, "VantagePro"); } else { wvstrncpy(wviewdWork.stationType, sValue, sizeof(wviewdWork.stationType)); } if ((!strcmp(wviewdWork.stationType, "WMRUSB")) || (!strcmp(wviewdWork.stationType, "WH1080"))) { // USB stations: radMsgLog (PRI_MEDIUM, "station interface: native USB ..."); } else { sValue = wvconfigGetStringValue(configItem_STATION_STATION_INTERFACE); if (sValue == NULL) { radMsgLog (PRI_MEDIUM, "no station interface given, defaulting to 'serial'..."); strcpy (wviewdWork.stationInterface, "serial"); } else { wvstrncpy(wviewdWork.stationInterface, sValue, sizeof(wviewdWork.stationInterface)); } // process the interface type if (!strcmp (wviewdWork.stationInterface, "serial")) { radMsgLog (PRI_MEDIUM, "station interface: serial ..."); // we need a device name for serial IFs sValue = wvconfigGetStringValue(configItem_STATION_STATION_DEV); if (sValue == NULL) { wvconfigExit(); radMsgLog (PRI_CATASTROPHIC, "no serial device given, aborting..."); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { wvstrncpy(wviewdWork.stationDevice, sValue, sizeof(wviewdWork.stationDevice)); } // grab the DTR toggle flag: iValue = wvconfigGetBooleanValue(configItem_STATION_STATION_DTR); if (iValue >= 0) { wviewdWork.stationToggleDTR = iValue; } else { wviewdWork.stationToggleDTR = TRUE; } } else if (!strcmp (wviewdWork.stationInterface, "ethernet")) { radMsgLog (PRI_MEDIUM, "station interface: ethernet ..."); // we need host and port for ethernet sValue = wvconfigGetStringValue(configItem_STATION_STATION_HOST); if (sValue == NULL) { wvconfigExit(); radMsgLog (PRI_CATASTROPHIC, "no hostname given, aborting..."); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { wvstrncpy(wviewdWork.stationHost, sValue, sizeof(wviewdWork.stationHost)); iValue = wvconfigGetINTValue(configItem_STATION_STATION_PORT); if (iValue <= 0) { wvconfigExit(); radMsgLog (PRI_CATASTROPHIC, "no port given, aborting..."); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { wviewdWork.stationPort = iValue; // grab the Weatherlink IP flag: iValue = wvconfigGetBooleanValue(configItem_STATION_STATION_WLIP); if (iValue >= 0) { wviewdWork.stationIsWLIP = iValue; } else { wviewdWork.stationIsWLIP = FALSE; } } } } else { // invalid type specified - abort wvconfigExit(); radMsgLog (PRI_CATASTROPHIC, "invalid STATION_INTERFACE %s given, aborting...", wviewdWork.stationInterface); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } } ///// STATION_INTERFACE PROCESSING END ///// iValue = wvconfigGetINTValue(configItem_STATION_STATION_RAIN_SEASON_START); if (iValue <= 0) { radMsgLog (PRI_MEDIUM, "Rain Season Start Month not found - defaulting to 1 (JAN)...\n"); wviewdWork.stationRainSeasonStart = 1; } else { wviewdWork.stationRainSeasonStart = iValue; if (wviewdWork.stationRainSeasonStart < 1 || wviewdWork.stationRainSeasonStart > 12) { radMsgLog (PRI_MEDIUM, "Invalid Rain Season Start Month %d found - defaulting to 1 (JAN)...\n", wviewdWork.stationRainSeasonStart); wviewdWork.stationRainSeasonStart = 1; } else { radMsgLog (PRI_STATUS, "Rain Season Start Month set to %d\n", wviewdWork.stationRainSeasonStart); } } dValue = wvconfigGetDOUBLEValue(configItem_STATION_STATION_RAIN_STORM_TRIGGER_START); if (dValue <= 0.0) { radMsgLog (PRI_MEDIUM, "no rain storm start trigger given, defaulting to 0.05 in/hr..."); wviewdWork.stationRainStormTrigger = 0.05; } else { wviewdWork.stationRainStormTrigger = (float)dValue; radMsgLog (PRI_STATUS, "Rain Storm Start Trigger set to %5.2f in/hr\n", wviewdWork.stationRainStormTrigger); } iValue = wvconfigGetINTValue(configItem_STATION_STATION_RAIN_STORM_IDLE_STOP); if (iValue <= 0) { radMsgLog (PRI_MEDIUM, "no rain storm idle stop time given, defaulting to 12 hours..."); wviewdWork.stationRainStormIdleHours = 12; } else { wviewdWork.stationRainStormIdleHours = iValue; radMsgLog (PRI_STATUS, "Rain Storm Stop Time set to %d hours\n", wviewdWork.stationRainStormIdleHours); } dValue = wvconfigGetDOUBLEValue(configItem_STATION_STATION_RAIN_YTD); if (dValue < 0.0) { radMsgLog (PRI_MEDIUM, "no rain YTD preset given, defaulting to 0.00 inches..."); wviewdWork.stationRainStormIdleHours = 12; } else { wviewdWork.stationRainYTDPreset = (float)dValue; radMsgLog (PRI_STATUS, "Rain YTD preset set to %.2f inches\n", wviewdWork.stationRainYTDPreset); } dValue = wvconfigGetDOUBLEValue(configItem_STATION_STATION_ET_YTD); if (dValue < 0.0) { radMsgLog (PRI_MEDIUM, "no ET YTD preset given, defaulting to 0.000 inches..."); wviewdWork.stationETYTDPreset = 0; } else { wviewdWork.stationETYTDPreset = (float)dValue; radMsgLog (PRI_STATUS, "ET YTD preset set to %.3f inches\n", wviewdWork.stationETYTDPreset); } iValue = wvconfigGetINTValue(configItem_STATION_STATION_RAIN_ET_YTD_YEAR); if (iValue < 0) { radMsgLog (PRI_MEDIUM, "no rain/ET YTD Year given, disabling..."); wviewdWork.stationRainETPresetYear = 0; } else { wviewdWork.stationRainETPresetYear = iValue; if (wviewdWork.stationRainETPresetYear < 2000 || wviewdWork.stationRainETPresetYear > 3000) { radMsgLog (PRI_MEDIUM, "bad rain/ET YTD Year given, disabling..."); wviewdWork.stationRainETPresetYear = 0; } else { radMsgLog (PRI_STATUS, "rain/ET YTD preset Year set to %d\n", wviewdWork.stationRainETPresetYear); } } iValue = wvconfigGetINTValue(configItem_STATION_POLL_INTERVAL); if (iValue < 0) { radMsgLog (PRI_MEDIUM, "no POLL_INTERVAL retrieved, setting to 30 seconds..."); wviewdWork.cdataInterval = 30000; } else { wviewdWork.cdataInterval = iValue * 1000; } if (((wviewdWork.cdataInterval % 1000) != 0) || ((wviewdWork.cdataInterval/1000) > 60) || ((60 % (wviewdWork.cdataInterval/1000)) != 0)) { radMsgLog (PRI_MEDIUM, "station polling interval %d found in wview.conf is invalid:", wviewdWork.cdataInterval); radMsgLog (PRI_MEDIUM, "defaulting to 30 seconds ..."); radMsgLog (PRI_MEDIUM, "Note: station polling interval must be less than 60 seconds"); radMsgLog (PRI_MEDIUM, " and an even divisor of 60 seconds (10000, 15000, 30000)"); wviewdWork.cdataInterval = 30 * 1000; } else { radMsgLog (PRI_STATUS, "station polling interval set to %d seconds", (wviewdWork.cdataInterval/1000)); } iValue = wvconfigGetINTValue(configItem_STATION_PUSH_INTERVAL); if (iValue < 0) { radMsgLog (PRI_MEDIUM, "no PUSH_INTERVAL retrieved, setting to 60 seconds..."); wviewdWork.pushInterval = 60000; } else { wviewdWork.pushInterval = iValue * 1000; } // Calibration configuration: dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_BAROMETER); if (dValue <= 0.0) { wviewdWork.calMBarometer = 1.00; } else { wviewdWork.calMBarometer = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_BAROMETER); wviewdWork.calCBarometer = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_PRESSURE); if (dValue <= 0.0) { wviewdWork.calMPressure = 1.00; } else { wviewdWork.calMPressure = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_PRESSURE); wviewdWork.calCPressure = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_ALTIMETER); if (dValue <= 0.0) { wviewdWork.calMAltimeter = 1.00; } else { wviewdWork.calMAltimeter = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_ALTIMETER); wviewdWork.calCAltimeter = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_INTEMP); if (dValue <= 0.0) { wviewdWork.calMInTemp = 1.00; } else { wviewdWork.calMInTemp = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_INTEMP); wviewdWork.calCInTemp = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_OUTTEMP); if (dValue <= 0.0) { wviewdWork.calMOutTemp = 1.00; } else { wviewdWork.calMOutTemp = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_OUTTEMP); wviewdWork.calCOutTemp = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_INHUMIDITY); if (dValue <= 0.0) { wviewdWork.calMInHumidity = 1.00; } else { wviewdWork.calMInHumidity = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_INHUMIDITY); wviewdWork.calCInHumidity = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_OUTHUMIDITY); if (dValue <= 0.0) { wviewdWork.calMOutHumidity = 1.00; } else { wviewdWork.calMOutHumidity = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_OUTHUMIDITY); wviewdWork.calCOutHumidity = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_WINDSPEED); if (dValue <= 0.0) { wviewdWork.calMWindSpeed = 1.00; } else { wviewdWork.calMWindSpeed = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_WINDSPEED); wviewdWork.calCWindSpeed = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_WINDDIR); if (dValue <= 0.0) { wviewdWork.calMWindDir = 1.00; } else { wviewdWork.calMWindDir = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_WINDDIR); wviewdWork.calCWindDir = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_RAIN); if (dValue <= 0.0) { wviewdWork.calMRain = 1.00; } else { wviewdWork.calMRain = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_RAIN); wviewdWork.calCRain = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_RAINRATE); if (dValue <= 0.0) { wviewdWork.calMRainRate = 1.00; } else { wviewdWork.calMRainRate = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_RAINRATE); wviewdWork.calCRainRate = dValue; iValue = wvconfigGetBooleanValue(configItem_ENABLE_EMAIL); if (iValue >= 0) { wviewdWork.IsAlertEmailsEnabled = iValue; } if (wviewdWork.IsAlertEmailsEnabled) { sValue = wvconfigGetStringValue(configItem_TO_EMAIL_ADDRESS); if (sValue == NULL) { radMsgLog (PRI_HIGH, "NO alert email TO address given - disabling email alerts..."); wviewdWork.IsAlertEmailsEnabled = 0; } else { wvstrncpy (wviewdWork.alertEmailToAdrs, sValue, sizeof(wviewdWork.alertEmailToAdrs)); } sValue = wvconfigGetStringValue(configItem_FROM_EMAIL_ADDRESS); if (sValue == NULL) { radMsgLog (PRI_HIGH, "NO alert email FROM address given - disabling email alerts..."); wviewdWork.IsAlertEmailsEnabled = 0; } else { wvstrncpy (wviewdWork.alertEmailFromAdrs, sValue, sizeof(wviewdWork.alertEmailFromAdrs)); } iValue = wvconfigGetBooleanValue(configItem_SEND_TEST_EMAIL); if (iValue >= 0) { wviewdWork.IsTestEmailEnabled = iValue; } } iValue = wvconfigGetBooleanValue(configItem_HTMLGEN_STATION_SHOW_IF); if (iValue >= 0) { wviewdWork.showStationIF = iValue; } else { wviewdWork.showStationIF = TRUE; } wvconfigExit (); if (statusInit(wviewdWork.statusFile, wviewStatusLabels) == ERROR) { radMsgLog (PRI_HIGH, "statusInit failed - exiting..."); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } statusUpdate(STATUS_BOOTING); // ... Initialize the archive database interface: if (dbsqliteArchiveInit() == ERROR) { radMsgLog (PRI_HIGH, "dbsqliteArchiveInit failed"); statusUpdateMessage("dbsqliteArchiveInit failed"); statusUpdate(STATUS_ERROR); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // Initialize timers: wviewdWork.archiveTimer = radTimerCreate (NULL, archiveTimerHandler, NULL); if (wviewdWork.archiveTimer == NULL) { radMsgLog (PRI_HIGH, "radTimerCreate failed"); statusUpdateMessage("radTimerCreate failed"); statusUpdate(STATUS_ERROR); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } wviewdWork.cdataTimer = radTimerCreate (NULL, cdtimerHandler, NULL); if (wviewdWork.cdataTimer == NULL) { radMsgLog (PRI_HIGH, "radTimerCreate failed"); statusUpdateMessage("radTimerCreate failed"); statusUpdate(STATUS_ERROR); radTimerDelete (wviewdWork.archiveTimer); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } wviewdWork.pushTimer = radTimerCreate (NULL, pushTimerHandler, NULL); if (wviewdWork.pushTimer == NULL) { radMsgLog (PRI_HIGH, "radTimerCreate failed"); statusUpdateMessage("radTimerCreate failed"); statusUpdate(STATUS_ERROR); radTimerDelete (wviewdWork.cdataTimer); radTimerDelete (wviewdWork.archiveTimer); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } wviewdWork.syncTimer = radTimerCreate (NULL, syncTimerHandler, NULL); if (wviewdWork.syncTimer == NULL) { radMsgLog (PRI_HIGH, "sync radTimerCreate failed"); statusUpdateMessage("radTimerCreate failed"); statusUpdate(STATUS_ERROR); radTimerDelete (wviewdWork.cdataTimer); radTimerDelete (wviewdWork.pushTimer); radTimerDelete (wviewdWork.archiveTimer); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } wviewdWork.ifTimer = radTimerCreate (NULL, ifTimerHandler, NULL); if (wviewdWork.ifTimer == NULL) { radMsgLog (PRI_HIGH, "sync radTimerCreate failed"); statusUpdateMessage("radTimerCreate failed"); statusUpdate(STATUS_ERROR); radTimerDelete (wviewdWork.syncTimer); radTimerDelete (wviewdWork.cdataTimer); radTimerDelete (wviewdWork.pushTimer); radTimerDelete (wviewdWork.archiveTimer); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } radProcessEventsAdd (STATION_INIT_COMPLETE_EVENT); radProcessEventsAdd (STATION_LOOP_COMPLETE_EVENT); // register with the radlib message router if (radMsgRouterInit (WVIEW_RUN_DIR) == ERROR) { radMsgLog (PRI_HIGH, "radMsgRouterInit failed!"); statusUpdateMessage("radMsgRouterInit failed"); statusUpdate(STATUS_ERROR); radTimerDelete (wviewdWork.ifTimer); radTimerDelete (wviewdWork.syncTimer); radTimerDelete (wviewdWork.cdataTimer); radTimerDelete (wviewdWork.pushTimer); radTimerDelete (wviewdWork.archiveTimer); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // enable message reception from the radlib router for worker requests radMsgRouterMessageRegister (WVIEW_MSG_TYPE_REQUEST); // enable message reception from the radlib router for POLL msgs radMsgRouterMessageRegister (WVIEW_MSG_TYPE_POLL); // enable message reception from the radlib router for ALERT msgs radMsgRouterMessageRegister (WVIEW_MSG_TYPE_ALERT); // enable message reception from the radlib router for STATION_DATA msgs radMsgRouterMessageRegister (WVIEW_MSG_TYPE_STATION_DATA); // Initialize the HILOW database interface: // (this cannot occur before the MsgRouter is initialized) if (dbsqliteHiLowInit(TRUE) == ERROR) { radMsgLog (PRI_HIGH, "dbsqliteHiLowInit failed"); statusUpdateMessage("dbsqliteHiLowInit failed"); statusUpdate(STATUS_ERROR); stationSendShutdown(&wviewdWork); radMsgRouterExit (); radTimerDelete (wviewdWork.ifTimer); radTimerDelete (wviewdWork.syncTimer); radTimerDelete (wviewdWork.cdataTimer); radTimerDelete (wviewdWork.pushTimer); radTimerDelete (wviewdWork.archiveTimer); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // initialize the station abstraction radMsgLog (PRI_STATUS, "-- Station Init Start --"); if (stationInit (&wviewdWork, daemonArchiveIndication) == ERROR) { radMsgLog (PRI_HIGH, "stationInit failed!"); statusUpdateMessage("stationInit failed"); statusUpdate(STATUS_ERROR); stationSendShutdown(&wviewdWork); radMsgRouterExit (); radTimerDelete (wviewdWork.ifTimer); radTimerDelete (wviewdWork.syncTimer); radTimerDelete (wviewdWork.cdataTimer); radTimerDelete (wviewdWork.pushTimer); radTimerDelete (wviewdWork.archiveTimer); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // register the station interface if it is device-based: if (wviewdWork.medium.type == MEDIUM_TYPE_DEVICE) { if (radProcessIORegisterDescriptor (wviewdWork.medium.fd, stationDataCallback, NULL) == ERROR) { radMsgLog (PRI_HIGH, "IORegDescriptor failed"); statusUpdateMessage("IORegDescriptor failed"); statusUpdate(STATUS_ERROR); stationSendShutdown(&wviewdWork); radMsgRouterExit (); radTimerDelete (wviewdWork.ifTimer); radTimerDelete (wviewdWork.syncTimer); radTimerDelete (wviewdWork.cdataTimer); radTimerDelete (wviewdWork.pushTimer); radTimerDelete (wviewdWork.archiveTimer); stationExit (&wviewdWork); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } } // Send test email if it is enabled: if (wviewdWork.IsTestEmailEnabled) { radMsgLog(PRI_STATUS, "Sending test email..."); emailAlertSend(ALERT_TYPE_TEST); } statusUpdate(STATUS_RUNNING); statusUpdateMessage("Normal operation"); radMsgLog (PRI_STATUS, "running..."); while (!wviewdWork.exiting) { // wait on timers, events, file descriptors, msgs if (radProcessWait (0) == ERROR) { wviewdWork.exiting = TRUE; } } statusUpdateMessage("exiting normally"); radMsgLog (PRI_STATUS, "exiting normally..."); statusUpdate(STATUS_SHUTDOWN); computedDataExit (&wviewdWork); radMsgRouterExit (); radTimerDelete (wviewdWork.ifTimer); radTimerDelete (wviewdWork.syncTimer); radTimerDelete (wviewdWork.pushTimer); radTimerDelete (wviewdWork.cdataTimer); radTimerDelete (wviewdWork.archiveTimer); stationExit (&wviewdWork); dbsqliteHiLowExit(); dbsqliteArchiveExit(); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (0); }
// the main entry point for the wvpmond process int main (int argc, char *argv[]) { void (*alarmHandler)(int); int i, retVal, intValue, iValue; FILE *pidfile, *markerFile; struct stat fileStatus; char* subString; char markerPath[PMON_MAX_PATH], markerVal[32]; int runAsDaemon = TRUE; if (argc > 1) { if (!strcmp(argv[1], "-f")) { runAsDaemon = FALSE; } } memset (&procmonWork, 0, sizeof (procmonWork)); // initialize some system stuff first retVal = procmonSysInit (&procmonWork); if (retVal == ERROR) { radMsgLogInit (PROC_NAME_PMON, FALSE, TRUE); radMsgLog (PRI_CATASTROPHIC, "wvpmond init failed!\n"); radMsgLogExit (); exit (1); } else if (retVal == ERROR_ABORT) { exit (2); } // call the global radlib system init function if (radSystemInit (WVIEW_SYSTEM_ID) == ERROR) { radMsgLogInit (PROC_NAME_PMON, TRUE, TRUE); radMsgLog (PRI_CATASTROPHIC, "radSystemInit failed!"); radMsgLogExit (); exit (1); } // call the radlib process init function if (radProcessInit (PROC_NAME_PMON, procmonWork.fifoFile, PROC_NUM_TIMERS_PMON, runAsDaemon, // TRUE for daemon msgHandler, evtHandler, NULL) == ERROR) { printf ("\nradProcessInit failed: %s\n\n", PROC_NAME_PMON); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } procmonWork.myPid = getpid (); pidfile = fopen (procmonWork.pidFile, "w"); if (pidfile == NULL) { radMsgLog (PRI_CATASTROPHIC, "lock file create failed!\n"); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } fprintf (pidfile, "%d", getpid ()); fclose (pidfile); alarmHandler = radProcessSignalGetHandler (SIGALRM); radProcessSignalCatchAll (defaultSigHandler); radProcessSignalCatch (SIGALRM, alarmHandler); radProcessSignalRelease(SIGABRT); if (wvconfigInit(FALSE) == ERROR) { radMsgLog (PRI_CATASTROPHIC, "wvconfigInit failed!\n"); radMsgRouterExit (); procmonSysExit (&procmonWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // Is the procmon daemon enabled? iValue = wvconfigGetBooleanValue(configItem_ENABLE_PROCMON); if (iValue == ERROR || iValue == 0) { radMsgLog (PRI_CATASTROPHIC, "process monitor daemon is disabled - exiting..."); wvconfigExit (); radMsgRouterExit (); procmonSysExit (&procmonWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // Close here; we'll re-open after waiting for the wviewd daemon to be ready: wvconfigExit(); if (statusInit(procmonWork.statusFile, pmonStatusLabels) == ERROR) { radMsgLog (PRI_HIGH, "statusInit failed - exiting..."); wvconfigExit (); radMsgRouterExit (); procmonSysExit (&procmonWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } statusUpdate(STATUS_BOOTING); // register with the radlib message router if (radMsgRouterInit (WVIEW_RUN_DIR) == ERROR) { radMsgLog (PRI_HIGH, "radMsgRouterInit failed!"); procmonSysExit (&procmonWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // enable message reception from the radlib router for SHUTDOWN msgs radMsgRouterMessageRegister (WVIEW_MSG_TYPE_SHUTDOWN); // wait for the wview daemon to be ready if (waitForWviewDaemon () == ERROR) { radMsgLog (PRI_HIGH, "waitForWviewDaemon failed"); statusUpdate(STATUS_ERROR); radMsgRouterExit (); procmonSysExit (&procmonWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } procmonWork.pollTimer = radProcessTimerCreate (NULL, pollTimerHandler, NULL); if (procmonWork.pollTimer == NULL) { radMsgLog (PRI_HIGH, "radTimerCreate failed"); procmonSysExit (&procmonWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } procmonWork.tickTimer = radProcessTimerCreate (NULL, tickTimerHandler, NULL); if (procmonWork.tickTimer == NULL) { radMsgLog (PRI_HIGH, "radTimerCreate failed"); procmonSysExit (&procmonWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } if (wvconfigInit(FALSE) == ERROR) { radMsgLog (PRI_CATASTROPHIC, "wvconfigInit failed!\n"); statusUpdateMessage("wvconfigInit failed"); statusUpdate(STATUS_ERROR); radMsgRouterExit (); procmonSysExit (&procmonWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // Populate our process table: memset (procmonWork.process, 0, sizeof(PMON_PROCESS) * PMON_PROCESS_MAX); for (i = 0; i < PMON_PROCESS_MAX; i ++) { iValue = wvconfigGetINTValue(configIDs[i]); if (iValue < 0) { // we can't do without this! radMsgLog (PRI_CATASTROPHIC, "PMON: %s: failed!", configIDs[i]); statusUpdateMessage("wvconfigGetINTValue failed"); statusUpdate(STATUS_ERROR); wvconfigExit(); radMsgRouterExit (); procmonSysExit (&procmonWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { procmonWork.process[i].timeout = iValue; radMsgLog (PRI_STATUS, "PMON: %s: %d", procNames[i], procmonWork.process[i].timeout); } if (procmonWork.process[i].timeout <= 0) { radMsgLog (PRI_STATUS, "PMON: %s process monitoring is disabled", procNames[i]); procmonWork.process[i].ticks = -1; procmonWork.process[i].pid = -1; } else { // Populate the rest of the values: wvstrncpy (procmonWork.process[i].binFile, argv[0], PMON_MAX_PATH); subString = strstr (procmonWork.process[i].binFile, "wvpmond"); if (subString == NULL) { radMsgLog (PRI_CATASTROPHIC, "PMON: %s is invalid for bin path!", procmonWork.process[i].binFile); statusUpdateMessage("invalid for bin path"); statusUpdate(STATUS_ERROR); wvconfigExit(); radMsgRouterExit (); procmonSysExit (&procmonWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } if (! strcmp(procNames[i], "wviewd")) { // Get the process name from the marker file: sprintf(markerPath, "%s/wview-binary", WVIEW_CONFIG_DIR); if (stat (markerPath, &fileStatus) != 0) { radMsgLog (PRI_HIGH, "PMON: wview-binary file is missing - was 'make install' run?"); statusUpdateMessage("wview-binary file is missing"); statusUpdate(STATUS_ERROR); radMsgRouterExit (); procmonSysExit (&procmonWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } markerFile = fopen(markerPath, "r"); if (markerFile == NULL) { radMsgLog (PRI_HIGH, "PMON: failed to open wview-binary file - was 'make install' run?"); statusUpdateMessage("failed to open wview-binary file"); statusUpdate(STATUS_ERROR); radMsgRouterExit (); procmonSysExit (&procmonWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } if (fgets(markerVal, 32, markerFile) == NULL) { radMsgLog (PRI_HIGH, "PMON: failed to read wview-binary file - was 'make install' run?"); statusUpdateMessage("failed to read wview-binary file"); statusUpdate(STATUS_ERROR); fclose(markerFile); radMsgRouterExit (); procmonSysExit (&procmonWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // Strip off CR/LF (caused by hand-editing of file!): stripEOLValues(markerVal); sprintf(subString, "%s", markerVal); fclose(markerFile); } else { sprintf (subString, "%s", procNames[i]); } sprintf (procmonWork.process[i].pidFile, "%s/%s.pid", WVIEW_RUN_DIR, procNames[i]); if (stat (procmonWork.process[i].pidFile, &fileStatus) == -1) { // Process is not running, mark it invalid radMsgLog (PRI_STATUS, "PMON: pid file %s not present, disable monitoring...", procmonWork.process[i].pidFile); procmonWork.process[i].timeout = 0; procmonWork.process[i].ticks = -1; procmonWork.process[i].pid = -1; } else { // Get his pid from the pidfile procmonWork.process[i].pid = pmonGetProcessPid (procmonWork.process[i].pidFile); if (procmonWork.process[i].pid == ERROR) { radMsgLog (PRI_CATASTROPHIC, "PMON: failed to READ %s!", procmonWork.process[i].pidFile); statusUpdateMessage("failed to read pid file"); statusUpdate(STATUS_ERROR); wvconfigExit(); radMsgRouterExit (); procmonSysExit (&procmonWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } } // Setup the state machine procmonWork.process[i].stateMachine = radStatesInit (&procmonWork); radStatesAddHandler (procmonWork.process[i].stateMachine, PMON_STATE_IDLE, IdleStateHandler); radStatesAddHandler (procmonWork.process[i].stateMachine, PMON_STATE_WAIT_RESP, WaitRespStateHandler); radStatesAddHandler (procmonWork.process[i].stateMachine, PMON_STATE_WAIT_EXIT, WaitExitStateHandler); radStatesAddHandler (procmonWork.process[i].stateMachine, PMON_STATE_WAIT_START, WaitStartStateHandler); radStatesSetState (procmonWork.process[i].stateMachine, PMON_STATE_IDLE); } } wvconfigExit(); radMsgRouterMessageRegister (WVIEW_MSG_TYPE_POLL_RESPONSE); // Start the timers: radProcessTimerStart (procmonWork.pollTimer, PMON_POLL_INTERVAL); radProcessTimerStart (procmonWork.tickTimer, PMON_TICK_INTERVAL); // enter normal processing procmonWork.inMainLoop = TRUE; statusUpdate(STATUS_RUNNING); statusUpdateMessage("Normal operation"); radMsgLog (PRI_STATUS, "running..."); while (!procmonWork.exiting) { // wait on something interesting if (radProcessWait (0) == ERROR) { procmonWork.exiting = TRUE; } } statusUpdateMessage("exiting normally"); radMsgLog (PRI_STATUS, "exiting normally..."); statusUpdate(STATUS_SHUTDOWN); radMsgRouterExit (); radProcessTimerDelete (procmonWork.pollTimer); radProcessTimerDelete (procmonWork.tickTimer); procmonSysExit (&procmonWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (0); }
/* ... the main entry point for the ssh process */ int main (int argc, char *argv[]) { void (*alarmHandler)(int); STIM stim; int i; int seconds; time_t ntime; struct tm locTime; int offset, retVal; long msOffset; FILE *pidfile; int runAsDaemon = TRUE; if (argc > 1) { if (!strcmp(argv[1], "-f")) { runAsDaemon = FALSE; } } memset (&sshWork, 0, sizeof (sshWork)); /* ... initialize some system stuff first */ retVal = sshSysInit (&sshWork); if (retVal == ERROR) { radMsgLogInit (PROC_NAME_SSH, FALSE, TRUE); radMsgLog (PRI_CATASTROPHIC, "ssh init failed!"); radMsgLogExit (); exit (1); } else if (retVal == ERROR_ABORT) { exit (2); } /* ... call the global radlib system init function */ if (radSystemInit (WVIEW_SYSTEM_ID) == ERROR) { radMsgLogInit (PROC_NAME_SSH, TRUE, TRUE); radMsgLog (PRI_CATASTROPHIC, "radSystemInit failed!"); radMsgLogExit (); exit (1); } /* ... call the radlib process init function */ if (radProcessInit (PROC_NAME_SSH, sshWork.fifoFile, PROC_NUM_TIMERS_SSH, runAsDaemon, // TRUE for daemon msgHandler, evtHandler, NULL) == ERROR) { printf ("\nradProcessInit failed: %s\n\n", PROC_NAME_SSH); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } sshWork.myPid = getpid (); pidfile = fopen (sshWork.pidFile, "w"); if (pidfile == NULL) { radMsgLog (PRI_CATASTROPHIC, "lock file create failed!"); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } fprintf (pidfile, "%d", getpid ()); fclose (pidfile); alarmHandler = radProcessSignalGetHandler (SIGALRM); radProcessSignalCatchAll (SSHDefaultSigHandler); radProcessSignalCatch (SIGALRM, alarmHandler); radProcessSignalRelease(SIGABRT); sshWork.timer = radTimerCreate (NULL, timerHandler, NULL); if (sshWork.timer == NULL) { radMsgLog (PRI_HIGH, "radTimerCreate failed - exiting"); sshSysExit (&sshWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // ... initialize the ssh utilities retVal = sshUtilsInit (&sshWork.sshData); if (retVal != OK) { if (retVal == ERROR) { radMsgLog (PRI_HIGH, "sshUtilsInit failed - exiting"); } radTimerDelete (sshWork.timer); sshSysExit (&sshWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { sshWork.sshId = &sshWork.sshData; } if (statusInit(sshWork.statusFile, sshStatusLabels) == ERROR) { radMsgLog (PRI_HIGH, "statusInit failed - exiting..."); sshSysExit (&sshWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } statusUpdate(STATUS_BOOTING); statusUpdateStat(SSH_STATS_RULES_DEFINED, radListGetNumberOfNodes(&sshWork.sshData.rules)); // ... start THE timer ntime = time (NULL); localtime_r (&ntime, &locTime); seconds = locTime.tm_sec - 15; // start at 15 secs past /* ... start the ssh timer to go off 1 min past the next archive record */ offset = locTime.tm_min % 5; if (offset) offset = 6 - offset; else offset = 1; if (seconds < -60) { offset += 1; offset += 60; } radMsgLog (PRI_HIGH, "SSH: starting updates in %d mins %d secs", ((seconds > 0) ? ((offset > 0) ? offset-1 : offset) : offset), (seconds > 0) ? 60 - seconds : (-1) * seconds); msOffset = radTimeGetMSSinceEpoch () % 1000; msOffset -= 250; // land on 250 ms mark sshWork.msOffset = 0; radProcessTimerStart (sshWork.timer, ((((offset * 60) - seconds) * 1000)) - msOffset); statusUpdate(STATUS_RUNNING); statusUpdateMessage("Normal operation"); while (!sshWork.exiting) { /* ... wait on timers, events, file descriptors, msgs, everything! */ if (radProcessWait (0) == ERROR) { sshWork.exiting = TRUE; } } statusUpdateMessage("exiting normally"); radMsgLog (PRI_STATUS, "exiting normally..."); statusUpdate(STATUS_SHUTDOWN); if (sshWork.sshId != NULL) { sshUtilsExit (sshWork.sshId); } radTimerDelete (sshWork.timer); sshSysExit (&sshWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (0); }
/* ... the main entry point for the alarm process */ int main (int argc, char *argv[]) { void (*alarmHandler)(int); int retVal; FILE *pidfile; WVIEW_ALARM *alarm; int runAsDaemon = TRUE; if (argc > 1) { if (!strcmp(argv[1], "-f")) { runAsDaemon = FALSE; } } memset (&alarmsWork, 0, sizeof (alarmsWork)); radListReset (&alarmsWork.alarmList); radListReset (&alarmsWork.clientList); /* ... initialize some system stuff first */ retVal = alarmsSysInit (&alarmsWork); if (retVal == ERROR) { radMsgLogInit (PROC_NAME_ALARMS, FALSE, TRUE); radMsgLog (PRI_CATASTROPHIC, "wvalarmd sysinit failed!"); radMsgLogExit (); exit (1); } else if (retVal == ERROR_ABORT) { exit (2); } /* ... call the global radlib system init function */ if (radSystemInit (WVIEW_SYSTEM_ID) == ERROR) { radMsgLogInit (PROC_NAME_ALARMS, TRUE, TRUE); radMsgLog (PRI_CATASTROPHIC, "radSystemInit failed!"); radMsgLogExit (); exit (1); } /* ... call the radlib process init function */ if (radProcessInit (PROC_NAME_ALARMS, alarmsWork.fifoFile, PROC_NUM_TIMERS_ALARMS, runAsDaemon, // TRUE for daemon msgHandler, evtHandler, NULL) == ERROR) { printf ("\nradProcessInit failed: %s\n\n", PROC_NAME_ALARMS); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } alarmsWork.myPid = getpid (); pidfile = fopen (alarmsWork.pidFile, "w"); if (pidfile == NULL) { radMsgLog (PRI_CATASTROPHIC, "lock file create failed!"); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } fprintf (pidfile, "%d", getpid ()); fclose (pidfile); alarmHandler = radProcessSignalGetHandler (SIGALRM); radProcessSignalCatchAll (defaultSigHandler); radProcessSignalCatch (SIGALRM, alarmHandler); radProcessSignalRelease(SIGABRT); // grab all of our alarm definitions from the config database retVal = readAlarmsConfig (); if (retVal == ERROR_ABORT) { radMsgLog (PRI_HIGH, "ALARM daemon not enabled - exiting..."); alarmsSysExit (&alarmsWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (0); } else if (retVal < 0) { radMsgLog (PRI_HIGH, "readAlarmsConfig failed - " "is there a problem with the wview config database?"); alarmsSysExit (&alarmsWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { radMsgLog (PRI_STATUS, "alarms: added %d alarm definitions", retVal); } if (statusInit(alarmsWork.statusFile, alarmsStatusLabels) == ERROR) { radMsgLog (PRI_HIGH, "ALARM status init failed - exiting..."); alarmsSysExit (&alarmsWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } statusUpdate(STATUS_BOOTING); statusUpdateStat(ALARM_STATS_ALARMS, retVal); // wait a bit here before continuing radUtilsSleep (500); // register with the radlib message router if (radMsgRouterInit (WVIEW_RUN_DIR) == ERROR) { statusUpdateMessage("radMsgRouterInit failed!"); radMsgLog (PRI_HIGH, "radMsgRouterInit failed!"); statusUpdate(STATUS_ERROR); alarmsSysExit (&alarmsWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // enable message reception from the radlib router for SHUTDOWN msgs radMsgRouterMessageRegister (WVIEW_MSG_TYPE_SHUTDOWN); // wait for the wview daemon to be ready if (waitForWviewDaemon () == ERROR) { radMsgLog (PRI_HIGH, "waitForWviewDaemon failed"); statusUpdate(STATUS_ERROR); radMsgRouterExit (); alarmsSysExit (&alarmsWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // finally, initialize our data feed socket alarmsWork.dataFeedServer = radSocketServerCreate(WV_DATAFEED_PORT); if (alarmsWork.dataFeedServer == NULL) { statusUpdateMessage("radSocketServerCreate failed"); radMsgLog (PRI_HIGH, "radSocketServerCreate failed..."); statusUpdate(STATUS_ERROR); radMsgRouterExit (); alarmsSysExit (&alarmsWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // add it to our descriptors of interest if (radProcessIORegisterDescriptor(radSocketGetDescriptor(alarmsWork.dataFeedServer), dataFeedAccept, NULL) == ERROR) { statusUpdateMessage("radProcessIORegisterDescriptor server failed"); radMsgLog (PRI_HIGH, "radProcessIORegisterDescriptor failed..."); statusUpdate(STATUS_ERROR); radSocketDestroy (alarmsWork.dataFeedServer); radMsgRouterExit (); alarmsSysExit (&alarmsWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // enable message reception from the radlib router for loop data radMsgRouterMessageRegister (WVIEW_MSG_TYPE_LOOP_DATA_SVC); // enable message reception from the radlib router for archive data radMsgRouterMessageRegister (WVIEW_MSG_TYPE_ARCHIVE_DATA); // enable message reception from the radlib router for POLL msgs radMsgRouterMessageRegister (WVIEW_MSG_TYPE_POLL); // enter normal processing alarmsWork.inMainLoop = TRUE; statusUpdate(STATUS_RUNNING); statusUpdateMessage("Normal operation"); radMsgLog (PRI_STATUS, "running..."); // Do we need to trigger a test alarm? if (alarmsWork.doTest) { if (1 <= alarmsWork.doTestNumber && alarmsWork.doTestNumber <= ALARMS_MAX) { // Generate the bad boy: retVal = 1; for (alarm = (WVIEW_ALARM *) radListGetFirst (&alarmsWork.alarmList); retVal <= ALARMS_MAX && alarm != NULL; alarm = (WVIEW_ALARM *) radListGetNext (&alarmsWork.alarmList, (NODE_PTR)alarm)) { if (retVal == alarmsWork.doTestNumber) { // This is the one to test: alarm->triggerValue = -1; // run user script here if (executeScript(alarm) != 0) { radMsgLog (PRI_MEDIUM, "Test Alarm %d: script %s failed", retVal, alarm->scriptToRun); } else { radMsgLog (PRI_MEDIUM, "Test Alarm %d: script %s executed", retVal, alarm->scriptToRun); } retVal = ALARMS_MAX; } retVal ++; } } else { radMsgLog (PRI_MEDIUM, "Test Alarm: bad alarm index %d given!", alarmsWork.doTestNumber); } } while (!alarmsWork.exiting) { // wait on something interesting if (radProcessWait (0) == ERROR) { alarmsWork.exiting = TRUE; } } statusUpdateMessage("exiting normally"); radMsgLog (PRI_STATUS, "exiting normally..."); statusUpdate(STATUS_SHUTDOWN); radSocketDestroy (alarmsWork.dataFeedServer); radMsgRouterExit (); alarmsSysExit (&alarmsWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (0); }
// Main routine to initialize esp-link. void user_init(void) { // get the flash config so we know how to init things // configWipe(); // uncomment to reset the config for testing purposes bool restoreOk = configRestore(); // init gpio pin registers gpio_init(); gpio_output_set(0, 0, 0, (1<<15)); // some people tie it to GND, gotta ensure it's disabled // init UART uart_init(flashConfig.baud_rate, 115200); logInit(); // must come after init of uart // say hello (leave some time to cause break in TX after boot loader's msg os_delay_us(10000L); os_printf("\n\n** %s\n", esp_link_version); os_printf("Flash config restore %s\n", restoreOk ? "ok" : "*FAILED*"); #if defined(STA_SSID) && defined(STA_PASS) int x = wifi_get_opmode() & 0x3; if (x == 2) { // we only force the STA settings when a full flash of the module has been made, which // resets the wifi settings not to have anything configured struct station_config stconf; wifi_station_get_config(&stconf); if (os_strlen((char*)stconf.ssid) == 0 && os_strlen((char*)stconf.password) == 0) { os_strncpy((char*)stconf.ssid, VERS_STR(STA_SSID), 32); os_strncpy((char*)stconf.password, VERS_STR(STA_PASS), 64); #ifdef CGIWIFI_DBG os_printf("Wifi pre-config trying to connect to AP %s pw %s\n", (char*)stconf.ssid, (char*)stconf.password); #endif wifi_set_opmode(3); // sta+ap, will switch to sta-only 15 secs after connecting stconf.bssid_set = 0; wifi_station_set_config(&stconf); } } #endif // Status LEDs statusInit(); serledInit(); // Wifi wifiInit(); // init the flash filesystem with the html stuff espFsInit(&_binary_espfs_img_start); //EspFsInitResult res = espFsInit(&_binary_espfs_img_start); //os_printf("espFsInit %s\n", res?"ERR":"ok"); // mount the http handlers httpdInit(builtInUrls, 80); // init the wifi-serial transparent bridge (port 23) serbridgeInit(23, 2323); uart_add_recv_cb(&serbridgeUartCb); #ifdef SHOW_HEAP_USE os_timer_disarm(&prHeapTimer); os_timer_setfn(&prHeapTimer, prHeapTimerCb, NULL); os_timer_arm(&prHeapTimer, 10000, 1); #endif struct rst_info *rst_info = system_get_rst_info(); NOTICE("Reset cause: %d=%s", rst_info->reason, rst_codes[rst_info->reason]); NOTICE("exccause=%d epc1=0x%x epc2=0x%x epc3=0x%x excvaddr=0x%x depc=0x%x", rst_info->exccause, rst_info->epc1, rst_info->epc2, rst_info->epc3, rst_info->excvaddr, rst_info->depc); uint32_t fid = spi_flash_get_id(); NOTICE("Flash map %s, manuf 0x%02lX chip 0x%04lX", flash_maps[system_get_flash_size_map()], fid & 0xff, (fid&0xff00)|((fid>>16)&0xff)); NOTICE("** esp-link ready"); cgiServicesSNTPInit(); #ifdef MQTT NOTICE("initializing MQTT"); mqtt_client_init(); #endif NOTICE("initializing user application"); app_init(); NOTICE("waiting for work to do..."); }