static CommissioningState_t SetBinding(void) {
  emberAfDebugPrintln("DEBUG: Set Binding");
  MatchDescriptorReq_t *in_dev = GetTopInDeviceDescriptor();
  assert(in_dev != NULL);
  // init clusters skip mask length for checking for duplicates in the binding
  // table
  InitRemoteSkipCluster(in_dev->source_cl_arr_len);
  // check the supported clusters list for existence in the binding table
  MarkDuplicateMatches(in_dev);
  // nothing to do if we unmarked all clusters
  if (GetRemoteSkipMask() == 0) {
    SetNextEvent(SC_EZEV_CHECK_QUEUE);
    emberEventControlSetActive(StateMachineEvent);
  } else if (CreateBindings(in_dev)) {
    // Create bindings for supported clusters
    SetNextEvent(SC_EZEV_BINDING_DONE);
  } else {
    SetNextEvent(SC_EZEV_CHECK_QUEUE);
  }

  PopInDeviceDescriptor();
  emberAfDebugPrintln("DEBUG: Supported clusters mask 0x%X",
                      skip_mask.skip_clusters);
  emberEventControlSetActive(StateMachineEvent);

  return SC_EZ_BIND;
}
Esempio n. 2
0
// See if we can recover from tunnel creation issues.
static bool handleRequestTunnelFailure(uint8_t tunnelIndex, EmberAfPluginTunnelingClientStatus status)
{
  uint8_t i;

  emberAfDebugPrintln("CHF: handleRequestTunnelFailure 0x%x, 0x%x",
                      tunnelIndex, status);

  if (status == EMBER_AF_PLUGIN_TUNNELING_CLIENT_BUSY) {
    // Per GBCS send another request 3 minutes from now
    tunnels[tunnelIndex].state = REQUEST_PENDING_TUNNEL;
    tunnels[tunnelIndex].timeoutMSec = halCommonGetInt32uMillisecondTick() +
        (MILLISECOND_TICKS_PER_SECOND * 180);
    emberEventControlSetActive(emberAfPluginCommsHubFunctionTunnelEventControl);
    emberAfPluginCommsHubFunctionPrintln("CHF: Busy status received from node ID 0x%2x",tunnels[tunnelIndex].remoteNodeId);
    return true;
  } else if (status == EMBER_AF_PLUGIN_TUNNELING_CLIENT_NO_MORE_TUNNEL_IDS) {
    // Per GBCS close any other tunnels we may have with the device
    // and once all responses are received try the RequestTunnel again
    bool retryRequest = false;
    for (i = 0; i < EMBER_AF_PLUGIN_COMMS_HUB_FUNCTION_TUNNEL_LIMIT; i++) {
      if (i != tunnelIndex && tunnels[i].remoteNodeId == tunnels[tunnelIndex].remoteNodeId) {
        retryRequest = true;
        emAfPluginCommsHubFunctionTunnelDestroy(tunnels[i].remoteDeviceId);
      }
    }
    if (retryRequest) {
      // We'll retry the request in the tunnel event handler so as to give the
      // tunnel(s) a chance to clean up.
      tunnels[tunnelIndex].state = REQUEST_PENDING_TUNNEL;
      tunnels[tunnelIndex].timeoutMSec = halCommonGetInt32uMillisecondTick() +
          (MILLISECOND_TICKS_PER_SECOND * 5);
      emberEventControlSetActive(emberAfPluginCommsHubFunctionTunnelEventControl);
      return true;
    }
    // no tunnels were closed so nothing more we can do
    emberAfPluginCommsHubFunctionPrintln("%p%p%p",
                                         "Error: ",
                                         "Tunnel Create failed: ",
                                         "No more tunnel ids");
    tunnels[tunnelIndex].state = CLOSED_TUNNEL;
    return false;
  }

  // All other errors are either due to mis-configuration or errors that we
  // cannot recover from so print the error and return false.
  emberAfPluginCommsHubFunctionPrintln("%p%p%p0x%x",
                                       "Error: ",
                                       "Tunnel Create failed: ",
                                       "Tunneling Client Status: ",
                                       status);
  tunnels[tunnelIndex].state = CLOSED_TUNNEL;
  return false;
}
static CommissioningState_t CheckNetwork(void) {
  emberAfDebugPrintln("DEBUG: Check Network state");
  EmberNetworkStatus nw_status = emberNetworkState();
  emberAfDebugPrintln("DEBUG: network state 0x%X", nw_status);
  if (nw_status == EMBER_JOINING_NETWORK ||
      nw_status == EMBER_LEAVING_NETWORK) {
    // Try to check again after 5 seconds
    emberEventControlSetDelayQS(StateMachineEvent,
                                SIMPLE_COMMISSIONING_NETWORK_RETRY_DELAY);

    return SC_EZ_START;
  }

  if (nw_status == EMBER_JOINED_NETWORK) {
    SetNextEvent(SC_EZEV_BCAST_IDENT_QUERY);
    // Send Permit Join broadcast to the current network
    // in case of ZED nothing will happen
    // TODO: Make this hadrcoded value as plugin's option
    emberAfPermitJoin(SIMPLE_COMMISSIONING_PERMIT_JOIN_TIME, TRUE);
  } else if (nw_status == EMBER_NO_NETWORK &&
             GetNetworkTries() < NETWORK_ACCESS_CONS_TRIES) {
    // Form or join available network
    SetNextEvent(SC_EZEV_FORM_JOIN_NETWORK);
  } else {
    SetNextEvent(SC_EZEV_NETWORK_FAILED);
  }

  // if the device is in the network continue commissioning
  // by sending Identify Query
  emberEventControlSetActive(StateMachineEvent);

  return SC_EZ_START;
}
Esempio n. 4
0
static bool requestTunnel(uint8_t tunnelIndex)
{
  EmberAfPluginTunnelingClientStatus status;

  // The tunneling cluster client code can only process one tunneling reuqest
  // at a time so if there's already on outstanding then mark this one pending
  // and let the tunnel event handler take care of the retry.
  if (responsePendingIndex != EM_AF_PLUGIN_COMMS_HUB_FUNCTION_NULL_TUNNEL_INDEX) {
    tunnels[tunnelIndex].state = REQUEST_PENDING_TUNNEL;
    tunnels[tunnelIndex].timeoutMSec = halCommonGetInt32uMillisecondTick();
    emberEventControlSetActive(emberAfPluginCommsHubFunctionTunnelEventControl);
    return true;
  }

  status = emberAfPluginTunnelingClientRequestTunnel(tunnels[tunnelIndex].remoteNodeId,
                                                     localTunnelEndpoint,
                                                     tunnels[tunnelIndex].remoteEndpoint,
                                                     GBCS_TUNNELING_PROTOCOL_ID,
                                                     GBCS_TUNNELING_MANUFACTURER_CODE,
                                                     GBCS_TUNNELING_FLOW_CONTROL_SUPPORT);
  if (status != EMBER_AF_PLUGIN_TUNNELING_CLIENT_SUCCESS
      && !handleRequestTunnelFailure(tunnelIndex, status)) {
    return false;
  }

  responsePendingIndex = tunnelIndex;
  tunnels[tunnelIndex].state = RESPONSE_PENDING_TUNNEL;
  return true;
}
/** @brief Identify Cluster Identify Query Response
 *
 *
 *
 * @param timeout   Ver.: always
 */
