MTK6225电话管理3

 

来电和呼叫等待

在空闲状态下是来电,在ACTIVE或者HOLD状态下是呼叫等待。

1.IDLE状态下来电,L4发送消息PRT_INCOMINGCALL_EVENT

void PsCBackCallIncoming(void *info)

{

       参数:#define MMI_INCOMING        mmi_cc_call_ring_ind_struct

       typedef struct

       {

              LOCAL_PARA_HDR

              kal_uint8       call_id;

              l4c_number_struct       num;

              l4c_sub_addr_struct    sub_addr;

              kal_uint8       name[30];

              kal_uint8       auto_answer;

              kal_uint8       call_type;

       } mmi_cc_call_ring_ind_struct;

 

       首先获取来电的号码,类型,句柄,然后判断是否启动了拒接不明来电,就是没有号码的来电。如果启用了,就自动拒接。也就是说,如果是匿名来电,并且手机启动了拒接功能,那么就直接发送ATH去拒接电话。即没有把来电的信息添加到AllCalls中。

       gRejectCallFlag判断当前是否开启拒接不明来电

       if(    GetRejectUnknownCallFlag() &&

              (pfnUnicodeStrlen((PS8)myIncmg.Number) == 0))

       {

              //Reject;

              SetClearKeyFlag(FALSE);

              MakePsAthRequest( (void*)PsCBackIncomingCallRejected);

              return;

       }与主动拒接来电的处理是相同的。

 

       ProcessIncomingEvents(CM_PS_CALL_INCOMING info);

}

 

进入状态机处理函数,参数info是来电信息

ACTION_RESULT ProcessIncomingCallEvent(void *info)

{

       gAttempToAnswer = FALSE;

       LeftKeyIncomingShowMute=FALSE;

       SetAnswerMode(NULL);//设置应答模式gCMAnsMode=0

       SetCallWaitFlag(FALSE);//设置呼叫等待的标志gCallWaitFlag=0

 

       switch(GetCurrentState())   //处理2种当前状态:IDLE,OUTGOING

       {

              case CM_IDLE_STATE:

                     SetPreviousState(GetCurrentState());

          SetCurrentState(CM_INCOMING_STATE);

                     AddNewCallInfo(

                myIncmg.Number,

                GetCurrentState(),

                GetPreviousState(),

                CM_CALL_MT,

                (CM_CALL_HANDLE) myIncmg.callHandle,

                myIncmg.callType);

 

              黑名单的拒接处理。

              gBlackListFlag指示是否启动了来电警卫。

              gBlackIncomingFlag指示拒接了一个黑名单中的电话

              #ifdef __MMI_CM_BLACK_LIST__

      if (BlockedHandle((CM_CALL_HANDLE) myIncmg.callHandle) == TRUE)

      {

        SetBlackIncomingFlag(TRUE);

        ProcessIncomingEvents(CM_KB_INCOMING_CALL_REJECT, info);

        return CM_CALL_SUCCESS;

     }

    #endif

 

              自动应答操作:

              gCMAnsMode---自动应答变量

              gAutoAnswerFlag—指示已经自动应答了

                     SetAnswerMode(GetAnsweringMode());

 

            if (((MMI_ANSWERING_MODE*) GetAnswerMode())->automatic == TRUE && (((MMI_INCOMING*)info)->call_type != CSMCC_FAX_CALL))

            {

                SetAutoAnswerFlag(TRUE);// gAutoAnswerFlag

                StartTimer(

                    CM_AUTOANSWER_NOTIFYDURATION_TIMER,

                    CM_AUTOANSWER_NOTIFY_TIMEOUT,       2秒钟

                    KbCBackCallIncomingAccepted);

            }

 

                     EntryScrIncomingCallEvent();

                     if (!GetRingingFlag())

              {

                 ShowIncomingCallIndication();

              }

              AddMarkerToHistory();

                     return CM_CALL_SUCCESS;

 

       case CM_OUTGOING_STATE:

                     if (cm_p->redial_info.RedialTimer == TRUE)//正处在自动重拨

                     {

                            与上面的处理一样,不同的就是:终止了自动重拨                                             ResetRedialAttempts();

                     }

                     else //MO MT冲突

                     {

                            冲突的话,终止MO,以MT为优先,与上面的处理相同

                     }

       }

}

 

*  This function is the entry screen for the incoming call*

void EntryScrIncomingCallEvent(void)

