예제 #1
0
bool emAfPluginCommsHubFunctionTunnelSendData(EmberEUI64 remoteDeviceId,
                                                 uint16_t headerLen,
                                                 uint8_t *header,
                                                 uint16_t dataLen,
                                                 uint8_t *data)
{
  EmberAfStatus status = EMBER_ZCL_STATUS_FAILURE;
  bool success;
  uint8_t tunnelIndex;

  emberAfDebugPrint("CHF: TunnelSendData ");
  emberAfDebugDebugExec(emberAfPrintBigEndianEui64(remoteDeviceId));
  emberAfDebugPrint(" [");
  emberAfDebugPrintBuffer(header, headerLen, false);
  emberAfDebugPrintBuffer(data, dataLen, false);
  emberAfDebugPrintln("]");

  tunnelIndex = findTunnelByDeviceId(remoteDeviceId);
  if (tunnelIndex != EM_AF_PLUGIN_COMMS_HUB_FUNCTION_NULL_TUNNEL_INDEX) {
    if (tunnels[tunnelIndex].state == ACTIVE_TUNNEL) {
      // Add the header to the output buffers to that we don't copy data twice
      if (headerLen > 0) {
        MEMCOPY(message, header, headerLen);
        MEMCOPY(message+headerLen, data, dataLen);
        data = message;
        dataLen += headerLen;
      }
      status = (tunnels[tunnelIndex].type == CLIENT_TUNNEL)
        ? emberAfPluginTunnelingClientTransferData(tunnels[tunnelIndex].tunnelId, data, dataLen)
        : emberAfPluginTunnelingServerTransferData(tunnels[tunnelIndex].tunnelId, data, dataLen);
    } else if (tunnels[tunnelIndex].state == CLOSED_TUNNEL) {
      // we'll return failure to this message but we'll start the process
      // of bring up the tunnel so that if the message is resent the tunnel
      // should be up.
      emberAfPluginCommsHubFunctionPrintln("Tunnel Closed: New tunnel is requested for the device.");
      requestTunnel(tunnelIndex);
    }
  }

  success = (status == EMBER_ZCL_STATUS_SUCCESS);
  if (!success) {
    emberAfPluginCommsHubFunctionPrintln("%p%p%p0x%x",
                                         "Error: ",
                                         "Tunnel SendData failed: ",
                                         "Tunneling Status: ",
                                         status);

  }
  return success;
}
예제 #2
0
bool emAfPluginCommsHubFunctionTunnelDestroy(EmberEUI64 remoteDeviceId)
{
  EmberAfStatus status = EMBER_ZCL_STATUS_NOT_FOUND;
  uint8_t tunnelIndex;

  emberAfDebugPrint("CHF: TunnelDestroy ");
  emberAfDebugDebugExec(emberAfPrintBigEndianEui64(remoteDeviceId));
  emberAfDebugPrintln("");

  tunnelIndex = findTunnelByDeviceId(remoteDeviceId);
  if (tunnelIndex < EMBER_AF_PLUGIN_COMMS_HUB_FUNCTION_TUNNEL_LIMIT) {
    status = (tunnels[tunnelIndex].type == CLIENT_TUNNEL)
        ? emberAfPluginTunnelingClientCloseTunnel(tunnels[tunnelIndex].tunnelId)
        : EMBER_ZCL_STATUS_SUCCESS;
    if (status == EMBER_ZCL_STATUS_SUCCESS) {
      tunnels[tunnelIndex].state = UNUSED_TUNNEL;
      if (tunnelIndex == responsePendingIndex) {
        responsePendingIndex = EM_AF_PLUGIN_COMMS_HUB_FUNCTION_NULL_TUNNEL_INDEX;
        // let the tunnel event handler retry any pending create requests
        emberEventControlSetActive(emberAfPluginCommsHubFunctionTunnelEventControl);
      }
    }
  }
  return (status == EMBER_ZCL_STATUS_SUCCESS);
}
EmberStatus SimpleCommissioningStart(uint8_t endpoint, bool is_server,
                                     const uint16_t *clusters, uint8_t length) {
  if (!clusters || !length) {
    // meaningless call if ClusterID array was not passed or its length
    // is zero
    return EMBER_BAD_ARGUMENT;
  }
  emberAfDebugPrintln("DEBUG: Call for starting commissioning");
  if (length > emberBindingTableSize) {
    // passed more clusters than the binding table may handle
    // TODO: may be it is worth to track available entries to write in
    // the binding table
    emberAfDebugPrint("Warning: ask for bind 0x%X clusters. ", length);
    emberAfDebugPrintln("Binding table size is 0x%X", emberBindingTableSize);
  }
  if (CommissioningStateMachineStatus() != SC_EZ_STOP) {
    // quite implicit, but if our state machine runs then network
    // probably busy
    return EMBER_NETWORK_BUSY;
  }

  InitDeviceCommissionInfo(&dev_comm_session, endpoint, is_server, clusters,
                           length);
  // Wake up our state machine
  emberEventControlSetActive(StateMachineEvent);

  return EMBER_SUCCESS;
}
/*! Callback for IEEE address Request */
static void ProcessEUI64Discovery(const EmberAfServiceDiscoveryResult *result) {
  if (emberAfHaveDiscoveryResponseStatus(result->status)) {
    MatchDescriptorReq_t *in_dev = GetTopInDeviceDescriptor();
    assert(in_dev != NULL);
    SetInConnEUI64Address((const uint8_t *)result->responseData);
    emberAfDebugPrint("DEBUG: EUI64 ");
    emberAfPrintLittleEndianEui64(in_dev->source_eui64);
    emberAfDebugPrintln("");
    SetNextEvent(SC_EZEV_BIND);
  }

  emberEventControlSetActive(StateMachineEvent);
}
예제 #5
0
/** @brief Data Received
 *
 * This function is called by the Tunneling server plugin whenever data is
 * received from a client through a tunnel.
 *
 * @param tunnelId The identifier of the tunnel through which the data was
 * received.  Ver.: always
 * @param data Buffer containing the raw octets of the data.  Ver.: always
 * @param dataLen The length in octets of the data.  Ver.: always
 */
