首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > 移动开发 >

Loongson1B开发板+GSM模块彩信发送兑现

2013-01-02 
Loongson1B开发板+GSM模块彩信发送实现一、文档简介:本文档用于介绍1B开发板GSM模块发送彩信的实现过程,以

Loongson1B开发板+GSM模块彩信发送实现
一、文档简介:

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

开发环境参数:

操作系统:Ubuntu 11.04

本机平台:X86

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

交叉编译工具链:gcc-3.4.6-2f(1B交叉编译工具链)

所需软件及工具包:

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.172的80端口或者9201端口。要注意的是彩信并非直接投递给接收方,而是像邮件一样,先发送给一个中间服务器MMS Proxy-Relay。MMS Proxy-Relay暂时保存彩信,然后通过push协议给彩信接收方发送一个通知,彩信接收方收到通知后从MMS Proxy-Relay上获取彩信内容。MMS Client和WAP Gateway之间用WAP传输协议传输,而WAP Gateway和MMS 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 PDU(Protocol Data Unit,协议数据单元)由MMS头和MMS消息体组成,MMS头由多个域名和域值组成,由客户端指定,MMS头里面的一些域可以被MMS Proxy-Replay修改或补充,MMS Proxy-Replay使用这些头域信息生成MM通知以及构造接收MM PDU中的相关头域,连同消息实体一同送往接收方。消息体跟在MMS头之后,大多数MMS PDU只含有MMS头,它们起到建立和维持通信的作用,只有在M-Send.req和M-Retrieve.conf PDU中才有消息体。MMS PDU和HTTP 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-HEADER中,X-Mms-Message-Type ,X-Mms-Transaction-ID和X-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

98:X-Mms-Transaction-ID

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

89:From 发送方

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

97:To 接收方

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:接收方数据“+8615814542975/TYPE=PLMN ”

84:Content-Type

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

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

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

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

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

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

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

再后边是Content Location和Content 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

1c:Header的长度为28字节

0c:Data的长度为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

12:Header的长度为18字节

df 22:Data的长度为1219字节

HeaderLen和DataLen均是采用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: 8613026872332

x-mmsc-tid: 0

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

热点排行