Example #1
0
/****************************************************************************
NAME	
    goepGetTheTask

DESCRIPTION
    This function returns the GOEP library task so that the GOEP library can use it.

RETURNS
    The GOEP library task.
*/
Task goepGetTheTask(void)
{
	goepState *theGoep = PanicUnlessNew(goepState);
	memset(theGoep, 0, sizeof(goepState));
	theGoep->task.handler = goepHandler;
    return &(theGoep->task);
}
Example #2
0
void GattInitEx(Task theAppTask, uint16 size_database, uint16* database, uint16 flags)
{
    if (theGatt)
    {
        GATT_DEBUG(("ERROR: Gatt Library already initialised.\n"));
    }
    else
    {
        theGatt = PanicUnlessNew(gattState);
        memset(theGatt, 0, sizeof(gattState));
        
        if (MessageAttTask(&theGatt->task))
            GATT_DEBUG(("ERROR: ATT Task already registered\n"));
    }
        

    theGatt->theAppTask         = theAppTask;
    theGatt->task.handler       = gattMessageHandler;
    theGatt->state              = gatt_state_initialising;
    theGatt->flags              = flags;

    theGatt->u.database.ptr     = database;
    theGatt->u.database.size    = size_database;

    /* Register with ATT protocol to start intialisation. */
    {
        MAKE_ATT_PRIM(ATT_REGISTER_REQ);
        VmSendAttPrim(prim);
    }
}
Example #3
0
/****************************************************************************
NAME
    deviceManagerUpdateAttributes
    
DESCRIPTION
    Stores the current attribute values for a given HFP/A2DP connection in
    PS.

RETURNS
    void
*/
void deviceManagerUpdateAttributes(const bdaddr* bd_addr, sink_link_type link_type, hfp_link_priority hfp_priority, a2dp_link_priority a2dp_priority)
{
    EVENT_UPDATE_ATTRIBUTES_T* update = PanicUnlessNew(EVENT_UPDATE_ATTRIBUTES_T);
    
    memset(update,0,sizeof(EVENT_UPDATE_ATTRIBUTES_T)); 
    
    update->bd_addr = *bd_addr;
    
    if(link_type == sink_hfp)
    {
        update->attributes.profiles = sink_hfp;
        update->attributes.hfp.volume = theSink.profile_data[PROFILE_INDEX(hfp_priority)].audio.gSMVolumeLevel;
    }
    else if(link_type == sink_a2dp)
    {
        update->attributes.profiles = sink_a2dp;
        update->attributes.a2dp.volume = theSink.a2dp_link_data->gAvVolumeLevel[a2dp_priority];
        update->attributes.a2dp.clock_mismatch = theSink.a2dp_link_data->clockMismatchRate[a2dp_priority];
    }
#ifdef ENABLE_SUBWOOFER
    else if(link_type == sink_swat)
    {
        update->attributes.profiles = sink_swat;
        update->attributes.sub.sub_trim = theSink.rundata->subwoofer.sub_trim_idx;
    }
#endif        

    DEV_DEBUG(("DEV: DelayUpdateAttributes - type %d profiles %d, hfp_vol %d, a2dp_vol %d\n",link_type, update->attributes.profiles, update->attributes.hfp.volume, update->attributes.a2dp.volume));
    MessageSendConditionally(&theSink.task, EventUpdateAttributes, update, (const uint16 *)AudioBusyPtr());
}
static void avrcpSendControlMessage(avrcp_controls control)
{
	if ( stateManagerIsAvrcpConnected() )
    {
		APP_AVRCP_CONTROLS_T *message = PanicUnlessNew(APP_AVRCP_CONTROLS_T);
		message->control = control;
		MessageSendConditionally(&theHeadset.task, APP_AVRCP_CONTROLS, message, &theHeadset.avrcp_data.pending);
	}
}
/****************************************************************************
NAME
    sendErrorToClient

DESCRIPTION
    Helper function to send the error message to the client task
*/
static void sendErrorToClient(void)
{
    /* Build the plugin error message to let the application know something serious in the plugin has failed */
    AUDIO_PLUGIN_DSP_IND_T * message = PanicUnlessNew(AUDIO_PLUGIN_DSP_IND_T);
    message->id = SUB_PLUGIN_FATAL_ERROR;
    message->size_value = 1;
    message->value[0] = 0;
    
    /* Ensure all streams have been disconnected and DSP turned off before sending error (also free's all memory used by the plugin to prevent memory leak) */
    CsrSubwooferPluginDisconnect();
    
    MessageSend(plugin_data->app_task, AUDIO_PLUGIN_DSP_IND, message);
}
/* Another dummy param to stop RFCLI breaking */
void ConnectionBleClearAdvertisingReportFilterTestExtra(
        Task theAppTask,
        uint16 dummy
        )
{
    CL_BLE_CLEAR_ADVERTISING_FILTER_CFM_TEST_EXTRA_T * cfm = 
        PanicUnlessNew(CL_BLE_CLEAR_ADVERTISING_FILTER_CFM_TEST_EXTRA_T);

    dummy = dummy;

    cfm->result = ConnectionBleClearAdvertisingReportFilter();
    
    MessageSend(theAppTask,CL_BLE_CLEAR_ADVERTISING_FILTER_CFM_TEST_EXTRA, cfm);
}
Example #7
0
void SwatInit(Task clientTask, uint16 max_remote_devs, swat_role role, bool auto_handle, const uint8 *service_record, uint16 size_service_record, const sync_config_params * esco_config)
{
    /* Attempt to initialise the task data */
    if ( !swat )
    {
        swat = PanicUnlessNew(swatTaskData);
        memset( swat, 0, sizeof(swatTaskData) );
        
        SWAT_DEBUG(("[SWAT] Sizeof(swatTaskData) = %u\n", sizeof(swatTaskData)));
        
        /* Initialise the swat profile data */
        swat->l2cap_task.handler = swatL2capHandler;
        swat->profile_task.handler = swatProfileHandler;
        swat->command_task.handler = swatCommandHandler;
        swat->clientTask = clientTask;
        swat->auto_handle = auto_handle;
        swat->role = role;
        swat->max_remote_devs = max_remote_devs;

        /* Allocate memory to store remote device data depending on number of allowed devices */
        swat->remote_devs = (remoteDevice *)PanicNull(malloc(max_remote_devs * sizeof(remoteDevice)));
        memset(swat->remote_devs, 0, (max_remote_devs * sizeof(remoteDevice)));
        
        /* Use service record supplied by client */
        if (service_record)
        {
            ConnectionRegisterServiceRecord(&swat->l2cap_task, (sizeof(uint8) * size_service_record), service_record);
        }
        /* Use library default service record */
        else
        {
            ConnectionRegisterServiceRecord(&swat->l2cap_task, sizeof(swat_service_record), swat_service_record);
        }
        
        /* Use eSCO config supplied by client */
        if (esco_config)
        {
            swat->esco_config = esco_config;
        }
        else
        {
            swat->esco_config = NULL;
        }
    }
    else
    {
        swatSendInitCfmToClient(swat_init_failed);
    }
}
Example #8
0
/******************************************************************************
 *
 * soundClearPluginToggleScActive()
 *
 * Description:
 *   Interface function for SoundClear plugin to enable/disable SoundClear
 *   processing.
 *
 * Arguments:
 *   uint16 scEnable
 *     [in] 1:Enable SoundClear;0:Disable SoundClear.
 *
 * Return Value:
 *   None
 *
 *****************************************************************************/
