/**************************************************************************** NAME sinkDialStoredNumber DESCRIPTION Dials a number stored in CONFIG_PHONE_NUMBER If HFP and connected - issues command If HFP and not connected - connects and issues if not in call If HSP sends button press RETURNS void */ void sinkDialStoredNumber ( void ) { uint16 ret_len; Sink sink; uint16 phone_number_key[SIZE_CONFIG_PHONE_NUMBER]; CM_DEBUG(("sinkDialStoredNumber\n")) ; if ((ret_len = ConfigRetrieve(CONFIG_PHONE_NUMBER, phone_number_key, SIZE_CONFIG_PHONE_NUMBER ))) { if((HfpLinkGetSlcSink(hfp_primary_link, &sink)) && SinkIsValid(sink)) { /* Send the dial request now */ CM_DEBUG(("CM:Dial Stored Number (Connected) len=%x\n",ret_len)) ; HfpDialNumberRequest(hfp_primary_link, ret_len, (uint8 *)&phone_number_key[0]); } else { /* Not connected, connect and queue the dial request */ #ifdef ENABLE_AVRCP sinkAvrcpCheckManualConnectReset(NULL); #endif MessageSend ( &theSink.task , EventUsrEstablishSLC , 0 ) ; sinkQueueEvent( EventUsrDialStoredNumber ) ; } } else { /*The PSKEY could not be read*/ MessageSend(&theSink.task, EventUsrUpdateStoredNumber, 0); } }
/**************************************************************************** NAME sinkHandleRingInd DESCRIPTION Received a RING indication from the AG. RETURNS void */ void sinkHandleRingInd( const HFP_RING_IND_T * pInd ) { /* check whether the ring ind needs to be shown as a call waiting beep for multipoint operation, if not multipoint function returns false */ if(!MPCheckRingInd(pInd)) { /* Determine which AG has the outband ring (if applicable) and play appropriate tone. */ #ifdef ENABLE_SPEECH_RECOGNITION if((!pInd->in_band)&&(!speechRecognitionIsEnabled())) #else if(!pInd->in_band) #endif { /* determine whether this is AG1 or AG2 and play appropriate tone */ if(pInd->priority == hfp_primary_link) { CM_DEBUG(("CM: OutBandRing - AG1 play ring 1\n")) ; TonesPlayEvent(EventSysRingtone1); } /* this is AG2 so play ring tone for AG2 */ else if(pInd->priority == hfp_secondary_link) { CM_DEBUG(("CM: OutBandRing - AG2 play ring 2\n")) ; TonesPlayEvent(EventSysRingtone2); } } else CM_DEBUG(("CM: inBandRing or speech rec enabled - no tone played\n")) ; } }
/**************************************************************************** NAME sinkHangUpCall DESCRIPTION Hang up the call from the device. RETURNS void */ void sinkHangUpCall( void ) { /* Determine which is the current active call */ hfp_link_priority priority = hfp_invalid_link; hfp_call_state call_state; /* Get profile if AG with audio, also ensure AG is actually in a call, otherwise try other methods */ if((theSink.routed_audio)&&(HfpLinkGetCallState(HfpLinkPriorityFromAudioSink(theSink.routed_audio), &call_state)&& (call_state))) priority = HfpLinkPriorityFromAudioSink(theSink.routed_audio); /* No audio so use AG state */ if(!priority) priority = HfpLinkPriorityFromCallState(hfp_call_state_active); /* No active call, check for an outgoing call to terminate */ if(!priority) priority = HfpLinkPriorityFromCallState(hfp_call_state_outgoing); /* No active/outgoing calls, check for TWC state */ if(!priority) priority = HfpLinkPriorityWithActiveCall(FALSE); /* no active calls but still a held call on the phone */ if(!priority) priority = HfpLinkPriorityFromCallState(hfp_call_state_held_remaining); /* If match found */ if(priority && HfpLinkGetCallState(priority, &call_state)) { switch(call_state) { case hfp_call_state_twc_incoming: case hfp_call_state_twc_outgoing: case hfp_call_state_held_active: case hfp_call_state_multiparty: CM_DEBUG(("CM: HangUp TWC active Call on AG%x\n",priority)) ; HfpCallHoldActionRequest(priority, hfp_chld_release_active_accept_other, 0); break; case hfp_call_state_held_remaining: CM_DEBUG(("CM: HangUp TWC held Call on AG%x\n",priority)) ; HfpCallHoldActionRequest(priority, hfp_chld_release_held_reject_waiting, 0); break; default: /* Terminate call using AT+CHUP */ CM_DEBUG(("CM: HangUp Call on AG%x\n",priority)) ; HfpCallTerminateRequest(priority); break; } } }
/**************************************************************************** NAME sinkCancelVoiceDial DESCRIPTION cancels a voice dial request RETURNS void */ void sinkCancelVoiceDial ( hfp_link_priority priority ) { uint8 Option = hfp_primary_link; CM_DEBUG(("CM: VD Cancelled")) ; /* for multipoint use there are two options */ if(theSink.MultipointEnable) { /* these being to use separate VD buttons, one for AG1 and one for AG2 or use one VD event and dial using the AG that last made an outgoing call */ if(theSink.features.SeparateVDButtons) { Option = priority; } /* voice dial using AG that made last outgoing call */ else { Option = theSink.last_outgoing_ag; } } /*if we believe voice dial is currently active*/ if ( theSink.VoiceRecognitionIsActive) { HfpVoiceRecognitionEnableRequest(Option, FALSE); theSink.VoiceRecognitionIsActive = hfp_invalid_link; } }
/**************************************************************************** NAME sinkRejectHeldIncomingCall DESCRIPTION looks for a held incoming call and performs the twc reject held incoming call function RETURNS void */ void sinkRejectHeldIncomingCall(void) { hfp_call_state CallState; /* find incoming held call */ if((HfpLinkGetCallState(hfp_primary_link, &CallState))&& (CallState == hfp_call_state_incoming_held)) { CM_DEBUG(("MAIN: Hold incoming Call on AG1\n")) ; HfpResponseHoldActionRequest(hfp_primary_link, hfp_reject_held_incoming_call); } else if((HfpLinkGetCallState(hfp_secondary_link, &CallState))&& (CallState == hfp_call_state_incoming_held)) { CM_DEBUG(("MAIN: Hold incoming Call on AG2\n")) ; HfpResponseHoldActionRequest(hfp_secondary_link, hfp_reject_held_incoming_call); } }
/**************************************************************************** NAME sinkPlaceIncomingCallOnHold DESCRIPTION looks for an incoming call and performs the twc hold incoming call function RETURNS void */ void sinkPlaceIncomingCallOnHold(void) { hfp_call_state CallState; /* find incoming call to hold */ if((HfpLinkGetCallState(hfp_primary_link, &CallState))&& (CallState == hfp_call_state_incoming)) { CM_DEBUG(("MAIN: Hold incoming Call on AG1\n")) ; HfpResponseHoldActionRequest(hfp_primary_link, hfp_hold_incoming_call); } else if((HfpLinkGetCallState(hfp_secondary_link, &CallState))&& (CallState == hfp_call_state_incoming)) { CM_DEBUG(("MAIN: Hold incoming Call on AG2\n")) ; HfpResponseHoldActionRequest(hfp_secondary_link, hfp_hold_incoming_call); } }
/**************************************************************************** NAME sinkInitiateLNR DESCRIPTION If HFP and connected - issues command If HFP and not connected - connects and issues if not in call If HSP sends button press RETURNS void */ void sinkInitiateLNR ( hfp_link_priority priority ) { CM_DEBUG(("CM: LNR\n")) ; /* if device not connected to any AG initiate a connection */ if (!stateManagerIsConnected() ) { #ifdef ENABLE_AVRCP sinkAvrcpCheckManualConnectReset(NULL); #endif MessageSend ( &theSink.task , EventUsrEstablishSLC , 0 ) ; sinkQueueEvent(EventUsrLastNumberRedial) ; } /* have at least one connection */ else { uint8 Option = hfp_primary_link; CM_DEBUG(("CM: LNR Connected\n")) ; /* for multipoint use there are two options */ if(theSink.MultipointEnable) { /* these being to use separate LNR buttons, one for AG1 and one for AG2 or use one LNR event and dial using the AG that last made an outgoing call */ if(theSink.features.SeparateLNRButtons) { CM_DEBUG(("CM: LNR use separate LNR buttons\n")) ; Option = priority; } /* dial using AG that made last outgoing call */ else { CM_DEBUG(("CM: LNR use last outgoing AG = %d\n",theSink.last_outgoing_ag)) ; Option = theSink.last_outgoing_ag; } } CM_DEBUG(("CM: LNR on AG %d\n",Option)) ; /* perform last number redial */ HfpDialLastNumberRequest(Option); } }
/**************************************************************************** NAME sinkInitiateVoiceDial DESCRIPTION If HFP and connected - issues command If HFP and not connected - connects and issues if not in call If HSP sends button press RETURNS void */ void sinkInitiateVoiceDial ( hfp_link_priority priority ) { CM_DEBUG(("CM: VD\n")) ; if (!stateManagerIsConnected() ) { #ifdef ENABLE_AVRCP sinkAvrcpCheckManualConnectReset(NULL); #endif MessageSend ( &theSink.task , EventUsrEstablishSLC , 0 ) ; sinkQueueEvent( EventUsrInitateVoiceDial ) ; theSink.VoiceRecognitionIsActive = hfp_invalid_link ; } else { uint8 Option = hfp_primary_link; CM_DEBUG(("CM: VD Connected\n")) ; /* for multipoint use there are two options */ if(theSink.MultipointEnable) { /* these being to use separate VD buttons, one for AG1 and one for AG2 or use one VD event and dial using the AG that last made an outgoing call */ if(theSink.features.SeparateVDButtons) { Option = priority; } /* voice dial using AG that made last outgoing call */ else { Option = theSink.last_outgoing_ag; } } CM_DEBUG(("CM: VoiceDial on %d\n",Option)) ; HfpVoiceRecognitionEnableRequest(Option, TRUE); theSink.VoiceRecognitionIsActive = Option; } }
/**************************************************************************** NAME sinkWriteStoredNumber DESCRIPTION Store number obtained via HfpRequestNumberForVoiceTag in CONFIG_PHONE_NUMBER RETURNS void */ void sinkWriteStoredNumber ( HFP_VOICE_TAG_NUMBER_IND_T* ind ) { /* validate length of number returned */ if((ind->size_phone_number)&&(ind->size_phone_number<SIZE_CONFIG_PHONE_NUMBER)) { uint16 phone_number_key[SIZE_CONFIG_PHONE_NUMBER]; CM_DEBUG(("Store Number ")); /* Make sure the phone number key is all zero to start */ memset(phone_number_key, 0, SIZE_CONFIG_PHONE_NUMBER*sizeof(uint16)); /* Write phone number into key array */ memmove(phone_number_key,ind->phone_number,ind->size_phone_number); /* Write to PS */ ConfigStore(CONFIG_PHONE_NUMBER, &phone_number_key, ind->size_phone_number); } }
/**************************************************************************** NAME sinkAnswerOrRejectCall DESCRIPTION Answer an incoming call from the device RETURNS void */ void sinkAnswerOrRejectCall( bool Action ) { hfp_link_priority priority; /* if the SR plugin is running, disconnect it */ MessageSend ( &theSink.task , EventSysSpeechRecognitionStop , 0 ) ; /* get profile if AG with incoming call */ priority = HfpLinkPriorityFromCallState(hfp_call_state_incoming); CM_DEBUG(("CM: Answer Call on AG%x\n",priority)) ; /* if match found */ if(priority) { /* answer call */ HfpCallAnswerRequest(priority, Action); theSink.profile_data[PROFILE_INDEX(priority)].status.local_call_action = TRUE; } /*terminate the ring tone*/ ToneTerminate(); }
/**************************************************************************** NAME sinkQueueEvent DESCRIPTION Queues an event to be sent once the device is connected RETURNS void */ void sinkQueueEvent ( sinkEvents_t pEvent ) { CM_DEBUG(("CM: QQ Ev[%x]\n", pEvent)) ; theSink.gEventQueuedOnConnection = (pEvent - EVENTS_MESSAGE_BASE); }
/** * @brief init the data warehouse, at the beginning, only the first buffer should be initiliazed * * @return 0-succ -1:fail */ int data_warehouse_init(void) { //set the initial buffer int switch_idx = 0; int max_switch_map_size = 0; if (cm_experiment_setting.switch_mem_type == UNIFORM) { max_switch_map_size = (int)( cm_experiment_setting.switch_memory_times * cm_experiment_setting.sample_hold_setting.default_byte_sampling_rate * cm_experiment_setting.sample_hold_setting.max_switch_interval_volume * cm_experiment_setting.sample_hold_setting.uniform_mem_ratio_to_diverse_mem ) ; if (max_switch_map_size <= 0) { char buf[200]; snprintf(buf, 200, "FATAL: ratio:%f, sample_rate:%f, max_switch_volume:%lu, max_switch_map_size:%d", cm_experiment_setting.sample_hold_setting.uniform_mem_ratio_to_diverse_mem, cm_experiment_setting.sample_hold_setting.default_byte_sampling_rate, cm_experiment_setting.sample_hold_setting.max_switch_interval_volume, max_switch_map_size ); ERROR(buf); return -1; } } int a_idx = 0; //active buffer idx for (; a_idx < BUFFER_NUM; ++a_idx) { for (switch_idx = 0; switch_idx < NUM_SWITCHES; ++switch_idx) { //init hashtables data_warehouse.flow_volume_map[a_idx][switch_idx] = ht_kfs_vi_create(); if (data_warehouse.flow_volume_map[a_idx][switch_idx] == NULL) { return -1; } data_warehouse.all_flow_selected_level_map[a_idx][switch_idx] = ht_kfs_vi_create(); if (data_warehouse.all_flow_selected_level_map[a_idx][switch_idx] == NULL) { return -1; } if (cm_experiment_setting.switch_mem_type == UNIFORM) { data_warehouse.flow_sample_map[a_idx][switch_idx] = ht_kfs_fixSize_create(max_switch_map_size); } else if (cm_experiment_setting.switch_mem_type == DIVERSE) { int map_size = (int)(cm_experiment_setting.switch_memory_times * cm_experiment_setting.sample_hold_setting.default_byte_sampling_rate * cm_experiment_setting.sample_hold_setting.switches_interval_volume[switch_idx]); if (map_size <= 0) { char buf[200]; snprintf(buf, 200, "FATAL: switchid:%d, switch_memory_times:%f, byte_sample_rate:%f, switch_volume:%lu", switch_idx, cm_experiment_setting.switch_memory_times, cm_experiment_setting.sample_hold_setting.default_byte_sampling_rate, cm_experiment_setting.sample_hold_setting.switches_interval_volume[switch_idx]); ERROR(buf); return -1; } data_warehouse.flow_sample_map[a_idx][switch_idx] = ht_kfs_fixSize_create(map_size); } if (data_warehouse.flow_sample_map[a_idx][switch_idx] == NULL) { return -1; } char buf[200]; snprintf(buf, 200, "init: buf_idx_%d, switch_%d, sample_volume_map_size-%u", a_idx, switch_idx, data_warehouse.flow_sample_map[a_idx][switch_idx]->size); CM_DEBUG(switch_idx, buf); //init interval infor data_warehouse.pkt_num_rece[a_idx][switch_idx] = 0; data_warehouse.volume_rece[a_idx][switch_idx] = 0; data_warehouse.condition_pkt_num_rece[a_idx][switch_idx] = 0; //data_warehouse.condition_map_collision_times[a_idx][switch_idx] = 0; //data_warehouse.condition_map_last_rotate_collision_times[a_idx][switch_idx] = 0; } } //pthread_mutex_init(&data_warehouse.condition_map_mutex, NULL); data_warehouse.active_idx = 0; NOTICE("SUCC data_warehouse_init"); return 0; }