Beispiel #1
0
/******************************************************************************
 * @fn          SMPL_Ioctl
 *
 * @brief       This routine supplies the SimpliciTI IOCTL support.
 *
 * input parameters
 * @param   object   - The IOCTL target object
 * @param   action   - The IOCTL target action on the object
 * @param   val      - pointer to value. exact forn depends on object type.
 *
 * output parameters
 *
 * @return   Status of action. Value depends on object, action, and result.
 *
 *           SMPL_BAD_PARAM is returned if this API is called before
 *                          initialization and the object is not one of
 *                          the valid exceptions.
 */
smplStatus_t SMPL_Ioctl(ioctlObject_t object, ioctlAction_t action, void *val)
{
  smplStatus_t rc;

  /* if init hasn't occurred see if access is still valid */
  if (!sInit_done && !ioctlPreInitAccessIsOK(object))
  {
    return SMPL_BAD_PARAM;
  }

  switch (object)
  {
#if defined(EXTENDED_API)
    case IOCTL_OBJ_TOKEN:
      {
        ioctlToken_t *t = (ioctlToken_t *)val;

        rc = SMPL_SUCCESS;
        if (TT_LINK == t->tokenType)
        {
          if (IOCTL_ACT_SET == action)
          {
            nwk_setLinkToken(t->token.linkToken);
          }
          else if (IOCTL_ACT_GET == action)
          {
            nwk_getLinkToken(&t->token.linkToken);
          }
          else
          {
            rc = SMPL_BAD_PARAM;
          }
        }
        else if (TT_JOIN == t->tokenType)
        {
          if (IOCTL_ACT_SET == action)
          {
            nwk_setJoinToken(t->token.joinToken);
          }
          else if (IOCTL_ACT_GET == action)
          {
            nwk_getJoinToken(&t->token.joinToken);
          }
          else
          {
            rc = SMPL_BAD_PARAM;
          }
        }
        else
        {
          rc = SMPL_BAD_PARAM;
        }
      }
      break;

    case IOCTL_OBJ_NVOBJ:
      rc = nwk_NVObj(action, (ioctlNVObj_t *)val);
      break;
#endif  /* EXTENDED_API */

    case IOCTL_OBJ_CONNOBJ:
      rc = nwk_connectionControl(action, val);
      break;

    case IOCTL_OBJ_ADDR:
      if ((IOCTL_ACT_GET == action) || (IOCTL_ACT_SET == action))
      {
        rc = nwk_deviceAddress(action, (addr_t *)val);
      }
      else
      {
        rc = SMPL_BAD_PARAM;
      }
      break;

    case IOCTL_OBJ_RAW_IO:
      if (IOCTL_ACT_WRITE == action)
      {
        rc = nwk_rawSend((ioctlRawSend_t *)val);
      }
      else if (IOCTL_ACT_READ == action)
      {
        rc = nwk_rawReceive((ioctlRawReceive_t *)val);
      }
      else
      {
        rc = SMPL_BAD_PARAM;
      }
      break;

    case IOCTL_OBJ_RADIO:
      rc = nwk_radioControl(action, val);
      break;

#if defined(ACCESS_POINT)
    case IOCTL_OBJ_AP_JOIN:
      rc = nwk_joinContext(action);
      break;
#endif
#if defined(FREQUENCY_AGILITY)
    case IOCTL_OBJ_FREQ:
      rc = nwk_freqControl(action, val);
      break;
#endif
    case IOCTL_OBJ_FWVER:
      if (IOCTL_ACT_GET == action)
      {
        memcpy(val, nwk_getFWVersion(), SMPL_FWVERSION_SIZE);
        rc = SMPL_SUCCESS;
      }
      else
      {
        rc = SMPL_BAD_PARAM;
      }
      break;

    case IOCTL_OBJ_PROTOVER:
      if (IOCTL_ACT_GET == action)
      {
        *((uint8_t *)val) = nwk_getProtocolVersion();
        rc = SMPL_SUCCESS;
      }
      else
      {
        rc = SMPL_BAD_PARAM;
      }
      break;

    default:
      rc = SMPL_BAD_PARAM;
      break;
  }

  return rc;
}
Beispiel #2
0
/******************************************************************************
 * @fn          smpl_send_join_reply
 *
 * @brief       Send the Join reply. Include the Link token. If the device is
 *              a polling sleeper put it into the list of store-and-forward
 *              clients.
 *
 * input parameters
 * @param   frame     - join frame for which a reply is needed...maybe
 *
 * output parameters
 *
 * @return   void
 */
