Completed
Push — master ( 9f9db9...be2090 )
by Yannick
32:30
created

AIS::getShipTypeID()   C

Complexity

Conditions 40
Paths 15

Size

Total Lines 18
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 40
eloc 17
nc 15
nop 1
dl 0
loc 18
rs 6.7804
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
Copyright 2014 Aaron Gong Hsien-Joen <[email protected]>
4
5
Licensed under the Apache License, Version 2.0 (the "License");
6
you may not use this file except in compliance with the License.
7
You may obtain a copy of the License at
8
9
    http://www.apache.org/licenses/LICENSE-2.0
10
11
Unless required by applicable law or agreed to in writing, software
12
distributed under the License is distributed on an "AS IS" BASIS,
13
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
See the License for the specific language governing permissions and
15
limitations under the License.
16
*/
17
/*
18
Modified in 2017 by Yannick Chabanois (Ycarus) <[email protected]>
19
Original version come from https://github.com/ais-one/phpais
20
*/
21
class AIS {
22
	protected $shiptype = array(0 => 'Not available (default)',
23
			20 => 'Wing in ground (WIG), all ships of this type',
24
			21 => 'Wing in ground (WIG), Hazardous category A',
25
			22 => 'Wing in ground (WIG), Hazardous category B',
26
			23 => 'Wing in ground (WIG), Hazardous category C',
27
			24 => 'Wing in ground (WIG), Hazardous category D',
28
			25 => 'Wing in ground (WIG), Reserved for future use',
29
			26 => 'Wing in ground (WIG), Reserved for future use',
30
			27 => 'Wing in ground (WIG), Reserved for future use',
31
			28 => 'Wing in ground (WIG), Reserved for future use',
32
			29 => 'Wing in ground (WIG), Reserved for future use',
33
			30 => 'Fishing',
34
			31 => 'Towing',
35
			32 => 'Towing: length exceeds 200m or breadth exceeds 25m',
36
			33 => 'Dredging or underwater ops',
37
			34 => 'Diving ops',
38
			35 => 'Military ops',
39
			36 => 'Sailing',
40
			37 => 'Pleasure Craft',
41
			38 => 'Reserved',
42
			39 => 'Reserved',
43
			40 => 'High speed craft (HSC), all ships of this type',
44
			41 => 'High speed craft (HSC), Hazardous category A',
45
			42 => 'High speed craft (HSC), Hazardous category B',
46
			43 => 'High speed craft (HSC), Hazardous category C',
47
			44 => 'High speed craft (HSC), Hazardous category D',
48
			45 => 'High speed craft (HSC), Reserved for future use',
49
			46 => 'High speed craft (HSC), Reserved for future use',
50
			47 => 'High speed craft (HSC), Reserved for future use',
51
			48 => 'High speed craft (HSC), Reserved for future use',
52
			49 => 'High speed craft (HSC), No additional information',
53
			50 => 'Pilot Vessel',
54
			51 => 'Search and Rescue vessel',
55
			52 => 'Tug',
56
			53 => 'Port Tender',
57
			54 => 'Anti-pollution equipment',
58
			55 => 'Law Enforcement',
59
			56 => 'Spare - Local Vessel',
60
			57 => 'Spare - Local Vessel',
61
			58 => 'Medical Transport',
62
			59 => 'Noncombatant ship according to RR Resolution No. 18',
63
			60 => 'Passenger, all ships of this type',
64
			61 => 'Passenger, Hazardous category A',
65
			62 => 'Passenger, Hazardous category B',
66
			63 => 'Passenger, Hazardous category C',
67
			64 => 'Passenger, Hazardous category D',
68
			65 => 'Passenger, Reserved for future use',
69
			66 => 'Passenger, Reserved for future use',
70
			67 => 'Passenger, Reserved for future use',
71
			68 => 'Passenger, Reserved for future use',
72
			69 => 'Passenger, No additional information',
73
			70 => 'Cargo, all ships of this type',
74
			71 => 'Cargo, Hazardous category A',
75
			72 => 'Cargo, Hazardous category B',
76
			73 => 'Cargo, Hazardous category C',
77
			74 => 'Cargo, Hazardous category D',
78
			75 => 'Cargo, Reserved for future use',
79
			76 => 'Cargo, Reserved for future use',
80
			77 => 'Cargo, Reserved for future use',
81
			78 => 'Cargo, Reserved for future use',
82
			79 => 'Cargo, No additional information',
83
			80 => 'Tanker, all ships of this type',
84
			81 => 'Tanker, Hazardous category A',
85
			82 => 'Tanker, Hazardous category B',
86
			83 => 'Tanker, Hazardous category C',
87
			84 => 'Tanker, Hazardous category D',
88
			85 => 'Tanker, Reserved for future use',
89
			86 => 'Tanker, Reserved for future use',
90
			87 => 'Tanker, Reserved for future use',
91
			88 => 'Tanker, Reserved for future use',
92
			89 => 'Tanker, No additional information',
93
			90 => 'Other Type, all ships of this type',
94
			91 => 'Other Type, Hazardous category A',
95
			92 => 'Other Type, Hazardous category B',
96
			93 => 'Other Type, Hazardous category C',
97
			94 => 'Other Type, Hazardous category D',
98
			95 => 'Other Type, Reserved for future use',
99
			96 => 'Other Type, Reserved for future use',
100
			97 => 'Other Type, Reserved for future use',
101
			98 => 'Other Type, Reserved for future use',
102
			99 => 'Other Type, no additional information');
103
104
105
106
107
108
109
110
/* AIS Decoding
111
- Receive and get ITU payload
112
- Organises the binary bits of the Payload into 6-bit strings,
113
- Converts the 6-bit strings into their representative "valid characters" – see IEC 61162-1, table 7,
114
- Assembles the valid characters into an encapsulation string, and
115
- Transfers the encapsulation string using the VDM sentence formatter.
116
*/
117
118
	private function make_latf($temp) { // unsigned long 
119
		$flat = 0.0; // float
0 ignored issues
show
Unused Code introduced by
$flat is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
120
		$temp = $temp & 0x07FFFFFF;
121
		if ($temp & 0x04000000) {
122
			$temp = $temp ^ 0x07FFFFFF;
123
			$temp += 1;
124
			$flat = (float)($temp / (60.0 * 10000.0));
125
			$flat *= -1.0;
126
		} else $flat = (float)($temp / (60.0 * 10000.0));
127
		return $flat; // float
128
	}
129
130
	private function make_lonf($temp) { // unsigned long
131
		$flon = 0.0; // float
0 ignored issues
show
Unused Code introduced by
$flon is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
132
		$temp = $temp & 0x0FFFFFFF;
133
		if ($temp & 0x08000000) {
134
			$temp = $temp ^ 0x0FFFFFFF;
135
			$temp += 1;
136
			$flon = (float)($temp / (60.0 * 10000.0));
137
			$flon *= -1.0;
138
		} else $flon = (float)($temp / (60.0 * 10000.0));
139
		return $flon;
140
	}
141
142
	private function ascii_2_dec($chr) {
143
		$dec=ord($chr);//get decimal ascii code
144
		$hex=dechex($dec);//convert decimal to hex
0 ignored issues
show
Unused Code introduced by
$hex is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
145
		return ($dec);
146
	}
147
	
148
    /*
149
    $ais_map64 = array(
150
       '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 48
151
       ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C',
152
       'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
153
       'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', // 87
154
       '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', // 96
155
       'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
156
       't', 'u', 'v', 'w' // 119
157
    ); // char 64
158
    */
159
	private function asciidec_2_8bit($ascii) {
160
		//only process in the following range: 48-87, 96-119
161
		if ($ascii < 48) { }
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
162
		else {
163
			if($ascii>119) { }
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
164
			else {
165
				if ($ascii>87 && $ascii<96) ;
166
				else {
167
					$ascii=$ascii+40;
168
					if ($ascii>128){
169
						$ascii=$ascii+32;
170
					} else {
171
						$ascii=$ascii+40;
172
					}
173
				}
174
			}
175
		}
176
		return ($ascii);
177
	}
178
179
	private function dec_2_6bit($dec) {
180
		$bin=decbin($dec);
181
		return(substr($bin, -6)); 
182
	}
183
184
	private function binchar($_str, $_start, $_size) {
185
		//  ' ' --- '?', // 0x20 - 0x3F
186
		//  '@' --- '_', // 0x40 - 0x5F
187
		$ais_chars = array(
188
		    '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
189
		    'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
190
		    'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']',
191
		    '^', '_', ' ', '!', '\"', '#', '$', '%', '&', '\'',
192
		    '(', ')', '*', '+', ',', '-', '.', '/', '0', '1',
193
		    '2', '3', '4', '5', '6', '7', '8', '9', ':', ';',
194
		    '<', '=', '>', '?'
195
		);
196
		// "
197
		$rv = '';
198
		if ($_size % 6 == 0) {
199
			$len = $_size / 6;
200
			for ($i=0; $i<$len; $i++) {
201
				$offset = $i * 6;
202
				$rv .= $ais_chars[ bindec(substr($_str,$_start + $offset,6)) ];
203
			}
204
		}
205
		return $rv;
206
	}
