PHP 7bit PDU generator

From D3xt3r01.tk
Revision as of 13:44, 27 January 2011 by Admin (talk | contribs) (→‎SOURCE)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

WHY

Because I needed something to be able to generate PDUs for my GSM modem in PHP. I only did the 7bit part because I wanted the 160 chars and I don't use any weird alphabet. This thing should give you a pretty good idea of how stuff is done !

SOURCE

<?php
function phoneNumberMap($char){
        if($char >= "0" && $char <= "9"){
                return $char;
        }
        switch(strtoupper($char)){
                case "*":
                        return "A";
                        break;
                case "#":
                        return "B";
                        break;
                case "A":
                        return "C";
                        break;
                case "B":
                        return "D";
                        break;
                case "C":
                        return "E";
                        break;
                default:
                        return 'F';
        }
        return "F";
}
function semiOctetToString($string){
        $strlen = strlen($string);
        $out = '';
        for($i=0;$i<$strlen;$i += 2){
                $temp = substr($string, $i, $i+2);
                $out = $out.phoneNumberMap($temp{1}).phoneNumberMap($temp{0});
        }
        return $out;
}
function getSevenBit($char){
        $sevenbitdefault = array('@', '�', '$', '�', '�', '�', '�', '�', '�', '�', '\n', '�', '�', '\r', '�', '�', '\u0394', '_', '\u03a6', '\u0393', '\u039b', '\u03a9', '\u03a0', '\u03a8', '\u03a3', '\u0398', '\u039e', '�', '�', '�', '�', '�', ' ', '!', '"', '#', '�', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7','8', '9', ':', ';', '<', '=', '>', '?', '�', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '�', '�', '�', '�', '�', '�', 'a','b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '�', '�', '�', '�', '�');
        $strlen = count($sevenbitdefault);
        for($i=0;$i<$strlen;$i++){
                if($sevenbitdefault[$i] == $char){
                        return $i;
                }
        }
        return 0;
}
function parseInt($string){
        if(preg_match('/(\d+)/', $string, $array)){
                return $array[1];
        }else{
                return 0;
        }
}
function str2bin($str){
    $out = false;
    for($a=0; $a < strlen($str); $a++) {
        $dec = ord(substr($str,$a,1));
        $bin = '';
        for($i=7; $i>=0; $i--) {
            if ( $dec >= pow(2, $i) ) {
                $bin .= "1";
                $dec -= pow(2, $i);
            } else {
                $bin .= "0";
            }
        }
        $out .= $bin;
    }
    return $out;
}
function intToBin($x, $size){
        $base = "2";
        $num = parseInt($x);
        $bin = decbin($num);
        for($i=strlen($bin);$i<$size;$i++){
                $bin = "0".$bin;
        }
        return $bin;
}
function getEightBit($char){
        return $char;
}
function get16Bit($char){
        return $char;
}
function genPDU($message, $destinationNumber, $smscNumber, $receipt = 0, $validity = 0, $valid_period = "", $mclass = -1){
        // mclass   : -1,0,1,2,3
        // validity : 0,1
        // receipt  : 0,1
        $output = '';
        $octetSecond = '';
        if(strlen($smscNumber) != 0){
                $smsc_number_format = "81";
                if(substr($smscNumber, 0, 1) == "+"){
                        $smsc_number_format = "91";
                        $smscNumber = substr($smscNumber, 1);
                }else if(substr($smscNumber, 0, 1) != "0"){
                        $smsc_number_format = "91";
                }
                if(strlen($smscNumber) % 2 != 0){
                        $smscNumber .= "F";
                }
        }
        $smsc = semiOctetToString($smscNumber);
        $smsc_info_length = strlen($smsc_number_format.$smsc)/2;
        $smsc_length = $smsc_info_length;
        if($smsc_info_length < 10){
                $smsc_info_length = "0".$smsc_info_length;
        }
        if($receipt == 1){
                if($validity == 1){
                        $firstOctet = "3100";
                }else{
                        $firstOctet = "2100";
                }
        }else{
                if($validity == 1){
                        $firstOctet = "1100";
                }else{
                        $firstOctet = "0100";
                }
        }
        if(strlen($destinationNumber) != 0){
                $destination_number_format = "81";
                if(substr($destinationNumber, 0, 1) == "+"){
                        $destination_number_format = "91";
                        $destinationNumber = substr($destinationNumber, 1);
                }else if(substr($destinationNumber, 0, 1) != "0"){
                        $destination_number_format = "91";
                }
                $destination_number_length = dechex(strlen($destinationNumber));
                if(strlen($destinationNumber) % 2 != 0){
                        $destinationNumber .= "F";
                }
        }
        if(strlen($destination_number_length) < 10){
                $destination_number_length = "0".$destination_number_length;
        }
        $destinationNumber = semiOctetToString($destinationNumber);
        $proto_id = '00';
        $dcs = 0;
        if($mclass != "-1"){
                $dcs = $mclass+16;
        }
        $data_encoding = dechex($dcs);
        if(strlen($data_encoding) == 1){
                $data_encoding = "0".$data_encoding;
        }
        if($validity == 1){
                $valid_period = dechex($valid_period);
        }
        $user_data_size = base_convert(strlen($message), 10, 16);
        if(strlen($user_data_size) == 1){
                $user_data_size = "0".$user_data_size;
        }
        $strlen = strlen($message);
        $octetSecond = '';
        for($i=0;$i<=$strlen;$i++){
                if($i == $strlen){
                        if($octetSecond != ""){
                                $b2d = dechex(bindec($octetSecond));
                                if(strlen($b2d) == 1){
                                        $b2d = "0".$b2d;
                                }
                                $output = $output.$b2d;
                        }
                        break;
                }
                $current = intToBin(getSevenBit($message{$i}), 7);
                if($i != 0 && $i % 8 != 0){
                        $octetFirst = substr($current,7-($i)%8);
                        $currentOctet = $octetFirst.$octetSecond;
                        $d2h = dechex(bindec($currentOctet));
                        if(strlen($d2h) == 1){
                                $d2h = "0".$d2h;
                        }
                        $output = $output.$d2h;
                        $octetSecond = substr($current,0,7-($i)%8);
                }else{
                        $octetSecond = substr($current,0,7-($i)%8);
                }
        }
        $header = strtoupper($smsc_info_length.$smsc_number_format.$smsc.$firstOctet.$destination_number_length.$destination_number_format.$destinationNumber.$proto_id.$data_encoding.$valid_period.$user_data_size);
        $pdu = $header.$output;
        echo "HEADER:\n";
        echo "Smsc Info Length: ".$smsc_info_length."\n";
        echo "Smsc Number Format: ".$smsc_number_format."\n";
        echo "Smsc: ".$smsc."\n";
        echo "FirstOctet: ".$firstOctet."\n";
        echo "Destination Number Length: ".$destination_number_length."\n";
        echo "Destination Number Format: ".$destination_number_format."\n";
        echo "Destination Number: ".$destinationNumber."\n";
        echo "Proto ID: ".$proto_id."\n";
        echo "Data Encoding: ".$data_encoding."\n";
        echo "Valid Period: ".$valid_period."\n";
        echo "User Data Size: ".$user_data_size."\n";
        echo "------------------\n";
        echo "DCS: ".$dcs."\n";
        echo "Header: ".$header."\n";
        echo "Output: ".$output."\n";
        echo "PDU: ".strtoupper($pdu)."\n";
        echo "AT+CMGS=".(strlen($pdu)/2 - $smsc_length -1)."\n";
}

genPDU($argv[1], "0760905294", "+40766000510", 0, 0, "", 0);
?>

THANKS

Big THANKS go to Rednaxela's Javascript PDU converter.