MTK6225电话管理1

 

1.IDLE界面输入电话号码 IdleApp.c

       在函数mmi_idle_entry_idle_screen()中,设置了用户按下按键时的处理函数:

SetGroupKeyHandler(    HandleIdleScreenDigitEntry,

                                   IdleScreenDigits,

                                   MAX_IDLE_SCREEN_DIGITS - 1,

                                   KEY_EVENT_DOWN);

就是设置全局变量:currKeyFuncPtrs[][]。把IdleScreenDigits[]里定义的KEY_0,KEY_1,…KEY_9,KEY_START,KEY_POUND这几个按键的响应函数都设置为函数:HandleIdleScreenDigitEntry()。

       按下按键输入数字后,进入HandleIdleScreenDigitEntry(),首先获取输入的按键CODE,保存在g_idle_context.IdleScreenDigitKeyCode,然后调用IdleScreenDigitHandler(),处理输入的号码。此时screen id为:IDLE_SCREEN_DIGIT_HANDLER_ID。

       SetLeftSoftkeyFunction(EntryScrDialOptions, KEY_EVENT_UP);

       (按下方向键的center键,也是进入[选项]screen)

2.按左软件,进入选项screen.

       1拨号            MENU_DIAL_GSM             HighlightDialGSM()

       2IP拨号        MENU_DIAO_GSM_IP HighlightDialGSMIP()

       3保存            MENU_DIAL_SAVE             HighlightDialSave()

 

       (1)先学习直接拨号HighlightDialGSM()

              IdleDialPadCall()

              {

                     g_idle_context.AvoidHistoryofDialerScreen = 1;

                     SetTempUseIPNumber(FALSE);//设置gTempUseIPNum=0,没有使用IP拨号

 

       然后把g_idle_context.DialPadCallBuffer保存的用户输入的号码与补充业务的字串作比较。

       如果是某个补充业务的字串,就直接执行代码中与定义的处理函数;如果不是补充业务的字串,就MakeCall ()。

       补充业务的字串在文件:SSCStringHandle.h中定义。

 

 

                     #ifdef __MMI_TOUCH_DIAL_SCREEN__

    if (!SSCStringParsing2() && g_idle_context.DialPadCallBuffer[0] != '\0')

#else

    if (!SSCStringParsing2())

#endif

        MakeCall(g_idle_context.DialPadCallBuffer);

              }

       (2)IP拨号HighlightDialGSMIP()

              Gsm_DialIPNumber()

              {

                     首先判断IPSetting是否设置了。

                     如果没有设置IP号码,那么就弹出提示信息,然后返回到拨号screen。

                     如果设置了IP号码,则:

                     g_idle_context.AvoidHistoryofDialerScreen=1;

                   SetTempUseIPNumber(TRUE);    //设置gTempUseIPNum=1,使用IP拨号

 

                     if(!SSCStringParsing2())              //分析补充业务字串

                       MakeCall(g_idle_context.DialPadCallBuffer);

              }

 

       以上都是在IDLE这个application中操作哦,然后进入MakeCall,进入CALL MANAGEMENT中操作。

       在文件:MMI——features.h中,打开、关闭了所有的宏

void MakeCall(PS8 strNumber)            //OutgoingCallHelper.c

{

       由于宏__MMI_BG_SOUND_EFFECT__没有打开,因此直接执行:

       g_phb_cntx.dial_from_list = FALSE;

    MakeCallEx(strNumber, FALSE);

}

 

void MakeCallEx(PS8 strNumber, BOOL pre_check)

{

       检测电量是否允许MAKE MO CALL。

       ClearDtmfBuf()//清空:DTMFPadCallBuffer和UnicodeDTMFPadCallbuffer

       FillDtmfBuff((PU8) strNumber);//把号码拷贝到UnicodeDTMFPadCallbuffer中。

      

       检查号码是否是紧急号码,格式是否符合要求,然后:

       CheckShortCutOrCall();

}

 

void CheckShortCutOrCall(void)

{

       IsStandardGsmSS(dtmfBuf)这个函数是用来判断输入的字串是否为GSM系统的补充业务字串。

       MakeMyCall((PS8) dtmfBuf);       //dtmfBuf是ASCII码

}

 

