2019-12-12 00:56:30 +01:00
< ? php
2020-01-17 18:19:25 +01:00
/*
* This file is part of RaspiSMS .
*
* ( c ) Pierre - Lin Bonnemaison < plebwebsas @ gmail . com >
*
* This source file is subject to the GPL - 3.0 license that is bundled
* with this source code in the file LICENSE .
*/
2019-12-12 00:56:30 +01:00
namespace daemons ;
2020-01-17 18:19:25 +01:00
use Monolog\Handler\StreamHandler ;
use Monolog\Logger ;
2019-12-12 00:56:30 +01:00
/**
2020-01-17 18:19:25 +01:00
* Phone daemon class .
2019-12-12 00:56:30 +01:00
*/
class Phone extends AbstractDaemon
{
2020-03-04 05:10:45 +01:00
private $max_inactivity = 5 * 60 ;
2021-12-21 14:43:07 +01:00
private $read_delay = 20 / 0.5 ;
2021-12-21 15:00:34 +01:00
private $read_tick = 0 ;
2019-12-12 00:56:30 +01:00
private $msg_queue ;
2020-01-07 01:31:34 +01:00
private $webhook_queue ;
2019-12-17 07:47:11 +01:00
private $last_message_at ;
2020-01-07 01:31:34 +01:00
private $phone ;
private $adapter ;
private $bdd ;
2019-12-12 00:56:30 +01:00
2020-01-07 01:31:34 +01:00
/**
2020-01-17 18:19:25 +01:00
* Constructor .
*
2020-01-07 01:31:34 +01:00
* @ param array $phone : A phone table entry
*/
public function __construct ( array $phone )
2019-12-12 00:56:30 +01:00
{
2020-01-07 01:31:34 +01:00
$this -> phone = $phone ;
2020-01-17 18:19:25 +01:00
2020-03-04 01:40:47 +01:00
$name = 'RaspiSMS Daemon Phone ' . $this -> phone [ 'id' ];
2019-12-12 00:56:30 +01:00
$logger = new Logger ( $name );
2020-03-04 04:18:26 +01:00
$logger -> pushHandler ( new StreamHandler ( PWD_LOGS . '/daemons.log' , Logger :: DEBUG ));
2019-12-17 07:47:11 +01:00
$pid_dir = PWD_PID ;
2020-01-08 18:20:17 +01:00
$no_parent = false ; //Phone should be rattach to manager, so manager can stop him easily
2019-12-17 07:47:11 +01:00
$additional_signals = [];
2020-01-08 18:20:17 +01:00
$uniq = true ; //Each phone should be uniq
2019-12-12 00:56:30 +01:00
2020-01-08 18:20:17 +01:00
//Construct the daemon
parent :: __construct ( $name , $logger , $pid_dir , $no_parent , $additional_signals , $uniq );
2020-01-17 18:19:25 +01:00
2019-12-12 00:56:30 +01:00
parent :: start ();
}
public function run ()
{
2020-03-04 03:28:34 +01:00
usleep ( 0.5 * 1000000 ); //Micro sleep for perfs
2020-01-17 18:19:25 +01:00
2022-07-12 13:16:22 +02:00
$this -> read_tick += 1 ;
2021-12-21 14:43:07 +01:00
2021-12-29 02:54:21 +01:00
$this -> bdd = \descartes\Model :: _connect ( DATABASE_HOST , DATABASE_NAME , DATABASE_USER , DATABASE_PASSWORD );
2020-01-17 18:19:25 +01:00
2020-01-07 01:31:34 +01:00
//Send smss in queue
$this -> send_smss ();
2019-12-17 07:47:11 +01:00
2021-12-21 14:43:07 +01:00
//Read only every x ticks (x/2 seconds) to prevent too many call
2021-12-21 15:00:34 +01:00
if ( $this -> read_tick >= $this -> read_delay )
2021-12-21 14:43:07 +01:00
{
//Read received smss
$this -> read_smss ();
2021-12-21 15:00:34 +01:00
$this -> read_tick = 0 ;
2021-12-21 14:43:07 +01:00
}
2020-01-07 01:31:34 +01:00
2020-03-04 03:28:34 +01:00
//Stop after 5 minutes of inactivity to avoid useless daemon
if (( microtime ( true ) - $this -> last_message_at ) > $this -> max_inactivity )
{
posix_kill ( getmypid (), SIGTERM ); //Send exit signal to the current process
2020-07-03 03:48:42 +02:00
2020-03-04 03:28:34 +01:00
return false ;
}
2020-01-04 19:30:06 +01:00
}
2020-01-17 18:19:25 +01:00
public function on_start ()
{
//Set last message at to construct time
$this -> last_message_at = microtime ( true );
2022-09-28 20:01:55 +02:00
$this -> msg_queue = msg_get_queue ( QUEUE_ID_PHONE );
2020-01-17 18:19:25 +01:00
//Instanciate adapter
$adapter_class = $this -> phone [ 'adapter' ];
2021-01-17 03:16:57 +01:00
$this -> adapter = new $adapter_class ( $this -> phone [ 'adapter_data' ]);
2020-01-17 18:19:25 +01:00
2020-01-17 18:47:08 +01:00
$this -> logger -> info ( 'Starting Phone daemon with pid ' . getmypid ());
2020-01-17 18:19:25 +01:00
}
public function on_stop ()
{
2022-09-28 20:01:55 +02:00
$this -> logger -> info ( 'Stopping Phone daemon with pid ' . getmypid ());
2020-01-17 18:19:25 +01:00
}
public function handle_other_signals ( $signal )
{
2020-01-17 18:47:08 +01:00
$this -> logger -> info ( 'Signal not handled by ' . $this -> name . ' Daemon : ' . $signal );
2020-01-17 18:19:25 +01:00
}
2020-01-04 19:30:06 +01:00
/**
2020-01-17 18:19:25 +01:00
* Send sms .
2020-01-04 19:30:06 +01:00
*/
2020-01-17 18:19:25 +01:00
private function send_smss ()
2020-01-04 19:30:06 +01:00
{
2020-04-02 18:40:39 +02:00
$internal_sended = new \controllers\internals\Sended ( $this -> bdd );
2020-06-23 21:06:13 +02:00
2020-01-07 01:31:34 +01:00
$find_message = true ;
while ( $find_message )
2019-12-12 00:56:30 +01:00
{
2020-01-17 18:19:25 +01:00
//Call message
2020-01-07 17:55:16 +01:00
$msgtype = null ;
$maxsize = 409600 ;
$message = null ;
2022-09-28 20:01:55 +02:00
// Message type is forged from a prefix concat with the phone ID
$message_type = ( int ) QUEUE_TYPE_SEND_MSG_PREFIX . $this -> phone [ 'id' ];
2020-01-07 17:55:16 +01:00
$error_code = null ;
2022-09-28 20:01:55 +02:00
$success = msg_receive ( $this -> msg_queue , $message_type , $msgtype , $maxsize , $message , true , MSG_IPC_NOWAIT , $error_code ); //MSG_IPC_NOWAIT == dont wait if no message found
2020-01-07 17:55:16 +01:00
2020-01-17 18:19:25 +01:00
if ( ! $success && MSG_ENOMSG !== $error_code )
2020-01-07 17:55:16 +01:00
{
2020-01-17 18:47:08 +01:00
$this -> logger -> critical ( 'Error reading MSG SEND Queue, error code : ' . $error_code );
2020-01-17 18:19:25 +01:00
2020-01-07 17:55:16 +01:00
return false ;
}
2020-01-07 01:31:34 +01:00
if ( ! $message )
{
$find_message = false ;
2020-01-17 18:19:25 +01:00
2020-01-07 01:31:34 +01:00
continue ;
}
2020-01-17 18:19:25 +01:00
2020-01-07 01:31:34 +01:00
//Update last message time
$this -> last_message_at = microtime ( true );
2020-06-23 21:06:13 +02:00
//Do message sending
2020-01-17 18:47:08 +01:00
$this -> logger -> info ( 'Try send message : ' . json_encode ( $message ));
2020-06-23 21:06:13 +02:00
2021-10-18 03:40:06 +02:00
$response = $internal_sended -> send ( $this -> adapter , $this -> phone [ 'id_user' ], $this -> phone [ 'id' ], $message [ 'text' ], $message [ 'destination' ], $message [ 'flash' ], $message [ 'mms' ], $message [ 'medias' ], $message [ 'id_scheduled' ]);
2020-04-02 01:55:55 +02:00
if ( $response [ 'error' ])
2020-01-07 01:31:34 +01:00
{
2020-04-02 01:55:55 +02:00
$this -> logger -> error ( 'Failed send message : ' . json_encode ( $message ) . ' with error : ' . $response [ 'error_message' ]);
2020-06-23 21:06:13 +02:00
2020-01-07 01:31:34 +01:00
continue ;
}
2022-03-15 02:24:28 +01:00
2020-01-17 18:47:08 +01:00
$this -> logger -> info ( 'Successfully send message : ' . json_encode ( $message ));
2019-12-12 00:56:30 +01:00
}
2020-01-07 01:31:34 +01:00
}
/**
2020-03-04 01:40:47 +01:00
* Read smss for a phone .
2020-01-07 01:31:34 +01:00
*/
2020-01-17 18:19:25 +01:00
private function read_smss ()
2020-01-07 01:31:34 +01:00
{
$internal_received = new \controllers\internals\Received ( $this -> bdd );
2020-01-17 18:19:25 +01:00
2020-03-31 02:22:40 +02:00
if ( ! $this -> adapter -> meta_support_read ())
{
return true ;
}
2020-06-23 21:06:13 +02:00
2020-04-02 01:55:55 +02:00
$response = $this -> adapter -> read ();
if ( $response [ 'error' ])
{
$this -> logger -> info ( 'Error reading received smss : ' . $response [ 'error_message' ]);
2020-06-23 21:06:13 +02:00
2020-04-02 01:55:55 +02:00
return false ;
}
if ( ! $response [ 'smss' ])
2020-01-07 01:31:34 +01:00
{
return true ;
}
//Process smss
2020-04-02 01:55:55 +02:00
foreach ( $response [ 'smss' ] as $sms )
2020-01-07 01:31:34 +01:00
{
2020-01-17 18:47:08 +01:00
$this -> logger -> info ( 'Receive message : ' . json_encode ( $sms ));
2021-03-26 23:32:29 +01:00
$response = $internal_received -> receive ( $this -> phone [ 'id_user' ], $this -> phone [ 'id' ], $sms [ 'text' ], $sms [ 'origin' ], $sms [ 'at' ], \models\Received :: STATUS_UNREAD , $sms [ 'mms' ] ? ? false , $sms [ 'medias' ] ? ? []);
2020-06-23 21:06:13 +02:00
2020-04-02 18:40:39 +02:00
if ( $response [ 'error' ])
2020-01-07 17:55:16 +01:00
{
2020-04-02 18:40:39 +02:00
$this -> logger -> error ( 'Failed receive message : ' . json_encode ( $sms ) . ' with error : ' . $response [ 'error_message' ]);
2020-06-23 21:06:13 +02:00
2020-04-02 18:40:39 +02:00
continue ;
2020-01-07 17:55:16 +01:00
}
2020-01-17 18:19:25 +01:00
2020-04-02 18:40:39 +02:00
$this -> logger -> info ( 'Message received successfully.' );
2020-01-08 14:14:40 +01:00
}
2019-12-12 00:56:30 +01:00
}
}