/******************************************************************************
 * @fn          change_channel_cmd_is_valid
 *
 * @brief       Check validity of a change channel command frame.
 *
 * input parameters
 * @param   frame  - pointer to frame with command context
 *
 * @return   Returns non-zero if command is valid, otherwise returns 0.
 *           Command is valid if either:
 *             - frame is directed
 *             - frame is from an AP and we know about that AP
 *
 *           It is possible that either we don't know about an AP or that
 *           we do but this frame comes from another AP in range.
 */
static uint8_t change_channel_cmd_is_valid(mrfiPacket_t *frame)
{
  uint8_t rc = 0;
  addr_t const *apAddr;

  /* If this was a directed frame obey the command. */
  if (!memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE))
  {
    rc = 1;
  }
  else
  {
    /* Do we know about an AP? If not assume frame bogus. */
    apAddr = nwk_getAPAddress();
    if (apAddr)
    {
      /* Yes, we know about an AP. Is that who sent it? */
      if (!memcmp(apAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE))
      {
        /* OK. We obey. */
        rc = 1;
      }
    }
  }

  return rc;
}
/***********************************************************************************
 * @fn          SMPL_Init
 *
 * @brief       Initialize the SimpliciTI stack.
 *
 * input parameters
 * @param   f  - Pointer to call back function. Function called by NWK when
 *               user application frame received. The callback is done in the
 *               ISR thread. Argument is Link ID associated with frame. Function
 *               returns 0 if frame is to be kept by NWK, otherwise 1. Frame
 *               should be kept if application will do a SMPL_Receive() in the
 *               user thread (recommended). Pointer may be NULL.
 *
 * output parameters
 *
 * @return   Status of operation:
 *             SMPL_SUCCESS
 *             SMPL_NO_JOIN     No Join reply. AP possibly not yet up.
 *             SMPL_NO_CHANNEL  Only if Frequency Agility enabled. Channel scan
 *                              failed. AP possibly not yet up.
 */
smplStatus_t SMPL_Init(uint8_t (*f)(linkID_t))
{
  smplStatus_t rc;

  if (!sInit_done)
  {
    /* set up radio. */
    MRFI_Init();

    /* initialize network */
    if ((rc=nwk_nwkInit(f)) != SMPL_SUCCESS)
    {
      return rc;
    }

    MRFI_WakeUp();
#if defined( FREQUENCY_AGILITY )
    {
      freqEntry_t chan;

      chan.logicalChan = 0;
      /* ok to set default channel explicitly now that MRFI initialized. */
      nwk_setChannel(&chan);
    }
#endif
    /* don't turn Rx on if we're an end device that isn't always on. */
    /* but do turn the radio on for PLL operations */
#if !defined( END_DEVICE ) || defined( NWK_PLL )
    MRFI_RxOn();
#endif

#if defined( END_DEVICE )
    /* All except End Devices are in promiscuous mode */
    MRFI_SetRxAddrFilter((uint8_t *)nwk_getMyAddress());
    MRFI_EnableRxAddrFilter();
#endif
  }
  sInit_done = 1;

#ifdef NWK_PLL
  /* If the PLL is enabled then it must get running before the join
   * request or the system may lock up in the join request becuase
   * PLL is not locked in.
   */
  // turn on the PLL
  SMPL_Ioctl(IOCTL_OBJ_PLL, IOCTL_ACT_ON, NULL);
  // reference clocks are by definition always locked.
  #ifndef NWK_PLL_REFERENCE_CLOCK
    // wait for a 5ms failure rate to be achieved
    while( nwk_pllIsLocked( 0 ) == false )
      nwk_pllBackgrounder( false );
  #endif
#endif

  /* Join. if no AP or Join fails that status is returned. */
  rc = nwk_join();

  return rc;
}
Exemple #3
0
/******************************************************************************
 * @fn          nwk_processMgmt
 *
 * @brief       Process Management frame. Just save the frame for the Management
 *              app it it is a reply. If it isn't a reply, send the reply in this
 *              thread.
 *
 * input parameters
 * @param   frame   - pointer to frame to be processed
 *
 * output parameters
 *
 * @return   Keep frame for application, release frame, or replay frame.
 */