void MakeMyCall(PS8 strNumber)

{

       就是把UnicodeDTMFPadCallBuffer中的号码拷贝到OUTGOING_CALL结构的变量outCall的number中,然后调用:

       MakeOutgoingcall(outCall);

}

 

typedef struct _outgoingcall

{

    U8 Number[MAX_CM_NUMBER];   /* Calling Number. */

    PS8 Name;

} OUTGOING_CALL;

 

void MakeOutgoingcall(OUTGOING_CALL MsgStruct)

{

       OutgoingProcessCMEvent(CM_KB_OUTGOINGCALL, &MsgStruct);进入状态机处理

}

 

ACTION_RESULT ProcessKBOutgoingEvent(void *MsgStruct)

{

       呼叫电话,不能在CM当前处于OUTGOING状态。

       AllowMoreCalls()判断能否再呼出一通电话。当1当前已经大于或等于6通电话了,2存在紧急电话EmergencyCallPresent(),3当前存在正在挂断的电话GetCallAbortReqSentFlag(),4存在呼叫等待的电话并且在history screen中,存在ITEM_SCR_USSN_MSG。

       gtmpOutgoingIndex = GetFirstFreeIndex();

       AddNewCallInfo()注意:如果在IDLE状态下呼叫,这个电话当前状态设置为OUGTOING,如果不是在IDLE状态下呼叫电话,那么这个CALL的当前状态被设置为GetCurrentState()。

       MakePsInitiateCall((PU8) DTMFPadCallBuffer, (void*)OutgoingCallConnected);

}

 

void MakePsInitiateCall(U8 *MsgStruct, void *callBack)

{

       获取IP号码

       MakePsSSVUSSDReq(MsgStruct, (PU8) IPNum, length, (void*)PsCBackSetCallFeatures);

       length没有包括IP号码的长度

}

void MakePsSSVUSSDReq(U8 *MsgStruct, U8 *IPNum, U16 length, void *callBack)

{

       Message.oslSrcId = MOD_MMI;

    Message.oslDestId = MOD_L4C;

    Message.oslMsgId = PRT_USSDVSS_REQ;

    Message.oslPeerBuffPtr = NULL;

 

详细消息:

       typedef struct

       {

              LOCAL_PARA_HDR

              kal_uint8 input[MAX_DIGITS_USSD];              IP号码+拨号号码

              kal_uint8 dcs;                                                  Ox0f

              kal_uint8 length;                                               IP+号码总长度

              kal_uint8 ip_string[21];                                     为空

       } mmi_ss_parsing_string_req_struct;

}

 

然后L4返回消息PRT_USSDVSS_RSP,进入CBACK:

PsCBackSetCallFeatures()

{

       首先判断L4返回的消息是否成功,并且判断是否是VOICE CALL。

       如果失败,显示失败提示信息,然后恢复CM之前的状态,设置这个CALL为IDLE状态,并且如果之前有INCOMING或者OUTGOING CALL,那么要重新设置变量:SetCMPhoneBookStruct(&phb_data);

       如果成功,并且gIsCCCall=1,那么就根据呼叫的号码到电话簿中找相关的信息:

PhoneNumberStruct = mmi_phb_call_get_data_for_call_mgnt(GetOutgoingNumber(), TRUE);

并且设置SetCMPhoneBookStruct(&PhoneNumberStruct);就是设置gPhoneNumberStruct变量。

 

       然后根据CHISTGetDialFromCallLogFlag()来判断是否从CALL LOG中拨号:

如果不是,那么就用刚才从电话簿中获取的信息去设置cm_p中的AllCalls变量:   SetOutgoingNamefromPhonebook();--把gPhoneNumberStruct里面的name,name_dcs复制    到cm_p->state_info.AllCalls[index]的pBname和name_dcs中。

如果是,并且CALL LOG中的名字与从电话簿中获取的名字一致,则什么都不做;如果不          一致,那么就使用CALL LOG中的名字,设置gPhoneNumberStruct的值全为0。

 

       然后OutgoingProcessCMEvent(CM_PS_SHOW_OUTGOING_CALL_SCREEN, NULL);

       CHISTSetDialFromCallLogFlag(0);//设置chis_p->dialFromCallLog=0

}

 