207
208
	// function for decoding the AIS Message ITU Payload
209
	private function decode_ais($_aisdata) {
210
		$ro = new stdClass(); // return object
211
		$ro->cls = 0; // AIS class undefined, also indicate unparsed msg
212
		$ro->name = '';
213
		$ro->status = '';
214
		$ro->callsign = '';
215
		$ro->imo = '';
216
		$ro->typeid = '';
217
		$ro->type = '';
218
		$ro->sog = -1.0;
219
		$ro->cog = 0.0;
220
		$ro->lon = 0.0;
221
		$ro->lat = 0.0;
222
		$ro->heading = '';
223
		$ro->destination = '';
224
		$ro->eta_month = '';
225
		$ro->eta_day = '';
226
		$ro->eta_hour = '';
227
		$ro->eta_minute = '';
228
		$ro->ts = time();
229
		$ro->id = bindec(substr($_aisdata,0,6));
230
		$ro->mmsi = bindec(substr($_aisdata,8,30));
231
		if ($ro->id >= 1 && $ro->id <= 3) {
232
			$ro->cog = bindec(substr($_aisdata,116,12))/10;
233
			$ro->sog = bindec(substr($_aisdata,50,10))/10;
234
			$ro->lon = $this->make_lonf(bindec(substr($_aisdata,61,28)));
235
			$ro->lat = $this->make_latf(bindec(substr($_aisdata,89,27)));
236
			$ro->cls = 1; // class A
237
		} else if ($ro->id == 4) {
238
			$ro->lon = $this->make_lonf(bindec(substr($_aisdata,79,28)));
239
			$ro->lat = $this->make_latf(bindec(substr($_aisdata,107,27)));
240
			$ro->cls = 1; // class A
241
		} else if ($ro->id == 5) {
242
			$ro->imo = bindec(substr($_aisdata,40,30));
243
			$ro->callsign = $this->binchar($_aisdata,70,42);
244
			$ro->name = $this->binchar($_aisdata,112,120);
245
			$ro->typeid = bindec(substr($_aisdata,232,8));
246
			$ro->type = $this->getShipType($ro->typeid);
247
			//$ro->to_bow = bindec(substr($_aisdata,240,9));
248
			//$ro->to_stern = bindec(substr($_aisdata,249,9));
249
			//$ro->to_port = bindec(substr($_aisdata,258,6));
250
			//$ro->to_starboard = bindec(substr($_aisdata,264,6));
251
			$ro->eta_month = bindec(substr($_aisdata,274,4));
252
			$ro->eta_day = bindec(substr($_aisdata,278,5));
253
			$ro->eta_hour = bindec(substr($_aisdata,283,5));
254
			$ro->eta_minute = bindec(substr($_aisdata,288,6));
255
			//$ro->draught = bindec(substr($_aisdata,294,8));
256
			$ro->destination = $this->binchar($_aisdata,302,120);
257
			$ro->cls = 1; // class A
258
		} else if ($ro->id == 9) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
259
			// Search and Rescue aircraft position report
260
		} else if ($ro->id == 18) {
261
			$ro->cog = bindec(substr($_aisdata,112,12))/10;
262
			$ro->sog = bindec(substr($_aisdata,46,10))/10;
263
			$ro->lon = $this->make_lonf(bindec(substr($_aisdata,57,28)));
264
			$ro->lat = $this->make_latf(bindec(substr($_aisdata,85,27)));
265
			$ro->heading = bindec(substr($_aisdata,124,9));
266
			if ($ro->heading == 511) $ro->heading = '';
267
			$ro->cls = 2; // class B
268
		} else if ($ro->id == 19) {
269
			$ro->cog = bindec(substr($_aisdata,112,12))/10;
270
			$ro->sog = bindec(substr($_aisdata,46,10))/10;
271
			$ro->lon = $this->make_lonf(bindec(substr($_aisdata,61,28)));
272
			$ro->lat = $this->make_latf(bindec(substr($_aisdata,89,27)));
273
			$ro->name = $this->binchar($_aisdata,143,120);
274
			$ro->cls = 2; // class B
275
			$ro->heading = bindec(substr($_aisdata,124,9));
276
			if ($ro->heading == 511) $ro->heading = '';
277
			$ro->typeid = bindec(substr($_aisdata,263,8));
278
			$ro->type = $this->getShipType($ro->typeid);
279
			//$ro->to_bow = bindec(substr($_aisdata,271,9));
280
			//$ro->to_stern = bindec(substr($_aisdata,280,9));
281
			//$ro->to_port = bindec(substr($_aisdata,289,6));
282
			//$ro->to_starboard = bindec(substr($_aisdata,295,6));
283
		} else if ($ro->id == 21) {
284
			$ro->lon = $this->make_lonf(bindec(substr($_aisdata,164,28)));
285
			$ro->lat = $this->make_latf(bindec(substr($_aisdata,192,27)));
286
			$ro->name = $this->binchar($_aisdata,43,120);
287
			//$ro->to_bow = bindec(substr($_aisdata,219,9));
288
			//$ro->to_stern = bindec(substr($_aisdata,228,9));
289
			//$ro->to_port = bindec(substr($_aisdata,237,6));
290
			//$ro->to_starboard = bindec(substr($_aisdata,243,6));
291
			$ro->cls = 2; // class B
292
		} else if ($ro->id == 24) {
293
			$pn = bindec(substr($_aisdata,38,2));
294
			if ($pn == 0) {
295
				$ro->name = $this->binchar($_aisdata,40,120);
296
			}
297
			$ro->typeid = bindec(substr($_aisdata,40,8));
298
			$ro->type = $this->getShipType($ro->typeid);
299
			$ro->callsign = $this->binchar($_aisdata,90,42);
300
			//$ro->to_bow = bindec(substr($_aisdata,132,9));
301
			//$ro->to_stern = bindec(substr($_aisdata,141,9));
302
			//$ro->to_port = bindec(substr($_aisdata,150,6));
303
			//$ro->to_starboard = bindec(substr($_aisdata,156,6));
304
			$ro->cls = 2; // class B
305
		} else if ($ro->id == 27) {
306
			$ro->cog = bindec(substr($_aisdata,85,9));
307
			if ($ro->cog == 511) $ro->cog = 0.0;
308
			$ro->sog = bindec(substr($_aisdata,79,6));
309
			if ($ro->sog == 63) $ro->sog = 0.0;
310
			$ro->lon = $this->make_lonf(bindec(substr($_aisdata,44,18))*10);
311
			$ro->lat = $this->make_latf(bindec(substr($_aisdata,62,17))*10);
312
			$ro->cls = 1; // class A
313
		
314
		}
