예제 #1
0
/*!
 * @brief send association abort request.
 *
 * This function implements association abort request, it builds abort data
 * and sends it out using PHDC transport channel.
 *
 * @param handle        the agent handle.
 * @param abort_reason  the abort reason.
 */
void AGENT_SendAssociationAbortRequest(uint32_t handle, abort_reason_t abortReason)
{
    apdu_t *pApdu;
    agent_struct_t *pAgent = NULL;
    pAgent = AGENT_GetDeviceByHandle(handle);
    if (NULL != pAgent)
    {
        uint16_t size;
        size = (uint16_t)(ABRT_DATA_LENGTH + APDU_HEADER_SIZE);
        pApdu = (apdu_t *)&pAgent->agentTxBuffer[0U];
        pApdu->choice = ABRT_CHOSEN;
        pApdu->length = (uint16_t)USB_SHORT_FROM_BIG_ENDIAN(size - APDU_HEADER_SIZE);
        pApdu->u.abrt.reason = USB_SHORT_FROM_BIG_ENDIAN(abortReason);
        if (AGENT_SendData(pAgent->agentHandle, AGENT_SEND_DATA_QOS, (uint8_t *)pApdu, (uint32_t)size))
        {
#if _DEBUG
            usb_echo("Send abort request error\n\r");
#endif
        }
    }
    else
    {
#if _DEBUG
        usb_echo("Cannot find the agent device\n\r");
#endif
    }
}
예제 #2
0
/*!
 * @brief send association release response.
 *
 * This function implements association release response, it builds release
 * response data and sends it out using PHDC transport channel.
 *
 * @param pAgent            the agent device instance pointer.
 * @param release_reason    the release reason.
 *
 * @retval AGENT_ERROR_SUCCESS          sending response is successful.
 * @retval AGENT_ERROR_INVALID_PARAM    sending response is fail.
 */
static void AGENT_SendAssociationReleaseResponse(uint32_t handle, release_request_reason_t releaseReason)
{
    apdu_t *pApdu;
    agent_struct_t *pAgent = NULL;
    pAgent = AGENT_GetDeviceByHandle(handle);
    if (NULL != pAgent)
    {
        uint16_t size;
        size = (uint16_t)(RLRE_DATA_LENGTH + APDU_HEADER_SIZE);
        pApdu = (apdu_t *)&pAgent->agentTxBuffer[0U];
        pApdu->choice = RLRE_CHOSEN;
        pApdu->length = (uint16_t)USB_SHORT_FROM_BIG_ENDIAN(size - APDU_HEADER_SIZE);
        pApdu->u.rlre.reason = USB_SHORT_FROM_BIG_ENDIAN(releaseReason);
        if (AGENT_SendData(handle, AGENT_SEND_DATA_QOS, (uint8_t *)pApdu, (uint32_t)size))
        {
#if _DEBUG
            usb_echo("Send release response error\n\r");
#endif
        }
    }
    else
    {
#if _DEBUG
        usb_echo("Cannot find the agent device\n\r");
#endif
    }
}
예제 #3
0
static void USB_HostApplicationInit(void)
{
    usb_status_t status = kStatus_USB_Success;
    IRQn_Type usbIrq;

#if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
    IRQn_Type usbFsIrqs[] = USB_IRQS;
    usbIrq = usbFsIrqs[CONTROLLER_ID - kUSB_ControllerKhci0];
    CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk));
#endif /* USB_HOST_CONFIG_KHCI */
#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
    IRQn_Type usbHsIrqs[] = USBHS_IRQS;
    usbIrq = usbHsIrqs[CONTROLLER_ID - kUSB_ControllerEhci0];
    CLOCK_EnableUsbhs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk));
    USB_EhciPhyInit(CONTROLLER_ID, BOARD_XTAL0_CLK_HZ);
#endif /* USB_HOST_CONFIG_EHCI */
#if ((defined FSL_FEATURE_SOC_MPU_COUNT) && (FSL_FEATURE_SOC_MPU_COUNT))
    MPU_Enable(MPU, 0);
#endif /* FSL_FEATURE_SOC_MPU_COUNT */

    status = USB_HostInit(CONTROLLER_ID, &g_HostHandle, USB_HostEvent);
    if (status != kStatus_USB_Success)
    {
        usb_echo("host init error\r\n");
        return;
    }
    NVIC_SetPriority(usbIrq, USB_HOST_INTERRUPT_PRIORITY);
    NVIC_EnableIRQ(usbIrq);

    usb_echo("host init done\r\n");
}
예제 #4
0
/*!
 * @brief send agent configuration.
 *
 * This function gets the agent configuration from application and sends it to
 * the host using PHDC transport channel.
 *
 * @param handle        the agent handle.
 * @param config_ptr    the agent configuration data.
 * @param size          the agent configuration data size.
 */
void AGENT_SendConfig(uint32_t handle, uint8_t *config, uint32_t size)
{
    agent_struct_t *pAgent = NULL;
    pAgent = AGENT_GetDeviceByHandle(handle);
    if (NULL != pAgent)
    {
        if (AGENT_STATE_CON_ASSOC_CFG_SENDING_CONFIG == pAgent->agentState)
        {
#if IEEE_MAX_TIMER_OBJECTS
            /* preparing association timer object */
            ieee11073_timer_struct_t *pAgentTimer = &pAgent->agentTimer[1U];
            pAgentTimer->timerObject.timerCount = TO_CONFIG; /* 10S */
            pAgentTimer->timerObject.timerCallback = AGENT_SendConfigTimeout;
            pAgentTimer->timerObject.timerArgument = (void *)pAgent;
            pAgentTimer->timerId = IEEE_AddTimerQueue(&pAgentTimer->timerObject);
#endif
            /* the first time for sending the association request to host */
            if (AGENT_SendData(handle, AGENT_SEND_DATA_QOS, (uint8_t *)config, size))
            {
#if _DEBUG
                usb_echo("Send configuration error\n\r");
#endif
            }
        }
    }
    else
    {
#if _DEBUG
        usb_echo("Cannot get agent device \n\r");
#endif
    }
}
예제 #5
0
/*!
 * @brief send association request.
 *
 * This function gets the association request data from application and sends
 * it to the host using PHDC transport channel, this request is to establish a
 * connection between the device and the host.
 *
 * @param handle        the agent handle.
 * @param assoc_ptr     the association request data.
 * @param size          the association request data size.
 */
void AGENT_SendAssociationRequest(uint32_t handle, uint8_t *associationData, uint32_t size)
{
    agent_struct_t *pAgent = NULL;
    pAgent = AGENT_GetDeviceByHandle(handle);
    if (NULL != pAgent)
    {
        if (AGENT_STATE_CON_UNASSOCIATED == pAgent->agentState)
        {
#if IEEE_MAX_TIMER_OBJECTS
            /* preparing association timer object */
            ieee11073_timer_struct_t *pAgentTimer = &pAgent->agentTimer[0U];
            pAgentTimer->timerObject.timerCount = (int32_t)(RC_ASSOC * TO_ASSOC); /* 30S */
            pAgentTimer->timerObject.timerCallback = AGENT_SendAssociationRequestTimeout;
            pAgentTimer->timerObject.timerArgument = (void *)pAgent;
            pAgentTimer->timerId = IEEE_AddTimerQueue(&pAgentTimer->timerObject);
#endif
            /* the first time for sending the association request to host */
            if (AGENT_SendData(handle, AGENT_SEND_DATA_QOS, (uint8_t *)associationData, size))
            {
#if _DEBUG
                usb_echo("Send association request error\n\r");
#endif
            }
        }
    }
    else
    {
#if _DEBUG
        usb_echo("Cannot get agent device \n\r");
#endif
    }
}
예제 #6
0
/*!
 * @brief Application initialization function.
 *
 * This function initializes the application.
 *
 * @return None.
 */
void APPInit(void)
{
    uint8_t irqNo;
#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)
    uint8_t ehciIrq[] = USBHS_IRQS;
    irqNo = ehciIrq[CONTROLLER_ID - kUSB_ControllerEhci0];

    CLOCK_EnableUsbhs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk));
    USB_EhciPhyInit(CONTROLLER_ID, BOARD_XTAL0_CLK_HZ);
#endif
#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0)
    uint8_t khciIrq[] = USB_IRQS;
    irqNo = khciIrq[CONTROLLER_ID - kUSB_ControllerKhci0];

    SystemCoreClockUpdate();

#if ((defined FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && (FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED))
    CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcIrc48M, 48000000U);
#else
    CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk));
#endif /* FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED */
#endif
#if (defined(FSL_FEATURE_SOC_MPU_COUNT) && (FSL_FEATURE_SOC_MPU_COUNT > 0U))
    MPU_Enable(MPU, 0);
#endif /* FSL_FEATURE_SOC_MPU_COUNT */

/*
 * If the SOC has USB KHCI dedicated RAM, the RAM memory needs to be clear after
 * the KHCI clock is enabled. When the demo uses USB EHCI IP, the USB KHCI dedicated
 * RAM can not be used and the memory can't be accessed.
 */
#if (defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U))
#if (defined(FSL_FEATURE_USB_KHCI_USB_RAM_BASE_ADDRESS) && (FSL_FEATURE_USB_KHCI_USB_RAM_BASE_ADDRESS > 0U))
    for (int i = 0; i < FSL_FEATURE_USB_KHCI_USB_RAM; i++)
    {
        ((uint8_t *)FSL_FEATURE_USB_KHCI_USB_RAM_BASE_ADDRESS)[i] = 0x00U;
    }
