如何拦截短消息
来源:互联网 发布:政务大数据基因系统 编辑:程序博客网 时间:2024/06/11 03:12
1.1 拦截短信SOP(09B之前的版本)
API原型
void mmi_frm_sms_reg_msg_check(
PsExtPeerIntFuncPtr action,
PsFuncPtrFuncPtr callback);
功能描述
通过使用该函数,可以对收到的新短信(通过action Function)作检查, 如果符合条件(返回值为TRUE), 则会(通过callback Function)把该短信相关信息传给对应的Application。该Application可以决定这个SMS是否还会被SMS Application处理到(比如把该SMS放在SMS Application的Inbox, 并显示给用户)。我们在这里称这种行为为“短信拦截”。
对于同一个SMS, 只能被其中一个注册的Application所拦截;当同时存在多个注册的Application时,则需要分优先级;高优先级的Application拦截到该SMS时(即其action Function的返回值为TRUE时), 低优先级的Application就没有机会可以拦截。
目前采用比较简单的方式,优先级是根据注册的前后顺序, 注册越靠前,优先级越高;目前在SMS Application内部,已经存在了2个拦截。
函数参数
action
检查函数;检查新来的SMS是否符合某种条件,当返回值为TRUE时,则会调用callback Function.
callback
回调函数; 当action的返回值为TRUE时,会执行callback function; callback Function的返回值可以决定该SMS是不是还会被SMS Application处理到(比如把该SMS放在SMS Application的Inbox, 并显示给用户)。当返回值为TRUE时,则允许SMS Application处理该SMS, 为FALSE,则不会由SMS Application处理。需要注意的是,在我们平台,SMS是由L4作保存的,如果不希望拦截的SMS不被SMS Application处理,则需要删除该SMS, 否则在下次开机,该SMS还会出现在SMS Inbox。
类型描述
PsExtPeerIntFuncPtr
typedef U8 (*PsExtPeerIntFuncPtr)(
void *data,
int withobject,
void *content);
data
该SMS的Information,需要做强制转换mmi_frm_sms_deliver_msg_struct;
withobject
是否有EMS Object, 即是否是EMS,而不是一般的Text SMS; TRUE表示有,FALSE为没有
content
该SMS的内容,内容的编码方式是由data中的dcs决定的; 如果dcs是GSM 7Bit编码,则content的编码格式为ASCII,如果是UCS2, 则content的编码格为Unicode。
PsFuncPtrFuncPtr
typedef U8 (*PsExtPeerIntFuncPtr)(
void *data,
int withobject,
void *content);
data
该SMS的Information,需要做强制转换mmi_frm_sms_deliver_msg_struct;
Withobject
是否有EMS Object, 即是否是EMS,而不是一般的Text SMS; TRUE表示有,FALSE为没有
content
该SMS的内容,内容的编码方式是由data中的dcs决定的; 如果dcs是GSM 7Bit编码,则content的编码格式为ASCII,如果是UCS2, 则content的编码格为Unicode。
mmi_frm_sms_deliver_msg_struct
typedef struct
{
U8 fo;
U8 scts[7];
l4c_number_struct sca_number;
l4c_number_struct addr_number;
U8 pid;
U8 dcs;
U8 ori_dcs;
U16 index; /* for awaited message, this is the start index */
U16 dest_port;
U16 src_port;
U8 mti;
U8 display_type;
#ifdef __MMI_MESSAGES_COPY__
U8 storageType;
#endif
U32 concat_info;
U16 no_msg_data;
U8 msg_data[1]; /* for awaited message, this is the first segment data */
} mmi_frm_sms_deliver_msg_struct;
fo
SMS TPDU的First Otect,用于判断短信的类型,是否有UDH等(具体可以参见sepc23.040的9.2.2.1)
scts
短信中心时间戳, 短信中心收到该SMS的时间,我们在Inbox里可以看到的时间;在开UM的情况下,对于Outbox,Unsent或Draft,为发送或保存的时间。在这个Case,是收到的SMS的时间。(具体可以参见spec23.040的9.2.3.11)
sca_number
短信中心号码
addr_number
接收者号码(DA)或发送者号码(OA); 在这个Case,是发送者的号码
pid
Protocol Identifier,如为0x00则是SMS Application, 0x32则是Email。(具体可以参见spec23.040的9.2.3.9)
dcs
Content部分编码格式,具体值请参考smsal_dcs_enum
ori_dcs
在TPDU中的TP-DCS字段值
index
L4 index, 在这个Case,为第一个Segment的L4 Index.
dest_port
目的端口,如果该SMS为端口短信,则不为零
src_port
源端口,如果该SMS为端口短信,则不为零
mti
message type identifier, 表示该SMS的类型(参考spec23.040的9.2.3.1)
display_type
显示类型,具体值请参考smsal_display_type_enum
storageType
存储类型,具体值请参考smsal_storage_enum
concat_info
长短信(Concatenated SMS)的Information, 包括这个SMS多少个Segment,这个Segment的第几个等。
2个低字节为Reference number;
最高字节为该SMS Segment是第几个Segment;
第三字节为该SMS的总Segment数。
no_msg_data
SMS content部分的字节数
msg_data[1]
新来的SMS的Content都会缓存在一个Buffer里, msg_data的是第一个Segment的Content缓存Buffer的Index。
l4c_number_struct
typedef struct
{
kal_uint8 type;
kal_uint8 length;
kal_uint8 number[MAX_CC_ADDR_LEN];
} l4c_number_struct;
type
号码的类型,如0x81表示国内号码,0x91表示国际号码,(通常用“+”表示)。
length
号码长度,number部分的长度
number
号码, 号码只有我们在MMI常见的号码的数字部分,
Sample Code
注册拦截函数
为了保证拦截的Application优先级,需要统一在如下位置作注册,在文件
…\mcu\plutommi\mmi\messages\messagesscr\smspshandler.c中
void mmi_msg_set_protocol_event_handler(void)
{
……
//Add your register function
mmi_frm_sms_reg_msg_check(
sample_check_new_sms,
sample_capture_new_sms);
}
检查函数 action
U8 sample_check_new_sms(void *data, int withobject, void *content)
{
mmi_frm_sms_deliver_msg_struct *msg =
(mmi_frm_sms_deliver_msg_struct*)data;
//If it is an EMS
if (withobject)
{
return FALSE;
}
else
{
if (/* Add your check code */)
{
return TRUE;
}
else
{
return FALSE;
}
}
}
回调函数callback
static MMI_BOOL sample_is_deleting_sms;
pBOOL sample_capture_new_sms(void *data, S8 *content)
{
mmi_frm_sms_deliver_msg_struct *inMsg =
(mmi_frm_sms_deliver_msg_struct*) data;
/* Add your handle code */
/* If doesn't allow the user to see this sms in the SMS Inbox, delete it */
/* If the arrival of new sms is very frequent, the deleting request is also very frequent; But he SMS
Framework can't handle too much request in short time,so we need to stored the sms index when deleting a
sms, and delete the next one after the deleting is finished. */
if (sample_is_deleting_sms == MMI_TRUE)
{
//Stored the new sms L4 index when it is deleting a sms
if (sample_add_sms_index(inMsg->index) == MMI_FALSE)
{
/* If add SMS index failed, increase the value
of the MACRO SAMPLE_MAX_STORED_INDEX_NUM */
MMI_ASSERT(0);
}
}
else
{
//If the sms is ready
if (mmi_frm_sms_get_sms_list_size(MMI_FRM_SMS_NOBOX) !=
MMI_FRM_SMS_INVALID_INDEX)
{
sample_delete_capture_sms_req(inMsg->index);
}
else //If the sms is not ready
{
if (sample_add_sms_index(inMsg->index) == MMI_FALSE)
{
/* If add SMS index failed, increase the value
of the MACRO SAMPLE_MAX_STORED_INDEX_NUM */
MMI_ASSERT(0);
}
//register the event which the SMS is ready
mmi_frm_sms_reg_interrupt_check(
MOD_MMI,
PRT_MSG_ID_MMI_SMS_READY_IND,
sample_handle_sms_ready);
}
}
/ * If don’t want the SMS application to handle this SMS, return FALSE, else return TRUE. In this
sample code, don’t want the SMS showed in the Inbox, so return FALSE */
return FALSE;
}
NOTE:
如果不希望该SMS出现在Inbox, 被User看到,则应该删除它,否则在下次开机时 ,它还会出现在Inbox.
如果在短时间内收到大量的SMS,则出现在短时间内会做多次删除的操作,但是由于SMS Framework的Action Queue Size为15,即最多只能支持15个删除的Request;当删除的操作被其它的操作Suspend时,就会出现有被拦截的SMS不会被删除的情况。
因此对于可能出现的这种情况,处理的策略是:当在拦截到新来SMS时,如果有正在删除的SMS,则把该新来的SMS的L4 Index保存,等待正在删除的动作完成后,则删除其它保存了L4 Index的SMS.
如果SMS Not Ready,则不能作删除的动作,所以需要把新来的SMS的L4 Index保存;此时注册SMS Ready的Interrupt, 在SMS Ready时再作删除的动作。
保存SMS L4 Index
#define SAMPLE_MAX_STORED_INDEX_NUM 100
typedef struct
{
U16 index[SAMPLE_MAX_STORED_INDEX_NUM];
U16 header;
U16 tailer;
U16 total_num;
}sample_stored_new_sms_index_struct;
sample_stored_new_sms_index_struct *sample_stored_index;
//Add new sms l4 index in the buffer
static MMI_BOOL sample_add_sms_index(U16 index)
{
if (sample_stored_index == NULL)
{
sample_stored_index = OslMalloc(sizeof
(sample_stored_new_sms_index_struct));
sample_stored_index->header = 0;
sample_stored_index->tailer = 0;
sample_stored_index->total_num = 0;
}
if (sample_stored_index->total_num == SAMPLE_MAX_STORED_INDEX_NUM)
{
return MMI_FALSE;
}
sample_stored_index->index[sample_stored_index->tailer] = index;
sample_stored_index->tailer++;
sample_stored_index->total_num++;
if (sample_stored_index->tailer == SAMPLE_MAX_STORED_INDEX_NUM)
{
sample_stored_index->tailer = 0;
}
return MMI_TRUE;
}
static U16 sample_get_next_sms_index(void)
{
U16 index = MMI_FRM_SMS_INVALID_INDEX;
if (sample_stored_index != NULL)
{
if (sample_stored_index->total_num == 0)
{
OslMfree(sample_stored_index);
sample_stored_index = NULL;
}
else
{
index = sample_stored_index->index
[sample_stored_index->header];
sample_stored_index->header++;
sample_stored_index->total_num--;
if (sample_stored_index->header ==
SAMPLE_MAX_STORED_INDEX_NUM)
{
sample_stored_index->header = 0;
}
}
}
return index;
}
SMS Ready后的处理
如果需要获取SMS Ready事件,需要使用下面的API注册该事件的回调函数
void mmi_frm_sms_reg_interrupt_check(
module_type mod,
U16 msgid,
PsFuncPtrU16 callback);
static void sample_handle_sms_ready(
void *dummy,
module_type mod,
U16 result)
{
U16 index = sample_get_next_sms_index();
if (index != MMI_FRM_SMS_INVALID_INDEX)
{
sample_delete_capture_sms_req(index);
}
}
删除SMS
void sample_delete_capture_sms_req(U16 index)
{
//Set the flag when delete
sample_is_deleting_sms = MMI_TRUE;
/* the typde of the capture SMS is MMI_FRM_SMS_APP_AWAITS */
mmi_frm_sms_delete_sms(
sample_delete_capture_sms_rsp,
MOD_MMI,
MMI_FRM_SMS_APP_AWAITS,
index);
}
void sample_delete_capture_sms_rsp(
void *dummy,
module_type mod,
U16 result)
{
U16 index;
if (result == MMI_FRM_SMS_OK)
{
//Delete Success
//Add Handle Code
}
else
{
//Delete Failed
//Add handle Code
}
//Get next new SMS which stored
index = sample_get_next_sms_index();
//Delete next new SMS which stored
if (index != MMI_FRM_SMS_INVALID_INDEX)
{
sample_delete_capture_sms_req(index);
}
else
{
sample_is_deleting_sms = MMI_FALSE;
}
}
1.2 拦截短信SOP(09B)
09B 中将sms部分分为了UI和service两个部分,在09B之前的处理是在SMSAL层存储短信,然后传给MMI,再由MMI来处理。但是在09B中拦截短信在service部分拦截就OK。09B sms的架构图如下:
从上图中可以看到service部分中包含了Reciever,这部分就是用来处理接收短信的所有的流程的。
当收到一条短信后会首先进入函数srv_sms_new_sms_ind,最后会进入函数srv_sms_handle_new_msg进行处理,在该函数中会针对不同类型的sms进行处理,保存sms也是在这个函数里处理的。所以拦截短信只要在这个函数里进行拦截就OK了。
srv_sms_handle_new_msg会调用smslib_decode_pdu和smslib_get_msg_content 解析msg,解析完成后信息存储在app_lib_data中,然后使用需要的条件来判断拦截短信就OK了。
结构体介绍如下:(可以使用这些值设定条件做判断)
smslib_general_struct *app_lib_data
typedef struct
{
smslib_sim_status_enum status;
l4_addr_bcd_struct sca;
smslib_tpdu_decode_struct tpdu;
kal_uint8 pdu_len; /* length of PDU */
kal_uint8 tpdu_len; /* length of TPDU */
l4c_number_struct forMMI_SCAAddr;
l4c_number_struct forMMI_TPAddr;
kal_uint16 forMMI_UserData_length; /*unit: octet*/
kal_uint8 forMMI_UserData[170];
} smslib_general_struct;
typedef struct
{
union
{
smslib_deliver_peer_struct deliver_tpdu;
smslib_submit_peer_struct submit_tpdu;
smslib_status_report_peer_struct report_tpdu;
} data;
smslib_mti_enum mti;
//
kal_uint8 fo; /* first octet */
kal_uint8 offset; /* offset to message content */
/* init address of User Data Header */
kal_uint8 msg_len;/* length of user data */
/* User Data Header + User Data */
kal_uint8 udhl; /* for calculating offset to unpack */
/* udhl + udh */
smslib_concat_struct concat_info;
/* for decoding DCS */
smslib_msg_class_enum msg_class;
smslib_alphabet_enum alphabet_type;
kal_uint8 is_compress;
smslib_msg_waiting_struct msg_wait;
/* User Data Header */
smslib_port_struct port;
} smslib_tpdu_decode_struct;
typedef struct
{
kal_uint8 reply_flag; /* whether reply is sought*/
kal_uint8 udh_p; /* indicates presence of
user data header*/
kal_uint8 status_rep_flag; /* whether status reports
are sought*/
kal_uint8 fill_bits; /* to be ignored*/
kal_uint8 mms; /* more message to send*/
kal_uint8 msg_type; /* sms deliver*/
kal_uint8 no_orig_addr;
kal_uint8 orig_addr_size; /* the max size of *orig_addr in octet*/
kal_uint8 *orig_addr; /* assumed to be
byte-packed*/
kal_uint8 pid; /* to be bit-wise decoded*/
kal_uint8 dcs; /* to be bit-wise decoded*/
kal_uint8 scts[7];
kal_uint8 user_data_len;
kal_uint8 no_user_data; /* 7-bit to octet */
kal_uint8 user_data_size; /* the max size of *user_data in octet*/
kal_uint8 *user_data; /* can have user data header also*/
} smslib_deliver_peer_struct;
typedef struct
{
kal_uint8 type_of_info;
kal_bool need_store;
kal_bool is_msg_wait;
kal_bool is_show_num[SMSLIB_NUM_OF_MSG_WAITING_TYPE];
kal_bool is_clear[SMSLIB_NUM_OF_MSG_WAITING_TYPE];
kal_bool ind_flag[SMSLIB_NUM_OF_MSG_WAITING_TYPE];
smslib_mwis_struct mwis;
kal_uint8 msp;
#ifdef __SMS_R6_ENHANCED_VOICE_MAIL__
smsal_evmi_struct evmi; // should free this after processing
#endif
} smslib_msg_waiting_struct;//waiting message ind相关
typedef struct
{
kal_int32 dest_port; /* -1: invalid port */
kal_int32 src_port;
} smslib_port_struct; // = smsal_port_struct
API原型
void mmi_frm_sms_reg_msg_check(
PsExtPeerIntFuncPtr action,
PsFuncPtrFuncPtr callback);
功能描述
通过使用该函数,可以对收到的新短信(通过action Function)作检查, 如果符合条件(返回值为TRUE), 则会(通过callback Function)把该短信相关信息传给对应的Application。该Application可以决定这个SMS是否还会被SMS Application处理到(比如把该SMS放在SMS Application的Inbox, 并显示给用户)。我们在这里称这种行为为“短信拦截”。
对于同一个SMS, 只能被其中一个注册的Application所拦截;当同时存在多个注册的Application时,则需要分优先级;高优先级的Application拦截到该SMS时(即其action Function的返回值为TRUE时), 低优先级的Application就没有机会可以拦截。
目前采用比较简单的方式,优先级是根据注册的前后顺序, 注册越靠前,优先级越高;目前在SMS Application内部,已经存在了2个拦截。
函数参数
action
检查函数;检查新来的SMS是否符合某种条件,当返回值为TRUE时,则会调用callback Function.
callback
回调函数; 当action的返回值为TRUE时,会执行callback function; callback Function的返回值可以决定该SMS是不是还会被SMS Application处理到(比如把该SMS放在SMS Application的Inbox, 并显示给用户)。当返回值为TRUE时,则允许SMS Application处理该SMS, 为FALSE,则不会由SMS Application处理。需要注意的是,在我们平台,SMS是由L4作保存的,如果不希望拦截的SMS不被SMS Application处理,则需要删除该SMS, 否则在下次开机,该SMS还会出现在SMS Inbox。
类型描述
PsExtPeerIntFuncPtr
typedef U8 (*PsExtPeerIntFuncPtr)(
void *data,
int withobject,
void *content);
data
该SMS的Information,需要做强制转换mmi_frm_sms_deliver_msg_struct;
withobject
是否有EMS Object, 即是否是EMS,而不是一般的Text SMS; TRUE表示有,FALSE为没有
content
该SMS的内容,内容的编码方式是由data中的dcs决定的; 如果dcs是GSM 7Bit编码,则content的编码格式为ASCII,如果是UCS2, 则content的编码格为Unicode。
PsFuncPtrFuncPtr
typedef U8 (*PsExtPeerIntFuncPtr)(
void *data,
int withobject,
void *content);
data
该SMS的Information,需要做强制转换mmi_frm_sms_deliver_msg_struct;
Withobject
是否有EMS Object, 即是否是EMS,而不是一般的Text SMS; TRUE表示有,FALSE为没有
content
该SMS的内容,内容的编码方式是由data中的dcs决定的; 如果dcs是GSM 7Bit编码,则content的编码格式为ASCII,如果是UCS2, 则content的编码格为Unicode。
mmi_frm_sms_deliver_msg_struct
typedef struct
{
U8 fo;
U8 scts[7];
l4c_number_struct sca_number;
l4c_number_struct addr_number;
U8 pid;
U8 dcs;
U8 ori_dcs;
U16 index; /* for awaited message, this is the start index */
U16 dest_port;
U16 src_port;
U8 mti;
U8 display_type;
#ifdef __MMI_MESSAGES_COPY__
U8 storageType;
#endif
U32 concat_info;
U16 no_msg_data;
U8 msg_data[1]; /* for awaited message, this is the first segment data */
} mmi_frm_sms_deliver_msg_struct;
fo
SMS TPDU的First Otect,用于判断短信的类型,是否有UDH等(具体可以参见sepc23.040的9.2.2.1)
scts
短信中心时间戳, 短信中心收到该SMS的时间,我们在Inbox里可以看到的时间;在开UM的情况下,对于Outbox,Unsent或Draft,为发送或保存的时间。在这个Case,是收到的SMS的时间。(具体可以参见spec23.040的9.2.3.11)
sca_number
短信中心号码
addr_number
接收者号码(DA)或发送者号码(OA); 在这个Case,是发送者的号码
pid
Protocol Identifier,如为0x00则是SMS Application, 0x32则是Email。(具体可以参见spec23.040的9.2.3.9)
dcs
Content部分编码格式,具体值请参考smsal_dcs_enum
ori_dcs
在TPDU中的TP-DCS字段值
index
L4 index, 在这个Case,为第一个Segment的L4 Index.
dest_port
目的端口,如果该SMS为端口短信,则不为零
src_port
源端口,如果该SMS为端口短信,则不为零
mti
message type identifier, 表示该SMS的类型(参考spec23.040的9.2.3.1)
display_type
显示类型,具体值请参考smsal_display_type_enum
storageType
存储类型,具体值请参考smsal_storage_enum
concat_info
长短信(Concatenated SMS)的Information, 包括这个SMS多少个Segment,这个Segment的第几个等。
2个低字节为Reference number;
最高字节为该SMS Segment是第几个Segment;
第三字节为该SMS的总Segment数。
no_msg_data
SMS content部分的字节数
msg_data[1]
新来的SMS的Content都会缓存在一个Buffer里, msg_data的是第一个Segment的Content缓存Buffer的Index。
l4c_number_struct
typedef struct
{
kal_uint8 type;
kal_uint8 length;
kal_uint8 number[MAX_CC_ADDR_LEN];
} l4c_number_struct;
type
号码的类型,如0x81表示国内号码,0x91表示国际号码,(通常用“+”表示)。
length
号码长度,number部分的长度
number
号码, 号码只有我们在MMI常见的号码的数字部分,
Sample Code
注册拦截函数
为了保证拦截的Application优先级,需要统一在如下位置作注册,在文件
…\mcu\plutommi\mmi\messages\messagesscr\smspshandler.c中
void mmi_msg_set_protocol_event_handler(void)
{
……
//Add your register function
mmi_frm_sms_reg_msg_check(
sample_check_new_sms,
sample_capture_new_sms);
}
检查函数 action
U8 sample_check_new_sms(void *data, int withobject, void *content)
{
mmi_frm_sms_deliver_msg_struct *msg =
(mmi_frm_sms_deliver_msg_struct*)data;
//If it is an EMS
if (withobject)
{
return FALSE;
}
else
{
if (/* Add your check code */)
{
return TRUE;
}
else
{
return FALSE;
}
}
}
回调函数callback
static MMI_BOOL sample_is_deleting_sms;
pBOOL sample_capture_new_sms(void *data, S8 *content)
{
mmi_frm_sms_deliver_msg_struct *inMsg =
(mmi_frm_sms_deliver_msg_struct*) data;
/* Add your handle code */
/* If doesn't allow the user to see this sms in the SMS Inbox, delete it */
/* If the arrival of new sms is very frequent, the deleting request is also very frequent; But he SMS
Framework can't handle too much request in short time,so we need to stored the sms index when deleting a
sms, and delete the next one after the deleting is finished. */
if (sample_is_deleting_sms == MMI_TRUE)
{
//Stored the new sms L4 index when it is deleting a sms
if (sample_add_sms_index(inMsg->index) == MMI_FALSE)
{
/* If add SMS index failed, increase the value
of the MACRO SAMPLE_MAX_STORED_INDEX_NUM */
MMI_ASSERT(0);
}
}
else
{
//If the sms is ready
if (mmi_frm_sms_get_sms_list_size(MMI_FRM_SMS_NOBOX) !=
MMI_FRM_SMS_INVALID_INDEX)
{
sample_delete_capture_sms_req(inMsg->index);
}
else //If the sms is not ready
{
if (sample_add_sms_index(inMsg->index) == MMI_FALSE)
{
/* If add SMS index failed, increase the value
of the MACRO SAMPLE_MAX_STORED_INDEX_NUM */
MMI_ASSERT(0);
}
//register the event which the SMS is ready
mmi_frm_sms_reg_interrupt_check(
MOD_MMI,
PRT_MSG_ID_MMI_SMS_READY_IND,
sample_handle_sms_ready);
}
}
/ * If don’t want the SMS application to handle this SMS, return FALSE, else return TRUE. In this
sample code, don’t want the SMS showed in the Inbox, so return FALSE */
return FALSE;
}
NOTE:
如果不希望该SMS出现在Inbox, 被User看到,则应该删除它,否则在下次开机时 ,它还会出现在Inbox.
如果在短时间内收到大量的SMS,则出现在短时间内会做多次删除的操作,但是由于SMS Framework的Action Queue Size为15,即最多只能支持15个删除的Request;当删除的操作被其它的操作Suspend时,就会出现有被拦截的SMS不会被删除的情况。
因此对于可能出现的这种情况,处理的策略是:当在拦截到新来SMS时,如果有正在删除的SMS,则把该新来的SMS的L4 Index保存,等待正在删除的动作完成后,则删除其它保存了L4 Index的SMS.
如果SMS Not Ready,则不能作删除的动作,所以需要把新来的SMS的L4 Index保存;此时注册SMS Ready的Interrupt, 在SMS Ready时再作删除的动作。
保存SMS L4 Index
#define SAMPLE_MAX_STORED_INDEX_NUM 100
typedef struct
{
U16 index[SAMPLE_MAX_STORED_INDEX_NUM];
U16 header;
U16 tailer;
U16 total_num;
}sample_stored_new_sms_index_struct;
sample_stored_new_sms_index_struct *sample_stored_index;
//Add new sms l4 index in the buffer
static MMI_BOOL sample_add_sms_index(U16 index)
{
if (sample_stored_index == NULL)
{
sample_stored_index = OslMalloc(sizeof
(sample_stored_new_sms_index_struct));
sample_stored_index->header = 0;
sample_stored_index->tailer = 0;
sample_stored_index->total_num = 0;
}
if (sample_stored_index->total_num == SAMPLE_MAX_STORED_INDEX_NUM)
{
return MMI_FALSE;
}
sample_stored_index->index[sample_stored_index->tailer] = index;
sample_stored_index->tailer++;
sample_stored_index->total_num++;
if (sample_stored_index->tailer == SAMPLE_MAX_STORED_INDEX_NUM)
{
sample_stored_index->tailer = 0;
}
return MMI_TRUE;
}
static U16 sample_get_next_sms_index(void)
{
U16 index = MMI_FRM_SMS_INVALID_INDEX;
if (sample_stored_index != NULL)
{
if (sample_stored_index->total_num == 0)
{
OslMfree(sample_stored_index);
sample_stored_index = NULL;
}
else
{
index = sample_stored_index->index
[sample_stored_index->header];
sample_stored_index->header++;
sample_stored_index->total_num--;
if (sample_stored_index->header ==
SAMPLE_MAX_STORED_INDEX_NUM)
{
sample_stored_index->header = 0;
}
}
}
return index;
}
SMS Ready后的处理
如果需要获取SMS Ready事件,需要使用下面的API注册该事件的回调函数
void mmi_frm_sms_reg_interrupt_check(
module_type mod,
U16 msgid,
PsFuncPtrU16 callback);
static void sample_handle_sms_ready(
void *dummy,
module_type mod,
U16 result)
{
U16 index = sample_get_next_sms_index();
if (index != MMI_FRM_SMS_INVALID_INDEX)
{
sample_delete_capture_sms_req(index);
}
}
删除SMS
void sample_delete_capture_sms_req(U16 index)
{
//Set the flag when delete
sample_is_deleting_sms = MMI_TRUE;
/* the typde of the capture SMS is MMI_FRM_SMS_APP_AWAITS */
mmi_frm_sms_delete_sms(
sample_delete_capture_sms_rsp,
MOD_MMI,
MMI_FRM_SMS_APP_AWAITS,
index);
}
void sample_delete_capture_sms_rsp(
void *dummy,
module_type mod,
U16 result)
{
U16 index;
if (result == MMI_FRM_SMS_OK)
{
//Delete Success
//Add Handle Code
}
else
{
//Delete Failed
//Add handle Code
}
//Get next new SMS which stored
index = sample_get_next_sms_index();
//Delete next new SMS which stored
if (index != MMI_FRM_SMS_INVALID_INDEX)
{
sample_delete_capture_sms_req(index);
}
else
{
sample_is_deleting_sms = MMI_FALSE;
}
}
1.2 拦截短信SOP(09B)
09B 中将sms部分分为了UI和service两个部分,在09B之前的处理是在SMSAL层存储短信,然后传给MMI,再由MMI来处理。但是在09B中拦截短信在service部分拦截就OK。09B sms的架构图如下:
从上图中可以看到service部分中包含了Reciever,这部分就是用来处理接收短信的所有的流程的。
当收到一条短信后会首先进入函数srv_sms_new_sms_ind,最后会进入函数srv_sms_handle_new_msg进行处理,在该函数中会针对不同类型的sms进行处理,保存sms也是在这个函数里处理的。所以拦截短信只要在这个函数里进行拦截就OK了。
srv_sms_handle_new_msg会调用smslib_decode_pdu和smslib_get_msg_content 解析msg,解析完成后信息存储在app_lib_data中,然后使用需要的条件来判断拦截短信就OK了。
结构体介绍如下:(可以使用这些值设定条件做判断)
smslib_general_struct *app_lib_data
typedef struct
{
smslib_sim_status_enum status;
l4_addr_bcd_struct sca;
smslib_tpdu_decode_struct tpdu;
kal_uint8 pdu_len; /* length of PDU */
kal_uint8 tpdu_len; /* length of TPDU */
l4c_number_struct forMMI_SCAAddr;
l4c_number_struct forMMI_TPAddr;
kal_uint16 forMMI_UserData_length; /*unit: octet*/
kal_uint8 forMMI_UserData[170];
} smslib_general_struct;
typedef struct
{
union
{
smslib_deliver_peer_struct deliver_tpdu;
smslib_submit_peer_struct submit_tpdu;
smslib_status_report_peer_struct report_tpdu;
} data;
smslib_mti_enum mti;
//
kal_uint8 fo; /* first octet */
kal_uint8 offset; /* offset to message content */
/* init address of User Data Header */
kal_uint8 msg_len;/* length of user data */
/* User Data Header + User Data */
kal_uint8 udhl; /* for calculating offset to unpack */
/* udhl + udh */
smslib_concat_struct concat_info;
/* for decoding DCS */
smslib_msg_class_enum msg_class;
smslib_alphabet_enum alphabet_type;
kal_uint8 is_compress;
smslib_msg_waiting_struct msg_wait;
/* User Data Header */
smslib_port_struct port;
} smslib_tpdu_decode_struct;
typedef struct
{
kal_uint8 reply_flag; /* whether reply is sought*/
kal_uint8 udh_p; /* indicates presence of
user data header*/
kal_uint8 status_rep_flag; /* whether status reports
are sought*/
kal_uint8 fill_bits; /* to be ignored*/
kal_uint8 mms; /* more message to send*/
kal_uint8 msg_type; /* sms deliver*/
kal_uint8 no_orig_addr;
kal_uint8 orig_addr_size; /* the max size of *orig_addr in octet*/
kal_uint8 *orig_addr; /* assumed to be
byte-packed*/
kal_uint8 pid; /* to be bit-wise decoded*/
kal_uint8 dcs; /* to be bit-wise decoded*/
kal_uint8 scts[7];
kal_uint8 user_data_len;
kal_uint8 no_user_data; /* 7-bit to octet */
kal_uint8 user_data_size; /* the max size of *user_data in octet*/
kal_uint8 *user_data; /* can have user data header also*/
} smslib_deliver_peer_struct;
typedef struct
{
kal_uint8 type_of_info;
kal_bool need_store;
kal_bool is_msg_wait;
kal_bool is_show_num[SMSLIB_NUM_OF_MSG_WAITING_TYPE];
kal_bool is_clear[SMSLIB_NUM_OF_MSG_WAITING_TYPE];
kal_bool ind_flag[SMSLIB_NUM_OF_MSG_WAITING_TYPE];
smslib_mwis_struct mwis;
kal_uint8 msp;
#ifdef __SMS_R6_ENHANCED_VOICE_MAIL__
smsal_evmi_struct evmi; // should free this after processing
#endif
} smslib_msg_waiting_struct;//waiting message ind相关
typedef struct
{
kal_int32 dest_port; /* -1: invalid port */
kal_int32 src_port;
} smslib_port_struct; // = smsal_port_struct
- 如何拦截短消息
- 短消息
- pendingintent以及短消息发送报告 && 拨号拦截 && 信息推送
- 如何不通过SIM卡直接读或写短消息
- 如何去掉论坛右下角的新短消息提醒
- 如何拦截键盘输入(HOOK)
- 如何拦截键盘输入
- BCB如何拦截消息
- 如何拦截touch事件
- 短消息分割
- 监听短消息
- 短消息系统
- 短消息系统
- Cempi实战攻略(六)——如何截获到达的短消息
- Cempi实战攻略(六)——如何截获到达的短消息
- Cempi实战攻略(六)——如何截获到达的短消息
- 用串口连接GSM手机发送和接收短消息,在应用程序中如何编程实现?
- 用串口连接GSM手机发送和接收短消息,在应用程序中如何编程实现?
- 添加短消息中多国语言的常用短语SOP
- cvCreateSeq源码分析
- java web项目中读取和修改properties配置文件
- 结局怎么写,才能不难过_伤感2则QQ日志
- 六类UML图
- 如何拦截短消息
- Android 调用相册,相机并且相机拍照后可直接裁剪
- Abstract Factory - 抽象工厂
- 非idle界面received SMS提示
- 用 WEKA 进行数据挖掘,第 2 部分: 分类和群集
- spring注解注入加载系统配置
- 如何添加默认的小区广播channel和name
- Extjs 4.x proxy设计思想解读
- sql developer 中一个数据库链接另外一个数据库