315
		$ro->statusid = bindec(substr($_aisdata,38,4));
316
		$ro->status = $this->getStatus($ro->statusid);
317
		return $ro;
318
	}
319
320
	public function getStatus($statusid) {
321
		if ($statusid == 0) {
322
			return 'under way using engine';
323
		} elseif ($statusid == 1) {
324
			return 'at anchor';
325
		} elseif ($statusid == 2) {
326
			return 'not under command';
327
		} elseif ($statusid == 3) {
328
			return 'restricted maneuverability';
329
		} elseif ($statusid == 4) {
330
			return 'constrained by her draught';
331
		} elseif ($statusid == 5) {
332
			return 'moored';
333
		} elseif ($statusid == 6) {
334
			return 'aground';
335
		} elseif ($statusid == 7) {
336
			return 'engaged in fishing';
337
		} elseif ($statusid == 8) {
338
			return 'under way sailing';
339
		} elseif ($statusid == 9) {
340
			return 'reserved for future amendment of navigational status for ships carrying DG, HS, or MP, or IMO hazard or pollutant category C, high speed craft (HSC)';
341
		} elseif ($statusid == 10) {
342
			return 'reserved for future amendment of navigational status for ships carrying dangerous goods (DG), harmful substances (HS) or marine pollutants (MP), or IMO hazard or pollutant category A, wing in ground (WIG)';
343
		} elseif ($statusid == 11) {
344
			return 'power-driven vessel towing astern (regional use)';
345
		} elseif ($statusid == 12) {
346
			return 'power-driven vessel pushing ahead or towing alongside (regional use)';
347
		} elseif ($statusid == 13) {
348
			return 'reserved for future use';
349
		} elseif ($statusid == 14) {
350
			return 'AIS-SART (active), MOB-AIS, EPIRB-AIS';
351
		} elseif ($statusid == 15) {
352
			return 'undefined = default (also used by AIS-SART, MOB-AIS and EPIRB-AIS under test)';
353
		}
354
	}
