source: pmb4.2/trunk/fuentes/pmb/classes/sip2_trame.class.php @ 815

Last change on this file since 815 was 815, checked in by jrpelegrina, 4 years ago

Initial release of pmb 4.2

  • Property svn:executable set to *
File size: 11.8 KB
Line 
1<?php
2define("UNKNOWN_ORIGIN"                         , 1);
3define("UNKNOWN_MESSAGE_ID"                     , 2);
4define("UNKNOWN_MESSAGE_NAME"           , 3);
5define("INVALID_SEQUENCE_NUMBER"        , 4);
6define("MESSAGE_UNDEFINED"                      , 5);
7define("FIXED_FIELD_MISSING"            , 6);
8define("BAD_LENGTH_FIELD_VALUE"         , 7);
9define("FIELD_TOO_LARGE"                        , 8);
10define("UNKNOWN_FIELD"                          , 9);
11define("MISSING_FIELDS"                         ,10);
12define("CR_MISSING"                                     ,11);
13define("TRAME_TOO_SHORT"                        ,12);
14define("UNAUTHORIZED_FIELD"                     ,13);
15define("CS_AZ_MISSING"                          ,14);
16define("BAD_CHECKSUM"                           ,15);
17
18/**
19 * \brief Construit/Vérifie/Décompose les trames SIP2
20 *
21 * Gère les trames SIP2 en lecture / écriture / vérification en fonction des règles de la classe protocol
22 * \ingroup sip2_protocol
23 */
24class sip2_trame {
25        var $error=false;
26        var $error_code=0;
27        var $error_message="";
28        var $message_id=0;
29        var $proto;
30        var $message_structure;
31       
32        var $trame;
33        var $message_values=array();
34        var $message_name;
35        var $sequence_number=0;
36        var $from;
37        var $message_pair;
38        var $checksum;
39       
40        function message_exists($message_id) {
41                return $this->proto->messages[$message_id];
42        }
43       
44        function set_checksum($checksum=true) {
45                $this->checksum=true;
46        }
47       
48        function set_from($from) {
49                if (($from!='ACS')&&($from!='SC')) {
50                        $this->error=true;
51                        $this->error_code=UNKNOWN_ORIGIN;
52                        $this->error_message="La provenance du message doit être ACS ou SC";
53                        return false;
54                } else {
55                        $this->from=$from;
56                        return $from;
57                }
58        }
59       
60        function set_message_id($id) {
61                if ($this->message_structure=$this->message_exists($id)) {
62                        $this->message_id=$id;
63                        $this->message_name=$this->message_structure["NAME"];
64                        $from=$this->set_from($this->message_structure["FROM"]);
65                        if ($from) return $id; else return false;
66                } else {
67                        $this->error=true;
68                        $this->error_code=UNKNOWN_MESSAGE_ID;
69                        $this->error_message="Le numéro de message ".$id." n'existe pas";
70                        return false;
71                }
72        }
73       
74        function set_message($message_name) {
75                foreach($this->proto->messages as $id => $val) {
76                        if ($val["NAME"]==$message_name) {
77                                return $this->set_message_id($id);
78                        }
79                }
80                $this->error=true;
81                $this->error_code=UNKNOWN_MESSAGE_NAME;
82                $this->error_message="Message ".$message_name." inconnu";
83                return false;
84        }
85       
86        function set_sequence_number($sqn) {
87                if (((string)($sqn*1)!=(string)$sqn)||(strlen($sqn)!=1)) {
88                        $this->error=true;
89                        $this->error_code=INVALID_SEQUENCE_NUMBER;
90                        $this->error_message="Numéro de séquence ".$sqn." invalide";
91                        return false;
92                } else {
93                        $this->sequence_number=$sqn;
94                        return $sqn;
95                }
96        }
97       
98        function set_message_values($values) {
99                if (!$this->message_id) {
100                        $this->error=true;
101                        $this->error_code=MESSAGE_UNDEFINED;
102                        $this->error_message="Il n'y a pas de message défini !";
103                } else {
104                        $fixedf=$this->message_structure["FIXEDFIELDS"];
105                        //Vérification des champs fixes
106                        for ($i=0; $i<count($fixedf); $i++) {
107                                $v=$values[$fixedf[$i]];
108                                if ((string)$v=="") {
109                                        $this->error=true;
110                                        $this->error_code=FIXED_FIELD_MISSING;
111                                        $this->error_message="Il manque le champ fixe obligatoire ".$fixedf[$i];
112                                        return false;
113                                } else {
114                                        //Vérification de la longueur de la valeur
115                                        $field=$this->proto->fields[$fixedf[$i]];
116                                        if (strlen((string)$v)!=$field["LEN"]) {
117                                                $this->error=true;
118                                                $this->error_code=BAD_LENGTH_FIELD_VALUE;
119                                                $this->error_message="Le champ ".$fixedf[$i]." ne fait pas la bonne taille (".$field["LEN"].")";
120                                                return false;
121                                        }
122                                }
123                        }
124                        //Les champs fixes sont OK
125                        //Vérifications des autres
126                        $optionals=$this->message_structure["OPTIONALS"];
127                if (!$optionals) $optionals=array();
128                foreach($values as $ifield=>$val) {
129                        if (array_search($ifield,$this->message_structure["FIXEDFIELDS"])===false) {
130                                //Est-ce un champ connu ?
131                                if (array_search($ifield,$this->message_structure["FIELDS"])!==false) {
132                                        if (!$optionals[$ifield]) $optionals[$ifield]=1;
133                                        //Vérification de la conformité du champ
134                                        $field=$this->proto->fields[$ifield];
135                                        for ($v=0; $v<count($val); $v++) {
136                                                if ($field["TYPE"]=="identify_fixed") {
137                                                        if (strlen((string)$val[$v])!=$field["LEN"]) {
138                                                                $this->error=true;
139                                                                $this->error_code=BAD_LENGTH_FIELD_VALUE;
140                                                                        $this->error_message="Le champ ".$ifield." ne fait pas la bonne taille (".$field["LEN"].")";
141                                                                        return false;
142                                                        } 
143                                                } else {
144                                                        if (strlen((string)$val[$v])>$field["LEN"]) {
145                                                                $this->error=true;
146                                                                $this->error_code=FIELD_TOO_LARGE;
147                                                                        $this->error_message="Le champ ".$fixedf[$i]." est trop grand (>".$field["LEN"]." caractères)";
148                                                                        return false;
149                                                        } 
150                                                }
151                                        }
152                                } else {
153                                        $this->error=true;
154                                        $this->error_code=UNKNOWN_FIELD;
155                                        $this->error_message="Champ ".$ifield." inconnu dans ce message";
156                                        return false;
157                                }
158                        }
159                }
160                //Vérification des champs obligatoires
161                $all_opt=true;
162                $err_opt=array();
163                foreach ($optionals as $fo=>$opt_value) {
164                        $all_opt=(($all_opt)&&($opt_value));
165                        if (!$opt_value) $err_opt[]=$fo;
166                }
167                //Tous les champs obligatoires n'ont pas étés lus
168                if (!$all_opt) {
169                        $this->error=true;
170                        $this->error_code=MISSING_FIELDS;
171                        $this->error_message="Il manque le(s) champ(s) ".implode(",",$err_opt);
172                        return false;
173                }
174                }
175                $this->message_values=$values;
176        }
177       
178        function make_trame() {
179                $trame=$this->message_id;
180                //Ajout des champs fixes
181                $fixedf=$this->message_structure["FIXEDFIELDS"];
182                for ($i=0; $i<count($fixedf); $i++) {
183                        $trame.=$this->message_values[$fixedf[$i]];
184                }
185                //Champs identifiés
186                $fields=$this->message_structure["FIELDS"];
187                for ($i=0; $i<count($fields); $i++) {
188                        if ($this->message_values[$fields[$i]]) {
189                                for ($j=0; $j<count($this->message_values[$fields[$i]]); $j++) {
190                                        $trame.=$this->proto->fields[$fields[$i]]["IDENTIFIER"].$this->message_values[$fields[$i]][$j]."|";
191                                }
192                        }
193                }
194                if ($this->checksum) {
195                        $sum=0;
196                        if ($this->message_id!=96)
197                                $trame.="AY".$this->sequence_number."AZ";
198                        else
199                                $trame.="AZ";
200                        for ($i=0; $i<strlen($trame); $i++) {
201                                $sum+=ord($trame[$i]);
202                        }
203                        $sum=~$sum+1;
204                        $sum=$sum&65535;
205                        $sum=strtoupper(dechex($sum));
206                        $trame.=$sum."\r";
207                }
208                $this->trame=$trame;
209        }
210       
211    function sip2_trame($trame,$protocol) {
212        $this->proto=$protocol;
213        $this->trame=$trame;
214       
215        if ($trame) {
216                //Analyse de la trame
217                if ($trame[strlen($trame)-1]!=chr(0x0d)) {
218                        $this->error=true;
219                        $this->error_code=CR_MISSING;
220                        $this->error_message="<CR> attendu en fin de message";
221                        return;
222                } else {
223                        $trame=substr($trame,0,strlen($trame)-1);
224                }
225               
226                //Numéro de message
227                $message_id=substr($trame,0,2);
228                if ($this->message_structure=$this->message_exists($message_id)) {
229                        $this->message_id=substr($trame,0,2);
230                        $this->message_name=$this->message_structure["NAME"];
231                        $this->from=$this->message_structure["FROM"];
232                        $this->message_pair=($this->message_structure["REPLY_ID"]?$this->message_structure["REPLY_ID"]:$this->message_structure["REQUEST_ID"]);
233                        //Lecture des champs fixes
234                        $fixedf=$this->message_structure["FIXEDFIELDS"];
235                        $start_field=2;
236                        for ($i=0; $i<count($fixedf); $i++) {
237                                $field=$this->proto->fields[$fixedf[$i]];
238                                if (!$field) {
239                                        $this->error=true;
240                                        $this->error_code=FIXED_FIELD_MISSING;
241                                        $this->error_message="Le champ fixe ".$fixedf[$i]." est inexistant";
242                                        return;
243                                } else {
244                                        if (strlen($trame)<$start_field+$field["LEN"]) {
245                                                $this->error=true;
246                                                $this->error_code=TRAME_TOO_SHORT;
247                                                $this->error_message="La trame est trop courte";
248                                        } else {
249                                                $this->message_values[$fixedf[$i]]=substr($trame,$start_field,$field["LEN"]);
250                                                $start_field+=$field["LEN"];
251                                        }
252                                }
253                        }
254                        //Lecture des champs identifiés
255                        //Recherche des champs obligatoires
256                        $optionals=$this->message_structure["OPTIONALS"];
257                        if (!$optionals) $optionals=array();
258                        $fields=$this->message_structure["FIELDS"];
259                        if (!$fields) $fields=array();
260                        $flag_end=false;
261                        while (!$flag_end) {
262                                $end_field=strpos($trame,"|",$start_field);
263                                if ($end_field===false) {
264                                        $flag_end=true;
265                                        $end_field=strlen($trame);
266                                        if ($end_field==$start_field) $end_field=false;
267                                } else if ($end_field==$start_field) {
268                                                $start_field++;
269                                                $end_field=strlen($trame); 
270                                }
271                                if ($end_field!==false) {
272                                        $f=substr($trame,$start_field,$end_field-$start_field);
273                                        if ((substr($f,0,2)!="AY")&&((substr($f,0,2)!="AZ")||($this->message_id!=97))) {
274                                                $start_field=$end_field+1;
275                                                //Recherche du champ
276                                                $identifier=substr($f,0,2);
277                                                if ($this->proto->identifiers[$identifier]) {
278                                                        $fname=$this->proto->identifiers[$identifier];
279                                                        $field=$this->proto->fields[$fname];
280                                                        //Est-ce un champ autorisé ?
281                                                        if (array_search($fname,$fields)!==false) {
282                                                                $this->message_values[$fname][]=substr($f,2);
283                                                                if (!$optionals[$fname]) $optionals[$fname]=1;
284                                                        } else {
285                                                                $this->error=true;
286                                                                $this->error_code=UNAUTHORIZED_FIELD;
287                                                                $this->error_message="Le champ ".$fname." n'est pas autorisé pour le message ".$this->message_structure["NAME"]." (".$this->message_id.")";
288                                                                return;
289                                                        }
290                                                } else {
291                                                        //$this->error=true;
292                                                        //$this->error_code=UNKNOWN_FIELD;
293                                                        //$this->error_message="Champ ".$identifier." inexistant";
294                                                }
295                                        } else {
296                                                //Gestion du checksum
297                                                $this->checksum=true;
298                                                if ($this->message_id!=97) {
299                                                        if ((string)($f[2]*1)!=(string)$f[2]) {
300                                                                //Erreur, le numéro de séquence est faux
301                                                                $this->error=true;
302                                                                $this->error_code=BAD_SEQUENCE_NUMBER;
303                                                                $this->error_message="Le numéro de séquence n'est pas conforme";
304                                                                return;
305                                                        } else {
306                                                                $this->sequence_number=$f[2];
307                                                                $offset=3;
308                                                        }
309                                                } else {
310                                                        $this->sequence_number="";
311                                                        $offset=0;
312                                                }
313                                                //Récupération du checksum
314                                                if (substr($f,$offset,2)!="AZ") {
315                                                        $this->error=true;
316                                                        $this->error_code=CS_AZ_MISSING;
317                                                        $this->error_message="Champ checksum (AZ) attendu";
318                                                        return;
319                                                } else {
320                                                        $checksum=substr($f,$offset+2);
321                                                                //Calcul de la checksum
322                                                                $sum=0;
323                                                                for ($i=0; $i<strlen($trame)-4; $i++) {
324                                                                        $sum+=ord($trame[$i]);
325                                                                }
326                                                                $sum=($sum+hexdec($checksum))&65535;
327                                                                //Problème avec l'UTF-8
328                                                                global $charset;
329                                                                if (($sum!=0) && ($charset == "utf-8")) {
330                                                                        $trame=utf8_decode($trame);
331                                                                        //Calcul de la checksum
332                                                                        $sum=0;
333                                                                        for ($i=0; $i<strlen($trame)-4; $i++) {
334                                                                                $sum+=ord($trame[$i]);
335                                                                        }
336                                                                        $sum=($sum+hexdec($checksum))&65535;
337                                                                }
338                                                                if ($sum!=0) {
339                                                                        $this->error=true;
340                                                                        $this->error_code=BAD_CHEKCSUM;
341                                                                        $this->error_message="La checksum est fausse";
342                                                                        return;
343                                                                }
344                                                }
345                                        }
346                                } else $flag_end=true;
347                        }
348                        //Test que tous les champs obligatoires ont été lus
349                        $all_opt=true;
350                        $err_opt=array();
351                        foreach ($optionals as $fo=>$opt_value) {
352                                $all_opt=(($all_opt)&&($opt_value));
353                                if (!$opt_value) $err_opt[]=$fo;
354                        }
355                        //Tous les champs obligatoires n'ont pas étés lus
356                        if (!$all_opt) {
357                                $this->error=true;
358                                $this->error_code=MISSING_FIELDS;
359                                $this->error_message="Il manque le(s) champ(s) ".implode(",",$err_opt);
360                                return;
361                        }
362                } else {
363                        $this->error=true;
364                        $this->error_code=UNKNOWN_MESSAGE_ID;
365                        $this->error_message="Le message ".$message_id." est inconnu";
366                        return;
367                }
368        }
369    }
370}
371?>
Note: See TracBrowser for help on using the repository browser.