status_t CameraAcc::acc_read_fw(const char* filename, fw_info &fw) { LOG1("@%s", __FUNCTION__); FILE* file; if (!filename) return UNKNOWN_ERROR; LOG1("filename=%s", filename); fw.size = 0; fw.data = NULL; file = fopen(filename, "rb"); if (!file) return UNKNOWN_ERROR; fseek(file, 0, SEEK_END); fw.size = ftell(file); fseek(file, 0, SEEK_SET); if (fw.size == 0) { fclose(file); return UNKNOWN_ERROR; } fw.data = host_alloc(fw.size); if (fw.data == NULL) { fclose(file); return UNKNOWN_ERROR; } if (fread(fw.data, 1, fw.size, file) != fw.size) { fclose(file); host_free(fw.data); return UNKNOWN_ERROR; } fclose(file); return NO_ERROR; }
/** Daemon main run loop. */ int daemon_main (int argc, const char *argv[]) { const char *buf; size_t sz; if (strcmp (APP.logpath, "@syslog") == 0) { log_open_syslog ("opticon-agent", APP.loglevel); } else { log_open_file (APP.logpath, APP.loglevel); } probelist_start (&APP.probes); APP.resender = authresender_create (APP.transport); time_t tlast = time (NULL); time_t nextslow = tlast + 5; time_t nextsend = tlast + 10; time_t lastkeyrotate = 0; int slowround = 0; log_info ("Daemonized"); while (1) { time_t tnow = tlast = time (NULL); slowround = 0; /* If a slow round is due at this time, use the excuse to send an authentication packet */ if (nextslow <= tnow) { slowround = 1; uint32_t sid = APP.auth.sessionid; if (! sid) sid = gen_sessionid(); log_debug ("Authenticating session <%08x>", sid); APP.auth.sessionid = sid; APP.auth.serial = 0; APP.auth.tenantid = APP.tenantid; APP.auth.hostid = APP.hostid; /* Only rotate the AES key every half hour */ if (tnow - lastkeyrotate > 1800) { APP.auth.sessionkey = aeskey_create(); lastkeyrotate = tnow; } APP.auth.tenantkey = APP.collectorkey; /* Dispatch */ ioport *io_authpkt = ioport_wrap_authdata (&APP.auth, gen_serial()); sz = ioport_read_available (io_authpkt); buf = ioport_get_buffer (io_authpkt); outtransport_send (APP.transport, (void*) buf, sz); authresender_schedule (APP.resender, buf, sz); ioport_close (io_authpkt); /* Schedule next slow round */ nextslow = nextslow + 300; } log_debug ("Poking probes"); probe *p = APP.probes.first; time_t wakenext = tnow + 300; /* Go over the probes to figure out whether we should kick them */ while (p) { time_t firewhen = p->lastpulse + p->interval; if (firewhen <= tnow) { conditional_signal (&p->pulse); p->lastpulse = tnow; } /* Figure out whether the next event for this probe is sooner than the next wake-up time we determined so far */ if (p->lastpulse + p->interval < wakenext) { wakenext = p->lastpulse + p->interval; } p = p->next; } int collected = 0; int ncollected = 0; host *h = host_alloc(); var *vnagios = var_alloc(); var *vchkwarn = var_get_array_forkey (vnagios, "chkwarn"); var *vchkalert = var_get_array_forkey (vnagios, "chkalert"); /* If we're in a slow round, we already know we're scheduled. Otherwise, see if the next scheduled moment for sending a (fast lane) packet has passed. */ if (slowround || (tnow >= nextsend)) { h->uuid = APP.hostid; host_begin_update (h, time (NULL)); if (! slowround) while (nextsend <= tnow) nextsend += 60; log_debug ("Collecting probes"); /* Go over the probes again, picking up the ones relevant to the current round being performed */ p = APP.probes.first; while (p) { pthread_mutex_lock (&p->vlock); volatile var *v = p->vcurrent; /* See if data for this probe has been collected since the last kick */ if (v && (p->lastdispatch <= p->lastreply)) { /* Filter probes for the current lane */ if ((slowround && p->interval>60) || ((!slowround) && p->interval<61)) { log_debug ("Collecting <%s>", p->call); if (p->type == PROBE_NAGIOS) { /* Check for alert/warning state and * summarize before adding to host struct */ int pstatus = var_get_int_forkey ((var*)v, "status"); if (pstatus) { var *arr; switch (pstatus) { case 1: var_add_str (vchkwarn, p->id); break; default: var_add_str (vchkalert, p->id); break; } collected++; } ncollected++; } else { host_import (h, (var *) v); collected++; } p->lastdispatch = tnow; } } else { if (tnow - p->lastreply > (2*(p->interval))) { log_warn ("Probe <%s> seems stuck after %i seconds", p->call, tnow - p->lastreply); } } pthread_mutex_unlock (&p->vlock); p = p->next; } } /* Add the chk tree with nagios self-checks to the data */ if (ncollected) host_import (h, vnagios); /* If any data was collected, encode it */ if (collected) { log_debug ("Encoding probes"); ioport *encoded = ioport_create_buffer (NULL, 4096); if (! encoded) { log_warn ("Error creating ioport"); ioport_close (encoded); host_delete (h); continue; } if (! codec_encode_host (APP.codec, encoded, h)) { log_warn ("Error encoding host"); ioport_close (encoded); host_delete (h); continue; } if (APP.dumppath) { FILE *pktf = fopen (APP.dumppath,"a"); fprintf (pktf, "\n--- %s ---\n\n", slowround?"Slow":"Fast"); ioport *dump = ioport_create_filewriter (pktf); log_debug ("dump %llx", dump); codec *jsonc = codec_create_json(); log_debug ("jsonc %llx", jsonc); codec_encode_host (jsonc, dump, h); codec_release (jsonc); ioport_close (dump); fclose (pktf); } log_debug ("Encoded %i bytes", ioport_read_available (encoded)); ioport *wrapped = ioport_wrap_meterdata (APP.auth.sessionid, gen_serial(), APP.auth.sessionkey, encoded); if (! wrapped) { log_error ("Error wrapping"); ioport_close (encoded); host_delete (h); continue; } sz = ioport_read_available (wrapped); buf = ioport_get_buffer (wrapped); /* Send it off into space */ outtransport_send (APP.transport, (void*) buf, sz); log_info ("%s lane packet sent: %i bytes", slowround ? "Slow":"Fast", sz); ioport_close (wrapped); ioport_close (encoded); } /* Done with the host object */ host_delete (h); /* Figure out what the next scheduled wake-up time is */ tnow = time (NULL); if (nextsend < wakenext) wakenext = nextsend; if (nextslow < wakenext) wakenext = nextslow; if (wakenext > tnow) { log_debug ("Sleeping for %i seconds", (wakenext-tnow)); sleep (wakenext-tnow); } } return 666; }