void ProcessShowOutgoingCallScreen(void)

{

       根据GetPreviousState()作不同处理。思路是:

       EntryScr1001OutgoingCall( );

       AddMarkerToHistory( );//根据需要来调用

}

 

void EntryScr1001OutgoingCall(void)

{

       TurnOnBacklight(1);             //开背光,1-短时间

    SetCbackAfterSS(NULL);

    SetAbortCallRequestedFlag(FALSE);    //gCallAbortRequested=0,

    SetProtocolEventHandler(PsCBackNetworkCallDropped, PRT_NWRK_CALL_RELEASE);

    SetCMScrnFlag(TRUE);                            //gCMScrnFlag=1

 

       gPhoneNumberStruct中,如果pictureId=1,表示在呼叫界面中要显示文件中存储的图片。调用接口:

       imgPath = mmi_phb_image_get_path_from_id(PhoneNumberStruct->record_index);

来获取图片的路径。参数是record_index。

       注意:宏__MMI_PHB_CALL_SHOW_PICTURE_FROM_FILE__是打开的。

       if (GetTotalCallCount() > 1)                               //大于1通电话

       {

              if (GetDisconnectingCallHandle() != -1)       //存在正在挂断的电话

              {

                     if (nOutGoingImgId == 1)                   //显示文件中的图片

                     {

                     }

                     else

                     {

                     }

              }

              else

              {

                     if (nOutGoingImgId == 1)

                     {

                     }

                     else

                     {

                     }

              }

       }

       else

       {

              if (GetDisconnectingCallHandle() != -1)

              {

                     if (nOutGoingImgId == 1)

                     {

                     }

                     else

                     {

                     }

              }

              else

              {

                     if (nOutGoingImgId == 1)

                     {

                     }

                     else

                     {

                     }

              }

       }

}

 

然后,如果L4处理成功,返回消息PRT_OUTGOINGCALL_EVENT_RSP,进入CBACK:

void PsCbackOutgoingCallIdSync(void *MsgStruct)

{

       主要是设置OUTGOING CALL的call_id,也就是call_handle。
       如果失败

              设置失败原因:gCallEndCause

              设置拨号标志:gCheckDialIndEndOutgoing=0

              LogCallInfoForCallHistory(GetOutgoingCallHandle());

       GetEndTimeAndLogUnconnectedMOCall();

               if (IsRedialSet())               //自动重拨,设置重拨的号码

        {  

            SetRedialNumber();

        }

              OutgoingProcessCMFailureEvent(CM_PS_CALLCONNECTED, response);

              设置gCallEndedBeforeConnFlag=0

       如果成功:

              SetOutgoingCallHandle(handle);       //设置AllCalls中的call_handle

              设置标志:gCheckDialIndEndOutgoing=1

              如果当前大于一通电话,就同步一下:SyncCallList()。

}

 

      至此,呼出一通电话的处理就完成了。

 

对方忙,启动了自动重拨

void ProcessPSCallConnectFailEvent(U16 cause)

{

       判断gIsCCCall。必须是voice call才能自动重拨

       switch( GetCurrentState( ) )       //判断当前的CM状态

       {

              case CM_INCOMING_STATE:如果此时有来电,就不会自动重拨

                PurgeOutgoingCallsStructure();

                cause = 0;

                break;

              case CM_OUTGOING_STATE:      //只有处于OUTGOING状态,才重拨

                     type = GetOutgoingCallType();.//获取呼出电话的类型

                     PurgeOutgoingCallsStructure();//设置OUTGOING CALL的状态为ILDE,清除AllCalls[index]中的变量,总的电话数目减1

                     SetCurrentState(GetPreviousState());

                     SetPreviousState(CM_OUTGOING_STATE);

                     if (GetTotalCallCount() == 0)

           {

只有是VOICE CALL才能重拨;IsRedialNeeded()这个函数判断哪些情况下需要重拨,并且设置重拨的次数:SetMaxAttempts()。就是设置变量:cm_p->redial_info.MaxAttempts的值。在这个函数中,如果不符合重拨的条件,就会清空cm_p->reial_info中的变量内容,停止自动重拨的定时器:StopTimer(CM_REDIAL_TIMER)。

           if ((type != CM_VOICE_CALL) || (IsRedialNeeded(cause) == FALSE))

                {

                    ShowCallManagementErrorMessage(cause);

                    GetOutOfCMforAdjustHistory();

                    return;

                }

                else

                {

                    if (IsRedialSet())读取NVRAM中保存的是否启动自动重拨标志。NVRAM_SETTING_AUTOREIDAL。如果取出的是Oxff,那么就默认为不启动自动重拨。设置变量:g_callset_context.AutoRedialStatus

                    {

                        SetCallEndedBeforeConnFlag(FALSE);

                        CheckRedialOrShowError(cause);

                        DeleteScreenIfPresent(ITEM_SCR_USSN_MSG);

                        return;

                     }

                }

            }

       }

       ShowCallManagementErrorMessage(cause);  //显示信息:对方忙。如果启动了自动重拨,那么还启动了一个定时器,显示自动重拨的提示信息。定时器溢出的响应函数是:ShowRedialScreen()-----

ShowCategory141Screen(0, 0, 0, 0, STR_GLOBAL_ABORT, 0, gRedialMsgTemp, 0, NULL);

                    

}

 