boolean emberAfIdentifyClusterIdentifyQueryResponseCallback(int16u timeout) {
  // TODO: !!! IMPORTANT !!! add  handling for several responses
  // now the state machine might be broken as we use only one global variable
  // for storing incoming connection information like Short ID and endpoint
  //
  // ignore broadcasts from yourself and from devices that are not
  // in the identifying state
  const EmberAfClusterCommand *const current_cmd = emberAfCurrentCommand();
  if (emberAfGetNodeId() != current_cmd->source && timeout != 0) {
    emberAfDebugPrintln("DEBUG: Got ID Query response");
    emberAfDebugPrintln("DEBUG: Sender 0x%2X", emberAfCurrentCommand()->source);
    // Queue is empty, so we can start commissioning process
    // otherwise we push it in the queue and will process later
    if (GetQueueSize() == 0) {
      // ID Query received -> go to the discover state for getting clusters info
      emberAfDebugPrintln("DEBUG: QUEUE IS EMPTY");
      SetNextState(SC_EZ_DISCOVER);
      SetNextEvent(SC_EZEV_CHECK_CLUSTERS);
      emberEventControlSetActive(StateMachineEvent);
    }
    // Store information about endpoint and short ID of the incoming response
    // for further processing in the Matching (SC_EZ_MATCH) state
    SetInConnBaseInfo(current_cmd->source,
                      current_cmd->apsFrame->sourceEndpoint);
    emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
  }

  return TRUE;
}
Esempio n. 6
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;
}
static void rescheduleUserControlEvent(void)
{
  // Look at all the active records and figure out when to schedule the event.
  // If any record should have been sent in the past, we immediately schedule
  // the event to send it as soon as possible.  Otherwise, we find the record
  // that has to be repeated soonest and schedule based on that.  If there are
  // no active records, we are done and cancel the event.
  uint16_t nowMs = halCommonGetInt16uMillisecondTick();
  uint16_t delayMs = MAX_INT16U_VALUE;
  uint8_t i;
  for (i = 0; i < COUNTOF(records); i++) {
    if (records[i].pairingIndex != 0xFF) {
      if (timeGTorEqualInt16u(nowMs, records[i].timeMs)) {
        delayMs = 0;
        break;
      } else {
        uint16_t remainingMs = elapsedTimeInt16u(nowMs, records[i].timeMs);
        if (remainingMs < delayMs) {
          delayMs = remainingMs;
        }
      }
    }
  }
  if (delayMs == MAX_INT16U_VALUE) {
    emberEventControlSetInactive(emberAfPluginRf4ceZrc11OutgoingUserControlEventControl);
  } else if (delayMs == 0) {
    emberEventControlSetActive(emberAfPluginRf4ceZrc11OutgoingUserControlEventControl);
  } else {
    emberEventControlSetDelayMS(emberAfPluginRf4ceZrc11OutgoingUserControlEventControl,
                                delayMs);
  }
}
Esempio n. 9
0
// ****** CLI Command helpers (public APIs) ******
void emberAfPluginLowVoltageShutdownEnable(bool enable)
{
  if (enable) {
    emberEventControlSetActive(myEvent);
  } else {
    emberEventControlSetInactive(myEvent);
  }
}
static CommissioningState_t BindingDone(void) {
  emberAfDebugPrintln("DEBUG: Binding Done");
  // as we've processed the current remote device delete it from the queue
  SetNextEvent(SC_EZEV_CHECK_QUEUE);
  emberEventControlSetActive(StateMachineEvent);

  return SC_EZ_BIND;
}
Esempio n. 11
0
// Hal Button ISR Callback
// This callback is called by the framework whenever a button is pressed on the
// device. This callback is called within ISR context.
void emberAfHalButtonIsrCallback(int8u button, int8u state)
{
  if ((button == BUTTON0 || button == BUTTON1)
      && state == BUTTON_PRESSED
      && !emberEventControlGetActive(buttonEventControl)) {
    buttonPressTime = halCommonGetInt16uMillisecondTick();
    emberEventControlSetActive(buttonEventControl);
  }
}
Esempio n. 12
0
void networkEventHandler(void)
{
  if (emberAfRf4ceStart() == EMBER_SUCCESS) {
    emberEventControlSetInactive(networkEventControl);
    halPlayTune_P(waitTune, TRUE);
  } else {
    emberEventControlSetActive(networkEventControl);
    halPlayTune_P(sadTune, TRUE);
  }
}
static void scheduleEvent(bool withDelay)
{
  if (withDelay) {
    debugPrintln("%p scheduled event for %d qs", PLUGIN_NAME, DISCOVERY_DELAY_QS);
    emberEventControlSetDelayQS(emberAfPluginDeviceQueryServiceMyEventControl,
                                DISCOVERY_DELAY_QS);
  } else {
    emberEventControlSetActive(emberAfPluginDeviceQueryServiceMyEventControl);
  }
}
/** @brief Identify
 *
 * This function is called by the ZLL Commissioning plugin to notify the
 * application that it should take an action to identify itself.  This
 * typically occurs when an Identify Request is received via inter-PAN
 * messaging.
 *
 * @param durationS If the duration is zero, the device should exit identify
 * mode.  If the duration is 0xFFFF, the device should remain in identify mode
 * for the default time.  Otherwise, the duration specifies the length of time
 * in seconds that the device should remain in identify mode.  Ver.: always
 */
