结束所有的HOLD CALLs,存在2种情况:
1.没有发生呼叫等待时,1通ACTIVE CALL + N通HOLD CALLs,【结束所有暂停】菜单
2.有呼叫等待时:
       (1)1通HOLD CALL,【结束】菜单
       (2)1通ACTIVE CALL + 1通HOLD CALL,【暂停结束】菜单
       (3)1通ACTIVE CALL + N通HOLD CALL,【结束所有暂停】菜单
       (4)1通HOLD CALL + N通ACTIVE CALL,【暂停结束】菜单
void HangupallHeld(void)
{
    OutgoingProcessCMEvent(CM_KB_HANGUPALLHLDREQ, (void*)NULL);
}
ACTION_RESULT ProcessKBHangupallHldReqEvent(void *MsgStruct)
{
       SetAllHldHangupFlag();         对当前所有状态为HOLD的CALL,设置其标志                                                             status_flag=CM_HANGUP_REQUESTED
    if (GetCurrentState() != CM_INCOMING_STATE)
    {
        SetAllHeldCallState(CM_DISCONNECTING_STATE);
    }
    MakePsSendRelHeld((void*)HangupallHldReqSucess);
    return CM_CALL_SUCCESS;
}
 
总结:在(1)结束单线;(2)结束所有ACTIVE CALL;(3)结束所有HOLD CALL这3种情况时,在发送挂断消息到L4之前,都有这样一个现象:判断当前的CM状态,如果当前CM不处于INCOMING STATE(没有来电),就设置即将被挂断的电话的当前状态为:CM_DISCONNECTING_STATE。如果CM处于INCOMING STATE,就不设置。WHY??
我的理解:如果在有来电时,设置被挂断电话的当前状态为DISCONNECTING STATE,可能是担心恰巧在这个时候,那个来电的状态发生了转变,也被设置成了DISCONNECTING状态,所以就不设置了。
 
void MakePsSendRelHeld(void *callBack)
{
       ClearInputEventHandler(MMI_DEVICE_ALL);
 
       SetChldReqSent(CM_UDUB_REQ_SENT);         设置gChldReqSent
 
       发送到L4的消息是:PRT_UDUB_REQ
       消息的opnode:CSMCC_REL_HELD
                            提醒:这里发送的消息与拒接一个呼叫等待的电话所发                                                 送的消息PRT_UDUB_REQ   (CSMCC_REL_HELD_OR_UDUB)相同,但是                        opnode不同。
       SetProtocolEventHandler((PsFuncPtr) callBack, PRT_UDUB_RES_SUCCESS);
    SetProtocolEventHandler((PsFuncPtr) CheckFailureChld, PRT_END_CHLD_RSP);
                     这里也注册了2个CBACK函数。
}
 
void HangupallHldReqSucess(void *MsgStruct)
{
    gMyhandle = DeriveCallHandle(MsgStruct);
    OutgoingProcessCMEvent(CM_PS_HANGUPALLHLDSUC, (void*)&gMyhandle);
}
 
ACTION_RESULT ProcessPSHangupallHldSucEvent(void *MsgStruct)
{
       LogCallInfoForCallHistory(*handle);
    GetEndTimeAndNotifyEndCallDuration(*handle);
 
    SetCallState((*handle), CM_IDLE_STATE, TRUE);
 
       if (GetTotalHoldCallCount() > 0)
    {
        return CM_CALL_SUCCESS;
    }
 
       根据当前的电话,设置CM的状态    
}
 
总结:与结束所有的电话,所有的ACTIVE CALL一样,结束所有的HOLD CALLs时,注册的CBACK函数仅仅处理第一通HOLD CALL的挂断过程,其他HOLD CALL都是由网络挂断的。
当所有的ACTIVE CALL都被挂断之后,L4要返回消息:PRT_END_CHLD_RSP,进入:
void CheckFailureChld(void *info)
{
       if (CheckChldRequestSuccess(info, &result))             成功
       {
              SetProtocolEventHandler(PsCBackNetworkCallDropped,                                                                                              PRT_NWRK_CALL_RELEASE);
        SetChldReqSent(CM_ACTION_NONE);      设置gChldReqSent
        return;
       }
       else
       {
              SetChldReqSent(CM_ACTION_NONE);
        SetProtocolEventHandler(PsCBackNetworkCallDropped,                                                                                              PRT_NWRK_CALL_RELEASE);
        ShowCallManagementErrorMessage(result);
       }
}
 
