VIA Selle SMS 系列之—接收篇

最近一段时间都在整VIA的SMS相关需求,有Page
Message,Duplic Message,Message Service等,积累了一些经验与大家分享,是基于Selle1.0的版本。
(由于与SMS关于代码分布在PS,VAL,UI三层,并且每层都有复杂的处理过程,这里只以某些功能的实现为主线串一下相关过程,不太可能覆盖的很全面,有兴趣的同行们可以补充:)
一,短信的接收过程
短信由基站发送到手机,首先应该是协议层接收到,然后会通知VAL层,再然后到ASL层,最后到APP,UI层。
具体点:
1.协议层会发送给VAL层消息,通知有SMS到来:
The messages received from PSW have
following kinds:
VAL_SMS_DELIVER_IND_PARMS_MSG: //短信的头,包含地址,设置等信息
VAL_SMS_DELIVER_IND_DATA_MSG: 
//短信的内容,如果是空短信,内容为空,不会处理此消息
VAL_SMS_ERROR_MSG:
VAL_SMS_BCAST_IND_PARMS_MSG:
VAL_SMS_BCAST_IND_DATA_MSG:
VAL_SMS_BCAST_ERROR_MSG:
VAL_SMS_CAUSE_CODE_STATUS_MSG
这里以普通短信类型为例,Task会找到对应此消息的处理函数为:
message hangler for messages from PSW
task
bool ValProcessSmsMsg( uint32
MsgId,void* MsgBuf,uint32 MsgLen )
{
         ……
    case VAL_SMS_DELIVER_IND_DATA_MSG:
      ValSmsTstSendSpy( MsgBuf, MsgLen
);
      ValSmsProcessDeliverDataMsg( MsgBuf, MsgLen );
      break;
}
在函数ValSmsProcessDeliverDataMsg(
MsgBuf, MsgLen )中对收到的短信进行复杂的处理,看相应的代码应该可以明白,这里只说几处关键的地方:
int8 ValSmsProcessDeliverDataMsg(
void* MsgBuf, uint16 MsgLen )
{
ValSmsIncomingMsgT SmsIncomingMsg;
 /* initialize */
 RcvMsgP =
(ValSmsUserDataMsgT*)MsgBuf;
 /* fill-in the buffer with the
message received */
    datalen =
RcvMsgP->NumFields;
    for (i = 0; i < datalen;
i++)
    {
     
TxtMessage.UserData[NumUserDataRcv].Data[i] = RcvMsgP->Char[i];
    }
 /* send the message to UI */
 if (
TxtMessage.TeleSrvId==VAL_SMS_TS_ID_CATPT)  
 {
           /* For UTK
message */
 }
 else
 {
        if
(TxtMessage.TeleSrvId==VAL_SMS_TS_ID_VOICE_MAIL)/*VMN, just save into the
previous position */
    {
             /*For Voice Mail*/
     }
         else if
         {
           /* check if is
immediate message */
         }
         else
         {
               /*
other teleservice than VMN */
            if(ValSmsJudgeDupMsg(&TxtMessage,&recid,&ValSmsDupPolicy))//判断SMS重复的条件,可以是内容,地址或是MsgID
            {
             
SmsIncomingMsg.
isDuplicateSms =
TRUE;//此字段是后来加上的,可以把自己添加一些特殊信息,传送到UI
              //result =
ValSmsWriteTxtMessage( &TxtMessage, &recid );
              result =
ValSmsUpdateTxtMessage( &TxtMessage, recid );
             
//SendMsgWriteAck(VAL_SMS_SUCCESS, RcvMsgP->SeqNum);
   //return 0;        
            }       
            else
            {
             
SmsIncomingMsg.isDuplicateSms = FALSE;//zjj add 20091022
              if(!bStoreInUIM)
              {
                result =
((*CheckSaveOneMessageFunc)(&TxtMessage, &recid));            
              }
              else
              {
                result =
ValSmsWriteTxtMessage( &TxtMessage, &recid );
              }            
            }
                  if(result !=
VAL_SMS_SUCCESS)
                  {
              SendMsgWriteAck(result,
RcvMsgP->SeqNum);
             
SendMsgWriteErr(device,result);
              return -2;           
                  }
            TxtMessage.SmsMsgRecId =
recid;
            SmsIncomingMsg.recid =
recid;
         }
      }
   ProcessEvt(VAL_SMS_EVENT_INCOMING_MESSAGE,
TxtMessage.TeleSrvId, (void *)&SmsIncomingMsg);
   }
