/**
 * Handle a RDM message.
 */
void SimpleE133Controller::HandlePacket(
    const ola::e133::E133RDMMessage &rdm_message) {
  OLA_INFO << "RDM callback executed with code: " <<
    ola::rdm::ResponseCodeToString(rdm_message.response_code);

  m_ss.Terminate();

  if (rdm_message.response_code != ola::rdm::RDM_COMPLETED_OK)
    return;

  switch (rdm_message.response->ResponseType()) {
    case ola::rdm::RDM_NACK_REASON:
      HandleNack(rdm_message.response);
      return;
    default:
      break;
  }

  const RDMResponse *response = rdm_message.response;

  const ola::rdm::PidDescriptor *pid_descriptor = m_pid_helper->GetDescriptor(
      response->ParamId(),
      response->SourceUID().ManufacturerId());
  const ola::messaging::Descriptor *descriptor = NULL;

  if (pid_descriptor) {
    switch (response->CommandClass()) {
      case ola::rdm::RDMCommand::GET_COMMAND_RESPONSE:
        descriptor = pid_descriptor->GetResponse();
        break;
      case ola::rdm::RDMCommand::SET_COMMAND_RESPONSE:
        descriptor = pid_descriptor->SetResponse();
        break;
      default:
        OLA_WARN << "Unknown command class " << response->CommandClass();
    }
  }

  auto_ptr<const ola::messaging::Message> message;
  if (descriptor)
    message.reset(m_pid_helper->DeserializeMessage(descriptor,
                                                   response->ParamData(),
                                                   response->ParamDataSize()));

  if (message.get())
    cout << m_pid_helper->PrettyPrintMessage(
        response->SourceUID().ManufacturerId(),
        response->CommandClass() == ola::rdm::RDMCommand::SET_COMMAND_RESPONSE,
        response->ParamId(),
        message.get());
  else
    m_command_printer.DisplayResponse(response, true);
}
Example #2
0
/**
 * Display parameter data in hex and ascii
 */
void RDMSniffer::DisplayParamData(const PidDescriptor *pid_descriptor,
                                  bool is_get,
                                  const uint8_t *data,
                                  unsigned int length) {
  if (!length)
    return;

  cout << "  Param data:" << endl;
  if (m_options.unpack_param_data && pid_descriptor) {
    const Descriptor *descriptor =
        is_get ? pid_descriptor->GetResponse() : pid_descriptor->SetResponse();

    if (descriptor) {
      auto_ptr<const Message> message(
          m_pid_helper.DeserializeMessage(descriptor, data, length));

      if (message.get()) {
        cout << m_pid_helper.MessageToString(message.get());
        return;
      }
    }
  }

  // otherwise just display the raw data
  stringstream raw;
  raw << std::setw(2) << std::hex;
  stringstream ascii;
  for (unsigned int i = 0; i != length; i++) {
    raw << std::setw(2) << std::setfill('0') <<
      static_cast<unsigned int>(data[i]) << " ";
    if (data[i] >= ' ' && data[i] <= '~')
      ascii << data[i];
    else
      ascii << ".";

    if (i % BYTES_PER_LINE == BYTES_PER_LINE - 1) {
      cout << "    " << raw.str() << " " << ascii.str() << endl;
      raw.str("");
      ascii.str("");
    }
  }
  if (length % BYTES_PER_LINE != 0) {
    // pad if needed
    raw << string(3 * (BYTES_PER_LINE - (length % BYTES_PER_LINE)), ' ');
    cout << "    " << raw.str() << " " << ascii.str() << endl;
  }
}
Example #3
0
/**
 * Display an RDM Request.
 */
void RDMSniffer::DisplayRDMRequest(unsigned int start, unsigned int end) {
  auto_ptr<RDMRequest> request(
      RDMRequest::InflateFromData(&m_frame[start], end - start + 1));
  if (!request.get()) {
    DisplayRawData(start, end);
    return;
  }

  const PidDescriptor *descriptor = m_pid_helper.GetDescriptor(
       request->ParamId(),
       request->DestinationUID().ManufacturerId());
  bool is_get = request->CommandClass() == RDMCommand::GET_COMMAND;

  if (m_options.summarize_rdm_frames) {
    cout <<
      request->SourceUID() << " -> " << request->DestinationUID() << " " <<
      (is_get ? "GET" : "SET") <<
      ", sub-device: " << std::dec << request->SubDevice() <<
      ", tn: " << static_cast<int>(request->TransactionNumber()) <<
      ", port: " << std::dec << static_cast<int>(request->PortId()) <<
      ", PID 0x" << std::hex << std::setfill('0') << std::setw(4) <<
        request->ParamId();
      if (descriptor)
        cout << " (" << descriptor->Name() << ")";
      cout << ", pdl: " << std::dec << request->ParamDataSize() << endl;
  } else {
    cout << endl;
    cout << "  Sub start code : 0x" << std::hex <<
      static_cast<unsigned int>(m_frame[start]) << endl;
    cout << "  Message length : " <<
      static_cast<unsigned int>(m_frame[start + 1]) << endl;
    cout << "  Dest UID       : " << request->DestinationUID() << endl;
    cout << "  Source UID     : " << request->SourceUID() << endl;
    cout << "  Transaction #  : " << std::dec <<
      static_cast<unsigned int>(request->TransactionNumber()) << endl;
    cout << "  Port ID        : " << std::dec <<
      static_cast<unsigned int>(request->PortId()) << endl;
    cout << "  Message count  : " << std::dec <<
      static_cast<unsigned int>(request->MessageCount()) << endl;
    cout << "  Sub device     : " << std::dec << request->SubDevice() << endl;
    cout << "  Command class  : " << (is_get ? "GET" : "SET") << endl;
    cout << "  Param ID       : 0x" << std::setfill('0') << std::setw(4) <<
      std::hex << request->ParamId();
    if (descriptor)
      cout << " (" << descriptor->Name() << ")";
    cout << endl;
    cout << "  Param data len : " << std::dec << request->ParamDataSize() <<
      endl;
    DisplayParamData(descriptor,
                     is_get,
                     request->ParamData(),
                     request->ParamDataSize());
  }
}
Example #4
0
/**
 * Handle an ACK response
 */