{

       获取显示的来电姓名,图像等

      

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

       {

              ShowCategory17Screen();

       }

       else //没有正在挂断的电话

       {

              #ifdef __MMI_INCOMING_CALL_VIDEO__   //来电显示VIDEO

              if ((imgId & 0x8000) || ((imgId & 0x3fff) >= VDO_ID_PHB_MTCALL_1))

                     ShowCategory17Screen();

              else

              #endif

                     ShowCategory17Screen()

 

              开始设置按键响应函数

              SetRightSoftkeyFunction(KbCBackCallIncomingRejected,                                                                                     KEY_EVENT_UP);

              if (GetTotalCallCount() > 1)

              {

                     SetLeftSoftkeyFunction(EntryScrIncomingMultipleOptions,                                                                              KEY_EVENT_UP);如果有多通电话时,发生                                                         呼叫等待时,左软件的选项入口函数

                    

              }

              else

              {

                     SetKeyHandler(KbCBackCallIncomingAccepted, KEY_SEND,                                                              KEY_EVENT_DOWN);

            SetKeyHandler(KbCBackCallIncomingRejected, KEY_END,                                                              KEY_EVENT_DOWN);

              SetKeyHandler(KbCBackCallIncomingRejected, KEY_RSK,                                                                  KEY_EVENT_DOWN);

              }

       }

}

 

呼叫等待

L4发送来消息PRT_INCOMING_CALL_WAIT,进入:

void PsCBackCallWait(void *info)

{

    ProcessIncomingEvents(CM_PS_CALL_WAIT, info);

}

 

首先设置:

SetAutoReleaseFlag(TRUE);     //gAutoReleaseFlag=TRUE

ReleaseCall();这个函数处理过程是:针对当前所有的curr_state=CM_DISCONNECTING_STATE的CALL,

                     MakePsReleaseCompleteRequest(handle); PRT_RELCOMP_EVENT

           OutgoingProcessCMEvent(CM_PS_HANGUPSUC, (void*)&handle);

然后再设置:SetAutoReleaseFlag(FALSE); //gAutoReleaseFlag=FALSE

 

再进入:

ACTION_RESULT ProcessCallWait(void *info)

{

       gAttempToAnswer=FALSE

       SetPreviousState(GetCurrentState());

    SetCurrentState(CM_INCOMING_STATE);

 

       SetCallWaitFlag(TRUE);//gCallWaitFlag=TRUE

       AddNewCallInfo(

        myIncmg.Number,

        GetCurrentState(),

        GetPreviousState(),

        CM_CALL_MT,

        (CM_CALL_HANDLE) myIncmg.callHandle,

        myIncmg.callType);

 

       黑名单处理,自动拒接,与上面的相同

       if (BlockedHandle((CM_CALL_HANDLE) myIncmg.callHandle) == TRUE)

    {

        ProcessIncomingEvents(CM_KB_INCOMING_CALL_REJECT, info);

        return CM_CALL_SUCCESS;

    }

 

       EntryScrIncomingCallEvent();

 

    StartRingTone(TONE_CALL_WAITING);

 

    if (!IsScreenPresent(CM_SCR_MARKER))

    {

        AddMarkerToHistory();

    }

}

 

拒接来电

来电的拒接,可以有这样几种情况:1自动拒接匿名来电,2自动拒接黑名单中的号码来电,3用户按下右软件手动拒接来电。这3种方式的代码进入点是不一样的,但是,本质操作是相同的。

 

手动按下右软件[拒接],进入:

void KbCBackCallIncomingRejected(void)

{    

       gAttempToReject=TRUE

       UnSilencethePhone();

    StopIncomingCallIndication();在这里清除了呼叫等待的标志gCallWaitFlag

    ProcessIncomingEvents(CM_KB_INCOMING_CALL_REJECT, NULL); 上面的拒接黑名单的操作就是直接进入这里,即直接进入状态机拒接,没有设置gAttempToReject,没有停止IncomingCallIndication(因为就没有打开)。

}

 

进入状态机,这里分为3中情况:

