?? mmsdecoder.php
字號:
<?php
// Version 0.77 //
/**
* Copyright (C) 2004 Jonatan Heyman
*
* This file is part of the PHP application MMS Decoder.
*
* MMS Decoder is free software; you can redistribute it and/or
* modify it under the terms of the Affero General Public License as
* published by Affero, Inc.; either version 1 of the License, or
* (at your option) any later version.
*
* MMS Decoder is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Affero General Public License for more details.
*
* You should have received a copy of the Affero General Public
* License in the COPYING file that comes with The Affero Project; if
* not, write to Affero, Inc., 510 Third Street, Suite 225, San
* Francisco, CA 94107 USA.
*/
define( "DEBUG", 0 ); // Print parseerrors? Print values while they are parsed? If you enable this, sending MMS from mobiles may not work. This is only for development purpose.
/*---------------------------------------------------*
* Constants *
* *
* http://wapforum.org/ *
* WAP-209-MMSEncapsulation-20020105-a *
* Table 8 *
* *
* The values are enconded using WSP 7bit encoding. *
* Read more about how to decode this here: *
* http://www.nowsms.com/discus/messages/12/3287.html*
* *
* Example from the above adress: *
* 7Bit 0D = 0001101 *
* 8Bit 0D = 10001101 = 8D *
*---------------------------------------------------*/
define( "BCC", 0x81 );
define( "CC", 0x82 );
define( "CONTENT_LOCATION", 0x83 );
define( "CONTENT_TYPE", 0x84 );
define( "DATE", 0x85 );
define( "DELIVERY_REPORT", 0x86 );
define( "DELIVERY_TIME", 0x87 );
define( "EXPIRY", 0x88 );
define( "FROM", 0x89 );
define( "MESSAGE_CLASS", 0x8A );
define( "MESSAGE_ID", 0x8B );
define( "MESSAGE_TYPE", 0x8C );
define( "MMS_VERSION", 0x8D );
define( "MESSAGE_SIZE", 0x8E );
define( "PRIORITY", 0x8F );
define( "READ_REPLY", 0x90 );
define( "REPORT_ALLOWED", 0x91 );
define( "RESPONSE_STATUS", 0x92 );
define( "RESPONSE_TEXT", 0x93 );
define( "SENDER_VISIBILITY", 0x94 );
define( "STATUS", 0x95 );
define( "SUBJECT", 0x96 );
define( "TO", 0x97 );
define( "TRANSACTION_ID", 0x98 );
/*--------------------------*
* Array of header contents *
*--------------------------*/
$mmsMessageTypes = array (
0x80 => "m-send-req",
0x81 => "m-send-conf",
0x82 => "m-notification-ind",
0x83 => "m-notifyresp-ind",
0x84 => "m-retrieve-conf",
0x85 => "m-acknowledge-ind",
0x86 => "m-delivery-ind",
0x00 => NULL
);
/*--------------------------*
* Some other useful arrays *
*--------------------------*/
$mmsYesNo = array(
0x80 => 1,
0x81 => 0,
0x00 => NULL
);
$mmsPriority = array(
0x80 => "Low",
0x81 => "Normal",
0x82 => "High",
0x00 => NULL
);
$mmsMessageClass = array(
0x80 => "Personal",
0x81 => "Advertisement",
0x82 => "Informational",
0x83 => "Auto"
);
$mmsContentTypes = array(
0x00 => '*/*',
0x01 => 'text/*',
0x02 => 'text/html',
0x03 => 'text/plain',
0x04 => 'text/x-hdml',
0x05 => 'text/x-ttml',
0x06 => 'text/x-vCalendar',
0x07 => 'text/x-vCard',
0x08 => 'text/vnd.wap.wml',
0x09 => 'text/vnd.wap.wmlscript',
0x0A => 'text/vnd.wap.wta-event',
0x0B => 'multipart/*',
0x0C => 'multipart/mixed',
0x0D => 'multipart/form-data',
0x0E => 'multipart/byterantes',
0x0F => 'multipart/alternative',
0x10 => 'application/*',
0x11 => 'application/java-vm',
0x12 => 'application/x-www-form-urlencoded',
0x13 => 'application/x-hdmlc',
0x14 => 'application/vnd.wap.wmlc',
0x15 => 'application/vnd.wap.wmlscriptc',
0x16 => 'application/vnd.wap.wta-eventc',
0x17 => 'application/vnd.wap.uaprof',
0x18 => 'application/vnd.wap.wtls-ca-certificate',
0x19 => 'application/vnd.wap.wtls-user-certificate',
0x1A => 'application/x-x509-ca-cert',
0x1B => 'application/x-x509-user-cert',
0x1C => 'image/*',
0x1D => 'image/gif',
0x1E => 'image/jpeg',
0x1F => 'image/tiff',
0x20 => 'image/png',
0x21 => 'image/vnd.wap.wbmp',
0x22 => 'application/vnd.wap.multipart.*',
0x23 => 'application/vnd.wap.multipart.mixed',
0x24 => 'application/vnd.wap.multipart.form-data',
0x25 => 'application/vnd.wap.multipart.byteranges',
0x26 => 'application/vnd.wap.multipart.alternative',
0x27 => 'application/xml',
0x28 => 'text/xml',
0x29 => 'application/vnd.wap.wbxml',
0x2A => 'application/x-x968-cross-cert',
0x2B => 'application/x-x968-ca-cert',
0x2C => 'application/x-x968-user-cert',
0x2D => 'text/vnd.wap.si',
0x2E => 'application/vnd.wap.sic',
0x2F => 'text/vnd.wap.sl',
0x30 => 'application/vnd.wap.slc',
0x31 => 'text/vnd.wap.co',
0x32 => 'application/vnd.wap.coc',
0x33 => 'application/vnd.wap.multipart.related',
0x34 => 'application/vnd.wap.sia',
0x35 => 'text/vnd.wap.connectivity-xml',
0x36 => 'application/vnd.wap.connectivity-wbxml',
0x37 => 'application/pkcs7-mime',
0x38 => 'application/vnd.wap.hashed-certificate',
0x39 => 'application/vnd.wap.signed-certificate',
0x3A => 'application/vnd.wap.cert-response',
0x3B => 'application/xhtml+xml',
0x3C => 'application/wml+xml',
0x3D => 'text/css',
0x3E => 'application/vnd.wap.mms-message',
0x3F => 'application/vnd.wap.rollover-certificate',
0x40 => 'application/vnd.wap.locc+wbxml',
0x41 => 'application/vnd.wap.loc+xml',
0x42 => 'application/vnd.syncml.dm+wbxml',
0x43 => 'application/vnd.syncml.dm+xml',
0x44 => 'application/vnd.syncml.notification',
0x45 => 'application/vnd.wap.xhtml+xml',
0x46 => 'application/vnd.wv.csp.cir',
0x47 => 'application/vnd.oma.dd+xml',
0x48 => 'application/vnd.oma.drm.message',
0x49 => 'application/vnd.oma.drm.content',
0x4A => 'application/vnd.oma.drm.rights+xml',
0x4B => 'application/vnd.oma.drm.rights+wbxml'
);
/*-------------------------------*
* The MMS header decoding class *
*-------------------------------*/
class MMSDecoder {
var $data; // The unparsed MMS data in an array of the ascii numbers
var $pos = 0; // The current parsing position of the data array
var $PARTS = array();
// The parsed data will be saved in these variables
var
$BCC,
$CC,
$CONTENTLOCATION,
$CONTENTTYPE,
$DATE,
$DELIVERYREPORT,
$DELIVERYTIME,
$EXPIRY,
$FROM,
$MESSAGECLASS,
$MESSAGEID,
$MESSAGETYPE,
$MMSVERSIONMAJOR,
$MMSVERSIONMINOR,
$MESSAGESIZE,
$PRIORITY,
$READREPLY,
$REPORTALLOWED,
$RESPONSESTATUS,
$RESPONSETEXT,
$SENDERVISIBILITY,
$STATUS,
$SUBJECT,
$TO,
$TRANSACTIONID,
$MMSVERSIONRAW, // used for the m-send-conf (confirmation answer)
$CONTENTTYPE_PARAMS; // parameter-values for the MMS content-type
// Constructor
function MMSDecoder($data) {
$this->data = array();
// Save the data in an array containing the ascii numbers
for ($i = 0; $i < strlen($data); $i++)
$this->data[$i] = ord($data[$i]);
// Reset position
$this->pos = 0;
// Reset variables
$this->PARTS = array();
}
// This function is called when the data is to be parsed
function parse() {
// Reset position
$this->pos = 0;
// parse the header
while ($this->parseHeader());
// Header done, fetch parts, but make sure the header was parsed correctly
if ($this->CONTENTTYPE == 'application/vnd.wap.multipart.related' || $this->CONTENTTYPE == 'application/vnd.wap.multipart.mixed')
while ($this->parseParts());
else
return 0;
return 1;
}
/*---------------------------------------------------*
* This function checks what kind of field is to be *
* parsed at the moment *
* *
* If true is returned, the class will go on and *
* and continue decode the header. If false, the *
* class will end the header decoding. *
*---------------------------------------------------*/
function parseHeader() {
// Some global variables used
global $mmsMessageTypes, $mmsYesNo, $mmsPriority, $mmsMessageClass, $mmsContentTypes;
if (!array_key_exists($this->pos, $this->data))
return 0;
switch ($this->data[$this->pos++]) {
case BCC:
$this->BCC = $this->parseEncodedStringValue();
if (DEBUG) $this->debug("BCC", $this->BCC);
break;
case CC:
$this->CC = $this->parseEncodedStringValue();
if (DEBUG) $this->debug("CC", $this->CC);
break;
case CONTENT_LOCATION:
$this->CONTENTLOCATION = $this->parseTextString();
if (DEBUG) $this->debug("Content-location", $this->CONTENTLOCATION);
break;
case CONTENT_TYPE:
if ($this->data[$this->pos] <= 31) { /* Content-general-form */
$len = $this->parseValueLength();
// check if next byte is in range of 32-127. Then we have a Extension-media which is a textstring
if ($this->data[$this->pos] > 31 && $this->data[$this->pos] < 128)
$this->CONTENTTYPE = $this->parseTextString();
else {
// we have Well-known-media; which is an integer
$this->CONTENTTYPE = $mmsContentTypes[$this->parseIntegerValue()];
}
} elseif ($this->data[$this->pos] < 128) { /* Constrained-media - Extension-media*/
$this->CONTENTTYPE = $this->parseTextString();
} else /* Constrained-media - Short Integer*/
$this->CONTENTTYPE = $mmsContentTypes[$this->parseShortInteger()];
// Ok, now we have parsed the content-type of the message, let's see if there are any parameters
while (!$noparams) {
switch ($this->data[$this->pos]) {
case 0x89: // Start, textstring
$this->pos++;
$this->parseTextString();
break;
case 0x8A: // type, constrained media
$this->pos++;
if ($this->data[$this->pos] < 128) { /* Constrained-media - Extension-media*/
$this->pos++;
$this->parseTextString();
} else // Constraind-media Short Integer
$this->CONTENTTYPE_PARAMS[type] = $this->parseShortInteger();
break;
default:
$noparams = 1;
break;
}
}
if (DEBUG) $this->debug("Content-type", $this->CONTENTTYPE);
// content-type parsed, that means we have reached the end of the header
return 0;
case DATE: /* In seconds from 1970-01-01 00:00 GMT */
$this->DATE = $this->parseLongInteger();
if (DEBUG) $this->debug("Date", date("Y-m-d H:i:s", $this->DATE));
break;
case DELIVERY_REPORT: /* Yes | No */
$this->DELIVERYREPORT = $mmsYesNo[ $this->data[$this->pos++] ];
if (DEBUG) $this->debug("Delivery-report", $this->DELIVERYREPORT);
break;
case DELIVERY_TIME:
if (DEBUG) $this->debug("Delivery-time", $this->DELIVERYTIME);
break;
case EXPIRY:
// not sure if this is right, but if I remeber right, it's the same format as date...
$this->EXPIRY = parseLongInteger();
if (DEBUG) $this->debug("Expiry", $this->EXPIRY);
break;
case FROM:
$this->FROM = $this->parseEncodedStringValue();
if (DEBUG) $this->debug("From", $this->FROM);
break;
case MESSAGE_CLASS:
$this->MESSAGECLASS = $mmsMessageClass[ $this->parseMessageClassValue() ];
if (DEBUG) $this->debug("Message-class", $this->MESSAGECLASS);
break;
case MESSAGE_ID: /* Text string */
$this->MESSAGEID = $this->parseTextString();
if (DEBUG) $this->debug("Message-id", $this->MESSAGEID);
break;
case MESSAGE_TYPE:
//$this->MESSAGETYPE = $mmsMessageTypes[ $this->data[$this->pos++] ];
$this->MESSAGETYPE = $this->data[$this->pos++];
// check that the message type is m-send-req
if (!$this->MESSAGETYPE = 128)
debug("Wrong type", "The message-type field is not 'm-send-req' (Octet 128)", 1);
if (DEBUG) $this->debug("Message-type", $mmsMessageTypes[$this->MESSAGETYPE]);
break;
case MMS_VERSION:
/*
* The version number (1.0) is encoded as a WSP short integer, which
* is a 7 bit value.
*
* The three most significant bits (001) are used to encode a major
* version number in the range 1-7. The four least significant
* bits (0000) contain a minor version number in the range 1-14.
*/
$this->MMSVERSIONRAW = $this->data[$this->pos];
$this->MMSVERSIONMAJOR = ($this->data[$this->pos] & 0x70) >> 4;
$this->MMSVERSIONMINOR = ($this->data[$this->pos++] & 0x0F);
if (DEBUG) $this->debug("MMS-version", $this->MMSVERSIONMAJOR . "." . $this->MMSVERSIONMINOR);
break;
case MESSAGE_SIZE: /* Long integer */
$this->MESSAGESIZE = $this->parseLongInteger();
if (DEBUG) $this->debug("Message-size", $this->MESSAGESIZE);
break;
case PRIORITY: /* Low | Normal | High */
$this->PRIORITY = $mmsPriority[ $this->data[$this->pos++] ];
if (DEBUG) $this->debug("Priority", $this->PRIORITY);
break;
case READ_REPLY: /* Yes | No */
$this->READREPLY = $mmsYesNo[ $this->data[$this->pos++] ];
if (DEBUG) $this->debug("Read-reply", $this->READREPLY);
break;
case REPORT_ALLOWED: /* Yes | No */
$this->REPORTALLOWED = $mmsYesNo[ $this->data[$this->pos++] ];
if (DEBUG) $this->debug("Report-allowed", $this->REPORTALLOWED);
break;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -