Ejemplo n.º 1
0
/****************************************************************************
NAME 
    usbAudioRoute
    
DESCRIPTION
    Connect USB audio stream
    
RETURNS
    void
*/ 
void usbAudioRoute(void)
{
    AudioPluginFeatures features;
    Sink sink;
    Source source;
    uint16 sampleFreq;
    UsbDeviceClassGetValue(USB_DEVICE_CLASS_GET_VALUE_AUDIO_SOURCE, (uint16*)(&source));
    /* Note: UsbDeviceClassGetValue uses uint16 which limits max value of sample frequency to 64k (uint 16 has range 0->65536) */
    UsbDeviceClassGetValue(USB_DEVICE_CLASS_GET_VALUE_SAMPLE_FREQ, &sampleFreq);
    sink = StreamSinkFromSource(source);
    /* determine additional features applicable for this audio plugin */
    features.stereo = (AUDIO_PLUGIN_FORCE_STEREO || theSink.features.stereo);
    features.use_i2s_output = theSink.features.UseI2SOutputCapability;

    USB_DEBUG(("USB: Audio "));
    /* Check Audio configured (sink will be NULL if VM USB not enabled) */
    if(USB_CLASS_ENABLED(USB_DEVICE_CLASS_AUDIO) && sink)
    {
        USB_DEBUG(("Configured "));
        if(usbAudioIsAttached())
        {
            USB_DEBUG(("Attached\n"));
            if(theSink.routed_audio != sink)
            {
                Task plugin;
                AUDIO_MODE_T mode;
                uint16 volume = usbGetVolume(&mode);
                const usb_plugin_info* plugin_info = usbAudioGetPluginInfo(&plugin, theSink.usb.config.plugin_type, theSink.usb.config.plugin_index);

                theSink.routed_audio = sink;
                UsbDeviceClassGetValue(USB_DEVICE_CLASS_GET_VALUE_AUDIO_SINK, (uint16*)(&theSink.cvc_params.usb_params.usb_sink));
                /* Make sure we're using correct parameters for USB */
                theSink.a2dp_link_data->a2dp_audio_connect_params.mode_params = &theSink.a2dp_link_data->a2dp_audio_mode_params;

                USB_DEBUG(("USB: Connect 0x%X 0x%X", (uint16)sink, (uint16)(theSink.cvc_params.usb_params.usb_sink)));

#ifdef ENABLE_SUBWOOFER
            /* set the sub woofer link type prior to passing to audio connect */
            theSink.a2dp_link_data->a2dp_audio_connect_params.sub_woofer_type  = AUDIO_SUB_WOOFER_NONE;  
            theSink.a2dp_link_data->a2dp_audio_connect_params.sub_sink  = NULL;  
            /* bits inverted in dsp plugin */                
            sinkAudioSetEnhancement(MUSIC_CONFIG_SUB_WOOFER_BYPASS,TRUE);
#else
            /* no subwoofer support, set the sub woofer bypass bit in music config message sent o dsp */
            sinkAudioSetEnhancement(MUSIC_CONFIG_SUB_WOOFER_BYPASS,FALSE);
#endif          

                /* use a2dp connect parameters */
                /* sample frequency is not fixed so read this from usb library */
                if(plugin_info->plugin_type == usb_plugin_stereo)
                    AudioConnect(plugin, sink, AUDIO_SINK_USB, theSink.codec_task, volume, sampleFreq, features, mode, 0, powerManagerGetLBIPM(), &theSink.a2dp_link_data->a2dp_audio_connect_params, &theSink.task);
                /* all other plugins use cvc connect parameters */                
                else
                    AudioConnect(plugin, sink, AUDIO_SINK_USB, theSink.codec_task, volume, sampleFreq, features, mode, 0, powerManagerGetLBIPM(), &theSink.cvc_params, &theSink.task);
                
            }
        }
    }
    USB_DEBUG(("\n"));
}
Ejemplo n.º 2
0
/****************************************************************************
NAME 
    usbAudioSinkMatch
    
DESCRIPTION
    Compare sink to the USB audio sink
    
RETURNS
    TRUE if sink matches USB audio sink, otherwise FALSE
*/ 
bool usbAudioSinkMatch(Sink sink)
{
    Source usb_source = NULL;
    UsbDeviceClassGetValue(USB_DEVICE_CLASS_GET_VALUE_AUDIO_SOURCE, (uint16*)&usb_source);

    USB_DEBUG(("USB: usbAudioSinkMatch sink %x = %x, enabled = %x\n", (uint16)sink , (uint16)StreamSinkFromSource(usb_source), USB_CLASS_ENABLED(USB_DEVICE_CLASS_AUDIO) ));

    return (USB_CLASS_ENABLED(USB_DEVICE_CLASS_AUDIO) && sink && (sink == StreamSinkFromSource(usb_source)));
}
Source avrcpSourceFromData(AVRCP *avrcp, uint8 *data, uint16 length)
{
    /* Create a source from the data */
    Source src = StreamRegionSource(data, length);

    /* Register a task for freeing the data and store a ptr to it */
    avrcp->dataFreeTask.sent_data = data;
    MessageSinkTask(StreamSinkFromSource(src), &avrcp->dataFreeTask.cleanUpTask);

    return src;
}
Ejemplo n.º 4
0
/****************************************************************************
NAME 
    usbGetAudioSink
    
DESCRIPTION
    check USB state and return sink if available
    
RETURNS
   sink if available, otherwise 0
*/ 
Sink usbGetAudioSink(void)
{
    Source usb_source = NULL;
    Sink sink = NULL;
    UsbDeviceClassGetValue(USB_DEVICE_CLASS_GET_VALUE_AUDIO_SOURCE, (uint16*)&usb_source);
    
    /* if the usb lead is attached and the speaker is active, try to obtain the audio sink */
    if((usbAudioIsAttached())&&(theSink.usb.spkr_active))
    {
        /* attempt to obtain USB audio sink */
        sink = StreamSinkFromSource(usb_source);
        USB_DEBUG(("USB: usbGetAudioSink sink %x, enabled = %x\n", (uint16)sink , USB_CLASS_ENABLED(USB_DEVICE_CLASS_AUDIO) ));
    }
    /* USB not attached */
    else
        USB_DEBUG(("USB: usbGetAudioSink sink %x, enabled = %x, speaker active = %x\n", (uint16)sink , USB_CLASS_ENABLED(USB_DEVICE_CLASS_AUDIO), theSink.usb.spkr_active ));
    
    return sink;
}
void a2dpProfileHandler(Task task, MessageId id, Message message)
{
    switch (id)
    {
    case A2DP_INTERNAL_L2CAP_CONNECT_REQ + 0:
    case A2DP_INTERNAL_L2CAP_CONNECT_REQ + 1:
    case A2DP_INTERNAL_L2CAP_CONNECT_REQ + 2:
    case A2DP_INTERNAL_L2CAP_CONNECT_REQ + 3:
    case A2DP_INTERNAL_L2CAP_CONNECT_REQ + 4:
    case A2DP_INTERNAL_L2CAP_CONNECT_REQ + 5:
    case A2DP_INTERNAL_L2CAP_CONNECT_REQ + 6:
        PRINT(("A2DP_INTERNAL_L2CAP_CONNECT_REQ\n"));
        a2dpHandleL2capConnectReq((A2DP_INTERNAL_L2CAP_CONNECT_REQ_T *) message);
        break;
    
    case A2DP_INTERNAL_SIGNALLING_CONNECT_REQ:
        PRINT(("A2DP_INTERNAL_SIGNALLING_CONNECT_REQ\n"));
        a2dpHandleSignallingConnectReq((A2DP_INTERNAL_SIGNALLING_CONNECT_REQ_T *) message);
        break;

    case A2DP_INTERNAL_SIGNALLING_CONNECT_RES:
        PRINT(("A2DP_INTERNAL_SIGNALLING_CONNECT_RES\n"));
        a2dpHandleSignallingConnectRes((A2DP_INTERNAL_SIGNALLING_CONNECT_RES_T *) message);
        break;

    case A2DP_INTERNAL_SIGNALLING_DISCONNECT_REQ:
        PRINT(("A2DP_INTERNAL_SIGNALLING_DISCONNECT_REQ\n"));
        a2dpHandleSignallingDisconnectReq((A2DP_INTERNAL_SIGNALLING_DISCONNECT_REQ_T *) message);
        break;

    case A2DP_INTERNAL_CODEC_CONFIGURE_RSP:
        PRINT(("A2DP_INTERNAL_CODEC_CONFIGURE_RSP\n"));
        a2dpHandleCodecConfigureResponse((A2DP_INTERNAL_CODEC_CONFIGURE_RSP_T *) message);
        break;

    case A2DP_INTERNAL_MEDIA_OPEN_REQ:
        PRINT(("A2DP_INTERNAL_OPEN_REQ\n"));
        a2dpStreamEstablish((A2DP_INTERNAL_MEDIA_OPEN_REQ_T *) message);
        break;

    case A2DP_INTERNAL_MEDIA_OPEN_RES:
        PRINT(("A2DP_INTERNAL_OPEN_RES\n"));
        a2dpStreamOpenResponse((A2DP_INTERNAL_MEDIA_OPEN_RES_T *) message);
        break;

    case A2DP_INTERNAL_MEDIA_START_REQ:
        PRINT(("A2DP_INTERNAL_START_REQ\n"));
        a2dpStreamStart((A2DP_INTERNAL_MEDIA_START_REQ_T *) message);
        break;
        
    case A2DP_INTERNAL_MEDIA_START_RES:
        PRINT(("A2DP_INTERNAL_START_RES\n"));
        a2dpStreamStartResponse((A2DP_INTERNAL_MEDIA_START_RES_T *) message);
        break;
        
    case A2DP_INTERNAL_MEDIA_SUSPEND_REQ:
        PRINT(("A2DP_INTERNAL_MEDIA_SUSPEND_REQ\n"));
        a2dpStreamSuspend((A2DP_INTERNAL_MEDIA_SUSPEND_REQ_T *) message);
        break;

    case A2DP_INTERNAL_MEDIA_CLOSE_REQ:
        PRINT(("A2DP_INTERNAL_MEDIA_CLOSE_REQ\n"));
        a2dpStreamRelease((A2DP_INTERNAL_MEDIA_CLOSE_REQ_T *) message);
        break;
        
    case A2DP_INTERNAL_MEDIA_RECONFIGURE_REQ:
        PRINT(("A2DP_INTERNAL_MEDIA_RECONFIGURE_REQ\n"));
        a2dpStreamReconfigure((A2DP_INTERNAL_MEDIA_RECONFIGURE_REQ_T *) message);
        break;
        
    case A2DP_INTERNAL_MEDIA_AV_SYNC_DELAY_REQ:
        PRINT(("A2DP_INTERNAL_MEDIA_AV_SYNC_DELAY_REQ\n"));
        a2dpStreamDelayReport(((A2DP_INTERNAL_MEDIA_AV_SYNC_DELAY_REQ_T *)message)->device, ((A2DP_INTERNAL_MEDIA_AV_SYNC_DELAY_REQ_T *)message)->delay);
        break;
        
    case A2DP_INTERNAL_MEDIA_AV_SYNC_DELAY_RES:
        PRINT(("A2DP_INTERNAL_MEDIA_AV_SYNC_DELAY_RES\n"));
        a2dpStreamDelayReport(((A2DP_INTERNAL_MEDIA_AV_SYNC_DELAY_RES_T *)message)->device, ((A2DP_INTERNAL_MEDIA_AV_SYNC_DELAY_RES_T *)message)->delay);
        break;
        
    case A2DP_INTERNAL_LINKLOSS_TIMEOUT_BASE + 0:
    case A2DP_INTERNAL_LINKLOSS_TIMEOUT_BASE + 1:
    case A2DP_INTERNAL_LINKLOSS_TIMEOUT_BASE + 2:
    case A2DP_INTERNAL_LINKLOSS_TIMEOUT_BASE + 3:
    case A2DP_INTERNAL_LINKLOSS_TIMEOUT_BASE + 4:
    case A2DP_INTERNAL_LINKLOSS_TIMEOUT_BASE + 5:
    case A2DP_INTERNAL_LINKLOSS_TIMEOUT_BASE + 6:
        PRINT(("A2DP_INTERNAL_LINKLOSS_TIMEOUT\n"));
        a2dpHandleL2capLinklossTimeout(id);
        break;
    
    case A2DP_INTERNAL_CLIENT_RSP_TIMEOUT_BASE + 0:
    case A2DP_INTERNAL_CLIENT_RSP_TIMEOUT_BASE + 1:
    case A2DP_INTERNAL_CLIENT_RSP_TIMEOUT_BASE + 2:
    case A2DP_INTERNAL_CLIENT_RSP_TIMEOUT_BASE + 3:
    case A2DP_INTERNAL_CLIENT_RSP_TIMEOUT_BASE + 4:
    case A2DP_INTERNAL_CLIENT_RSP_TIMEOUT_BASE + 5:
    case A2DP_INTERNAL_CLIENT_RSP_TIMEOUT_BASE + 6:
        PRINT(("A2DP_INTERNAL_CLIENT_RSP_TIMEOUT\n"));
        a2dpHandleInternalClientRspTimeout(id);
        break;
    
    case A2DP_INTERNAL_REMOTE_CMD_TIMEOUT_BASE + 0:
    case A2DP_INTERNAL_REMOTE_CMD_TIMEOUT_BASE + 1:
    case A2DP_INTERNAL_REMOTE_CMD_TIMEOUT_BASE + 2:
    case A2DP_INTERNAL_REMOTE_CMD_TIMEOUT_BASE + 3:
    case A2DP_INTERNAL_REMOTE_CMD_TIMEOUT_BASE + 4:
    case A2DP_INTERNAL_REMOTE_CMD_TIMEOUT_BASE + 5:
    case A2DP_INTERNAL_REMOTE_CMD_TIMEOUT_BASE + 6:
        PRINT(("A2DP_INTERNAL_REMOTE_CMD_TIMEOUT\n"));
        a2dpHandleInternalRemoteCmdTimeout(id);
        break;
    
    case A2DP_INTERNAL_WATCHDOG_BASE + 0:
    case A2DP_INTERNAL_WATCHDOG_BASE + 1:
    case A2DP_INTERNAL_WATCHDOG_BASE + 2:
    case A2DP_INTERNAL_WATCHDOG_BASE + 3:
    case A2DP_INTERNAL_WATCHDOG_BASE + 4:
    case A2DP_INTERNAL_WATCHDOG_BASE + 5:
    case A2DP_INTERNAL_WATCHDOG_BASE + 6:
        PRINT(("A2DP_INTERNAL_WATCHDOG_IND\n"));
        a2dpHandleInternalWatchdogTimeout(id);
        break;

#if 0
    case A2DP_INTERNAL_RECONFIGURE_REQ:
        PRINT(("A2DP_INTERNAL_RECONFIGURE_REQ\n"));
        a2dpHandleReconfigureReq((A2DP_INTERNAL_RECONFIGURE_REQ_T *) message);
        break;
#endif

#if 0
    case A2DP_INTERNAL_SEND_CODEC_PARAMS_REQ:
        PRINT(("A2DP_INTERNAL_SEND_CODEC_PARAMS_REQ\n"));
        a2dpSendCodecAudioParams();
        if (((A2DP_INTERNAL_SEND_CODEC_PARAMS_REQ_T *) message)->send_reconfigure_message)
            a2dpSendReconfigureCfm(a2dp_success);
        break;
#endif

#if 0
    case A2DP_INTERNAL_GET_CAPS_TIMEOUT_IND:
        PRINT(("A2DP_INTERNAL_GET_CAPS_TIMEOUT_IND\n"));
        a2dpGetCapsTimeout();
        break;
#endif

    default:
        switch(id)
        {
        case CL_SDP_REGISTER_CFM:
            PRINT(("CL_SDP_REGISTER_CFM\n"));
            a2dpHandleSdpRegisterCfm((CL_SDP_REGISTER_CFM_T *) message);
            break;

        case CL_L2CAP_REGISTER_CFM:
            PRINT(("CL_L2CAP_REGISTER_CFM\n"));
            a2dpHandleL2capRegisterCfm((CL_L2CAP_REGISTER_CFM_T *) message);
            break;

        case CL_L2CAP_CONNECT_IND:
            PRINT(("CL_L2CAP_CONNECT_IND\n"));
            a2dpHandleL2capConnectInd((CL_L2CAP_CONNECT_IND_T *) message);
            break;

        case CL_L2CAP_CONNECT_CFM:
            PRINT(("CL_L2CAP_CONNECT_CFM\n"));
            a2dpHandleL2capConnectCfm((CL_L2CAP_CONNECT_CFM_T *) message);
            break;

        case CL_L2CAP_DISCONNECT_IND:
            PRINT(("CL_L2CAP_DISCONNECT_IND\n"));
            a2dpHandleL2capDisconnect(((CL_L2CAP_DISCONNECT_IND_T *)message)->identifier, ((CL_L2CAP_DISCONNECT_IND_T *)message)->sink, ((CL_L2CAP_DISCONNECT_IND_T *)message)->status);
            ConnectionL2capDisconnectResponse(((CL_L2CAP_DISCONNECT_IND_T *)message)->identifier, ((CL_L2CAP_DISCONNECT_IND_T *)message)->sink);
            break;

        case CL_L2CAP_DISCONNECT_CFM:
            PRINT(("CL_L2CAP_DISCONNECT_CFM\n"));
            a2dpHandleL2capDisconnect(0, ((CL_L2CAP_DISCONNECT_CFM_T *)message)->sink, ((CL_L2CAP_DISCONNECT_CFM_T *)message)->status);
            break;

        case CL_SM_ENCRYPTION_CHANGE_IND:
            PRINT(("CL_SM_ENCRYPTION_CHANGE_IND\n"));
            /* We have received an indication that the encryption status of the sink has changed */
            sendEncryptionChangeInd((CL_SM_ENCRYPTION_CHANGE_IND_T *) message);
            break;

        case CL_DM_ROLE_CFM:
        case CL_SM_ENCRYPTION_KEY_REFRESH_IND:
        case CL_L2CAP_TIMEOUT_IND:
            break;

        case CL_SDP_SERVICE_SEARCH_ATTRIBUTE_CFM:
            a2dpHandleSdpServiceSearchAttributeCfm ((CL_SDP_SERVICE_SEARCH_ATTRIBUTE_CFM_T *)message);
            break;

        default:
            switch(id)
            {
            case MESSAGE_MORE_DATA:
                PRINT(("MESSAGE_MORE_DATA\n"));
                /* Data has arrived on the signalling channel */
                a2dpHandleSignalPacket( a2dpFindDeviceFromSink( StreamSinkFromSource(((MessageMoreData *)message)->source) ));
                break;

            case MESSAGE_MORE_SPACE:
            case MESSAGE_STREAM_DISCONNECT:
            case MESSAGE_SOURCE_EMPTY:
                break;

            default:
                handleUnexpected(id);
                break;
            }
        }
    }
}
void swatHandleSwatSignallingData(Source source)
{
    uint16 packet_size, data_size;
    const uint8 *ptr = SourceMap(source);
    
    /* Get the device that sent the signalling data */
    remoteDevice* device = swatFindDeviceFromSink( StreamSinkFromSource(source) );
    
    packet_size = SourceSize(source);
    
    /* Process each signalling packet in the source (may be more than one signal in the source) */
    while(packet_size >= PKT_PAYLOAD)
    {
        /* calculate size of packet */              
        data_size = ((ptr[PKT_PAYLOAD_LEN] & 0x7f) + 3);
        
        /* Process the signalling data by the remote device */
        switch(ptr[PKT_SIGNAL_ID])
        {
            /*****************************************************************************/
            case SWAT_OPEN:
            {
                /* send to command handler, include message payload  */
                MAKE_SWAT_MESSAGE_WITH_LEN(SWAT_COMMAND_OPEN, data_size);
                message->device = device;                    
                memmove(&message->data[0], &ptr[0], data_size);
                
                /* If message is a response, send immediatley, otherwise add to queue */
                if (ptr[PKT_SIGNAL_TYPE] == SWAT_RSP)
                {
                    MessageSend(&swat->command_task, SWAT_COMMAND_OPEN, message);
                }
                else
                {
                    SWAT_DEBUG(("[SWAT] SWAT_OPEN_CMD [%x]\n", device->signalling_block));
                    
                    /* Action the message or add to queue if already handling another message */
                    MessageSendConditionally(&swat->command_task, SWAT_COMMAND_OPEN, message, &device->signalling_block);
                }
                
                /* command actioned, discard buffer data leaving any additional data behind */
                SourceDrop(source, data_size);
                /* having removed a packet reset the pointer to the start of any more packets */
                ptr = SourceMap(source);
            }
            break;
            /*****************************************************************************/
            case SWAT_CLOSE:
            {
                /* send to command handler, include message payload  */
                MAKE_SWAT_MESSAGE_WITH_LEN(SWAT_COMMAND_CLOSE, data_size);
                message->device = device;                    
                memmove(&message->data[0], &ptr[0], data_size);
                
                /* If message is a response, send immediatley, otherwise add to queue */
                if (ptr[PKT_SIGNAL_TYPE] == SWAT_RSP)
                {
                    MessageSend(&swat->command_task, SWAT_COMMAND_CLOSE, message);
                }
                else
                {
                    SWAT_DEBUG(("[SWAT] SWAT_CLOSE_CMD [%x]\n", device->signalling_block));
                    
                    /* Action the message or add to queue if already handling another message */
                    MessageSendConditionally(&swat->command_task, SWAT_COMMAND_CLOSE, message, &device->signalling_block);
                }
                
                /* command actioned, discard buffer data leaving any additional data behind */
                SourceDrop(source, data_size);
                /* having removed a packet reset the pointer to the start of any more packets */
                ptr = SourceMap(source);
            }
            break;
            /*****************************************************************************/
            case SWAT_START:
            {
                /* send to command handler, include message payload  */
                MAKE_SWAT_MESSAGE_WITH_LEN(SWAT_COMMAND_START, data_size);
                message->device = device;                    
                memmove(&message->data[0], &ptr[0], data_size);
                
                /* If message is a response, send immediatley, otherwise add to queue */
                if (ptr[PKT_SIGNAL_TYPE] == SWAT_RSP)
                {
                    MessageSend(&swat->command_task, SWAT_COMMAND_START, message);
                }
                else
                {
                    SWAT_DEBUG(("[SWAT] SWAT_START_CMD [%x]\n", device->signalling_block));
                    
                    /* Action the message or add to queue if already handling another message */
                    MessageSendConditionally(&swat->command_task, SWAT_COMMAND_START, message, &device->signalling_block);
                }
                
                /* command actioned, discard buffer data leaving any additional data behind */
                SourceDrop(source, data_size);
                /* having removed a packet reset the pointer to the start of any more packets */
                ptr = SourceMap(source);
            }
            break;
            /*****************************************************************************/
            case SWAT_SUSPEND:
            {
                /* send to command handler, include message payload  */
                MAKE_SWAT_MESSAGE_WITH_LEN(SWAT_COMMAND_SUSPEND, data_size);
                message->device = device;                    
                memmove(&message->data[0], &ptr[0], data_size);
                
                /* If message is a response, send immediatley, otherwise add to queue */
                if (ptr[PKT_SIGNAL_TYPE] == SWAT_RSP)
                {
                    MessageSend(&swat->command_task, SWAT_COMMAND_SUSPEND, message);
                }
                else
                {
                    SWAT_DEBUG(("[SWAT] SWAT_SUSPEND_CMD [%x]\n", device->signalling_block));
                    
                    /* Action the message or add to queue if already handling another message */
                    MessageSendConditionally(&swat->command_task, SWAT_COMMAND_SUSPEND, message, &device->signalling_block);    
                }
                
                /* command actioned, discard buffer data leaving any additional data behind */
                SourceDrop(source, data_size);
                /* having removed a packet reset the pointer to the start of any more packets */
                ptr = SourceMap(source);
            }
            break;
            /*****************************************************************************/
            case SWAT_SET_VOLUME:
            {
                /* send to command handler, include message payload  */
                MAKE_SWAT_MESSAGE_WITH_LEN(SWAT_COMMAND_SET_VOLUME, data_size);
                message->device = device;                    
                memmove(&message->data[0], &ptr[0], data_size);
                
                /* If message is a response, send immediatley, otherwise add to queue */
                if (ptr[PKT_SIGNAL_TYPE] == SWAT_RSP)
                {
                    MessageSend(&swat->command_task, SWAT_COMMAND_SET_VOLUME, message);
                }
                else
                {
                    SWAT_DEBUG(("[SWAT] SWAT_SET_VOLUME_CMD [%x]\n", device->signalling_block));
                    
                    /* Action the message or add to queue if already handling another message */
                    MessageSendConditionally(&swat->command_task, SWAT_COMMAND_SET_VOLUME, message, &device->signalling_block);
                }
                
                /* command actioned, discard buffer data leaving any additional data behind */
                SourceDrop(source, data_size);
                /* having removed a packet reset the pointer to the start of any more packets */
                ptr = SourceMap(source);
            }
            break;
            /*****************************************************************************/
            case SWAT_SAMPLE_RATE:
            {
                /* send to command handler, include message payload  */
                MAKE_SWAT_MESSAGE_WITH_LEN(SWAT_COMMAND_SAMPLE_RATE, data_size);
                message->device = device;
                memmove(&message->data[0], &ptr[0], data_size);
                
                /* If message is a response, send immediatley, otherwise add to queue */
                if (ptr[PKT_SIGNAL_TYPE] == SWAT_RSP)
                {
                    MessageSend(&swat->command_task, SWAT_COMMAND_SAMPLE_RATE, message);
                }
                else
                {
                    SWAT_DEBUG(("[SWAT] SWAT_SAMPLE_RATE_CMD [%x]\n", device->signalling_block));
                    
                    /* Action the message or add to queue if already handling another message */
                    MessageSendConditionally(&swat->command_task, SWAT_COMMAND_SAMPLE_RATE, message, &device->signalling_block);
                }
                
                /* Command actioned, discard buffer data leaving any additional data behind */
                SourceDrop(source, data_size);
                /* Having removed a packet reset the pointer to the start of any more packets */
                ptr = SourceMap(source);
            }
            break;
            /*****************************************************************************/
            case SWAT_GET_VERSION:
            {
                /* send to command handler, include message payload  */
                MAKE_SWAT_MESSAGE_WITH_LEN(SWAT_COMMAND_GET_VERSION, data_size);
                message->device = device;
                memmove(&message->data[0], &ptr[0], data_size);
                
                /* If message is a response, send immediatley, otherwise add to queue */
                if (ptr[PKT_SIGNAL_TYPE] == SWAT_RSP)
                {
                    MessageSend(&swat->command_task, SWAT_COMMAND_GET_VERSION, message);
                }
                else
                {
                    SWAT_DEBUG(("[SWAT] SWAT_COMMAND_GET_VERSION [%x]\n", device->signalling_block));
                    
                    /* Action the message or add to queue if already handling another message */
                    MessageSendConditionally(&swat->command_task, SWAT_COMMAND_GET_VERSION, message, &device->signalling_block);
                }
                
                /* Command actioned, discard buffer data leaving any additional data behind */
                SourceDrop(source, data_size);
                /* Having removed a packet reset the pointer to the start of any more packets */
                ptr = SourceMap(source);
            }
            break;
            /*****************************************************************************/
            case SWAT_GENERAL_REJECT:
            {
                /* send to command handler, include message payload  */
                MAKE_SWAT_MESSAGE_WITH_LEN(SWAT_COMMAND_GENERAL_REJECT, data_size);
                message->device = device;                    
                memmove(&message->data[0], &ptr[0], data_size);
                
                /* Handle the GENERAL_REJECT command as it won't affect ongoing operations */
                MessageSend(&swat->command_task, SWAT_COMMAND_GENERAL_REJECT, message);
                
                /* command actioned, discard buffer data leaving any additional data behind */
                SourceDrop(source, data_size);
                /* having removed a packet reset the pointer to the start of any more packets */
                ptr = SourceMap(source);
            }
            break;
            /*****************************************************************************/
            default:
            {
                /* send to command handler, include message payload  */
                MAKE_SWAT_MESSAGE(SWAT_COMMAND_DEFAULT);
                message->device = device;                    
                
                MessageSend(&swat->command_task, SWAT_COMMAND_DEFAULT, message);
                
                /* block any more signalling commands until current process has completed */
                device->signalling_block = DATA_BLOCK;
                
                /* Discard entire buffer as got out of sync */
                SourceDrop(source, packet_size);
            }
        }
        /* recalculate the packet size of any data left in the source */
        packet_size = SourceSize(source);    
    }
}
Ejemplo n.º 7
0
static void handleHidClassRequest(Source source, usb_device_class_type class_type)
{
    static uint8 idle_rate = 0;
    
    {    
        Sink sink = StreamSinkFromSource(source);
        uint16 packet_size;

        while ((packet_size = SourceBoundary(source)) != 0)
        {
            /* Build the respnse. It must contain the original request, so copy 
               from the source header. */
            UsbResponse resp;
            memcpy(&resp.original_request, SourceMapHeader(source), sizeof(UsbRequest));
        
            /* Set the response fields to default values to make the code below simpler */
            resp.success = FALSE;
            resp.data_length = 0;
        
            switch (resp.original_request.bRequest)
            {
                /* GET_REPORT */
                case 0x01:
                {
                    PRINT(("USB: HID Get_Report src=0x%X wValue=0x%X wIndex=0x%X wLength=0x%X\n", (uint16)source, resp.original_request.wValue, resp.original_request.wIndex, resp.original_request.wLength));
                    break;
                }
            
                /* GET_IDLE */
                case 0x02:
                {
                    uint8 *out;
                    if ((out = claimSink(sink, 1)) != 0)
                    {
                        PRINT(("USB: HID Get_Idle src=0x%X wValue=0x%X wIndex=0x%X\n", (uint16)source, resp.original_request.wValue, resp.original_request.wIndex));
                        out[0] = idle_rate;
                        resp.success = TRUE;
                        resp.data_length = 1;                
                    }
                    break;
                }
            
                /* SET_REPORT */
                case 0x09:
                {
                    const uint8 *in = SourceMap(source);                    
                    uint16 size_data = resp.original_request.wLength;                
                    uint8 report_id = resp.original_request.wValue & 0xff;
                    PRINT(("USB: HID Set_Report src=0x%X wValue=0x%X wIndex=0x%X wLength=0x%X -> \n", (uint16)source, resp.original_request.wValue, resp.original_request.wIndex, resp.original_request.wLength));
                  
                    resp.success = TRUE;
                                                            
                    if (size_data)
                    {
                        if (class_type == USB_DEVICE_CLASS_TYPE_HID_CONSUMER_TRANSPORT_CONTROL)
                        {
                            USB_DEVICE_CLASS_MSG_REPORT_IND_T *message = PanicUnlessMalloc(sizeof(USB_DEVICE_CLASS_MSG_REPORT_IND_T) + size_data);
                            uint16 source_size = SourceSize(source);
                            
                            PRINT(("    send report ind source_size[0x%x]\n", source_size));
                            
                            message->class_type = class_type;
                            message->report_id = report_id;
                            message->size_report = size_data;
                            
                            in = SourceMap(source);  
                            if (source_size < message->size_report)
                            {
                                message->size_report = source_size;                                    
                            }
                            memmove(message->report, in, message->size_report);
                            MessageSend(device->app_task, USB_DEVICE_CLASS_MSG_REPORT_IND, message);
                            PRINT(("    sent report ind to Task [0x%x]\n", (uint16)device->app_task));
                        }
                    }                                     
                    break;
                }
            
                /* SET_IDLE */
                case 0x0A:    
                {
                    PRINT(("USB: HID Set_Idle src=0x%X wValue=0x%X wIndex=0x%X\n", (uint16)source, resp.original_request.wValue, resp.original_request.wIndex));
                    idle_rate = resp.original_request.wValue >> 8;
                    resp.success = TRUE;
                    break;
                }
            
                default:
                {
                    PRINT(("USB: HID req=0x%X src=0x%X wValue=0x%X wIndex=0x%X wLength=0x%X\n", resp.original_request.bRequest, (uint16)source, resp.original_request.wValue, resp.original_request.wIndex, resp.original_request.wLength));
                    break;            
                }
            }
        
            /* Send response */
            if (resp.data_length)
            {
                (void)SinkFlushHeader(sink, resp.data_length, (uint16 *)&resp, sizeof(UsbResponse));
            }
            else
            {
                   /* Sink packets can never be zero-length, so flush a dummy byte */
                (void) SinkClaim(sink, 1);
                (void) SinkFlushHeader(sink, 1, (uint16 *) &resp, sizeof(UsbResponse));          
            }   

            /* Discard the original request */
              SourceDrop(source, packet_size);
        }
    }
}
Ejemplo n.º 8
0
void ConnectionHandleComplexMessage(Task task, MessageId id, Message message)
{
    switch (id)
    {
        case CL_L2CAP_CONNECT_IND:
            {
                CL_L2CAP_CONNECT_IND_T *original;
                CL_L2CAP_CONNECT_IND_TEST_EXTRA_T *new_msg = 
                    malloc(sizeof(CL_L2CAP_CONNECT_IND_TEST_EXTRA_T));
                original = (CL_L2CAP_CONNECT_IND_T *) message;
            
                new_msg->bd_addr = original->bd_addr;
                new_msg->psm = original->psm;
                new_msg->cid = original->connection_id;
                new_msg->identifier = original->identifier;
                new_msg->task = (uint16) task;
                MessageSend(task, CL_L2CAP_CONNECT_IND_TEST_EXTRA, new_msg);
            }
            break;

        case CL_L2CAP_CONNECT_CFM:
            {
                CL_L2CAP_CONNECT_CFM_T *original;
                CL_L2CAP_CONNECT_CFM_TEST_EXTRA_T *new_msg = 
                    malloc(sizeof(CL_L2CAP_CONNECT_CFM_TEST_EXTRA_T));
                original = (CL_L2CAP_CONNECT_CFM_T *) message;

                new_msg->status = original->status;
                new_msg->psm_local = original->psm_local;
                new_msg->sink = original->sink;
                new_msg->connection_id = original->connection_id;
                new_msg->mtu_remote = original->mtu_remote;
                new_msg->flush_timeout_remote = original->flush_timeout_remote;
                new_msg->qos_remote = original->qos_remote;
                new_msg->flow_mode = original->mode;
                new_msg->task = (uint16) MessageSinkGetTask(original->sink);
                MessageSend(task, CL_L2CAP_CONNECT_CFM_TEST_EXTRA, new_msg);
            }
            break;
            
        case MESSAGE_MORE_DATA:
            {
                Source src = ((MessageMoreData*)message)->source;
                CL_SYSTEM_MORE_DATA_TEST_EXTRA_T *pdu;
                const uint8 *s = SourceMap(src);
                uint16 len = SourceBoundary(src);
                uint16 datalen=len;
                
                /* Do not allow large data more than 512 ..Just Limit to 
                 * 128 bytes.
                 */
                if(len > 128) len=128;
                
                pdu = malloc(sizeof(CL_SYSTEM_MORE_DATA_TEST_EXTRA_T)+len);
                memset(pdu, 0, sizeof(CL_SYSTEM_MORE_DATA_TEST_EXTRA_T));
                
                pdu->sink = StreamSinkFromSource(src);
                pdu->size_data = datalen;
                
                memmove(pdu->data, s, len);
                
                SourceDrop(src, datalen);
                
                MessageSend(task, CL_SYSTEM_MORE_DATA_TEST_EXTRA, pdu);
            }
                break;
            
        case MESSAGE_MORE_SPACE:
        case MESSAGE_SOURCE_EMPTY:
            break;

        case CL_SM_READ_LOCAL_OOB_DATA_CFM:
            {
                /* Create new message */
                CL_SM_READ_LOCAL_OOB_DATA_CFM_T *original;
                CL_SM_READ_LOCAL_OOB_DATA_CFM_TEST_EXTRA_T *new_msg = 
                    malloc(
                        sizeof(CL_SM_READ_LOCAL_OOB_DATA_CFM_TEST_EXTRA_T) 
                        + (2 * CL_SIZE_OOB_DATA)
                        );
                original = (CL_SM_READ_LOCAL_OOB_DATA_CFM_T*)message;
                /* Copy over the status */
                new_msg->status = original->status;
                /* Copy over transport */
                new_msg->transport = original->transport;
                /* Copy over what type of OOB data is present */
                new_msg->oob_data_present = original->oob_data;
                /* Set size */
                new_msg->size_oob_data = 2*CL_SIZE_OOB_DATA;
                /* Copy over the OOB data */
                memmove(
                    new_msg->oob_data,
                    original->oob_hash_c,
                    CL_SIZE_OOB_DATA
                    );
                memmove(
                    new_msg->oob_data+CL_SIZE_OOB_DATA,
                    original->oob_rand_r,
                    CL_SIZE_OOB_DATA
                    );
                /* Send it to the app */
                MessageSend(
                    task,
                    CL_SM_READ_LOCAL_OOB_DATA_CFM_TEST_EXTRA,
                    new_msg
                    );
            }
                break;

        /* Flatten CL_SM_GET_INDEXED_ATTRIBUTE_CFM */
        case CL_SM_GET_INDEXED_ATTRIBUTE_CFM:
        {
            CL_SM_GET_INDEXED_ATTRIBUTE_CFM_T *original = 
                (CL_SM_GET_INDEXED_ATTRIBUTE_CFM_T *) message;
            CL_SM_GET_INDEXED_ATTRIBUTE_CFM_TEST_EXTRA_T *new_msg = 
                malloc(
                    sizeof(CL_SM_GET_INDEXED_ATTRIBUTE_CFM_TEST_EXTRA_T) 
                    + (original->size_psdata * sizeof(uint8))
                    - 1     /* for the psdata array of 1 */
                    );

            new_msg->status = original->status;
            new_msg->type = original->taddr.type;
            new_msg->bd_addr = original->taddr.addr;
            new_msg->size_psdata = original->size_psdata;
            memmove(new_msg->psdata, original->psdata, original->size_psdata);

            /* Send the copied message to the app. */
            MessageSend(
                task,
                CL_SM_GET_INDEXED_ATTRIBUTE_CFM_TEST_EXTRA,
                new_msg
                );
        }
            break;
                    
        FLATTEN_BDADDR(CL_DM_ACL_OPENED_IND); 
        FLATTEN_BDADDR(CL_DM_ACL_CLOSED_IND);
        FLATTEN_BDADDR(CL_DM_APT_IND);
        FLATTEN_BDADDR(CL_SM_USER_PASSKEY_REQ_IND);
        FLATTEN_BDADDR(CL_SM_USER_PASSKEY_NOTIFICATION_IND);
        FLATTEN_BDADDR(CL_SM_USER_CONFIRMATION_REQ_IND);
        FLATTEN_BDADDR(CL_SM_PIN_CODE_IND);
        FLATTEN_BDADDR(CL_SM_ENCRYPTION_KEY_REFRESH_IND);
        FLATTEN_BDADDR(CL_SM_ENCRYPTION_CHANGE_IND);
        FLATTEN_BDADDR(CL_SM_IO_CAPABILITY_REQ_IND);
        FLATTEN_BDADDR(CL_SM_REMOTE_IO_CAPABILITY_IND);

#ifndef DISABLE_BLE
        /* Flatten the typed_bdaddr parts of the message - grrr! */
        case CL_DM_BLE_ADVERTISING_REPORT_IND:
        {
            CL_DM_BLE_ADVERTISING_REPORT_IND_T *original = 
                (CL_DM_BLE_ADVERTISING_REPORT_IND_T *)message;
            CL_DM_BLE_ADVERTISING_REPORT_IND_TEST_EXTRA_T *new_msg = 
                (CL_DM_BLE_ADVERTISING_REPORT_IND_TEST_EXTRA_T *) 
                    PanicUnlessMalloc(
                        sizeof(CL_DM_BLE_ADVERTISING_REPORT_IND_TEST_EXTRA_T) +
                        original->size_advertising_data - 1
                        );
            new_msg->num_reports = original->num_reports;
            new_msg->event_type  = original->event_type;
            new_msg->current_addr_type = original->current_taddr.type;
            new_msg->current_addr = original->current_taddr.addr;
            new_msg->permanent_addr_type = original->permanent_taddr.type;
            new_msg->permanent_addr = original->permanent_taddr.addr;
            new_msg->rssi = original->rssi;

            new_msg->size_ad_data = original->size_advertising_data;
            memmove(
                new_msg->ad_data,
                original->advertising_data,
                original->size_advertising_data
                );
            MessageSend(
                task, 
                CL_DM_BLE_ADVERTISING_REPORT_IND_TEST_EXTRA, 
                new_msg
                );
        }
        break;

        FLATTEN_BDADDR(CL_SM_BLE_SIMPLE_PAIRING_COMPLETE_IND);
        FLATTEN_BDADDR(CL_DM_BLE_SECURITY_CFM);
        FLATTEN_BDADDR(CL_DM_BLE_CONFIGURE_LOCAL_ADDRESS_CFM);
#endif

        default:
            printf("CL_MESSAGE_TOP 0x%X\n", CL_MESSAGE_TOP);
            printf("CL_SHIM_MESSAGE_TOP 0x%X\n", CL_SHIM_MESSAGE_TOP);
            printf("Message received id 0x%X\n", id);
            Panic();
            break;
    }
}