void emberAfPluginZllCommissioningIdentifyCallback(int16u durationS)
{
  if (durationS != 0) {
    halStackIndicatePresence();
  }
  identifyDurationMs = (durationS == 0xFFFF
                        ? DEFAULT_IDENTIFY_DURATION_MS
                        : durationS * MILLISECOND_TICKS_PER_SECOND);
  emberEventControlSetActive(identifyEventControl);
}
/*! State Machine handlers implementation */
static CommissioningState_t StartCommissioning(void) {
  emberAfDebugPrintln("DEBUG: Commissioning Start");
  // TODO: here we might add some sanity check like cluster existense
  // or something like that, but now just start commissioning process
  // init internal queue for processing several remote devices
  InitQueue();
  SetNextEvent(SC_EZEV_CHECK_NETWORK);
  emberEventControlSetActive(StateMachineEvent);

  return SC_EZ_START;
}
Esempio n. 16
0
/** @brief Stack Status
 *
 * This function is called by the application framework from the stack status
 * handler.  This callbacks provides applications an opportunity to be
 * notified of changes to the stack status and take appropriate action.  The
 * return code from this callback is ignored by the framework.  The framework
 * will always process the stack status after the callback returns.
 *
 * @param status   Ver.: always
 */
boolean emberAfStackStatusCallback(EmberStatus status)
{
  if (status == EMBER_NETWORK_UP) {
    emberEventControlSetInactive(networkEventControl);
    halPlayTune_P(happyTune, TRUE);
  } else if (status == EMBER_NETWORK_DOWN
             && emberNetworkState() == EMBER_NO_NETWORK) {
    emberEventControlSetActive(networkEventControl);
  }
  return FALSE;
}
/*! Callback for Simple Descriptor Request */
static void ProcessServiceDiscovery(
    const EmberAfServiceDiscoveryResult *result) {
  // if we get a matche or a default response handle it
  // otherwise stop commissioning or go to the next incoming device
  if (emberAfHaveDiscoveryResponseStatus(result->status)) {
    EmberAfClusterList *discovered_clusters =
        (EmberAfClusterList *)result->responseData;

    // if our device requested to bind to server clusters (is_server parameter
    // during the SimpleCommissioningStart was FALSE) -> use inClusterList of
    // the incoming device's response
    // otherwise -> outClusterList (as our device has server clusters)
    const uint16_t *inc_clusters_arr = (dev_comm_session.is_server)
                                           ? discovered_clusters->outClusterList
                                           : discovered_clusters->inClusterList;
    // get correct lenght of the incoming clusters array
    const uint8_t inc_clusters_arr_len =
        (dev_comm_session.is_server) ? discovered_clusters->outClusterCount
                                     : discovered_clusters->inClusterCount;
    // init clusters skip mask length for further using
    InitRemoteSkipCluster(inc_clusters_arr_len);
    // check how much clusters our device wants to bind to
    uint8_t supported_clusters =
        CheckSupportedClusters(inc_clusters_arr, inc_clusters_arr_len);

    emberAfDebugPrintln("DEBUG: Supported clusters %d", supported_clusters);
    if (supported_clusters == 0) {
      // we should not do anything with that, just wait maybe another response
      // would come
      SetNextEvent(SC_EZEV_TIMEOUT);
      SetNextState(SC_EZ_WAIT_IDENT_RESP);
      emberEventControlSetDelayMS(
          StateMachineEvent, SIMPLE_COMMISSIONING_IDENTIFY_RESPONSE_WAIT_TIME());
    } else {
      // update our incoming device structure with information about clusters
      SetInDevicesClustersInfo(inc_clusters_arr, inc_clusters_arr_len,
                               supported_clusters);
      // Now we have all information about responded device's clusters
      // Start matching procedure for checking how much of them fit for our
      // device
      SetNextEvent(SC_EZEV_CHECK_CLUSTERS);
      SetNextState(SC_EZ_MATCH);
      emberEventControlSetActive(StateMachineEvent);
    }
  } else {
    // we should not do anything with that, just wait maybe another response
    // would come
    SetNextEvent(SC_EZEV_TIMEOUT);
    SetNextState(SC_EZ_WAIT_IDENT_RESP);
    emberEventControlSetDelayMS(
        StateMachineEvent, SIMPLE_COMMISSIONING_IDENTIFY_RESPONSE_WAIT_TIME());
  }
}
/*! 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);
}
Esempio n. 19
0
/** @brief Tunnel Closed
 *
 * This function is called by the Tunneling client plugin whenever a server
 * sends a notification that it preemptively closed an inactive tunnel.
 * Servers are not required to notify clients of tunnel closures, so
 * applications cannot rely on this callback being called for all tunnels.
 *
 * @param tunnelId The ID of the tunnel that has been closed.  Ver.:
 * always
 */
