I have installed Mosquitto on the server, and it's running, and working fine.
I have installed Paho mqtt client plugin to check.
and I wrote the code for android and it's working fine on the emulator.
now in my own computer everything works fine, I run the php code and my app in android receives the message and Paho client receives that message too.
but when I upload the file on the server and run it nothing happens, although the php code runs everything successfully, and publishes the message without any error.
and even the mosquitto's publisher executable works fine and clients receive the message.
only this php code on the server doesn't do anything.
$mqtt = new phpMQTT("localhost", 1883, "server");
if ($mqtt->connect()) {
echo"connected\n";
for($i=0;$i<4;++$i){
if($mqtt->publish("new","Hey . ".$i,2)){
echo "published\n";
}
else{
echo "not published\n";
}
}
$mqtt->close();
}
else{
echo"couldn't connect\n";
}
Bluerhinos phpMQTT:
<?php
/* phpMQTT */
class phpMQTT {
private $socket; /* holds the socket */
private $msgid = 1; /* counter for message id */
public $keepalive = 10; /* default keepalive timmer */
public $timesinceping; /* host unix time, used to detect disconects */
public $topics = array(); /* used to store currently subscribed topics */
public $debug = true; /* should output debug messages */
public $address; /* broker address */
public $port; /* broker port */
public $clientid; /* client id sent to brocker */
public $will; /* stores the will of the client */
private $username; /* stores username */
private $password; /* stores password */
function __construct($address, $port, $clientid){
$this->broker($address, $port, $clientid);
}
/* sets the broker details */
function broker($address, $port, $clientid){
$this->address = $address;
$this->port = $port;
$this->clientid = $clientid;
}
/* connects to the broker
inputs: $clean: should the client send a clean session flag */
function connect($clean = true, $will = NULL, $username = NULL, $password = NULL){
if($will) $this->will = $will;
if($username) $this->username = $username;
if($password) $this->password = $password;
$address = $this->address;
$this->socket = fsockopen($address, $this->port, $errno, $errstr, 60);
if (!$this->socket ) {
error_log("fsockopen() $errno, $errstr \n");
return false;
}
stream_set_timeout($this->socket, 5);
stream_set_blocking($this->socket, 0);
$i = 0;
$buffer = "";
$buffer .= chr(0x00); $i++;
$buffer .= chr(0x06); $i++;
$buffer .= chr(0x4d); $i++;
$buffer .= chr(0x51); $i++;
$buffer .= chr(0x49); $i++;
$buffer .= chr(0x73); $i++;
$buffer .= chr(0x64); $i++;
$buffer .= chr(0x70); $i++;
$buffer .= chr(0x03); $i++;
//No Will
$var = 0;
if($clean) $var+=2;
//Add will info to header
if($this->will != NULL){
$var += 4; // Set will flag
$var += ($this->will['qos'] << 3); //Set will qos
if($this->will['retain']) $var += 32; //Set will retain
}
if($this->username != NULL) $var += 128; //Add username to header
if($this->password != NULL) $var += 64; //Add password to header
$buffer .= chr($var); $i++;
//Keep alive
$buffer .= chr($this->keepalive >> 8); $i++;
$buffer .= chr($this->keepalive & 0xff); $i++;
$buffer .= $this->strwritestring($this->clientid,$i);
//Adding will to payload
if($this->will != NULL){
$buffer .= $this->strwritestring($this->will['topic'],$i);
$buffer .= $this->strwritestring($this->will['content'],$i);
}
if($this->username) $buffer .= $this->strwritestring($this->username,$i);
if($this->password) $buffer .= $this->strwritestring($this->password,$i);
$head = " ";
$head{0} = chr(0x10);
$head{1} = chr($i);
fwrite($this->socket, $head, 2);
fwrite($this->socket, $buffer);
$string = $this->read(4);
if(ord($string{0})>>4 == 2 && $string{3} == chr(0)){
if($this->debug) echo "Connected to Broker\n";
}else{
error_log(sprintf("Connection failed! (Error: 0x%02x 0x%02x)\n",
ord($string{0}),ord($string{3})));
return false;
}
$this->timesinceping = time();
return true;
}
/* read: reads in so many bytes */
function read($int = 8192, $nb = false){
// print_r(socket_get_status($this->socket));
$string="";
$togo = $int;
if($nb){
return fread($this->socket, $togo);
}
while (!feof($this->socket) && $togo>0) {
$fread = fread($this->socket, $togo);
$string .= $fread;
$togo = $int - strlen($string);
}
return $string;
}
/* subscribe: subscribes to topics */
function subscribe($topics, $qos = 0){
$i = 0;
$buffer = "";
$id = $this->msgid;
$buffer .= chr($id >> 8); $i++;
$buffer .= chr($id % 256); $i++;
foreach($topics as $key => $topic){
$buffer .= $this->strwritestring($key,$i);
$buffer .= chr($topic["qos"]); $i++;
$this->topics[$key] = $topic;
}
$cmd = 0x80;
//$qos
$cmd += ($qos << 1);
$head = chr($cmd);
$head .= chr($i);
fwrite($this->socket, $head, 2);
fwrite($this->socket, $buffer, $i);
$string = $this->read(2);
$bytes = ord(substr($string,1,1));
$string = $this->read($bytes);
}
/* ping: sends a keep alive ping */
function ping(){
$head = " ";
$head = chr(0xc0);
$head .= chr(0x00);
fwrite($this->socket, $head, 2);
if($this->debug) echo "ping sent\n";
}
/* disconnect: sends a proper disconect cmd */
function disconnect(){
$head = " ";
$head{0} = chr(0xe0);
$head{1} = chr(0x00);
fwrite($this->socket, $head, 2);
}
/* close: sends a proper disconect, then closes the socket */
function close(){
$this->disconnect();
fclose($this->socket);
}
/* publish: publishes $content on a $topic */
function publish($topic, $content, $qos = 0, $retain = 0){
$i = 0;
$buffer = "";
$buffer .= $this->strwritestring($topic,$i);
//$buffer .= $this->strwritestring($content,$i);
if($qos){
$id = $this->msgid++;
$buffer .= chr($id >> 8); $i++;
$buffer .= chr($id % 256); $i++;
}
$buffer .= $content;
$i+=strlen($content);
$head = " ";
$cmd = 0x30;
if($qos) $cmd += $qos << 1;
if($retain) $cmd += 1;
$head{0} = chr($cmd);
$head .= $this->setmsglength($i);
if((fwrite($this->socket, $head, strlen($head)))&&(fwrite($this->socket, $buffer, $i))){
echo "done: ".$this->socket."<br>";
return true;
}
else {
echo $head;
return false;
}
}
/* message: processes a recieved topic */
function message($msg){
$tlen = (ord($msg{0})<<8) + ord($msg{1});
$topic = substr($msg,2,$tlen);
$msg = substr($msg,($tlen+2));
$found = 0;
foreach($this->topics as $key=>$top){
if( preg_match("/^".str_replace("#",".*",
str_replace("+","[^\/]*",
str_replace("/","\/",
str_replace("$",'\$',
$key))))."$/",$topic) ){
if(function_exists($top['function'])){
call_user_func($top['function'],$topic,$msg);
$found = 1;
}
}
}
if($this->debug && !$found) echo "msg recieved but no match in subscriptions\n";
}
/* proc: the processing loop for an "allways on" client
set true when you are doing other stuff in the loop good for watching something else at the same time */
function proc( $loop = true){
if(1){
$sockets = array($this->socket);
$w = $e = NULL;
$cmd = 0;
//$byte = fgetc($this->socket);
if(feof($this->socket)){
if($this->debug) echo "eof receive going to reconnect for good measure\n";
fclose($this->socket);
$this->connect(false);
if(count($this->topics))
$this->subscribe($this->topics);
}
$byte = $this->read(1, true);
if(!strlen($byte)){
if($loop){
usleep(100000);
}
}else{
$cmd = (int)(ord($byte)/16);
if($this->debug) echo "Recevid: $cmd\n";
$multiplier = 1;
$value = 0;
do{
$digit = ord($this->read(1));
$value += ($digit & 127) * $multiplier;
$multiplier *= 128;
}while (($digit & 128) != 0);
if($this->debug) echo "Fetching: $value\n";
if($value)
$string = $this->read($value,"fetch");
if($cmd){
switch($cmd){
case 3:
$this->message($string);
break;
}
$this->timesinceping = time();
}
}
if($this->timesinceping < (time() - $this->keepalive )){
if($this->debug) echo "not found something so ping\n";
$this->ping();
}
if($this->timesinceping<(time()-($this->keepalive*2))){
if($this->debug) echo "not seen a package in a while, disconnecting\n";
fclose($this->socket);
$this->connect(false);
if(count($this->topics))
$this->subscribe($this->topics);
}
}
return 1;
}
/* getmsglength: */
function getmsglength(&$msg, &$i){
$multiplier = 1;
$value = 0 ;
do{
$digit = ord($msg{$i});
$value += ($digit & 127) * $multiplier;
$multiplier *= 128;
$i++;
}while (($digit & 128) != 0);
return $value;
}
/* setmsglength: */
function setmsglength($len){
$string = "";
do{
$digit = $len % 128;
$len = $len >> 7;
// if there are more digits to encode, set the top bit of this digit
if ( $len > 0 )
$digit = ($digit | 0x80);
$string .= chr($digit);
}while ( $len > 0 );
return $string;
}
/* strwritestring: writes a string to a buffer */
function strwritestring($str, &$i){
$ret = " ";
$len = strlen($str);
$msb = $len >> 8;
$lsb = $len % 256;
$ret = chr($msb);
$ret .= chr($lsb);
$ret .= $str;
$i += ($len+2);
return $ret;
}
function printstr($string){
$strlen = strlen($string);
for($j=0;$j<$strlen;$j++){
$num = ord($string{$j});
if($num > 31)
$chr = $string{$j}; else $chr = " ";
printf("%4d: %08b : 0x%02x : %s \n",$j,$num,$num,$chr);
}
}
}
?>
Follow this library publish example and see what happens both logs: the localhost broker and the php log
https://github.com/bluerhinos/phpMQTT/blob/master/examples/publish.php
Related
I trying to make some simple library for encrypting files in PHP with OTP method. My problem is that some chars in decrypted code are different than original. I worked on it almost one week but without result. Is there problem with base64 chars or with encoding/decoding mechanism ?
Many thanks for the answers.
final class Otp
{
private static $charSet = array('+','/','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');
public static function encryptFile($originalFilePath, $encryptedFilePath, $keyFilePath)
{
if(!self::existsFile($keyFilePath) || !self::existsFile($encryptedFilePath)) {
if($originalFileData = self::existsFile($originalFilePath)) {
$originalFileBase64Data = base64_encode($originalFileData);
$originalFileBase64DataLength = strlen($originalFileBase64Data) - 1;
$originalFileBase64DataArray = str_split($originalFileBase64Data);
$encryptedData = NULL;
$encryptedDataKey = NULL;
for ($i = 0; $i <= $originalFileBase64DataLength; $i++) {
$randKey = rand(0, sizeOf(self::$charSet) - 1);
$arrayKey = array_search($originalFileBase64DataArray[$i], self::$charSet);
if($randKey > $arrayKey) {
$str = '-' . ($randKey - $arrayKey);
} elseif($randKey < $arrayKey) {
$str = ($randKey + $arrayKey);
} else {
$str = $randKey;
}
$encryptedData .= self::$charSet[$randKey];
$encryptedDataKey .= $str. ';';
}
$encryptedDataString = $encryptedData;
$encryptedDataKeyString = $encryptedDataKey;
if(!self::existsFile($keyFilePath)) {
file_put_contents($keyFilePath, $encryptedDataKeyString);
}
if(!self::existsFile($encryptedFilePath)) {
file_put_contents($encryptedFilePath, $encryptedDataString);
}
return 'OK';
} else {
return 'Source file not exists';
}
} else {
return 'Encrypted data already exists';
}
}
public static function decryptFile($encryptedFilePath, $keyFilePath, $decryptedFilePath)
{
$keyFileData = self::existsFile($keyFilePath);
$encryptedFileData = self::existsFile($encryptedFilePath);
$encryptedFileDataLength = strlen($encryptedFileData) - 1;
if($encryptedFileData && $keyFileData) {
$encryptedFileDataArray = str_split($encryptedFileData);
$keyFileDataArray = explode(';', $keyFileData);
$decryptedData = NULL;
for ($i = 0; $i <= $encryptedFileDataLength; $i++) {
$poziciaaktualneho = array_search($encryptedFileDataArray[$i], self::$charSet);
$poziciasifrovana = $keyFileDataArray[$i];
if($poziciasifrovana < 0) {
$move = $poziciasifrovana + $poziciaaktualneho;
} elseif($poziciasifrovana > 0) {
$move = $poziciasifrovana - $poziciaaktualneho;
} else {
$move = '0';
}
$decryptedData .= self::$charSet[$move];
}
if(!self::existsFile($decryptedFilePath)) {
file_put_contents($decryptedFilePath, base64_decode($decryptedData));
return 'OK';
} else {
return 'Decrypted data already exists';
}
}
}
private static function existsFile($filePath)
{
$fileData = #file_get_contents($filePath);
if($fileData) {
return $fileData;
}
return FALSE;
}
}
$originalFilePath = 'original.jpg';
$keyFilePath = 'Otp_Key_' . $originalFilePath;
$encryptedFilePath = 'Otp_Data_' . $originalFilePath;
$decryptedFilePath = 'Otp_Decrypted_' . $originalFilePath;
echo Otp::encryptFile($originalFilePath, $encryptedFilePath, $keyFilePath);
echo Otp::decryptFile($encryptedFilePath, $keyFilePath, $decryptedFilePath);
The problem seems to be only happening when $poziciaaktualneho is equal to $poziciasifrovana and so by adding another if statement on line 78 to check for this and instead set $move equal to $poziciasifrovana I was able to fix the problem. The below script should work:
final class Otp
{
private static $charSet = array('+','/','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');
public static function encryptFile($originalFilePath, $encryptedFilePath, $keyFilePath)
{
if(!self::existsFile($keyFilePath) || !self::existsFile($encryptedFilePath)) {
if($originalFileData = self::existsFile($originalFilePath)) {
$originalFileBase64Data = base64_encode($originalFileData);
$originalFileBase64DataLength = strlen($originalFileBase64Data) - 1;
$originalFileBase64DataArray = str_split($originalFileBase64Data);
$encryptedData = NULL;
$encryptedDataKey = NULL;
for ($i = 0; $i <= $originalFileBase64DataLength; $i++) {
$randKey = rand(0, sizeOf(self::$charSet) - 1);
$arrayKey = array_search($originalFileBase64DataArray[$i], self::$charSet);
if($randKey > $arrayKey) {
$str = '-' . ($randKey - $arrayKey);
} elseif($randKey < $arrayKey) {
$str = ($randKey + $arrayKey);
} else {
$str = $randKey;
}
$encryptedData .= self::$charSet[$randKey];
$encryptedDataKey .= $str. ';';
}
$encryptedDataString = $encryptedData;
$encryptedDataKeyString = $encryptedDataKey;
if(!self::existsFile($keyFilePath)) {
file_put_contents($keyFilePath, $encryptedDataKeyString);
}
if(!self::existsFile($encryptedFilePath)) {
file_put_contents($encryptedFilePath, $encryptedDataString);
}
return 'OK';
} else {
return 'Source file not exists';
}
} else {
return 'Encrypted data already exists';
}
}
public static function decryptFile($encryptedFilePath, $keyFilePath, $decryptedFilePath)
{
$keyFileData = self::existsFile($keyFilePath);
$encryptedFileData = self::existsFile($encryptedFilePath);
$encryptedFileDataLength = strlen($encryptedFileData) - 1;
if($encryptedFileData && $keyFileData) {
$encryptedFileDataArray = str_split($encryptedFileData);
$keyFileDataArray = explode(';', $keyFileData);
$decryptedData = NULL;
for ($i = 0; $i <= $encryptedFileDataLength; $i++) {
$poziciaaktualneho = array_search($encryptedFileDataArray[$i], self::$charSet);
$poziciasifrovana = $keyFileDataArray[$i];
if ($poziciasifrovana == $poziciaaktualneho) {
$move = $poziciasifrovana;
} elseif($poziciasifrovana < 0) {
$move = $poziciasifrovana + $poziciaaktualneho;
} elseif($poziciasifrovana > 0) {
$move = $poziciasifrovana - $poziciaaktualneho;
} else {
$move = '0';
}
$decryptedData .= self::$charSet[$move];
}
if(!self::existsFile($decryptedFilePath)) {
file_put_contents($decryptedFilePath, base64_decode($decryptedData));
return 'OK';
} else {
return 'Decrypted data already exists';
}
}
}
private static function existsFile($filePath)
{
$fileData = #file_get_contents($filePath);
if($fileData) {
return $fileData;
}
return FALSE;
}
}
$originalFilePath = 'original.jpg';
$keyFilePath = 'Otp_Key_' . $originalFilePath;
$encryptedFilePath = 'Otp_Data_' . $originalFilePath;
$decryptedFilePath = 'Otp_Decrypted_' . $originalFilePath;
echo Otp::encryptFile($originalFilePath, $encryptedFilePath, $keyFilePath);
echo Otp::decryptFile($encryptedFilePath, $keyFilePath, $decryptedFilePath);
Warning: I would not recommend using my solution in an enterprise setting if at all since I do not know why this fixes your script or what was
originally wrong with it and it is most likely not air tight.
I'm trying to scrape Amazon ASIN codes using the below code:
<?php
class Scraper {
const BASE_URL = "http://www.amazon.com";
private $categoryFile = "";
private $outputFile = "";
private $catArray;
private $currentPage = NULL;
private $asin = array();
private $categoriesMatched = 0;
private $categoryProducts = array();
private $pagesMatched = 0;
private $totalPagesMatched = 0;
private $productsMatched = 0;
public function __construct($categoryFile, $outputFile) {
$this->categoryFile = $categoryFile;
$this->outputFile = $outputFile;
}
public function run() {
$this->readCategories($this->categoryFile);
$this->setupASINArray($this->asin);
$x = 1;
foreach ($this->catArray as $cat) {
$this->categoryProducts["$x"] = 0;
if ($this->currentPage == NULL) {
$this->currentPage = $cat;
$this->scrapeASIN($this->currentPage, $x);
$this->pagesMatched++;
}
if ($this->getNextPageLink($this->currentPage)) {
do {
// next page found
$this->pagesMatched++;
$this->scrapeASIN($this->currentPage, $x);
} while ($this->getNextPageLink($this->currentPage));
}
echo "Category complete: $this->pagesMatched Pages" . "\n";
$this->totalPagesMatched += $this->pagesMatched;
$this->pagesMatched = 0;
$this->writeASIN($this->outputFile, $x);
$x++;
$this->currentPage = NULL;
$this->categoriesMatched++;
}
$this->returnStats();
}
private function readCategories($categoryFile) {
$catArray = file($categoryFile, FILE_IGNORE_NEW_LINES);
$this->catArray = $catArray;
}
private function setupASINArray($asinArray) {
$x = 0;
foreach ($this->catArray as $cat) {
$asinArray["$x"][0] = "$cat";
$x++;
}
$this->asin = $asinArray;
}
private function getNextPageLink($currentPage) {
$document = new DOMDocument();
$html = file_get_contents($currentPage);
#$document->loadHTML($html);
$xpath = new DOMXPath($document);
$element = $xpath->query("//a[#id='pagnNextLink']/#href");
if ($element->length != 0) {
$this->currentPage = self::BASE_URL . $element->item(0)->value;
return true;
} else {
return false;
}
}
private function scrapeASIN($currentPage, $catNo) {
$html = file_get_contents($currentPage);
$regex = '~(?:www\.)?ama?zo?n\.(?:com|ca|co\.uk|co\.jp|de|fr)/(?:exec/obidos/ASIN/|o/|gp/product/|(?:(?:[^"\'/]*)/)?dp/|)(B[A-Z0-9]{9})(?:(?:/|\?|\#)(?:[^"\'\s]*))?~isx';
preg_match_all($regex, $html, $asin);
foreach ($asin[1] as $match) {
$this->asin[$catNo-1][] = $match;
}
}
private function writeASIN($outputFile, $catNo) {
$fh = fopen($outputFile, "a+");
$this->fixDupes($catNo);
$this->productsMatched += (count($this->asin[$catNo-1]) - 1);
$this->categoryProducts["$catNo"] = (count($this->asin[$catNo-1]) - 1);
flock($fh, LOCK_EX);
$x = 0;
foreach ($this->asin[$catNo-1] as $asin) {
fwrite($fh, "$asin" . "\n");
$x++;
}
flock($fh, LOCK_UN);
fclose($fh);
$x -= 1;
echo "$x ASIN codes written to file" . "\n";
}
private function fixDupes($catNo) {
$this->asin[$catNo-1] = array_unique($this->asin[$catNo-1], SORT_STRING);
}
public function returnStats() {
echo "Categories matched: " . $this->categoriesMatched . "\n";
echo "Pages parsed: " . $this->totalPagesMatched . "\n";
echo "Products parsed: " . $this->productsMatched . "\n";
echo "Category breakdown:" . "\n";
$x = 1;
foreach ($this->categoryProducts as $catProds) {
echo "Category $x had $catProds products" . "\n";
$x++;
}
}
}
$scraper = new Scraper($argv[1], $argv[2]);
$scraper->run();
?>
But it works fine on XAMPP on Windows but not on Linux. Any ideas as to why this may be? Sometimes it scrapes 0 ASIN's to file, sometimes it only scrapes 1 page in a category of 400+ pages. But the output/functionality is totally fine in Windows/XAMPP.
Any thoughts would be greatly appreciated!
Cheers
- Bryce
So try to change this way, just to avoid the error messages:
private function readCategories($categoryFile) {
if (file_exists($categoryFile)) {
$catArray = file($categoryFile, FILE_IGNORE_NEW_LINES);
$this->catArray = $catArray;
} else {
echo "File ".$categoryFile.' not exists!';
$this->catArray = array();
}
}
I found a script which can extract the artist & title name from an Icecast or Shoutcast stream.
I want the script to update automatically when a song changed, at the moment its working only when i execute it. I'm new to PHP so any help will be appreciated.
Thanks!
define('CRLF', "\r\n");
class streaminfo{
public $valid = false;
public $useragent = 'Winamp 2.81';
protected $headers = array();
protected $metadata = array();
public function __construct($location){
$errno = $errstr = '';
$t = parse_url($location);
$sock = fsockopen($t['host'], $t['port'], $errno, $errstr, 5);
$path = isset($t['path'])?$t['path']:'/';
if ($sock){
$request = 'GET '.$path.' HTTP/1.0' . CRLF .
'Host: ' . $t['host'] . CRLF .
'Connection: Close' . CRLF .
'User-Agent: ' . $this->useragent . CRLF .
'Accept: */*' . CRLF .
'icy-metadata: 1'.CRLF.
'icy-prebuffer: 65536'.CRLF.
(isset($t['user'])?'Authorization: Basic '.base64_encode($t['user'].':'.$t['pass']).CRLF:'').
'X-TipOfTheDay: Winamp "Classic" rulez all of them.' . CRLF . CRLF;
if (fwrite($sock, $request)){
$theaders = $line = '';
while (!feof($sock)){
$line = fgets($sock, 4096);
if('' == trim($line)){
break;
}
$theaders .= $line;
}
$theaders = explode(CRLF, $theaders);
foreach ($theaders as $header){
$t = explode(':', $header);
if (isset($t[0]) && trim($t[0]) != ''){
$name = preg_replace('/[^a-z][^a-z0-9]*/i','', strtolower(trim($t[0])));
array_shift($t);
$value = trim(implode(':', $t));
if ($value != ''){
if (is_numeric($value)){
$this->headers[$name] = (int)$value;
}else{
$this->headers[$name] = $value;
}
}
}
}
if (!isset($this->headers['icymetaint'])){
$data = ''; $metainterval = 512;
while(!feof($sock)){
$data .= fgetc($sock);
if (strlen($data) >= $metainterval) break;
}
$this->print_data($data);
$matches = array();
preg_match_all('/([\x00-\xff]{2})\x0\x0([a-z]+)=/i', $data, $matches, PREG_OFFSET_CAPTURE);
preg_match_all('/([a-z]+)=([a-z0-9\(\)\[\]., ]+)/i', $data, $matches, PREG_SPLIT_NO_EMPTY);
echo '<pre>';var_dump($matches);echo '</pre>';
$title = $artist = '';
foreach ($matches[0] as $nr => $values){
$offset = $values[1];
$length = ord($values[0]{0}) +
(ord($values[0]{1}) * 256)+
(ord($values[0]{2}) * 256*256)+
(ord($values[0]{3}) * 256*256*256);
$info = substr($data, $offset + 4, $length);
$seperator = strpos($info, '=');
$this->metadata[substr($info, 0, $seperator)] = substr($info, $seperator + 1);
if (substr($info, 0, $seperator) == 'title') $title = substr($info, $seperator + 1);
if (substr($info, 0, $seperator) == 'artist') $artist = substr($info, $seperator + 1);
}
$this->metadata['streamtitle'] = $artist . ' - ' . $title;
}else{
$metainterval = $this->headers['icymetaint'];
$intervals = 0;
$metadata = '';
while(1){
$data = '';
while(!feof($sock)){
$data .= fgetc($sock);
if (strlen($data) >= $metainterval) break;
}
//$this->print_data($data);
$len = join(unpack('c', fgetc($sock))) * 16;
if ($len > 0){
$metadata = str_replace("\0", '', fread($sock, $len));
break;
}else{
$intervals++;
if ($intervals > 100) break;
}
}
$metarr = explode(';', $metadata);
foreach ($metarr as $meta){
$t = explode('=', $meta);
if (isset($t[0]) && trim($t[0]) != ''){
$name = preg_replace('/[^a-z][^a-z0-9]*/i','', strtolower(trim($t[0])));
array_shift($t);
$value = trim(implode('=', $t));
if (substr($value, 0, 1) == '"' || substr($value, 0, 1) == "'"){
$value = substr($value, 1);
}
if (substr($value, -1) == '"' || substr($value, -1) == "'"){
$value = substr($value, 0, -1);
}
if ($value != ''){
$this->metadata[$name] = $value;
}
}
}
}
fclose($sock);
$this->valid = true;
}else echo 'unable to write.';
}else echo 'no socket '.$errno.' - '.$errstr.'.';
}
public function print_data($data){
$data = str_split($data);
$c = 0;
$string = '';
echo "<pre>\n000000 ";
foreach ($data as $char){
$string .= addcslashes($char, "\n\r\0\t");
$hex = dechex(join(unpack('C', $char)));
if ($c % 4 == 0) echo ' ';
if ($c % (4*4) == 0 && $c != 0){
foreach (str_split($string) as $s){
//echo " $string\n";
if (ord($s) < 32 || ord($s) > 126){
echo '\\'.ord($s);
}else{
echo $s;
}
}
echo "\n";
$string = '';
echo str_pad($c, 6, '0', STR_PAD_LEFT).' ';
}
if (strlen($hex) < 1) $hex = '00';
if (strlen($hex) < 2) $hex = '0'.$hex;
echo $hex.' ';
$c++;
}
echo " $string\n</pre>";
}
public function __get($name){
if (isset($this->metadata[$name])){
return $this->metadata[$name];
}
if (isset($this->headers[$name])){
return $this->headers[$name];
}
return null;
}
}
$t = new streaminfo('http://64.236.34.196:80/stream/1014'); // get metadata
echo Meta Interval: $t->icymetaint;
echo Current Track: $t->streamtitle;
You will need to constantly query the stream at a set interval to find when the song changes.
This can be best done by scheduling a cron job.
If on Windows, you should use the Windows Task Scheduler
If you want to run the PHP script to keep your meta data up to date (I'm assuming you're making a website and using html audio tags here) you can use the ontimeupdate event with an ajax function. If you're not you probably should look up your audio playback documentation for something similar.
<audio src="http://ip:port/;" ontimeupdate="loadXMLDoc()">
You can find a great example here http://www.w3schools.com/php/php_ajax_php.asp
You want to use the PHP echo function all the relevant information at once using one php variable at the very end of your script.
<?php ....
$phpVar=$streamtitle;
$phpVar2=$streamsong;
$result="I want my string to look like this: <br> {$phpVar} {$phpVar2}";
echo $result;
?>
and then use the function called by the .onreadystatechange to modify the particular elements you want on your website by using the .resonseText (this will contain the same content as your PHP script's echo).
After SCOURING the web for 4 hours, this is the only Shoutcast metadata script I've found that works! Thankyou.
To run this constantly, why not use a setInterval combined with jQuery's AJAX call?
<script>
$(function() {
setInterval(getTrackName,16000);
});
function getTrackName() {
$.ajax({
url: "track_name.php"
})
.done(function( data ) {
$( "#results" ).text( data );
});
}
</script>
Also your last couple 'echo' lines were breaking the script for me. Just put quotes around the Meta Interval, etc....
I wrote a WebSocket Server in PHP, which connects to Firefox well but not to Safari. I think, there's something wrong with the handshake. Safari needs the older draft hybi00... but I can't find the mistake :/
The connection closed in Safari directly after trying to connect.
Thanks in advance for your help!
<?php
error_reporting(E_ALL);
set_time_limit(0);
date_default_timezone_set("Europe/Berlin");
ob_implicit_flush(true);
function debug($text)
{
$file = "log.html";
file_put_contents($file,
"<pre>".$text."</pre>"."<b>Ende der Information</b><p />", 8);
}
//Socket initialisieren
$master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($master, SOL_SOCKET, SO_REUSEADDR, 1);
//An diesen Computer binden
socket_bind($master, "localhost", 10000) or die();
//Maximale Verbindungsanforderungen: 5
socket_listen($master, 5);
do
{
$client = socket_accept($master);
echo "Neuer Client!\n";
new Client($client);
} while(true);
exit();
//Clientklasse
class Client
{
private $connection;
private $header = array();
private $crypt; //BOOL, hybi00 needs no en-/decryption but hybi06+
function __construct(&$socket)
{
$this->connection = $socket;
$this->SetWebSecKey();
while(true)
{
$q = socket_read($this->connection, 1024);
if(isset($q))
{
echo $this->unmask($q);
}
$welcome = "\x81\x8c\xff\xb8\xbd\xbd\xb7\xdd\xd1\xd1\x90\x98\xea\xd2\x8d\xd4\xd9\x9c";
}
}
/**
* Unmask a received payload
* #param $payload
*
* http://srchea.com/blog/2011/12/build-a-real-time-application-using-html5-websockets/
*/
private function unmask($payload) {
$length = ord($payload[1]) & 127;
if($length == 126) {
$masks = substr($payload, 4, 4);
$data = substr($payload, 8);
}
elseif($length == 127) {
$masks = substr($payload, 10, 4);
$data = substr($payload, 14);
}
else {
$masks = substr($payload, 2, 4);
$data = substr($payload, 6);
}
$text = '';
for ($i = 0; $i < strlen($data); ++$i) {
$text .= $data[$i] ^ $masks[$i%4];
}
return $text;
}
/**
* Encode a text for sending to clients via ws://
* #param $text
*
* http://srchea.com/blog/2011/12/build-a-real-time-application-using-html5-websockets/
*/
private function encode($text)
{
// 0x1 text frame (FIN + opcode)
$b1 = 0x80 | (0x1 & 0x0f);
$length = strlen($text);
if($length <= 125)
$header = pack('CC', $b1, $length);
elseif($length > 125 && $length < 65536)
$header = pack('CCS', $b1, 126, $length);
elseif($length >= 65536)
$header = pack('CCN', $b1, 127, $length);
return $header.$text;
}
private function SetWebSecKey()
{
//Headerrequest in Array teilen
$request = socket_read($this->connection, 1024);
$request = explode("\n", $request);
foreach($request as $key=>$head)
{
$header = explode(":", $head, 2);
$header[0] = trim($header[0]); //Parameter
$header[1] = trim($header[1]); //Wert
$this->header[$header[0]] = $header[1];
}
$handshake = new Handshake($this->header);
$handshake->Send($this->connection);
}
private function SendPlain($text)
{
socket_write($this->connection, $text, strlen($text));
}
}
class Handshake
{
private $header;
private $hybi00;
private $secKey;
public function __construct($headerArray)
{
echo "\nHandshake wird ausgeführt: ";
//Einfacher oder doppelter SecWebKey?
//Einfach: Hybi06+
//Doppelt: Hybi00+
$this->header = $headerArray;
if(isset($this->header["Sec-WebSocket-Key"]))
{
echo "Hybi06+\n";
//Moderner Hybi06+
$this->secKey = $this->InitHybi06();
} elseif(isset($this->header["Sec-WebSocket-Key1"])) {
//Älterer Hybi00+
echo "Hybi00+\n";
$this->secKey = $this->InitHybi00();
} else {
echo "Fehler - Unbekanntes WebSocket-Protokoll\n";
return;
}
}
private function InitHybi06()
{
$this->hybi00 = false;
$key = $this->header["Sec-WebSocket-Key"];
$GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
$key .= $GUID;
return base64_encode(sha1($key, true));
}
private function InitHybi00()
{
$this->hybi00 = true;
$key1 = $this->header["Sec-WebSocket-Key1"];
$key2 = $this->header["Sec-WebSocket-Key2"];
$key1 = $this->Hybi00NumSpace($key1);
$key2 = $this->Hybi00NumSpace($key2);
$data = array_keys($this->header);
$data = $data[count($this->header)-1];
$ctx = hash_init('md5');
hash_update($ctx, pack("N", $key1));
hash_update($ctx, pack("N", $key2));
hash_update($ctx, $data);
$hash_data = hash_final($ctx,true);
return $hash_data;
}
private function Hybi00NumSpace($key)
{
$numbrs = preg_replace('/[^\d]*/', '', $key);
$spaces = strlen(preg_replace('/[^\s][^\s]*/', '', $key));
return $numbrs/$spaces;
}
public function Send($socket, $origin="http://localhost", $location="ws://localhost", $return=false)
{
if(!isset($this->header) || !isset($this->hybi00) || !isset($this->secKey))
{
echo "Fehler: Handshake nicht vollständig!\n"; return;
}
$header = $this->CreateHeader($origin, $location);
debug($header);
$header = explode("\n", $header);
if($return)
return $header;
foreach($header as $line)
{
$line .= "\n";
socket_write($socket, $line, strlen($line));
}
}
private function CreateHeader($origin, $location)
{
$header = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n".
"Upgrade: WebSocket\r\n".
"Connection: Upgrade\r\n".
"Sec-WebSocket-Origin: $origin\r\n";
if($this->hybi00)
{
$header .= "Sec-WebSocket-Location: $location\r\n";
$header .= "\r\n".$this->secKey.chr(0);
} else {
$header .= "Sec-WebSocket-Accept: ".$this->secKey."\r\n\r\n";
}
return $header;
}
}
I dont know how to do this in your code, you can look at PHPDaemon - its non blocking server writing on php, with websocket support.
<?php
/*
File : smppclass.php
Implements : SMPPClass()
Description : This class can send messages via the SMPP protocol. Also supports unicode and multi-part messages.
License : GNU Lesser Genercal Public License: http://www.gnu.org/licenses/lgpl.html
Commercial advertisement: Contact info#chimit.nl for SMS connectivity and more elaborate SMPP libraries in PHP and other languages.
*/
/*
The following are the SMPP PDU types that we are using in this class.
Apart from the following 5 PDU types, there are a lot of SMPP directives
that are not implemented in this version.
*/
/*
define(CM_BIND_TRANSMITTER, 0x00000002);
define(CM_SUBMIT_SM, 0x00000004);
define(CM_SUBMIT_MULTI, 0x00000021);
define(CM_UNBIND, 0x00000006);
define(CM_ENQUIRELINK, 0x00000015);
*/
define('generic_nack', 0x80000000);
define('bind_receiver', 0x00000001);
define('bind_receiver_resp', 0x80000001);
define('bind_transmitter', 0x00000002);
define('bind_transmitter_resp', 0x80000002);
define('query_sm', 0x00000003);
define('query_sm_resp', 0x80000003);
define('submit_sm', 0x00000004);
define('submit_sm_resp', 0x80000004);
define('deliver_sm', 0x00000005);
define('deliver_sm_resp', 0x80000005);
define('unbind', 0x00000006);
define('unbind_resp', 0x80000006);
define('replace_sm', 0x00000007);
define('replace_sm_resp', 0x80000007);
define('cancel_sm', 0x00000008);
define('cancel_sm_resp', 0x80000008);
define('bind_transceiver', 0x00000009);
define('bind_transceiver_resp', 0x80000009);
define('outbind', 0x0000000B);
define('enquire_link', 0x00000015);
define('enquire_link_resp', 0x80000015);
define('submit_multi', 0x00000021);
define('submit_multi_resp', 0x80000021);
define('alert_notification', 0x00000102);
define('data_sm', 0x00000103);
define('data_sm_resp', 0x80000103);
class SMPPClass
{
// public members:
/*
Constructor.
Parameters:
none.
Example:
$smpp = new SMPPClass();
*/
function SMPPClass()
{
/* seed random generator */
list($usec, $sec) = explode(' ', microtime());
$seed = (float)$sec + ((float)$usec * 100000);
srand($seed);
/* initialize member variables */
$this->_debug = true;
/* set this to false if you want to suppress debug output. */
$this->_socket = null;
$this->_command_status = 0;
$this->_sequence_number = 1;
$this->_source_address = "";
$this->_message_sequence = rand(1, 255);
$this->_message_id = 0;
$this->interface_version = 0x34;
$this->addr_ton = 1;
$this->addr_npi = 1;
$this->address_range = '';
$this->dlvrSms = array();
}
/*
For SMS gateways that support sender-ID branding, the method
can be used to set the originating address.
Parameters:
$from : Originating address
Example:
$smpp->SetSender("31495595392");
*/
function SetSender($from)
{
if (strlen($from) > 20) {
$this->debug("Error: sender id too long.\n");
return;
}
$this->_source_address = $from;
}
/*
This method initiates an SMPP session.
It is to be called BEFORE using the Send() method.
Parameters:
$host : SMPP ip to connect to.
$port : port # to connect to.
$username : SMPP system ID
$password : SMPP passord.
$system_type : SMPP System type
Returns:
true if successful, otherwise false
Example:
$smpp->Start("smpp.chimit.nl", 2345, "chimit", "my_password", "client01");
*/
function getMessageId(){
return $this->_message_id;
}
function Start($host, $port, $username, $password, $system_type, $type)
{
/*
$testarr = stream_get_transports();
$have_tcp = false;
reset($testarr);
while (list(, $transport) = each($testarr)) {
if ($transport == "tcpp") {
$have_tcp = true;
}
}
if (!$have_tcp) {
$this->debug("No TCP support in this version of PHP.\n");
return false;
}
*/
$this->_socket = #fsockopen($host, $port, $errno, $errstr, 120);
// todo: sanity check on input parameters
if (!$this->_socket) {
$this->debug("Error opening SMPP session.\n");
$this->debug("Error was: $errstr.\n");
return;
}
socket_set_timeout($this->_socket, 120);
//$status = $this->SendBindTransmitter($username, $password, $system_type);
if ($type == 'transmitter') {
$status = $this->SendBindTransmitter($username, $password, $system_type);
} elseif ($type == 'receiver') {
$status = $this->SendBindReceiver($username, $password, $system_type);
}
if ($status != 0) {
$this->debug("Error binding to SMPP server. Invalid credentials?\n");
}
return($status == 0);
}
/*
This method sends out one SMS message.
Parameters:
$to : destination address.
$text : text of message to send.
$unicode: Optional. Indicates if input string is html encoded unicode.
Returns:
true if messages sent successfull, otherwise false.
Example:
$smpp->Send("31649072766", "This is an SMPP Test message.");
$smpp->Send("31648072766", "صباحالخير", true);
*/
function Send($to, $text, $unicode = false)
{
if (strlen($to) > 20) {
$this->debug("to-address too long.\n");
return;
}
if (!$this->_socket) {
$this->debug("Not connected, while trying to send SUBMIT_SM.\n");
// return;
}
$service_type = "";
//default source TON and NPI for international sender
$source_addr_ton = 1;
$source_addr_npi = 1;
$source_addr = $this->_source_address;
if (preg_match('/\D/', $source_addr)) {
//alphanumeric sender
$source_addr_ton = 5;
$source_addr_npi = 0;
} elseif (strlen($source_addr) < 11) {
//national or shortcode sender
$source_addr_ton = 2;
$source_addr_npi = 1;
}
$dest_addr_ton = 1;
$dest_addr_npi = 1;
$destination_addr = $to;
$esm_class = 3;
$protocol_id = 0;
$priority_flag = 0;
$schedule_delivery_time = "";
$validity_period = "";
$registered_delivery_flag = 1;
$replace_if_present_flag = 0;
$data_coding = 241;
$sm_default_msg_id = 0;
if ($unicode) {
$text = mb_convert_encoding($text, "UCS-2BE", "HTML-ENTITIES");
/* UCS-2BE */
$data_coding = 8;
/* UCS2 */
$multi = $this->split_message_unicode($text);
} else {
$multi = $this->split_message($text);
}
$multiple = (count($multi) > 1);
if ($multiple) {
$esm_class += 0x00000040;
}
$result = true;
reset($multi);
while (list(, $part) = each($multi)) {
$short_message = $part;
$sm_length = strlen($short_message);
$status = $this->SendSubmitSM($service_type, $source_addr_ton, $source_addr_npi, $source_addr, $dest_addr_ton, $dest_addr_npi, $destination_addr, $esm_class, $protocol_id, $priority_flag, $schedule_delivery_time, $validity_period, $registered_delivery_flag, $replace_if_present_flag, $data_coding, $sm_default_msg_id, $sm_length, $short_message);
if ($status != 0) {
$this->debug("SMPP server returned error $status.\n");
$result = false;
}
}
return $result;
}
/*
This method ends a SMPP session.
Parameters:
none
Returns:
true if successful, otherwise false
Example: $smpp->End();
*/
function end()
{
if (!$this->_socket) {
// not connected
return;
}
$status = $this->SendUnbind();
if ($status != 0) {
$this->debug("SMPP Server returned error $status.\n");
}
fclose($this->_socket);
$this->_socket = null;
return($status == 0);
}
/*
This method sends an enquire_link PDU to the server and waits for a response.
Parameters:
none
Returns:
true if successfull, otherwise false.
Example: $smpp->TestLink()
*/
function TestLink()
{
$pdu = "";
$status = $this->SendPDU(enquire_link, $pdu);
return($status == 0);
}
function ReadSms()
{
$pdu = "";
$status = true;
$m = 0;
echo date('H:i:s') . "\n";
$status = $this->SendPDU(deliver_sm_resp, $pdu);
return $this->dlvrSms;
}
function QuerySms($message_id, $gsm)
{
$this->dlvrSms = array();
socket_set_timeout($this->_socket, 120);
$pdu = "";
$message_id = $message_id;
$source_addr_ton = 1;
$source_addr_npi = 1;
$source_addr = $gsm;
////$pdu = pack($message_id . chr(0), $source_addr_ton . chr(0), $source_addr_npi . chr(0), $source_addr);
$status = $this->SendPDU(deliver_sm, $pdu);
////$this->ExpectPDU(0);
return $this->dlvrSms;
}
/*
This method sends a single message to a comma separated list of phone numbers.
There is no limit to the number of messages to send.
Parameters:
$tolist : comma seperated list of phone numbers
$text : text of message to send
$unicode: Optional. Indicates if input string is html encoded unicode string.
Returns:
true if messages received by smpp server, otherwise false.
Example:
$smpp->SendMulti("31777110204,31649072766,...,...", "This is an SMPP Test message.");
*/
function SendMulti($tolist, $text, $unicode = false)
{
if (!$this->_socket) {
$this->debug("Not connected, while trying to send SUBMIT_MULTI.\n");
// return;
}
$service_type = '';
//default source TON and NPI for international sender
$source_addr_ton = 1;
$source_addr_npi = 1;
$source_addr = $this->_source_address;
if (preg_match('/\D/', $source_addr)) {
//alphanumeric sender
$source_addr_ton = 5;
$source_addr_npi = 0;
} elseif (strlen($source_addr) < 11) {
//national or shortcode sender
$source_addr_ton = 2;
$source_addr_npi = 1;
}
$dest_addr_ton = 1;
$dest_addr_npi = 1;
$destination_arr = explode(",", $tolist);
$esm_class = 3;
$protocol_id = 0;
$priority_flag = 0;
$schedule_delivery_time = "";
$validity_period = "";
$registered_delivery_flag = 1;
$replace_if_present_flag = 0;
$data_coding = 241;
$sm_default_msg_id = 0;
if ($unicode) {
$text = mb_convert_encoding($text, "UCS-2BE", "HTML-ENTITIES");
$data_coding = 8;
/* UCS2 */
$multi = $this->split_message_unicode($text);
} else {
$multi = $this->split_message($text);
}
$multiple = (count($multi) > 1);
if ($multiple) {
$esm_class += 0x00000040;
}
$result = true;
reset($multi);
while (list(, $part) = each($multi)) {
$short_message = $part;
$sm_length = strlen($short_message);
$status = $this->SendSubmitMulti($service_type, $source_addr_ton, $source_addr_npi, $source_addr, $dest_addr_ton, $dest_addr_npi, $destination_arr, $esm_class, $protocol_id, $priority_flag, $schedule_delivery_time, $validity_period, $registered_delivery_flag, $replace_if_present_flag, $data_coding, $sm_default_msg_id, $sm_length, $short_message);
if ($status != 0) {
$this->debug("SMPP server returned error $status.\n");
$result = false;
}
}
return $result;
}
// private members (not documented):
function ExpectPDU($our_sequence_number)
{
do {
$this->debug("\n\nTrying to read PDU.\n");
if (feof($this->_socket)) {
$this->debug("Socket was closed.!!\n");
return false;
}
$elength = fread($this->_socket, 4);
if (empty($elength)) {
$this->debug("Connection lost.\n");
return false;
}
extract(unpack("Nlength", $elength));
$this->debug("Reading PDU : $length bytes.\n");
$stream = fread($this->_socket, $length - 4);
//$stream = fread($this->_socket, 12);
if (!$stream)
return false;
$this->debug("Stream len : " . strlen($stream) . "\n");
$this->debug("Stream Hex : " . $this->printHex($stream) . "\n");
extract(unpack("Ncommand_id/Ncommand_status/Nsequence_number", $stream));
//$info = stream_get_meta_data($this->_socket);
//$this->debug("stream_get_meta_data id : ".var_export($info,true)."\n");
$command_id &= 0x0fffffff;
$this->debug("Command id : $command_id.\n");
$this->debug("Command status : $command_status.\n");
$this->debug("sequence_number : $sequence_number.\n");
$pdu = substr($stream, 12);
//$pdu=$stream;
switch ($command_id) {
case bind_transmitter:
$this->debug("Got bind_transmitter_RESP.\n");
$spec = "asystem_id";
//extract($this->unpack2($spec, $pdu));
$this->debug("system id : $system_id.\n");
break;
case bind_receiver:
$this->debug("Got bind_receiver_RESP.\n");
$spec = "asystem_id";
extract($this->unpack2($spec, $pdu));
$this->debug("system id : $system_id.\n");
break;
case unbind:
$this->debug("Got unbind_RESP.\n");
break;
case submit_sm:
$this->debug("Got submit_sm_RESP.\n");
if ($command_status == 0) {
$spec = "amessage_id";
extract($this->unpack2($spec, $pdu));
$this->debug("message id : $message_id.\n");
$this->_message_id = $message_id;
}
break;
case submit_multi:
$this->debug("Got submit_multi_RESP.\n");
$spec = "amessage_id/cno_unsuccess/";
extract($this->unpack2($spec, $pdu));
$this->debug("message id : $message_id.\n");
$this->debug("no_unsuccess : $no_unsuccess.\n");
break;
case enquire_link:
$this->debug("GOT enquire_link_RESP.\n");
break;
case deliver_sm;
$this->debug("GOT deliver_sm.\n");
$body = substr($stream, 8, $length);
$this->dlvrSms[] = $this->parseSMS($body, $sequence_number);
$this->SendPDU(deliver_sm_resp, "",$sequence_number);
break;
case deliver_sm_resp;
$this->debug("GOT deliver_sm_resp.\n");
//$body = substr($stream,8, $length);
//$this->dlvrSms[]= $this->parseSMS($body);
break;
case query_sm;
$this->debug("GOT deliver_sm.\n");
$body = substr($stream, 8, $length);
$this->dlvrSms[] = $this->parseSMS($body, $sequence_number);
break;
case generic_nack:
$this->debug("Got generic_nack SMPP pdu.\n");
$spec = "ccommand_length/ccommand_id/ccommand_status/csequence_number";
extract($this->unpack2($spec, $pdu));
$this->debug("command_length generic_nack == " . $command_length . "\n");
$this->debug("command_id generic_nack == " . $command_id . "\n");
$this->debug("command_status generic_nack == " . $command_status . "\n");
$this->debug("command_status generic_nack == " . $command_status . "\n");
break;
default:
$this->debug("Got unknow $command_id SMPP pdu.\n");
}
$this->debug("\nReceived PDU: \n");
for ($i = 0; $i < strlen($stream); $i++) {
if (ord($stream[$i]) < 32)
$this->debug("(" . ord($stream[$i]) . ")");
else
$this->debug($stream[$i]);
}
$this->debug("\n");
} while ($sequence_number != $our_sequence_number);
return $command_status;
}
/**
* #private function
* Parse deliver PDU from SMSC.
* #param $pdu - deliver PDU from SMSC.
* #return parsed PDU as array.
*/
function parseSMS($body, $sequence_number)
{
//check command id
//unpack PDU
$ar = unpack("C*", $body);
//$ar=unpack("C*",$pdu['body']);
$sms = array('service_type' => $this->getString($ar, 6), 'source_addr_ton' => array_shift($ar), 'source_addr_npi' => array_shift($ar), 'source_addr' => $this->getString($ar, 21), 'dest_addr_ton' => array_shift($ar), 'dest_addr_npi' => array_shift($ar), 'destination_addr' => $this->getString($ar, 21), 'esm_class' => array_shift($ar), 'protocol_id' => array_shift($ar), 'priority_flag' => array_shift($ar), 'schedule_delivery_time' => array_shift($ar), 'validity_period' => array_shift($ar), 'registered_delivery' => array_shift($ar), 'replace_if_present_flag' => array_shift($ar), 'data_coding' => array_shift($ar), 'sm_default_msg_id' => array_shift($ar), 'sm_length' => array_shift($ar), 'short_message' => $this->getString($ar, 255));
// $this->_sequence_number=$sequence_number;
//send responce of recieving sms
return $sms;
}
function SendPDU($command_id, $pdu, $sequence_number = null)
{
if ($sequence_number == null) {
$sequence_number = $this->_sequence_number;
}
$length = strlen($pdu) + 16;
$header = pack("NNNN", $length, $command_id, $this->_command_status, $sequence_number);
$this->debug("Sending PDU, len == $length\n");
$this->debug("Sending PDU, header-len == " . strlen($header) . "\n");
$this->debug("Sending PDU, command_id == " . $command_id . "\n");
$this->debug("Sending PDU, sequence number == " . $sequence_number . "\n");
$this->debug("Sending PDU, command status == " . $this->_command_status . "\n");
fwrite($this->_socket, $header . $pdu, $length);
$status = $this->ExpectPDU($sequence_number);
$this->_sequence_number = $this->_sequence_number + 1;
return $status;
}
function SendBindTransmitter($system_id, $smpppassword, $system_type)
{
$system_id = $system_id . chr(0);
$system_id_len = strlen($system_id);
$smpppassword = $smpppassword . chr(0);
$smpppassword_len = strlen($smpppassword);
$system_type = $system_type . chr(0);
$system_type_len = strlen($system_type);
$pdu = pack("a{$system_id_len}a{$smpppassword_len}a{$system_type_len}CCCa1", $system_id, $smpppassword, $system_type, $this->interface_version, $this->addr_ton, $this->addr_npi, $this->address_range);
$this->debug("Bind Transmitter PDU: ");
for ($i = 0; $i < strlen($pdu); $i++) {
$this->debug(ord($pdu[$i]) . " ");
}
$this->debug("\n");
$status = $this->SendPDU(bind_transmitter, $pdu);
return $status;
}
function SendBindReceiver($system_id, $smpppassword, $system_type)
{
$system_id = $system_id . chr(0);
$system_id_len = strlen($system_id);
$smpppassword = $smpppassword . chr(0);
$smpppassword_len = strlen($smpppassword);
$system_type = $system_type . chr(0);
$system_type_len = strlen($system_type);
$pdu = pack("a{$system_id_len}a{$smpppassword_len}a{$system_type_len}CCCa1" . (strlen($this->address_range) + 1), $system_id, $smpppassword, $system_type, $this->interface_version, $this->addr_ton, $this->addr_npi, $this->address_range);
$this->debug("Bind Receiver PDU: ");
for ($i = 0; $i < strlen($pdu); $i++) {
$this->debug(ord($pdu[$i]) . " ");
}
$this->debug("\n");
$status = $this->SendPDU(bind_transceiver, $pdu);
return $status;
}
function SendUnbind()
{
$pdu = "";
$status = $this->SendPDU(unbind, $pdu);
return $status;
}
function SendSubmitSM($service_type, $source_addr_ton, $source_addr_npi, $source_addr, $dest_addr_ton, $dest_addr_npi, $destination_addr, $esm_class, $protocol_id, $priority_flag, $schedule_delivery_time, $validity_period, $registered_delivery_flag, $replace_if_present_flag, $data_coding, $sm_default_msg_id, $sm_length, $short_message)
{
$service_type = $service_type . chr(0);
$service_type_len = strlen($service_type);
$source_addr = $source_addr . chr(0);
$source_addr_len = strlen($source_addr);
$destination_addr = $destination_addr . chr(0);
$destination_addr_len = strlen($destination_addr);
$schedule_delivery_time = $schedule_delivery_time . chr(0);
$schedule_delivery_time_len = strlen($schedule_delivery_time);
$validity_period = $validity_period . chr(0);
$validity_period_len = strlen($validity_period);
// $short_message = $short_message . chr(0);
$message_len = $sm_length;
$spec = "a{$service_type_len}cca{$source_addr_len}cca{$destination_addr_len}ccca{$schedule_delivery_time_len}a{$validity_period_len}ccccca{$message_len}";
$this->debug("PDU spec: $spec.\n");
$pdu = pack($spec, $service_type, $source_addr_ton, $source_addr_npi, $source_addr, $dest_addr_ton, $dest_addr_npi, $destination_addr, $esm_class, $protocol_id, $priority_flag, $schedule_delivery_time, $validity_period, $registered_delivery_flag, $replace_if_present_flag, $data_coding, $sm_default_msg_id, $sm_length, $short_message);
$status = $this->SendPDU(submit_sm, $pdu);
return $status;
}
function SendSubmitMulti($service_type, $source_addr_ton, $source_addr_npi, $source_addr, $dest_addr_ton, $dest_addr_npi, $destination_arr, $esm_class, $protocol_id, $priority_flag, $schedule_delivery_time, $validity_period, $registered_delivery_flag, $replace_if_present_flag, $data_coding, $sm_default_msg_id, $sm_length, $short_message)
{
$service_type = $service_type . chr(0);
$service_type_len = strlen($service_type);
$source_addr = $source_addr . chr(0);
$source_addr_len = strlen($source_addr);
$number_destinations = count($destination_arr);
$dest_flag = 1;
$spec = "a{$service_type_len}cca{$source_addr_len}c";
$pdu = pack($spec, $service_type, $source_addr_ton, $source_addr_npi, $source_addr, $number_destinations);
$dest_flag = 1;
reset($destination_arr);
while (list(, $destination_addr) = each($destination_arr)) {
$destination_addr .= chr(0);
$dest_len = strlen($destination_addr);
$spec = "ccca{$dest_len}";
$pdu .= pack($spec, $dest_flag, $dest_addr_ton, $dest_addr_npi, $destination_addr);
}
$schedule_delivery_time = $schedule_delivery_time . chr(0);
$schedule_delivery_time_len = strlen($schedule_delivery_time);
$validity_period = $validity_period . chr(0);
$validity_period_len = strlen($validity_period);
$message_len = $sm_length;
$spec = "ccca{$schedule_delivery_time_len}a{$validity_period_len}ccccca{$message_len}";
$pdu .= pack($spec, $esm_class, $protocol_id, $priority_flag, $schedule_delivery_time, $validity_period, $registered_delivery_flag, $replace_if_present_flag, $data_coding, $sm_default_msg_id, $sm_length, $short_message);
$this->debug("\nMulti PDU: ");
for ($i = 0; $i < strlen($pdu); $i++) {
if (ord($pdu[$i]) < 32)
$this->debug(".");
else
$this->debug($pdu[$i]);
}
$this->debug("\n");
//$this->_command_status='';
$status = $this->SendPDU(submit_multi, $pdu);
return $status;
}
function split_message($text)
{
$this->debug("\n\nIn split_message.\n");
$max_len = 153;
$res = array();
if (strlen($text) <= 160) {
$this->debug("One message: " . strlen($text) . "\n");
$res[] = $text;
return $res;
}
$pos = 0;
$msg_sequence = $this->_message_sequence++;
$num_messages = ceil(strlen($text) / $max_len);
$part_no = 1;
while ($pos < strlen($text)) {
$ttext = substr($text, $pos, $max_len);
$pos += strlen($ttext);
$udh = pack("cccccc", 5, 0, 3, $msg_sequence, $num_messages, $part_no);
$part_no++;
$res[] = $udh . $ttext;
$this->debug("Split: UDH = ");
for ($i = 0; $i < strlen($udh); $i++) {
$this->debug(ord($udh[$i]) . " ");
}
$this->debug("\n");
$this->debug("Split: $ttext.\n");
}
return $res;
}
function split_message_unicode($text)
{
$this->debug("\n\nIn split_message.\n");
$max_len = 134;
$res = array();
if (mb_strlen($text) <= 140) {
$this->debug("One message: " . mb_strlen($text) . "\n");
$res[] = $text;
return $res;
}
$pos = 0;
$msg_sequence = $this->_message_sequence++;
$num_messages = ceil(mb_strlen($text) / $max_len);
$part_no = 1;
while ($pos < mb_strlen($text)) {
$ttext = mb_substr($text, $pos, $max_len);
$pos += mb_strlen($ttext);
$udh = pack("cccccc", 5, 0, 3, $msg_sequence, $num_messages, $part_no);
$part_no++;
$res[] = $udh . $ttext;
$this->debug("Split: UDH = ");
for ($i = 0; $i < strlen($udh); $i++) {
$this->debug(ord($udh[$i]) . " ");
}
$this->debug("\n");
$this->debug("Split: $ttext.\n");
}
return $res;
}
function unpack2($spec, $data)
{
$res = array();
$specs = explode("/", $spec);
$pos = 0;
reset($specs);
while (list(, $sp) = each($specs)) {
$subject = substr($data, $pos);
$type = substr($sp, 0, 1);
$var = substr($sp, 1);
switch ($type) {
case "N":
$temp = unpack("Ntemp2", $subject);
$res[$var] = $temp["temp2"];
$pos += 4;
break;
case "c":
$temp = unpack("ctemp2", $subject);
$res[$var] = $temp["temp2"];
$pos += 1;
break;
case "a":
$pos2 = strpos($subject, chr(0)) + 1;
$temp = unpack("a{$pos2}temp2", $subject);
$res[$var] = $temp["temp2"];
$pos += $pos2;
break;
}
}
return $res;
}
/**
* #private function
* Reads C style zero padded string from the char array.
* #param $ar - input array
* #param $maxlen - maximum length to read.
* #return readed string.
*/
function getString(&$ar, $maxlen = 255)
{
$s = "";
$i = 0;
do {
$c = array_shift($ar);
if ($c != 0)
$s .= chr($c);
$i++;
} while ($i < $maxlen && $c != 0);
return $s;
}
/**
* #private function
* Prints the binary string as hex bytes.
* #param $maxlen - maximum length to read.
*/
function printHex($pdu)
{
$a = "";
$ar = unpack("C*", $pdu);
foreach ($ar as $v) {
$s = dechex($v);
if (strlen($s) < 2)
$s = "0$s";
$a .= "$s ";
}
return $a . "\n";
}
function debug($str)
{
if ($this->_debug) {
echo $str;
}
}
}
?>
Deliver_sm and Deliver_sm_resp is not working, When i request for delivery report the server is sending me deliver_sm but deliver_sm_resp is not working.
Any body know how to receive delivery report of specific sms, although i have message id of every sms.