/** * Perform a full factory reset. * This can be triggered automatically at boot time if * certain sanity checks fail, or via a test mode option. */ void factory_reset (void) { file_reset (); #ifdef __m6809__ memset (AREA_BASE (permanent), 0, AREA_SIZE (permanent)); #else /* TODO - how to clean the permanent area in native mode? */ #endif timestamp_update (&system_timestamps.factory_reset); callset_invoke (factory_reset); }
CALLSET_ENTRY (service, sw_escape) { #ifndef CONFIG_BPT if (coin_door_warning_needed ()) return; else if (!in_test) { add_credit (); audit_increment (&system_audits.service_credits); timestamp_update (&system_timestamps.last_service_credit); } #endif }
/* This function should be invoked from a separate task context, because it may sleep. */ void print_all_audits (void) { printer_reconfig (); timestamp_update (&system_timestamps.last_printout); printout_name = "AUDIT REPORT"; print_audit_list ("MAIN AUDITS", main_audits); print_nl (); print_audit_list ("EARNINGS AUDITS", earnings_audits); print_nl (); print_audit_list ("STANDARD AUDITS", standard_audits); print_nl (); print_audit_list ("FEATURE AUDITS", feature_audit_info); print_ff (); }
/* feed implementation for Beast-format data (including Radarcape) */ static PyObject *feed_beast(modesreader *self, Py_buffer *buffer, int max_messages) { PyObject *rv = NULL; uint8_t *buffer_start, *p, *eod; int message_count = 0; PyObject *message_tuple = NULL; PyObject **messages = NULL; int error_pending = 0; buffer_start = buffer->buf; if (max_messages <= 0) { /* allocate the maximum size we might need, given a minimal encoding of: * <1A> <'1'> <6 bytes timestamp> <1 byte signal> <2 bytes message> = 11 bytes total */ max_messages = buffer->len / 11 + 2; } messages = calloc(max_messages, sizeof(PyObject*)); if (!messages) { PyErr_NoMemory(); goto out; } /* parse messages */ p = buffer_start; eod = buffer_start + buffer->len; while (p+2 <= eod && message_count+2 < max_messages) { int message_len = -1; uint64_t timestamp; uint8_t signal; uint8_t data[14]; uint8_t *m, *eom; int i; uint8_t type; PyObject *message; int wanted; if (p[0] != 0x1a) { error_pending = 1; if (message_count > 0) goto nomoredata; PyErr_Format(PyExc_ValueError, "Lost sync with input stream: expected a 0x1A marker at offset %d but found 0x%02x instead", (int) (p - buffer_start), (int)p[0]); goto out; } type = p[1]; switch (type) { case '1': message_len = 2; break; /* mode A/C */ case '2': message_len = 7; break; /* mode S short */ case '3': message_len = 14; break; /* mode S long */ case '4': message_len = 14; break; /* radarcape status message */ default: error_pending = 1; if (message_count > 0) goto nomoredata; PyErr_Format(PyExc_ValueError, "Lost sync with input stream: unexpected message type 0x%02x after 0x1A marker at offset %d", (int)p[1], (int) (p - buffer_start)); goto out; } m = p + 2; eom = m + 7 + message_len; if (eom > eod) break; #define ADVANCE \ do { \ if (*m++ == 0x1a) { \ if (m < eod && *m != 0x1a) { \ error_pending = 1; \ if (message_count > 0) \ goto nomoredata; \ PyErr_SetString(PyExc_ValueError, "Lost sync with input stream: expected 0x1A after 0x1A escape"); \ goto out; \ } \ ++m, ++eom; \ if (eom > eod) \ goto nomoredata; \ } \ } while(0) /* timestamp, 6 bytes */ timestamp = *m; ADVANCE; timestamp = (timestamp << 8) | *m; ADVANCE; timestamp = (timestamp << 8) | *m; ADVANCE; timestamp = (timestamp << 8) | *m; ADVANCE; timestamp = (timestamp << 8) | *m; ADVANCE; timestamp = (timestamp << 8) | *m; ADVANCE; /* signal, 1 byte */ signal = *m; ADVANCE; /* message, N bytes */ for (i = 0; i < message_len; ++i) { data[i] = *m; ADVANCE; } /* do some filtering */ if (type == '4') { /* radarcape-style status message, use this to switch our decoder type */ self->radarcape_utc_bugfix = (data[2] & 0x80) == 0x80; if (self->allow_mode_change) { decoder_mode newmode; if (data[0] & 0x10) { /* radarcape in GPS timestamp mode */ if ((data[2] & 0x20) == 0x20) { newmode = DECODER_RADARCAPE_EMULATED; } else { newmode = DECODER_RADARCAPE; } } else { /* radarcape in 12MHz timestamp mode */ newmode = DECODER_BEAST; } /* handle mode changes by inserting an event message */ if (newmode != self->decoder_mode) { set_decoder_mode(self, newmode); if (self->want_events) { if (! (messages[message_count++] = make_mode_change_event(self))) goto out; } } } } if (self->decoder_mode == DECODER_BEAST) { /* 12MHz mode */ /* check for very out of range value * (dump1090 can hold messages for up to 60 seconds! so be conservative here) * also work around dump1090-mutability issue #47 which can send very stale Mode A/C messages */ if (self->want_events && type != '1' && !timestamp_check(self, timestamp)) { if (! (messages[message_count++] = make_timestamp_jump_event(self, timestamp))) goto out; } } else { /* gps mode */ /* adjust timestamp so that it is a contiguous nanoseconds-since- * midnight value, rather than the raw form which skips values once * a second */ uint64_t nanos = timestamp & 0x00003FFFFFFF; uint64_t secs = timestamp >> 30; if (!self->radarcape_utc_bugfix) { /* fix up the timestamp so it is UTC, not 1 second ahead */ --secs; } timestamp = nanos + secs * 1000000000; /* adjust for the timestamp being at the _end_ of the frame; * we don't really care about getting a particular starting point * (that's just a fixed offset), so long as it is _the same in * every frame_. * * (but don't do this for status messages as they have a timestamp * as at the start of the message, which is basically the time of * the PPS) */ if (type != '4') { uint64_t adjust = (8000 + message_len * 8000); /* each byte takes 8us to transmit, plus 8us preamble */ if (adjust <= timestamp) { timestamp = timestamp - adjust; } else { /* wrap it to the previous day */ timestamp = timestamp + 86400 * 1000000000ULL - adjust; } } /* check for end of day rollover */ if (self->want_events && self->last_timestamp >= (86340 * 1000000000ULL) && timestamp <= (60 * 1000000000ULL)) { if (! (messages[message_count++] = make_epoch_rollover_event(self, timestamp))) goto out; } else if (self->want_events && type != '1' && !timestamp_check(self, timestamp)) { if (! (messages[message_count++] = make_timestamp_jump_event(self, timestamp))) goto out; } } if (type != '1') { timestamp_update(self, timestamp); } if (type == '4') { /* radarcape-style status message, emit the status event if wanted */ if (self->want_events) { if (! (messages[message_count++] = make_radarcape_status_event(self, timestamp, data))) goto out; } /* don't try to process this as a Mode S message */ p = m; continue; } /* it's a Mode A/C or Mode S message, parse it */ if (! (message = modesmessage_from_buffer(timestamp, signal, data, message_len))) goto out; /* apply filters, update seen-set */ ++self->received_messages; wanted = filter_message(self, message); if (wanted < 0) goto out; else if (wanted) messages[message_count++] = message; else { ++self->suppressed_messages; Py_DECREF(message); } p = m; } nomoredata: if (! (message_tuple = PyTuple_New(message_count))) goto out; while (--message_count >= 0) { PyTuple_SET_ITEM(message_tuple, message_count, messages[message_count]); /* steals ref */ } rv = Py_BuildValue("(l,N,N)", (long) (p - buffer_start), message_tuple, PyBool_FromLong(error_pending)); out: while (--message_count >= 0) { Py_XDECREF(messages[message_count]); } free(messages); return rv; }
static PyObject *feed_avr(modesreader *self, Py_buffer *buffer, int max_messages) { PyObject *rv = NULL; uint8_t *buffer_start, *p, *eod; int message_count = 0; PyObject *message_tuple = NULL; PyObject **messages = NULL; int error_pending = 0; buffer_start = buffer->buf; if (max_messages <= 0) { /* allocate the maximum size we might need, given a minimal encoding of: * '*' <2 bytes message> ';' LF */ max_messages = buffer->len / 5 + 1; } messages = calloc(max_messages, sizeof(PyObject*)); if (!messages) { PyErr_NoMemory(); goto out; } p = buffer_start; eod = buffer_start + buffer->len; while (p+17 <= eod && message_count+1 < max_messages) { int message_len = -1; uint64_t timestamp; uint8_t data[14]; uint8_t message_format; int i; uint8_t *m; PyObject *message; message_format = p[0]; if (message_format != '@' && message_format != '%' && message_format != '<' && message_format != '*' && message_format != ':') { error_pending = 1; if (message_count > 0) goto nomoredata; PyErr_Format(PyExc_ValueError, "Lost sync with input stream: expected '@'/'%%'/'<'/'*'/':' at offset %d but found 0x%02x instead", (int) (p - buffer_start), (int)p[0]); goto out; } m = p + 1; if (message_format == '@' || message_format == '%' || message_format == '<') { /* read 6 bytes of timestamp */ timestamp = 0; for (i = 0; i < 12; ++i, ++m) { int c; if (m >= eod) { goto nomoredata; } timestamp <<= 4; c = hexvalue(*m); if (c >= 0) { timestamp |= c; } else { error_pending = 1; if (message_count > 0) goto nomoredata; PyErr_Format(PyExc_ValueError, "Lost sync with input stream: expected a hex digit at offset %d but found 0x%02x instead", (int) (m - buffer_start), (int)*m); goto out; } } } else { /* AVR format with no timestamp */ timestamp = 0; } if (message_format == '<') { /* in format '<', skip 1 byte of signal */ m += 2; if (m >= eod) goto nomoredata; } /* read 2-14 bytes of data */ message_len = 0; while (message_len < 14) { int c0, c1; if (m+1 >= eod) { goto nomoredata; } if (m[0] == ';') { break; /* end of message marker */ } else { c0 = hexvalue(m[0]); if (c0 < 0) { error_pending = 1; if (message_count > 0) goto nomoredata; PyErr_Format(PyExc_ValueError, "Lost sync with input stream: expected a hex digit at offset %d but found 0x%02x instead", (int) (m - buffer_start), (int)m[0]); goto out; } } c1 = hexvalue(m[1]); if (c1 < 0) { error_pending = 1; if (message_count > 0) goto nomoredata; PyErr_Format(PyExc_ValueError, "Lost sync with input stream: expected a hex digit at offset %d but found 0x%02x instead", (int) (m - buffer_start), (int)m[1]); goto out; } if (message_len < 14) { data[message_len] = (c0 << 4) | c1; } ++message_len; m += 2; } /* consume ';' */ if (m >= eod) goto nomoredata; if (*m != ';') { error_pending = 1; if (message_count > 0) goto nomoredata; PyErr_Format(PyExc_ValueError, "Lost sync with input stream: expected ';' at offset %d but found 0x%02x instead", (int) (m - buffer_start), (int)*m); goto out; } /* CR LF, LF CR, LF all seen! ugh. */ /* skip until CR or LF */ while (m < eod && *m != '\r' && *m != '\n') ++m; /* consume however many CRs and LFs */ while (m < eod && (*m == '\r' || *m == '\n')) ++m; /* check length */ if (message_len != 2 && message_len != 7 && message_len != 14) { error_pending = 1; if (message_count > 0) goto nomoredata; PyErr_Format(PyExc_ValueError, "Lost sync with input stream: unexpected %d-byte message starting at offset %d", message_len, (int) (p - buffer_start)); goto out; } /* check for very out of range value * (dump1090 can hold messages for up to 60 seconds! so be conservative here) * also work around dump1090-mutability issue #47 which can send very stale Mode A/C messages */ if (self->want_events && message_len != 2 && !timestamp_check(self, timestamp)) { if (! (messages[message_count++] = make_timestamp_jump_event(self, timestamp))) goto out; } timestamp_update(self, timestamp); /* decode it */ if (! (message = modesmessage_from_buffer(timestamp, 0, data, message_len))) goto out; /* apply filters, update seen-set */ ++self->received_messages; int wanted = filter_message(self, message); if (wanted < 0) goto out; else if (wanted) messages[message_count++] = message; else { ++self->suppressed_messages; Py_DECREF(message); } /* next message */ p = m; } nomoredata: if (! (message_tuple = PyTuple_New(message_count))) goto out; while (--message_count >= 0) { PyTuple_SET_ITEM(message_tuple, message_count, messages[message_count]); /* steals ref */ } rv = Py_BuildValue("(l,N,N)", (long) (p - buffer_start), message_tuple, PyBool_FromLong(error_pending)); out: while (--message_count >= 0) { Py_XDECREF(messages[message_count]); } free(messages); return rv; }
int main (int argc, char**argv) { int ret = 0; int heartbeat_usec = 50000; //20Hz is ok by default uint64_t last_beat = 0; Log_info ("cloudvpn starting"); Log (0, "You are using CloudVPN, which is Free software."); Log (0, "For more information please see the GNU GPL license,"); Log (0, "which you should have received along with this program."); setup_sighandler (kill_cloudvpn); /* * initialization */ if (!config_parse (argc, argv) ) { Log_error ("failed to parse config, terminating."); ret = 1; goto failed_config; } if (!config_get_int ("heartbeat", heartbeat_usec) ) heartbeat_usec = 50000; Log_info ("heartbeat is set to %d usec", heartbeat_usec); timestamp_update(); //get initial timestamp status_init(); route_init(); squeue_init(); network_init(); if (poll_init() ) { Log_fatal ("poll initialization failed"); ret = 2; goto failed_poll; } if (do_memlock() ) { Log_fatal ("locking process to memory failed"); ret = 3; goto failed_poll; } if (comm_load() ) { Log_fatal ("failed to load comm data"); ret = 4; goto failed_poll; } if (comm_init() ) { Log_fatal ("communication initialization failed"); ret = 5; goto failed_comm; } if (gate_init() ) { Log_fatal ("gate initialization failed"); ret = 6; goto failed_gate; } if (do_chroot() ) { Log_fatal ("chrooting failed"); ret = 7; goto failed_sec; } if (do_switch_user() ) { Log_fatal ("user switch failed"); ret = 8; goto failed_sec; } /* * main loop */ Log_info ("initialization complete, entering main loop"); last_beat = 0; //update immediately. while (!g_terminate) { timestamp_update(); if ( (timestamp() - last_beat) < (unsigned int) heartbeat_usec) { //poll more stuff poll_wait_for_event (heartbeat_usec - timestamp() + last_beat); //send the results comm_flush_data(); gate_flush_data(); continue; } last_beat = timestamp(); gate_periodic_update(); comm_periodic_update(); route_periodic_update(); status_try_export(); } /* * deinitialization */ Log_info ("shutting down"); failed_sec: gate_shutdown(); failed_gate: comm_shutdown(); failed_comm: if (poll_deinit() ) Log_warn ("poll_deinit somehow failed!"); failed_poll: failed_config: if (!ret) Log_info ("cloudvpn exiting gracefully"); else Log_error ("cloudvpn exiting with code %d", ret); return ret; }