1.call history的保存。在各种通话状态中的保存过程​
1.MO
(1)放弃outgoing call
ProcessPSHangupSucEvent()
LogCallInfoForCallHistory(*handle);
GetEndTimeAndNotifyCallAborted();
CMGetExactTime(GetDateTimeAndNotifyCallAbortedCBack);
memcpy(&cm_p->state_info.CallStructureForCallLog.start_time, t, sizeof(MYTIME)); 拷贝当前时间
memcpy(&cm_p->state_info.CallStructureForCallLog.end_time, t, sizeof(MYTIME));
LogCall();
LogCallWithStartTime(&cm_p->state_info.CallStructureForCallLog);
if (CM_CALL_MO == log->orgination_flag) 判断电话类型:MO, MT
{
CHISTLogDialedCall(log);
ReqWriteCallLog(call, PHB_LND);
}
else if (CM_CALL_MT == log->orgination_flag)
{
CHISTLogRecvdCall(log);
ReqWriteCallLog(call, PHB_LNR);
}
EntryScrNotifyCallAborted();

ReqWriteCallLog()这是最后写入函数
设置返回消息PRT_MMI_PHB_SET_LAST_NUMBER_RSP的CBack函数:RspWriteDialedNum,RspWriteMissedNum,RspWriteRecvdNum。
chis_p->process = CALL_LOG_PROC_WRITE;

dataPtr = (SET_LAST_NUMBER_REQ*) OslConstructDataPtr(sizeof(SET_LAST_NUMBER_REQ));
dataPtr->type = type;
dataPtr->no_data = 0;
dataPtr->index = 0xff;
memset((U8*) & dataPtr->entry.tel, 0, sizeof(CALL_LOG_NUMBER_STRUCT)); 清空号码入口
memset((U8*) & dataPtr->entry.alpha_id, 0, sizeof(CALL_LOG_NAME_STRUCT)); 清空姓名入口

//开始装载号码和姓名
如果号码第一位是+,dataPtr->entry.tel.type = 145(0x91),否则dataPtr->entry.tel.type = 129(0x81).
然后把号码转换成ASCII码,并拷贝到dataPtr->entry.tel.number中。
姓名也要转换成ASCII码,并转换成大端格式。(小端:低位放低地址,大端:低位放高地址)

ConvertMYTIME2RTC(&dataPtr->entry.time, &dailCall->start_time); 开始时间转换成RTC格式
dataPtr->entry.call_duration = 0; 时间
dataPtr->entry.count = 1; 次数

发送消息: PRT_MMI_PHB_SET_LAST_NUMBER_REQ

然后PS返回消息PRT_MMI_PHB_SET_LAST_NUMBER_RSP,进入CBACK函数:
RspWriteDialedNum()
chis_p->nDialedCalls = (U8) rsp->no_list; 当前已拨电话数目
chis_p->process = CALL_LOG_PROC_NONE;


(2)网络挂断MO call
ProcessEndCallIdAndGoBack()
LogCallInfoForCallHistory()
GetEndTimeAndLogUnconnectedMOCall()
CMGetExactTime(GetDateTimeAndLogUnconnectedMOCallCBack);
memcpy(&cm_p->state_info.CallStructureForCallLog.start_time, t, sizeof(MYTIME));
memcpy(&cm_p->state_info.CallStructureForCallLog.end_time, t, sizeof(MYTIME));
LogCall();
EntryScr1004NotifyEndCallDuration()


(3)MO call connect
OutgoingCallConnected()
DTGetRTCTime(&t); 获取当前时间
UpdateCallStartTimeAndLogCall(handle, &t);
memcpy(&cm_p->state_info.AllCalls[index].start_time, t, sizeof(MYTIME)); //拷贝当前时间
LogCallWithStartTime(&cm_p->state_info.AllCalls[index]);

MT CALL
(4)reject a MT
ProcessIncomingCallRejected
LogCallInfoForCallHistory(GetIncomingCallHandle());
PurgeIncomingCallStructure();
SetCallState( )
reject a MT call
CMGetExactTime( GetDateTimeAndNotifyCallRejectedCBack );
memcpy(&cm_p->state_info.CallStructureForCallLog.start_time,t,sizeof(MYTIME));
memcpy(&cm_p->state_info.CallStructureForCallLog.end_time,t,sizeof(MYTIME));
CHISTLogRejectedCall(&cm_p->state_info.CallStructureForCallLog);
ReqWriteCallLog( call, PHB_LNM );
EntryScr1004NotifyEndCallDuration( )

miss a MT call
memcpy(&cm_p->state_info.CallStructureForCallLog.start_time, &t, sizeof(MYTIME));
memcpy(&cm_p->state_info.CallStructureForCallLog.end_time, &t, sizeof(MYTIME));
CHISTLogMissedCall(&cm_p->state_info.CallStructureForCallLog);
设置未接电话的status icon以及一些变量
ReqWriteCallLog(call, PHB_LNM);

(5)接听MT
ProcessAcceptIncomingCall()
EntryScr1002ActiveCall()
DummyScr1002ActiveCall()
UpdateCallStartTimeAndLogCall() 与MO接通相同
memcpy(&cm_p->state_info.AllCalls[index].start_time, t, sizeof(MYTIME));
LogCallWithStartTime(&cm_p->state_info.AllCalls[index]);


(6)挂断ACTIVE、HOLD call
ProcessPSHangupSucEvent()
LogCallInfoForCallHistory()
GetEndTimeAndNotifyEndCallDuration()
memcpy(&gTimeStructForEndedCallStartTime, &(cm_p->state_info.AllCalls[GetMMIStructIndexof(handle)].start_time), sizeof(MYTIME)); //开始时间
memset(&temp, 0, sizeof(MYTIME));
if (!(memcmp(&gTimeStructForEndedCallStartTime, &temp, sizeof(MYTIME)) == 0)) //开始时间不为0,即:要更新已经写入NVRAM的call log record
{
DTGetRTCTime(&(cm_p->state_info.CallStructureForCallLog.end_time)); //获取电话结束时间
CHISTLogDialedCallDuration(&cm_p->state_info.CallStructureForCallLog); 或者
if (电话start time 与 end time不同)
{
GetTimeDifference(&call->end_time, &call->start_time, &chis_p->last_call_time); 获取时间差,即最后通话时间
IncrementTime(chis_p->total_out_time, chis_p->last_call_time, &(chis_p->total_out_time)); 已拨电话总计增加

WriteRecord(NVRAM_EF_CALL_TIME_LID, 2, (void*)&chis_p->total_out_time, sizeof(MYTIME), &error);
WriteRecord(NVRAM_EF_CALL_TIME_LID, 1, (void*)&chis_p->last_call_time, sizeof(MYTIME), &error);

mmi_chist_log_call_duration(call, PHB_LND); 更新已经写入NVRAM中的record.
首先根据类型:PHB_LND,PHB_LNR设置开始读取的record位置:
if (type == PHB_LND)
{
start_lid = 1;
}
else if (type == PHB_LNR)
{
//计算结果是5。
start_lid = 1 + ((TOT_SIZE_OF_DIALED_LIST + TOT_SIZE_OF_ONE_LN_LIST -1)/TOT_SIZE_OF_ONE_LN_LIST) +
((TOT_SIZE_OF_DIALED_LIST + TOT_SIZE_OF_ONE_LN_LIST -1)/TOT_SIZE_OF_ONE_LN_LIST);
}
注意:关于call log在NVRAM中的存储,文件ID是:NVRAM_EF_PHB_LN_ENTRY_LID。一共有6个record,每个record共924字节。
是不是record1,2存储dialed call log,3,4存储misesed call log,5,6存储received call log?
在下面的ReadRecord( )函数中,变量temp_call_log中最多只能读取10个log entry,那么另外10个call log也就是上面的record 6怎么读取的 (每种call log是20个)?

temp_call_log = OslMalloc(NVRAM_EF_PHB_LN_ENTRY_SIZE); 分配空间,准备存储读取的call log
ReadRecord(NVRAM_EF_PHB_LN_ENTRY_LID, start_lid, temp_call_log, NVRAM_EF_PHB_LN_ENTRY_SIZE, &error); 读取NVRAM
for (i=0; i< temp_call_log->no_entry; i++)
{
ConvertRTC2MYTIME(&start_time, &temp_call_log->array[i].time); 获取读取到的call log开始时间
if (CompareTime(start_time, call->start_time, NULL) == 0) 与要保存的开始时间相同
{
先把temp_call_log->array[i].addr_bcd[]中的BCD码转换成ASCII码,再转换成UCS2。
AnsiiToUnicodeString(ucs2_number, (S8*) tempNumber);
if (pfnUnicodeStrcmp((const S8*)ucs2_number, (const S8*)call->num) == 0) 与要保存的电话号码相同
{
更新temp_call_log->array[i].call_duration = call.end_time – call.start_time;
WriteRecord(NVRAM_EF_PHB_LN_ENTRY_LID, start_lid, temp_call_log, NVRAM_EF_PHB_LN_ENTRY_SIZE, &error);
break;
}
}
}
}

CHISTLogRecvdCallDuration(&cm_p->state_info.CallStructureForCallLog);
if (电话start time 与 end time不同)
{
GetTimeDifference(&call->end_time, &call->start_time, &chis_p->last_call_time); 获取时间差,即最后通话时间
IncrementTime(chis_p->total_in_time, chis_p->last_call_time, &(chis_p->total_in_time)); 已接电话总计增加

WriteRecord(NVRAM_EF_CALL_TIME_LID, 3, (void*)&chis_p->total_in_time, sizeof(MYTIME), &error);
WriteRecord(NVRAM_EF_CALL_TIME_LID, 1, (void*)&chis_p->last_call_time, sizeof(MYTIME), &error);

mmi_chist_log_call_duration(call, PHB_LNR);
}
}

CMGetExactTime(GetDateTimeAndNotifyEndCallDurationCBack);
EntryScr1004NotifyEndCallDuration();