一、进入ILDE界面
1.EntryIdleScreen()
2.mmi_idle_entry_idle_screen()
注册按键:HandleIdleScreenDigitEntry()
IdleSetLRKey()注册左软件EntryMainMenuFromIdleScreen(),右软件mmi_phb_idle_enter_phb_list()
注册SEND键CHISTGetCallLogBySENDKey()
注册相机按键mmi_camera_entry_app_screen()
注册声音按键SetDefaultVolumeKeyHandlers()
二、按下数字键(123456)
1. HandleIdleScreenDigitEntry()
判断是否处飞行静音模式
2. IdleScreenDigitHandler()
ShowCategory16Screen()建立拨号输入框,并且注册每个按键的响应
执行数字键‘1’的响应:MMI_key_1_down()
注册 左软件IdleDialPadSavePhoneBook(),SEND键IdleDialPadCall (),#键IdleAbbrevDialling(),
速拨IdleCallSpeedDialOnLongPress(),语音DialVoiceMail()
三、按下SEND键拨号
1. IdleDialPadCall()
gTempUseIPNum——
判断是否是ssc_table2[]中号码()
mmi_idle_remove_dialer_screen_exit_handler()
2. MakeCall()
在初始化函数InitCallInfo( )中设置了cm_p->ucm_action_type = MMI_GSM_UCM_NO_ACTION,cm_p->ucm_operation = MMI_GSM_UCM_IDLE
因此: mmi_ucm_app_make_call(MMI_UCM_VOICE_CALL_TYPE, (U8*)strNumber);
return;
3. mmi_ucm_app_make_call()
把拨号信息装载到g_ucm_p->mo_info中(module_id, dial_type, dial_num.num_uri,只有号码,暂时还没有姓名)
4. mmi_ucm_outgoing_call_sendkey()
判断是否是飞行模式mmi_bootup_get_active_flight_mode()
判断UCM是否存在有待处理的CALL:mmi_ucm_is_pending_action()
判断是否是call related supplementary service:mmi_ucm_is_crss()
判断是否是紧急呼叫:mmi_ucm_is_sos_number()--CheckValidEmergencyNo1()
判断是否是空号码
判断是否已经存在SOS
判断UCM是否忙:mmi_ucm_is_busy()--没有需要处理的Call,没有OUTGOING, INCOMING的group,没有emergency call。
判断是否可以显示拨号选项:mmi_ucm_dial_option()
以上都排除之后,存在以下3中拨号:
(1)是SS_OPERATION:mmi_ucm_dial_action()
(2)已经存在DATA/CSD且本次拨号非DATA/CSD,或者已经存在非DATA/CSD且本次拨号是DATA/CSD:(即:DATA/CSD与正常call不能同时存在)
g_ucm_p->mo_info.is_wait_dial = TRUE;
mmi_ucm_end_all_action();
(3)已经有一组group电话状态为MMI_UCM_ACTIVE_STATE:mmi_ucm_hold_and_dial_action()
(4) mmi_ucm_dial_action( )
如果拨号失败,设置自动重拨。
5. mmi_ucm_dial_action()
S32 freeTab = g_ucm_p->call_list.num_group;
mmi_ucm_id_info_struct actionId; 这个变量传到下一个函数去
g_ucm_p->call_misc.curr_action = MMI_UCM_DIAL;
装载g_ucm_p->call_list.group_info[freeTab]信息(group_id, call_type, call_state)
装载g_ucm_p->call_list.group_info[freeTab].call_info[0]信息
g_ucm_p->call_list.group_info[freeTab].num_call++;
g_ucm_p->call_list.num_group++;
装载actionId
mmi_ucm_pre_send_req(MMI_UCM_DIAL, &actionId, NULL, &g_ucm_p->mo_info);
6. mmi_ucm_pre_send_req( ) 所有关于CALL的请求都要走这里
mmi_ucm_dial_req_struct dialReq;
装载dialReq
mmi_ucm_send_req(op_code, first_ptr->call_type, &dialReq);
7. mmi_ucm_send_req( ) 所有关于CALL的请求都要走这里
mmi_gsm_ucm_act_req(MMI_UCM_DIAL, act_struct);
8. mmi_gsm_ucm_act_req( )
设置了cm_p->ucm_action_type = MMI_GSM_UCM_NORMAL,cm_p->ucm_operation = MMI_GSM_UCM_DIAL
mmi_gsm_dial(act_struct)
9. mmi_gsm_dial( )
MakeCall((PS8)dial_number);
10.MakeCall( )
此时,cm_p->ucm_operation = MMI_GSM_UCM_DIAL
判断是否是紧急拨号
判断号码是否为空,是否含有非法字符
MakeCallEx(strNumber, TRUE, CSMCC_VOICE_CALL);
11.MakeCallEX( )
装载UnicodeDTMFPadCallBuffer
CheckShortCutOrCall(call_type);
12. CheckShortCutOrCall( )
装载DTMFPadCallBuffer
判断是否含有#
判断是否是短号码
MakeMyCall((PS8) dtmfBuf,call_type)
13. MakeMyCall( )
OUTGOING_CALL outCall;
装载outCall。(号码,类型)
MakeOutgoingcall(outCall);
14. MakeOutgoingcall( )
OutgoingProcessCMEvent(CM_KB_OUTGOINGCALL, &MsgStruct); 进入状态机
15. ProcessKBOutgoingEvent()
装载gCurrOutcall(号码和类型)
switch (GetCurrentState())
case CM_IDLE_STATE:
SetPreviousState(CM_IDLE_STATE);
SetCurrentState(CM_OUTGOING_STATE);
AddNewCallInfo()
MakePsInitiateCall((PU8)MsgStruct, (void*)OutgoingCallConnected);
16. MakePsInitiateCall( )
获取IP number。不使用为NULL
MakePsSSVUSSDReq(MsgStruct, (PU8) IPNum, length, (void*)PsCBackSetCallFeatures);
17. MakePsSSVUSSDReq( )
装载消息结构,发送消息:PRT_USSDVSS_REQ(到L4层分析号码)
L4层分析号码后,返回消息:PRT_USSDVSS_RSP,进入CBACK:
1.PsCBackSetCallFeatures()
根据拨出号码,设置到PHB查找,设置gPhoneNumberStruct
设置拨出电话的姓名SetOutgoingNamefromPhonebook()
mmi_gsm_dial_rsp(TRUE, CC_OPERATION, NULL, NULL);
2. mmi_gsm_dial_rsp( )
mmi_ucm_dial_act_rsp_struct dial_rsp;
设置了cm_p->ucm_action_type = MMI_GSM_UCM_NO_ACTION,cm_p->ucm_operation = MMI_GSM_UCM_IDLE
mmi_gsm_get_call_list(dial_rsp.call_list); 把cm_p中的信息拷贝到dial_rsp.call_list中,填充dial_rsp.call_list的所有结构
装载dial_rsp.remote_info为最后一通呼出电话的信息
装载dial_rsp. alert_info(image_info.image_id,image_info.record_index,ip_num)
mmi_ucm_dispatch_rsp(MMI_UCM_DIAL, MMI_UCM_VOICE_CALL_TYPE, (void *)&dial_rsp);
3. mmi_ucm_dispatch_rsp( ) UCM都走这里
mmi_ucm_dial_act_rsp(act_struct);
4. mmi_ucm_dial_act_rsp(void *act_struct ) 参数就是上面的dial_rsp
g_ucm_p->mo_info.is_wait_dial = FALSE;
mmi_ucm_sync_call_list(rsp->call_list); 需要理解!!!!!!!!
memcpy(&g_ucm_p->mo_mt_display, &rsp->alert_info, sizeof(mmi_ucm_ring_info_struct));
mmi_ucm_set_process_state(-1, -1, MMI_UCM_DO_PROCESS_STATE, MMI_UCM_COMP_PROCESS_STATE);
mmi_ucm_set_process_state(-1, -1, MMI_UCM_COMP_PROCESS_STATE, MMI_UCM_IDLE_PROCESS_STATE);
mmi_ucm_go_back_screen_check();
5. mmi_ucm_go_back_screen_check( )
判断UCM没有处于:MMI_UCM_WAIT_PROCESS_STATE,MMI_UCM_DO_PROCESS_STATE,MMI_UCM_COMP_PROCESS_STATE
mmi_ucm_entry_marker();
mmi_ucm_entry_outgoing_call();
6. mmi_ucm_entry_outgoing_call()
EntryNewScreen(SCR_ID_UCM_OUTGOING, mmi_ucm_exit_outgoing_call, mmi_ucm_entry_outgoing_call, NULL);
ShowCategory17Screen()
注册右软件,END键mmi_ucm_outgoing_call_endkey()
注册侧键mmi_ucm_set_sidekey();
L4返回消息PRT_OUTGOINGCALL_EVENT_RSP,进入CBACK:
1.PsCbackOutgoingCallIdSync( )
如果不止1通电话,MMI与L4 PS同步:SyncCallList();
SetOutgoingCallHandle(handle); 设置 cm_p->state_info.AllCalls[count].call_handle,cm_p->state_info.AllCalls[count].group_id
mmi_gsm_sync_call_list_ind();
2. mmi_gsm_sync_call_list_ind( )
mmi_gsm_get_call_list(call_list); 把cm_p中的电话信息拷贝到call_list中
mmi_ucm_dispatch_ind(MMI_UCM_SYNC_CALL_LIST, (void *)call_list);
3. mmi_ucm_sync_call_list(call_list) 同步cm_p与g_ucm_p电话信息
4. mmi_ucm_go_back_screen_check();
返回到mmi_ucm_entry_outgoing_call()
拨出电话被网络接通,L4返回消息PRT_OUTGOINGCALL_CONNECTED,进入CBACK:
1.OutgoingCallConnected()
OutgoingProcessCMEvent(CM_PS_CALLCONNECTED, &handle);
2. ProcessPSCallconnectedEvent()
switch (GetCurrentState())
case CM_OUTGOING_STATE:
MakeHold();
SetPreviousState(GetCurrentState());
SetCurrentState(CM_ACTIVE_STATE);
SetCallState(gtmpOutgoingIndex, CM_ACTIVE_STATE, FALSE);
判断是否有INCOMING CALL,如果有,要回到来电界面
mmi_gsm_connect_ind(callHandle);
3. mmi_gsm_connect_ind( )
mmi_ucm_connect_ind_struct connect_ind;
装载connect_ind的3个结构:uid_info, remote_info, call_list。(call_list拷贝于cm_p中的电话信息)
mmi_ucm_dispatch_ind(MMI_UCM_CONNECT_IND, (void *)&connect_ind);
SetTempUseIPNumber(FALSE);
ResetRedialAttempts();
4. void mmi_ucm_connect_ind(void *act_struct) 参数就是上面的connect_ind
断言OUTGOING GROUP只有1组
DTGetRTCTime(&g_ucm_p->call_list.group_info[groupIndex].call_info[0].start_time);
mmi_ucm_log_call_history(groupIndex, 0, TRUE); log call
mmi_ucm_sync_call_list(ind->call_list); 同步cm_p和g_ucm_p
mmi_ucm_go_back_screen_check( )
5. mmi_ucm_go_back_screen_check( )
如果SCR_ID_UCM_IN_CALL不存在,则mmi_ucm_entry_in_call( ); 然后启动时间提醒
如果存在,GoBackHistory();
6. mmi_ucm_entry_in_call()
RegisterHighlightHandler(mmi_ucm_highlight_in_call_item);
ShowCategory403Screen()
注册按键响应
主动挂断1通ACTIVE CALL
1.mmi_ucm_in_call_endkey()
当前高亮group,如果:
只有1通电话:mmi_ucm_end_single_action()
不止一通电话:mmi_ucm_end_conference_action()
2. mmi_ucm_end_single_action()
3. mmi_ucm_end_single_action_with_index(g_ucm_p->call_misc.hilite_tab, g_ucm_p->call_misc.hilite_index)
mmi_ucm_id_info_struct actionId;
显示:processing。。。
g_ucm_p->call_misc.curr_action = MMI_UCM_END_SINGLE;
g_ucm_p->call_list.group_info[hiliteTab].call_info[hiliteIndex].proc_state = MMI_UCM_DO_PROCESS_STATE;
g_ucm_p->call_list.group_info[hiliteTab].call_info[hiliteIndex].act_type = MMI_UCM_END_SINGLE;
装载actionId
mmi_ucm_pre_send_req(MMI_UCM_END_SINGLE, &actionId, NULL, NULL);
4. mmi_ucm_pre_send_req( )
mmi_ucm_single_call_struct singleReq;
装载singleReq
mmi_ucm_send_req(op_code, first_ptr->call_type, &singleReq);
5. mmi_ucm_send_req( )
mmi_gsm_ucm_act_req(MMI_UCM_END_SINGLE, act_struct);
6. mmi_gsm_ucm_act_req( )
设置了cm_p->ucm_action_type = MMI_GSM_UCM_NORMAL,cm_p->ucm_operation = MMI_GSM_UCM_END_SINGLE
mmi_gsm_end_single(act_struct);
7. mmi_gsm_end_single(act_struct); 所有的挂断电话都是在这里处理!!
分3中情况:
(1)挂断的电话是OUTGOING,且还没有返回call id
SetCallAbortReqSentFlag(TRUE);
SetCallflag(((mmi_ucm_single_call_struct*) act_struct)->action_uid.call_id, CM_HANGUP_REQUESTED, TRUE);
MakePsAthRequest((void*)PsCBackOutgoingCallEnded);
(2)挂断的电话是来电,且目前只有此1通电话
SetCallflag(((mmi_ucm_single_call_struct*) act_struct)->action_uid.call_id, CM_HANGUP_REQUESTED, TRUE);
MakePsAthRequest((void*)PsCBackIncomingCallRejected);
(3)其他情况(已经返回call id的OUTGOING CALL, 拒接呼叫等待的INCOMING CALL, ACTIVE、HOLD CALL)
根据挂断电话的call id到cm_p->state_info.AllCalls[count]查找
挂断呼叫等待:MakePsSendUDUB((void*)PsCBackIncomingCallRejected);
挂断其他:MakePsEndSelectiveCall((void*)HangupReqSucess, ((mmi_ucm_single_call_struct*) act_struct)->action_uid.call_id);
8.MakePsEndSelectiveCall()
SetChldReqSent(CM_ENDSELECTIVE_REQ_SENT);
装载消息PRT_CALLENDSPECIFIC_EVENT
opcode = CSMCC_REL_SPECIFIC_CALL;
L4返回消息PRT_CALLENDSPECIFIC_SUCCESS:进入CBACK:
1.HangupReqSucess()
OutgoingProcessCMEvent(CM_PS_HANGUPSUC, (void*)&handle); 进入状态机
2. ProcessPSHangupSucEvent()
根据返回的call id到cm_p中找到这个被挂断的电话,用找到的信息设置cm_p->disc_call
switch (GetCurrentState())
case CM_HOLD_STATE:
case CM_ACTIVE_STATE:
ResetCallflag((*handle), CM_HANGUP_REQUESTED, TRUE);
SetCallState((*handle), CM_IDLE_STATE, TRUE);
设置cm_p的prev_state和curr_state 到此,挂断电话信息在cm_p中仅存在于cm_p->disc_call中。
mmi_gsm_release_ind( GetCallEndCause());
SetCallAbortReqSentFlag(FALSE);
mmi_gsm_end_single_rsp(TRUE, NULL);
3. mmi_gsm_release_ind( )
mmi_ucm_release_ind_struct release_ind;
用cm_p->disc_call去装载release_ind
mmi_ucm_dispatch_ind(MMI_UCM_RELEASE_IND, (void *)&release_ind);
memset(&cm_p->disc_call, 0, sizeof(mmi_gsm_disc_call_struct));
4. mmi_ucm_release_ind( )
根据挂断电话的句柄,到g_ucm_p中找它的信息
mmi_ucm_stop_inband_tone();
mmi_ucm_stop_incoming_tone();
memcpy(&ansMode, GetAnsweringMode(), sizeof(MMI_ANSWERING_MODE));
如果自动应答开启,停止自动应答定时器
if (开始时间正确,说明已经log call)
mmi_ucm_log_call_duration(index.group_index, index.call_index); 记录通话时间
else //说明还没有log call
mmi_ucm_log_call_history( )
装载g_ucm_p->call_end
mmi_ucm_sync_call_list(ind->call_list); 同步g_ucm_p与cm_p的电话信息。此时,挂断电话信息在cm_p->disc_call和g_ucm_p->call_end中。
mmi_ucm_entry_call_end() 通过g_ucm_p->call_end的信息,显示通话时间界面
mmi_ucm_go_back_screen_check( );
调整:扩音器,静音等设置。
5. mmi_gsm_end_single_rsp()
mmi_ucm_act_rsp_struct end_single_rsp;
设置:cm_p->ucm_action_type = MMI_GSM_UCM_NO_ACTION, cm_p->ucm_operation = MMI_GSM_UCM_IDLE
memset(&end_single_rsp, 0, sizeof(mmi_ucm_act_rsp_struct));
mmi_gsm_get_call_list(end_single_rsp.call_list); 装载call_list结构,从cm_p中拷贝过来(被挂断电话的信息已经不存在了)
清除自动重拨ResetRedialAttempts();
mmi_ucm_dispatch_rsp(MMI_UCM_END_SINGLE, MMI_UCM_VOICE_CALL_TYPE, (void *)&end_single_rsp);
6. mmi_ucm_end_act_rsp( )
mmi_ucm_sync_call_list(rsp->call_list); 同步g_ucm_p与rsp->call_list(即:cm_p)中的电话信息
mmi_ucm_set_process_state(-1, -1, MMI_UCM_DO_PROCESS_STATE, MMI_UCM_COMP_PROCESS_STATE);
mmi_ucm_set_process_state(-1, -1, MMI_UCM_COMP_PROCESS_STATE, MMI_UCM_IDLE_PROCESS_STATE);
L4返回消息PRT_END_CHLD_RSP:进入CBACK:
1.CheckFailureChld( )
SetChldReqSent(CM_ACTION_NONE);
mmi_gsm_end_single_rsp(TRUE, NULL); 与上面的相同!