#endif /* FSL_FEATURE_USB_KHCI_USB_RAM_BASE_ADDRESS */
#endif /* FSL_FEATURE_USB_KHCI_USB_RAM */

    s_cdcVcom.speed = USB_SPEED_FULL;
    s_cdcVcom.attach = 0;
    s_cdcVcom.deviceHandle = NULL;

    if (kStatus_USB_Success != USB_DeviceInit(CONTROLLER_ID, USB_DeviceCallback, &s_cdcVcom.deviceHandle))
    {
        usb_echo("USB device vcom failed\r\n");
        return;
    }
    else
    {
        usb_echo("USB device CDC vcom demo\r\n");
    }

    NVIC_SetPriority((IRQn_Type)irqNo, USB_DEVICE_INTERRUPT_PRIORITY);
    NVIC_EnableIRQ((IRQn_Type)irqNo);

    USB_DeviceRun(s_cdcVcom.deviceHandle);
}
예제 #7
0
/*!
 * @brief cdc open control interface.
 *
 * @param cdcInstance     cdc instance pointer.
 *
 * @return kStatus_USB_Success or error codes.
 */
static usb_status_t USB_HostCdcOpenControlInterface(usb_host_cdc_instance_struct_t *cdcInstance)
{
    usb_status_t status;
    uint8_t ep_index = 0;
    usb_host_pipe_init_t pipeInit;
    usb_descriptor_endpoint_t *ep_desc = NULL;
    usb_host_interface_t *interfaceHandle;

    if (cdcInstance->interruptPipe != NULL)
    {
        status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->interruptPipe, NULL);
        status = USB_HostClosePipe(cdcInstance->hostHandle, cdcInstance->interruptPipe);

        if (status != kStatus_USB_Success)
        {
#ifdef HOST_ECHO
            usb_echo("error when close pipe\r\n");
#endif
        }
        cdcInstance->interruptPipe = NULL;
    }

    status = USB_HostOpenDeviceInterface(cdcInstance->deviceHandle, cdcInstance->controlInterfaceHandle);
    /* open interface pipes */
    interfaceHandle = (usb_host_interface_t *)cdcInstance->controlInterfaceHandle;

    for (ep_index = 0; ep_index < interfaceHandle->epCount; ++ep_index)
    {
        ep_desc = interfaceHandle->epList[ep_index].epDesc;
        if (((ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
             USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
            ((ep_desc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_INTERRUPT))
        {
            pipeInit.devInstance = cdcInstance->deviceHandle;
            pipeInit.pipeType = USB_ENDPOINT_INTERRUPT;
            pipeInit.direction = USB_IN;
            pipeInit.endpointAddress = (ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
            pipeInit.interval = ep_desc->bInterval;
            pipeInit.maxPacketSize = (uint16_t)(USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
                                                USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK);
            pipeInit.numberPerUframe = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
                                        USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK);
            pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;

            cdcInstance->packetSize = pipeInit.maxPacketSize;

            status = USB_HostOpenPipe(cdcInstance->hostHandle, &cdcInstance->interruptPipe, &pipeInit);
            if (status != kStatus_USB_Success)
            {
#ifdef HOST_ECHO
                usb_echo("USB_HostCdcSetControlInterface fail to open pipe\r\n");
#endif
                return kStatus_USB_Error;
            }
        }
    }
    return kStatus_USB_Success;
}
예제 #8
0
/*!
 * @brief cdc send control transfer common code.
 *
 * @param classHandle    the class handle.
 * @param request_type   setup packet request type.
 * @param request        setup packet request value.
 * @param wvalue_l       setup packet wvalue low byte.
 * @param wvalue_h       setup packet wvalue high byte.
 * @param wlength        setup packet wlength value.
 * @param data           data buffer pointer
 * @param callbackFn     this callback is called after this function completes.
 * @param callbackParam  the first parameter in the callback function.
 *
 * @return An error code or kStatus_USB_Success.
 */
usb_status_t USB_HostCdcControl(usb_host_class_handle classHandle,
                                uint8_t request_type,
                                uint8_t request,
                                uint8_t wvalue_l,
                                uint8_t wvalue_h,
                                uint16_t wlength,
                                uint8_t *data,
                                transfer_callback_t callbackFn,
                                void *callbackParam)
{
    usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)classHandle;
    usb_host_transfer_t *transfer;

    if (classHandle == NULL)
    {
        return kStatus_USB_InvalidHandle;
    }

    if (USB_HostMallocTransfer(cdcInstance->hostHandle, &transfer) != kStatus_USB_Success)
    {
#ifdef HOST_ECHO
        usb_echo("error to get transfer\r\n");
#endif
        return kStatus_USB_Error;
    }
    cdcInstance->controlCallbackFn = callbackFn;
    cdcInstance->controlCallbackParam = callbackParam;

    transfer->transferBuffer = data;
    transfer->transferLength = wlength;
    transfer->callbackFn = USB_HostCdcControlPipeCallback;
    transfer->callbackParam = cdcInstance;
    transfer->setupPacket.bmRequestType = request_type;
    transfer->setupPacket.bRequest = request;
    transfer->setupPacket.wValue = (wvalue_l | (uint16_t)((uint16_t)wvalue_h << 8));
    transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
        ((usb_host_interface_t *)cdcInstance->controlInterfaceHandle)->interfaceDesc->bInterfaceNumber);
    transfer->setupPacket.wLength = USB_SHORT_TO_LITTLE_ENDIAN(wlength);

    if (USB_HostSendSetup(cdcInstance->hostHandle, cdcInstance->controlPipe, transfer) != kStatus_USB_Success)
    {
#ifdef HOST_ECHO
        usb_echo("failt for USB_HostSendSetup\r\n");
#endif
        USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
        return kStatus_USB_Error;
    }
    cdcInstance->controlTransfer = transfer;

    return kStatus_USB_Success;
}
예제 #9
0
static usb_status_t USB_HostEvent(usb_device_handle deviceHandle,
                                  usb_host_configuration_handle configurationHandle,
                                  uint32_t eventCode)
{
#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
    USB_HostTestEvent(deviceHandle, configurationHandle, eventCode);
#else
    usb_status_t status = kStatus_USB_Success;
    switch (eventCode)
    {
        case kUSB_HostEventAttach:
            status = USB_HostMsdEvent(deviceHandle, configurationHandle, eventCode);
            break;

        case kUSB_HostEventNotSupported:
            usb_echo("device not supported.\r\n");
            break;

        case kUSB_HostEventEnumerationDone:
            status = USB_HostMsdEvent(deviceHandle, configurationHandle, eventCode);
            break;

        case kUSB_HostEventDetach:
            status = USB_HostMsdEvent(deviceHandle, configurationHandle, eventCode);
            break;

        default:
            break;
    }
    return status;
#endif
}
/*!
 * @brief Response to kUSB_DeviceCdcEventSendEncapsulatedCommand.
 *
 * This function is called in response to kUSB_DeviceCdcEventSendEncapsulatedCommand.
 *
 * @param handle The pointer the RNDIS device.
 * @param message The pointer to the pointer of the message buffer.
 * @param len The pointer of the length of the buffer.
 * @return A USB error code or kStatus_USB_Success.
 */
usb_status_t USB_DeviceCdcRndisMessageSet(usb_device_cdc_rndis_struct_t *handle, uint8_t **message, uint32_t *len)
{
    uint32_t messageType;

    if (!handle)
    {
        return kStatus_USB_InvalidHandle;
    }

    if (*len > RNDIS_MAX_EXPECTED_COMMAND_SIZE)
    {
        usb_echo("message length: (%d) exceeds the max: (%d)\n", len, RNDIS_MAX_EXPECTED_COMMAND_SIZE);
        return kStatus_USB_Error;
    }

    messageType = USB_LONG_TO_LITTLE_ENDIAN(*((uint32_t *)(*message)));

    if (messageType == RNDIS_HALT_MSG)
    {
        /* No response is send to host on receiving Halt Command */
        USB_DeviceCdcRndisHaltCommand(handle);
    }
    else
    {
        USB_DeviceCdcRndisResponseAvailable(handle);
    }

    if (messageType == RNDIS_INITIALIZE_MSG)
    {
        /* Update the NDIS HW status */
        handle->rndisHwState = NDIS_HARDWARE_STATUS_INITIALIZING;
    }

    return kStatus_USB_Success;
}
예제 #11
0
static usb_status_t USB_HostEvent(usb_device_handle deviceHandle,
                                  usb_host_configuration_handle configurationHandle,
                                  uint32_t eventCode)
{
    usb_status_t status = kStatus_USB_Success;

    switch (eventCode)
    {
        case kUSB_HostEventAttach:
            status = USB_HostHidGenericEvent(deviceHandle, configurationHandle, eventCode);
            break;

        case kUSB_HostEventNotSupported:
            usb_echo("device not supported.\r\n");
            break;

        case kUSB_HostEventEnumerationDone:
            status = USB_HostHidGenericEvent(deviceHandle, configurationHandle, eventCode);
            break;

        case kUSB_HostEventDetach:
            status = USB_HostHidGenericEvent(deviceHandle, configurationHandle, eventCode);
            break;

        default:
            break;
    }
    return status;
}
/*!
 * @brief Initializes the USB CDC RNDIS device.
 *
 * This function initializes the USB CDC RNDIS device.
 *
 * @param classHandle The class handle of the CDC ACM class.
 * @param config The pointer to the configure parameter.
 * @param handle The pointer to pointer of the RNDIS device.
 * @return A USB error code or kStatus_USB_Success.
 */