355
	
356
	public function getShipType($code) {
357
		if (isset($this->shiptype[$code])) return $this->shiptype[$code];
358
		else return '';
359
	}
360
361
	public function getShipTypeID($type) {
362
		$typeid = array_search($type,$this->shiptype);
363
		if ($typeid !== FALSE) return $typeid;
364
		elseif ($type == 'Cargo' || $type == 'General Cargo' || $type == 'Bulk Carrier' || $type == 'Container Ship' || $type == 'Cargo A' || $type == 'Reefer' || $type == 'Vehicles Carrier') return 70;
365
		elseif ($type == 'Passengers Ship' || $type == 'Passenger' || $type == 'Ro-Ro/Passenger Ship' || $type == 'Motor Passenger') return 60;
366
		elseif ($type == 'Tanker' || $type == 'Crude Oil Tanker' || $type == 'Oil Products Tanker' || $type == 'Oil/Chemical Tanker') return 80;
367
		elseif ($type == 'Lpg Tanker') return 84;
368
		elseif ($type == 'Sailing Vessel') return 36;
369
		elseif ($type == 'Yacht') return 37;
370
		elseif ($type == 'Trailing Suction Hopper Dredger' || $type == 'Drilling Jack Up' || $type == 'Suction Dredger' || $type == 'Hopper Dredger') return 33;
371
		elseif ($type == 'High speed craft') return 40;
372
		elseif ($type == 'Icebreaker') return 52;
373
		elseif ($type == 'Pollution Control Vessel') return 54;
374
		elseif ($type == 'Other Type') return 90;
375
		elseif ($type == 'Anchor Handling Vessel' || $type == 'Offshore Supply Ship' || $type == 'Research/Survey Vessel' || $type == 'Utility Vessel' || $type == 'Pipe Burying Vessel') return 59;
376
		elseif ($type == 'Fish Carrier' || $type == 'Trawler' || $type == 'Trawlers' || $type == 'Fishing Vessel' || $type == 'Trawlers|unknown Not Fishing' || $type == 'Purse Seines|trawlers' || $type == 'Purse Seines') return 30;
377
		else return '';
378
	}
379
380
	public function process_ais_itu($_itu, $_len, $_filler, $aux /*, $ais_ch*/) {
0 ignored issues
show
Unused Code introduced by
The parameter $_len is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $_filler is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $aux is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
381
		global $port; // tcpip port...
382
		static $debug_counter = 0;
383
		$aisdata168='';//six bit array of ascii characters
384
		$ais_nmea_array = str_split($_itu); // convert to an array
385
		foreach ($ais_nmea_array as $value) {
386
			$dec = $this->ascii_2_dec($value);
387
			$bit8 = $this->asciidec_2_8bit($dec);
388
			$bit6 = $this->dec_2_6bit($bit8);
389
			//echo $value ."-" .$bit6 ."";
390
			$aisdata168 .=$bit6;
391
		}
392
		//echo $aisdata168 . "<br/>";
393
		//return $this->decode_ais($aisdata168, $aux);
394
		return $this->decode_ais($aisdata168);
395
	}
396
397
	// char* - AIS \r terminated string
398
	// TCP based streams which send messages in full can use this instead of calling process_ais_buf
399
	public function process_ais_raw($rawdata, $aux = '') { // return int
400
		static $num_seq; // 1 to 9
401
		static $seq; // 1 to 9
402
		static $pseq; // previous seq
403
		static $msg_sid = -1; // 0 to 9, indicate -1 at start state of device, do not process messages
404
		static $cmsg_sid; // current msg_sid
405
		static $itu; // buffer for ITU message
406
		//echo $rawdata."\n";
407
		$filler = 0; // fill bits (int)
408
		$chksum = 0;
409
		// raw data without the \n
410
		// calculate checksum after ! till *
411
		// assume 1st ! is valid
412
		// find * ensure that it is at correct position
413
		$end = strrpos ( $rawdata , '*' );
414
		if ($end === FALSE) return -1; // check for NULLS!!!
415
		$cs = substr( $rawdata, $end + 1 );
416
		if ( strlen($cs) != 2 ) return -1; // correct cs length
417
		$dcs = (int)hexdec( $cs );
418
		for ( $alias=1; $alias<$end; $alias++) $chksum ^= ord( $rawdata[$alias] ); // perform XOR for NMEA checksum
419
		if ( $chksum == $dcs ) { // NMEA checksum pass
420
			$pcs = explode(',', $rawdata);
421
			// !AI??? identifier
422
			if (!isset($pcs[1])) {
423
				echo "ERROR,INVALID_DATA ".time()." $rawdata\n";
424
				return -1;
425
			}
426
			$num_seq = (int)$pcs[1]; // number of sequences
427
			$seq = (int)$pcs[2]; // get sequence
428
			// get msg sequence id
429
			if ($pcs[3] == '') $msg_sid = -1; // non-multipart message, set to -1
430
			else $msg_sid = (int)$pcs[3]; // multipart message
431
			$ais_ch = $pcs[4]; // get AIS channel
0 ignored issues
show
Unused Code introduced by
$ais_ch is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
432
			// message sequence checking
433
			if ($num_seq < 1 || $num_seq > 9) {
434
				echo "ERROR,INVALID_NUMBER_OF_SEQUENCES ".time()." $rawdata\n";
435
				return -1;
436
			} else if ($seq < 1 || $seq > 9) { // invalid sequences number
437
				echo "ERROR,INVALID_SEQUENCES_NUMBER ".time()." $rawdata\n";
438
				return -1;
439
			} else if ($seq > $num_seq) {
440
				echo "ERROR,INVALID_SEQUENCE_NUMBER_OR_INVALID_NUMBER_OF_SEQUENCES ".time()." $rawdata\n";
441
				return -1;
442
			} else { // sequencing ok, handle single/multi-part messaging
443
				if ($seq == 1) { // always init to 0 at first sequence
444
					$filler = 0; // ?
445
					$itu = ""; // init message length
446
					$pseq = 0; // note previous sequence number
447
					$cmsg_sid = $msg_sid; // note msg_sid
448
				}
449
				if ($num_seq > 1) { // for multipart messages
450
					if ($cmsg_sid != $msg_sid // different msg_sid
451
					    || $msg_sid == -1 // invalid initial msg_sid
452
					    || ($seq - $pseq) != 1 // not insequence
453
					) {  // invalid for multipart message
454
						$msg_sid = -1;
455
						$cmsg_sid = -1;
456
						echo "ERROR,INVALID_MULTIPART_MESSAGE ".time()." $rawdata\n";
457
						return -1;
458
					} else {
459
						$pseq++;
460
					}
461
				}
462
				$itu = $itu.$pcs[5]; // get itu message
463
				$filler += (int)$pcs[6][0]; // get filler
464
				if ($num_seq == 1 // valid single message
465
				    || $num_seq == $pseq // valid multi-part message
466
				) {
467
					/*
468
					if ($num_seq != 1) { // test
469
						echo $rawdata;
470
					}
471
					*/
472
					return $this->process_ais_itu($itu, strlen($itu), $filler, $aux /*, $ais_ch*/);
473
				}
474
			} // end process raw AIS string (checksum passed)
475
		}
476
		return -1;
477
	}
478
479
	// incoming data from serial or IP comms
480
	public function process_ais_buf($ibuf) {
481
		static $cbuf = "";
482
		$cbuf = $cbuf.$ibuf;
483
		$last_pos = 0;
484
		$result = new stdClass();
485
		while ( ($start = strpos($cbuf,"VDM",$last_pos)) !== FALSE) {
486
		//while ( ($start = strpos($cbuf,"!AI",$last_pos)) !== FALSE) {
487
			//DEBUG echo $cbuf;
488
			if ( ($end = strpos($cbuf,"\r\n", $start)) !== FALSE) { //TBD need to trim?
489
				$tst = substr($cbuf, $start - 3, ($end - $start + 3));
490
				//DEBUG echo "[$start $end $tst]\n";
491
				$result = $this->process_ais_raw( $tst, "" );
492
				$last_pos = $end + 1;
493
			} else break;
494
		}
495
		if ($last_pos > 0) $cbuf = substr($cbuf, $last_pos); // move...
496
		if (strlen($cbuf) > 1024) $cbuf = ""; // prevent overflow simple mode...
497
		return $result;
498
	}
499
500
	// incoming data from serial or IP comms
501
	public function process_ais_line($cbuf) {
502
		$result = new stdClass();
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
503
		$start = strpos($cbuf,"VDM");
504
		$tst = substr($cbuf, $start - 3);
505
		$result = $this->process_ais_raw( $tst, "" );
506
		return $result;
507
	}
508
509
	/* AIS Encoding
510
	*/
511
	private function mk_ais_lat( $lat ) {
512
		//$lat = 1.2569;
513
		if ($lat<0.0) {
514
			$lat = -$lat;
515
			$neg=true;
516
		} else $neg=false;
517
		$latd = 0x00000000;
0 ignored issues
show
Unused Code introduced by
$latd is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
518
		$latd = intval ($lat * 600000.0);
519
		if ($neg==true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
520
			$latd = ~$latd;
521
			$latd+=1;
522
			$latd &= 0x07FFFFFF;
523
		}
524
		return $latd;
525
	}