case CM_KB_INCOMING_CALL_REJECT:

       handle = GetIncomingCallHandle();

    if (GetTotalCallCount() > 1)   //拒接的是呼叫等待的来电

       {

              SetCallState(handle, CM_DISCONNECTING_STATE, TRUE);

              MakePsSendUDUB((void*)PsCBackIncomingCallRejected);

                     设置gChldReqSent=CM_UDUB_REQ_SENT

                     发送的消息是:PRT_UDUB_REQ

                     消息opnode是:CSMCC_REL_HELD_OR_UDUB.

                     L4返回消息是:PRT_UDUB_RES_SUCCESS

       }

       else if(GetCCBSFlag() == MMI_TRUE)       //拒接的时遇忙回叫的来电

       {

              SetCallState(handle, CM_DISCONNECTING_STATE, TRUE);

        MakePsEndSelectiveCall((void*)PsCBackIncomingCallRejected, handle);

                     设置gChldReqSent=CM_ENDSELECTIVE_REQ_SENT

                     发送的消息是:PRT_CALLENDSPECIFIC_EVENT

                     消息opnode是:CSMCC_REL_SPECIFIC_CALL

                     L4返回消息是:PRT_CALLENDSPECIFIC_SUCCESS

       }

       else  //IDLE状态下的一般来电

       {

              SetCallState(handle, CM_DISCONNECTING_STATE, TRUE);

        MakePsAthRequest((void*)PsCBackIncomingCallRejected);自动拒接匿名来电是直接进入这里,即直接发送ATH到L4。

                     发送的消息是:PRT_ATH_REQ

                     消息的opnode是:L4C_DISCONNECT_NONE

                     L4返回的消息是:PRT_ATH_REQ_SUCCESS

       }

       break;

 

 

CALL BACK函数:

void PsCBackIncomingCallRejected(void *info)

{

       ProcessIncomingEvents(CM_PS_INCOMING_CALL_REJECTED, info);

}

 

g_bUserReject=TRUE;

SetIncomingCallDroppedFlag(TRUE); gIncomingCallDroppedFlag=TRUE

ProcessIncomingCallRejected(info);

 

ACTION_RESULT ProcessIncomingCallRejected(void *info)    //来电时,如果网络挂断了这个来电(对方放弃),不论是什么类型的电话,只要是incoming call,就直接进入这个函数进行一些处理操作。返回的消息:

#define MMI_RELEASE_IND                mmi_cc_call_release_ind_struct

       typedef struct

       {

              LOCAL_PARA_HDR

              kal_uint8 call_id;

              kal_uint16       cause;

       } mmi_cc_call_release_ind_struct;

{

       if ((GetTotalCallCount() > 1) &&

              (GetIncomingCallHandle() != ((MMI_RELEASE_IND*) info)->call_id))

       /* use chld to reject */

        /* dropped is not MT call, use default drop call handler */

       {

              PsCBackNetworkCallDropped(info);

       }

       else if ((GetTotalCallCount() == 1 && GetCurrentState() != CM_INCOMING_STATE) ||                           (GetIncomingCallHandle() == -1))

    {

        /* use ath to reject or call already dropped when ath rsp comes */

              OutgoingProcessCMEvent(CM_PS_HANGUPSUC, (void*)&handle);

       }

 

       gAttempToReject=TRUE;

       清除CALL的CM_HANGUP_REQUESTED标志

       根据来电之前的CM状态,设置CM的之前和当前状态

 

       LogCallInfoForCallHistory(GetIncomingCallHandle());

    PurgeIncomingCallStructure();在这个函数中,有SetCallState(CM_IDLE_STATE)。如果拒接的是黑名单中的电话,那么直接ResetCallInfo(index, FALSE)清除AllCalls中的参数,然后电话总数减一;如果不是黑名单中的电话,那么将分为2中处理:missed和rejected。

                     SetCallEndedBeforeConnFlag(TRUE);   //gCallEndedBeforeConnFlag=TRUE

                     if( g_bUserReject )

                            GetEndTimeAndNotifyCallRejected();

                     else

                GetEndTimeAndNotifyCallMissed();

}

 

 

提醒:呼叫等待的【接听】。

       只存在ACTIVE CALL或者只存在HOLD CALL时,才有【接听】菜单。即:如果同时存在ACTIVEHOLD CALL,那么将不会有【接听】菜单。HiliteMenuIncomingAnswer(),响应函数:KbCBackCallIncomingAccepted

 

接听INCOMING CALL

来电的接听有2种方式:1自动接听:定时器溢出时自动调用接听函数CM_AUTOANSWER_NOTIFYDURATION_TIMER,2手动按下左软件或者[SEND]键(只有1路通话时)

void KbCBackCallIncomingAccepted(void)