usb_status_t USB_DeviceCdcRndisInit(class_handle_t classHandle,
                                    usb_device_cdc_rndis_config_struct_t *config,
                                    usb_device_cdc_rndis_struct_t **handle)
{
    usb_device_cdc_rndis_struct_t *cdcRndisHandle;
    usb_status_t error = kStatus_USB_Error;

    error = USB_DeviceCdcRndisAllocateHandle(&cdcRndisHandle);

    if (kStatus_USB_Success != error)
    {
        return error;
    }

    /* Initially RNDIS is in Uninitialized state */
    cdcRndisHandle->cdcAcmHandle = classHandle;
    cdcRndisHandle->rndisDeviceState = RNDIS_UNINITIALIZED;
    cdcRndisHandle->rndisHwState = NDIS_HARDWARE_STATUS_NOT_READY;
    cdcRndisHandle->rndisMediaConnectStatus = NDIS_MEDIA_STATE_UNKNOWN;
    cdcRndisHandle->rndisDevMaxTxSize = config->devMaxTxSize;
    cdcRndisHandle->rndisCallback = config->rndisCallback;
    cdcRndisHandle->rndisCommand = &rndisCommand[0];
    cdcRndisHandle->responseData = &responseData[0];
    if (kStatus_USB_OSA_Success != USB_OsaMutexCreate(&(cdcRndisHandle->statusMutex)))
    {
        usb_echo("mutex create error!");
    }
    *handle = cdcRndisHandle;
    return error;
}
예제 #13
0
/*!
 * @brief initialize the agent device.
 *
 * This function initializes the agent device and starts transporting.
 *
 * @param handle            the agent handle.
 */
void AGENT_Init(uint32_t handle)
{
    uint8_t isNonActiveAgent = 0U;
    uint8_t agentIndex = 0U;
    agent_struct_t *pAgent = NULL;
    for (; agentIndex < MAX_AGENT_NUM; agentIndex++)
    {
        if (0U == g_agentDevice[agentIndex].agentHandle)
        {
            isNonActiveAgent = 1U;
            break;
        }
    }
    if (0U == isNonActiveAgent)
    {
#if _DEBUG
        usb_echo("ERROR: Users need to increase the max number of agent devices!\n\r");
#endif
    }
    else
    {
        /* Initialize Global Variable Structure */
        pAgent = (agent_struct_t *)(&g_agentDevice[agentIndex]);
        memset(pAgent, 0U, sizeof(agent_struct_t));
#if IEEE_MAX_TIMER_OBJECTS
        IEEE_TimerInit();
#endif
        /* set the default state of agent device is disconnected */
        AGENT_SetAgentState(pAgent->agentHandle, AGENT_STATE_DISCONNECTED);
        pAgent->agentHandle = handle;
    }
}
예제 #14
0
/*!
 * @brief send error.
 * This function is called to send error command to the device.
 *
 * @param param             the phdc manager instance pointer.
 * @param errorResult       error result.
 */
static void AGENT_SendRoer(uint32_t handle, error_result_t *errorResult)
{
    agent_struct_t *pAgent = NULL;
    pAgent = AGENT_GetDeviceByHandle(handle);
    if (NULL != pAgent)
    {
        uint16_t size;
        apdu_t *pApdu;
        data_apdu_t *pPrst;

        /* Calculate the size of Roer data */
        size = (uint16_t)(APDU_HEADER_SIZE + PRST_HEADER_LENGTH + sizeof(errorResult->errorValue) +
                          sizeof(errorResult->parameter.length) +
                          USB_SHORT_FROM_BIG_ENDIAN(errorResult->parameter.length));

        pApdu = (apdu_t *)&pAgent->agentTxBuffer[0];
        pApdu->choice = (uint16_t)USB_SHORT_FROM_BIG_ENDIAN(PRST_CHOSEN);
        pApdu->length = (uint16_t)USB_SHORT_FROM_BIG_ENDIAN(size - APDU_HEADER_SIZE);
        pApdu->u.prst.length = (uint16_t)USB_SHORT_FROM_BIG_ENDIAN(size - APDU_HEADER_SIZE - sizeof(uint16_t));
        pPrst = (data_apdu_t *)&pApdu->u.prst.value[0U];
        pPrst->invokeId = pAgent->invokeId;
        pPrst->choice.choice = USB_SHORT_FROM_BIG_ENDIAN(ROER_CHOSEN);
        pPrst->choice.length = (uint16_t)USB_SHORT_FROM_BIG_ENDIAN(size - APDU_HEADER_SIZE - PRST_HEADER_LENGTH);
        pPrst->choice.u.roer.errorValue = errorResult->errorValue;
        pPrst->choice.u.roer.parameter.length = errorResult->parameter.length;
        if (USB_SHORT_FROM_BIG_ENDIAN(errorResult->parameter.length) > 0U)
        {
            memcpy(&pPrst->choice.u.roer.parameter.value[0U], &errorResult->parameter.value[0U],
                   USB_SHORT_FROM_BIG_ENDIAN(errorResult->parameter.length));
        }
        if (AGENT_SendData(handle, AGENT_SEND_DATA_QOS, (uint8_t *)pApdu, (uint32_t)size))
        {
#if _DEBUG
            usb_echo("Send release response error\n\r");
#endif
        }
    }
    else
    {
#if _DEBUG
        usb_echo("Cannot find the agent device\n\r");
#endif
    }
}
예제 #15
0
/*!
 * @brief receive data.
 *
 * This function implements cdc receiving data.
 *
 * @param classHandle    the class handle.
 * @param buffer         the buffer pointer.
 * @param bufferLength   the buffer length.
 * @param callbackFn     this callback is called after this function completes.
 * @param callbackParam  the first parameter in the callback function.
 *
 * @retval kStatus_USB_Success        receive request successfully.
 * @retval kStatus_USB_InvalidHandle  The classHandle is NULL pointer.
 * @retval kStatus_USB_Busy           There is no idle transfer.
 * @retval kStatus_USB_Error          pipe is not initialized.
 *                                    Or, send transfer fail, please reference to USB_HostRecv.
 */
usb_status_t USB_HostCdcDataRecv(usb_host_class_handle classHandle,
                                 uint8_t *buffer,
                                 uint32_t bufferLength,
                                 transfer_callback_t callbackFn,
                                 void *callbackParam)
{
    usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)classHandle;
    usb_host_transfer_t *transfer;

    if (classHandle == NULL)
    {
        return kStatus_USB_InvalidHandle;
    }

    if (cdcInstance->inPipe == NULL)
    {
        return kStatus_USB_Error;
    }

    if (USB_HostMallocTransfer(cdcInstance->hostHandle, &transfer) != kStatus_USB_Success)
    {
#ifdef HOST_ECHO
        usb_echo("error to get transfer\r\n");
#endif
        return kStatus_USB_Error;
    }
    cdcInstance->inCallbackFn = callbackFn;
    cdcInstance->inCallbackParam = callbackParam;
    transfer->transferBuffer = buffer;
    transfer->transferLength = bufferLength;
    transfer->callbackFn = USB_HostCdcDataInPipeCallback;
    transfer->callbackParam = cdcInstance;

    if (USB_HostRecv(cdcInstance->hostHandle, cdcInstance->inPipe, transfer) != kStatus_USB_Success)
    {
#ifdef HOST_ECHO
        usb_echo("failt to USB_HostRecv\r\n");
#endif
        USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
        return kStatus_USB_Error;
    }

    return kStatus_USB_Success;
}
예제 #16
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_test_mode_init
* Returned Value : None
* Comments       :
*     This function is called by common class to initialize the class driver. It
*     is called in response to a select interface call by application
*
*END*--------------------------------------------------------------------*/
usb_status_t USB_HostTestModeInit(usb_device_handle deviceHandle)
{
#if (((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI)) || \
     ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS)))
    usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
    usb_host_instance_t *hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
#endif
    uint32_t productId;
    uint32_t vendorId;

    usb_echo("usb host test init\r\n");
    USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDevicePID, &productId);
    USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceVID, &vendorId);
    usb_echo(" vendor id :0x%x product id:0x%x \r\n", vendorId, productId);

    if ((productId != 0x0200U) && (productId != 0x0101) && (productId != 0x0102) && (productId != 0x0103) &&
        (productId != 0x0104) && (productId != 0x0105) && (productId != 0x0106) && (productId != 0x0107) &&
        (productId != 0x0108))
    {
        usb_echo("Unsupported Device\r\n");
    }

    if (productId == 0x0200U)
    {
        usb_echo("PET test device attached\r\n");
    }
    else
    {
#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
        if (hostInstance->controllerTable == &s_EhciInterface)
        {
            USB_HostEhciTestModeInit(deviceHandle);
        }
#elif((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS))
        if (hostInstance->controllerTable == &s_Ip3516HsInterface)
        {
            USB_HostIp3516HsTestModeInit(deviceHandle);
        }
#endif
    }

    return kStatus_USB_Success;
}
/*!
 * @brief app initialization.
 */
void APP_init(void)
{
    usb_status_t status = kStatus_USB_Success;
    IRQn_Type usb_irq;
    usb_uartConfiguration uartConfiguration;

    g_xfer.buffer = (uint8_t *)&usbRecvUart[0];
    g_xfer.size = USB_HOST_CDC_UART_RX_MAX_LEN;
    USB_UartGetDefaultConfiguratoion(&uartConfiguration);
    uartConfiguration.baudRate_Bps = BOARD_DEBUG_UART_BAUDRATE;
    uartConfiguration.enableTx = true;
    uartConfiguration.enableRx = true;
    USB_UartInit((USB_UartType *)BOARD_DEBUG_UART_BASEADDR, &uartConfiguration, CLOCK_GetFreq(BOARD_DEBUG_UART_CLKSRC));
    USB_UartCreateHandle((USB_UartType *)BOARD_DEBUG_UART_BASEADDR, &g_UartHandle, UART_UserCallback, NULL);

    USB_UartReceiveDataIRQ((USB_UartType *)BOARD_DEBUG_UART_BASEADDR, &g_UartHandle, &g_xfer, NULL);

    g_AttachFlag = 0;

    USB_HostCdcInitBuffer();

#if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
    IRQn_Type usb_fs_irqs[] = USB_IRQS;
    usb_irq = usb_fs_irqs[CONTROLLER_ID - kUSB_ControllerKhci0];
    CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk));