void RDMController::HandleAckResponse(uint16_t manufacturer_id,
                                      bool is_set,
                                      uint16_t pid,
                                      const string &rdm_data) {
  const ola::rdm::PidDescriptor *pid_descriptor = m_pid_helper.GetDescriptor(
      pid,
      m_pending_request.uid->ManufacturerId());

  if (!pid_descriptor) {
    OLA_WARN << "Unknown PID: " << pid << ".";
    return;
  }

  const ola::messaging::Descriptor *descriptor = NULL;
  if (is_set)
    descriptor = pid_descriptor->SetResponse();
  else
    descriptor = pid_descriptor->GetResponse();

  if (!descriptor) {
    OLA_WARN << "Unknown response message: " << (is_set ? "SET" : "GET") <<
        " " << pid_descriptor->Name();
    return;
  }

  auto_ptr<const ola::messaging::Message> message(
      m_pid_helper.DeserializeMessage(
          descriptor,
          reinterpret_cast<const uint8_t*>(rdm_data.data()),
          rdm_data.size()));

  if (!message.get()) {
    OLA_WARN << "Unable to inflate RDM response";
    return;
  }

  cout << m_pid_helper.PrettyPrintMessage(manufacturer_id,
                                          is_set,
                                          pid,
                                          message.get());
}
Example #5
0
/*
 * Dump the list of known pids
 */
void DisplayPIDsAndExit(uint16_t manufacturer_id,
                        const PidStoreHelper &pid_helper) {
  vector<string> pid_names;
  pid_helper.SupportedPids(manufacturer_id, &pid_names);
  sort(pid_names.begin(), pid_names.end());

  vector<string>::const_iterator iter = pid_names.begin();
  for (; iter != pid_names.end(); ++iter) {
    cout << *iter << endl;
  }
  exit(ola::EXIT_OK);
}
Example #6
0
/**
 * Display an RDM response
 */
