支持smil文件的MMS PDU打包方式.

Posted axman

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了支持smil文件的MMS PDU打包方式.相关的知识,希望对你有一定的参考价值。

 mms如果不支持smil那就不能叫真正的MMS,mixed的格式对于多个附件的MMS来说不仅没有"排版"功能,

而且即使用你想一个文件一个文件"拆单了看",也不得不看一次手工播放一次,就象要手动"翻页".所以不支持

smil干脆就别玩MMS了.

但基于related格式的支持smil的PDU打包方式怎么也搜索不到,很多厂商和技术人员都故作神秘,不就是一

堆规范的实现吗?只好下了几个文档来研究,经过反复调试,其中用nowSMS的mmscomp打包出来的格式竟然

是错误的,最后多次抓包比较,总算成功了.在『别人原来的mixed方式』的基础上修改成related方式的.有需要的

就自己用去吧.(注意基础类是别人原来提供的,我只是提供了related方式的打包逻辑)

工程文件在:http://dl2.csdn.net/down4/20070706/06201955542.rar

 

using  System;
using  System.Net;
using  System.IO;
using  System.Diagnostics;
using  System.Threading;
using  System.Collections;
using  System.Text;
///   <summary>
///  Lib 的摘要说明
///   </summary>


namespace  MMSLib


    
public   class  MMessage
    
        
string  subject  =   " 测试 " ;
        
int  deliverTime  =   0 ;    //    多少秒以后开始投递
        ArrayList inlineFiles  =   new  ArrayList();        //    文件列表  
        ArrayList destinations  =   new  ArrayList();       //    目标号码  

        
static   long  serialNumber  =   19700311L ;                   //    流水号
        FileInfo smilFile;



        
public   void  SetSubject( string  subject)
        
            
this .subject  =  subject;
        
        
public   void  SetDeliverTime( int  deliverTime)
        
            
this .deliverTime  =  deliverTime;
        
        
//     
         public   void  AddTo( string  dest)
        
            destinations.Add(dest);
        

        
public   void  AddFile( string  file)
        

            
if  (file.ToLower().EndsWith( " .smil " ))
            
                
if  ( this .smilFile  !=   null )
                    
throw   new  Exception( " The smil file has existed! " );
                
this .smilFile  =   new  FileInfo(file);
            
            inlineFiles.Add(file);
        

        
public   void  ClearTo()
        
            destinations.Clear();
        

        
//    得到二进制编码字节  
         public   byte [] MakeMMSContent()
        

            