526
527
	private function mk_ais_lon( $lon ) {
528
		//$lon = 103.851;
529
		if ($lon<0.0) {
530
			$lon = -$lon;
531
			$neg=true;
532
		} else $neg=false;
533
		$lond = 0x00000000;
0 ignored issues
show
Unused Code introduced by
$lond is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
534
		$lond = intval ($lon * 600000.0);
535
		if ($neg==true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
536
			$lond = ~$lond;
537
			$lond+=1;
538
			$lond &= 0x0FFFFFFF;
539
		}
540
		return $lond;
541
	}
542
543
	private function char2bin($name, $max_len) {
544
		$len = strlen($name);
545
		if ($len > $max_len) $name = substr($name,0,$max_len);
546
		if ($len < $max_len) $pad = str_repeat('0', ($max_len - $len) * 6);
547
		else $pad = '';
548
		$rv = '';
549
		$ais_chars = array(
550
		    '@'=>0, 'A'=>1, 'B'=>2, 'C'=>3, 'D'=>4, 'E'=>5, 'F'=>6, 'G'=>7, 'H'=>8, 'I'=>9,
551
		    'J'=>10, 'K'=>11, 'L'=>12, 'M'=>13, 'N'=>14, 'O'=>15, 'P'=>16, 'Q'=>17, 'R'=>18, 'S'=>19,
552
		    'T'=>20, 'U'=>21, 'V'=>22, 'W'=>23, 'X'=>24, 'Y'=>25, 'Z'=>26, '['=>27, '\\'=>28, ']'=>29,
553
		    '^'=>30, '_'=>31, ' '=>32, '!'=>33, '\"'=>34, '#'=>35, '$'=>36, '%'=>37, '&'=>38, '\''=>39,
554
		    '('=>40, ')'=>41, '*'=>42, '+'=>43, ','=>44, '-'=>45, '.'=>46, '/'=>47, '0'=>48, '1'=>49,
555
		    '2'=>50, '3'=>51, '4'=>52, '5'=>53, '6'=>54, '7'=>55, '8'=>56, '9'=>57, ':'=>58, ';'=>59,
556
		    '<'=>60, '='=>61, '>'=>62, '?'=>63
557
		);
558
		// "
559
		$_a = str_split($name);
560
		if ($_a) foreach ($_a as $_1) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $_a of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
561
			if (isset($ais_chars[$_1])) $dec = $ais_chars[$_1];
562
			else $dec = 0;
563
			$bin = str_pad(decbin( $dec ), 6, '0', STR_PAD_LEFT);
564
			$rv .= $bin;
565
			//echo "$_1 $dec ($bin)<br/>";
566
		}
567
		return $rv.$pad;
568
	}
569
570
	private function mk_ais($_enc, $_part=1,$_total=1,$_seq='',$_ch='A') {
571
		$len_bit = strlen($_enc);
572
		$rem6 = $len_bit % 6;
573
		$pad6_len = 0;
574
		if ($rem6) $pad6_len = 6 - $rem6;
575
		//echo  $pad6_len.'<br>';
576
		$_enc .= str_repeat("0", $pad6_len); // pad the text...
577
		$len_enc = strlen($_enc) / 6;
578
		//echo $_enc.' '.$len_enc.'<br/>';
579
		$itu = '';
580
		for ($i=0; $i<$len_enc; $i++) {
581
			$offset = $i * 6;
582
			$dec = bindec(substr($_enc,$offset,6));
583
			if ($dec < 40) $dec += 48;
584
			else $dec += 56;
585
			//echo chr($dec)." $dec<br/>";
586
			$itu .= chr($dec);
587
		}
588
		// add checksum
589
		$chksum = 0;
590
		$itu = "AIVDM,$_part,$_total,$_seq,$_ch,".$itu.",0";
591
		$len_itu = strlen($itu);
592
		for ($i=0; $i<$len_itu; $i++) {
593
			$chksum ^= ord( $itu[$i] );
594
		}
595
		$hex_arr = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
596
		$lsb = $chksum & 0x0F;
597
		if ($lsb >=0 && $lsb <= 15 ) $lsbc = $hex_arr[$lsb];
598
		else $lsbc = '0';
599
		$msb = (($chksum & 0xF0) >> 4) & 0x0F;
600
		if ($msb >=0 && $msb <= 15 ) $msbc = $hex_arr[$msb];
601
		else $msbc = '0';
602
		$itu = '!'.$itu."*{$msbc}{$lsbc}\r\n";
603
		return $itu;
604
	}
605
606
	public function parse($buffer) {
607
		$data = $this->process_ais_buf($buffer);
608
		if (!is_object($data)) return array();
609
		$result = array();
610
		if ($data->lon != 0) $result['longitude'] = $data->lon;
611
		if ($data->lat != 0) $result['latitude'] = $data->lat;
612
		$result['ident'] = trim($data->name);
613
		$result['timestamp'] = $data->ts;
614
		$result['mmsi'] = $data->mmsi;
615
		if ($data->sog != -1.0) $result['speed'] = $data->sog;
616
		if ($data->cog != 0) $result['heading'] = $data->cog;
617
		/*
618
		    $ro->cls = 0; // AIS class undefined, also indicate unparsed msg
619
		    $ro->id = bindec(substr($_aisdata,0,6));
620
		*/
621
		return $result;
622
	}