void RDMSniffer::DisplayRDMResponse(unsigned int start, unsigned int end) {
  ola::rdm::rdm_response_code code;
  unsigned int length = end - start + 1;
  auto_ptr<RDMResponse> response(
      RDMResponse::InflateFromData(&m_frame[start], length, &code));

  if (!response.get()) {
    DisplayRawData(start, end);
    return;
  }

  const PidDescriptor *descriptor = m_pid_helper.GetDescriptor(
       response->ParamId(),
       response->SourceUID().ManufacturerId());

  bool is_get = response->CommandClass() == RDMCommand::GET_COMMAND_RESPONSE;

  if (m_options.summarize_rdm_frames) {
    cout <<
      response->SourceUID() << " -> " << response->DestinationUID() << " " <<
      (is_get ? "GET_RESPONSE" : "SET_RESPONSE") <<
      ", sub-device: " << std::dec << response->SubDevice() <<
      ", tn: " << static_cast<int>(response->TransactionNumber()) <<
      ", response type: ";

    switch (response->ResponseType()) {
      case ola::rdm::RDM_ACK:
        cout << "ACK";
        break;
      case ola::rdm::RDM_ACK_TIMER:
        cout << "ACK TIMER";
        break;
      case ola::rdm::RDM_NACK_REASON:
        if (length >= 26) {
          uint16_t reason;
          memcpy(reinterpret_cast<uint8_t*>(&reason),
                 reinterpret_cast<const void*>(&m_frame[start + 23]),
                 sizeof(reason));
          reason = ola::network::NetworkToHost(reason);
          cout << "NACK (" << ola::rdm::NackReasonToString(reason) << ")";
        } else {
          cout << "Malformed NACK ";
        }
        break;
      case ola::rdm::ACK_OVERFLOW:
        cout << "ACK OVERFLOW";
        break;
      default:
        cout << "Unknown (" << response->ResponseType() << ")";
    }
    cout << ", PID 0x" << std::hex <<
      std::setfill('0') << std::setw(4) << response->ParamId();
    if (descriptor)
      cout << " (" << descriptor->Name() << ")";
    cout << ", pdl: " << std::dec << response->ParamDataSize() << endl;
  } else {
    cout << endl;
    cout << "  Sub start code : 0x" << std::hex <<
      static_cast<unsigned int>(m_frame[start]) << endl;
    cout << "  Message length : " <<
      static_cast<unsigned int>(m_frame[start + 1]) << endl;
    cout << "  Dest UID       : " << response->DestinationUID() << endl;
    cout << "  Source UID     : " << response->SourceUID() << endl;
    cout << "  Transaction #  : " << std::dec <<
      static_cast<unsigned int>(response->TransactionNumber()) << endl;
    cout << "  Response Type  : ";
    switch (response->ResponseType()) {
      case ola::rdm::RDM_ACK:
        cout << "ACK";
        break;
      case ola::rdm::RDM_ACK_TIMER:
        cout << "ACK TIMER";
        break;
      case ola::rdm::RDM_NACK_REASON:
        if (length >= 26) {
          uint16_t reason;
          memcpy(reinterpret_cast<uint8_t*>(&reason),
                 reinterpret_cast<const void*>(&m_frame[start + 23]),
                 sizeof(reason));
          reason = ola::network::NetworkToHost(reason);
          cout << "NACK (" << ola::rdm::NackReasonToString(reason) << ")";
        } else {
          cout << "Malformed NACK ";
        }
        break;
      case ola::rdm::ACK_OVERFLOW:
        cout << "ACK OVERFLOW";
        break;
      default:
        cout << "Unknown (" << response->ResponseType() << ")";
    }
    cout  << endl;
    cout << "  Message count  : " << std::dec <<
      static_cast<unsigned int>(response->MessageCount()) << endl;
    cout << "  Sub device     : " << std::dec << response->SubDevice() << endl;
    cout << "  Command class  : " << (is_get ? "GET_RESPONSE" : "SET_RESPONSE")
      << endl;

    cout << "  Param ID       : 0x" << std::setfill('0') << std::setw(4) <<
      std::hex << response->ParamId();
    if (descriptor)
      cout << " (" << descriptor->Name() << ")";
    cout << endl;
    cout << "  Param data len : " << std::dec << response->ParamDataSize() <<
      endl;
    DisplayParamData(descriptor,
                     is_get,
                     response->ParamData(),
                     response->ParamDataSize());
  }
}
Example #7
0
/**
 * Build a RDM Request from the options provided and send it to the daemon.
 */
int RDMController::PerformRequestAndWait(unsigned int universe,
                                         const UID &uid,
                                         uint16_t sub_device,
                                         const string &pid_name,
                                         bool is_set,
                                         const vector<string> &inputs) {
  // get the pid descriptor
  const ola::rdm::PidDescriptor *pid_descriptor = m_pid_helper.GetDescriptor(
      pid_name,
      uid.ManufacturerId());

  uint16_t pid_value;
  if (!pid_descriptor &&
      (ola::PrefixedHexStringToInt(pid_name, &pid_value) ||
       ola::StringToInt(pid_name, &pid_value))) {
    pid_descriptor = m_pid_helper.GetDescriptor(
        pid_value,
        uid.ManufacturerId());
  }

  if (!pid_descriptor) {
    cout << "Unknown PID: " << pid_name << endl;
    cout << "Use --list-pids to list the available PIDs." << endl;
    return ola::EXIT_USAGE;
  }

  const ola::messaging::Descriptor *descriptor = NULL;
  if (is_set)
    descriptor = pid_descriptor->SetRequest();
  else
    descriptor = pid_descriptor->GetRequest();

  if (!descriptor) {
    cout << (is_set ? "SET" : "GET") << " command not supported for "
      << pid_name << endl;
    exit(ola::EXIT_USAGE);
  }

  // attempt to build the message
  auto_ptr<const ola::messaging::Message> message(m_pid_helper.BuildMessage(
      descriptor,
      inputs));

  if (!message.get()) {
    cout << m_pid_helper.SchemaAsString(descriptor);
    return ola::EXIT_USAGE;
  }

  m_pending_request.universe = universe;
  m_pending_request.uid = &uid;
  m_pending_request.sub_device = sub_device;
  m_pending_request.pid_value = pid_descriptor->Value();

  unsigned int param_data_length;
  const uint8_t *param_data = m_pid_helper.SerializeMessage(
      message.get(),
      &param_data_length);

  if (is_set) {
    m_ola_client.GetClient()->RDMSet(
      ola::NewSingleCallback(this, &RDMController::HandleResponse),
      m_pending_request.universe,
      *m_pending_request.uid,
      m_pending_request.sub_device,
      pid_descriptor->Value(),
      param_data,
      param_data_length);
  } else {
    m_ola_client.GetClient()->RDMGet(
      ola::NewSingleCallback(this, &RDMController::HandleResponse),
      m_pending_request.universe,
      *m_pending_request.uid,
      m_pending_request.sub_device,
      pid_descriptor->Value(),
      param_data,
      param_data_length);
  }

  m_ola_client.GetSelectServer()->Run();
  return ola::EXIT_OK;
}
Example #8
0
bool RDMController::InitPidHelper() {
  return m_pid_helper.Init();
}