void soundClearPluginToggleScActive(uint16 scEnable)
{
  /* Send a message to handleAudioMessage so that it can handle the request
     with the Audio Manager Framework messages. */
  ScPluginToggleScActiveMsgT *pScPluginToggleScActiveMsg
        = PanicUnlessNew(ScPluginToggleScActiveMsgT);

  scPluginPrintf(("soundClearPluginToggleScActive\n"));

  pScPluginToggleScActiveMsg->scEnable = scEnable;

  /* Message Will be sent when AUDIO_BUSY is zero */
  MessageSendConditionally((TaskData *)&soundclearPlugin,
                           SCPLUGINTOGGLESCACTIVEMSG,
                           pScPluginToggleScActiveMsg,
                           (const uint16 *)&AUDIO_BUSY);
}
Example #9
0
/******************************************************************************
 *
 * soundClearPluginSetScConfig()
 *
 * Description:
 *   Sets the SoundClear DSP Software tuning configuration.  This function
 *   should be called after AudioConnect() and
 *   soundClearPluginSetCodecConfig().
 *
 * Arguments:
 *   uint16 scPskey
 *     [in] The absolute address of the SoundClear DSP Software configuration
 *          PSKEY
 *
 * Return Value:
 *   None
 *
 *****************************************************************************/