void emberAfPluginTunnelingClientTunnelClosedCallback(uint8_t tunnelId) 
{
  uint8_t tunnelIndex;
  emberAfDebugPrintln("CHF: ClientTunnelClosed:0x%x", tunnelId);

  tunnelIndex = findTunnelByTunnelId(tunnelId, CLIENT_TUNNEL);
  if (tunnelIndex != EM_AF_PLUGIN_COMMS_HUB_FUNCTION_NULL_TUNNEL_INDEX) {
    tunnels[tunnelIndex].state = CLOSED_TUNNEL;
    if (tunnelIndex == responsePendingIndex) {
      responsePendingIndex = EM_AF_PLUGIN_COMMS_HUB_FUNCTION_NULL_TUNNEL_INDEX;
      emberEventControlSetActive(emberAfPluginCommsHubFunctionTunnelEventControl);
    }
  }
}
static CommissioningState_t CheckQuery(void) {
  emberAfDebugPrintln("DEBUG: Check query");
  CommissioningState_t next_st = SC_EZ_UNKNOWN;

  if (GetQueueSize() != 0) {
    SetNextEvent(SC_EZEV_CHECK_CLUSTERS);
    next_st = SC_EZ_DISCOVER;
  } else {
    SetNextEvent(SC_EZEV_QUEUE_EMPTY);
    next_st = SC_EZ_BIND;
  }

  emberEventControlSetActive(StateMachineEvent);

  return next_st;
}
Esempio n. 21
0
/** @brief Tunnel Opened
 *
 * This function is called by the Tunneling client plugin whenever a tunnel is
 * opened.
 *
 * @param tunnelId The ID of the tunnel that has been opened.  Ver.:
 * always
 * @param tunnelStatus The status of the request.  Ver.: always
 * @param maximumIncomingTransferSize The maximum incoming transfer size of
 * the server.  Ver.: always
 */
