Example #1
0
// Cluster: Messaging, server
EmberAfStatus emberAfMessagingClusterServerCommandParse(EmberAfClusterCommand *cmd)
{
  boolean wasHandled = FALSE;
  if (!cmd->mfgSpecific) {
    switch (cmd->commandId) {
    case ZCL_GET_LAST_MESSAGE_COMMAND_ID:
      {
        // Command is fixed length: 0
        wasHandled = emberAfMessagingClusterGetLastMessageCallback();
        break;
      }
    case ZCL_MESSAGE_CONFIRMATION_COMMAND_ID:
      {
        int16u payloadOffset = cmd->payloadStartIndex;
        int32u messageId;  // Ver.: always
        int32u confirmationTime;  // Ver.: always
        int8u messageConfirmationControl;  // Ver.: since se-1.2a-14-0256-03
        int8u* messageResponse;  // Ver.: since se-1.2a-14-0256-03
        // Command is not a fixed length
        if (cmd->bufLen < payloadOffset + 4) return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
        messageId = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 4;
        if (cmd->bufLen < payloadOffset + 4) return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
        confirmationTime = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 4;
        if ( ( cmd->bufLen < payloadOffset + 1)) {
          // Argument is not always present:
          // - it is present only in versions higher than: se-1.2a-14-0256-03
          messageConfirmationControl = 0xFF;
        } else {
          messageConfirmationControl = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen);
          payloadOffset += 1;
        }
        if ( ( cmd->bufLen < payloadOffset + emberAfStringLength(cmd->buffer + payloadOffset) + 1)) {
          // Argument is not always present:
          // - it is present only in versions higher than: se-1.2a-14-0256-03
          messageResponse = NULL;
        } else {
          messageResponse = emberAfGetString(cmd->buffer, payloadOffset, cmd->bufLen);
        }
        wasHandled = emberAfMessagingClusterMessageConfirmationCallback(messageId,
                                                                        confirmationTime,
                                                                        messageConfirmationControl,
                                                                        messageResponse);
        break;
      }
    }
  }
  return status(wasHandled, cmd->mfgSpecific);
}
Example #2
0
bool emberAfEventsClusterPublishEventLogCallback(uint16_t totalNumberOfEvents,
                                                    uint8_t commandIndex,
                                                    uint8_t totalCommands,
                                                    uint8_t logPayloadControl,
                                                    uint8_t* logPayload)
{
  emberAfEventsClusterPrint("RX: PublishEventLog 0x%2x, 0x%x, 0x%x, 0x%x",
                            totalNumberOfEvents,
                            commandIndex,
                            totalCommands,
                            logPayloadControl);

  #if defined(EMBER_AF_PRINT_ENABLE) && defined(EMBER_AF_PRINT_EVENTS_CLUSTER)
  uint16_t logPayloadLen = (emberAfCurrentCommand()->bufLen
                          - (emberAfCurrentCommand()->payloadStartIndex
                             + sizeof(totalNumberOfEvents)
                             + sizeof(commandIndex)
                             + sizeof(totalCommands)
                             + sizeof(logPayloadControl)));
  uint16_t logPayloadIndex = 0;
  uint8_t i;
  if (NULL != logPayload) {
    for (i = 0; i < numberOfEvents(logPayloadControl); i++) {
      uint8_t logId;
      uint16_t eventId;
      uint32_t eventTime;
      uint8_t *eventData;
      uint8_t eventDataLen;
      logId = emberAfGetInt8u(logPayload, logPayloadIndex, logPayloadLen);
      logPayloadIndex++;
      eventId = emberAfGetInt16u(logPayload, logPayloadIndex, logPayloadLen);
      logPayloadIndex += 2;
      eventTime = emberAfGetInt32u(logPayload, logPayloadIndex, logPayloadLen);
      logPayloadIndex += 4;
      eventData = logPayload + logPayloadIndex;
      eventDataLen = emberAfGetInt8u(logPayload, logPayloadIndex, logPayloadLen);
      logPayloadIndex += (1 + eventDataLen);
      emberAfEventsClusterPrint(" [");
      emberAfEventsClusterPrint("0x%x, 0x%2x, 0x%4x, 0x%x", logId, eventId, eventTime, eventDataLen);
      if (eventDataLen > 0) {
        emberAfEventsClusterPrint(", ");
        emberAfEventsClusterPrintString(eventData);
      }
      emberAfEventsClusterPrint("]");
    }
  }
  emberAfEventsClusterPrintln("");
#endif // defined(EMBER_AF_PRINT_ENABLE) && defined(EMBER_AF_PRINT_EVENTS_CLUSTER)

  emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
  return true;
}
bool emberAfPluginInterpanPreMessageReceivedCallback(const EmberAfInterpanHeader *header,
                                                        uint8_t msgLen,
                                                        uint8_t *message)
{
  uint32_t transaction;
  uint8_t frameControl, commandId, msgIndex;

  // If the message isn't for the ZLL Commissioning cluster, drop it with an
  // indication that we didn't handle it.  After this, everything else will be
  // considered handled so that the message doesn't end up going through the
  // normal ZCL processing.
  if (header->profileId != EMBER_ZLL_PROFILE_ID
      || header->clusterId != ZCL_ZLL_COMMISSIONING_CLUSTER_ID) {
    return false;
  }

  if (header->messageType != EMBER_AF_INTER_PAN_UNICAST
      || !(header->options & EMBER_AF_INTERPAN_OPTION_MAC_HAS_LONG_ADDRESS)
      || msgLen < ZLL_HEADER_OVERHEAD) {
    return true;
  }

  // Verify that the frame control byte makes sense.  Accept only the legacy
  // format or simple client-to-server or server-to-client messages (i.e., no
  // manufacturer-specific commands, etc.)  For non-legacy messages, check that
  // the frame control is correct for the command.  The check is based on
  // DeviceInformationResponse because it is the only server-to-client command
  // we care about.
  frameControl = message[ZLL_HEADER_FRAME_CONTROL_OFFSET];
  commandId = message[ZLL_HEADER_COMMAND_ID_OFFSET];
  if (frameControl != ZLL_FRAME_CONTROL_LEGACY
      && (frameControl != ZLL_FRAME_CONTROL_CLIENT_TO_SERVER
          || commandId == ZCL_DEVICE_INFORMATION_RESPONSE_COMMAND_ID)
      && (frameControl != ZLL_FRAME_CONTROL_SERVER_TO_CLIENT
          || commandId != ZCL_DEVICE_INFORMATION_RESPONSE_COMMAND_ID)) {
    return true;
  }

  msgIndex = ZLL_HEADER_TRANSACTION_ID_OFFSET;
  transaction = emberAfGetInt32u(message, msgIndex, msgLen);
  msgIndex += 4;

  switch (commandId) {
  case ZCL_DEVICE_INFORMATION_REQUEST_COMMAND_ID:
    if (msgIndex + 1 <= msgLen) {
      uint8_t startIndex = emberAfGetInt8u(message, msgIndex, msgLen);
      deviceInformationRequestHandler(header->longAddress,
                                      transaction,
                                      startIndex);
    }
    break;
#ifdef EMBER_AF_PLUGIN_ZLL_COMMISSIONING_LINK_INITIATOR
  case ZCL_DEVICE_INFORMATION_RESPONSE_COMMAND_ID:
    if (msgIndex + 3 <= msgLen) {
      uint8_t numberOfSubDevices, startIndex, deviceInformationRecordCount;
      numberOfSubDevices = emberAfGetInt8u(message, msgIndex, msgLen);
      msgIndex++;
      startIndex = emberAfGetInt8u(message, msgIndex, msgLen);
      msgIndex++;
      deviceInformationRecordCount = emberAfGetInt8u(message, msgIndex, msgLen);
      msgIndex++;
      if ((msgIndex
           + deviceInformationRecordCount * ZLL_DEVICE_INFORMATION_RECORD_SIZE)
          <= msgLen) {
        uint8_t *deviceInformationRecordList = message + msgIndex;
        deviceInformationResponseHandler(header->longAddress,
                                         transaction,
                                         numberOfSubDevices,
                                         startIndex,
                                         deviceInformationRecordCount,
                                         deviceInformationRecordList);
      }
    }
    break;
#endif //EMBER_AF_PLUGIN_ZLL_COMMISSIONING_LINK_INITIATOR
  case ZCL_IDENTIFY_REQUEST_COMMAND_ID:
    if (msgIndex + 2 <= msgLen) {
      uint16_t identifyDurationS = emberAfGetInt16u(message, msgIndex, msgLen);
      identifyRequestHandler(header->longAddress,
                             transaction,
                             identifyDurationS);
    }
    break;
  case ZCL_RESET_TO_FACTORY_NEW_REQUEST_COMMAND_ID:
    resetToFactoryNewRequestHandler(header->longAddress, transaction);
    break;
  }

  // All ZLL Commissioning cluster messages are considered handled, even if we
  // ended up dropping them because they were malformed, etc.
  return true;
}
Example #4
0
// Cluster: Price, server
EmberAfStatus emberAfPriceClusterServerCommandParse(EmberAfClusterCommand *cmd)
{
  boolean wasHandled = FALSE;
  if (!cmd->mfgSpecific) {
    switch (cmd->commandId) {
    case ZCL_GET_CURRENT_PRICE_COMMAND_ID:
      {
        int16u payloadOffset = cmd->payloadStartIndex;
        int8u commandOptions;  // Ver.: always
        // Command is fixed length: 1
        if (cmd->bufLen < payloadOffset + 1) return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
        commandOptions = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen);
        wasHandled = emberAfPriceClusterGetCurrentPriceCallback(commandOptions);
        break;
      }
    case ZCL_GET_SCHEDULED_PRICES_COMMAND_ID:
      {
        int16u payloadOffset = cmd->payloadStartIndex;
        int32u startTime;  // Ver.: always
        int8u numberOfEvents;  // Ver.: always
        // Command is fixed length: 5
        if (cmd->bufLen < payloadOffset + 5) return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
        startTime = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 4;
        numberOfEvents = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen);
        wasHandled = emberAfPriceClusterGetScheduledPricesCallback(startTime,
                                                                   numberOfEvents);
        break;
      }
    case ZCL_GET_TARIFF_INFORMATION_COMMAND_ID:
      {
        int16u payloadOffset = cmd->payloadStartIndex;
        int32u earliestStartTime;  // Ver.: always
        int32u minIssuerEventId;  // Ver.: always
        int8u numberOfCommands;  // Ver.: always
        int8u tariffType;  // Ver.: always
        // Command is fixed length: 10
        if (cmd->bufLen < payloadOffset + 10) return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
        earliestStartTime = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 4;
        minIssuerEventId = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 4;
        numberOfCommands = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 1;
        tariffType = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen);
        wasHandled = emberAfPriceClusterGetTariffInformationCallback(earliestStartTime,
                                                                     minIssuerEventId,
                                                                     numberOfCommands,
                                                                     tariffType);
        break;
      }
    case ZCL_GET_PRICE_MATRIX_COMMAND_ID:
      {
        int16u payloadOffset = cmd->payloadStartIndex;
        int32u issuerTariffId;  // Ver.: always
        // Command is fixed length: 4
        if (cmd->bufLen < payloadOffset + 4) return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
        issuerTariffId = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
        wasHandled = emberAfPriceClusterGetPriceMatrixCallback(issuerTariffId);
        break;
      }
    }
  }
  return status(wasHandled, cmd->mfgSpecific);
}
Example #5
0
// Cluster: Simple Metering, server
EmberAfStatus emberAfSimpleMeteringClusterServerCommandParse(EmberAfClusterCommand *cmd)
{
  boolean wasHandled = FALSE;
  if (!cmd->mfgSpecific) {
    switch (cmd->commandId) {
    case ZCL_GET_PROFILE_COMMAND_ID:
      {
        int16u payloadOffset = cmd->payloadStartIndex;
        int8u intervalChannel;  // Ver.: always
        int32u endTime;  // Ver.: always
        int8u numberOfPeriods;  // Ver.: always
        // Command is fixed length: 6
        if (cmd->bufLen < payloadOffset + 6) return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
        intervalChannel = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 1;
        endTime = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 4;
        numberOfPeriods = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen);
        wasHandled = emberAfSimpleMeteringClusterGetProfileCallback(intervalChannel,
                                                                    endTime,
                                                                    numberOfPeriods);
        break;
      }
    case ZCL_REQUEST_FAST_POLL_MODE_COMMAND_ID:
      {
        int16u payloadOffset = cmd->payloadStartIndex;
        int8u fastPollUpdatePeriod;  // Ver.: always
        int8u duration;  // Ver.: always
        // Command is fixed length: 2
        if (cmd->bufLen < payloadOffset + 2) return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
        fastPollUpdatePeriod = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 1;
        duration = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen);
        wasHandled = emberAfSimpleMeteringClusterRequestFastPollModeCallback(fastPollUpdatePeriod,
                                                                             duration);
        break;
      }
    case ZCL_SCHEDULE_SNAPSHOT_COMMAND_ID:
      {
        int16u payloadOffset = cmd->payloadStartIndex;
        int32u issuerEventId;  // Ver.: always
        int8u commandIndex;  // Ver.: always
        int8u commandCount;  // Ver.: always
        int8u* snapshotSchedulePayload;  // Ver.: always
        // Command is fixed length: 6
        if (cmd->bufLen < payloadOffset + 6) return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
        issuerEventId = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 4;
        commandIndex = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 1;
        commandCount = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 1;
        snapshotSchedulePayload = cmd->buffer + payloadOffset;
        wasHandled = emberAfSimpleMeteringClusterScheduleSnapshotCallback(issuerEventId,
                                                                          commandIndex,
                                                                          commandCount,
                                                                          snapshotSchedulePayload);
        break;
      }
    case ZCL_TAKE_SNAPSHOT_COMMAND_ID:
      {
        int16u payloadOffset = cmd->payloadStartIndex;
        int32u snapshotCause;  // Ver.: always
        // Command is fixed length: 4
        if (cmd->bufLen < payloadOffset + 4) return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
        snapshotCause = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
        wasHandled = emberAfSimpleMeteringClusterTakeSnapshotCallback(snapshotCause);
        break;
      }
    case ZCL_GET_SNAPSHOT_COMMAND_ID:
      {
        int16u payloadOffset = cmd->payloadStartIndex;
        int32u earliestStartTime;  // Ver.: always
        int32u latestEndTime;  // Ver.: always
        int8u snapshotOffset;  // Ver.: always
        int32u snapshotCause;  // Ver.: always
        // Command is fixed length: 13
        if (cmd->bufLen < payloadOffset + 13) return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
        earliestStartTime = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 4;
        latestEndTime = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 4;
        snapshotOffset = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 1;
        snapshotCause = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
        wasHandled = emberAfSimpleMeteringClusterGetSnapshotCallback(earliestStartTime,
                                                                     latestEndTime,
                                                                     snapshotOffset,
                                                                     snapshotCause);
        break;
      }
    }
  }
  return status(wasHandled, cmd->mfgSpecific);
}
Example #6
0
// Cluster: Simple Metering, client
EmberAfStatus emberAfSimpleMeteringClusterClientCommandParse(EmberAfClusterCommand *cmd)
{
  boolean wasHandled = FALSE;
  if (!cmd->mfgSpecific) {
    switch (cmd->commandId) {
    case ZCL_GET_PROFILE_RESPONSE_COMMAND_ID:
      {
        int16u payloadOffset = cmd->payloadStartIndex;
        int32u endTime;  // Ver.: always
        int8u status;  // Ver.: always
        int8u profileIntervalPeriod;  // Ver.: always
        int8u numberOfPeriodsDelivered;  // Ver.: always
        int8u* intervals;  // Ver.: always
        // Command is fixed length: 7
        if (cmd->bufLen < payloadOffset + 7) return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
        endTime = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 4;
        status = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 1;
        profileIntervalPeriod = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 1;
        numberOfPeriodsDelivered = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 1;
        intervals = cmd->buffer + payloadOffset;
        wasHandled = emberAfSimpleMeteringClusterGetProfileResponseCallback(endTime,
                                                                            status,
                                                                            profileIntervalPeriod,
                                                                            numberOfPeriodsDelivered,
                                                                            intervals);
        break;
      }
    case ZCL_REQUEST_MIRROR_COMMAND_ID:
      {
        // Command is fixed length: 0
        wasHandled = emberAfSimpleMeteringClusterRequestMirrorCallback();
        break;
      }
    case ZCL_REMOVE_MIRROR_COMMAND_ID:
      {
        // Command is fixed length: 0
        wasHandled = emberAfSimpleMeteringClusterRemoveMirrorCallback();
        break;
      }
    case ZCL_REQUEST_FAST_POLL_MODE_RESPONSE_COMMAND_ID:
      {
        int16u payloadOffset = cmd->payloadStartIndex;
        int8u appliedUpdatePeriod;  // Ver.: always
        int32u fastPollModeEndtime;  // Ver.: always
        // Command is fixed length: 5
        if (cmd->bufLen < payloadOffset + 5) return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
        appliedUpdatePeriod = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 1;
        fastPollModeEndtime = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
        wasHandled = emberAfSimpleMeteringClusterRequestFastPollModeResponseCallback(appliedUpdatePeriod,
                                                                                     fastPollModeEndtime);
        break;
      }
    case ZCL_CONFIGURE_MIRROR_COMMAND_ID:
      {
        int16u payloadOffset = cmd->payloadStartIndex;
        int32u issuerEventId;  // Ver.: always
        int32u reportingInterval;  // Ver.: always
        int8u mirrorNotificationReporting;  // Ver.: always
        int8u notificationScheme;  // Ver.: always
        // Command is fixed length: 9
        if (cmd->bufLen < payloadOffset + 9) return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
        issuerEventId = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 4;
        reportingInterval = emberAfGetInt24u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 3;
        mirrorNotificationReporting = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen);
        payloadOffset += 1;
        notificationScheme = emberAfGetInt8u(cmd->buffer, payloadOffset, cmd->bufLen);
        wasHandled = emberAfSimpleMeteringClusterConfigureMirrorCallback(issuerEventId,
                                                                         reportingInterval,
                                                                         mirrorNotificationReporting,
                                                                         notificationScheme);
        break;
      }
    }
  }
  return status(wasHandled, cmd->mfgSpecific);
}