开发板+GSM模块彩信发送实现

来源:互联网 发布:linux 在线安装ant 编辑:程序博客网 时间:2024/06/06 12:08

一、文档简介:

本文档用于介绍1B开发板+GSM模块发送彩信的实现过程,以及彩信MMS协议封装过程。

开发环境参数:

操作系统:Ubuntu 11.04

本机平台:X86

目标平台:Loongson 1B 开发板+华为GSM模块MG323

交叉编译工具链:gcc-3.4.6-2f1B交叉编译工具链)

所需软件及工具包:

1b-linux-3.0内核git版本号:115a0a040ffdaaba5f3afa58cb08625020d3fde8

PPP工具源码包:ppp-2.4.5.tar.gz

二、实现过程

1.实现步骤:

A. 开发板上PPP连接GPRS上网

B. 与移动网关建立TCP-Socket连接

C. 封装MMS-PDU数据包

D. 封装HTTP-POST数据包

E. 发送HTTP报文至移动网关

F. 接收网关回复信息

2.开发板上PPP连接GPRS上网

首先配置kernel使它支持如下PPP选项:

Make menuconfig--->Device Drivers--->Network device support--->

PPP(point-to-point) support
PPP multilink support(EXPERIMENTAL)
PPP support for async serial prots
PPP support for sync tty ports
PPP Deflate compression
PPP BSD-Compress compression

接下来编译交叉编译ppp-2.4.5

编译完成后将./pppd/pppd, ,/chat/chat, ./pppdump/pppdump, ./pppstats/pppstats四个文件拷贝到1B开发板文件系统的/usr/sbin目录下,并将他们的文件属性改为755

检查/etc/host.conf脚本,确保这一行:order hosts,bind

1B开发板文件系统/etc/ppp目录下建立如下四个PPP配置文件:

File1/etc/ppp/peers/gprs

#/etc/ppp/peers/gprs

# Usage:   root>pppd call gprs

/dev/ttyS0   #改成自己的GSM模块设备号

115200    #改成自己串口波特率

nocrtscts 

#可能你的串口是需要crtscts,硬件流控的,这是由你的串口决定的,一般嵌入式系统的串口没有带硬件流控,也不需要就加nocrtscts

modem   #这个参数使得pppd进程将等待模块发回的CD (Carrier Detect)信号,与local真好相反

#noauth

debug  #把调试信息输出到/var/log/messages,在调试成功后去掉它,以减少垃圾的产生。

nodetach 

#hide-password

usepeerdns  #以下的3个参数一般不可少

noipdefault

defaultroute 

user "cmnet"  #设置接入的用户名,在chap-secrets或者pap-secets中使用

0.0.0.0:0.0.0.0  #本地和远端的ip都设为0使得接入的isp分配本地的ip地址

ipcp-accept-local  #要求peer也就是isp给自己非配动态的IP地址

#ipcp-accept-remote

#lcp-echo-failure  12

#lcp-echo-interval 3

noccp  #不需要压缩控制协议,有可能对端不需要,根据自己的isp的情况

#novj

#novjccomp

persist  #保证在连接断开的情况下不退出,并尝试重新打开连接

connect '/usr/sbin/chat -s -v -f /etc/ppp/gprs-connect-chat' 

#pppd调用chat会话进程接入对端isp,启动对端的pppd,然后本地pppd与对端的pppd一起进行协

#商网络参数和chap/pap认证,成功后,再进行ncp层的ip的分配。


File2/etc/ppp/gprs-connect-chat

#/etc/ppp/gprs-connect-chat

#chat script for China Mobile, used wavecom module by lee.

TIMEOUT 15

ABORT '\nDELAYED\r'

ABORT '\nBUSY\r'

ABORT '\nERROR\r'

ABORT '\nNO DIALTONE\r'

ABORT '\nNO CARRIER\r'

'' \rAT

OK ATS0=0

OK ATE0V1

OK AT+CGDCONT=1,"IP","CMWAP"

OK ATDT*99***1#

CONNECT ''


File3/etc/ppp/chap-secrets