void emberAfPluginTunnelingClientTunnelOpenedCallback(uint8_t tunnelId,
                                                      EmberAfPluginTunnelingClientStatus tunnelStatus,
                                                      uint16_t maximumIncomingTransferSize) {
  emberAfDebugPrintln("CHF: ClientTunnelOpened:0x%x,0x%x,0x%2x", tunnelId, tunnelStatus, maximumIncomingTransferSize);

  if (responsePendingIndex != EM_AF_PLUGIN_COMMS_HUB_FUNCTION_NULL_TUNNEL_INDEX) {
    uint8_t tunnelIndex = responsePendingIndex;
    responsePendingIndex = EM_AF_PLUGIN_COMMS_HUB_FUNCTION_NULL_TUNNEL_INDEX;
    emberEventControlSetActive(emberAfPluginCommsHubFunctionTunnelEventControl);
    if (tunnelStatus == EMBER_AF_PLUGIN_TUNNELING_CLIENT_SUCCESS) {
      tunnels[tunnelIndex].tunnelId = tunnelId;
      tunnels[tunnelIndex].state = ACTIVE_TUNNEL;

      // Per GBCS v0.8 section 10.2.2, Devices supporting the Tunneling Cluster
      // as a Server shall have a MaximumIncomingTransferSize set to 1500 octets,
      // in line with the ZSE default.  All Devices supporting the Tunneling
      // Cluster shall use this value in any RequestTunnelResponse command and
      // any RequestTunnel command.
      //
      // So rather than bring down the tunnel in the case when the maximumIncomingTransferSize
      // is less than 1500 we'll just log a warning message.
      if (maximumIncomingTransferSize < 1500) {
        emberAfPluginCommsHubFunctionPrintln("Warning: tunnel opened but MaximumIncomingTransferSize of server is %d but should be 1500",
                                             maximumIncomingTransferSize);
      }

      // providing as a stub for the user to re-send data if the tunnel was re-established while sending data
      // and other cases
      emberAfPluginCommsHubFunctionTunnelOpenedCallback(tunnels[tunnelIndex].remoteDeviceId);
      return;
    }

    // see if we can recover from the open failure
    if (handleRequestTunnelFailure(tunnelIndex, tunnelStatus)) {
    	//Jira EMAPPFWKV2-1421: tunnel event handler will take care of retries and request again to setup tunnel, don't need to save
    	//tunnelIndex in responsePendingIndex here, as response to tunnel request is already received.
      responsePendingIndex = EM_AF_PLUGIN_COMMS_HUB_FUNCTION_NULL_TUNNEL_INDEX;
      return;
    }
  } else {
    // The tunnel has opened but we no longer require it so close it
    emberAfPluginTunnelingClientCloseTunnel(tunnelId);
  }
}
// Start the transmissions of a sequence of IR frames. The format must
// be specified in the IR database entry.
int halInfraredLedStart(HalInfraredLedDbFormat irDbFormat,
                        const uint8_t *ird,
                        uint8_t irdLen)
{
static uint8_t *irdPtrPrevious;
static uint8_t irdLenPrevious;
int iSta;

  // Is there a requests in progress?
  if ((irdPtrCurrent != 0) || (irdLenCurrent != 0)) {
    return 1;
  }
  irdPtrCurrent = (uint8_t *)ird;
  irdLenCurrent = irdLen;
  // Is the current request different from the previous?
  if ((ird != irdPtrPrevious) || (irdLen != irdLenPrevious)) {
    //This is a new format
    irdPtrPrevious = (uint8_t *)ird;
    irdLenPrevious = irdLen;
    // Always reset the toggle counter for the SIRD format
    if (irDbFormat == HAL_INFRARED_LED_DB_FORMAT_SIRD) {
      halInternalInfraredLedEmitToggleReset();
    }
  }
  if (ird == 0) {
    // If the pointer is 0, irdLen shall be interpreted as the index.
    iSta = infraredLedDecodeIndex(irDbFormat, irdLen);
  } else {
    iSta = infraredLedDecodeData(irDbFormat, ird, irdLen);
  }
  if (iSta == 0) {
    reqStart = true;
    if (state == IDLE) {
      emberEventControlSetActive(halInfraredLedEventControl);
    }
  }
  return iSta;
}
Esempio n. 23
0
static bool buttonPress(uint8_t button, uint8_t state)
{
  // ISR CONTEXT!!!
  static uint32_t timeMs;
  EmberEventControl* event;
	
  if (button == BUTTON0) {
    event = &buttonEvent0;
  } else if (button == BUTTON1) {
		event = &buttonEvent1;
  } else {
		return false;
	}
	if (state == BUTTON_PRESSED) {
		buttonPressDurationMs = 0;
		timeMs = halCommonGetInt32uMillisecondTick();
  } else {
		buttonPressDurationMs = elapsedTimeInt32u(timeMs, halCommonGetInt32uMillisecondTick());
		emberEventControlSetActive(*event);
	}

  return true;
}
// Stop the ongoing sequence of IR transmissions and transmit the final
// IR frame. The format must be specified in the IR database entry.
int halInfraredLedStop(HalInfraredLedDbFormat irDbFormat,
                       const uint8_t *ird,
                       uint8_t irdLen)
{
  int iSta;

  // Is it the current request that is stopped?
  if ((ird != irdPtrCurrent) || (irdLen != irdLenCurrent)) {
    return 1;
  }
  if (ird == 0) {
    // If the pointer is 0, irdLen shall be interpreted as the index.
    iSta = infraredLedDecodeIndex(irDbFormat, irdLen);
  } else {
    iSta = infraredLedDecodeData(irDbFormat, ird, irdLen);
  }
  if (iSta == 0) {
    reqStop = true;
    if (state == IDLE) {
      emberEventControlSetActive(halInfraredLedEventControl);
    }
  }
  return iSta;
}
Esempio n. 25
0
/** @brief Main Init
 *
 * This function is called from the application's main function. It gives the
 * application a chance to do any initialization required at system startup.
 * Any code that you would normally put into the top of the application's
 * main() routine should be put into this function.
        Note: No callback
 * in the Application Framework is associated with resource cleanup. If you
 * are implementing your application on a Unix host where resource cleanup is
 * a consideration, we expect that you will use the standard Posix system
 * calls, including the use of atexit() and handlers for signals such as
 * SIGTERM, SIGINT, SIGCHLD, SIGPIPE and so on. If you use the signal()
 * function to register your signal handler, please mind the returned value
 * which may be an Application Framework function. If the return value is
 * non-null, please make sure that you call the returned function from your
 * handler to avoid negating the resource cleanup of the Application Framework
 * itself.
 *
 */
