char *sensorGetHighDate (WV_SENSOR *sensor, char *store, char *dateFormat) { struct tm locTime; if (sensor->time_high == (time_t)0) { sprintf (store, "----------"); } else { if (sensor->debug) { radMsgLog(PRI_MEDIUM, "SENSOR HIGHDATE DBG: " "low: %.2f, time_low: %u, high: %.2f, time_high: %u," "samples: %d", sensor->low, (unsigned int)sensor->time_low, sensor->high, (unsigned int)sensor->time_high, sensor->samples); } localtime_r(&sensor->time_high, &locTime); strftime(store, WV_MAX_DATE_LENGTH-1, dateFormat, &locTime); if (sensor->debug) { radMsgLog(PRI_MEDIUM, "SENSOR HIGHDATE RESULT DBG: %s", store); } } return store; }
// Expects the medium to already be open: static int writeDataRefresh (WVIEWD_WORK *work) { uint8_t rqstBuffer[8], readBuffer[8]; int retVal; rqstBuffer[0] = 0xA2; // One byte write command rqstBuffer[1] = 0; rqstBuffer[2] = 0x1A; rqstBuffer[3] = 0x20; rqstBuffer[4] = 0xA2; rqstBuffer[5] = 0xAA; rqstBuffer[6] = 0; rqstBuffer[7] = 0x20; retVal = (*(work->medium.usbhidWrite))(&work->medium, rqstBuffer, 8); if (retVal != 8) { radMsgLog (PRI_HIGH, "WH1080: write data ACK failed!"); return ERROR; } // Read 8-byte ACK: retVal = (*(work->medium.usbhidRead))(&work->medium, readBuffer, 8, 1000); if (retVal != 8) { radMsgLog (PRI_HIGH, "WH1080: read data ACK failed!"); return ERROR; } return OK; }
// system initialization static int procmonSysInit (WVIEW_PMON_WORK *work) { char devPath[256], temp[64]; struct stat fileData; // check for our daemon's pid file, don't run if it isn't there sprintf (devPath, "%s/%s", WVIEW_RUN_DIR, WVD_LOCK_FILE_NAME); if (stat (devPath, &fileData) != 0) { radMsgLogInit (PROC_NAME_PMON, TRUE, TRUE); radMsgLog (PRI_CATASTROPHIC, "wviewd process not running - aborting!"); radMsgLogExit (); return ERROR; } sprintf (work->pidFile, "%s/%s", WVIEW_RUN_DIR, PMON_LOCK_FILE_NAME); sprintf (work->fifoFile, "%s/dev/%s", WVIEW_RUN_DIR, PROC_NAME_PMON); sprintf (work->statusFile, "%s/%s", WVIEW_STATUS_DIRECTORY, PMON_STATUS_FILE_NAME); sprintf (work->daemonQname, "%s/dev/%s", WVIEW_RUN_DIR, PROC_NAME_DAEMON); sprintf (work->wviewdir, "%s", WVIEW_RUN_DIR); // check for our pid file, don't run if it IS there if (stat (work->pidFile, &fileData) == 0) { radMsgLogInit (PROC_NAME_PMON, TRUE, TRUE); radMsgLog (PRI_CATASTROPHIC, "lock file %s exists, older copy may be running - aborting!", work->pidFile); radMsgLogExit (); return ERROR; } return OK; }
// station-supplied function to retrieve positional info (lat, long, elev) - // should populate 'work' fields: latitude, longitude, elevation // -- Synchronous -- // // - If station does not store these parameters, they can be retrieved from the // wview.conf file (see daemon.c for example conf file use) - user must choose // station type "Generic" when running the wviewconfig script // // Returns: OK or ERROR // int stationGetPosition (WVIEWD_WORK *work) { // just set the values from our internal store - we retrieved them in // stationInit work->elevation = (short)ws2300WorkData.elevation; if (ws2300WorkData.latitude >= 0) work->latitude = (short)((ws2300WorkData.latitude*10)+0.5); else work->latitude = (short)((ws2300WorkData.latitude*10)-0.5); if (ws2300WorkData.longitude >= 0) work->longitude = (short)((ws2300WorkData.longitude*10)+0.5); else work->longitude = (short)((ws2300WorkData.longitude*10)-0.5); radMsgLog (PRI_STATUS, "station location: elevation: %d feet", work->elevation); radMsgLog (PRI_STATUS, "station location: latitude: %3.1f %c longitude: %3.1f %c", (float)abs(work->latitude)/10.0, ((work->latitude < 0) ? 'S' : 'N'), (float)abs(work->longitude)/10.0, ((work->longitude < 0) ? 'W' : 'E')); return OK; }
char *sensorGetHighTime (WV_SENSOR *sensor, char *store) { if (sensor->time_high == (time_t)0) { sprintf (store, "-----"); } else { if (sensor->debug) { radMsgLog(PRI_MEDIUM, "SENSOR HIGHTIME DBG: " "low: %.2f, time_low: %u, high: %.2f, time_high: %u," "samples: %d", sensor->low, (unsigned int)sensor->time_low, sensor->high, (unsigned int)sensor->time_high, sensor->samples); } sprintf (store, "%2.2d:%2.2d", wvutilsGetHour(sensor->time_high), wvutilsGetMin(sensor->time_high)); if (sensor->debug) { radMsgLog(PRI_MEDIUM, "SENSOR HIGHTIME RESULT DBG: %s", store); } } return store; }
// Expects the medium to already be open: static int readFixedBlock(WVIEWD_WORK *work, uint8_t* block) { // Read fixed block: if (readBlock(work, 0, block) == ERROR) { radMsgLog (PRI_HIGH, "WH1080: readFixedBlock readBlock failed"); return ERROR; } // Check for valid magic numbers: // This is hardly an exhaustive list and I can find no definitive // documentation that lists all possible values; further, I suspect it is // more of a header than a magic number... if ((block[0] == 0x55) || (block[0] == 0xFF) || (block[0] == 0x01) || ((block[0] == 0x00) && (block[1] == 0x1E)) || ((block[0] == 0x00) && (block[1] == 0x01))) { return OK; } else { radMsgLog (PRI_HIGH, "WH1080: readFixedBlock bad magic number %2.2X %2.2X", (int)block[0], (int)block[1]); radMsgLog(PRI_HIGH, "WH1080: You may want to clear the memory on the station " "console to remove any invalid records or data..."); return ERROR_ABORT; } }
static void pushLoopToClients(LOOP_PKT* loopData) { WVIEW_ALARM_CLIENT *client, *oldClient; LOOP_PKT networkLoop; datafeedConvertLOOP_HTON(&networkLoop, loopData); // Push to each socket client: for (client = (WVIEW_ALARM_CLIENT *) radListGetFirst (&alarmsWork.clientList); client != NULL; client = (WVIEW_ALARM_CLIENT *) radListGetNext (&alarmsWork.clientList, (NODE_PTR)client)) { // write the frame start so clients may sync to the beginning of each // data update if (radSocketWriteExact (client->client, (void *)DF_LOOP_START_FRAME, DF_START_FRAME_LENGTH) != DF_START_FRAME_LENGTH) { // write error, bail on this guy radMsgLog (PRI_HIGH, "LOOP: write error to client %s:%d - closing socket...", radSocketGetHost (client->client), radSocketGetPort (client->client)); statusDecrementStat(ALARM_STATS_CLIENTS); radProcessIODeRegisterDescriptorByFd(radSocketGetDescriptor(client->client)); radSocketDestroy (client->client); oldClient = client; client = (WVIEW_ALARM_CLIENT *) radListGetPrevious (&alarmsWork.clientList, (NODE_PTR)client); radListRemove (&alarmsWork.clientList, (NODE_PTR)oldClient); free (oldClient); continue; } // write out the loop data in network byte order: if (radSocketWriteExact(client->client, &networkLoop, sizeof(networkLoop)) != sizeof(networkLoop)) { // write error, bail on this guy radMsgLog (PRI_HIGH, "LOOP: write error to client %s:%d - closing socket...", radSocketGetHost (client->client), radSocketGetPort (client->client)); statusDecrementStat(ALARM_STATS_CLIENTS); radProcessIODeRegisterDescriptorByFd(radSocketGetDescriptor(client->client)); radSocketDestroy (client->client); oldClient = client; client = (WVIEW_ALARM_CLIENT *) radListGetPrevious (&alarmsWork.clientList, (NODE_PTR)client); radListRemove (&alarmsWork.clientList, (NODE_PTR)oldClient); free (oldClient); continue; } statusIncrementStat(ALARM_STATS_PKTS_SENT); } return; }
// Query for a parameter value - it is converted to the proper format later: static int queryParmValue (const char* configItem, char* valueStore) { char query[DB_SQLITE_QUERY_LENGTH_MAX]; SQLITE_RESULT_SET_ID result; SQLITE_ROW_ID rowDescr; SQLITE_FIELD_ID field; if (sqliteID == NULL) { radMsgLog (PRI_HIGH, "queryParmValue: sqliteID is NULL!"); return ERROR; } sprintf (query, "SELECT value FROM config WHERE name = '%s'", configItem); if (radsqliteQuery(sqliteID, query, TRUE) == ERROR) { radMsgLog (PRI_MEDIUM, "queryParmValue: radsqliteQuery %s failed!", configItem); return ERROR; } result = radsqliteGetResults (sqliteID); if (result == NULL) { radMsgLog (PRI_MEDIUM, "queryParmValue: radsqliteGetResults failed!"); return ERROR; } // We have a result, return it to the caller: rowDescr = radsqliteResultsGetFirst (result); if (rowDescr == NULL) { radMsgLog (PRI_MEDIUM, "queryParmValue: radsqliteResultsGetFirst failed!"); radsqliteReleaseResults (sqliteID, result); return ERROR; } field = radsqliteFieldGet (rowDescr, configCOLUMN_VALUE); if (field == NULL) { radMsgLog (PRI_MEDIUM, "queryParmValue: radsqliteFieldGet failed!"); radsqliteReleaseResults (sqliteID, result); return ERROR; } memcpy (valueStore, radsqliteFieldGetCharValue(field), radsqliteFieldGetCharLength(field)); valueStore[radsqliteFieldGetCharLength(field)] = 0; // Clean up: radsqliteReleaseResults (sqliteID, result); return OK; }
static void defaultSigHandler (int signum) { int retVal; switch (signum) { case SIGHUP: // user wants us to change the verbosity setting retVal = wvutilsToggleVerbosity (); radMsgLog (PRI_STATUS, "wvcwopd: SIGHUP - toggling log verbosity %s", ((retVal == 0) ? "OFF" : "ON")); radProcessSignalCatch(signum, defaultSigHandler); return; case SIGPIPE: // we have a far end socket disconnection, we'll handle it in the // "read/write" code radProcessSignalCatch(signum, defaultSigHandler); break; case SIGILL: case SIGBUS: case SIGFPE: case SIGSEGV: case SIGXFSZ: case SIGSYS: // unrecoverable radProcessSignalCatch- we must exit right now! radMsgLog (PRI_CATASTROPHIC, "wvcwopd: recv unrecoverable signal %d: aborting!", signum); abort (); case SIGCHLD: wvutilsWaitForChildren(); radProcessSignalCatch(signum, defaultSigHandler); return; default: if (cwopWork.exiting) { radProcessSignalCatch(signum, defaultSigHandler); return; } // Exit here in case the socket transaction is hung statusUpdateMessage("exiting normally"); statusUpdate(STATUS_SHUTDOWN); radMsgLog (PRI_HIGH, "wvcwopd: recv sig %d: exiting now!", signum); radMsgRouterExit (); cwopSysExit (&cwopWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (0); } return; }
void SSHDefaultSigHandler (int signum) { int retVal; switch (signum) { case SIGHUP: // user wants us to change the verbosity setting retVal = wvutilsToggleVerbosity (); radMsgLog (PRI_STATUS, "wviewsshd: SIGHUP - toggling log verbosity %s", ((retVal == 0) ? "OFF" : "ON")); radProcessSignalCatch(signum, SSHDefaultSigHandler); return; case SIGBUS: case SIGFPE: case SIGSEGV: case SIGXFSZ: case SIGSYS: // unrecoverable radProcessSignalCatch- we must exit right now! radMsgLog (PRI_CATASTROPHIC, "wviewsshd: recv unrecoverable signal %d: aborting!", signum); if (!sshWork.exiting) { radTimerDelete (sshWork.timer); sshSysExit (&sshWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); } abort (); case SIGCHLD: // it is normal behavior to have children finishing up wvutilsWaitForChildren(); radProcessSignalCatch(signum, SSHDefaultSigHandler); break; default: // we can allow the process to exit normally... if (sshWork.exiting) { radProcessSignalCatch(signum, SSHDefaultSigHandler); return; } radMsgLog (PRI_HIGH, "wviewsshd: recv signal %d: exiting!", signum); sshWork.exiting = TRUE; radProcessSetExitFlag (); radProcessSignalCatch(signum, SSHDefaultSigHandler); break; } return; }
/* ... system initialization */ static int daemonSysInit (WVIEWD_WORK *work) { char temp[256]; char *installPath; struct stat fileData; FILE *pidfile; /* ... create our run directory if it is not there */ sprintf (temp, "%s", WVIEW_RUN_DIR); if (stat (temp, &fileData) != 0) { if (mkdir (temp, 0755) != 0) { radMsgLogInit (PROC_NAME_DAEMON, TRUE, TRUE); radMsgLog (PRI_CATASTROPHIC, "Cannot create run directory: %s - aborting!", temp); radMsgLogExit (); return -1; } } /* ... create our device directory if it is not there */ sprintf (temp, "%s/dev", WVIEW_RUN_DIR); if (stat (temp, &fileData) != 0) { if (mkdir (temp, 0755) != 0) { radMsgLogInit (PROC_NAME_DAEMON, TRUE, TRUE); radMsgLog (PRI_CATASTROPHIC, "Cannot create device directory: %s - aborting!", temp); radMsgLogExit (); return -1; } } sprintf (work->pidFile, "%s/%s", WVIEW_RUN_DIR, WVD_LOCK_FILE_NAME); sprintf (work->fifoFile, "%s/dev/%s", WVIEW_RUN_DIR, PROC_NAME_DAEMON); sprintf (work->statusFile, "%s/%s", WVIEW_STATUS_DIRECTORY, WVIEW_STATUS_FILE_NAME); /* ... check for our pid file, don't run if it is there */ if (stat (work->pidFile, &fileData) == 0) { radMsgLogInit (PROC_NAME_DAEMON, TRUE, TRUE); radMsgLog (PRI_CATASTROPHIC, "lock file %s exists, older copy may be running - aborting!", work->pidFile); radMsgLogExit (); return -1; } return 0; }
static void defaultSigHandler (int signum) { int retVal; switch (signum) { case SIGHUP: // user wants us to change the verbosity setting retVal = wvutilsToggleVerbosity (); radMsgLog (PRI_STATUS, "wviewd: SIGHUP - toggling log verbosity %s", ((retVal == 0) ? "OFF" : "ON")); radProcessSignalCatch(signum, defaultSigHandler); return; case SIGPIPE: // we have a far end socket disconnection, we'll handle it in the // "read/write" code radProcessSignalCatch(signum, defaultSigHandler); break; case SIGBUS: case SIGFPE: case SIGSEGV: case SIGXFSZ: case SIGSYS: // unrecoverable radProcessSignalCatch- we must exit right now! radMsgLog (PRI_CATASTROPHIC, "wviewd: recv sig %d: shutting down!", signum); abort (); case SIGCHLD: wvutilsWaitForChildren(); radProcessSignalCatch(signum, defaultSigHandler); return; default: // we can allow the process to exit normally... if (wviewdWork.exiting) { radProcessSignalCatch(signum, defaultSigHandler); return; } radMsgLog (PRI_HIGH, "wviewd: recv sig %d: exiting!", signum); wviewdWork.exiting = TRUE; radProcessSetExitFlag (); radProcessSignalCatch(signum, defaultSigHandler); break; } return; }
static void ClientDataRX (int fd, void *userData) { RADSOCK_ID client = (RADSOCK_ID)userData; int retVal; ULONG dateTime; retVal = datafeedSyncStartOfFrame(client); switch (retVal) { case ERROR: /* problems! - bail out */ statusUpdateMessage("ClientDataRX: socket error during sync - disconnecting"); radMsgLog (PRI_HIGH, "ClientDataRX: socket error during sync - disconnecting"); RemoveClient(client); break; case ERROR_ABORT: // This guy has bailed out: statusUpdateMessage("ClientDataRX: socket far-end closed"); radMsgLog (PRI_MEDIUM, "ClientDataRX: socket far-end closed"); RemoveClient(client); break; case FALSE: radMsgLog (PRI_STATUS, "ClientDataRX: RX sync failure - ignoring"); break; case DF_RQST_ARCHIVE_PKT_TYPE: // OK, read the unix time sent to retrieve the record: if (radSocketReadExact(client, (void *)&dateTime, sizeof(dateTime)) != sizeof (dateTime)) { statusUpdateMessage("ClientDataRX: socket read error - disconnecting"); radMsgLog (PRI_HIGH, "ClientDataRX: socket read error - disconnecting"); RemoveClient(client); break; } // Convert from network byte order: dateTime = ntohl(dateTime); // Now we have the date and time, get busy: SendNextArchiveRecord(client, dateTime); break; } return; }
static void dataFeedAccept (int fd, void *userData) { RADSOCK_ID newConnection; WVIEW_ALARM_CLIENT *client; newConnection = radSocketServerAcceptConnection(alarmsWork.dataFeedServer); if (newConnection == NULL) { statusUpdateMessage("dataFeed: accept connection failed!"); radMsgLog (PRI_MEDIUM, "dataFeed: accept connection failed!"); return; } // stick him on the data feed client list client = (WVIEW_ALARM_CLIENT *) malloc(sizeof(*client)); if (client == NULL) { radMsgLog (PRI_MEDIUM, "dataFeedAccept: malloc failed!"); radSocketDestroy(newConnection); return; } memset(client, 0, sizeof (*client)); client->client = newConnection; radSocketSetBlocking(client->client, TRUE); // add it to our descriptors of interest: if (radProcessIORegisterDescriptor(radSocketGetDescriptor(client->client), ClientDataRX, (void*)client->client) == ERROR) { statusUpdateMessage("dataFeedAccept: register descriptor failed!"); radMsgLog (PRI_MEDIUM, "dataFeedAccept: register descriptor failed!"); radSocketDestroy(client->client); return; } radListAddToEnd(&alarmsWork.clientList, (NODE_PTR)client); statusIncrementStat(ALARM_STATS_CLIENTS); radMsgLog (PRI_STATUS, "dataFeed: client %s:%d accepted...", radSocketGetHost (client->client), radSocketGetPort (client->client)); return; }
/* ... sets both value AND length */ int raddatabaseFieldSetCharValue ( FIELD_ID id, const char *value, int valueLength ) { char *temp; if (id->cvalLength < valueLength) { temp = (char *) malloc (valueLength+1); if (temp == NULL) { radMsgLog(PRI_MEDIUM, "raddatabaseFieldSetCharValue: malloc failed!"); return ERROR; } free (id->cvalue); id->cvalue = temp; } strncpy (id->cvalue, value, valueLength+1); id->cvalLength = valueLength; id->type &= ~FIELD_VALUE_IS_NULL; raddatabaseFieldSetTypeChar (id); return OK; }
int htmlIdleState (int state, void *stimulus, void *data) { STIM *stim = (STIM *)stimulus; HTML_WORK *work = (HTML_WORK *)data; uint16_t year, month, day, hour, minute, second; WVIEW_MSG_REQUEST msg; switch (stim->type) { case STIM_DUMMY: // this one starts this state machine - send the archive request msg.requestType = WVIEW_RQST_TYPE_STATION_INFO; if (radMsgRouterMessageSend (WVIEW_MSG_TYPE_REQUEST, &msg, sizeof(msg)) == ERROR) { radMsgLog (PRI_HIGH, "htmlIdleState: radMsgRouterMessageSend failed!"); statusUpdateMessage("radMsgRouterMessageSend failed!"); statusUpdate(STATUS_ERROR); return HTML_STATE_ERROR; } // initialize the DST state change detector here wvutilsDetectDSTInit (); statusUpdate(STATUS_WAITING_FOR_WVIEW); return HTML_STATE_STATION_INFO; } return state; }
// compute HILOW values for the current month: // Returns: 0 if OK or ERROR if an error occurs static int computeDataMonth (WVIEWD_WORK *work, time_t lastTime) { SENSOR_STORE *store = &work->sensors; int retVal; time_t timenow = time(NULL); struct tm bkntimenow; // do this so we pick up the proper hour/day when mins < archiveInterval timenow -= (work->archiveInterval * 60); localtime_r (&timenow, &bkntimenow); // process the month retVal = computeDataForMonth (work, bkntimenow.tm_mon + 1, bkntimenow.tm_year + 1900, STF_MONTH, FALSE, lastTime); if (retVal == ERROR || retVal == 0) { return ERROR; } radMsgLog(PRI_STATUS, "computeDataMonth: %4.4d%2.2d", bkntimenow.tm_year + 1900, bkntimenow.tm_mon + 1); return OK; }
/* ... returns OK or ERROR */ int raddatabaseRowDescriptionAddField ( ROW_ID id, const char *name, UINT type, int maxLength ) { FIELD_ID field; field = (FIELD_ID) malloc (sizeof (*field)); if (field == NULL) { radMsgLog(PRI_MEDIUM, "raddatabaseRowDescriptionCreate: malloc failed!"); return ERROR; } memset (field, 0, sizeof (*field)); strncpy (field->name, name, DB_FIELD_NAME_MAX-1); field->type = type; field->cvalLength = maxLength; radListAddToEnd (&id->fields, (NODE_PTR)field); return OK; }
static void timerHandler (void *parm) { time_t ntime; struct tm locTime; radProcessTimerStart (cwopWork.timer, CWOP_MINUTE_INTERVAL); ntime = time (NULL); localtime_r (&ntime, &locTime); if ((locTime.tm_min % cwopWork.reportInterval) == cwopWork.callSignOffset) { // Time to send a packet if we have any new data: if (cwopWork.rxArchive) { processCWOP (); cwopWork.rxArchive = FALSE; } else { if (cwopWork.rxFirstArchive) { statusUpdateMessage("no new archive data received since last CWOP submission"); radMsgLog (PRI_MEDIUM, "wvcwopd: no new archive data received since last CWOP submission:"); } } } return; }
int dbsqliteHistoryGetDay (time_t date, HISTORY_DATA* store) { SQLITE_DATABASE_ID historyDB = NULL; historyDB = radsqliteOpen(getHistoryDBFilename()); if (historyDB == NULL) { radMsgLog (PRI_HIGH, "dbsqliteHistoryInsertDay: failed to open %s!", getHistoryDBFilename()); return ERROR; } // First make sure the day history table exists: if (! radsqliteTableIfExists(historyDB, WVIEW_DAY_HISTORY_TABLE)) { radsqliteClose(historyDB); return ERROR; } // Try to get the day requested: if (getHistoryRecord(historyDB, date, store) == ERROR) { radsqliteClose(historyDB); return ERROR; } radsqliteClose(historyDB); return OK; }
// PRAGMA statement to modify the operation of the SQLite library int dbsqliteHistoryPragmaSet(char *pragma, char *setting) { char query[DB_SQLITE_QUERY_LENGTH_MAX]; SQLITE_DATABASE_ID historyDB = NULL; historyDB = radsqliteOpen(getHistoryDBFilename()); if (historyDB == NULL) { radMsgLog (PRI_HIGH, "dbsqliteHistoryPragmaSet: failed to open %s!", getHistoryDBFilename()); return ERROR; } // Check SQLite version if a journalling pragma: if (!strcmp(pragma, "journal_mode")) { if (SQLITE_VERSION_NUMBER < 3005009) { // Not supported: radsqliteClose(historyDB); return OK; } } sprintf (query, "PRAGMA %s = %s", pragma, setting); // Execute the query: if (radsqliteQuery(historyDB, query, FALSE) == ERROR) { return ERROR; } radsqliteClose(historyDB); return OK; }
static void archiveTimerHandler (void *parm) { ARCHIVE_PKT* newRec; time_t ntime; int intSECS; // get the current time ntime = time (NULL); // check to see if system time has changed if (ntime < (wviewdWork.nextArchiveTime - 4)) { // time was set back since our last timer start - restart the timer radMsgLog (PRI_MEDIUM, "archiveTimerHandler: system time has skewed, adjusting..."); stationStartArchiveTimerUniform (&wviewdWork); return; } if (wviewdWork.stationGeneratesArchives) { // tell the station to generate an archive record // (he will indicate it back to us) stationGetArchive (&wviewdWork); } else { // generate it on our own newRec = computedDataGenerateArchive(&wviewdWork); if (newRec != NULL) { daemonStoreArchiveRecord(newRec); // Push to internal clients: stationPushArchiveToClients(&wviewdWork, newRec); } else { radMsgLog (PRI_MEDIUM, "STATION: no new archive record generated " "probably caused by not receiving any LOOP data"); emailAlertSend(ALERT_TYPE_STATION_ARCHIVE); } } // restart the timer stationStartArchiveTimerUniform (&wviewdWork); return; }
int radTimerListDebug (void) { register TIMER_ID next; radMsgLog(PRI_HIGH, "################## radTimerListDebug START ##################"); for (next = (TIMER_ID) radListGetFirst (&timerList->pendingList); next != NULL; next = (TIMER_ID) radListGetNext (&timerList->pendingList, (NODE_PTR)next)) { if (next->routine) { radMsgLog(PRI_HIGH, "Timer-%8.8X: delta: %u, pending: %d, routine: %8.8X", (ULONG)next, next->deltaTime, next->pending, (ULONG)next->routine); } } radMsgLog(PRI_HIGH, "################## radTimerListDebug END ##################"); }
static int serialInit (WVIEW_MEDIUM *med, char *deviceName) { MEDIUM_SERIAL *serialWork = (MEDIUM_SERIAL *)med->workData; // ... open our serial channel med->fd = open (deviceName, serialWork->openFlags); if (med->fd == -1) { radMsgLog (PRI_CATASTROPHIC, "Serial device %s failed to open: %s", deviceName, strerror(errno)); return ERROR; } #ifdef HAVE_FLOCK if (flock (med->fd, LOCK_EX) < 0) #else struct flock lock = {0}; lock.l_type = F_WRLCK; if (fcntl(med->fd, F_SETLKW, &lock) < 0) #endif { if (errno == EOPNOTSUPP) { radMsgLog(PRI_MEDIUM, "serial device locking not supported by OS for %s", deviceName); } else { radMsgLog (PRI_CATASTROPHIC, "Serial device %s locked by other program!", deviceName); return ERROR; } } // configure it serialWork->portInit (med->fd); tcflush (med->fd, TCIFLUSH); tcflush (med->fd, TCOFLUSH); // Save the device name: strncpy(serialWork->device, deviceName, WVIEW_STRING2_SIZE); radUtilsSleep (1); return OK; }
// wvconfigInit: Open the configuration database for this process: int wvconfigInit (int firstProcess) { char buffer[_MAX_PATH]; struct stat fileData; // Make sure our config db is there: sprintf (buffer, "%s/%s", WVIEW_CONFIG_DIR, WVIEW_CONFIG_DATABASE); if (stat (buffer, &fileData) != 0) { radMsgLog (PRI_CATASTROPHIC, "Cannot locate config database %s - aborting!", buffer); return ERROR; } if (firstProcess == TRUE) { wvconfigMutex = radSemCreate(WVIEW_CONFIG_SEM_INDEX, 1); } else { wvconfigMutex = radSemCreate(WVIEW_CONFIG_SEM_INDEX, -1); } if (wvconfigMutex == NULL) { radMsgLog (PRI_CATASTROPHIC, "Cannot create/attach config database semaphore - aborting!"); return ERROR; } // Lock for serial access: radSemTake(wvconfigMutex); sqliteID = radsqliteOpen ((const char*)buffer); if (sqliteID == NULL) { radMsgLog (PRI_CATASTROPHIC, "wvconfigInit: radsqliteOpen %s failed!", buffer); radSemGive(wvconfigMutex); radSemDelete(wvconfigMutex); return ERROR; } return OK; }
static int serialRestart (WVIEW_MEDIUM *med) { MEDIUM_SERIAL *work = (MEDIUM_SERIAL*)med->workData; serialExit(med); radMsgLog (PRI_HIGH, "serialRestart: attempting restart"); while ((!wviewdIsExiting()) && (serialInit(med, work->device) == ERROR)) { radMsgLog (PRI_HIGH, "serialRestart: restart failed"); radUtilsSleep(5000); radMsgLog (PRI_HIGH, "serialRestart: retrying restart"); } if (!wviewdIsExiting()) { radMsgLog (PRI_HIGH, "serialRestart: recovered"); } return OK; }
static void SendNextArchiveRecord(RADSOCK_ID client, ULONG dateTime) { ARCHIVE_PKT recordStore; ARCHIVE_PKT networkStore; WVIEW_ALARM_CLIENT* alarmClient; alarmClient = FindClient(client); if (alarmClient == NULL) { radMsgLog (PRI_HIGH, "SendNextArchiveRecord: failed to get client!"); return; } if (dbsqliteArchiveInit() == ERROR) { radMsgLog (PRI_HIGH, "SendNextArchiveRecord: failed to open archive db!"); return; } if (dbsqliteArchiveGetNextRecord((time_t)dateTime, &recordStore) == ERROR) { WriteArchiveToClient(client, NULL); alarmClient->syncInProgress = FALSE; return; } dbsqliteArchiveExit(); // Mark the sync in progress: alarmClient->syncInProgress = TRUE; // OK, send the bloody thing: datafeedConvertArchive_HTON(&networkStore, &recordStore); if (WriteArchiveToClient(client, &networkStore) == ERROR) { statusUpdateMessage("SendNextArchiveRecord: failed to write archive record!"); radMsgLog (PRI_HIGH, "SendNextArchiveRecord: failed to write archive record!"); return; } return; }
// Expects the medium to already be open: static int writeBlock (WVIEWD_WORK *work, int offset, uint8_t* buffer) { // Write 32 bytes data at offset 'offset': char rqstBuffer[8]; int retVal; rqstBuffer[0] = 0xA0; // WRITE COMMAND rqstBuffer[1] = (char)(offset / 256); // WRITE ADDRESS HIGH rqstBuffer[2] = (char)(offset & 0xFF); // WRITE ADDRESS LOW rqstBuffer[3] = 0x20; // END MARK rqstBuffer[4] = 0xA0; // WRITE COMMAND rqstBuffer[5] = (char)(offset / 256); // WRITE ADDRESS HIGH rqstBuffer[6] = (char)(offset & 0xFF); // WRITE ADDRESS LOW rqstBuffer[7] = 0x20; // END MARK // Request write of 32-byte chunk from offset: retVal = (*(work->medium.usbhidWrite))(&work->medium, rqstBuffer, 8); if (retVal != 8) { radMsgLog (PRI_HIGH, "WH1080: write data request failed!"); return ERROR; } // Write 32-byte chunk: retVal = (*(work->medium.usbhidWrite))(&work->medium, buffer, 32); if (retVal != 32) { radMsgLog (PRI_HIGH, "WH1080: write data block failed!"); return ERROR; } // Read 8-byte ACK: retVal = (*(work->medium.usbhidRead))(&work->medium, buffer, 8, 1000); if (retVal != 8) { radMsgLog (PRI_HIGH, "WH1080: read data ACK failed!"); return ERROR; } return OK; }
static int requestDataPackets (HTML_WORK *work) { WVIEW_MSG_REQUEST msg; msg.requestType = WVIEW_RQST_TYPE_LOOP_DATA; if (radMsgRouterMessageSend (WVIEW_MSG_TYPE_REQUEST, &msg, sizeof(msg)) == ERROR) { radMsgLog (PRI_HIGH, "requestDataPackets: radMsgRouterMessageSend failed!"); return ERROR; } msg.requestType = WVIEW_RQST_TYPE_HILOW_DATA; if (radMsgRouterMessageSend (WVIEW_MSG_TYPE_REQUEST, &msg, sizeof(msg)) == ERROR) { radMsgLog (PRI_HIGH, "requestDataPackets: radMsgRouterMessageSend failed!"); return ERROR; } return OK; }
static int RestoreConnection(WVIEWD_WORK *work) { if (ethernetMediumInit (&work->medium, work->stationHost, work->stationPort) == ERROR) { radMsgLog (PRI_HIGH, "RestoreConnection: ethernet MediumInit failed"); return ERROR_ABORT; } // initialize the interface using the media specific routine if ((*(work->medium.init))(&work->medium, work->stationDevice) == ERROR) { radMsgLog (PRI_HIGH, "RestoreConnection: medium setup failed"); return ERROR; } // Make the socket blocking: radSocketSetBlocking ((*(work->medium.getsocket))(&work->medium), TRUE); return OK; }