97 public static function BYTE($value) {
98 return chr($value & 0xFF);
101 public static function UINT16($value,$endianness = 0) {
102 return pack(($endianness?
"n":
"v"),$value);
105 public static function UINT32($value,$endianness = 0){
106 return pack(($endianness?
"N":
"V"),$value);
109 public static function UINT64($value,$endianness = 0){
110 $a = gmp_init(
"$value");
113 $res = gmp_div_qr($a,
"0x10000");
115 $b[$i]=gmp_intval($res[1]);
118 if($endianness)
return pack(
"nnnn",$b[3],$b[2],$b[1],$b[0]);
119 else return pack(
"vvvv",$b[0],$b[1],$b[2],$b[3]);
122 public static function FLOAT32($value,$endianness = 0){
123 $float = pack(
"f", $value);
125 $w = unpack(
"L", $float);
126 return self::UINT32(
$w[1],$endianness);
129 public static function INT32($value,$endianness = 0){
130 $int = pack(
"l", $value);
132 $w = unpack(
"L", $int);
133 return self::UINT32(
$w[1],$endianness);
136 public static function INT16($value,$endianness = 0){
137 $int = pack(
"s", $value);
139 $w = unpack(
"S", $int);
140 return self::UINT16(
$w[1],$endianness);
144 $res=unpack(
"C",$value);
149 $res=unpack(
"c",$value);
154 $res=unpack(($endianness?
"n":
"v"),$value);
160 $res=unpack(($endianness?
"N":
"V"),$value);
165 $res=unpack(($endianness?
"N2":
"V2"),$value);
166 if($endianness)
return $res[1]<<32+$res[2];
167 else return $res[2]<<32+$res[1];
171 $res=unpack(($endianness?
"N":
"V"),$value);
172 $int=pack(
"L",$res[1]);
173 $res=unpack(
"f",$int);
178 $res=unpack(($endianness?
"N":
"V"),$value);
179 $int=pack(
"L",$res[1]);
180 $res=unpack(
"l",$int);
185 $res=unpack(($endianness?
"n":
"v"),$value);
186 $int=pack(
"S",$res[1]);
187 $res=unpack(
"s",$int);
203 $bayeos_frame=pack(
"C2",0x1,intval($type,0));
205 $offset_type=(0xf0 & $type);
206 $data_type=(0x0f & $type);
207 if($offset_type==0x0) $bayeos_frame.=pack(
"C",$offset);
208 while(list($key,$value)=each($values)){
209 if($offset_type==0x40) $bayeos_frame.=pack(
"C",$key);
221 $bayeos_frame.=pack(
"C",$value);
224 $bayeos_frame.=pack(
"d",$value);
230 return $bayeos_frame;
244 if(! $ts) $ts=microtime(TRUE);
245 $type=array_pop(unpack(
"C",substr(
$frame,0,1)));
250 $res[
'type']=
"DataFrame";
253 $res[
'value']=substr(
$frame,2);
254 $res[
'cmd']=array_pop(unpack(
'C',substr(
$frame,1,1)));
255 $res[
'type']=
"Command";
258 $res[
'value']=substr(
$frame,2);
259 $res[
'cmd']=array_pop(unpack(
'C',substr(
$frame,1,1)));
260 $res[
'type']=
"CommandResponse";
263 $res[
'value']=substr(
$frame,1);
264 $res[
'type']=
"Message";
267 $res[
'value']=substr(
$frame,1);
268 $res[
'type']=
"ErrorMessage";
280 if(! $rssi) $rssi=$rssi_neu;
281 if($rssi_neu>$rssi) $rssi=$rssi_neu;
284 $ts=DateTime::createFromFormat(
'Y-m-d H:i:s P',
'2000-01-01 00:00:00 +00:00')->format(
'U')+
290 $res[
'value']=substr(
$frame,5);
291 $res[
'type']=
"Binary";
295 $origin=substr(
$frame,2,$length);
298 $ts=array_pop(unpack(
'd',substr(
$frame,1,8)));
302 error_log(
'ParseFrame: Unexpected type '.$type);
303 $res[
'type']=
'Unknown';
307 $res[
'ts_f']=DateTime::createFromFormat(
'U',round($ts))->format(
'Y-m-d H:i:s P');
308 $res[
'origin']=$origin;
309 if($rssi) $res[
'rssi']=$rssi;
321 if(substr(
$frame,0,1)!=pack(
"C",0x1))
return FALSE;
322 $type=array_pop(unpack(
"C",substr(
$frame,1,1)));
324 $offset_type=(0xf0 & $type);
325 $data_type=(0x0f & $type);
329 if($offset_type==0x0){
330 $key=array_pop(unpack(
"C",substr(
$frame,2,1)));
334 if($offset_type==0x40){
335 $key=array_pop(unpack(
"C",substr(
$frame,
$pos,1)));
356 $value=array_pop(unpack(
"d",substr(
$frame,
$pos,8)));
381 $this->max_chunk=$max_chunk;
382 $this->max_time=$max_time;
383 if(! is_dir($this->path)){
384 if(! mkdir($this->path,0700,TRUE)){
385 die(
"could not create ".$this->dir);
391 if(strstr($last.
'$',
'.act$')){
393 rename($last,str_replace(
'.act',
'.rd',$last));
395 $this->start_new_file();
415 function save($values,$origin=
'',$type=0x41,$offset=0,$ts=0){
418 $origin=substr($origin,0,255);
420 pack(
"C",strlen($origin)).
460 $origin=substr($origin,0,255);
463 pack(
"C",strlen($origin)).
479 $origin=substr($origin,0,255);
482 pack(
"C",strlen($origin)).
521 $this->
saveFrame(pack(
"C",0x4).$sting,$ts);
534 $this->
saveFrame(pack(
"C",0x5).$sting,$ts);
549 if(! $ts) $ts=microtime(TRUE);
553 if(ftell($this->fp)>$this->max_chunk ||
554 (mktime()-$this->current_ts)>$this->max_time){
557 rename($this->current_name.
'.act',$this->current_name.
'.rd');
558 $this->start_new_file();
563 private function start_new_file(){
564 $this->current_ts=mktime();
566 list($usec,$sec)=explode(
' ',$tmp);
567 $this->current_name=$sec.
'-'.$usec;
568 $this->fp=fopen($this->current_name.
'.act',
'w');
576 private $current_name;
602 function __construct($path,$name,$url,$pw=
'import',$user=
'import',$absolute_time=TRUE,$rm=TRUE,$gateway_version=
'1.9',$sleep_time=10){
603 if(! filter_var($url, FILTER_VALIDATE_URL))
604 die(
"URL '$url' not valid\n");
606 die(
"No gateway password found\n");
613 $this->absolute_time=$absolute_time;
615 $this->gateway_version=$gateway_version;
616 $this->sleep_time=$sleep_time;
627 while($post=$this->sendFile()){
639 private function sendFile(){
642 if(count($files)==0)
return 0;
646 $fp=fopen($files[0],
'r');
648 $data=
"sender=".urlencode($this->name).
"&password=".urlencode($this->pw);
651 $ref= DateTime::createFromFormat(
'Y-m-d H:i:s P',
'2000-01-01 00:00:00 +00:00')->format(
'U');
653 $size_of_double=strlen(pack(
'd',1.0));
654 $size_of_short=strlen(pack(
's',1));
660 $tmp=fread(
$fp,$size_of_double);
661 if(strlen($tmp)==0)
break;
662 $tmp=unpack(
'd',$tmp);
664 $tmp=unpack(
's',fread(
$fp,$size_of_short));
666 $bayeos_frame=fread(
$fp,$length);
669 if($this->absolute_time){
670 if($this->gateway_version==
'1.8') $bayeos_frame=pack(
"C",0x9).BayEOSType::UINT32(round($ts-$ref)).$bayeos_frame;
671 else $bayeos_frame=pack(
"C",0xc).BayEOSType::UINT64(round($ts*1000)).$bayeos_frame;
673 $bayeos_frame=pack(
"C",0x7).BayEOSType::UINT32(round((microtime(TRUE)-$ts)*1000)).$bayeos_frame;
674 $frames.=
"&bayeosframes[]=".($this->gateway_version==
'1.8'?
675 base64_encode($bayeos_frame):urlencode(base64_encode($bayeos_frame)));
681 if($res=$this->post(
$data.$frames)){
684 if($this->rm) unlink($files[0]);
685 else rename($files[0],str_replace(
'.rd',
'.bak',$files[0]));
687 fwrite(STDERR, date(
'Y-m-d H:i:s').
' '.$this->name.
" Will keep failed file as ".
688 str_replace(
'.rd',
'.bak',$files[0]).
"\n");
689 rename($files[0],str_replace(
'.rd',
'.bak',$files[0]));
695 if(filesize($files[0])>0)
696 rename($files[0],str_replace(
'.rd',
'.bak',$files[0]));
710 private function post(
$data){
712 $ch=curl_init($this->url);
713 curl_setopt($ch,CURLOPT_POST,1);
714 curl_setopt($ch,CURLOPT_TIMEOUT,120);
715 curl_setopt($ch,CURLOPT_CONNECTTIMEOUT, 30);
716 curl_setopt($ch,CURLOPT_POSTFIELDS,
$data);
717 curl_setopt($ch,CURLOPT_HEADER,1);
718 curl_setopt($ch,CURLOPT_USERAGENT,
'BayEOS-PHP/1.0.10');
719 curl_setopt($ch, CURLOPT_USERPWD, $this->user .
":" . $this->pw);
721 curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
726 fwrite(STDERR, date(
'Y-m-d H:i:s').
' '.$this->name.
" curl_exec failed\n");
729 $res=explode(
"\n",$res);
730 for($i=0;$i<count($res);$i++){
731 if(preg_match(
'|^HTTP/1\\.[0-9] 200 OK|i',$res[$i]))
return 1;
732 elseif(preg_match(
'|^HTTP/1\\.[0-9] 500|i',$res[$i],$matches)){
733 fwrite(STDERR, date(
'Y-m-d H:i:s').
' '.$this->name.
" Post Error: $res[$i]\n");
736 elseif(preg_match(
'|^HTTP/1\\.[0-9] [45]|i',$res[$i],$matches)){
737 fwrite(STDERR, date(
'Y-m-d H:i:s').
' '.$this->name.
" Post Error: $res[$i]\n");
754 echo date(
'Y-m-d H:i:s').
" ".$this->name.
": Successfully sent $c frames\n";
756 sleep($this->sleep_time);
766 private $absolute_time;
768 private $gateway_version;
795 function __construct($path,
$name,
$url,$pw=
'import',$user=
'import',$absolute_time=TRUE,$rm=TRUE,$gateway_version=
'1.9',$sleep_time=10){
803 if($this->sender_pid){
804 fwrite(STDERR,date(
'Y-m-d H:i:s').
" Sender is running with pid ".$this->sender_pid.
"\n");
809 die(
'Could not fork');
812 $this->sender_pid=$pid;
813 echo date(
'Y-m-d H:i:s').
" Sender started with pid ".$this->sender_pid.
"\n";
817 $this->sender->run();
823 if(! $this->sender_pid){
824 fwrite(STDERR,date(
'Y-m-d H:i:s').
" Sender is not running\n");
827 posix_kill($this->sender_pid,SIGTERM);
828 $res=pcntl_waitpid($this->sender_pid,$status);
829 echo date(
'Y-m-d H:i:s').
" Stopping sender with pid ".$this->sender_pid.
": ".
830 ($res>0?
'ok':
'failed').
"\n";
838 echo date(
'Y-m-d H:i:s').
" Stopping main process\n";
866 die(
"Duplicate names detected!");
868 die(
"No name given");
872 $prefix=gethostname().
'/';
878 for($i=0;$i<count(
$names);$i++){
879 $sender_defaults[
$i]=$prefix.$names[
$i];
882 $defaults=array_merge(array(
'writer_sleep_time'=>15,
886 'sender_sleep_time'=>5,
887 'sender'=>$sender_defaults,
888 'bayeosgateway_user'=>
'import',
889 'bayeosgateway_version'=>
'1.9',
890 'absolute_time'=>TRUE,
892 'sleep_between_childs'=>0,
893 'tmp_dir'=>sys_get_temp_dir()),$defaults);
894 while(list($key,$value)=each($defaults)){
896 echo
"Option '$key' not set using default: ".(is_array($value)?implode(
', ',$value):$value).
"\n";
914 if(isset($this->options[$key])){
915 if(is_array($this->options[$key])){
916 if(isset($this->options[$key][$this->i]))
917 return $this->options[$key][
$this->i];
918 if(isset($this->options[$key][$this->name]))
921 return $this->options[$key];
932 for($i=0;$i<count($this->names);$i++){
934 $this->name=$this->names[
$i];
935 $path=$this->
getOption(
'tmp_dir').
'/'.str_replace(array(
'/',
'\\',
'"',
'\''),
'_',$this->name);
936 $this->pid_w[
$i] = pcntl_fork();
937 if ($this->pid_w[$i] == -1) {
938 die(
'Could not fork writer process!');
939 }
else if ($this->pid_w[$i]) {
941 echo date(
'Y-m-d H:i:s').
" Started writer for ".$this->name.
" with pid ".$this->pid_w[
$i].
"\n";
953 else fwrite(STDERR,date(
'Y-m-d H:i:s').
" ".$this->name.
": readData failed\n");
954 sleep($this->
getOption(
'writer_sleep_time'));
960 $this->pid_r[
$i] = pcntl_fork();
961 if ($this->pid_r[$i] == -1) {
962 die(
'Could not fork sender process');
963 }
else if ($this->pid_r[$i]) {
965 echo date(
'Y-m-d H:i:s').
" Started sender for ".$this->name.
" with pid ".$this->pid_r[
$i].
"\n";
966 sleep($this->
getOption(
'sleep_between_childs'));
977 $this->
getOption(
'bayeosgateway_version'),
990 pcntl_signal(SIGTERM,
function($signo) {
994 for($i=0;$i<count($this->pid_w);$i++){
995 posix_kill($this->pid_w[$i],SIGTERM);
996 $res=pcntl_waitpid($this->pid_w[$i],$status);
997 echo date(
'Y-m-d H:i:s').
" Stopping writer for ".$this->names[
$i].
" with pid ".$this->pid_w[
$i].
': '.
998 ($res>0?
'ok':
'failed').
"\n";
1001 for($i=0;$i<count($this->pid_r);$i++){
1002 posix_kill($this->pid_r[$i],SIGTERM);
1003 $res=pcntl_waitpid($this->pid_r[$i],$status);
1004 echo date(
'Y-m-d H:i:s').
" Stopping sender for ".$this->names[
$i].
" with pid ".$this->pid_r[
$i].
": ".
1005 ($res>0?
'ok':
'failed').
"\n";
1007 echo date(
'Y-m-d H:i:s').
" Stopping main process\n";
1035 die(
"no readData() found!\n");
1045 $this->writer->saveDataFrame(
$data,$this->
getOption(
'data_type'));
static unpackUINT16($value, $endianness=0)
static parseDataFrame($frame)
static UINT16($value, $endianness=0)
static createDataFrame($values, $type=0x1, $offset=0)
static unpackINT16($value, $endianness=0)
static FLOAT32($value, $endianness=0)
saveErrorMessage($sting, $ts=0)
static INT32($value, $endianness=0)
static unpackINT8($value)
__construct($names, $options=array(), $defaults=array())
saveRoutedFrameRSSI($MyId, $PanId, $rssi, $frame, $ts=0)
static UINT64($value, $endianness=0)
saveOriginDataFrame($origin, $values, $type=0x1, $offset=0, $ts=0)
getOption($key, $default='')
saveMessage($sting, $ts=0)
static unpackUINT64($value, $endianness=0)
__construct($path, $name, $url, $pw='import', $user='import', $absolute_time=TRUE, $rm=TRUE, $gateway_version='1.9', $sleep_time=10)
__construct($path, $name, $url, $pw='import', $user='import', $absolute_time=TRUE, $rm=TRUE, $gateway_version='1.9', $sleep_time=10)
save($values, $origin='', $type=0x41, $offset=0, $ts=0)
static parseFrame($frame, $ts=FALSE, $origin='', $rssi=FALSE)
static UINT32($value, $endianness=0)
static unpackUINT32($value, $endianness=0)
__construct($path, $max_chunk=5000, $max_time=60)
saveOriginFrame($origin, $frame, $ts=0)
static INT16($value, $endianness=0)
static unpackFLOAT32($value, $endianness=0)
saveDataFrame($values, $type=0x1, $offset=0, $ts=0)
static unpackINT32($value, $endianness=0)
static unpackUINT8($value)