void TimeSync::sendSyncMsg(Socket *socket, socket_addr_t target, byte phase, int adjustment = 0) { if (socket->send_data_size < HMTL_MSG_SIZE(msg_time_sync_t)) { DEBUG1_VALUELN("sync buf too small: ", socket->send_data_size); // DEBUG_ERR("startsync to small"); return; } msg_hdr_t *msg_hdr = (msg_hdr_t *)socket->send_buffer; msg_time_sync_t *msg_time = (msg_time_sync_t *)(msg_hdr + 1); msg_time->sync_phase = phase; msg_time->timestamp = ms() + adjustment; hmtl_msg_fmt(msg_hdr, target, HMTL_MSG_SIZE(msg_time_sync_t), MSG_TYPE_TIMESYNC); socket->sendMsgTo(target, socket->send_buffer, HMTL_MSG_SIZE(msg_time_sync_t)); DEBUG3_VALUE(" phase:", phase); DEBUG3_VALUE(" time:", msg_time->timestamp); }
void set_mode(uint8_t place, uint8_t new_mode) { if (current_modes[place] != new_mode) { previous_modes[place] = current_modes[place]; current_modes[place] = new_mode; // Set next_time to zero to trigger initialization modeConfigs[place].next_time = 0; DEBUG3_VALUE("Set mode ", place); DEBUG3_VALUELN("=", current_modes[place]); // Reset the brightness FastLED.setBrightness(255); } }
ProgramManager::ProgramManager(output_hdr_t **_outputs, program_tracker_t **_trackers, void **_objects, byte _num_outputs, hmtl_program_t *_functions, byte _num_programs) { outputs = _outputs; trackers = _trackers; objects = _objects; num_outputs = _num_outputs; functions = _functions; num_programs = _num_programs; for (byte i = 0; i < num_outputs; i++) { trackers[i] = NULL; } DEBUG3_VALUE("ProgramManager: outputs:", num_outputs); DEBUG3_VALUELN(" programs:", num_programs); }
// TODO: Static method? boolean TimeSync::synchronize(Socket *socket, socket_addr_t target, msg_hdr_t *msg_hdr) { if (msg_hdr == NULL) { /* This was called to synchronize the times to a remote address */ if (state != STATE_IDLE) { // XXX: What should we do if a sync was already pending? For now // just continue as if it weren't } /* Begin the synchronization process */ DEBUG3_VALUELN("SYNC to:", target); sendSyncMsg(socket, target, TIMESYNC_SYNC); state = STATE_AWAITING_ACK; } else { if (msg_hdr->type != MSG_TYPE_TIMESYNC) { // TODO: What to do here? goto EXIT; } unsigned long now = millis(); msg_time_sync_t *msg_time = (msg_time_sync_t *)(msg_hdr + 1); socket_addr_t source = socket->sourceFromData(msg_hdr); switch (msg_time->sync_phase) { case TIMESYNC_CHECK: { DEBUG3_COMMAND(unsigned long local_now = ms(); DEBUG3_VALUE("CHECK from:", source); DEBUG3_VALUE(" ts:", msg_time->timestamp); DEBUG3_VALUE(" ms:", local_now); DEBUG3_VALUE(" diff:", (long)(msg_time->timestamp + latency - local_now)); ); sendSyncMsg(socket, source, TIMESYNC_ACK, latency); break; } case TIMESYNC_SYNC: { switch (state) { case STATE_IDLE: case STATE_SYNCED: { // Record the timestamp to compute the latency DEBUG3_VALUE("SYNC from:", source); latency = now; // Reply with ack sendSyncMsg(socket, source, TIMESYNC_ACK); state = STATE_AWAITING_SET; break; } } break; } case TIMESYNC_RESYNC: { if (state == STATE_SYNCED) { delta = (msg_time->timestamp + latency) - now; DEBUG3_VALUE("RESYNC from:", source); DEBUG3_VALUE(" delta:", delta); } break; } case TIMESYNC_ACK: { // TODO: Check if this is a response to the message we sent DEBUG3_VALUE("ACK from:", source); if (state == STATE_AWAITING_ACK) { // Send TIMESYNC_SET sendSyncMsg(socket, source, TIMESYNC_SET); state = STATE_IDLE; } else { DEBUG3_COMMAND(unsigned long local_now = ms(); DEBUG3_VALUE(" ts:", msg_time->timestamp); DEBUG3_VALUE(" ms:", local_now); DEBUG3_VALUE(" diff:", (long)(local_now - msg_time->timestamp)); ); } break; } case TIMESYNC_SET: { if (state == STATE_AWAITING_SET) { /* * Set the latecy to 1/2 the time between sending the ack and receiving * this message, and then use that latecy to compute the delta from * the sender's time. */ DEBUG3_VALUE("SET from:", source); DEBUG3_VALUE(" ts:", msg_time->timestamp); latency = (now - latency) / 2; delta = (msg_time->timestamp + latency) - now; state = STATE_SYNCED; DEBUG3_VALUE(" lat:", latency); DEBUG3_VALUE(" delta:", delta); } break; } }