#cat /etc/ppp/chap-secrets

#client server secret IP address

"cmnet" * "cmnet" *


File4/etc/ppp/pap-secrets

#cat /etc/ppp/pap-secrets

# Secrets for authentication using PAP# client server secret IP addresses

######## redhat-config-network will overwrite this part!!! (begin) ##########

######## redhat-config-network will overwrite this part!!! (end) ############

"cmnet" * "cmnet" *

完成以上配置,然后在板上执行以下指令就能实现PPP连接GPRS了:

[root@Loongson-gz:/]#pppd call gprs &

[root@Loongson-gz:/]#ifconfig

ppp0      Link encap:Point-to-Point Protocol  

          inet addr:10.55.53.150  P-t-P:192.200.1.21  Mask:255.255.255.255

          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1

          RX packets:4 errors:0 dropped:0 overruns:0 frame:0

          TX packets:5 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:3 

          RX bytes:58 (58.0 B)  TX bytes:98 (98.0 B)

[root@Loongson-gz:/]#ping 10.0.0.172

PING 10.0.0.172 (10.0.0.172): 56 data bytes

64 bytes from 10.0.0.172: seq=0 ttl=252 time=556.702 ms

64 bytes from 10.0.0.172: seq=1 ttl=252 time=293.645 ms

64 bytes from 10.0.0.172: seq=2 ttl=252 time=492.732 ms

64 bytes from 10.0.0.172: seq=3 ttl=252 time=290.228 ms

^C

--- 10.0.0.172 ping statistics ---

4 packets transmitted, 4 packets received, 0% packet loss

round-trip min/avg/max = 290.228/408.326/556.702 ms

看到以上打印信息,就说明成功使用PPP拨通GSM模块的GPRS连接上网络。

3.MMS封装及发送过程

彩信和其它WAP应用的架构差不多,都要经过WAP Gateway中转,彩信在中国移动以及中国联通的GPRS接入点均一样,都是10.0.0.17280端口或者9201端口。要注意的是彩信并非直接投递给接收方,而是像邮件一样,先发送给一个中间服务器MMS Proxy-RelayMMS Proxy-Relay暂时保存彩信,然后通过push协议给彩信接收方发送一个通知,彩信接收方收到通知后从MMS Proxy-Relay上获取彩信内容。MMS ClientWAP Gateway之间用WAP传输协议传输,而WAP GatewayMMS Proxy-Relay之间走传统的TCP/IP协议

要实现发送彩信,作为客户端,我们需要完成的主要是与10.0.0.172建立TCP连接,将彩信数据包发送至WAP Gateway即可,其他部分工作由WAP Gateway与MMS Proxy-Relay自行完成。

将彩信数据包发送至WAP Gateway有两种实现方式,由于MMS是基于WAP协议的,移动的WAP代理服务器80/8080端口支持WAP2.0,可以采用HTTP方式传输数据;也可以通过WSP/WTP/WDP这一套传输协议传输数据,WAP代理服务器9201端口支持WSP/WTP/WDP协议。在这里我们选择的是HTTP方式。

以下是采用HTTP方式传输数据的数据包结构:

1

HTTP-HEADER

HTTP-DATA

2

MMS-HEADER

Message Body

接下来从MMS-PDU封装实现开始,主要参考MMS的编码协议文档《WAP-209-MMSEncapsulation-20010601-a.pdf》。

首先需要了解一下MMS PDU的结构,MMS PDUProtocol Data Unit,协议数据单元)由MMS头和MMS消息体组成,MMS头由多个域名和域值组成,由客户端指定,MMS头里面的一些域可以被MMS Proxy-Replay修改或补充,MMS Proxy-Replay使用这些头域信息生成MM通知以及构造接收MM PDU中的相关头域,连同消息实体一同送往接收方。消息体跟在MMS头之后,大多数MMS PDU只含有MMS头,它们起到建立和维持通信的作用,只有在M-Send.reqM-Retrieve.conf PDU中才有消息体。MMS PDUHTTP PDU极为类似,但要简单一些。一个MMS PDU对应一种消息格式。不同类型的MMS PDU有不同的MMS Header MMS Header根据由一系列的域组成,这些域定义了PDU的各种属性,包括PDU类型,版本号,接受方,发送方,主题,发送时间等。MMS Header中的域分为可选项和必选项,根据PDU的类型不同而不同。