if  ( this .smilFile  ==   null throw   new  Exception( " The smil file not found! " );

            
byte [] MMSContent  =   new   byte [ 0 ];
 
            
// X-Mms-Message-Type  
            MMSContent  =  appendContent( new   byte []   0x8C 0x80  , MMSContent);

            
            
// X-Mms-Transaction-ID  
            MMSContent  =  appendContent( new   byte []   0x98  , MMSContent);
            MMSContent 
=  appendContent(serialNumber.ToString(), MMSContent);
            serialNumber
++ ;   

            MMSContent 
=  appendContent( new   byte []   0x0  , MMSContent);

            
// X-Mms-MMS-Version  
            MMSContent  =  appendContent( new   byte []   0x8D 0x90  , MMSContent);

            
// Date  
            MMSContent  =  appendContent( new   byte []   0x85  , MMSContent);
            TimeSpan ts 
=  DateTime.Now  -   new  DateTime( 1970 1 1 0 0 0 );
            
int  sec  =  ( int )ts.TotalSeconds;
            
byte [] bySec  =  BitConverter.GetBytes(sec);
            MMSContent 
=  appendContent( new   byte []  ( byte )bySec.Length , MMSContent);
            Array.Reverse(bySec);
            MMSContent 
=  appendContent(bySec, MMSContent);

            
if  (deliverTime  >   0 )
            
                MMSContent 
=  appendContent( new   byte []   0x87  , MMSContent);
                
byte [] bfTime  =  BitConverter.GetBytes(deliverTime);     
                Array.Reverse(bfTime);
                
byte [] bfTimeLen  =   new   byte [ 3 ];
                bfTimeLen[
0 =  ( byte )(bfTime.Length  +   2 );
                bfTimeLen[
1 =   0x81 ;      //    相对时间格式  
                bfTimeLen[ 2 =  ( byte )bfTime.Length;
                MMSContent 
=  appendContent(bfTimeLen, MMSContent);
                MMSContent 
=  appendContent(bfTime, MMSContent);
            


            
// From,Len = 0x01,一个以0x81为标记的占位符,发送时自动插入发送号码.
            MMSContent  =  appendContent( new   byte []   0x89 0x01 0x81  , MMSContent);

            
// To  
             for  ( int  i  =   0 ; i  <  destinations.Count; i ++ )
            
                MMSContent 
=  appendContent( new   byte []   0x97  , MMSContent);
                MMSContent 
=  appendContent( " +86 "   +  ( string )destinations[i]  +   " /TYPE=PLMN " , MMSContent);
                
// MMSContent = appendContent(new byte[]  0x20, 0x20, 0x0 , MMSContent);
                MMSContent  =  appendContent( new   byte []   0x0  , MMSContent);
            

            
// subject  
             if  (subject.Length  >   0 )      //    使用Utf8编码  
            
                MMSContent 
=  appendContent( new   byte []   0x96  , MMSContent);
                
byte [] byLen  =   new   byte [ 1 ];
                byLen[
0 =  ( byte )(Encoding.UTF8.GetByteCount(subject)  +   2 );
                MMSContent 
=  appendContent(byLen, MMSContent);
                MMSContent 
=  appendContent( new   byte []   0xEA  , MMSContent);
                MMSContent 
=  appendContent(Encoding.UTF8.GetBytes(subject), MMSContent);
                MMSContent 
=  appendContent( new   byte []   0x0  , MMSContent);
            


            MMSContent 
=  appendContent( new   byte []   0x84  , MMSContent);
            
int  ctLen  =   2     //  0xB3 ,0x89
                 +    " application/smil " .Length
                
+   3           // 0x00 0x8A 0x3c
                 +  smilFile.Name.Length
                
+   2 ;          // 0x3c,0x00

            
byte [] cl  =  uintToBytes(ctLen);

            
if (cl[ 0 >=   0x1F )
                MMSContent 
=  appendContent( new   byte []   0x1F  , MMSContent);
            MMSContent 
=  appendContent(cl, MMSContent);
            MMSContent 
=  appendContent( new   byte []   0xB3 , MMSContent);
                
// 0xB3   Content-Type:application/vnd.wap.multipart.related
            
            MMSContent 
=  appendContent( new   byte []   0x89  , MMSContent);
            MMSContent 
=  appendContent(Encoding.ASCII.GetBytes( " application/smil " ), MMSContent);
            MMSContent 
=  appendContent( new   byte []   0x0  , MMSContent);

            MMSContent 
=  appendContent( new   byte []   0x8A  , 0x3C , MMSContent); // 0x8A:Start,0x3C:<
            MMSContent  =  appendContent(Encoding.ASCII.GetBytes( smilFile.Name ), MMSContent);
            MMSContent 
=  appendContent( new   byte []   0x3E  , 0x0  , MMSContent);  // 0x3E:>





            
byte [] byFileCount  =   new   byte [ 1 ];
            byFileCount[
0 =  ( byte )inlineFiles.Count;
            MMSContent 
=  appendContent(byFileCount, MMSContent);

            
int  chLen  =   " application/smil " .Length 
            
+   4       // 0x00 0xc0 0x22 0x3c: cid,",<
             +  smilFile.Name.Length
            
+   3       //  0x3E,0x00,0x8E
             +  smilFile.Name.Length
            
+   1 ;      //  0x00
            
            
for  ( int  j  =   0 ; j  <  inlineFiles.Count; j ++ )
            
                MMSContent 
=  appendContent(GetFileContent(inlineFiles[j].ToString()), MMSContent);
            
            
return  MMSContent;
        


        
//    打包文件
         private   byte [] GetFileContent( string  FileName)
        

            
byte [] byHeaders  =   new   byte [ 0 ];        //    ContentType和Headers组合  
             byte [] byData  =  readFile(FileName);

            
string  FileID  =  getContentId(FileName);
            
if  (FileName.EndsWith( " .txt " ))
            
                byHeaders 
=   new   byte [ 1 ];
                byHeaders[
0 =  ( byte )(Encoding.ASCII.GetByteCount(FileID)  +   5 );
                byHeaders 
=  appendContent( new   byte []   0x83 0x85  , byHeaders);        //    Utf-8  
                byHeaders  =  appendContent(Encoding.ASCII.GetBytes(FileID), byHeaders);
                byHeaders 
=  appendContent( new   byte []   0x00  , byHeaders);
                byHeaders 
=  appendContent( new   byte []   0x81 0xEA  , byHeaders);

            
            
else   if  (FileName.EndsWith( " .gif " ))
            
                byHeaders 
=   new   byte []   0x9D  ;
            
            
else   if  (FileName.EndsWith( " .mid " ||  FileName.EndsWith( " .midi " ))
            
                byHeaders 
=  Encoding.ASCII.GetBytes( " audio/midi " );
                byHeaders 
=  appendContent( new   byte []   0x00  , byHeaders);     
            
            
else   if  (FileName.EndsWith( " .smil " ))
            
                byHeaders 
=  Encoding.ASCII.GetBytes( " application/smil " );
                byHeaders 
=  appendContent( new   byte []   0x00  , byHeaders);     
            

            
// 加入Content-ID 
            byHeaders  =  appendContent( new   byte []   0xC0 0x22 0x3C  , byHeaders);
            byHeaders 
=  appendContent(Encoding.ASCII.GetBytes(FileID), byHeaders);
            byHeaders 
=  appendContent( new   byte []   0x3E 0x00  , byHeaders);
            
            
// 加入Content-Location  
            byHeaders  =  appendContent( new   byte []   0x8E  , byHeaders);
            byHeaders 
=  appendContent(Encoding.ASCII.GetBytes(FileID), byHeaders);
            byHeaders 
=  appendContent( new   byte []   0x00  , byHeaders);

            
byte [] byHeaderLen  =  uintToBytes(byHeaders.Length);
            
byte [] byDataLen  =  uintToBytes(byData.Length);

            
byte [] byMmc  =   new   byte [byHeaderLen.Length  +  byDataLen.Length  +  byHeaders.Length  +  byData.Length];
            Array.Copy(byHeaderLen, byMmc, byHeaderLen.Length);
            Array.Copy(byDataLen, 
0 , byMmc, byHeaderLen.Length, byDataLen.Length);
            Array.Copy(byHeaders, 
0 , byMmc, byHeaderLen.Length  +  byDataLen.Length, byHeaders.Length);
            Array.Copy(byData, 
0 , byMmc, byHeaderLen.Length  +  byDataLen.Length  +  byHeaders.Length, byData.Length);

            
return  byMmc;
        

        
private   byte [] uintToBytes( int  n)
        
            
byte [] buf  =   new   byte [ 8 ];
            
int  l  =   0 ;
            
while  (n  >=   128 )
            
                
byte  b  =  ( byte )(n  &   0x7F );
                n 
=  n  >>   7 ;
                buf[l
++ =  b;
            
            buf[l
++ =  ( byte )n;

            
byte [] retBys  =   new   byte [l];
            
for  ( int  i  =   0 ; i  <  l;  ++ i)
            
                retBys[i] 
=  ( byte )(buf[l  -  i  -   1 |   0x80 );
            
            retBys[l 
-   1 &=   0x7F ;
            
return  retBys;

        
        
        
//    读取文件  
         private   byte [] readFile( string  FileName)
        
            
if  (FileName.EndsWith( " .txt " )) 

                StreamReader sr 
=   null ;
                
try
                    sr 
=   new  StreamReader(FileName, Encoding.Default);
                    
string  text  =  sr.ReadToEnd();
                    
byte [] bf  =  Encoding.UTF8.GetBytes(text);
                    
return  bf;
                
                
catch  
                    
return   new   byte [ 0 ];
                
                
finally  
                    
if  (sr  !=   null ) sr.Close();
                
            
            FileStream fs 
=   null ;
            
try
            
                fs 
=   new  FileStream(FileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None);      //    没有设定Buffsize  
                 byte [] bf  =   new   byte [fs.Length];
                fs.Read(bf, 
0 , ( int )fs.Length);
                
return  bf;
            
            
catch
                
return   new   byte [ 0 ];
            
            
finally
                
if (fs  !=   null ) fs.Close();
            
        
        
        
private   string  getContentId( string  FileName)
        
            
int  at  =  FileName.LastIndexOf( " / " );
            
if  (at  <   0 )
                at 
=  FileName.LastIndexOf( " / " );
            
return  FileName.Substring(at  +   1 );
        
  
        
private   byte [] appendContent( byte [] srcBys,  byte [] destBys)
        
            Array.Resize(
ref  destBys, srcBys.Length  +  destBys.Length);
            Array.Copy(srcBys,
0 ,destBys,destBys.Length  -  srcBys.Length,srcBys.Length);
            
return  destBys;
        

        
private   byte [] appendContent( string  sz,  byte [] byDest)
        
            
return  appendContent(Encoding.Default.GetBytes(sz), byDest);
        
    

    
///     <summary>   
    
///    MMSender   的摘要说明。  
    
///     
    
///     </summary>   
     public   class  MMSender
    
        
//    设置参数  
         string  sMmscUrl  =   "

以上是关于支持smil文件的MMS PDU打包方式.的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式通过 ios 7+ 中的 mms 发送图像? [关闭]

GSM协议PDU编码长短信方法

急求基于Java的smil文件解析器,我把的全部积分送出去,谢啦

SMIL:t:Internet Explorer 8 中的音频问题

SWFObject / 加载 smil 文件

ACP和PDU是什么