对于挂断电话的总结:
1.      挂断电话包括:挂断一通电话;挂断所有电话;挂断所有ACTIVE电话;挂断所有HOLD电话。
2.      在发送挂断电话的消息之前,都要设置变量: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;
3.在发送消息之前,注册CBACK函数的时候,除了一般的回调处理函数外,都要设置L4返回消息:PRT_END_CHLD_RSP的回调函数。也就是说:L4在处理完挂断电话之后,除了返回正常的成功挂断消息之外,还返回消息:PRT_END_CHLD_RSP。
4.在3中对消息PRT_END_CHLD_RSP注册的CBACK函数时,挂断一通电话+挂断所有电话+挂断所有HOLD电话,这3中情况设置的都是:CheckFailureChld();
       对挂断所有的ACTIVE电话设置的CBACK是:CBackHangupAllActive()。
       这2个回调函数,主要工作就是设置变量:gChldReqSent。
 
对L4返回的消息PRT_END_CHLD_RSP的总结:
1.在有ACTIVE CALL的情况下,接听呼叫等待的电话
       MakePsActiveHold()发送
       PRT_RETRIEVECALL_EVENT(CSMCC_HOLD_ACTIVE_AND_ACCEPT)
       回调函数:PsCBackActiveCallsHeld()
2.暂停ACTIVE CALL 
       MakePsActiveHold()发送
       PRT_RETRIEVECALL_EVENT(CSMCC_HOLD_ACTIVE_AND_ACCEPT)
       回调函数:HoldReqSucess()
3.恢复HOLD CALL
       MakePsActiveHold()发送:
       PRT_RETRIEVECALL_EVENT(CSMCC_HOLD_ACTIVE_AND_ACCEPT)
       回调函数:RetrieveReqSucess()
4.切换电话
       MakePsSwapCallRequest()发送
       PRT_SWAPCALL_EVENT (CSMCC_SWAP_CALL)
      回调函数:SwapReqSucess()
5.会议
       MakePsConfCallRequest()发送:
       PRT_CONFCALL_EVENT (CSMCC_ADD_HELD_CALL)
       回调函数:ConfReqSucess()
6.分机
       MakePsSplitRequest()发送:
       PRT_SPLITCALL_EVENT(CSMCC_HOLD_ACTIVE_EXCEPT_SPECIFIC_CALL)
       回调函数:SplitReqSucess()
 
电话会议:只要同时存在ACTIVE CALL和HOLD CALL,不论是否发生呼叫等待,左软件选项中就有【会议】这个菜单。
void ConferenceCall(void)
{
       判断是否符合电话会议:必须同时存在ACTIVE和HOLD CALL;HOLD CALL的数目必须小于5;ACTIVE CALL的数目必须小于5。
    if (  (GetTotalActiveCallCount() < MAX_HOLD) &&
        (GetTotalHoldCallCount() < MAX_HOLD) &&
              ((GetTotalActiveCallCount() > 0 && GetTotalHoldCallCount() > 0)))
    {
        OutgoingProcessCMEvent(CM_KB_CONFREQ, (void*)NULL);
    }
    else
    {
        ShowCallManagementErrorMessage(NO_ACTIVE_CALL);
    }
}
 
ACTION_RESULT ProcessKBConfReqEvent(void *MsgStruct)
{
       与【暂停】,【恢复】,【切换】一样,必须保证当前所有的CALL都没有CM_SWAP/CONF/ECT_REQUESTED这3个标志
 
       flag = GetAllCallFlags();
    if (((flag & CM_SWAP_REQUESTED) != 0) || 
           ((flag & CM_CONF_REQUESTED) != 0) ||
           ((flag & CM_ECT_REQUESTED) != 0))
    {
        return CM_CALL_FAILURE;
    }
 
       switch (GetCurrentState())    当前只可能为:INCOMING或者ACTIVE
       {
              SetConfFlag();              设置当前所有的ACTIVE和HOLD CALL的                                                                           status_flag=CM_CONF_REQUESTED
        MakePsConfCallRequest();
       }
}
 
void MakePsConfCallRequest(void)
{
    ClearInputEventHandler(MMI_DEVICE_ALL);
 
    发送到L4的消息是:PRT_CONFCALL_EVENT;
       消息的opcode = CSMCC_ADD_HELD_CALL;
    SetProtocolEventHandler(ConfReqSucess, PRT_END_CHLD_RSP);
    OslMsgSendExtQueue(&Message);
    return;
}
 
void ConfReqSucess(void *MsgStruct)
{
       OutgoingProcessCMEvent(CM_PS_CONFSUC, (void*)MsgStruct);
}
 
ACTION_RESULT ProcessPSConfSucEvent(void *MsgStruct)
{
       MakeConf();         对当前所有status_flag=CM_CONF_REQUESTED的电话,清除                                      status_flag标志,并且如果curr_state=CM_HOLD_STATE,就设置为                                CM_ACTIVE_STATE。
       EntryScr1008NotifyConfSucess();              提示信息
}OVER!!!!
MTK6225电话管理1--6是自己结合606项目的学习笔记,如有错误,请不吝赐教!谢谢