常见的PDU的类型有:

发送请求:     M-send.req

发送确认:     M-send.conf

彩信通知:     M-notification.ind

通知回应:     M-notifyresp.ind

获取彩信回应: M-retrieve.conf

接收确认:     M-acknowledge.ind

彩信回执:     M-delivery.ind

而要实现发送彩信功能,我们需要完成一个M-send.req Message的封装。M-send.req Message由两部分组成,MMS Header后面接的是Message Body。根据MMS Message Body组装的是否有序(是否有位置控制信息,有显示先后顺序),M-send.req Message的组装方式分为:

application/vnd.wap.multipart.mixed方式,所有的消息内容混合在一起,没有时间上的顺序,内容怎么显示由客户端的显示控制策略来决定。
application/vnd.wap.multipart.related方式,各消息内容之间有一定关系,该关系可能是显示的时间上的先后,显示的位置等。这样在终端显示该消息的时候,就可以以幻灯片的方式显示一系列消息。

我们仅需要简单实现文本以及图片的发送,所以选择application/vnd.wap.multipart.mixed组装方式。

根据协议文档,M-send.req Message Header由以下内容组成:

Name

Content

Comments

Value

X-Mms-Message-Type

Message-type-value=m-send-req

Mandatory

0x0C

X-Mms-Transaction-ID

Transaction-id-value

Mandatory

0x18

X-Mms-MMS-Version

MMS-version-value

Mandatory

0x0D

Date

Date-value

Optional

0x05

From  

From-value

Mandatory

0x09

To

To-value

Optional

0x17

Cc

Cc-value

Optional

0x02

Bcc

Bcc-value

Optional

0x01

Subject

Subject-value 

Optional

0x16

X-Mms-Message-Class

Message-class-value

Optional

0x0A

X-Mms-Expiry

Expiry-value

Optional

0x08

X-Mms-Delivery-Time

Delivery-time-value

Optional

0x07

X-Mms-Priority

Priority-value

Optional

0x0F

X-Mms-Sender-Visibility

Sender-visibility-value

Optional

0x14

X-Mms-Delivery-Report

Delivery-report-value

Optional

0x06

X-Mms-Read-Reply

Read-reply-value

Optional

0x10

Content-Type

Content-type-value

Mandatory

0x04

在MMS-HEADERX-Mms-Message-Type ,X-Mms-Transaction-IDX-Mms-MMS-Version必须位于MMS-HEADER的开始,并且按照前面所列的顺序。Content-Type必须在MMS-HEADER域的最后,其后为消息体,其它域的顺序可以随意安排。而为了使传输的数据更紧凑,MMS协议规定,对于Header Field Name的编码,数值的最高位(即bit7)置1。因此,上述编码值在实际的MMS PDU中需要加上0x80。 

下面主要以一段MMS PDU数据为例进行分析各个域值:

8c  80  98  30  00  8d  90  89  01  81  97  2b  38  36  31  35  38  31  34  35  34  32  39  37  35  2f  54  59  50  45  3d  50  4c  4d  4e  00  96  74  65  73  74  00  84  a3  02  1c  0c  0a  83  85  31  2e  74  78  74  00  81  ea  c0  22  3c  31  2e  74  78  74  3e  00  8e  31  2e  74  78  74  00  4d  4d  53  20  42  79  20  45  74  68  61  6e  12  df  22  9d  c0  22  3c  31  2e  67  69  66  3e  00  8e  31  2e  67  69  66  00  ff  d8 ... ff  d9

8C:X-Mms-Message-Type
80:M-send.req

98X-Mms-Transaction-ID

30  00:MMS Transaction ID为48
8D:X-Mms-Version
90:MMS Version为1.0

89From 发送方

01:后接一个字节数据 
81:发送方号码占位符

97To 接收方

