/**************************************************************************** NAME configManagerButtonPatterns DESCRIPTION Read and configure any buttonpattern matches that exist RETURNS */ static void configManagerButtonPatterns( void ) { /* Allocate enough memory to hold event configuration */ button_pattern_config_type* config = (button_pattern_config_type*) mallocPanic(BM_NUM_BUTTON_MATCH_PATTERNS * sizeof(button_pattern_config_type)); CONF_DEBUG(("Co: No Button Patterns - %d\n", BM_NUM_BUTTON_MATCH_PATTERNS)); /* Now read in event configuration */ if(config) { if(ConfigRetrieve(theSink.config_id , PSKEY_BUTTON_PATTERN_CONFIG, config, BM_NUM_BUTTON_MATCH_PATTERNS * sizeof(button_pattern_config_type))) { uint16 n; /* Now we have the event configuration, map required events to system events */ for(n = 0; n < BM_NUM_BUTTON_MATCH_PATTERNS ; n++) { CONF_DEBUG(("Co : AddPattern Ev[%x]\n", config[n].event )) ; /* Map PIO button event to system events in specified states */ buttonManagerAddPatternMapping ( theSink.theButtonsTask , config[n].event , config[n].pattern, n ) ; } } else { CONF_DEBUG(("Co: !EvLen\n")) ; } freePanic(config) ; } }
static void readPsPermanentPairing (bdaddr *bd_addr, uint16 *link_key, uint16 *link_key_status, sink_attributes *attributes) { uint16 * ps_key; /* Allocate and zero buffer to hold PS key */ ps_key = mallocPanic(BD_ADDR_SIZE + LINK_KEY_SIZE + ATTRIBUTES_SIZE + 1); memset(ps_key, 0, BD_ADDR_SIZE + LINK_KEY_SIZE + ATTRIBUTES_SIZE + 1); /* Attempt to obtain current pairing data */ PsRetrieve(CONFIG_PERMANENT_PAIRING, ps_key, BD_ADDR_SIZE + LINK_KEY_SIZE + ATTRIBUTES_SIZE + 1); /* Return any requested fields */ if (link_key_status) { *link_key_status = ps_key[STATUS_LOC]; } if (bd_addr) { memcpy(bd_addr, &ps_key[BD_ADDR_LOC], BD_ADDR_SIZE); } if (link_key) { memcpy(link_key, &ps_key[LINK_KEY_LOC], LINK_KEY_SIZE); } if (attributes) { memcpy(attributes, &ps_key[ATTRIBUTES_LOC], ATTRIBUTES_SIZE); } free(ps_key); }
/**************************************************************************** NAME configManagerUserDefinedTones DESCRIPTION Attempt to read the user configured tones, if data exists it will be in the following format: uint16 offset in array to user tone 1, uint16 offset in array to user tone ...., uint16 offset in array to user tone 8, uint16[] user tone data To play a particular tone it can be access via gVariableTones, e.g. to access tone 1 theSink.audioData.gConfigTones->gVariableTones[0] + (uint16)*theSink.audioData.gConfigTones->gVariableTones[0] or to access tone 2 theSink.audioData.gConfigTones->gVariableTones[0] + (uint16)*theSink.audioData.gConfigTones->gVariableTones[1] and so on RETURNS void */ static void configManagerUserDefinedTones( uint16 KeyLength ) { /* if the keyLength is zero there are no user tones so don't malloc any memory */ if(KeyLength) { /* malloc only enough memory to hold the configured tone data */ uint16 * configTone = mallocPanic(KeyLength * sizeof(uint16)); /* retrieve pskey data up to predetermined max size */ uint16 size_ps_key = ConfigRetrieve( theSink.config_id, PSKEY_CONFIG_TONES , configTone , KeyLength ); CONF_DEBUG(("Co : Configurable Tones Malloc size [%x]\n", KeyLength )) ; /* is there any configurable tone data, if present update pointer to tone data */ if (size_ps_key) { /* the data is in the form of 8 x uint16 audio note start offsets followed by the up to 8 lots of tone data */ theSink.conf1->gConfigTones.gVariableTones = (ringtone_note*)&configTone[0]; } /* no user configured tone data is available, so free previous malloc as not in use */ else { /* no need to waste memory */ freePanic(configTone); } } /* no tone data available, ensure data pointer is null */ else { theSink.conf1->gConfigTones.gVariableTones = NULL; } }
static void InitConfigMemory_1(lengths_config_type * keyLengths) { uint16 lSize = 0; uint16 *buffer; uint16 pos=0, pos1=0, pos2; uint16 no_tones = keyLengths->no_tones; /*** One memory slot ***/ /* Allocate memory for Button data and volume mapping */ pos = sizeof(button_config_type); pos1 = pos + sizeof(ConfigTone_t); lSize = pos1 + (VOL_NUM_VOL_SETTINGS * sizeof(VolMapping_t) ); buffer = mallocPanic( lSize ); CONF_DEBUG(("INIT: Malloc size 1: [%d]\n",lSize)); /* Store pointer to button task memory */ theHeadset.buttons_duration = (button_config_type *)&buffer[0]; /* The config tone */ theHeadset.audioData.gConfigTones = (ConfigTone_t *)&buffer[pos]; /* The volume configuaration */ theHeadset.audioData.gVolMaps = (VolMapping_t *)&buffer[pos1]; /* ***************************************************** */ /*** One memory slot ***/ /* Allocate memory for SSR data and Event Tone */ /* Added PIO block and radio */ pos = sizeof(subrate_t); pos1 = pos + ((no_tones +1) * sizeof(tone_config_type)); pos2 = pos1 + sizeof(PIO_block_t); lSize = pos2 + sizeof(radio_config_type); buffer = mallocPanic( lSize ); CONF_DEBUG(("INIT: Malloc size 2: [%d]\n",lSize)); /* Store pointer to SSR data */ theHeadset.ssr_data = (subrate_t *)&buffer[0]; /* Hold event tone configuration */ theHeadset.audioData.gEventTones = (HeadsetTone_t*)&buffer[pos]; /* PIOs assigned to fixed events */ theHeadset.PIO = (PIO_block_t*)&buffer[pos1]; /* radio configuration data */ theHeadset.radio = (radio_config_type*)&buffer[pos2]; }
/**************************************************************************** NAME InitConfigMemoryAtCommands DESCRIPTION Dynamically allocate memory slot for AT commands (conf3) RETURNS void */ static void InitConfigMemoryAtCommands(uint16 atCmdsKeyLength) { /* Allocate memory for supported custom AT commands, malloc one extra word to ensure a string terminator is present should the data read from ps be incorrect */ theSink.conf3 = mallocPanic( sizeof(config_block3_t) + atCmdsKeyLength + 1); /* ensure that all data is set as string terminator in case of incorrect pskey data being read */ memset(theSink.conf3, 0, (sizeof(config_block3_t) + atCmdsKeyLength + 1)); CONF_DEBUG(("INIT: Malloc size %d:\n", sizeof(config_block3_t) + atCmdsKeyLength )); }
static void configManagerButtons( void ) { /* Allocate enough memory to hold event configuration */ event_config_type* configA = (event_config_type*) mallocPanic(BM_EVENTS_PER_PS_BLOCK * sizeof(event_config_type)); event_config_type* configB = (event_config_type*) mallocPanic(BM_EVENTS_PER_PS_BLOCK * sizeof(event_config_type)); event_config_type* configC = (event_config_type*) mallocPanic(BM_EVENTS_PER_PS_BLOCK * sizeof(event_config_type)); uint16 n; uint8 i = 0; ConfigRetrieve(theSink.config_id , PSKEY_EVENTS_A, configA, BM_EVENTS_PER_PS_BLOCK * sizeof(event_config_type)) ; ConfigRetrieve(theSink.config_id , PSKEY_EVENTS_B, configB, BM_EVENTS_PER_PS_BLOCK * sizeof(event_config_type)) ; ConfigRetrieve(theSink.config_id , PSKEY_EVENTS_C, configC, BM_EVENTS_PER_PS_BLOCK * sizeof(event_config_type)) ; /* Now we have the event configuration, map required events to system events */ for(n = 0; n < BM_EVENTS_PER_PS_BLOCK; n++) { CONF_DEBUG(("Co : AddMap indexes [%u,%u] Ev[%x][%x][%x]\n", n, i, configA[n].event , configB[n].event, configC[n].event )) ; /* check to see if a valid pio mask is present, this includes the upper 2 bits of the state info as these are being used for bc5 as vreg enable and charger detect */ if ( (configA[n].pio_mask)||(configA[n].state_mask & 0xC000)) buttonManagerAddMapping ( &configA[n], i++ ); if ( (configB[n].pio_mask)||(configB[n].state_mask & 0xC000)) buttonManagerAddMapping ( &configB[n], i++ ); if ( (configC[n].pio_mask)||(configC[n].state_mask & 0xC000)) buttonManagerAddMapping ( &configC[n], i++ ); } freePanic(configA) ; freePanic(configB) ; freePanic(configC) ; /* perform an initial pio check to see if any pio changes need processing following the completion of the configuration ps key reading */ BMCheckButtonsAfterReadingConfig(); }
void configManagerInitMemory( void ) { #ifdef DEBUG_CONFIG uint8 slot_count = 1; #endif /* Allocate memory for run time data*/ theSink.rundata = mallocPanic( sizeof(runtime_block1_t) ); memset(theSink.rundata, 0, sizeof (runtime_block1_t)); CONF_DEBUG(("INIT: Malloc size %d: [%d]\n",slot_count++,sizeof(runtime_block1_t))); }
/**************************************************************************** NAME buttonManagerInit */ void buttonManagerInit ( void ) { /*put the buttons task and the button patterens in a single memory block*/ int lSize = sizeof(ButtonsTaskData) ; /*allocate the memory*/ theSink.theButtonsTask = mallocPanic( lSize ); /* initialise structure */ memset(theSink.theButtonsTask, 0, lSize); theSink.theButtonsTask->client = &theSink.task; /*create the array of Button Events that we are going to populate*/ BM_DEBUG(("BM: ButtonEvents block size [%u]\n" , sizeof( ButtonEvents_t ) * BM_EVENTS_PER_CONF_BLOCK )); theSink.theButtonsTask->gButtonEvents[0] = (ButtonEvents_t * ) ( mallocPanic( sizeof( ButtonEvents_t ) * BM_EVENTS_PER_CONF_BLOCK ) ) ; theSink.theButtonsTask->gButtonEvents[1]= (ButtonEvents_t * ) ( mallocPanic( sizeof( ButtonEvents_t ) * BM_EVENTS_PER_CONF_BLOCK ) ) ; /*init the PIO button routines with the Button manager Task data */ ButtonsInit( theSink.theButtonsTask ) ; }
static void InitConfigMemory(lengths_config_type * keyLengths) { /* Allocate memory for SSR, PIO and radio data, and Event Tone */ theSink.conf2 = mallocPanic( sizeof(config_block2_t) + (keyLengths->no_tones * sizeof(tone_config_type)) ); CONF_DEBUG(("INIT: Malloc size %d:\n", sizeof(config_block2_t) + (keyLengths->no_tones * sizeof(tone_config_type)))); /* initialise the memory block to 0 */ memset(theSink.conf2,0,sizeof(config_block2_t) + (keyLengths->no_tones * sizeof(tone_config_type))); theSink.conf3 = NULL; /* Allocate memory for voice prompts config if required*/ if(keyLengths->no_tts || keyLengths->no_vp) { theSink.conf4 = mallocPanic( sizeof(config_block4_t) + (keyLengths->no_tts * sizeof(tts_config_type))); CONF_DEBUG(("INIT: Malloc size %d:\n", sizeof(config_block4_t) + (keyLengths->no_tts * sizeof(tts_config_type)))); } else { theSink.conf4 = NULL; } }
void configManagerReadFmData(void) { /* determine size of data required by fm library */ int lSize = (sizeof(fm_rx_data_t) + FMRX_MAX_BUFFER_SIZE); /*allocate the memory*/ theSink.conf2->sink_fm_data.fm_plugin_data = mallocPanic( lSize ); /* initialise structure */ memset(theSink.conf2->sink_fm_data.fm_plugin_data, 0, lSize); /* get the FM config from pskey */ ConfigRetrieve(theSink.config_id, PSKEY_FM_CONFIG, &theSink.conf2->sink_fm_data.fm_plugin_data->config, sizeof(fm_rx_config)); /* get the FM stored freq from pskey */ ConfigRetrieve(theSink.config_id, PSKEY_FM_FREQUENCY_STORE, &theSink.conf2->sink_fm_data.fmStoredFreq, sizeof(fm_stored_freq)); }
/**************************************************************************** NAME LEDManagerSendEventComplete DESCRIPTION Sends a message to the main task thread to say that an event indication has been completed RETURNS void */ void LedsSendEventComplete ( sinkEvents_t pEvent , bool pPatternCompleted ) { if ( (pEvent > EVENTS_MESSAGE_BASE) && (pEvent <= EVENTS_LAST_EVENT ) ) { LMEndMessage_t * lEventMessage = mallocPanic ( sizeof(LMEndMessage_t) ) ; /*need to add the message containing the EventType here*/ lEventMessage->Event = pEvent ; lEventMessage->PatternCompleted = pPatternCompleted ; LED_DEBUG(("LM : lEvCmp[%x] [%x]\n",lEventMessage->Event , lEventMessage->PatternCompleted )) ; MessageSend ( &theSink.task , EventSysLEDEventComplete , lEventMessage ) ; } }
/**************************************************************************** NAME configManagerButtonPatterns DESCRIPTION Read and configure any buttonpattern matches that exist RETURNS */ static void configManagerButtonPatterns( uint16 pConfigID ) { /* Allocate enough memory to hold event configuration */ button_pattern_config_type* config = (button_pattern_config_type*) mallocPanic(BM_NUM_BUTTON_MATCH_PATTERNS * sizeof(button_pattern_config_type)); CONF_DEBUG(("Co: No Button Patterns - %d\n", BM_NUM_BUTTON_MATCH_PATTERNS)); /* Now read in event configuration */ if(config) { if(ConfigRetrieve(pConfigID , PSKEY_BUTTON_PATTERN_CONFIG, config, BM_NUM_BUTTON_MATCH_PATTERNS * sizeof(button_pattern_config_type))) { uint16 n; /* Now we have the event configuration, map required events to system events */ for(n = 0; n < BM_NUM_BUTTON_MATCH_PATTERNS ; n++) { CONF_DEBUG(("Co : AddPattern Ev[%x]\n", config[n].event )) ; #ifdef BHC612 if(n == 0) { config[0].event = 0x6000; config[0].pattern[0] = 2;/*Vol - */ config[0].pattern[1] = 4;/*Talk*/ config[0].pattern[2] = 1;/*Vol +*/ config[0].pattern[3] = 6;/*Vol - & Talk*/ config[0].pattern[4] = 5;/*Vol + & Talk*/ config[0].pattern[5] = 2;/*Vol -*/ } #endif /* Map PIO button event to system events in specified states */ buttonManagerAddPatternMapping ( theHeadset.theButtonsTask , config[n].event , config[n].pattern, n ) ; } } else { CONF_DEBUG(("Co: !EvLen\n")) ; } free (config) ; } }
/**************************************************************************** NAME configManagerPioMap DESCRIPTION Read PIO config and map in configured PIOs. RETURNS void */ void configManagerPioMap(void) { pio_config_type* pio; /* Allocate memory for Button data, volume mapping */ theSink.conf1 = mallocPanic( sizeof(config_block1_t) ); memset(theSink.conf1, 0, sizeof (config_block1_t)); CONF_DEBUG(("INIT: Malloc size 1: [%d]\n",sizeof(config_block1_t))); /* Retrieve config */ pio = &theSink.conf1->PIOIO; ConfigRetrieve(theSink.config_id , PSKEY_PIO_BLOCK, pio, sizeof(pio_config_type)); /* Make sure all references to mic parameters point to the right place */ theSink.cvc_params.digital = &pio->digital; /* Map in any required pins */ CONF_DEBUG(("INIT: Map PIO 0x%lX\n", pio->pio_map)); PioSetMapPins32(pio->pio_map,pio->pio_map); }
/**************************************************************************** NAME SetupPowerTable DESCRIPTION Attempts to obtain a low power table from the Ps Key store. If no table (or an incomplete one) is found in Ps Keys then the default is used. RETURNS void */ void SetupPowerTable( void ) { uint16 size_ps_key; power_table *PowerTable; /* obtain the size of memory in words required to hold the contents of the pskey */ size_ps_key = PsFullRetrieve(PS_HFP_POWER_TABLE, NULL, 0); /* initialise user power table */ theSink.user_power_table = 0; /* check whether any pskey data exists */ if (size_ps_key) { /* malloc storage for power table entries */ PowerTable = (power_table*)mallocPanic(size_ps_key); /* attempt to retrieve all power table entries from ps */ size_ps_key = PsFullRetrieve(PS_HFP_POWER_TABLE, PowerTable, ((sizeof(lp_power_table) * MAX_POWER_TABLE_ENTRIES) + sizeof(uint16))); /* sanity check the number of entried and length of pskey data to ensure entries are complete */ if(size_ps_key == ((sizeof(lp_power_table)*PowerTable->normalEntries)+ (sizeof(lp_power_table)*PowerTable->SCOEntries)+ (sizeof(lp_power_table)*PowerTable->A2DPStreamEntries)+ (sizeof(uint16))) ) { /* Use user defined power table */ theSink.user_power_table = PowerTable; /* pskey format is correct */ INIT_DEBUG(("User Power Table - Norm[%x] Sco[%x] Stream[%x]\n",PowerTable->normalEntries,PowerTable->SCOEntries,PowerTable->A2DPStreamEntries)); } else { /* No/incorrect power table defined in Ps Keys - use default table */ freePanic(PowerTable); PowerTable = NULL; INIT_DEBUG(("No User Power Table\n")); } } }
/**************************************************************************** NAME configManagerFillPs DESCRIPTION Fill PS to the point defrag is required (for testing only) RETURNS void */ void configManagerFillPs(void) { CONF_DEBUG(("CONF: Fill PS ")) ; if(theSink.rundata->defrag.key_size) { uint16 count = PsFreeCount(theSink.rundata->defrag.key_size); uint16* buff = mallocPanic(theSink.rundata->defrag.key_size); CONF_DEBUG(("[%d] ", count)); if(count > theSink.rundata->defrag.key_minimum) { for(count = count - theSink.rundata->defrag.key_minimum ; count > 0; count --) { *buff = count; PsStore(PSKEY_CONFIGURATION_ID, buff, theSink.rundata->defrag.key_size); } PsStore(PSKEY_CONFIGURATION_ID, &theSink.config_id, sizeof(uint16)); } CONF_DEBUG(("[%d]", PsFreeCount(theSink.rundata->defrag.key_size))); } CONF_DEBUG(("\n")); }
void sinkGattHidRcConfigRemote(uint16 rc_lookup_sie) { #ifdef DEBUG_GATT_HID_RC uint16 i; #endif if(!rc_lookup_sie) { /* No RC lookup table exists, there's nothing the RC task can do without the lookup table, return */ return; } /* Allocate enough memory to extract the configured BLE HID lookup table (can be of max size 16 entries) */ GATT_HID_RC.rc_lookup_size = rc_lookup_sie; GATT_HID_RC_DEBUG(("GattHIDRc: RC Config: Malloc size for RC Config: [%d]\n", ((sizeof(gattHidRcConfig_t) - sizeof(gattHidRcLookupTable_t)) + (GATT_HID_RC.rc_lookup_size * sizeof(gattHidRcLookupTable_t))) )); GATT_HID_RC.config = mallocPanic( ((sizeof(gattHidRcConfig_t) - sizeof(gattHidRcLookupTable_t)) + (GATT_HID_RC.rc_lookup_size * sizeof(gattHidRcLookupTable_t))) ); /* If there is enough memory available for a look up table, then get it */ if (GATT_HID_RC.config) { ConfigRetrieve(CONFIG_BLE_REMOTE_CONTROL, GATT_HID_RC.config, ((sizeof(gattHidRcConfig_t) - sizeof(gattHidRcLookupTable_t)) + (GATT_HID_RC.rc_lookup_size * sizeof(gattHidRcLookupTable_t))) ); #ifdef DEBUG_GATT_HID_RC /* Print the lookup table in a readable format for debugging purposes */ GATT_HID_RC_DEBUG(("GattHIDRc: RC Config : Max RC[%d], Lookup Size[%d]:\n", GATT_HID_RC.config->max_remotes, GATT_HID_RC.rc_lookup_size)); for (i=0; i<GATT_HID_RC.rc_lookup_size; i++) { GATT_HID_RC_DEBUG(("GattHIDRc: RC Config: [0x%x]->[0x%03x]\n", GATT_HID_RC.config->lookup_table[i].input_id, GATT_HID_RC.config->lookup_table[i].hid_code)); } #endif } else { /* Set look up size as zero, without config memory and data , RC task can not work */ GATT_HID_RC.rc_lookup_size = 0; GATT_HID_RC_DEBUG(("GattHIDRc: Memory for RC config is not available \n")); } }
/**************************************************************************** NAME configManagerEventTone DESCRIPTION Configure an event tts phrase only if one is defined RETURNS void */ static void configManagerEventTTSPhrases( uint16 pConfigID , uint16 no_tts ) { #ifdef TEXT_TO_SPEECH_PHRASES /* cheack the number of events configured and the supported tts languages */ if(no_tts) { tts_config_type * config; /* Allocate enough memory to hold event configuration */ config = (tts_config_type *) mallocPanic((no_tts + 1) * sizeof(tts_config_type)); if (config) { /* Now read in tones configuration */ if(ConfigRetrieve(pConfigID , PSKEY_TTS, config, no_tts * sizeof(tts_config_type))) { theHeadset.audioData.gEventTTSPhrases = (HeadsetTts_t*)config; theHeadset.audioData.gEventTTSPhrases[no_tts].tts_id = TTS_NOT_DEFINED; } } } #endif }
static void configManagerVoicePromptsInit( uint16 pConfigID , uint16 no_vp , uint16 no_tts_languages ) { #ifdef CSR_VOICE_PROMPTS /* cheack the number of events configured and the supported tts languages */ if(no_vp) { vp_config_type * config = NULL; uint16 size_vp_config = sizeof(vp_config_type); /* Allocate enough memory to hold event configuration */ config = (vp_config_type *) mallocPanic(size_vp_config); if (config) { /* Read in the PSKEY that tells us where the prompt header is */ if(ConfigRetrieve(pConfigID , PSKEY_VOICE_PROMPTS, config, size_vp_config)) { TTSConfigureVoicePrompts(no_vp, config, no_tts_languages); } } } #endif /* CSR_VOICE_PROMPTS */ }
static void writePsPermanentPairing (const bdaddr *bd_addr, uint16 *link_key, uint16 link_key_status, const sink_attributes *attributes) { uint16 * ps_key; /* Allocate and zero buffer to hold PS key */ ps_key = mallocPanic(BD_ADDR_SIZE + LINK_KEY_SIZE + ATTRIBUTES_SIZE + 1); memset(ps_key, 0, BD_ADDR_SIZE + LINK_KEY_SIZE + ATTRIBUTES_SIZE + 1); /* Attempt to obtain current pairing data */ PsRetrieve(CONFIG_PERMANENT_PAIRING, ps_key, BD_ADDR_SIZE + LINK_KEY_SIZE + ATTRIBUTES_SIZE + 1); /* Update supplied fields */ if (link_key_status) { ps_key[STATUS_LOC] = link_key_status; } if (bd_addr) { memcpy(&ps_key[BD_ADDR_LOC], bd_addr, BD_ADDR_SIZE); } if (link_key) { memcpy(&ps_key[LINK_KEY_LOC], link_key, LINK_KEY_SIZE); } if (attributes) { memcpy(&ps_key[ATTRIBUTES_LOC], attributes, ATTRIBUTES_SIZE); } /* Store updated pairing data */ PsStore(CONFIG_PERMANENT_PAIRING, ps_key, BD_ADDR_SIZE + LINK_KEY_SIZE + ATTRIBUTES_SIZE + 1); free(ps_key); }
/**************************************************************************** NAME mapcHandleServiceSearchAttributeCfm DESCRIPTION confirmation of the service search for MAP support, if successful the app will progress and attempt to connect to the message access service PARAMS @cfm message RETURNS void */ void mapcHandleServiceSearchAttributeCfm( const CL_SDP_SERVICE_SEARCH_ATTRIBUTE_CFM_T *cfm) { uint8 *rfcomm_channels; uint8 size_rfcomm_channels = 1; uint8 channels_found = 0; mapcState *state = NULL; mapc_link_priority device_id = mapcGetLinkFromBdAddr( &cfm->bd_addr ); /* ensure device_id has been correctly retrieved */ if(device_id != mapc_invalid_link) state = &(theSink.rundata->mapc_data.state[device_id]); /* if the service search has been successful, parse returned entries */ if(cfm->status == sdp_response_success) { MAPC_DEBUG(("MAPC:\tReceived SDP Response of length %d\n", cfm->size_attributes)); rfcomm_channels = mallocPanic(size_rfcomm_channels * sizeof(uint8)); /* parse all returned reports */ if (SdpParseGetMultipleRfcommServerChannels( cfm->size_attributes, (uint8*)cfm->attributes, 1, &rfcomm_channels, &channels_found) ) { /* If receiving multiple responses, the first record will be stored in this application */ if(state) { state->masChannel = rfcomm_channels[0]; state->bdAddr = cfm->bd_addr; state->device_state = mapc_sdp_searched; /* set the link security requirements */ ConnectionSmSetSdpSecurityOut(TRUE, &cfm->bd_addr); ConnectionSmRegisterOutgoingService(&theSink.task, &cfm->bd_addr, protocol_rfcomm, state->masChannel, sec4_out_level_2); /* attempt to connect the message access service */ MapcMasConnectRequest( &theSink.task, &cfm->bd_addr, state->masChannel ); } } /* no channels were found, there reset the state of this connection */ else { if(state) state->device_state = mapc_state_idle; MAPC_DEBUG(("MAPC:NO Channels found\n")); } /* ensure memory used in sdp record parsing is free'd */ freePanic(rfcomm_channels); } /* the sdp record search was not successful, no further action needs to be taken */ else { /* reset current connection state so that it can be reused */ if(state) state->device_state = mapc_state_idle; MAPC_DEBUG(("MAPC:SDP Search Failed. Status = %x, more = %x, error = %x \n", cfm->status, cfm->more_to_come, cfm->error_code)); } }
/**************************************************************************** NAME A2dpRouteAudio DESCRIPTION attempt to connect an audio connection from a2dp device via the passed in deviceID RETURNS */ void A2dpRouteAudio(uint8 Index, Sink sink) { AUD_DEBUG(("AudioA2dpRoute Index[%x] Sink[%x]\n", Index , (uint16) sink )) ; /* ensure sink is valid before attempting the connection */ if(sink) { /* Use an instance of A2DP message structure for initial volume setting */ AUDIO_PLUGIN_SET_VOLUME_A2DP_MSG_T volumeInitAudio; a2dp_codec_settings * codec_settings; AUD_DEBUG(("AudioA2dpRoute Index[%d] DevId[%x]\n", Index , theSink.a2dp_link_data->device_id[Index] )) ; /* get the rate information for connection */ codec_settings = A2dpCodecGetSettings(theSink.a2dp_link_data->device_id[Index], theSink.a2dp_link_data->stream_id[Index]); /* ensure stream is valid */ if(codec_settings) { AUDIO_MODE_T mode = AUDIO_MODE_CONNECTED; int16 a2dp_gain_dB; /* determine additional features applicable for this audio plugin */ /* Volume info is sent to DSP in dB units */ a2dp_gain_dB = VolumeConvertStepsToDB(theSink.volume_levels->a2dp_volume[Index].masterVolume, &theSink.conf1->volume_config.volume_control_config, DSP_DB_SCALE); /* check for MUTE volume level and mute as appropriate */ if (theSink.volume_levels->a2dp_volume[Index].masterVolume == VOLUME_A2DP_MUTE_GAIN) { mode = AUDIO_MODE_MUTE_SPEAKER; } /* initialise the AudioConnect extra parameters required to pass in additional codec information */ if (codec_settings->codecData.latency_reporting) /* latency reporting retrieved from a2dp library */ { /* TODO: obtain settings from PS, probably based on codec type */ theSink.a2dp_link_data->a2dp_audio_connect_params.latency.last = 150; theSink.a2dp_link_data->a2dp_audio_connect_params.latency.target = 150/5; theSink.a2dp_link_data->a2dp_audio_connect_params.latency.change = 10/5; theSink.a2dp_link_data->a2dp_audio_connect_params.latency.period = 500/100; } theSink.a2dp_link_data->a2dp_audio_connect_params.packet_size = codec_settings->codecData.packet_size; /* Packet size retrieved from a2dp library */ theSink.a2dp_link_data->a2dp_audio_connect_params.content_protection = codec_settings->codecData.content_protection; /* content protection retrieved from a2dp library */ theSink.a2dp_link_data->a2dp_audio_connect_params.clock_mismatch = theSink.a2dp_link_data->clockMismatchRate[Index]; /* clock mismatch rate for this device */ theSink.a2dp_link_data->a2dp_audio_connect_params.mode_params = &theSink.a2dp_link_data->a2dp_audio_mode_params; /* EQ mode and Audio enhancements */ #ifdef INCLUDE_A2DP_EXTRA_CODECS #ifdef INCLUDE_FASTSTREAM theSink.a2dp_link_data->a2dp_audio_connect_params.voice_rate = codec_settings->codecData.voice_rate; /* voice rate retrieved from a2dp library */ theSink.a2dp_link_data->a2dp_audio_connect_params.bitpool = codec_settings->codecData.bitpool; /* bitpool retrieved from a2dp library */ theSink.a2dp_link_data->a2dp_audio_connect_params.format = codec_settings->codecData.format; /* format retrieved from a2dp library */ #endif #ifdef INCLUDE_APTX theSink.a2dp_link_data->a2dp_audio_connect_params.channel_mode = codec_settings->channel_mode; /* aptX channel mode */ #endif #ifdef INCLUDE_APTX_ACL_SPRINT theSink.a2dp_link_data->a2dp_audio_connect_params.aptx_sprint_params = codec_settings->codecData.aptx_sprint_params; /* aptX LL params */ #endif #endif #ifdef ENABLE_SOUNDBAR theSink.a2dp_link_data->seid[Index] = codec_settings->seid; #endif /* ENABLE_SOUNDBAR */ #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 AUD_DEBUG(("AudioA2dpRoute Index[%d] DevId[%x] Gain[%x] Codec[%x] ClkMismatch[%x] EQ[%x] packet_size[%u]\n", Index , theSink.a2dp_link_data->device_id[Index], a2dp_gain_dB, codec_settings->seid, theSink.a2dp_link_data->a2dp_audio_connect_params.clock_mismatch, (uint16)theSink.a2dp_link_data->a2dp_audio_connect_params.mode_params, theSink.a2dp_link_data->a2dp_audio_connect_params.packet_size)) ; audioIndicateCodec( codec_settings->seid ); #ifdef ENABLE_SOUNDBAR /* Set the LE SCAN priority to Low since we are Streaming It is possible that we might be receiving less or no LE adverts when streaming is in progress*/ InquirySetPriority(inquiry_low_priority); #endif /* ENABLE_SOUNDBAR */ /* We need to set A2DP volume info as the audio is in mute state after connection */ volumeInitAudio.volume_type = theSink.conf1->volume_config.volume_control_config.volume_type; volumeInitAudio.codec_task = theSink.codec_task; volumeInitAudio.master_gain = a2dp_gain_dB; volumeInitAudio.system_gain = theSink.conf1->volume_config.volume_control_config.system_volume; volumeInitAudio.trim_gain_left = theSink.conf1->volume_config.volume_control_config.trim_volume_left; volumeInitAudio.trim_gain_right= theSink.conf1->volume_config.volume_control_config.trim_volume_right; volumeInitAudio.device_trim_master = theSink.conf1->volume_config.volume_control_config.device_trim_master; volumeInitAudio.device_trim_slave = theSink.conf1->volume_config.volume_control_config.device_trim_slave; volumeInitAudio.tones_gain = VolumeConvertStepsToDB(((TonesGetToneVolume(FALSE) * theSink.conf1->volume_config.volume_control_config.no_of_steps)/VOLUME_NUM_VOICE_STEPS), &theSink.conf1->volume_config.volume_control_config, DSP_DB_SCALE); volumeInitAudio.mute_active = theSink.sink_enable_present; /* connect the audio via the audio plugin */ AudioConnect(getA2dpPlugin(codec_settings->seid), sink , AUDIO_SINK_AV , theSink.codec_task, volumeInitAudio.tones_gain, codec_settings->rate, theSink.conf2->audio_routing_data.PluginFeatures , mode, AUDIO_ROUTE_INTERNAL, powerManagerGetLBIPM(), &theSink.a2dp_link_data->a2dp_audio_connect_params, FALSE, &theSink.task); AudioSetVolumeA2DP(&volumeInitAudio); #ifdef ENABLE_SUBWOOFER /* set subwoofer volume level */ updateSwatVolume(theSink.volume_levels->a2dp_volume[Index].masterVolume); SWAT_DEBUG(("SW : Send sample rate to Sub, rate is %ld\n",codec_settings->rate)); /* send sample rate to sub */ sendSampleRateToSub(codec_settings->rate); #endif audioControlLowPowerCodecs (FALSE) ; /* caller responsible for freeing memory */ freePanic(codec_settings); #ifdef ENABLE_AVRCP if(theSink.features.avrcp_enabled) { UpdateAvrpcMessage_t * lUpdateMessage = mallocPanic ( sizeof(UpdateAvrpcMessage_t) ) ; lUpdateMessage->bd_addr = theSink.a2dp_link_data->bd_addr[Index]; /* any AVRCP commands should be targeted to the device which has A2DP audio routed */ MessageSend( &theSink.task, EventSysSetActiveAvrcpConnection, lUpdateMessage); } #endif } /* update the current sink being routed */ theSink.routed_audio = sink; } }
void configManagerInit( void ) { /* use a memory allocation for the lengths data to reduce stack usage */ lengths_config_type * keyLengths = mallocPanic(sizeof(lengths_config_type)); /* Read key lengths */ configManagerKeyLengths(keyLengths); /* Allocate the memory required for the configuration data */ InitConfigMemory(keyLengths); /* Read and configure the button translations */ configManagerButtonTranslations( ); /* Read and configure the button durations */ configManagerButtonDurations( ); /* Read the system event configuration and configure the buttons */ configManagerButtons( ); /*configures the pattern button events*/ configManagerButtonPatterns( ) ; /*Read and configure the event tones*/ configManagerEventTones( keyLengths->no_tones ) ; /* Read and configure the system features */ configManagerFeatureBlock( ); /* Read and configure the automatic switch off time*/ configManagerConfiguration( ); /* Must happen between features and session data... */ InitA2dp(); /* Read and configure the user defined tones */ configManagerUserDefinedTones( keyLengths->userTonesLength ); /* Read and configure the LEDs */ configManagerLEDS(); /* Read and configure the voume settings */ configManagerVolume( ); /* Read and configure the power management system */ configManagerPower( ); /* Read and configure the radio parameters */ configManagerRadio(); /* Read and configure the volume orientation, LED Disable state, and tts_language */ configManagerReadSessionData ( ) ; configManagerReadDspData(); /* Read and configure the sniff sub-rate parameters */ configManagerSetupSsr ( ) ; configManagerEventTTSPhrases( keyLengths->no_tts ) ; configManagerVoicePromptsInit( keyLengths->no_vp , keyLengths->no_tts_languages ); #if defined (ENABLE_REMOTE) && defined (ENABLE_SOUNDBAR) /* Read the hid remote control key mapping. */ configManagerHidkeyMap(); #endif /* don't allocate memory for AT commands if they're not required */ if (keyLengths->size_at_commands) { InitConfigMemoryAtCommands(keyLengths->size_at_commands); configManagerAtCommands(keyLengths->size_at_commands + sizeof(config_block3_t) - 1); } #ifdef ENABLE_FM /* read the fm configuration data */ configManagerReadFmData(); #endif /* release the memory used for the lengths key */ freePanic(keyLengths); }
void configManagerInit( void ) { /* use a memory allocation for the lengths data to reduce stack usage */ lengths_config_type * keyLengths = mallocPanic(sizeof(lengths_config_type)); /*get the config ID**/ uint16 lConfigID = get_config_id ( PSKEY_CONFIGURATION_ID ) ; /* Read key lengths */ configManagerKeyLengths(lConfigID, keyLengths); /* Allocate the memory required for the configuration data */ InitConfigMemory_1(keyLengths); /* Read and configure the button durations */ configManagerButtonDurations(lConfigID ); #ifndef T3ProductionTest /* Read the system event configuration and configure the buttons */ configManagerButtons(lConfigID ); #endif /*configures the pattern button events*/ configManagerButtonPatterns(lConfigID ) ; /*Read and configure the event tones*/ configManagerEventTones( lConfigID, keyLengths->no_tones ) ; /* Read and configure the system features */ configManagerFeatureBlock( lConfigID ); /* Read and configure the user defined tones */ configManagerUserDefinedTones( lConfigID, keyLengths->userTonesLength ); #ifdef ROM_LEDS /* Read and configure the LEDs */ configManagerLEDS(lConfigID); #endif /* Read and configure the voume settings */ configManagerVolume( lConfigID ); /* Read and configure the automatic switch off time*/ configManagerConfiguration( lConfigID ); /* Read and configure the power management system */ configManagerPower( lConfigID ); /* Read and configure the radio parameters */ configManagerRadio( lConfigID ); #ifdef BHC612 /* Read and configure the volume orientation, LED Disable state, and tts_language */ configManagerReadSessionData ( lConfigID ) ; #else configManagerReadSessionData ( lConfigID ) ; #endif #ifdef T3ProductionTest configManagerButtons(lConfigID ); #endif /* Read and configure the sniff sub-rate parameters */ configManagerSetupSsr ( lConfigID ) ; configManagerEventTTSPhrases( lConfigID, keyLengths->no_tts ) ; configManagerVoicePromptsInit( lConfigID, keyLengths->no_vp , keyLengths->no_tts_languages ); /* release the memory used for the lengths key */ free(keyLengths); }
/**************************************************************************** NAME sinkWriteEirData DESCRIPTION Writes the local name, inquiry tx power and device UUIDs into device EIR data RETURNS void */ void sinkWriteEirData( CL_DM_LOCAL_NAME_COMPLETE_T *message ) { uint16 size_uuids = 0; uint16 size = 0; uint8 *eir = NULL; uint8 *p = NULL; /* Determine length of EIR data */ size_uuids = SIZE_A2DP_UUIDS + SIZE_AVRCP_UUIDS + SIZE_PBAP_UUIDS + SIZE_HFP_UUIDS + SIZE_HSP_UUIDS; size = GetDeviceIdEirDataSize() + EIR_BLOCK_SIZE(EIR_DATA_SIZE_FULL(size_uuids) + EIR_DATA_SIZE_FULL(message->size_local_name) + EIR_DATA_SIZE_FULL(sizeof(uint8))); /* Allocate space for EIR data */ eir = (uint8 *)mallocPanic(size * sizeof(uint8)); p = eir; /* Device Id Record */ p += WriteDeviceIdEirData( p ); /* Inquiry Tx Field */ *p++ = EIR_DATA_SIZE(sizeof(int8)); *p++ = EIR_TYPE_INQUIRY_TX; *p++ = theSink.inquiry_tx; /* UUID16 field */ *p++ = EIR_DATA_SIZE(size_uuids); *p++ = EIR_TYPE_UUID16_PARTIAL; if(theSink.features.EnableA2dpStreaming) { memmove(p, a2dp_uuids, sizeof(a2dp_uuids)); p += sizeof(a2dp_uuids); } #ifdef ENABLE_AVRCP if (theSink.features.avrcp_enabled) { memmove(p, avrcp_uuids, sizeof(avrcp_uuids)); p += sizeof(avrcp_uuids); } #endif #ifdef ENABLE_PBAP if (theSink.features.pbap_enabled) { memmove(p, pbap_uuids, sizeof(pbap_uuids)); p += sizeof(pbap_uuids); } #endif if(theSink.hfp_profiles & hfp_handsfree_all) { memmove(p, hfp_uuids, sizeof(hfp_uuids)); p += sizeof(hfp_uuids); } if(theSink.hfp_profiles & hfp_headset_all) { memmove(p, hsp_uuids, sizeof(hsp_uuids)); p += sizeof(hsp_uuids); } /* Device Name Field */ *p++ = EIR_DATA_SIZE(message->size_local_name); *p++ = EIR_TYPE_LOCAL_NAME_COMPLETE; memmove(p, message->local_name, message->size_local_name); p += message->size_local_name; /* NULL Termination */ *p++ = 0x00; /* Register and free EIR data */ ConnectionWriteEirData(FALSE, size, eir); freePanic(eir); }