ProcessEvt会调用注册消息VAL_SMS_EVENT_INCOMING_MESSAGE对应的asl层的回调函数:
注册的地方在:
/*!
\brief initialize SMS Data: register
callback function, register teleservice id
bool AslSmsInitialize (void)
{
 gSmsRegisterId = ValSmsRegister(SMSMessageListener);
}
2.接到收此消息后,轮到ASL层的处理;
/*
 SMSMessageListener: to process event
from VAL
*/
static void SMSMessageListener( RegIdT RegId, ValSmsEventIdT
Event, void *MsgP)
{
    ……
 switch (Event)
 {
 case VAL_SMS_EVENT_INCOMING_MESSAGE:
    SmsListenerIncomingMessage(MsgP);
    break;
 case
VAL_SMS_EVENT_SEND_STATUS_MESSAGE:
    SmsListenerSendStatus(MsgP);
    break;
       ……
 }
}
static void SmsListenerIncomingMessage(void *MsgP)
{
 UiGetMailServer()->PostMail(APPMSG_SMS_MESSAGE_LISTEN_INCOMING,
WIN_HANDLE_NULL, (uint32)MsgP, sizeof(ValSmsIncomingMsgT), BY_ADDRESS);
}
void AslSmsListenerIncomingMessage(void *MsgP)
{
     ……
 ValSmsIncomingMsgT *SmsIncomingMsgP =
(ValSmsIncomingMsgT*)MsgP;//这样就收到了在VAL层自己添加的信息
 VsmsRecordId =
SmsIncomingMsgP->recid;
 bool duplicateSms=SmsIncomingMsgP->isDuplicateSms;
    ……
     
UiGetMailServer()->PostMail(APPMSG_SMS_MESSAGE_INCOMING, WIN_HANDLE_NULL,
(uint32)VsmsRecordId, (uint32)
duplicateSms, BY_VALUE); //这里原来第二个参数为空,但也可以添加想传到UI层的自定义数据。
}
以上为SMS在ASL层的流程,从代码可知其意,过渡到App,UI之上。
3.ASL层发送消息,映射函数到APP层接着处理:
ON_MSG_VOID_WORDLONG(APPMSG_SMS_MESSAGE_INCOMING,SmsAppC::OnMessageIncoming)//这里要注意的是,由于自己添加了一个参数,所以映身类型从ON_MSG_VOID_WORD改为了ON_MSG_VOID_WORDLONG即传递了两个参数。
void SmsAppC::OnMessageIncoming(uint32
Param,uint32 ParamB)
{
 mControllerP->HandleMessageIncoming(Param,ParamB);
}
下面这个函数,负责处理SMS在UI上的显示,如是直显短信就直接显示内容,是普通短信则打开提示窗口,是重复短信则跳出来我加上去的窗口
void
SmsControllerC::HandleMessageIncoming(uint32 Param,uint32 ParamB)
{
 ……
 if(ParamB) //if ParamB is True ,it is
duplicate Sms
   {
      SmsViewMsgManagerC
*ViewMsgManagerP = ((SmsModelC*)mModelP)->GetViewMsgManager();
      UIASSERT(
!IsNull(ViewMsgManagerP) );
     
ViewMsgManagerP->SetViewMsg(NewMsg);
//这里把Controller层的新短信数据,传到UI层可以读取并显示
     
if(!IsTrue(GetView()->IsDialogOpened(APPSMS_DIALOGID_DISPLAY_DUPLICATE_MSG))
)
      {
        
GetView()->OpenDialog(APPSMS_DIALOGID_DISPLAY_DUPLICATE_MSG);
//打开自定义的重复窗口
      }
      else
      {
        
GetView()->UpdateView(APPSMS_DIALOGID_DISPLAY_DUPLICATE_MSG);
      }
      //update menu info
     
GetView()->UpdateSmsListInfoOnMsgModify();
      //start alert
     
GetView()->StartAlert();
     
GetView()->UpdateAlert();
      return;
   }
 ……
}
4.总结:
以上实现了在VAL判断是否是重复短信,把结果放在一参数中,传到UI,跟据此参数来显示不同内容的大致方法,即短信接收的大致流程。
本来想写成一篇,看来这篇简介己经够长了,所以拆分成了一个个之一了
🙂
下次介绍Page Message的实现,亦即短信发送的大致过程。

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.