コード例 #1
0
/*
 * Write out the HMTL config, returning the EEProm address following
 * what was written.
 */
int hmtl_write_config(config_hdr_t *hdr, output_hdr_t *outputs[])
{
  int addr;
  hdr->magic = HMTL_CONFIG_MAGIC;
  hdr->protocol_version = HMTL_CONFIG_VERSION;
  addr = EEPROM_safe_write(HMTL_CONFIG_ADDR,
                           (uint8_t *)hdr, sizeof (config_hdr_t));
  if (addr < 0) {
    DEBUG_ERR("hmtl_write_config: failed to write config to EEProm");
    return -1;
  }

  if (outputs != NULL) {
    for (int i = 0; i < hdr->num_outputs; i++) {
      output_hdr_t *output = outputs[i];
      addr = EEPROM_safe_write(addr, (uint8_t *)output,
                               hmtl_output_size(output));
      if (addr < 0) {
        DEBUG_ERR("hmtl_write_config: failed to write outputs to EEProm");
        return -2;
      }
    }
  }

  DEBUG2_VALUE("hmtl_write_config: size=", addr - HMTL_CONFIG_ADDR);
  DEBUG2_VALUELN(" end=", addr);

  return addr;
}
コード例 #2
0
ファイル: SoundCLI.cpp プロジェクト: aphelps/ObjectLights
void cliHandler(char **tokens, byte numtokens) {
  switch (tokens[0][0]) {
    case 'v': {
      if (numtokens < 2) return;
      verbosity = atoi(tokens[1]);
      DEBUG2_VALUELN("Set verbose:", verbosity);
      break;
    }

    case 'p': {
      if (numtokens < 2) return;
      output_period = atoi(tokens[1]);
      DEBUG2_VALUELN("Set output period:", output_period);
      break;
    }

    case 'm': {
      DEBUG2_VALUELN("millis:", millis());
      break;
    }

    case 'n': {
      DEBUG2_PRINTLN("Set output mode: none");
      output_mode = OUTPUT_MODE_NONE;
      break;
    }
    case 't': {
      DEBUG2_PRINTLN("Set output mode: text");
      output_mode = OUTPUT_MODE_TEXT;
      break;
    }
    case 'b': {
      DEBUG2_PRINTLN("Set output mode: binary");
      output_mode = OUTPUT_MODE_BINARY;
      break;
    }

    case '?':
    case 'h': {
      print_usage();
    }
  }
}
コード例 #3
0
/*
 * Read in the HMTL config, returning the EEProm address following
 * what was read.
 */