#endif
#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
    IRQn_Type usb_hs_irqs[] = USBHS_IRQS;
    usb_irq = usb_hs_irqs[CONTROLLER_ID - kUSB_ControllerEhci0];
    CLOCK_EnableUsbhs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk));
    USB_EhciPhyInit(CONTROLLER_ID, BOARD_XTAL0_CLK_HZ);
#endif
#if ((defined FSL_FEATURE_SOC_MPU_COUNT) && (FSL_FEATURE_SOC_MPU_COUNT))
    MPU_Enable(MPU, 0);
#endif /* FSL_FEATURE_SOC_MPU_COUNT */

    status = USB_HostInit(CONTROLLER_ID, &g_hostHandle, USB_HostEvent);
    if (status != kStatus_USB_Success)
    {
        usb_echo("host init error\r\n");
        return;
    }
    NVIC_SetPriority(usb_irq, USB_HOST_INTERRUPT_PRIORITY);
    NVIC_EnableIRQ(usb_irq);

    usb_echo("host init done\r\n");
    usb_echo("This example requires that the CDC device uses Hardware flow\r\n");
    usb_echo(
        "if the device does't support it, please set USB_HOST_UART_SUPPORT_HW_FLOW to zero and rebuild this "
        "project\r\n");
    usb_echo("Type strings, then the string\r\n");
    usb_echo("will be echoed back from the device\r\n");
}
/*!
 * @brief De-initializes the USB CDC RNDIS device.
 *
 * This function de-initializes the USB CDC RNDIS device.
 *
 * @param handle The pointer the RNDIS device.
 * @return A USB error code or kStatus_USB_Success.
 */
usb_status_t USB_DeviceCdcRndisDeinit(usb_device_cdc_rndis_struct_t *handle)
{
    usb_device_cdc_rndis_struct_t *cdcRndisHandle;
    usb_status_t error = kStatus_USB_Error;

    cdcRndisHandle = handle;

    if (!cdcRndisHandle)
    {
        return kStatus_USB_InvalidHandle;
    }
    if (kStatus_USB_OSA_Success != USB_OsaMutexDestroy(cdcRndisHandle->statusMutex))
    {
        usb_echo("mutex destroy error!");
    }
    error = USB_DeviceCdcRndisFreeHandle(cdcRndisHandle);
    return error;
}
/*!
 * @brief Halt the RNDIS device.
 *
 * This function is called to halt the RNDIS device.
 * i.e. to terminate the network connection.
 *
 * @param handle The pointer the RNDIS device.
 * @return A USB error code or kStatus_USB_Success.
 */
usb_status_t USB_DeviceCdcRndisHaltCommand(usb_device_cdc_rndis_struct_t *handle)
{
    usb_device_cdc_acm_struct_t *cdcAcmHandle;
    cdcAcmHandle = (usb_device_cdc_acm_struct_t *)(handle->cdcAcmHandle);

    if (!handle)
    {
        return kStatus_USB_InvalidHandle;
    }
    usb_echo("RNDIS_Halt_Command\n");
    USB_CDC_MUTEX_LOCK(handle->statusMutex);
    handle->rndisDeviceState = RNDIS_UNINITIALIZED;
    handle->rndisMediaConnectStatus = NDIS_MEDIA_STATE_DISCONNECTED;
    handle->rndisHwState = NDIS_HARDWARE_STATUS_CLOSING;
    handle->rndisHwState = NDIS_HARDWARE_STATUS_NOT_READY;
    USB_CDC_MUTEX_UNLOCK(handle->statusMutex);
    return kStatus_USB_Success;
}
예제 #20
0
static usb_status_t USB_HostCdcClearHalt(usb_host_cdc_instance_struct_t *cdcInstance,
                                         usb_host_transfer_t *stallTransfer,
                                         host_inner_transfer_callback_t callbackFn,
                                         uint8_t endpoint)
{
    usb_status_t status;
    usb_host_transfer_t *transfer;

    /* malloc one transfer */
    status = USB_HostMallocTransfer(cdcInstance->hostHandle, &transfer);
    if (status != kStatus_USB_Success)
    {
#ifdef HOST_ECHO
        usb_echo("allocate transfer error\r\n");
#endif
        return status;
    }
    cdcInstance->stallDataBuffer = stallTransfer->transferBuffer;
    cdcInstance->stallDataLength = stallTransfer->transferSofar;
    /* save the application callback function */
    cdcInstance->controlCallbackFn = NULL;
    cdcInstance->controlCallbackParam = NULL;
    /* initialize transfer */
    transfer->callbackFn = callbackFn;
    transfer->callbackParam = cdcInstance;
    transfer->transferBuffer = NULL;
    transfer->transferLength = 0;
    transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_CLEAR_FEATURE;
    transfer->setupPacket.bmRequestType = USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
    transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT);
    transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(endpoint);
    transfer->setupPacket.wLength = 0;
    status = USB_HostSendSetup(cdcInstance->hostHandle, cdcInstance->controlPipe, transfer);

    if (status != kStatus_USB_Success)
    {
        USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
    }
    cdcInstance->controlTransfer = transfer;

    return status;
}
예제 #21
0
usb_status_t USB_HostDeinit(usb_host_handle hostHandle)
{
    usb_status_t status = kStatus_USB_Success;
    usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
    usb_host_device_instance_t *deviceInstance = NULL;

    if (hostHandle == NULL)
    {
        return kStatus_USB_InvalidHandle;
    }

    /* device list detach */
    deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
    while (deviceInstance != NULL)
    {
        deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
        USB_HostDetachDeviceInternal(hostHandle, deviceInstance);
    }

    /* controller instance destory */
    status = hostInstance->controllerTable->controllerDestory(hostInstance->controllerHandle);
    hostInstance->controllerHandle = NULL;
    if (status != kStatus_USB_Success)
    {
#ifdef HOST_ECHO
        usb_echo("host controller destory fail\r\n");
#endif
    }

    /* resource release */
    if (hostInstance->hostMutex)
    {
        USB_OsaMutexDestroy(hostInstance->hostMutex);
        hostInstance->hostMutex = NULL;
    }
    USB_HostReleaseInstance(hostInstance);

    return status;
}
예제 #22
0
/*!
 * @brief receive association response handle.
 *
 * This function handles the association request response sent by the host.
 *
 * @param handle       the agent handle.
 * @associaionResponse association response data
 */
static void AGENT_RecvAssociationResponse(uint32_t handle, aare_apdu_t *associaionResponse)
{
    agent_struct_t *pAgent = NULL;
    pAgent = AGENT_GetDeviceByHandle(handle);
    if (NULL != pAgent)
    {
        if (ACCEPTED == USB_SHORT_FROM_BIG_ENDIAN(associaionResponse->result))
        {
            /* The Agent is accepted by manager, change the state to operating,
            and wait roivCmipGet event from manager to change the procedure to
            operating */
            AGENT_SetAgentState(handle, AGENT_STATE_CON_ASSOC_OPERATING);
            AGENT_MedicalCallback(handle, AGENT_EVENT_ACCEPTED_AARQ, NULL);
        }
        else if (ACCEPTED_UNKNOWN_CONFIG == USB_SHORT_FROM_BIG_ENDIAN(associaionResponse->result))
        {
            /* The Agent is accepted by manager with unknown configuration, change agent state
            to configuring sending config, callback to application to send the device's configuration
            to the manager then change the procedure to configuring */
            AGENT_SetAgentState(handle, AGENT_STATE_CON_ASSOC_CFG_SENDING_CONFIG);
            AGENT_MedicalCallback(handle, AGENT_EVENT_ACCEPTED_UNKNOWN_CONFIG_AARQ, NULL);
        }
        else
        {
            /* The Agent is rejected by manager, change to state to unassociated, change the procedure
            to unassociated, callback to application with Reject event */
            AGENT_SetAgentState(handle, AGENT_STATE_CON_UNASSOCIATED);
            AGENT_MedicalCallback(handle, AGENT_EVENT_REJECTED_AARQ, NULL);
        }
    }
    else
    {
#if _DEBUG
        usb_echo("Cannot find the Agent device\n\r");
#endif
    }
}
예제 #23
0
/*!
 * @brief set agent device state.
 *
 * This function sets the state of device corresponding with specified agent.
 *
 * @param handle            the agent handle.
 * @param state             the state to set.
 *
 * @retval AGENT_ERROR_SUCCESS          the agent device is found.
 * @retval AGENT_ERROR_INVALID_PARAM    the agent device is not found.
 */
