MTK6225电话管理2

 

放弃呼出的电话,OUTGOING界面按下右软件,进入:

void DropRequest(void)

{

       gCallAbortRequested---指示是否正在处理放弃的电话

       gDropRequestFlag------指示是否是主动放弃电话的。

       以上全部设置为TRUE

 

       HangupCall(handle);

}

void HangupCall(CM_CALL_HANDLE CallHandle)

{

       OutgoingProcessCMEvent(CM_KB_HANGUPREQ, &CallHandle);

}

ACTION_RESULT ProcessKBHangupReqEvent(void *MsgStruct)

{

CASE CM_OUTGOING_CALL:

       SetCallflag(handle, CM_HANGUP_REQUESTED, TRUE);

       SetCallState(handle, CM_DISCONNECTING_STATE, TRUE);

 

       如果这个CALL已经被接通了,那么就

              MakePsEndSelectiveCall((void*)HangupReqSucess, handle);

       如果还没被接通,并且还没设置call_handle,那么就:

              gCallAbortReqSentFlag=1  //表示已经发送了放弃电话这个请求

              MakePsAthRequest((void*)PsCBackOutgoingCallEnded);

       如果还没被接通,并且已经设置了call_handle,那么就:

              MakePsEndSelectiveCall((void*)HangupReqSucess, handle);

 

提醒:当存在多通电话,没有发生呼叫等待时,【结束单线】菜单的响应函数也是ProcessKBHangupReqEvent()。

 

 

花开两朵,各表一支。

1. void MakePsAthRequest(void *callBack)放弃还没设置call_handle的CALL

{

       放弃电话的消息:

       #define MMI_ATH_REQ                    mmi_cc_ath_req_struct

       typedef struct

       {

              LOCAL_PARA_HDR

              kal_uint8       op_code; /* l4c_ath_req_enum */

       } mmi_cc_ath_req_struct;

 

       Message.oslSrcId = MOD_MMI;

    Message.oslDestId = MOD_L4C;

    Message.oslMsgId = PRT_ATH_REQ;

    Message.oslPeerBuffPtr = NULL;

    athReq = (MMI_ATH_REQ*) OslConstructDataPtr(sizeof(MMI_ATH_REQ));

    Message.oslDataPtr = (oslParaType*) athReq;

 

    if (GetCallAbortReqSentFlag())

    {

        /* set abort MO flag */

        athReq->op_code = L4C_DISCONNECT_MO;

    }

    else

    {

        athReq->op_code = L4C_DISCONNECT_NONE;

    }

 

       SetProtocolEventHandler((PsFuncPtr) callBack, PRT_ATH_REQ_SUCCESS);

 

 

    OslMsgSendExtQueue(&Message);

}

       然后L4返回消息PRT_ATH_REQ_SUCCESS,进入CBACK函数:

void PsCBackOutgoingCallEnded(void *MsgStruct)

{

       设置gCallAbortReqSentFlag=FALSE;

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

}

 

另一个挂断函数:

void MakePsEndSelectiveCall(void *callBack, CM_CALL_HANDLE handle)

{

       ClearInputEventHandler(MMI_DEVICE_ALL);

       SetChldReqSent(CM_ENDSELECTIVE_REQ_SENT);//设置gChldReqSent

       gChldReqSent可能的值为:

              typedef enum CHLD_REQ_ACTION

{

    CM_ACTION_NONE = 0,

    CM_HANGUPALL_REQ_SENT,                    挂断所有电话

    CM_HANGUPALLACTIVE_REQ_SENT,      挂断所有ACTIVE

    CM_HANGUPALLHLD_REQ_SENT,             挂断所有HOLD

    CM_ENDSELECTIVE_REQ_SENT,               挂断指定的一通电话

    CM_UDUB_REQ_SENT

} CHLD_REQ_ACTION;

 

       Message.oslSrcId = MOD_MMI;

    Message.oslDestId = MOD_L4C;

    Message.oslMsgId = PRT_CALLENDSPECIFIC_EVENT;

 

       具体的消息,主要设置:

              opcode=CSMCC_REL_SPECIFIC_CALL

              call_id=handle

      

       SetProtocolEventHandler((PsFuncPtr) callBack,                                                                                       PRT_CALLENDSPECIFIC_SUCCESS);

    SetProtocolEventHandler((PsFuncPtr) CheckFailureChld,                                                                        PRT_END_CHLD_RSP);

       注意:这里注册了2个CBACK函数,都是将要被调用的。

 

    OslMsgSendExtQueue(&Message);

}

L4返回消息PRT_CALLENDSPECIFIC_SUCCESS之后,进入:

void HangupReqSucess(void *MsgStruct)

{

       返回的消息结构:

              typedef struct

     {

            LOCAL_PARA_HDR

            kal_uint8       call_id;

            kal_uint16     cause;

     } mmi_cc_call_release_ind_struct;

 

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

}

 

可见,无论是发送什么挂断电话的消息去放弃呼出的电话,最后都是进入状态机:CM_PS_HANGUPSUC。(网络挂断1通ACTIVE或者HOLD CALL,最后也是进入这个函数处理)

ACTION_RESULT ProcessPSHangupSucEvent(void *MsgStruct)

{

       switch (GetCurrentState())

       {

       CASE CM_IDLE_STATE:

                     break;

       CASE CM_OUTGOING_STATE:当前处于OUTGOIN状态,可能存在其他的电话。在下面的处理中,要判断挂断的是什么电话(比如:挂断了正在呼出的电话;或者已经有1通HOLD CALL时,呼出另一同电话,此刻那个HOLD CALL被网络挂断了。。。)。

                     LogCallInfoForCallHistory(*handle);       //把电话信息拷贝到                                                                              cm_p->state_info.CallStructureForCallLog中

                     if (GetCallState(*handle) == CM_OUTGOING_STATE)//挂断的就是                        是呼出的电话,此时这个电话还处于OUTGOING STATE

                     {

                            flag = TRUE; //方便下面的操作

              GetEndTimeAndNotifyCallAborted();//注册函数:

                                          GetDateTimeAndNotifyCallAbortedCBack()。在这里,                                                 设置了start_time and end_time,然后LogCall( )。再然后                                     进入EntryScrNotifyCallAborted()显示“通话已放弃”                                      这个消息。

                     }

                     else //虽然此时CM处于OUTGOING状态(正在呼出电话),但是挂        断的是其他的电话(比如在make call之前已经有一通ACTIVE CALL了)

                     {

                            GetEndTimeAndNotifyEndCallDuration(*handle);//设置CALL的                                              结束时间为当前时间,并且把最后通话时间和总的                                                  通话时间写入NVRAM中,然后注册:                                                CMGetExactTime(GetDateTimeAndNotifyEndCallDurationCBack);                                            最后进入EntryScr1004NotifyEndCallDuration()。

                     }

                     SetTempUseIPNumber(FALSE);      //设置gTempUseIPNum=0

                     ResetCallflag((*handle), CM_HANGUP_REQUESTED, TRUE);

           SetCallState((*handle), CM_IDLE_STATE, TRUE);

                     根据不同的状态来设置CM状态。

                     break;

       CASE CM_INCOMING_STATE:比如在呼叫等待时,挂断一通ACTIVE                                                                              CALL,或者HOLD CALL。

                     LogCallInfoForCallHistory(*handle);//拷贝电话信息

                     /* rel active and accept waiting but waiting is released by network */

                     if (GetIncomingCallHandle() == *handle)

                     {

                              SetCurrentState(GetPreviousState());

                SetPreviousState(CM_INCOMING_STATE);

                SetCallState((*handle), CM_IDLE_STATE, TRUE);

                     }

                     else//在CM处于INCOMING状态下挂断ACTIVE或HOLD CALL。

                            //此时,不再需要设置CM的当前状态(仍然为INCOING)

                     {

                              GetEndTimeAndNotifyEndCallDuration(*handle);

                SetCallState((*handle), CM_IDLE_STATE, TRUE);

 

                              设置CM的prev_state为:ACTIVE或者HOLD。

                     }

                     break;

       CASE CM_HOLD_STATE:

       CASE CM_ACTIVE_STATE:

                       LogCallInfoForCallHistory(*handle);

            GetEndTimeAndNotifyEndCallDuration(*handle);              

            ResetCallflag((*handle), CM_HANGUP_REQUESTED, TRUE);

            SetCallState((*handle), CM_IDLE_STATE, TRUE);

                       设置CM的当前和之前状态。

       }

}

然后,L4返回消息PRT_END_CHLD_RSP,进入:CheckFailureChld()。这个函数主要就是设置gChldReqSent=CM_ACTION_NONE。

 

 

学习一下这个函数:GetEndTimeAndNotifyEndCallDuration(*handle);用来显示通话时间的提示信息

void GetEndTimeAndNotifyEndCallDuration(CM_CALL_HANDLE handle)

{

       gTimeStructForEndedCallStartTime—保存了结束的通话的开始时间

       如果开始时间不为0的话,那么就设置cm_p->state_info.CallStructureForCallLog.end_time为当前的时间,然后:

       CHISTLogDialedCallDuration(&cm_p->state_info.CallStructureForCallLog);或者       CHISTLogRecvdCallDuration(&cm_p->state_info.CallStructureForCallLog);主要就是把最后通话时间,以及总的通话时间写入到NVRAM中。

       最后注册:CMGetExactTime(GetDateTimeAndNotifyEndCallDurationCBack);这个函数主要做:

       EntryScr1004NotifyEndCallDuration();//显示信息ShowCategory63Screen()。

    memset(&cm_p->state_info.CallStructureForCallLog, 0, sizeof(CALL_INFO));

      

}

 

 

呼出的电话被网络接通(对方接听电话)

L4返回消息PRT_OUTGOINGCALL_CONNECTED,进入:

void OutgoingCallConnected(void *MsgStruct)

{

返回消息的结构:

#define MMI_CONNECT_IND                mmi_cc_call_connect_ind_struct

 

typedef struct

       {

              LOCAL_PARA_HDR

              l4c_number_struct       num;

              l4c_sub_addr_struct    sub_addr;

              kal_uint8       call_type;

              kal_uint8       call_id;

       } mmi_cc_call_connect_ind_struct;

 

       首先停止手机听筒的“嘟嘟”声

       playRequestedTone(CONNECT_TONE);

              学习一下声音的控制:

              1.声音的种类:#define ERROR_TONE  1

#define CONNECT_TONE 2

#define CAMP_ON_TONE 3

#define WARNING_TONE 4

#define INCOMING_CALL_TONE 5

#define ALARM_TONE 6

#define POWER_ON_TONE 7

#define POWER_OFF_TONE 8

#define COVER_OPEN_TONE 9

#define COVER_CLOSE_TONE 10

#define MESSAGE_TONE 11

#define KEYPAD_PLAY_TONE 12

#define SUCCESS_TONE 13

#define SAVE_TONE 14

#define EMPTY_LIST_TONE 15

#define GENERAL_TONE 16

#define SMS_IN_CALL_TONE 17

#define AUX_TONE  18

#define WARNING_TONE_IN_CALL 19

#define ERROR_TONE_IN_CALL 20

#define CONNECT_TONE_IN_CALL 21

#define SUCCESS_TONE_IN_CALL 22

/* Brian added for battery indication, 2003/11/17 */

#define BATTERY_LOW_TONE 23

#define BATTERY_WARNING_TONE 24

#define CALL_REMINDER_TONE 25

#define CCBS_TONE 26

#define CONGESTION_TONE 27

#define AUTH_FAIL_TONE 28

#define NUM_UNOBTAIN_TONE 29

#define CALL_DROP_TONE 30

 

                     2 .void playRequestedTone(ALL_TONE_ENUM playtone)// API to all                               applications to play tone.

 

       //下面是log call,注意看

       handle = GetOutgoingCallHandle();

 

    /* log MO call with original number and name */

    SetCalledNumWithTypeAux(GetMMIStructIndexof(handle), MsgStruct);这个函数把AllCalls[index]中的number拷贝到num中,然后用L4返回来的网络接通的号码msgBuf->num.number拷贝到number中,并且用返回来的msgBuf->call_type拷贝到AllCalls[index].call_trpe。 也就是说,在下面的call log中,使用L4返回来的信息。

    DTGetRTCTime(&t);  获取系统的当前时间,以便下面设置为开始时间

    UpdateCallStartTimeAndLogCall(handle, &t);设置CALL的开始时间为上面的t,然后LogCallWithStartTime(&cm_p->state_info.AllCalls[index]);

   

    /* set MO name for display in case number is changed by PS */

    SetCalledNumWithType(GetMMIStructIndexof(handle), MsgStruct);如果AllCalls[index]中的number与num不一致(说明在上面的函数中,号码被L4改变过),那么就用电话簿中的信息重新设置AllCalls[index]的pBname和name_dcs,以及number。这里有个问题:实验发现在电话簿和call log中,号码相同但是名字不相同,通过call log呼出电话,在OUTGOING 界面显示的是CALL LOG中的名字,接通之后显示的仍然是CALL LOG中的名字。这里已经设置AllCalls的名字为电话簿中的名字了啊? 难道在哪里又设置成CALL LOG中了??

解答:在函数SetCalledNumWithTypeAux()和()中,存在一个宏:

__MMI_CM_DISPLAY_CONN_NUM__。这个宏是关闭的,因此实际上上面所描述的:“先用L4返回的消息设置AllCalls,然后LOG CALL,然后再恢复电话簿里的信息到AllCalls”这个步骤并未执行。也就是说AllCalls里的信息在LOG前后没有改变过。

 

       SetTempUseIPNumber(FALSE);

       OutgoingProcessCMEvent(CM_PS_CALLCONNECTED, &handle);

}

 

ACTION_RESULT ProcessPSCallconnectedEvent(void *MsgStruct)

{

       此时,CM的当前状态只可能是OUTGOING STATE

       MakeHold( );

       SetPreviousState(GetCurrentState());

    SetCurrentState(CM_ACTIVE_STATE);

       SetCallState(gtmpOutgoingIndex, CM_ACTIVE_STATE, FALSE);

 

       if (GetTotalCallCount() > 1)       此时,不止1通电话,要显示电话列表

       {

              handle = GetIncomingCallHandle();

       if (handle != -1)    此时还存在呼叫等待的电话,要显示INCOMING界面

              {

                      SetPreviousState(CM_ACTIVE_STATE);

           SetCurrentState(CM_INCOMING_STATE);

 

                     设置gPhoneNumberStruct结构为呼叫等待的电话信息

                     GoBackToHistory(ITEMSCR_INCOMING_CALL); 回到来电的界面

              }

              else        //没有呼叫等待的电话

              {

                     if (IsScreenPresent(ITEM_SCR_USSN_MSG))

          {

                GoBackHistory();

          }

                     else

                     {                                                                                                                       GoBackToHistory(SCR_CM_ACTIVECALLSCREEN);

                     }

              }

       }

       else 只有刚刚接通的这1通电话

       {

              如果之前已经存在SCR_CM_ACTIVECALLSCREEN,就                                                 GoBackToHistory(SCR_CM_ACTIVECALLSCREEN);

              如果不存在,则:

                            EntryScr1002ActiveCall();  //displays the list of active/Held calls                                                                                     or the single active/held call

                 DeleteUptoCmScreen();

       }

}

然后进入void DummyScr1002ActiveCall(MYTIME *t)

{

       这个IF主要是在接听来电的时候被执行。在来电时,变量gCallHandleForStartTimeUpdate被设置成来电的call_handle,接通之后呢,进入这个函数,显示电话列表,于是就被调用,设置开始时间,并且LOG CALL。

对于OUTGOING CALL,在电话被网络接通的时候,进入回调函数OutgoingCallConnected()时,就已经LOG CALL了。

       if (GetCallHandleForStartTimeUpdate())

    {

        UpdateCallStartTimeAndLogCall(GetCallHandleForStartTimeUpdate(), t);

        SetCallHandleForStartTimeUpdate(0);

    }

       nActiveCall = GetTotalActiveCallCount();

    nHoldCall = GetTotalHoldCallCount();

 

    if (nActiveCall + nHoldCall == 0)

    {

        GetOutOfCMApplication();

        return;

    }

 

设置几个全局变量:

gcallListlen----电话列表的长度

gcallList--------电话列表显示的名字

另外:

gHiliteCall------当前高亮的电话索引

       gcallListlen =

                     GetAllDispNameorNum(gcallList, gcallListImage, nIconIds, &dummy);

 

       nAllcall =             GetAllDispNameorNum(strDispnames,nImgIds,nIconIds,&firstActiveCallIndex);和上面的函数一样的,只不过设置的变量不同。这里主要是用在显示列表中。firstActiveCallIndex保存的最后的那通电话的索引,用来设置高亮菜单。在排列所有的通话时,通话最早的排在最上面,最后开始通话的排在最下面。高亮的是最下面的也就是最后通话的。

 

在显示通话列表状态时,右软件有关扩音器的操作变量是:

gLoudSpeaker=1,表示扩音器已经激活,此时,设置alert_info.IsHFree=1,右软件将                        要显示“正常”(HHeld)。

gLoudSpeaker=0,表示扩音器已经关闭,此时,设置alert_info.IsHFree=0,右软件将                        要显示“免提”(HFree)。

 

 

       InitializeTimeStructure(&timeStruct, t);//t是作为参数传过来的当前时间,这个函数是获取电话列表中,最早的那个电话时间设置到timeStruct中。并且启动了通话时间的提醒。定时器是CM_CTR_TIMER,响应函数是CheckCtrExpiry().

 

       if ((nActiveCall + nHoldCall) > 1)     //大于1通电话

       {

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

                     ShowCategory19Screen( );       //左、右软件都为0

              else

                     ShowCategory19Screen( );       //左、右软件有选项

       }

       else        //只有这1通电话

       {

              设置显示的图片。3中可能:

(1)    使用默认的图片         nImgIds[0]=IMG_CM_STATE_SINGLE_ACTIVE;

(2)    使用系统的4幅图片

(3)    使用文件里的图片

              (2)(3)通过调用

              GetSingleActiveCallInfo(&tmp, &picid, &pic_storeindex)来判断。

              其中如果是2:nImgIds[0] = picid;
                     如果是3:imgPath=GetActiveCallImgPath(tmp, pic_storeindex);

 

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

       ShowCategory20Screen( );       //左、右软件都为0

}

else

{

       ShowCategory20Screen( );       //左、右软件都有选项

}

 

下面开始设置一些KeyHandler

EntryScr1003CMActiveCallOptions()设置的左软件的选项入口

       }

}

  • 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、付费专栏及课程。

余额充值