{

       这几种情况下,不能接听来电:1.同时存在ACTIVE CALL,HOLD CALL,2当前存在CM_HOLD_REQUESTED,或者CM_RETRIEVE_REQUESTED,或者CM_SPLIT_REQUESTED,3.来电不是CSMCC_VOICE_CALL。

       以上几种情况直接显示错误信息,然后返回

      

       如果已经启动了自动应答(比如在自动应答之前就手动接听了),则停止自动应答定时器,设置gAutoAnswerFlag=FALSE

 

       UnSilencethePhone();

    StopIncomingCallIndication();

    ProcessIncomingEvents(CM_KB_INCOMING_CALL_ACCEPT, NULL);

}

 

void ProcessStateCheckIncomingCall(void)处理在接听之前,做一些事情

{

              gAttempToAnswer = TRUE;

 

              根据当前是否有ACTIVE CALL,发送不同的消息去接听来电。

              if (GetTotalActiveCallCount() > 0)

        {

            gAcceptIncoming = TRUE;

            SetHoldFlag();

            MakePsActiveHold((void*)PsCBackActiveCallsHeld);

        }

        else

        {

            MakePsCallAcceptIncoming((void*)PsCBackIncomingCallAccepted);

        }

}

先来看第二种情况,简单一些,直接接听(当前没有ACTIVE CALL)

void MakePsCallAcceptIncoming(void *callBack)

{

       发送到L4的消息:PRT_INCOMINGCALL_ACCEPT_EVENT

       L4返回消息:PRT_INCONINGCALL_ACCEPT_SUCCESS
}

进入回调函数:

void PsCBackIncomingCallAccepted(void *info)

{    

       gAttempToAnswer=FALSE

       ProcessIncomingEvents(CM_PS_INCOMING_CALL_CONNECTED, info);

}

第一种情况:先HOLD当前的ACTIVE CALL,然后接听来电

void MakePsActiveHold(void *callBack)

{

       发送到L4的消息结构:

       #define MMI_CC_CHLD_REQ                mmi_cc_chld_req_struct

       typedef struct

       {

              LOCAL_PARA_HDR

              kal_uint8 opcode; /* csmcc_crss_req_enum */

              kal_uint8 call_id;

       } mmi_cc_chld_req_struct;

 

       发送到L4的消息是:PRT_RETRIEVECALL_EVENT

       消息opnode:CSMCD_HOLD_ACTIVE_AND_ACCEPT

       L4返回的消息是:PRT_END_CHLD_RSP

}

进入回调函数:

void PsCBackActiveCallsHeld(void *info)

{

       ProcessIncomingEvents(CM_PS_ACTIVE_CALL_HELD, info);
}

ACTION_RESULT ProcessCallsHeld(void *info)

{

       此刻,至少有2通电话,因此,MMI与L4要进行一次电话同步

       if (GetTotalCallCount() > 0)

    {

        SyncCallList();

    }

 

    gAttempToAnswer = FALSE;

 

       switch (GetPreviousState())我认为:此时CM的prev_state只可能为CM_ACTIVE_SATAE,但是代码中为什么还列举了那么多CASE?

       {

              case CM_ACTIVE_STATE:

            if (gAcceptIncoming)

            {

                MakeHold();

                ProcessIncomingEvents(CM_PS_INCOMING_CALL_CONNECTED, info);

                gAcceptIncoming = FALSE;

            }

       }
}

 

无论是哪种方式接听来电,最后都是进入这个函数处理:

ACTION_RESULT ProcessAcceptIncomingCall(void *info)

{

       SetCallHandleForStartTimeUpdate(GetIncomingCallHandle());设置变量:                                                 gCallHandleForStartTimeUpdate,以便在Dummy1002Screen()中log call。

       switch (GetPreviousState())  //根据CM的prev_state进行不同处理

       {

              case CM_IDLE_STATE:

                     设置CM的状态:之前INCOMING,现在:ACTIVE

                     设置这个CALL的当前状态:ACTIVE。

                     EntryScr1002ActiveCall();

                     break;

              case CM_ACTIVE_CALL:

                     设置CM的状态:之前:INCOMING,当前:ACTIVE

                     设置CALL的当前状态:ACTIVE

                     进行SMS的SCREEN的一些设置操作

                     最后,直接或通过GoBackToHistory进入:EntryScr1002ActiveCall()

                     break;

              case CM_HOLD_STATE:

                     CM_INCOMING_STATE:

                     CM_OUTGOING_STATE:

                     操作大体与上面都相同,都是设置CM的状态,设置CALL的ACTIVE状态。               然后进入Entry1002ActiveCall()中。

       }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

IOT物联网小镇

赏点银子去植发

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

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

打赏作者

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

抵扣说明:

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

余额充值