<?php
/**
* @package net
* Class for receiving or sending sms through SMPP protocol.
* @version 0.2
* @author paladin
* @since 04/25/2006
* @see http://www.smpp.org/doc/public/index.html - SMPP 3.4 protocol specification
*/
class SMPP{
//SMPP bind parameters
var $system_type="VMA";
var $interface_version=0x34;
var $addr_ton=0;
var $addr_npi=0;
var $address_range="";
//ESME transmitter parameters
var $sms_service_type="";
var $sms_source_addr_ton=0;
var $sms_source_addr_npi=0;
var $sms_dest_addr_ton=0;
var $sms_dest_addr_npi=0;
var $sms_esm_class=0;
var $sms_protocol_id=0;
var $sms_priority_flag=0;
var $sms_schedule_delivery_time="";
var $sms_validity_period="";
var $sms_registered_delivery_flag=0;
var $sms_replace_if_present_flag=0;
var $sms_data_coding=0;
var $sms_sm_default_msg_id=0;
# custom vars
var $sms_lmt_addr="";
var $sms_lmt_addr_ton="";
var $sms_lmt_tariff_class="";
/**
* Constructs the smpp class
* @param $host - SMSC host name or host IP
* @param $port - SMSC port
*/
function SMPP($host, $port=5016){
//internal parameters
$this->sequence_number=1;
$this->debug=true;
$this->pdu_queue=array();
$this->host=$host;
$this->port=$port;
$this->state="closed";
//open the socket
$this->socket=fsockopen($this->host, $this->port, $errno, $errstr, 30);
if($this->socket)$this->state="open";
}
/**
* Binds the receiver. One object can be bound only as receiver or only as trancmitter.
* @param $login - ESME system_id
* @param $port - ESME password
* @return true when bind was successful
*/
function bindReceiver($login, $pass){
if($this->state!="open")return false;
if($this->debug){
echo "Binding receiver...\n\n";
}
$status=$this->_bind($login, $pass, 0x00000001);
if($this->debug){
echo "Binding status : $status\n\n";
}
if($status===0)$this->state="bind_rx";
return ($status===0);
}
/**
* Binds the transmitter. One object can be bound only as receiver or only as trancmitter.
* @param $login - ESME system_id
* @param $port - ESME password
* @return true when bind was successful
*/
function bindTransmitter($login, $pass){
if($this->state!="open")return false;
if($this->debug){
echo "Binding transmitter...\n\n";
}
$status=$this->_bind($login, $pass, 0x00000002);
if($this->debug){
echo "Binding status : $status\n\n";
}
if($status===0)$this->state="bind_tx";
return ($status===0);
}
/**
* Closes the session on the SMSC server.
*/
function close(){
if($this->state=="closed")return;
if($this->debug){
echo "Unbinding...\n\n";
}
$status=$this->sendCommand(0x00000006,"");
if($this->debug){
echo "Unbind status : $status\n\n";
}
fclose($this->socket);
$this->state="closed";
}
/**
* Read one SMS from SMSC. Can be executed only after bindReceiver() call.
* This method bloks. Method returns on socket timeout or enquire_link signal from SMSC.
* @return sms associative array or false when reading failed or no more sms.
*/
function readSMS(){
if($this->state!="bind_rx")return false;
//stream_set_timeout($this->socket, 10);
$command_id=0x00000005;
//check the queue
for($i=0;$i<count($this->pdu_queue);$i++){
$pdu=$this->pdu_queue[$i];
if($pdu['id']==$command_id){
//remove responce
array_splice($this->pdu_queue, $i, 1);
return parseSMS($pdu);
}
}
//read pdu
do{
if($this->debug){
echo "read sms...\n\n";
}
$pdu=$this->readPDU();
//check for enquire link command
if($pdu['id']==0x00000015){
$this->sendPDU(0x80000015, "", $pdu['sn']);
return false;
}
array_push($this->pdu_queue, $pdu);
}while($pdu && $pdu['id']!=$command_id);
if($pdu){
array_pop($this->pdu_queue);
return $this->parseSMS($pdu);
}
return false;
}
/**
* Read one SMS from SMSC. Can be executed only after bindTransmitter() call.
* @return true on succesfull send, false if error encountered
*/
function sendSMS($from, $to, $message){
if (strlen($from)>20 || strlen($to)>20 || strlen($message)>160)return false;
if($this->state!="bind_tx")return false;
$short_message = $text;
//*
$pdu = pack('a1cca'.(strlen($from)+1).'cca'.(strlen($to)+1).'ccca1a1ccccca'.(strlen($message)+1),
$this->sms_service_type,
$this->sms_source_addr_ton,
$this->sms_source_addr_npi,
$from,//source_addr
$this->sms_dest_addr_ton,
$this->sms_dest_addr_npi,
$to,//destination_addr
$this->sms_esm_class,
$this->sms_protocol_id,
$this->sms_priority_flag,
$this->sms_schedule_delivery_time,
$this->sms_validity_period,
$this->sms_registered_delivery_flag,
$this->sms_replace_if_present_flag,
$this->sms_data_coding,
$this->sms_sm_default_msg_id,
$this->sms_lmt_addr,
$this->sms_lmt_addr_ton,
$this->sms_lmt_tariff_class,
strlen($message),//sm_length
$message//short_message
);
$status=$this->sendCommand(0x00000004,$pdu);
//*/
return ($status===0);
}
////////////////private functions///////////////
/**
* @private function
* Binds the socket and opens the session on SMSC
* @param $login - ESME system_id
* @param $port - ESME password
* @return bind status or false on error
*/
function _bind($login, $pass, $command_id){
//make PDU
$pdu = pack(
'a'.(strlen($login)+1).
'a'.(strlen($pass)+1).
'a'.(strlen($this->system_type)+1).
'CCCa'.(strlen($this->addre