int hmtl_read_config(config_hdr_t *hdr, config_max_t outputs[],
                     int max_outputs) 
{
  int addr;

  /* Zero the outputs */
  for (int i = 0; i < max_outputs; i++) {
    outputs[i].hdr.type = HMTL_OUTPUT_NONE;
  }

  addr = EEPROM_safe_read(HMTL_CONFIG_ADDR,
                          (uint8_t *)hdr, sizeof (config_hdr_t));
  if (addr < 0) {
    DEBUG_ERR("hmtl_read_config: error reading config from eeprom");
    return -1;
  }

  if (hdr->magic != HMTL_CONFIG_MAGIC) {
    DEBUG_ERR("hmtl_read_config: read config with invalid magic");
    return -2;
  }

  if (hdr->protocol_version != HMTL_CONFIG_VERSION) {
    DEBUG1_VALUELN("hmtl_read_config: hdr has wrong protocol version:", hdr->protocol_version);
    return -3;
  }

  if ((hdr->num_outputs > 0) && (max_outputs != 0)) {
    /* Read in the outputs if any were indicated and a buffer was provided */
    if (max_outputs < hdr->num_outputs) {
      DEBUG_ERR("hmtl_read_config: not enough outputs");
      return -4;
    }
    for (int i = 0; i < hdr->num_outputs; i++) {
      addr = EEPROM_safe_read(addr,
                              (uint8_t *)&outputs[i], sizeof (config_max_t));
      if (addr <= 0) {
        DEBUG_ERR("hmtl_read_config: error reading outputs");
        return -5;
      }
    }
  }

  DEBUG2_VALUE("hmtl_read_config: size=", addr - HMTL_CONFIG_ADDR);
  DEBUG2_VALUE(" end=", addr);
  DEBUG2_VALUELN(" module address=", hdr->address);

  return addr;
}
コード例 #4
0
ファイル: MessageHandler.cpp プロジェクト: HMTL/HMTL
/* Process a message if it is for this module */
boolean MessageHandler::process_msg(msg_hdr_t *msg_hdr, Socket *src,
                                    Socket *serial_socket,
                                    config_hdr_t *config) {
  if (msg_hdr->version != HMTL_MSG_VERSION) {
    DEBUG_ERR("Invalid message version");
    return false;
  }

  /* Test if the message is for this device */
  if ((msg_hdr->address == address) ||
      (msg_hdr->address == SOCKET_ADDR_ANY)) {

    if ((msg_hdr->flags & MSG_FLAG_ACK) &&
        (msg_hdr->address != SOCKET_ADDR_ANY)) {
      /*
       * This is an ack message that is not for us, resend it over serial in
       * case that was the original source.
       * TODO: Maybe this should check address as well, and serial needs to be
       * assigned an address?
       */
      DEBUG4_PRINTLN("Forwarding ack to serial");
      Serial.write((byte *)msg_hdr, msg_hdr->length);

      if (msg_hdr->type != MSG_TYPE_SENSOR) { // Sensor broadcasts are for everyone
        return false;
      }
    }

    switch (msg_hdr->type) {

      case MSG_TYPE_OUTPUT: {
        output_hdr_t *out_hdr = (output_hdr_t *)(msg_hdr + 1);
        if (out_hdr->type == HMTL_OUTPUT_PROGRAM) {
          manager->handle_msg((msg_program_t *)out_hdr);
        } else {
          hmtl_handle_output_msg(msg_hdr, manager->num_outputs,
                                 manager->outputs, manager->objects);
        }

        return true;
      }

      case MSG_TYPE_POLL: {
        // Generate a response to a poll message
        uint16_t source_address = 0;
        Socket *sock;

        if (src != NULL) {
          // The response will be going over a socket, get the source address
          source_address = src->sourceFromData(msg_hdr);
          sock = src;
        } else {
          // The data will be sent back to the indicated Serial device.  A
          // socket still needs to be specified in order to have a buffer to
          // fill.
          sock = serial_socket;
        }

        DEBUG3_VALUELN("Poll req src:", source_address);

        // Format the poll response
        uint16_t len = hmtl_poll_fmt(sock->send_buffer,
                                     sock->send_data_size,
                                     source_address,
                                     msg_hdr->flags, OBJECT_TYPE,
                                     config,
                                     manager->outputs,
                                     sock->recvLimit);

        // Respond to the appropriate source
        if (src != NULL) {
          if (msg_hdr->address == SOCKET_ADDR_ANY) {
            // If this was a broadcast address then do not respond immediately,
            // delay for time based on our address.
            int delayMs = address * 2;
            DEBUG3_VALUELN("Delay resp: ", delayMs)
            delay(delayMs); // TODO: This blocks any running program?  Use a timer
          }

          src->sendMsgTo(source_address, sock->send_buffer, len);
        } else {
          // Send the response on the serial device
          Serial.write(sock->send_buffer, len);
        }

        break;
      }

      case MSG_TYPE_SET_ADDR: {
        /* Handle an address change message */
        msg_set_addr_t *set_addr = (msg_set_addr_t *)(msg_hdr + 1);
        if ((set_addr->device_id == 0) ||
            (set_addr->device_id == config->device_id)) {
          address = set_addr->address;
          src->sourceAddress = address;
          DEBUG2_VALUELN("Address changed to ", address);
        }
        break;
      }

      case MSG_TYPE_SENSOR: {
        if (msg_hdr->flags & MSG_FLAG_ACK) {
          /*
           * This is a sensor response, record relevant values for usage
           * elsewhere.
           */
          msg_sensor_data_t *sensor = NULL;
          while ((sensor = hmtl_next_sensor(msg_hdr, sensor))) {
            // Call the ProgramManager's handler for the sensor function
            manager->run_program(PROGRAM_SENSOR_DATA, sensor);
          }
          DEBUG_PRINT_END();
        }
        break;
      }

      case MSG_TYPE_TIMESYNC: {
        /*
         * This is a time synchronization message, send to the ProgramManager's
         * TimeSync object.
         */
        timesync.synchronize(src, SOCKET_ADDR_INVALID, msg_hdr);
        break;
      }

      case MSG_TYPE_DUMP_CONFIG: {
        /*
         * This is a request to dump the EEPROM objects to the serial device.
         *
         * TODO: This could be made to work remotely rather than only to requests
         * from the serial device.
         */
        uint16_t source_address = 0;

        DEBUG3_VALUELN("Dump req src:", source_address);

        /*
         * The response will be a typical message header followed by the raw data
         * from EEPROM.
         */
        msg_dumpconfig_response_t *resp = (msg_dumpconfig_response_t *)(serial_socket->send_buffer + sizeof (msg_hdr_t));

        int location = HMTL_CONFIG_ADDR; // Starting location in EEPROM
        int next_addr = 0;
        uint8_t flags;

        do {
          uint16_t len;
          flags = msg_hdr->flags;

          next_addr = EEPROM_safe_read(location, resp->data,
                                       serial_socket->send_data_size -
                                           HMTL_MSG_DUMPCONFIG_MIN_LEN);
          if (next_addr > 0) {
            uint16_t datalen = (uint16_t)EEPROM_DATA_SIZE(next_addr - location);

            DEBUG4_VALUELN("Dump config:", location);

            /*
             * Check if the next address is a valid structure and if so indicate
             * that there will be additional messages.
             */
            if (EEPROM_check_address(next_addr)) {
              flags |= MSG_FLAG_MORE_DATA;
            } else {
              DEBUG4_PRINTLN("Dump final message")
            }

            // Now that the length of the data is known construct the message
            len = hmtl_dumpconfig_fmt(serial_socket->send_buffer,
                                      serial_socket->send_data_size,
                                      source_address,
                                      flags,
                                      datalen);

            location = next_addr;
          } else {
            /*
             * There was an error, respond with an error flag
             */
            flags |= MSG_FLAG_ERROR;

            len = hmtl_dumpconfig_fmt(serial_socket->send_buffer,
                                      serial_socket->send_data_size,
                                      source_address,
                                      flags,
                                      0);
          }

          Serial.write(serial_socket->send_buffer, len);

        } while (flags & MSG_FLAG_MORE_DATA);

        break;
      }
    }
  }