void emberAfMainInitCallback(void)
{
  emberEventControlSetActive(networkEventControl);
}
Esempio n. 26
0
void initAndRunMainLoop(void)
{
  EmberEventControl dataReportControl;
  EmberStatus status;
  int counter_reset = 0;
  emberTaskEnableIdling(true);

  emAppTask = emberTaskInit(emAppEvents);

  // Initialize the radio and the stack.  If this fails, we have to assert
  // because something is wrong.
  status = emberInit();
  emberSerialPrintfLine(COM_USART2, "Inititialization: 0x%x", status);	//ember success;0x00 so emberinit worked
  assert(status == EMBER_SUCCESS);


  emberAfInit();
  emberAfMainInitCallback();       //emberNetworkInit() called here

  emberResetNetworkState(); /////////////////leave network to join coordinator

  EmberNetworkStatus net_status;
  EmberNetworkParameters parameters;

  emberSetSecurityKey(&securityKey);

  MEMSET(&parameters, 0, sizeof(EmberNetworkParameters));
  parameters.radioTxPower = 0;
  parameters.radioChannel = 1;
  parameters.panId = 0x01FF;

  halStackSeedRandom(halCommonGetInt32uMillisecondTick());

  while (TRUE) {
    // Let the stack or EZSP layer run periodic tasks.
    emberTick();
    // Let the application and plugins run periodic tasks.

    emberAfMainTickCallback();
    emberAfTick();
    emberEventControlSetActive(dataReportControl);

    net_status = emberNetworkState();
    //emberResetNetworkState();
    //emberJoinNetwork(EMBER_STAR_END_DEVICE, &parameters);
    /*
    if(!emberStackIsUp()){
    	emberAfGuaranteedPrintln("stack wasn't up");
    	emberJoinNetwork(EMBER_STAR_END_DEVICE, &parameters);
    }
	*/
    //emberAfGuaranteedPrintln("net_status is: %d", net_status);
    if(counter_reset == 10000){
    	emberResetNetworkState();
    	counter_reset = 0;
    }
    else{
    	counter_reset++;
    }
    if (net_status == EMBER_NO_NETWORK){
        //emberPermitJoining(0xFF);
    	//emberResetNetworkState();
    	emberAfGuaranteedPrintln("Network has been reset");
    	emberJoinNetwork(EMBER_STAR_END_DEVICE, &parameters);
    }



    emberRunTask(emAppTask);
  }
}
void emberAfPluginRf4ceZrc11OutgoingUserControlEventHandler(void)
{
  emberEventControlSetActive(emberAfPluginRf4ceZrc11OutgoingUserControlEventControl);
}
Esempio n. 28
0
// Hal Button ISR Callback
// This callback is called by the framework whenever a button is pressed on the
// device. This callback is called within ISR context.
void emberAfHalButtonIsrCallback(int8u button, int8u state)
{
  if ((button == BUTTON0 || button == BUTTON1) && state == BUTTON_PRESSED) {
    emberEventControlSetActive(buttonEventControl);
  }
}