学习一下这个函数:

void CheckRedialOrShowError(U16 response)

{

       result = CalculateSetBackOff();在这个函数中,处理了自动重拨的一些设置

    ShowCallManagementErrorMessage(response);

    if (result == TRUE)

          SetCurrentState(GetPreviousState());

    return;

}

 

pBOOL CalculateSetBackOff(void)

{

       cm_p->redial_info.CurrentAttempt++;     //对重拨次数的控制就是在此实现的

       if (cm_p->redial_info.CurrentAttempt > cm_p->redial_info.MaxAttempts)

    {

        ResetRedialAttempts();重拨次数结束,就要清空redial_info。

        return FALSE;

    }

 

       然后根据重拨的次数,动态的设置距离下次拨号的时间,也就是定时器的溢出时间。并设置要显示的字串:gReialMsgTemp。

 

       cm_p->redial_info.RedialTimer = TRUE;

    StartTimer(CM_REDIAL_TIMER, (timer * 1000), (FuncPtr)                                                    RedailAttemptNoArg);       启动定时间,注册响应函数

    return TRUE;

}

 

重拨定时器溢出后,进入响应函数:

void RedailAttemptNoArg(void *info)

{

       StopTimer(CM_REDIAL_TIMER); 首先停止定时器

       cm_p->redial_info.RedialTimer = FALSE;

 

       SetPreviousState(CM_IDLE_STATE);

    SetCurrentState(CM_OUTGOING_STATE);

 

       AddNewCallInfo(

        (U8*) cm_p->redial_info.RedialNum,

        (CALL_STATE) GetCurrentState(),

        CM_IDLE_STATE,

        CM_CALL_MO,

        (CM_CALL_HANDLE) (index + 1),

        CM_VOICE_CALL);

 

       UnicodeToAnsii(TempMsgStruct, (PS8) cm_p->redial_info.RedialNum);

    MakePsInitiateCall((PU8) TempMsgStruct, (void*)OutgoingCallConnected);

}

 

小结:自动重拨的控制变量就是cm_p->redial_info。

              自动重拨之后,又进入OUTGOING的状态,下面的步骤与刚开始拨号的步骤是一样的,只不过CurrentAttempt的值增加了1。如果已经达到了最大次数,仍没有拨通,那么在函数CalculateSetBackOff()中会调用ResetRedialAttempts()把这组变量都清为0。以便以后自动重拨的使用。

       如果在某次自动重拨时成功接通了,这时也要调用ResetRedialAttempts()函数把这组变量清为0,否则以后自动重拨就收到影响了。那么成功接通时,是在哪里清0这组变量的呢??

       解答:在模拟器上跟踪发现,并不是在电话接通时清0的,而是在挂断电话时,显示“通话已结束”这个信息之后,进入函数:GoBackfromNotifyScr()中,调用GetOutOfCMApplication();其中又有:

        /* reset redial data */

    if (IsRedialSet())

    {

        ResetRedialAttempts();     在这里对redial_info进行了清0操作

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七斗星

赏点银子去植发

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值