static void smpl_send_join_reply(mrfiPacket_t *frame)
{
  frameInfo_t *pOutFrame;
  uint8_t      msg[JOIN_REPLY_FRAME_SIZE];

  /* Is this a legacy frame? If so continue. Otherwise check verion.*/
  if ((MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS) > JOIN_LEGACY_MSG_LENGTH)
  {
    /* see if protocol version is correct... */
    if (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+J_PROTOCOL_VERSION_OS) != nwk_getProtocolVersion())
    {
      /* Accommodation of protocol version differences can be noted or accomplished here.
       * Otherwise, no match and the board goes back
       */
      return;
    }
  }


  /* see if join token is correct */
  {
    uint32_t jt;

    nwk_getNumObjectFromMsg(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+J_JOIN_TOKEN_OS, &jt, sizeof(jt));
    if (jt != sJoinToken)
    {
      return;
    }
  }

  /* send reply with tid, the link token, and the encryption context */
  {
    uint32_t linkToken;

    nwk_getLinkToken(&linkToken);
    nwk_putNumObjectIntoMsg((void *)&linkToken, msg+JR_LINK_TOKEN_OS, sizeof(linkToken));
  }
  msg[JR_CRYPTKEY_SIZE_OS] = SEC_CRYPT_KEY_SIZE;
  msg[JB_REQ_OS]           = JOIN_REQ_JOIN | NWK_APP_REPLY_BIT;
  /* sender's tid... */
  msg[JB_TID_OS]           = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+JB_TID_OS);

  if (pOutFrame = nwk_buildFrame(SMPL_PORT_JOIN, msg, sizeof(msg), MAX_HOPS_FROM_AP))
  {
    /* destination address is the source adddress of the received frame. */
    memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE);

#ifdef AP_IS_DATA_HUB
    /* if source device supports ED objects save source address to detect duplicate joins */
    if (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+J_NUMCONN_OS))
    {
      if (nwk_saveJoinedDevice(frame) && spCallback)
      {
        spCallback(0);
      }
    }
#endif
  }
  else
  {
    /* oops -- no room left for Tx frame. Don't send reply. */
    return;
  }

  /* If this device polls we need to provide store-and-forward support */
  if (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame),F_RX_TYPE) == F_RX_TYPE_POLLS)
  {
    uint8_t loc;

    /* Check duplicate status */
    if (!nwk_isSandFClient(MRFI_P_SRC_ADDR(frame), &loc))
    {
      uint8_t        *pNumc   = &spSandFContext->curNumSFClients;
      sfClientInfo_t *pClient = &spSandFContext->sfClients[*pNumc];

      /* It's not a duplicate. Save it if there's room */
      if (*pNumc < NUM_STORE_AND_FWD_CLIENTS)
      {
        memcpy(pClient->clientAddr.addr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE);
        *pNumc = *pNumc + 1;
      }
      else
      {
        /* No room left. Just return and don't send reply. */
        return;
      }
    }
    else
    {
      /* We get here if it's a duplicate. We drop through and send reply.
       * Reset the S&F marker in the Management application -- we should
       * assume that the Client reset so the TID will be random. If this is
       * simply a duplicate frame it causes no harm.
       */
      nwk_resetSFMarker(loc);
    }
  }

#ifdef SMPL_SECURE
    nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0);
#endif  /* SMPL_SECURE */

  /* It's not S&F or it is but we're OK to send reply. */
  nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED);

  return;
}