void emberAfPluginTunnelingServerDataReceivedCallback(uint16_t tunnelId,
                                                      uint8_t * data,
                                                      uint16_t dataLen)
{
  uint8_t tunnelIndex;
  emberAfDebugPrint("CHF: ServerDataReceived:%x,[", tunnelId);
  emberAfDebugPrintBuffer(data, dataLen, false);
  emberAfDebugPrintln("]");

  tunnelIndex = findTunnelByTunnelId(tunnelId, SERVER_TUNNEL);
  if (tunnelIndex != EM_AF_PLUGIN_COMMS_HUB_FUNCTION_NULL_TUNNEL_INDEX) {
    emAfPluginCommsHubFunctionTunnelDataReceivedCallback(tunnels[tunnelIndex].remoteDeviceId,
                                                         dataLen,
                                                         data);
  }
}
예제 #6
0
void emAfPluginCommsHubFunctionTunnelCleanup(EmberEUI64 remoteDeviceId)
{
  uint8_t tunnelIndex;

  tunnelIndex = findTunnelByDeviceId(remoteDeviceId);
  if (tunnelIndex < EMBER_AF_PLUGIN_COMMS_HUB_FUNCTION_TUNNEL_LIMIT) {
    emberAfDebugPrint("CHF: TunnelCleanup ");
    emberAfDebugDebugExec(emberAfPrintBigEndianEui64(remoteDeviceId));
    emberAfDebugPrintln("");

    if (tunnels[tunnelIndex].type == CLIENT_TUNNEL) {
      emberAfPluginTunnelingClientCleanup(tunnels[tunnelIndex].tunnelId);
    } else {
      emberAfPluginTunnelingServerCleanup(tunnels[tunnelIndex].tunnelId);
    }
    tunnels[tunnelIndex].state = UNUSED_TUNNEL;
  }
}
예제 #7
0
// This should be called after CBKE.
bool emAfPluginCommsHubFunctionTunnelCreate(EmberEUI64 remoteDeviceId,
                                               uint8_t remoteEndpoint)
{
  uint8_t tunnelIndex;
  emberAfDebugPrint("CHF: TunnelCreate ");
  emberAfDebugDebugExec(emberAfPrintBigEndianEui64(remoteDeviceId));
  emberAfDebugPrintln(" 0x%x", remoteEndpoint);

  // We only support one tunnel to a given remote device/endpoint so if we
  // already have a tunnel lets work with it.
  tunnelIndex = findTunnelByDeviceId(remoteDeviceId);
  if (tunnelIndex != EM_AF_PLUGIN_COMMS_HUB_FUNCTION_NULL_TUNNEL_INDEX) {
    if (tunnels[tunnelIndex].state == CLOSED_TUNNEL) {
      return requestTunnel(tunnelIndex);
    }
    return true;
  }

  // Find a slot in the tunnels table for the new tunnel
  tunnelIndex = findUnusedTunnel();
  if (tunnelIndex != EM_AF_PLUGIN_COMMS_HUB_FUNCTION_NULL_TUNNEL_INDEX) {
    MEMCOPY(tunnels[tunnelIndex].remoteDeviceId, remoteDeviceId, EUI64_SIZE);
    tunnels[tunnelIndex].remoteNodeId = emberLookupNodeIdByEui64(remoteDeviceId);
    tunnels[tunnelIndex].remoteEndpoint = remoteEndpoint;
    tunnels[tunnelIndex].type = CLIENT_TUNNEL;
    tunnels[tunnelIndex].state = CLOSED_TUNNEL;
    tunnels[tunnelIndex].tunnelId = 0xFF;
    tunnels[tunnelIndex].timeoutMSec = 0;
    return requestTunnel(tunnelIndex);
  }

  // This is a misconfiguration or a bug in the code calling this API. Either
  // the tunnel client plugin limit is set too low for the number of tunnels
  // required or the code that is calling this function is in error.  Either way,
  // we'll print the error and return false indicating that the tunnel was
  // not created.
  emberAfPluginCommsHubFunctionPrintln("%p%p%p",
                                       "Error: ",
                                       "Tunnel Create failed: ",
                                       "Too many tunnels");
  return false;
}