void AGENT_SetAgentState(uint32_t handle, uint8_t state)
{
    agent_struct_t *pAgent = NULL;
    pAgent = AGENT_GetDeviceByHandle(handle);
    if (NULL != pAgent)
    {
        switch (state)
        {
            case AGENT_STATE_DISCONNECTED:
#if IEEE_MAX_TIMER_OBJECTS
                /* de-queue timer */
                for (uint8_t i = 0U; i < IEEE_MAX_TIMER_OBJECTS; i++)
                {
                    ieee11073_timer_struct_t *pAgentTimer = &pAgent->agentTimer[i];
                    IEEE_RemoveTimerQueue(pAgentTimer->timerId);
                }
#endif
                pAgent->agentState = state;
#if _DEBUG
                usb_echo("\n\r11073Agent: ENTER DISCONNECTED state");
#endif
                break;
            case AGENT_STATE_CON_UNASSOCIATED:
                pAgent->agentState = state;
#if _DEBUG
                usb_echo("\n\r11073Agent: ENTER UNASSOCIATED state");
#endif
                break;
            case AGENT_STATE_CON_ASSOCIATING:
                pAgent->agentState = state;
#if _DEBUG
                usb_echo("\n\r11073Agent: ENTER ASSOCIATING state");
#endif
                break;
            case AGENT_STATE_CON_ASSOC_CFG_SENDING_CONFIG:
                pAgent->agentState = state;
#if _DEBUG
                usb_echo("\n\r11073Agent: ENTER CONFIGURING SENDING CONFIG state");
#endif
                break;
            case AGENT_STATE_CON_ASSOC_CFG_WAITING_APPROVAL:
                pAgent->agentState = state;
#if _DEBUG
                usb_echo("\n\r11073Agent: ENTER CONFIGURING WAITING APPROVAL state");
#endif
                break;
            case AGENT_STATE_CON_ASSOC_OPERATING:
                pAgent->agentState = state;
#if _DEBUG
                usb_echo("\n\r11073Agent: ENTER OPERATING state");
#endif
                break;
            case AGENT_STATE_CON_DISASSOCIATING:
                pAgent->agentState = state;
#if _DEBUG
                usb_echo("\n\r11073Agent: ENTER DISASSOCIATING state");
#endif
                break;
            default:
#if _DEBUG
                usb_echo("\n\r11073Agent: Error invalid state");
#endif
                break;
        }
    }
    else
    {
#if _DEBUG
        usb_echo("\n\r11073Agent: Error invalid param");
#endif
    }
}
예제 #24
0
/*!
 * @brief de-initialize the cdc instance.
 *
 * This function release the resource for cdc instance.
 *
 * @param deviceHandle   the device handle.
 * @param classHandle    the class handle.
 *
 * @retval kStatus_USB_Success        The device is de-initialized successfully.
 */
usb_status_t USB_HostCdcDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle)
{
    usb_status_t status;
    usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)classHandle;

    if (deviceHandle == NULL)
    {
        return kStatus_USB_InvalidHandle;
    }

    if (classHandle != NULL)
    {
        if (cdcInstance->interruptPipe != NULL)
        {
            status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->interruptPipe, NULL);
            status = USB_HostClosePipe(cdcInstance->hostHandle, cdcInstance->interruptPipe);

            if (status != kStatus_USB_Success)
            {
#ifdef HOST_ECHO
                usb_echo("error when close pipe\r\n");
#endif
            }
            cdcInstance->interruptPipe = NULL;
        }

        USB_HostCloseDeviceInterface(deviceHandle, cdcInstance->controlInterfaceHandle);

        if (cdcInstance->inPipe != NULL)
        {
            status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->inPipe, NULL);
            status = USB_HostClosePipe(cdcInstance->hostHandle, cdcInstance->inPipe);

            if (status != kStatus_USB_Success)
            {
#ifdef HOST_ECHO
                usb_echo("error when close pipe\r\n");
#endif
            }
            cdcInstance->inPipe = NULL;
        }
        if (cdcInstance->outPipe != NULL)
        {
            status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->outPipe, NULL);
            status = USB_HostClosePipe(cdcInstance->hostHandle, cdcInstance->outPipe);

            if (status != kStatus_USB_Success)
            {
#ifdef HOST_ECHO
                usb_echo("error when close pipe\r\n");
#endif
            }
            cdcInstance->outPipe = NULL;
        }
        if ((cdcInstance->controlPipe != NULL) && (cdcInstance->controlTransfer != NULL))
        {
            status =
                USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->controlPipe, cdcInstance->controlTransfer);
        }
        USB_HostCloseDeviceInterface(deviceHandle, cdcInstance->dataInterfaceHandle);

        USB_OsaMemoryFree(cdcInstance);
    }
    else
    {
        USB_HostCloseDeviceInterface(deviceHandle, NULL);
    }

    return kStatus_USB_Success;
}
예제 #25
0
/*!
 * @brief set data interface.
 *
 * This function bind the control interface with the cdc instance.
 *
 * @param classHandle      the class handle.
 * @param interfaceHandle  the data interface handle.
 * @param alternateSetting the alternate setting value.
 * @param callbackFn       this callback is called after this function completes.
 * @param callbackParam    the first parameter in the callback function.
 *
 * @retval kStatus_USB_Success        The device is initialized successfully.
 * @retval kStatus_USB_InvalidHandle  The classHandle is NULL pointer.
 * @retval kStatus_USB_Busy           There is no idle transfer.
 * @retval kStatus_USB_Error          send transfer fail, please reference to USB_HostSendSetup.
 * @retval kStatus_USB_Busy           callback return status, there is no idle pipe.
 * @retval kStatus_USB_TransferStall  callback return status, the transfer is stall by device.
 * @retval kStatus_USB_Error          callback return status, open pipe fail, please reference to USB_HostOpenPipe.
 */
usb_status_t USB_HostCdcSetDataInterface(usb_host_class_handle classHandle,
                                         usb_host_interface_handle interfaceHandle,
                                         uint8_t alternateSetting,
                                         transfer_callback_t callbackFn,
                                         void *callbackParam)
{
    usb_status_t status;
    usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)classHandle;
    usb_host_transfer_t *transfer;

    status = kStatus_USB_Success;
    if (classHandle == NULL)
    {
        return kStatus_USB_InvalidParameter;
    }

    cdcInstance->dataInterfaceHandle = interfaceHandle;

    /* cancel transfers */
    if (cdcInstance->inPipe != NULL)
    {
        status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->inPipe, NULL);

        if (status != kStatus_USB_Success)
        {
#ifdef HOST_ECHO
            usb_echo("error when cancel pipe\r\n");
#endif
        }
    }

    if (cdcInstance->outPipe != NULL)
    {
        status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->outPipe, NULL);

        if (status != kStatus_USB_Success)
        {
#ifdef HOST_ECHO
            usb_echo("error when cancel pipe\r\n");
#endif
        }
    }

    if (alternateSetting == 0)
    {
        if (callbackFn != NULL)
        {
            status = USB_HostCdcOpenDataInterface(cdcInstance);
            callbackFn(callbackParam, NULL, 0, status);
        }
    }
    else
    {
        if (USB_HostMallocTransfer(cdcInstance->hostHandle, &transfer) != kStatus_USB_Success)
        {
#ifdef HOST_ECHO
            usb_echo("error to get transfer\r\n");
#endif
            return kStatus_USB_Error;
        }
        cdcInstance->controlCallbackFn = callbackFn;
        cdcInstance->controlCallbackParam = callbackParam;
        /* initialize transfer */
        transfer->callbackFn = USB_HostCdcSetDataInterfaceCallback;
        transfer->callbackParam = cdcInstance;
        transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_SET_INTERFACE;
        transfer->setupPacket.bmRequestType = USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
        transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
            ((usb_host_interface_t *)cdcInstance->dataInterfaceHandle)->interfaceDesc->bInterfaceNumber);
        transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(alternateSetting);
        transfer->setupPacket.wLength = 0;
        transfer->transferBuffer = NULL;
        transfer->transferLength = 0;
        status = USB_HostSendSetup(cdcInstance->hostHandle, cdcInstance->controlPipe, transfer);

        if (status == kStatus_USB_Success)
        {
            cdcInstance->controlTransfer = transfer;
        }
        else
        {
            USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
        }
    }

    return status;
}
예제 #26
0
/*!
 * @brief Audio class specific request function.
 *
 * This function handles the Audio class specific requests.
 *
 * @param handle           The Audio class handle.
 * @param event            The Audio class event type.
 * @param param            The parameter of the class specific request.
 *
 * @return A USB error code or kStatus_USB_Success.
 */