fhStatus_t nwk_processMgmt(mrfiPacket_t *frame)
{
  fhStatus_t   rc;
  uint8_t      replyType;

  /* If we sent this then this is the reply. Validate the
   * packet for reception by client app. If we didn't send
   * it then we are the target. send the reply.
   */
  if (SMPL_MY_REPLY == (replyType=nwk_isValidReply(frame, sTid, MB_APP_INFO_OS, MB_TID_OS)))
  {
    /* It's a match and it's a reply. Validate the received packet by
     * returning a 1 so it can be received by the client app.
     */
    MRFI_PostKillSem();
    rc = FHS_KEEP;
  }
#if !defined( END_DEVICE )
  else if (SMPL_A_REPLY == replyType)
  {
    /* no match. if i'm not an ED this is a reply that should be passed on. */
    rc = FHS_REPLAY;
  }
#endif  /* !END_DEVICE */
  else
  {
    /* no, we didn't send it. send reply if it's intended for us */
    if (!memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE))
    {
      smpl_send_mgmt_reply(frame);

      /* we're done with the frame. */
      rc = FHS_RELEASE;
    }
    else
    {
      rc = FHS_REPLAY;
    }
  }

  (void) replyType;  /* keep compiler happy */

  return rc;
}
Exemple #4
0
/***********************************************************************************
 * @fn          SMPL_Init
 *
 * @brief       Initialize the SimpliciTI stack.
 *
 * input parameters
 * @param   f  - Pointer to call back function. Function called by NWK when
 *               user application frame received. The callback is done in the
 *               ISR thread. Argument is Link ID associated with frame. Function
 *               returns 0 if frame is to be kept by NWK, otherwise 1. Frame
 *               should be kept if application will do a SMPL_Receive() in the
 *               user thread (recommended). Pointer may be NULL.
 *
 * output parameters
 *
 * @return   Status of operation:
 *             SMPL_SUCCESS
 *             SMPL_NO_JOIN     No Join reply. AP possibly not yet up.
 *             SMPL_NO_CHANNEL  Only if Frequency Agility enabled. Channel scan
 *                              failed. AP possibly not yet up.
 */
smplStatus_t SMPL_Init(uint8_t (*f)(linkID_t))
{
  smplStatus_t rc;

  if (!sInit_done)
  {
    /* set up radio. */
    MRFI_Init();

    /* initialize network */
    if ((rc=nwk_nwkInit(f)) != SMPL_SUCCESS)
    {
      return rc;
    }

    MRFI_WakeUp();
#if defined( FREQUENCY_AGILITY )
    {
      freqEntry_t chan;

      chan.logicalChan = 0;
      /* ok to set default channel explicitly now that MRFI initialized. */
      nwk_setChannel(&chan);
    }
#endif
    /* don't turn Rx on if we're an end device that isn't always on. */
#if !defined( END_DEVICE )
    MRFI_RxOn();
#endif

#if defined( END_DEVICE )
    /* All except End Devices are in promiscuous mode */
    MRFI_SetRxAddrFilter((uint8_t *)nwk_getMyAddress());
    MRFI_EnableRxAddrFilter();
#endif
  }
  sInit_done = 1;

  /* Join. if no AP or Join fails that status is returned. */
  rc = nwk_join();

  return rc;
}
smplStatus_t nwk_deviceAddress(ioctlAction_t action, addr_t *addr)
{
    smplStatus_t rc = SMPL_BAD_PARAM;

    if (IOCTL_ACT_GET == action)
    {
        memcpy(addr, nwk_getMyAddress(), sizeof(addr_t));
        rc = SMPL_SUCCESS;
    }
    else if (IOCTL_ACT_SET == action)
    {
        if (nwk_setMyAddress(addr))
        {
            rc = SMPL_SUCCESS;
        }
    }

    return rc;
}
Exemple #6
0
/*******************************************************************************
 * @fn          nwk_isValidReply
 *
 * @brief       Examine a frame to see if it is a valid reply when compared with
 *              expected parameters.
 *
 * input parameters
 * @param   frame      - pointer to frmae being examined
 * @param   tid        - expected transaction ID in application payload
 * @param   infoOffset - offset to payload information containing reply hint
 * @param   tidOffset  - offset to transaction ID in payload
 *
 * output parameters
 *
 * @return   reply category:
 *               SMPL_NOT_REPLY: not a reply
 *               SMPL_MY_REPLY : a reply that matches input parameters
 *               SMPL_A_REPLY  : a reply but does not match input parameters
 */
uint8_t nwk_isValidReply(mrfiPacket_t *frame, uint8_t tid, uint8_t infoOffset, uint8_t tidOffset)
{
  uint8_t rc = SMPL_NOT_REPLY;

  if ((*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+infoOffset) & NWK_APP_REPLY_BIT))
  {
    if ((*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+tidOffset) == tid) &&
        !memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE))
    {
      rc = SMPL_MY_REPLY;
    }
    else
    {
      rc = SMPL_A_REPLY;
    }
  }

  return rc;
}
void nwk_frameInit(uint8_t (*pF)(linkID_t))
{

/****** Fill static values for the DEVICEINFO byte that will go in each frame ******/
  /* Rx type when frame originates from this device. Set in nwk_buildFrame() */
  /* Tx type when frame sent from this device. Set in nwk_sendframe() */
#if !defined(END_DEVICE)
    sMyRxType = F_RX_TYPE_USER_CTL;
  #if defined(ACCESS_POINT)
    sMyTxType = F_TX_DEVICE_AP;
  #else
    sMyTxType = F_TX_DEVICE_RE;
  #endif
#else
    sMyTxType = F_TX_DEVICE_ED;
  #if defined(RX_POLLS)
    sMyRxType = F_RX_TYPE_POLLS;
  #endif
  #if defined(RX_USER)
    sMyRxType = F_RX_TYPE_USER_CTL;
  #endif
#endif
/****** DONE fill static values for the DEVICEINFO byte that will go in each frame ******/

#if !defined(RX_POLLS)
  spCallback = pF;
#else
  (void) pF;
#endif

  sMyAddr = nwk_getMyAddress();

  while (!(sTRACTID=MRFI_RandomByte())) ;

  return;
}