623
624
	public function mmsitype($mmsi) {
625
		if (strlen($mmsi) == 9) {
626
			if (substr($mmsi,0,3) == '974') return 'EPIRB (Emergency Position Indicating Radio Beacon) AIS';
627
			elseif (substr($mmsi,0,3) == '972') return 'MOB (Man Overboard) device';
628
			elseif (substr($mmsi,0,3) == '970') return 'AIS SART (Search and Rescue Transmitter)';
629
			elseif (substr($mmsi,0,3) == '111') return 'SAR (Search and Rescue) aircraft';
630
			elseif (substr($mmsi,0,2) == '98') return 'Auxiliary craft associated with a parent ship';
631
			elseif (substr($mmsi,0,2) == '99') return 'Aids to Navigation';
632
			elseif (substr($mmsi,0,2) == '00') return 'Coastal stations';
633
			elseif (substr($mmsi,0,1) == '0') return 'Group of ships';
634
			else return 'Ship';
635
		}
636
637
	
638
	}
639
640
	public function parse_line($buffer) {
641
		global $globalDebug;
642
		$result = array();
643
		$start = strpos($buffer,"VDM");
644
		$tst = substr($buffer, $start - 3);
645
		$data = $this->process_ais_raw( $tst, "" );
646
		if (!is_object($data)) {
647
			//if ($globalDebug) echo '==== Line format not supported : '.$buffer."\n";
648
			return array();
649
		}
650
		if ($data->lon != 0) $result['longitude'] = $data->lon;
651
		if ($data->lat != 0) $result['latitude'] = $data->lat;
652
		$result['ident'] = trim(str_replace('@','',$data->name));
653
		$result['timestamp'] = $data->ts;
654
		$result['mmsi'] = $data->mmsi;
655
		if (strlen($result['mmsi']) == 8 && substr($result['mmsi'],0,3) == '669') $result['mmsi'] = '3'.$result['mmsi'];
656
		$result['mmsi_type'] = $this->mmsitype($result['mmsi']);
657
		if ($data->sog != -1.0) $result['speed'] = $data->sog;
658
		if ($data->heading !== '') $result['heading'] = $data->heading;
659
		elseif ($data->cog != 0) $result['heading'] = $data->cog;
660
		if ($data->status != '') $result['status'] = $data->status;
661
		if ($data->statusid !== '') $result['statusid'] = $data->statusid;
662
		if ($data->type !== '') $result['type'] = $data->type;
663
		if ($data->typeid !== '') $result['typeid'] = $data->typeid;
664
		if ($data->imo !== '') $result['imo'] = $data->imo;
665
		if ($data->callsign !== '') $result['callsign'] = trim(str_replace('@','',$data->callsign));
666
		if (is_numeric($data->eta_month) && $data->eta_month != 0 && is_numeric($data->eta_day) && $data->eta_day != 0 && $data->eta_hour !== '' && $data->eta_minute !== '') {
667
			$eta_ts = strtotime(date('Y').'-'.sprintf("%02d",$data->eta_month).'-'.sprintf("%02d",$data->eta_day).' '.sprintf("%02d",$data->eta_hour).':'.sprintf("%02d",$data->eta_minute).':00');
668
			if ($eta_ts != '') $result['eta_ts'] = $eta_ts;
669
		} elseif (is_numeric($data->eta_hour) && is_numeric($data->eta_minute)) {
670
			$eta_ts = strtotime(date('Y-m-d').' '.sprintf("%02d",$data->eta_hour).':'.sprintf("%02d",$data->eta_minute).':00');
671
			if ($eta_ts != '') $result['eta_ts'] = $eta_ts;
672
		}
673
		if ($data->destination != '') {
674
			$dest = trim(str_replace('@','',$data->destination));
675
			if ($dest != '') $result['destination'] = $dest;
676
		}
677
		$result['all'] = (array) $data;
678
		/*
679
		    $ro->cls = 0; // AIS class undefined, also indicate unparsed msg
680
		    $ro->id = bindec(substr($_aisdata,0,6));
681
		*/
682
		return $result;
683
	}
684
	