usb_status_t USB_DeviceAudioRequest(class_handle_t handle, uint32_t event, void *param)
{
    usb_device_control_request_struct_t *request = (usb_device_control_request_struct_t *)param;
    usb_status_t error = kStatus_USB_Success;

    switch (event)
    {
        case USB_DEVICE_AUDIO_GET_CUR_MUTE_CONTROL:
            request->buffer = &s_audioGenerator.curMute;
            request->length = sizeof(s_audioGenerator.curMute);
            break;
        case USB_DEVICE_AUDIO_GET_CUR_VOLUME_CONTROL:
            request->buffer = s_audioGenerator.curVolume;
            request->length = sizeof(s_audioGenerator.curVolume);
            break;
        case USB_DEVICE_AUDIO_GET_CUR_BASS_CONTROL:
            request->buffer = &s_audioGenerator.curBass;
            request->length = sizeof(s_audioGenerator.curBass);
            break;
        case USB_DEVICE_AUDIO_GET_CUR_MID_CONTROL:
            request->buffer = &s_audioGenerator.curMid;
            request->length = sizeof(s_audioGenerator.curMid);
            break;
        case USB_DEVICE_AUDIO_GET_CUR_TREBLE_CONTROL:
            request->buffer = &s_audioGenerator.curTreble;
            request->length = sizeof(s_audioGenerator.curTreble);
            break;
        case USB_DEVICE_AUDIO_GET_CUR_AUTOMATIC_GAIN_CONTROL:
            request->buffer = &s_audioGenerator.curAutomaticGain;
            request->length = sizeof(s_audioGenerator.curAutomaticGain);
            break;
        case USB_DEVICE_AUDIO_GET_CUR_DELAY_CONTROL:
            request->buffer = s_audioGenerator.curDelay;
            request->length = sizeof(s_audioGenerator.curDelay);
            break;
        case USB_DEVICE_AUDIO_GET_CUR_SAMPLING_FREQ_CONTROL:
            request->buffer = s_audioGenerator.curSamplingFrequency;
            request->length = sizeof(s_audioGenerator.curSamplingFrequency);
            break;
        case USB_DEVICE_AUDIO_GET_MIN_VOLUME_CONTROL:
            request->buffer = s_audioGenerator.minVolume;
            request->length = sizeof(s_audioGenerator.minVolume);
            break;
        case USB_DEVICE_AUDIO_GET_MIN_BASS_CONTROL:
            request->buffer = &s_audioGenerator.minBass;
            request->length = sizeof(s_audioGenerator.minBass);
            break;
        case USB_DEVICE_AUDIO_GET_MIN_MID_CONTROL:
            request->buffer = &s_audioGenerator.minMid;
            request->length = sizeof(s_audioGenerator.minMid);
            break;
        case USB_DEVICE_AUDIO_GET_MIN_TREBLE_CONTROL:
            request->buffer = &s_audioGenerator.minTreble;
            request->length = sizeof(s_audioGenerator.minTreble);
            break;
        case USB_DEVICE_AUDIO_GET_MIN_DELAY_CONTROL:
            request->buffer = s_audioGenerator.minDelay;
            request->length = sizeof(s_audioGenerator.minDelay);
            break;
        case USB_DEVICE_AUDIO_GET_MIN_SAMPLING_FREQ_CONTROL:
            request->buffer = s_audioGenerator.minSamplingFrequency;
            request->length = sizeof(s_audioGenerator.minSamplingFrequency);
            break;
        case USB_DEVICE_AUDIO_GET_MAX_VOLUME_CONTROL:
            request->buffer = s_audioGenerator.maxVolume;
            request->length = sizeof(s_audioGenerator.maxVolume);
            break;
        case USB_DEVICE_AUDIO_GET_MAX_BASS_CONTROL:
            request->buffer = &s_audioGenerator.maxBass;
            request->length = sizeof(s_audioGenerator.maxBass);
            break;
        case USB_DEVICE_AUDIO_GET_MAX_MID_CONTROL:
            request->buffer = &s_audioGenerator.maxMid;
            request->length = sizeof(s_audioGenerator.maxMid);
            break;
        case USB_DEVICE_AUDIO_GET_MAX_TREBLE_CONTROL:
            request->buffer = &s_audioGenerator.maxTreble;
            request->length = sizeof(s_audioGenerator.maxTreble);
            break;
        case USB_DEVICE_AUDIO_GET_MAX_DELAY_CONTROL:
            request->buffer = s_audioGenerator.maxDelay;
            request->length = sizeof(s_audioGenerator.maxDelay);
            break;
        case USB_DEVICE_AUDIO_GET_MAX_SAMPLING_FREQ_CONTROL:
            request->buffer = s_audioGenerator.maxSamplingFrequency;
            request->length = sizeof(s_audioGenerator.maxSamplingFrequency);
            break;
        case USB_DEVICE_AUDIO_GET_RES_VOLUME_CONTROL:
            request->buffer = s_audioGenerator.resVolume;
            request->length = sizeof(s_audioGenerator.resVolume);
            break;
        case USB_DEVICE_AUDIO_GET_RES_BASS_CONTROL:
            request->buffer = &s_audioGenerator.resBass;
            request->length = sizeof(s_audioGenerator.resBass);
            break;
        case USB_DEVICE_AUDIO_GET_RES_MID_CONTROL:
            request->buffer = &s_audioGenerator.resMid;
            request->length = sizeof(s_audioGenerator.resMid);
            break;
        case USB_DEVICE_AUDIO_GET_RES_TREBLE_CONTROL:
            request->buffer = &s_audioGenerator.resTreble;
            request->length = sizeof(s_audioGenerator.resTreble);
            break;
        case USB_DEVICE_AUDIO_GET_RES_DELAY_CONTROL:
            request->buffer = s_audioGenerator.resDelay;
            request->length = sizeof(s_audioGenerator.resDelay);
            break;
        case USB_DEVICE_AUDIO_GET_RES_SAMPLING_FREQ_CONTROL:
            request->buffer = s_audioGenerator.resSamplingFrequency;
            request->length = sizeof(s_audioGenerator.resSamplingFrequency);
            break;

        case USB_DEVICE_AUDIO_SET_CUR_VOLUME_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = s_audioGenerator.curVolume;
            }
            else
            {
                uint16_t volume = (uint16_t)((uint16_t)s_audioGenerator.curVolume[1] << 8U);
                volume |= (uint8_t)(s_audioGenerator.curVolume[0]);
                usb_echo("Set Cur Volume : %x\r\n", volume);
            }
            break;
        case USB_DEVICE_AUDIO_SET_CUR_MUTE_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = &s_audioGenerator.curMute;
            }
            else
            {
                usb_echo("Set Cur Mute : %x\r\n", s_audioGenerator.curMute);
            }
            break;
        case USB_DEVICE_AUDIO_SET_CUR_BASS_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = &s_audioGenerator.curBass;
            }
            break;
        case USB_DEVICE_AUDIO_SET_CUR_MID_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = &s_audioGenerator.curMid;
            }
            break;
        case USB_DEVICE_AUDIO_SET_CUR_TREBLE_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = &s_audioGenerator.curTreble;
            }
            break;
        case USB_DEVICE_AUDIO_SET_CUR_AUTOMATIC_GAIN_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = &s_audioGenerator.curAutomaticGain;
            }
            break;
        case USB_DEVICE_AUDIO_SET_CUR_DELAY_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = s_audioGenerator.curDelay;
            }
            break;
        case USB_DEVICE_AUDIO_SET_CUR_SAMPLING_FREQ_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = s_audioGenerator.curSamplingFrequency;
            }
            break;
        case USB_DEVICE_AUDIO_SET_MIN_VOLUME_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = s_audioGenerator.minVolume;
            }
            break;
        case USB_DEVICE_AUDIO_SET_MIN_BASS_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = &s_audioGenerator.minBass;
            }
            break;
        case USB_DEVICE_AUDIO_SET_MIN_MID_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = &s_audioGenerator.minMid;
            }
            break;
        case USB_DEVICE_AUDIO_SET_MIN_TREBLE_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = &s_audioGenerator.minTreble;
            }
            break;
        case USB_DEVICE_AUDIO_SET_MIN_DELAY_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = s_audioGenerator.minDelay;
            }
            break;
        case USB_DEVICE_AUDIO_SET_MIN_SAMPLING_FREQ_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = s_audioGenerator.minSamplingFrequency;
            }
            break;
        case USB_DEVICE_AUDIO_SET_MAX_VOLUME_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = s_audioGenerator.maxVolume;
            }
            break;
        case USB_DEVICE_AUDIO_SET_MAX_BASS_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = &s_audioGenerator.maxBass;
            }
            break;
        case USB_DEVICE_AUDIO_SET_MAX_MID_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = &s_audioGenerator.maxMid;
            }
            break;
        case USB_DEVICE_AUDIO_SET_MAX_TREBLE_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = &s_audioGenerator.maxTreble;
            }
            break;
        case USB_DEVICE_AUDIO_SET_MAX_DELAY_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = s_audioGenerator.maxDelay;
            }
            break;
        case USB_DEVICE_AUDIO_SET_MAX_SAMPLING_FREQ_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = s_audioGenerator.maxSamplingFrequency;
            }
            break;
        case USB_DEVICE_AUDIO_SET_RES_VOLUME_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = s_audioGenerator.resVolume;
            }
            break;
        case USB_DEVICE_AUDIO_SET_RES_BASS_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = &s_audioGenerator.resBass;
            }
            break;
        case USB_DEVICE_AUDIO_SET_RES_MID_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = &s_audioGenerator.resMid;
            }
            break;
        case USB_DEVICE_AUDIO_SET_RES_TREBLE_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = &s_audioGenerator.resTreble;
            }
            break;
        case USB_DEVICE_AUDIO_SET_RES_DELAY_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = s_audioGenerator.resDelay;
            }
            break;
        case USB_DEVICE_AUDIO_SET_RES_SAMPLING_FREQ_CONTROL:
            if (request->isSetup == 1U)
            {
                request->buffer = s_audioGenerator.resSamplingFrequency;
            }
            break;
        default:
            error = kStatus_USB_InvalidRequest;
            break;
    }
    return error;
}
예제 #27
0
/* Application initialization */
static void USB_DeviceApplicationInit(void)
{
    uint8_t irqNumber;
#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)
    uint8_t usbDeviceEhciIrq[] = USBHS_IRQS;
    irqNumber = usbDeviceEhciIrq[CONTROLLER_ID - kUSB_ControllerEhci0];

    CLOCK_EnableUsbhs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk));
    USB_EhciPhyInit(CONTROLLER_ID, BOARD_XTAL0_CLK_HZ);
#endif
#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U)
    uint8_t usbDeviceKhciIrq[] = USB_IRQS;
    irqNumber = usbDeviceKhciIrq[CONTROLLER_ID - kUSB_ControllerKhci0];

    SystemCoreClockUpdate();

#if ((defined FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && (FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED))
    CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcIrc48M, 48000000U);
#else
    CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk));
#endif /* FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED */
#endif
#if (defined(FSL_FEATURE_SOC_MPU_COUNT) && (FSL_FEATURE_SOC_MPU_COUNT > 0U))
    MPU_Enable(MPU, 0);
#endif /* FSL_FEATURE_SOC_MPU_COUNT */

/*
 * If the SOC has USB KHCI dedicated RAM, the RAM memory needs to be clear after
 * the KHCI clock is enabled. When the demo uses USB EHCI IP, the USB KHCI dedicated
 * RAM can not be used and the memory can't be accessed.
 */