void soundClearPluginSetScConfig(uint16 scPskey)
{
  /* Send a message to handleAudioMessage so that it can handle the request
     with the Audio Manager Framework messages. */
  ScPluginSetScCfgMsgT *pScPluginSetScCfgMsg
        = PanicUnlessNew(ScPluginSetScCfgMsgT);

  scPluginPrintf(("soundClearPluginSetScConfig\n"));

  pScPluginSetScCfgMsg->scPskey = scPskey;

  /* Message Will be sent when AUDIO_BUSY is zero*/
  MessageSendConditionally((TaskData *)&soundclearPlugin,
                           SCPLUGINSETSCCFGMSG,
                           pScPluginSetScCfgMsg,
                           (const uint16 *)&AUDIO_BUSY);
}
Example #10
0
void ConnectionDmBleSetConnectionParametersReqTestExtra(
        uint16      size_param_arr,
        const uint8 *param_arr
        )
{
    ble_connection_params *params = PanicUnlessNew(ble_connection_params);

    uint16 size_arr =  size_param_arr/2;
    uint16 *u16_array = malloc( sizeof(uint16) * size_arr);
    uint16 *ptr = u16_array;
    uint16 idx;

    for(idx=0; idx<size_param_arr; idx+=2)
    {
        *(ptr++) = ((uint16)param_arr[idx] << 8) | (param_arr[idx+1]);
    }

    if (size_arr > sizeof(ble_connection_params))
        size_arr = sizeof(ble_connection_params);

    /* setup defaults, in case the array falls short. */
    params->scan_interval           = 0x0010;
    params->scan_window             = 0x0010;
    params->conn_interval_min       = 0x0010;
    params->conn_interval_max       = 0x0010;
    params->conn_latency            = 0x0040;
    params->supervision_timeout     = 0x0BB8;   /* 30-seconds */
    params->conn_attempt_timeout    = 0x03E8;   /* 10-seconds */
    params->adv_interval_min        = 0x0020;
    params->adv_interval_max        = 0x0020;
    params->conn_latency_max        = 0x0040;
    params->supervision_timeout_min = 0x01F4;   /* 5 seconds */
    params->supervision_timeout_max = 0x0c80;   /* 32 seconds */
    params->own_address_type        = 0;

    memmove(params, u16_array, size_arr);
    free(u16_array);

    ConnectionDmBleSetConnectionParametersReq(params);
   
    free(params);
}
void ConnectionBleAddAdvertisingReportFilterTestExtra(
        Task theAppTask,
        ble_ad_type ad_type,
        uint16 interval,
        uint16 size_pattern,
        const uint8 * pattern
        )
{
    CL_BLE_ADD_ADVERTISING_FILTER_CFM_TEST_EXTRA_T * cfm = 
        PanicUnlessNew(CL_BLE_ADD_ADVERTISING_FILTER_CFM_TEST_EXTRA_T);

    cfm->result = ConnectionBleAddAdvertisingReportFilter(
                        ad_type,
                        interval,
                        size_pattern,
                        pattern
                        );
    
    MessageSend(theAppTask,CL_BLE_ADD_ADVERTISING_FILTER_CFM_TEST_EXTRA, cfm);
}
/* Use for directed advertising params */
void ConnectionDmBleSetAdvertisingParamsReqTestExtra(
        bool                    random_own_address,
        uint8                   channel_map,
        bool                    random_direct_address,
        const bdaddr            *bd_addr
        )
{
    ble_adv_params_t *params = PanicUnlessNew(ble_adv_params_t);

    params->direct_adv.random_direct_address = random_direct_address;
    memmove(&params->direct_adv.direct_addr, bd_addr, sizeof(bdaddr));

    /* ble_adv_type is fixed to direct advertising.*/
    ConnectionDmBleSetAdvertisingParamsReq(
            ble_adv_direct_ind,
            random_own_address,
            channel_map,
            params
            );
    free(params);
}
void connectionStoreCompletedConnection(Task app_task, bdaddr addr, uint16 psm, cid_t cid)
{
	conn_task_map *map;
	multiple_channels_instance* conn = NULL;
	multiple_channels_instance data;
    map_id id;

    id.psm = psm;

    /* Get the task map based on the id as this has the task recipe */
    map = connectionFindTaskMap(conn_l2cap, id);

	if (map && map->task_recipe && (map->task_recipe->max_channels > 1))
	{
		/* Add new completed connection */

		if (multiple_channels_list_head == NULL)
		{
			conn = PanicUnlessNew(multiple_channels_instance);
		}
		else
		{	
			conn = (multiple_channels_instance*) realloc(multiple_channels_list_head, sizeof(multiple_channels_instance) * (multiple_channels_entries+1));

			if (!conn)
				Panic();
		}

		data.appTask = app_task;
		data.psm = psm;
		data.addr = addr;
		data.cid = cid;

		memmove(conn + multiple_channels_entries, &data, sizeof(multiple_channels_instance));

		multiple_channels_entries++;
		multiple_channels_list_head = conn;
	}
}
void SppConnectResponse(Task theAppTask, const bdaddr *bd_addr, const bool response, const Sink sink, const uint8 local_server_channel, const uint16 max_payload_size)
{
    /* Create the Sppc task */
    SPP *spp = PanicUnlessNew(SPP);

    rfcomm_config_params rfcomm_config = 
        {
        RFCOMM_DEFAULT_PAYLOAD_SIZE,
        RFCOMM_DEFAULT_MODEM_SIGNAL,
        RFCOMM_DEFAULT_BREAK_SIGNAL,
        RFCOMM_DEFAULT_MSC_TIMEOUT
        };

    SPP_PRINT(("SPP Server Task Created.\n"));
    
    spp->c.task.handler= sppsConnectionHandler;
    spp->c.client_task = theAppTask;
    spp->c.sink = sink;
    spp->c.bd_addr = *bd_addr;
    spp->c.max_payload_size = max_payload_size;
    spp->c.state = sppConnecting;
    spp->server_channel = local_server_channel;

    /* If the response is negative, then the CL_RFCOM_SERVER_CONNECT_CFM will 
     * indicate that the connection was unsuccessful and put the SPP Server 
     * into the disconnecting state to tidy up
     */
    if (spp->c.max_payload_size)
        rfcomm_config.max_payload_size = spp->c.max_payload_size;

    ConnectionRfcommConnectResponse(
        &spp->c.task,
        response,
        sink,
        local_server_channel,
        &rfcomm_config
        );
}
/* Used for undirected advertising params */
void ConnectionDmBleSetAdvertisingParamsReqTestExtraDefault(
        ble_adv_type            adv_type,
        bool                    random_own_address,
        uint8                   channel_map,
        uint16                  adv_interval_min,
        uint16                  adv_interval_max, 
        ble_adv_filter_policy   filter_policy
        )
{
    ble_adv_params_t *params = PanicUnlessNew(ble_adv_params_t);

    params->undirect_adv.adv_interval_min = adv_interval_min;
    params->undirect_adv.adv_interval_max = adv_interval_max;
    params->undirect_adv.filter_policy    = filter_policy;

    ConnectionDmBleSetAdvertisingParamsReq(
            adv_type,
            random_own_address,
            channel_map,
            params
            );
    free(params);
}
void AvrcpConnectLazy(Task clientTask, const bdaddr *bd_addr, const avrcp_init_params *config)
{
    if (!config)
    {
        /* Client must pass down a valid config so report connect fail */
        MAKE_AVRCP_MESSAGE(AVRCP_CONNECT_CFM);
	    message->status = avrcp_fail;
	    message->sink = 0;
	    message->avrcp = 0;
	    MessageSend(clientTask, AVRCP_CONNECT_CFM, message);

        /* 
            TODO use fun below but it needs updating
        avrcpSendCommonCfmMessageToApp(AVRCP_CONNECT_CFM, avrcp_fail, 0, avrcp);
        */
    }
    else
    {
        AVRCP *avrcp = PanicUnlessNew(AVRCP);
        avrcpInitTaskData(avrcp, clientTask, avrcpReady, config->device_type, config->supported_controller_features, config->supported_target_features, config->profile_extensions, 1);
        avrcpSendInternalConnectReq(avrcp, bd_addr);
    }
}
Example #17
0
void handleInternalPluginMessage(Task task, MessageId id, Message message)
{
    switch(id)
    {
        case MESSAGE_FROM_KALIMBA:
        {
            const DSP_REGISTER_T *msg = (const DSP_REGISTER_T *)message;
            
            /* Handle the message sent from Kalimba */
            switch(msg->id)
            {
                case MUSIC_READY_MSG:
                {
                    PRINT(("[SW_PLUGIN] : MUSIC_READY_MSG a[%x] b[%x] c[%x] d[%x]\n", msg->a, msg->b, msg->c, msg->d));
                    if (plugin_data)
                    {
                        /* Send parameters PSKEY to DSP */
                        KalimbaSendMessage(MUSIC_LOADPARAMS_MSG, MUSIC_PS_BASE, 0, 0, 0);
                    }
                    else
                    {
                        SetCurrentDspStatus(DSP_ERROR);
                    }
                }
                break;
                case MUSIC_PARAMS_LOADED_MSG:
                {
                    /* Send a message to the app to inform the number of subwoofer volume gains (for ADC mode) */
                    AUDIO_PLUGIN_DSP_IND_T * message = PanicUnlessNew(AUDIO_PLUGIN_DSP_IND_T);
                    message->id = SUB_PLUGIN_NUM_VOL_GAINS;
                    message->size_value = 1;
                    message->value[0] = msg->a;
                    MessageSend(plugin_data->app_task, AUDIO_PLUGIN_DSP_IND, message);
                    
                    PRINT(("[SW_PLUGIN] : MUSIC_PARAMS_LOADED_MSG a[%x] b[%x] c[%x] d[%x]\n", msg->a, msg->b, msg->c, msg->d));
                    
                    /* Connect input and output streams */
                    connectAudioStreams();
                    
                    /* Send Volume to DSP */
                    KalimbaSendMessage(MUSIC_VOLUME_MSG, plugin_data->swat_system_volume_db, plugin_data->swat_trim_gain_db, 0, plugin_data->adc_volume_index);
                    
                    /* Set the DSP status */
                    SetCurrentDspStatus(DSP_RUNNING);
                    
                    /* Send GO to DSP */
                    PanicFalse(KalimbaSendMessage(KALIMBA_MSG_GO, 0, 0, 0, 0));
                    
                    /* Send a message to the app to inform that the plugin is ready to recieve audio data */
                    MessageSend(plugin_data->app_task, AUDIO_PLUGIN_DSP_READY_FOR_DATA, 0);
                }
                break;
                case MUSIC_CODEC_MSG:
                {
                    PRINT(("[SW_PLUGIN] : MUSIC_CODEC_MSG a[%x] b[%x] c[%x] d[%x]\n", msg->a, msg->b, msg->c, msg->d));
                    
                    /* Parameters for this message :                */
                    /* msg->a BITS[0-3] = input gain                */
                    /* msg->a BIT[15]   = enable/disable mic preamp */
                    /* msg->b = output gain                         */
                    
                    /* Only set the input gain if using the ADC input (ESCO/L2CAP inputs don't use the ADC) */
                    if (plugin_data->input == SUBWOOFER_INPUT_ADC)
                    {
                        PRINT(("[SW PLUGIN] : Set ADC input GAIN[%x] Pre-amp enable[%x]\n", (msg->a & 0x1F), (msg->a>>15) & 0x1));
                        AudioPluginSetMicGain(plugin_data->audio_source, FALSE, (msg->a & 0x1F), (msg->a>>15) & 0x1);
                    }
                    
                    PRINT(("[SW PLUGIN] : Set DAC GAIN[%x]\n", msg->b));

                    /* Set the codec output gain according to what the DSP sent */
                    if (plugin_data->output == SUBWOOFER_OUTPUT_I2S)
                    {
                        CsrI2SAudioOutputSetVolume(FALSE, msg->b, msg->b, FALSE);
                    }
                    else
                    {
                        CodecSetOutputGainNow(plugin_data->codec_task, msg->b, left_and_right_ch);
                    }
                }
                break;
                case MUSIC_CUR_EQ_BANK:
                {
                    PRINT(("[SW_PLUGIN] : MUSIC_CUR_EQ_BANK a[%x] b[%x] c[%x] d[%x]\n", msg->a, msg->b, msg->c, msg->d));
                    
                    /* TODO */
                }
                break;
                case MUSIC_SIGNAL_DETECT_STATUS:
                {
                    /* msg->a = 1 if playing audio, 0 if audio is silent */
                    PRINT(("[SW_PLUGIN] : MUSIC_SIGNAL_DETECT_STATUS a[%x]\n", msg->a));
                    
                    if (msg->a)
                    {
                        /* Audio on wired input has been detected - Inform client task */
                        AUDIO_PLUGIN_DSP_IND_T * message = PanicUnlessNew(AUDIO_PLUGIN_DSP_IND_T);
                        message->id = SUB_PLUGIN_ADC_SIGNAL_ACTIVE;
                        message->size_value = 1;
                        message->value[0] = 0;
                        MessageSend(plugin_data->app_task, AUDIO_PLUGIN_DSP_IND, message);
                    }
                    else
                    {
                        /* Audio on wired input is now silent - Inform client task */
                        AUDIO_PLUGIN_DSP_IND_T * message = PanicUnlessNew(AUDIO_PLUGIN_DSP_IND_T);
                        message->id = SUB_PLUGIN_ADC_SIGNAL_IDLE;
                        message->size_value = 1;
                        message->value[0] = 0;
                        MessageSend(plugin_data->app_task, AUDIO_PLUGIN_DSP_IND, message);
                    }
                 }
                break;
                default:
                {
                    PRINT(("[SW_PLUGIN] : Unhandled message from Kalimba ID[%x]\n", msg->id));
                }
                break;
            }
        }
        break;
        default:
        {
            PRINT(("[SW_PLUGIN] : Unhandled internal message ID[%x]\n", id));
        }
        break;
    }
Example #18
0
void A2dpInit(Task clientTask, uint16 role, service_record_type *service_records, uint16 size_seps, sep_data_type *seps, uint16 linkloss_timeout)
{
    /* Initialise the task data */
    if ( !a2dp )
    {
        uint8 device_id;
        
        a2dp = PanicUnlessNew(A2DP);
        memset( a2dp, 0, sizeof(A2DP) );
        for (device_id=0; device_id<A2DP_MAX_REMOTE_DEVICES_DEFAULT; device_id++)
        {
            a2dpInitialiseRemoteDevice(&a2dp->remote_conn[device_id],device_id);
        }
        
        PRINT(("sizeof(A2DP)=0x%u\n", sizeof(A2DP)));
        
        /* Set the handler function */
        a2dp->task.handler = a2dpProfileHandler;
        /* Set up the lib client */
        a2dp->clientTask = clientTask;
        a2dp->linkloss_timeout = linkloss_timeout;
        a2dp->max_remote_devs = A2DP_MAX_REMOTE_DEVICES_DEFAULT;
        a2dp->profile_role = role;
        
        blockInit();
        
        if ( seps && size_seps && validateSeps(seps, size_seps) )
        {
            for (device_id=0; device_id<A2DP_MAX_REMOTE_DEVICES; device_id++)
            {
                sep_data_type *sep_list = (sep_data_type *)PanicNull( blockAdd( device_id, data_block_sep_list, size_seps, sizeof(sep_data_type) ) );
                memmove( sep_list, (sep_data_type *)seps, size_seps*sizeof(sep_data_type) );
            }
        }
        else
        {
            a2dpSendInitCfmToClient(a2dp_invalid_parameters);
            return;
        }
    
    
        /* Used to count the number of SDP records registered.  Decremented again by a2dpHandleSdpRegisterCfm() and will 
           kick off a call to a2dpRegisterL2cap() when it hits zero - i.e. all CFM messages for SDP regsitering process
           have been received.                                                                                           */
        a2dp->sdp_register_outstanding = 0;
        
        if (service_records)
        {
            if (service_records->size_service_record_a && service_records->service_record_a)
            {
                /* Client has supplied their own record so register it without checking */
                ConnectionRegisterServiceRecord(&a2dp->task, service_records->size_service_record_a, service_records->service_record_a);
                a2dp->sdp_register_outstanding++;
            }
            if (service_records->size_service_record_b && service_records->service_record_b)
            {
                /* Client has supplied their own record so register it without checking */
                ConnectionRegisterServiceRecord(&a2dp->task, service_records->size_service_record_b, service_records->service_record_b);
                a2dp->sdp_register_outstanding++;
            }
        }
        else
        {
            /* Client using default library record */
            if (role & A2DP_INIT_ROLE_SINK)
            {
                ConnectionRegisterServiceRecord(&a2dp->task, sizeof(a2dp_sink_service_record), a2dp_sink_service_record);
                PRINT(("Register Sink Service Rec\n"));
                a2dp->sdp_register_outstanding++;
            }
            if (role & A2DP_INIT_ROLE_SOURCE)
            {
                ConnectionRegisterServiceRecord(&a2dp->task, sizeof(a2dp_source_service_record), a2dp_source_service_record);
                PRINT(("Register Source Service Rec\n"));
                a2dp->sdp_register_outstanding++;
            }
        }
    
        if ( a2dp->sdp_register_outstanding==0 )
        {
            /* Skip the service record registering if the user doesn't require any at this point. */
            a2dpRegisterL2cap();
        }
    }
}
void sppProfileHandler(Task task, MessageId id, Message message)
{
	SPP* spp = (SPP*) task;
	sppState profileState = spp->state;

	/* Check the message id */
    switch (id)
    {
    case SPP_INTERNAL_TASK_INIT_REQ:
        {
            uint16 app = (*((uint16 *)message));
            sppInitTaskData(spp, 0, 0, (Task) app, sppReady, 0, 0, 0, 0, 1);
        }
        break;

    case SPP_INTERNAL_TASK_DELETE_REQ:
        sppHandleFreeSppTask(spp);
        break;

    case SPP_INTERNAL_INIT_REQ:
        switch(profileState)
        {
        case sppInitialising:
            sppHandleInternalInitReq(spp, (SPP_INTERNAL_INIT_REQ_T *) message);
            break;

        case sppReady:
        case sppSearching:
        case sppConnecting:
        case sppConnected:
        default:
            handleUnexpected(sppUnexpectedSppPrim, profileState, id);
        }
        break;

    case CL_RFCOMM_REGISTER_CFM:
        switch(profileState)
        {
        case sppInitialising:
            sppHandleRfcommRegisterCfm(spp, (CL_RFCOMM_REGISTER_CFM_T *) message);
            break;
            
        case sppReady:
        case sppSearching:
        case sppConnecting:
        case sppConnected:
        default:
            handleUnexpected(sppUnexpectedClPrim, profileState, id);
            break;
        }
        break;

    case CL_SDP_REGISTER_CFM:
        switch(profileState)
        {
        case sppInitialising:
            sppHandleSdpRegisterCfm(spp, (CL_SDP_REGISTER_CFM_T *) message);
            break;
            
        case sppReady:
        case sppSearching:
        case sppConnecting:
            sppHandleSdpRegisterCfmReady(spp, (CL_SDP_REGISTER_CFM_T *) message);
            break;
            
        case sppConnected:
        default:
            handleUnexpected(sppUnexpectedClPrim, profileState, id);
            break;
        }
		break;

	case CL_SDP_UNREGISTER_CFM:
        switch(profileState)
        {
        case sppReady:
        case sppConnected:
            sppHandleSdpUnregisterCfm(spp, (CL_SDP_UNREGISTER_CFM_T *) message);
            break;
            
        case sppInitialising:		
        case sppSearching:
        case sppConnecting:
        default:
            handleUnexpected(sppUnexpectedClPrim, profileState, id);
            break;
        }
		break;

    case SPP_INTERNAL_CONNECT_REQ:
        switch(profileState)
        {
        case sppReady:
            sppHandleConnectRequest(spp, (SPP_INTERNAL_CONNECT_REQ_T *) message);
            break;
            
        case sppSearching:
        case sppConnecting:
        case sppConnected:	
            sppSendConnectCfmToApp(spp_connect_failed_busy, spp);
            break;
            
        case sppInitialising:
        default:
            handleUnexpected(sppUnexpectedSppPrim, profileState, id);
            break;
        }
		break;

	case SPP_INTERNAL_CONNECT_RES:
        switch(profileState)
        {
        case sppConnecting:
            sppHandleConnectResponse(spp, (SPP_INTERNAL_CONNECT_RES_T *) message);
            break;
            
        case sppReady:
        case sppSearching:
        case sppConnected:	
            sppSendConnectCfmToApp(spp_connect_failed_busy, spp);
            break;
            
        case sppInitialising:
        default:
            handleUnexpected(sppUnexpectedSppPrim, profileState, id);
            break;
        }
		break;

	case CL_SDP_SERVICE_SEARCH_ATTRIBUTE_CFM:
        switch(profileState)
        {
        case sppSearching:
            sppHandleSdpServiceSearchAttributeCfm(spp, (CL_SDP_SERVICE_SEARCH_ATTRIBUTE_CFM_T *) message);
            break;
            
        case sppReady:
        case sppConnecting:
        case sppConnected:
            break;
            
        case sppInitialising:		
        default:
            handleUnexpected(sppUnexpectedClPrim, profileState, id);
            break;
        }
		break;

	case SPP_INTERNAL_RFCOMM_CONNECT_REQ:
        switch(profileState)
        {
        case sppConnecting:
            sppHandleInternalRfcommConnectRequest(spp, (SPP_INTERNAL_RFCOMM_CONNECT_REQ_T *) message);
            break;
            
        case sppReady:
        case sppSearching:
        case sppInitialising:
        case sppConnected:	
        default:
            handleUnexpected(sppUnexpectedSppPrim, profileState, id);
            break;
        }
		break;

	case CL_RFCOMM_CONNECT_CFM:
        switch(profileState)
        {
        case sppConnecting: 
            sppHandleRfcommConnectCfm(spp, (CL_RFCOMM_CONNECT_CFM_T *) message);
            break;
            
        case sppConnected:	
        case sppReady:
        case sppSearching:
        case sppInitialising:
        default:
            handleUnexpected(sppUnexpectedClPrim, profileState, id);
            break;
        }
		break;

	case CL_RFCOMM_CONNECT_IND:
        switch(profileState)
        {
        case sppReady:
            sppHandleRfcommConnectInd(spp, (CL_RFCOMM_CONNECT_IND_T *) message);
            break;
            
        case sppSearching:
        case sppConnecting:
        case sppConnected:	
            sppHandleConnectIndReject(spp, (CL_RFCOMM_CONNECT_IND_T *) message);
            break;
            
        case sppInitialising:
        default:
            handleUnexpected(sppUnexpectedClPrim, profileState, id);
            break;
        }
		break;

	case CL_RFCOMM_DISCONNECT_IND:
        switch(profileState)
        {
        case sppReady:
        case sppSearching:
        case sppConnecting:
        case sppConnected:
            sppHandleRfcommDisconnectInd(spp, (CL_RFCOMM_DISCONNECT_IND_T *) message);
            break;
            
        case sppInitialising:
        default:
            handleUnexpected(sppUnexpectedClPrim, profileState, id);
            break;
        }
		break;

	case SPP_INTERNAL_DISCONNECT_REQ:
        switch(profileState)
        {
        case sppConnecting:
        case sppConnected:
            sppHandleInternalDisconnectReq(spp);
            break;
            
        case sppReady:
        case sppSearching:
            sppSendDisconnectIndToApp(spp, spp_disconnect_no_slc);
            break;
            
        case sppInitialising:
        default:
            handleUnexpected(sppUnexpectedSppPrim, profileState, id);
            break;
        }
		break;

	case CL_RFCOMM_CONTROL_IND:
        { 
            /* Forward the Modem Control Indicators */
            CL_RFCOMM_CONTROL_IND_T *src_msg;
            CL_RFCOMM_CONTROL_IND_T *ind = PanicUnlessNew(CL_RFCOMM_CONTROL_IND_T);
            src_msg = (CL_RFCOMM_CONTROL_IND_T *)message;
            *ind = *src_msg;    	    
            MessageSend(spp->clientTask, CL_RFCOMM_CONTROL_IND, ind);
        }
		break;
        
    case MESSAGE_MORE_DATA:
        {
            SPP_MESSAGE_MORE_DATA_T* msg = PanicUnlessNew(SPP_MESSAGE_MORE_DATA_T);
            msg->source = ((MessageMoreData*)message)->source;
            msg->spp = spp;
            MessageSend(spp->clientTask, SPP_MESSAGE_MORE_DATA, msg);
        }
        break;
        
    case MESSAGE_MORE_SPACE:
        {
            SPP_MESSAGE_MORE_SPACE_T* msg = PanicUnlessNew(SPP_MESSAGE_MORE_SPACE_T);
            msg->sink = ((MessageMoreSpace*)message)->sink;
            msg->spp = spp;
            MessageSend(spp->clientTask, SPP_MESSAGE_MORE_SPACE, msg);
        }
		break;
		
	case SPP_INTERNAL_SEND_CFM_TO_APP:
		{
			SPP_INTERNAL_SEND_CFM_TO_APP_T* msg = (SPP_INTERNAL_SEND_CFM_TO_APP_T*)message;
			sppSendConnectCfmToApp(msg->status, msg->spp);
		}
		break;
		
		/* Ignored messages */
	case MESSAGE_STREAM_DISCONNECT:
	case MESSAGE_SOURCE_EMPTY:
		break;
		
	default:
		/* Received an unknown message */
		SPP_DEBUG(("spp profile handler - msg type  not yet handled 0x%x\n", id));
		break;
	}
}
Example #20
0
/******************************************************************************
 *
 * handleAudioMessage()
 *
 * Description:
 *  The main task message handler for Audio Plugin.  It will receive messages
 *  from the CSR Audio library or from one of the public functions in
 *  soundclearPlugin.h.  In general, the AUDIO_BUSY flag is checked for each
 *  message.  If AUDIO_BUSY is set, then the message will be queued until
 *  AUDIO_BUSY is cleared.  Otherwise, the message will be executed
 *  immediately.  The only exception is AUDIO_PLUGIN_STOP_TONE_MSG.  It is
 *  expected that AUDIO_BUSY is set when a tone is playing.
 *
 * Arguments:
 *   Task task
 *     [in] task for audio plugin.
 *   MessageId id
 *     [in] Audio Message Id,see audio_plugin_interface_message_type_t in CSR
 *          lib
 *   Message message
 *     [in] Audio Message,see audio_plugin_interface_message_type_t in CSR lib
 *
 * Return Value:
 *   None
 *
 *****************************************************************************/
static void handleAudioMessage ( Task task , MessageId id, Message message )
{
  void *    pQueuedMessage = NULL;
  MessageId queuedMsgId    = 0;
  uint16    queuedMsgSize  = 0;
  bool      queueMsg       = FALSE;

  /* AUDIO_BUSY: global flag acts as a semaphore that indicates if the audio
     plugin is busy*/
  if (AUDIO_BUSY)
  {
    queueMsg = TRUE;
  }

  switch (id)
  {
    /* This message is received when the VM application calls AudioConnect().
       It indicates that the VM app wants to starts the SoundClear Plug-In.  */
    case (AUDIO_PLUGIN_CONNECT_MSG ):
    {

		
      /* Print the version of the SoundClear Plug-In */
      scPluginPrintf(("Version %d.%d.%d\n",
                     VMAPPVERNUMBER,
                     VMAPPVERMAJORREV,
                     VMAPPVERMINORREV));
      scPluginPrintf(("AUDIO_PLUGIN_CONNECT_MSG\n"));

      if (!queueMsg)
      {
        scPluginPrintf(("Starting SoundClear Plug-In\n"));
        
        /* Start the SoundClear Plug-In */
#ifdef APPBUILDFOR2010
        soundClearConnect(((AUDIO_PLUGIN_CONNECT_MSG_T *)message)->audio_sink, 
                          ((AUDIO_PLUGIN_CONNECT_MSG_T *)message)->sink_type, 
                          ((AUDIO_PLUGIN_CONNECT_MSG_T *)message)->codec_task, 
                          ((AUDIO_PLUGIN_CONNECT_MSG_T *)message)->volume, 
                          ((AUDIO_PLUGIN_CONNECT_MSG_T *)message)->rate, 
                          ((AUDIO_PLUGIN_CONNECT_MSG_T *)message)->stereo, 
                          ((AUDIO_PLUGIN_CONNECT_MSG_T *)message)->mode, 
                          ((AUDIO_PLUGIN_CONNECT_MSG_T *)message)->route, 
                          ((AUDIO_PLUGIN_CONNECT_MSG_T *)message)->power,
                          ((AUDIO_PLUGIN_CONNECT_MSG_T *)message)->params, 
                          ((AUDIO_PLUGIN_CONNECT_MSG_T *)message)->app_task );
#else
        soundClearConnect(((AUDIO_PLUGIN_CONNECT_MSG_T *)message)->audio_sink,
                          ((AUDIO_PLUGIN_CONNECT_MSG_T *)message)->codec_task,
                          ((AUDIO_PLUGIN_CONNECT_MSG_T *)message)->volume,
                          ((AUDIO_PLUGIN_CONNECT_MSG_T *)message)->stereo,
                          ((AUDIO_PLUGIN_CONNECT_MSG_T *)message)->mode);
#endif
      }
      else
      {
        /* Get space for the message and save its ID and size in case we have
           to queue it */
        pQueuedMessage = PanicUnlessNew(AUDIO_PLUGIN_CONNECT_MSG_T);
        queuedMsgId    = AUDIO_PLUGIN_CONNECT_MSG;
        queuedMsgSize  = sizeof(AUDIO_PLUGIN_CONNECT_MSG_T);
      }
      break;
    }

    /* This message is received when the VM application calls
       AudioDisconnect().  It indicates that the VM app wants to end the
       SoundClear Plug-In */
    case (AUDIO_PLUGIN_DISCONNECT_MSG ):
    {
      scPluginPrintf(("AUDIO_PLUGIN_DISCONNECT_MSG \n"));

      if (!queueMsg)
      {
        /* End the SoundClear Plug-In */
        soundClearDisconnect() ;
      }
      else
      {
        /* Get space for the message and save its ID and size in case we have to
           queue it */
     /* pQueuedMessage = NULL; Use default */
        queuedMsgId    = AUDIO_PLUGIN_DISCONNECT_MSG;
     /* queuedMsgSize  = 0; Use default */
      }
      break;
    }

    /* This message is received when the VM application calls AudioSetMode().
       It indicates that the VM app wants to change the mute mode of the
       SoundClear Plug-In. */
    case (AUDIO_PLUGIN_SET_MODE_MSG ):
    {
      scPluginPrintf(("AUDIO_PLUGIN_SET_MODE_MSG \n"));

      if (!queueMsg)
      {
        /* Change the mute mode of the SoundClear Plug-In */
        soundClearSetMode(((AUDIO_PLUGIN_SET_MODE_MSG_T *)message)->mode);
      }
      else
      {
        /* Get space for the message and save its ID and size in case we have
           to queue it */
        pQueuedMessage = PanicUnlessNew(AUDIO_PLUGIN_SET_MODE_MSG_T);
        queuedMsgId    = AUDIO_PLUGIN_SET_MODE_MSG;
        queuedMsgSize  = sizeof(AUDIO_PLUGIN_SET_MODE_MSG_T);
      }
      break;
    }

    /* This message is received when the VM application calls AudioSetVolume().
       It indicates that the VM app wants to change the volume level of the
       speaker. */
    case (AUDIO_PLUGIN_SET_VOLUME_MSG ):
    {
      scPluginPrintf(("AUDIO_PLUGIN_SET_VOLUME_MSG \n"));

      if (!queueMsg)
      {
        /* Change the volume of the SoundClear Plug-In */
        soundClearSetVolumeLevel(
                     ((AUDIO_PLUGIN_SET_VOLUME_MSG_T *)message)->volume );
      }
      else
      {
        /* Get space for the message and save its ID and size in case we have
           to queue it */
        pQueuedMessage = PanicUnlessNew(AUDIO_PLUGIN_SET_VOLUME_MSG_T);
        queuedMsgId    = AUDIO_PLUGIN_SET_VOLUME_MSG;
        queuedMsgSize  = sizeof(AUDIO_PLUGIN_SET_VOLUME_MSG_T);
      }
      break;
    }

    /* This message is received when the VM application calls AudioPlayTone().
       It indicates that the VM app wishes to play a tone through the receive
       path. */
    case (AUDIO_PLUGIN_PLAY_TONE_MSG ):
    {
      scPluginPrintf(("AUDIO_PLUGIN_PLAY_TONE_MSG \n"));

      if (!queueMsg)
      {
        /* Play the requested tone */
        soundClearPlayTone(
                ((AUDIO_PLUGIN_PLAY_TONE_MSG_T *)message)->tone,
                ((AUDIO_PLUGIN_PLAY_TONE_MSG_T *)message)->tone_volume,
                ((AUDIO_PLUGIN_PLAY_TONE_MSG_T *)message)->stereo);
      }
      else if (((AUDIO_PLUGIN_PLAY_TONE_MSG_T *)message)->can_queue != TRUE)
      {
        /* Only allowing queuing of tone messages if required. */
        queueMsg = FALSE;
      }
      else
      {
        /* Get space for the message and save its ID and size in case we have to
           queue it.  Only do this if we can queue tones. */
        pQueuedMessage = PanicUnlessNew(AUDIO_PLUGIN_PLAY_TONE_MSG_T);
        queuedMsgId    = AUDIO_PLUGIN_PLAY_TONE_MSG;
        queuedMsgSize  = sizeof(AUDIO_PLUGIN_PLAY_TONE_MSG_T);
      }
      break;
    }

    /* This message is received when the VM application calls AudioStopTone().
       It indicates that the VM app wishes to stop a tone that is currenly
       being played */
    case (AUDIO_PLUGIN_STOP_TONE_MSG ):
    {
      scPluginPrintf(("AUDIO_PLUGIN_STOP_TONE_MSG\n"));

      /* This message is never queued since it only has relevance if a tone is
         currently playing */
      queueMsg = FALSE;

      /* End any tone currently being played.  This call will perform no action
         if a tone is not currently playing. */
      soundClearToneEnd();
      break;
    }

    /* This message is received when the VM application calls
       soundClearPluginSetCodecConfig().  It indicates that the VM app wishes
       to change the current codec configuration of the SoundClear Plug-In. */
    case (SCPLUGINSETCODECCFGMSG):
    {
      scPluginPrintf(("SCPLUGINSETCODECCFGMSG \n"));

      if (!queueMsg)
      {
        if (soundClearReadyRcvMsg())
        {
          /* Set the codec configuration for the SoundClear Plug-In */
          soundClearSetCodecConfig(
                  ((ScPluginSetCodecCfgMsgT *)message)->codecPskey);
        }
        else
        {
          errorPanic(("This function must be called after AudioConnect()"));
        }
      }
      else
      {
        /* Get space for the message and save its ID and size in case we have to
           queue it */
        pQueuedMessage = PanicUnlessNew(ScPluginSetCodecCfgMsgT);
        queuedMsgId    = SCPLUGINSETCODECCFGMSG;
        queuedMsgSize  = sizeof(ScPluginSetCodecCfgMsgT);
      }
      break;
    }

    /* This message is received when the VM application calls
       soundClearPluginSetScConfig().  It indicates that the VM app wishes
       to change the current tuning used by the SoundClear DSP Software. */
    case (SCPLUGINSETSCCFGMSG):
    {
      scPluginPrintf(("SCPLUGINSETSCCFGMSG \n"));

      if (!queueMsg)
      {
        if (soundClearReadyRcvMsg())
        {
          /* Set the tuning for the SoundClear DSP Software */
          soundClearSetScConfig(((ScPluginSetScCfgMsgT *)message)->scPskey);
        }
        else
        {
          errorPanic(("This function must be called after AudioConnect()"));
        }
      }
      else
      {
        /* Get space for the message and save its ID and size in case we have to
           queue it */
        pQueuedMessage = PanicUnlessNew(ScPluginSetScCfgMsgT);
        queuedMsgId    = SCPLUGINSETSCCFGMSG;
        queuedMsgSize  = sizeof(ScPluginSetScCfgMsgT);
      }
      break;
    }

    /* This message is received when the VM application calls
       soundClearPluginToggleActiveMsg().  It indicates that the VM app wishes
       to enable/disable the processing performed by the SoundClear DSP
       Software. */
    case SCPLUGINTOGGLESCACTIVEMSG:
    {
      scPluginPrintf(("SCPLUGINTOGGLESCACTIVEMSG \n"));

      if (!queueMsg)
      {
        if (soundClearReadyRcvMsg())
        {
          /* Toggle SoundClear processing */
          soundClearToggleActive(
                    ((ScPluginToggleScActiveMsgT *)message)->scEnable);
        }
        else
        {
          errorPanic(("This function must be called after AudioConnect()"));
        }
      }
      else
      {
        /* Get space for the message and save its ID and size in case we have to
           queue it */
        pQueuedMessage = PanicUnlessNew(ScPluginToggleScActiveMsgT);
        queuedMsgId    = SCPLUGINTOGGLESCACTIVEMSG;
        queuedMsgSize  = sizeof(ScPluginToggleScActiveMsgT);
      }
      break;
    }

    default:
    {
      scPluginPrintf(("Received unknown message\n"));
      /*Make sure we will not get here if we processed all audio messages*/
      /*Panic();*/
      break;
    }
  }

  if (queueMsg)
  {
    scPluginPrintf(("Queue Message\n"));

    /* If there is message data, then copy it into the queued message */
    if (pQueuedMessage != NULL)
    {
      memcpy(pQueuedMessage, message, queuedMsgSize);
    }

    /* Message Will be sent when AUDIO_BUSY is zero */
    MessageSendConditionally ( task,
                               queuedMsgId,
                               pQueuedMessage,
                               (const uint16 *)&AUDIO_BUSY);
  }
}