685
	public function famaprs_to_ais($data) {
0 ignored issues
show
Unused Code introduced by
The parameter $data is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
686
		/*
687
		// In dev. Not yet finished.
688
		$result = array();
689
		$result['id'] = str_pad(decbin($data['id']),6,'0',STR_PAD_LEFT);
690
		$result['noidea'] = str_pad(decbin(0), 2, '0', STR_PAD_LEFT);
691
		$result['mmsi'] = str_pad(decbin($data['mmsi']),30,'0',STR_PAD_LEFT);
692
		//$result['noidea2'] = str_pad(decbin(0), 2, '0', STR_PAD_LEFT);
693
		$result['statusid'] = str_pad(decbin($data['status_id']),4,'0',STR_PAD_LEFT);
694
		//$result['statusid'] = str_pad(decbin($data['status_id']),2,'0',STR_PAD_LEFT);
695
		
696
		//$result['callsign'] = $this->char2bin($data['callsign'],20);
697
		if ($id >= 1 && $id <= 3) {
698
			$result['noidea2'] = str_pad(decbin(0), 8, '0', STR_PAD_LEFT);
699
			$result['sog'] = str_pad(decbin($data['speed']*10),10,'0',STR_PAD_LEFT);
700
			$result['longitude'] = str_pad(decbin($this->mk_ais_lon($data['longitude'])),28,'0',STR_PAD_LEFT);
701
			$result['latitude'] = str_pad(decbin($this->mk_ais_lat($data['latitude'])),27,'0',STR_PAD_LEFT);
702
			$result['cog'] = str_pad(decbin($data['heading']*10),12,'0',STR_PAD_LEFT);
703
		} else if ($id == 4) {
704
			//$ro->lon = $this->make_lonf(bindec(substr($_aisdata,79,28)));
705
			//$ro->lat = $this->make_latf(bindec(substr($_aisdata,107,27)));
706
			$result['longitude'] = str_pad(decbin($this->mk_ais_lon($data['longitude'])),28,'0',STR_PAD_LEFT);
707
			$result['latitude'] = str_pad(decbin($this->mk_ais_lat($data['latitude'])),27,'0',STR_PAD_LEFT);
708
		} else if ($id == 5) {
709
			$result['imo'] = str_pad(decbin($data['imo']),30,'0',STR_PAD_LEFT);
710
			$result['callsign'] = $this->char2bin($data['callsign'],42);
711
			$result['name'] = $this->char2bin($data['ident'],120);
712
			$ro->typeid = bindec(substr($_aisdata,232,8));
713
			$ro->type = $this->getShipType($ro->typeid);
714
			//$ro->to_bow = bindec(substr($_aisdata,240,9));
715
			//$ro->to_stern = bindec(substr($_aisdata,249,9));
716
			//$ro->to_port = bindec(substr($_aisdata,258,6));
717
			//$ro->to_starboard = bindec(substr($_aisdata,264,6));
718
			$ro->eta_month = bindec(substr($_aisdata,274,4));
719
			$ro->eta_day = bindec(substr($_aisdata,278,5));
720
			$ro->eta_hour = bindec(substr($_aisdata,283,5));
721
			$ro->eta_minute = bindec(substr($_aisdata,288,6));
722
			//$ro->draught = bindec(substr($_aisdata,294,8));
723
			$ro->destination = $this->binchar($_aisdata,302,120);
724
		} else if ($id == 9) {
725
			// Search and Rescue aircraft position report
726
		} else if ($id == 18) {
727
			$ro->sog = bindec(substr($_aisdata,46,10))/10;
728
			$ro->lon = $this->make_lonf(bindec(substr($_aisdata,57,28)));
729
			$ro->lat = $this->make_latf(bindec(substr($_aisdata,85,27)));
730
			$ro->cog = bindec(substr($_aisdata,112,12))/10;
731
			$ro->heading = bindec(substr($_aisdata,124,9));
732
			if ($ro->heading == 511) $ro->heading = '';
733
		} else if ($id == 19) {
734
			$ro->cog = bindec(substr($_aisdata,112,12))/10;
735
			$ro->sog = bindec(substr($_aisdata,46,10))/10;
736
			$ro->lon = str_pad($this->mk_ais_lon($data['longitude']),28,'0',STR_PAD_LEFT);
737
			$ro->lat = $this->mk_ais_lat(bindec(substr($_aisdata,89,27)));
738
			$ro->name = $this->binchar($_aisdata,143,120);
739
			$ro->cls = 2; // class B
740
			$ro->heading = bindec(substr($_aisdata,124,9));
741
			if ($ro->heading == 511) $ro->heading = '';
742
			$ro->typeid = bindec(substr($_aisdata,263,8));
743
			$ro->type = $this->getShipType($ro->typeid);
744
			//$ro->to_bow = bindec(substr($_aisdata,271,9));
745
			//$ro->to_stern = bindec(substr($_aisdata,280,9));
746
			//$ro->to_port = bindec(substr($_aisdata,289,6));
747
			//$ro->to_starboard = bindec(substr($_aisdata,295,6));
748
		} else if ($id == 21) {
749
			$ro->lon = $this->make_lonf(bindec(substr($_aisdata,164,28)));
750
			$ro->lat = $this->make_latf(bindec(substr($_aisdata,192,27)));
751
			$ro->name = $this->binchar($_aisdata,43,120);
752
			//$ro->to_bow = bindec(substr($_aisdata,219,9));
753
			//$ro->to_stern = bindec(substr($_aisdata,228,9));
754
			//$ro->to_port = bindec(substr($_aisdata,237,6));
755
			//$ro->to_starboard = bindec(substr($_aisdata,243,6));
756
		} else if ($id == 24) {
757
			$pn = bindec(substr($_aisdata,38,2));
758
			if ($pn == 0) {
759
				$ro->name = $this->binchar($_aisdata,40,120);
760
			}
761
			$ro->typeid = bindec(substr($_aisdata,40,8));
762
			$ro->type = $this->getShipType($ro->typeid);
763
			$ro->callsign = $this->binchar($_aisdata,90,42);
764
			//$ro->to_bow = bindec(substr($_aisdata,132,9));
765
			//$ro->to_stern = bindec(substr($_aisdata,141,9));
766
			//$ro->to_port = bindec(substr($_aisdata,150,6));
767
			//$ro->to_starboard = bindec(substr($_aisdata,156,6));
768
		} else if ($id == 27) {
769
			$ro->cog = bindec(substr($_aisdata,85,9));
770
			if ($ro->cog == 511) $ro->cog = 0.0;
771
			$ro->sog = bindec(substr($_aisdata,79,6));
772
			if ($ro->sog == 63) $ro->sog = 0.0;
773
			$ro->lon = $this->make_lonf(bindec(substr($_aisdata,44,18))*10);
774
			$ro->lat = $this->make_latf(bindec(substr($_aisdata,62,17))*10);
775
			$ro->cls = 1; // class A
776
		
777
		}
778
		$ro->statusid = bindec(substr($_aisdata,38,4));
779
		$ro->status = $this->getStatus($ro->statusid);
780
781
		return $this->mk_ais(implode('',$result));
782
		*/
783
	}
784
}
785