#if (defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U))
#if (defined(FSL_FEATURE_USB_KHCI_USB_RAM_BASE_ADDRESS) && (FSL_FEATURE_USB_KHCI_USB_RAM_BASE_ADDRESS > 0U))
    for (int i = 0; i < FSL_FEATURE_USB_KHCI_USB_RAM; i++)
    {
        ((uint8_t *)FSL_FEATURE_USB_KHCI_USB_RAM_BASE_ADDRESS)[i] = 0x00U;
    }
#endif /* FSL_FEATURE_USB_KHCI_USB_RAM_BASE_ADDRESS */
#endif /* FSL_FEATURE_USB_KHCI_USB_RAM */

    /* Set composite device default state */
    g_UsbDeviceComposite.speed = USB_SPEED_FULL;
    g_UsbDeviceComposite.attach = 0U;
    g_UsbDeviceComposite.deviceHandle = NULL;

    /* Initialize the usb stack and class drivers */
    if (kStatus_USB_Success != USB_DeviceInit(CONTROLLER_ID, USB_DeviceCallback, &g_UsbDeviceComposite.deviceHandle))
    {
        usb_echo("USB device composite demo init failed\r\n");
        return;
    }
    else
    {
        usb_echo("USB device composite demo\r\n");
    }

    USB_DeviceHidKeyboardInit(&g_UsbDeviceComposite);
    USB_DeviceHidMouseInit(&g_UsbDeviceComposite);

    /* Install isr, set priority, and enable IRQ. */
    NVIC_SetPriority((IRQn_Type)irqNumber, USB_DEVICE_INTERRUPT_PRIORITY);
    NVIC_EnableIRQ((IRQn_Type)irqNumber);

    /* Start USB device composite */
    USB_DeviceRun(g_UsbDeviceComposite.deviceHandle);
}
예제 #28
0
/*!
 * @brief receive PRST handle.
 *
 * This function handles the request/data sent by the host when the device is in
 * operating state.
 *
 * @param handle       the agent handle.
 * @param pPrst        presentation data unit pointer.
 */
static void AGENT_RecvPresentationProtocolDataUnit(uint32_t handle, prst_apdu_t *pPrst)
{
    agent_struct_t *pAgent = NULL;
    pAgent = AGENT_GetDeviceByHandle(handle);
    if (NULL != pAgent)
    {
        data_apdu_t *dataApdu = (data_apdu_t *)&(pPrst->value[0U]);
        /* Store the invoke ID */
        pAgent->invokeId = dataApdu->invokeId;
        if ((AGENT_STATE_CON_UNASSOCIATED == pAgent->agentState) || (AGENT_STATE_CON_ASSOCIATING == pAgent->agentState))
        {
#if AGENT_SUPPORT_FULL_FEATURE
            /* should not happen, send abort request to the manager */
            AGENT_SendAssociationAbortRequest(handle, ABORT_REASON_UNDEFINED);
#endif
        }
        switch (USB_SHORT_FROM_BIG_ENDIAN(dataApdu->choice.choice))
        {
            case ROIV_CMIP_GET_CHOSEN:
                if ((AGENT_STATE_CON_ASSOC_CFG_SENDING_CONFIG == pAgent->agentState) ||
                    (AGENT_STATE_CON_ASSOC_CFG_WAITING_APPROVAL == pAgent->agentState) ||
                    (AGENT_STATE_CON_ASSOC_OPERATING == pAgent->agentState))
                {
                    /* The remote operation response | Get is sending */
                    pAgent->isSendingRorsCmipGet = 1U;
                    /* callback to application to send rors-cmip-ge (MDS attribute) */
                    AGENT_MedicalCallback(handle, AGENT_EVENT_RECV_ROIV_CMIP_GET, (uint8_t *)&pAgent->invokeId);
                }
                else if (AGENT_STATE_CON_DISASSOCIATING == pAgent->agentState)
                {
                    /* do nothing */
                }
                else
                {
                }
                break;
            case ROIV_CMIP_EVENT_REPORT_CHOSEN:
            case ROIV_CMIP_CONFIRMED_EVENT_REPORT_CHOSEN:
            case ROIV_CMIP_SET_CHOSEN:
            case ROIV_CMIP_CONFIRMED_SET_CHOSEN:
            case ROIV_CMIP_ACTION_CHOSEN:
            case ROIV_CMIP_CONFIRMED_ACTION_CHOSEN:
                if ((AGENT_STATE_CON_ASSOC_CFG_SENDING_CONFIG == pAgent->agentState) ||
                    (AGENT_STATE_CON_ASSOC_CFG_WAITING_APPROVAL == pAgent->agentState))
                {
#if AGENT_SUPPORT_FULL_FEATURE
                    /* not allowed, send roer with no-such-object-instance */
                    uint8_t tempBuffer[4U];
                    error_result_t *errorResult = (error_result_t *)&tempBuffer[0];
                    errorResult->errorValue = USB_SHORT_FROM_BIG_ENDIAN(NO_SUCH_OBJECT_INSTANCE);
                    errorResult->parameter.length = 0U; /* There is no parameter for error result */
                    /* Send rors or rore or rorj, no state transition */
                    AGENT_SendRoer(handle, errorResult);
#endif
                }
                else if (AGENT_STATE_CON_ASSOC_OPERATING == pAgent->agentState)
                {
                    /* normal processing of message */
                }
                else if (AGENT_STATE_CON_DISASSOCIATING == pAgent->agentState)
                {
                    /* do nothing */
                }
                else
                {
                }
                break;
            case RORS_CMIP_CONFIRMED_EVENT_REPORT_CHOSEN:
                if ((AGENT_STATE_CON_ASSOC_CFG_SENDING_CONFIG == pAgent->agentState))
                {
#if AGENT_SUPPORT_FULL_FEATURE
                    /* should not happen, send abort request to the manager */
                    AGENT_SendAssociationAbortRequest(handle, ABORT_REASON_UNDEFINED);
#endif
                    AGENT_SetAgentState(handle, AGENT_STATE_CON_UNASSOCIATED);
                }
                else if (AGENT_STATE_CON_ASSOC_CFG_WAITING_APPROVAL == pAgent->agentState)
                {
                    /* configuration accepted */
                    config_report_rsp_t *configReport =
                        (config_report_rsp_t *)(&dataApdu->choice.u.rorsCmipConfirmedEventReport.eventReplyInfo
                                                     .value[0]);
                    configReport->configReportId = USB_SHORT_FROM_BIG_ENDIAN(configReport->configReportId);
                    if ((EXTENDED_CONFIG_START == configReport->configReportId) &&
                        (ACCEPTED_CONFIG == configReport->configResult))
                    {
                        /* The device's configuration is accepted by manager, change the state to operating, callback to
                        application to start sending data */
                        AGENT_SetAgentState(handle, AGENT_STATE_CON_ASSOC_OPERATING);
                        AGENT_MedicalCallback(handle, AGENT_EVENT_ACCEPTED_CONFIG, NULL);
                    }
                    else
                    {
                        /* The device's configuration is not accepted by manager, change the state to sending
                        configuration,
                        callback to application to resent the config */
                        AGENT_SetAgentState(pAgent->agentHandle, AGENT_STATE_CON_ASSOC_CFG_SENDING_CONFIG);
                        AGENT_MedicalCallback(handle, AGENT_EVENT_UNSUPPORTED_CONFIG, NULL);
                    }
                }
                else if (AGENT_STATE_CON_ASSOC_OPERATING == pAgent->agentState)
                {
                    /* the measurement data is sent complete, callback to application to send measurement data */
                    AGENT_MedicalCallback(handle, AGENT_EVENT_MEASUREMENT_SENT, NULL);
                }
                else if (AGENT_STATE_CON_DISASSOCIATING == pAgent->agentState)
                {
#if AGENT_SUPPORT_FULL_FEATURE
                    /* send abort */
                    AGENT_SendAssociationAbortRequest(handle, ABORT_REASON_UNDEFINED);
#endif
                }
                else
                {
                }
                break;
            case RORS_CMIP_GET_CHOSEN:
            case RORS_CMIP_CONFIRMED_SET_CHOSEN:
            case RORS_CMIP_CONFIRMED_ACTION_CHOSEN:
            case ROER_CHOSEN:
            case RORJ_CHOSEN:
                if ((AGENT_STATE_CON_ASSOC_CFG_SENDING_CONFIG == pAgent->agentState) ||
                    (AGENT_STATE_CON_ASSOC_CFG_WAITING_APPROVAL == pAgent->agentState))
                {
#if AGENT_SUPPORT_FULL_FEATURE
                    /* should not happen, send abort request to the manager */
                    AGENT_SendAssociationAbortRequest(handle, ABORT_REASON_UNDEFINED);
#endif
                    AGENT_SetAgentState(handle, AGENT_STATE_CON_UNASSOCIATED);
                }
                else if (AGENT_STATE_CON_ASSOC_OPERATING == pAgent->agentState)
                {
                    /* normal processing of message, do nothing */
                }
                else if (AGENT_STATE_CON_DISASSOCIATING == pAgent->agentState)
                {
#if AGENT_SUPPORT_FULL_FEATURE
                    /* send abort */
                    AGENT_SendAssociationAbortRequest(handle, ABORT_REASON_UNDEFINED);
#endif
                    AGENT_SetAgentState(handle, AGENT_STATE_CON_UNASSOCIATED);
                }
                else
                {
                }
                break;
            default:
                break;
        }
    }
    else
    {
#if _DEBUG
        usb_echo("Cannot find the Agent device\n\r");
#endif
    }
}
예제 #29
0
/*!
 * @brief the agent receive complete.
 *
 * This function analyses the received APDU data and calls to corresponding
 * agent function.
 *
 * @param handle       the agent handle.
 * @param dataBuffer   pointer to data
 * @param size         data size
 */