2b  38  36  31  35  38  31  34  35  34  32  39  37  35  2f  54  59  50  45  3d  50  4c  4d  4e  00:接收方数据“+86***********/TYPE=PLMN ”

84Content-Type

a3表示:application/vnd.wap.multipart.mixed组装方式 

02:表示后接两部分内容数据

接下来讲述一下内容数据部分的结构:

每一部分的内容数据均由两部分组成,分别是Header+Data

首先包含一个HeaderLen,用来指示ContentType域和Header域的总长度,是一个Uintvar变量

接下来时DataLen,用来指示后面Data域的长度,在这里指的是一块多媒体数据的字节数

然后是ContentType域用来表示后面的数据块是什么类型的数据(如txt文本,jpeg图片,还是vidoe数据流)

再后边是Content LocationContent ID,通常是多媒体数据的文件名,Content Location域以单引号"开始,后面一对<>里面包含文件名,Content ID域则直接就是一对<>里面包含文件名

最后接Data域,它的长度由DataLen指定

1c  0c  0a  83  85  31  2e  74  78  74  00  81  ea  c0  22  3c  31  2e  74  78  74  3e  00  8e  31  2e  74  78  74  00  4d  4d  53  20  42  79  20  45  74  68  61  6e  :第一段内容的Header+Data

1cHeader的长度为28字节

0cData的长度为12字节

0a:指明后边数据为txt文本类型

85 ~00:这段数据的指明文件名为1.txt

4d~6e:文本数据

12  df  22  9d  c0  22  3c  31  2e  67  69  66  3e  00  8e  31  2e  67  69  66  00  ff  d8 ... ff  d9  第二段内容的Header+Data

12Header的长度为18字节

df 22Data的长度为1219字节

HeaderLenDataLen均是采用Uintvar变量,特点是对超过7bit的数值进行拆分,低7位存放数据,高位补1表示有后续,最大32bit。 

9d:指明后边数据为gif格式,但是在测试过程中,发现jpg格式也可以发送成功并显示。

22 ~00:这段数据的指明文件名为1.gif

ff~d9:图片数据,这是一张jpg图片

至此,便完成了整个MMS PDU的组装,在组装的过程中,需计算好整个MMS PDU的长度。

接下来是对MMS PDU进行HTTP封装,主要方法是为MMS PDU增加一个HTTP HEADER,以下是HTTP HEADER相关代码:

if(mms_main.net_choose == UNIWAP)

    {

        //联通彩信接入点

        sprintf(http_request,, "POST http://mmsc.myuni.com.cn/ HTTP/1.1\r\n"

                "Host:10.0.0.172:80\r\nUser-Agent: Ethan\r\n"

                "Content-Type: application/vnd.wap.multipart.related\r\n"

                "Accept: application/vnd.wap.multipart.related\r\n"

                "Content-Length: %d\r\n\r\n", mms_pdu_len);

    }

    else if(mms_main.net_choose == CMWAP)

    {

        //移动彩信接入点

        sprintf(http_request, "POST http://mmsc.monternet.com/ HTTP/1.1\r\n"

                "Host:10.0.0.172:80\r\nUser-Agent: Ethan\r\n"

                "Content-Type: application/vnd.wap.multipart.related\r\n"

                "Accept: application/vnd.wap.multipart.related\r\n"

                "Content-Length: %d\r\n\r\n", mms_pdu_len);

}

其中mms_pdu_len为之前MMS PDU的长度,若Content-Length错误,则网关回复HTTP 400错误(Content-Length<mms_pdu_len)或者HTTP 500错误(Content-Length>mms_pdu_len)

然后将MMS PDU整个数据包置于HTTP HEADER之后,再发送出去即可。

发送成功,网关回复:

HTTP/1.1 200 OK

Content-Type: application/vnd.wap.mms-message

Content-Length: 32

Date: Thu, 07 Jun 2012 07:00:56 GMT

Server: MMSC

x-mmsc-code: -128

x-mmsc-from: 86***********

x-mmsc-tid: 0

x-mmsc-to: +86***********

原创粉丝点击