/**************************************************************************** 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); }
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); } }
/**************************************************************************** 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); }
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); } }
/****************************************************************************** * * 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); }
/****************************************************************************** * * 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); }
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(¶ms->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); } }
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; }
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; } }
/****************************************************************************** * * 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); } }