static void AGENT_RecvComplete(uint32_t handle, uint8_t *dataBuffer, uint32_t size)
{
    agent_struct_t *pAgent = NULL;
    pAgent = AGENT_GetDeviceByHandle(handle);
    if (NULL != pAgent)
    {
        if (AGENT_STATE_DISCONNECTED != pAgent->agentState)
        {
            uint16_t apduChoice;
            apdu_t *pApdu = NULL;
            pApdu = (apdu_t *)dataBuffer;
            apduChoice = USB_SHORT_FROM_BIG_ENDIAN(pApdu->choice);
            switch (apduChoice)
            {
                case AARQ_CHOSEN:
                    if ((AGENT_STATE_CON_UNASSOCIATED == pAgent->agentState) ||
                        (AGENT_STATE_CON_ASSOCIATING == pAgent->agentState))
                    {
                        /* agent-agent association - send aare request to reject association reqeuest*/
                        AGENT_SetAgentState(handle, AGENT_STATE_CON_UNASSOCIATED);
#if AGENT_SUPPORT_FULL_FEATURE
/* cannot establish a connection between two USB devices, this case will never occurs */
#endif
                    }
                    else if ((AGENT_STATE_CON_ASSOC_CFG_SENDING_CONFIG == pAgent->agentState) ||
                             (AGENT_STATE_CON_ASSOC_CFG_WAITING_APPROVAL == pAgent->agentState) ||
                             (AGENT_STATE_CON_ASSOC_OPERATING == pAgent->agentState) ||
                             (AGENT_STATE_CON_DISASSOCIATING == pAgent->agentState))
                    {
                        /* Should not happen - send abort request*/
                        AGENT_SetAgentState(handle, AGENT_STATE_CON_UNASSOCIATED);
#if AGENT_SUPPORT_FULL_FEATURE
                        AGENT_SendAssociationAbortRequest(handle, (abort_reason_t)ABORT_REASON_UNDEFINED);
#endif
                    }
                    else
                    {
                    }
                    break;
                case AARE_CHOSEN:
                    if ((AGENT_STATE_CON_UNASSOCIATED == pAgent->agentState) ||
                        (AGENT_STATE_CON_ASSOC_CFG_SENDING_CONFIG == pAgent->agentState) ||
                        (AGENT_STATE_CON_ASSOC_CFG_WAITING_APPROVAL == pAgent->agentState) ||
                        (AGENT_STATE_CON_ASSOC_OPERATING == pAgent->agentState) ||
                        (AGENT_STATE_CON_DISASSOCIATING == pAgent->agentState))
                    {
                        /* Should not happen - send abort request */
                        AGENT_SetAgentState(handle, AGENT_STATE_CON_UNASSOCIATED);
#if AGENT_SUPPORT_FULL_FEATURE
                        /* send abort request */
                        AGENT_SendAssociationAbortRequest(handle, (abort_reason_t)ABORT_REASON_UNDEFINED);
#endif
                    }
                    else if ((AGENT_STATE_CON_ASSOCIATING == pAgent->agentState))
                    {
                        AGENT_RecvAssociationResponse(handle, &(pApdu->u.aare));
                    }
                    else
                    {
                    }
                    break;
                case RLRQ_CHOSEN:
                    if ((AGENT_STATE_CON_UNASSOCIATED == pAgent->agentState) ||
                        (AGENT_STATE_CON_ASSOCIATING == pAgent->agentState))
                    {
                        /* Should not happen - send abort request to host */
                        AGENT_SetAgentState(handle, AGENT_STATE_CON_UNASSOCIATED);
#if AGENT_SUPPORT_FULL_FEATURE
                        /* send abort request */
                        AGENT_SendAssociationAbortRequest(handle, (abort_reason_t)ABORT_REASON_UNDEFINED);
#endif
                    }
                    else if ((AGENT_STATE_CON_ASSOC_CFG_SENDING_CONFIG == pAgent->agentState) ||
                             (AGENT_STATE_CON_ASSOC_CFG_WAITING_APPROVAL == pAgent->agentState) ||
                             (AGENT_STATE_CON_ASSOC_OPERATING == pAgent->agentState) ||
                             (AGENT_STATE_CON_DISASSOCIATING == pAgent->agentState))
                    {
                        AGENT_SetAgentState(handle, AGENT_STATE_CON_UNASSOCIATED);
#if AGENT_SUPPORT_FULL_FEATURE
                        /* send rlre(normal) */
                        AGENT_SendAssociationReleaseResponse(handle,
                                                             (release_request_reason_t)RELEASE_REQUEST_REASON_NORMAL);
#endif
                    }
                    else
                    {
                    }
                    break;
                case RLRE_CHOSEN:
                    if ((AGENT_STATE_CON_UNASSOCIATED == pAgent->agentState) ||
                        (AGENT_STATE_CON_ASSOCIATING == pAgent->agentState) ||
                        (AGENT_STATE_CON_ASSOC_CFG_SENDING_CONFIG == pAgent->agentState) ||
                        (AGENT_STATE_CON_ASSOC_CFG_WAITING_APPROVAL == pAgent->agentState) ||
                        (AGENT_STATE_CON_ASSOC_OPERATING == pAgent->agentState))
                    {
                        /* Should not happen - send abort request to host */
                        AGENT_SetAgentState(handle, AGENT_STATE_CON_UNASSOCIATED);
#if AGENT_SUPPORT_FULL_FEATURE
                        /* send abort request */
                        AGENT_SendAssociationAbortRequest(handle, (abort_reason_t)ABORT_REASON_UNDEFINED);
#endif
                    }
                    else if (AGENT_STATE_CON_DISASSOCIATING == pAgent->agentState)
                    {
                        AGENT_SetAgentState(handle, AGENT_STATE_CON_UNASSOCIATED);
                    }
                    else
                    {
                    }
                    break;
                case ABRT_CHOSEN:
                    if ((AGENT_STATE_CON_UNASSOCIATED == pAgent->agentState) ||
                        (AGENT_STATE_CON_ASSOCIATING == pAgent->agentState) ||
                        (AGENT_STATE_CON_ASSOC_CFG_SENDING_CONFIG == pAgent->agentState) ||
                        (AGENT_STATE_CON_ASSOC_CFG_WAITING_APPROVAL == pAgent->agentState) ||
                        (AGENT_STATE_CON_ASSOC_OPERATING == pAgent->agentState) ||
                        (AGENT_STATE_CON_DISASSOCIATING == pAgent->agentState))
                    {
                        AGENT_SetAgentState(handle, AGENT_STATE_CON_UNASSOCIATED);
                    }
                    break;
                case PRST_CHOSEN:
                    AGENT_RecvPresentationProtocolDataUnit(handle, &(pApdu->u.prst));
                    break;
                default:
                    break;
            }
        }
    }
    else
    {
#if _DEBUG
        usb_echo("Cannot find the Agent device\n\r");
#endif
    }
}
예제 #30
0
/*!
 * @brief agent callback.
 *
 * This function is the callback function called by transport layer and then it
 * will call to proper agent functions.
 *
 * @param handle        the agent handle.
 * @param request       the callback request.
 * @param data          the callback data.
 * @param size          the callback data size.
 */
void AGENT_Callback(uint32_t handle, uint8_t request, uint8_t *data, uint32_t size)
{
    agent_struct_t *pAgent = NULL;
    pAgent = AGENT_GetDeviceByHandle(handle);
    if (NULL != pAgent)
    {
        switch (request)
        {
            case SHIM_AGENT_EVENT_RECV_MESSAGE_PREAMBLE:
            case SHIM_AGENT_EVENT_RECV_OPAQUE_DATA:
                break;
            case SHIM_AGENT_EVENT_RECV_COMPLETE:
            {
                AGENT_RecvComplete(handle, data, size);
            }
            break;
            case SHIM_AGENT_EVENT_SENT_COMPLETE:
            {
                if (AGENT_STATE_DISCONNECTED == pAgent->agentState)
                {
                    AGENT_SetAgentState(pAgent->agentHandle, AGENT_STATE_CON_UNASSOCIATED);
                    pAgent->isSendingRorsCmipGet = 0U;
                    AGENT_MedicalCallback(handle, AGENT_EVENT_CONNECTED, NULL);
                }
                else if (AGENT_STATE_CON_UNASSOCIATED == pAgent->agentState)
                {
#if IEEE_MAX_TIMER_OBJECTS
                    ieee11073_timer_struct_t *pAgentTimer = &pAgent->agentTimer[0U];
                    IEEE_RemoveTimerQueue(pAgentTimer->timerId);
#endif
                    AGENT_SetAgentState(pAgent->agentHandle, AGENT_STATE_CON_ASSOCIATING);
                }
                else if (AGENT_STATE_CON_ASSOC_CFG_SENDING_CONFIG == pAgent->agentState)
                {
#if IEEE_MAX_TIMER_OBJECTS
                    ieee11073_timer_struct_t *pAgentTimer;
                    pAgentTimer = &pAgent->agentTimer[1U];
                    IEEE_RemoveTimerQueue(pAgentTimer->timerId);
#endif
                    AGENT_SetAgentState(pAgent->agentHandle, AGENT_STATE_CON_ASSOC_CFG_WAITING_APPROVAL);
                }
                else if (AGENT_STATE_CON_ASSOC_OPERATING == pAgent->agentState)
                {
                    if (1U == pAgent->isSendingRorsCmipGet)
                    {
                        pAgent->isSendingRorsCmipGet = 0U;
                        AGENT_MedicalCallback(handle, AGENT_EVENT_RORS_CMIP_GET_SENT, NULL);
                    }
                }
                else
                {
                }
            }
            break;
            default:
                break;
        }
    }
    else
    {
#if _DEBUG
        usb_echo("Cannot the Agent device\n\r");
#endif
    }
}