Issues (843)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

require/class.AIS.php (13 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
$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
$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
$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) { }
162
		else {
163
			if($ascii>119) { }
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) {
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' || $type == 'Ro-Ro Cargo') 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' || $type == 'Bunkering Tanker') return 80;
367
		elseif ($type == 'Lpg Tanker' || $type == 'Lng 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 == 'Crew Boat') return 53;
373
		elseif ($type == 'Icebreaker') return 52;
374
		elseif ($type == 'Pollution Control Vessel') return 54;
375
		elseif ($type == 'Other Type') return 90;
376
		elseif ($type == 'Anchor Handling Vessel' || $type == 'Offshore Supply Ship' || $type == 'Research/Survey Vessel' || $type == 'Utility Vessel' || $type == 'Pipe Burying Vessel' || $type == 'Heavy Lift Vessel' || $type == 'Crane Ship' || $type == 'Buoy-laying Vessel') return 59;
377
		elseif ($type == 'Fish Carrier' || $type == 'Trawler' || $type == 'Trawlers' || $type == 'Fishing Vessel' || $type == 'Trawlers|unknown Not Fishing' || $type == 'Purse Seines|trawlers' || $type == 'Purse Seines' || $type == 'Trollers' || $type == 'Set Longlines' || $type == 'Set Gillnets|trawlers') return 30;
378
		else return 0;
379
	}
380
381
	public function process_ais_itu($_itu, $_len, $_filler, $aux /*, $ais_ch*/) {
0 ignored issues
show
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...
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...
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...
382
		global $port; // tcpip port...
383
		static $debug_counter = 0;
384
		$aisdata168='';//six bit array of ascii characters
385
		$ais_nmea_array = str_split($_itu); // convert to an array
386
		foreach ($ais_nmea_array as $value) {
387
			$dec = $this->ascii_2_dec($value);
388
			$bit8 = $this->asciidec_2_8bit($dec);
389
			$bit6 = $this->dec_2_6bit($bit8);
390
			//echo $value ."-" .$bit6 ."";
391
			$aisdata168 .=$bit6;
392
		}
393
		//echo $aisdata168 . "<br/>";
394
		//return $this->decode_ais($aisdata168, $aux);
395
		return $this->decode_ais($aisdata168);
396
	}
397
398
	// char* - AIS \r terminated string
399
	// TCP based streams which send messages in full can use this instead of calling process_ais_buf
400
	public function process_ais_raw($rawdata, $aux = '') { // return int
401
		static $num_seq; // 1 to 9
402
		static $seq; // 1 to 9
403
		static $pseq; // previous seq
404
		static $msg_sid = -1; // 0 to 9, indicate -1 at start state of device, do not process messages
405
		static $cmsg_sid; // current msg_sid
406
		static $itu; // buffer for ITU message
407
		//echo $rawdata."\n";
408
		$filler = 0; // fill bits (int)
409
		$chksum = 0;
410
		// raw data without the \n
411
		// calculate checksum after ! till *
412
		// assume 1st ! is valid
413
		// find * ensure that it is at correct position
414
		$end = strrpos ( $rawdata , '*' );
415
		if ($end === FALSE) return -1; // check for NULLS!!!
416
		$cs = substr( $rawdata, $end + 1 );
417
		if ( strlen($cs) != 2 ) return -1; // correct cs length
418
		$dcs = (int)hexdec( $cs );
419
		for ( $alias=1; $alias<$end; $alias++) $chksum ^= ord( $rawdata[$alias] ); // perform XOR for NMEA checksum
420
		if ( $chksum == $dcs ) { // NMEA checksum pass
421
			$pcs = explode(',', $rawdata);
422
			// !AI??? identifier
423
			if (!isset($pcs[1])) {
424
				echo "ERROR,INVALID_DATA ".time()." $rawdata\n";
425
				return -1;
426
			}
427
			$num_seq = (int)$pcs[1]; // number of sequences
428
			$seq = (int)$pcs[2]; // get sequence
429
			// get msg sequence id
430
			if ($pcs[3] == '') $msg_sid = -1; // non-multipart message, set to -1
431
			else $msg_sid = (int)$pcs[3]; // multipart message
432
			$ais_ch = $pcs[4]; // get AIS channel
0 ignored issues
show
$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...
433
			// message sequence checking
434
			if ($num_seq < 1 || $num_seq > 9) {
435
				echo "ERROR,INVALID_NUMBER_OF_SEQUENCES ".time()." $rawdata\n";
436
				return -1;
437
			} else if ($seq < 1 || $seq > 9) { // invalid sequences number
438
				echo "ERROR,INVALID_SEQUENCES_NUMBER ".time()." $rawdata\n";
439
				return -1;
440
			} else if ($seq > $num_seq) {
441
				echo "ERROR,INVALID_SEQUENCE_NUMBER_OR_INVALID_NUMBER_OF_SEQUENCES ".time()." $rawdata\n";
442
				return -1;
443
			} else { // sequencing ok, handle single/multi-part messaging
444
				if ($seq == 1) { // always init to 0 at first sequence
445
					$filler = 0; // ?
446
					$itu = ""; // init message length
447
					$pseq = 0; // note previous sequence number
448
					$cmsg_sid = $msg_sid; // note msg_sid
449
				}
450
				if ($num_seq > 1) { // for multipart messages
451
					if ($cmsg_sid != $msg_sid // different msg_sid
452
					    || $msg_sid == -1 // invalid initial msg_sid
453
					    || ($seq - $pseq) != 1 // not insequence
454
					) {  // invalid for multipart message
455
						$msg_sid = -1;
456
						$cmsg_sid = -1;
457
						echo "ERROR,INVALID_MULTIPART_MESSAGE ".time()." $rawdata\n";
458
						return -1;
459
					} else {
460
						$pseq++;
461
					}
462
				}
463
				$itu = $itu.$pcs[5]; // get itu message
464
				$filler += (int)$pcs[6][0]; // get filler
465
				if ($num_seq == 1 // valid single message
466
				    || $num_seq == $pseq // valid multi-part message
467
				) {
468
					/*
469
					if ($num_seq != 1) { // test
470
						echo $rawdata;
471
					}
472
					*/
473
					return $this->process_ais_itu($itu, strlen($itu), $filler, $aux /*, $ais_ch*/);
474
				}
475
			} // end process raw AIS string (checksum passed)
476
		}
477
		return -1;
478
	}
479
480
	// incoming data from serial or IP comms
481
	public function process_ais_buf($ibuf) {
482
		static $cbuf = "";
483
		$cbuf = $cbuf.$ibuf;
484
		$last_pos = 0;
485
		$result = new stdClass();
486
		while ( ($start = strpos($cbuf,"VDM",$last_pos)) !== FALSE) {
487
		//while ( ($start = strpos($cbuf,"!AI",$last_pos)) !== FALSE) {
488
			//DEBUG echo $cbuf;
489
			if ( ($end = strpos($cbuf,"\r\n", $start)) !== FALSE) { //TBD need to trim?
490
				$tst = substr($cbuf, $start - 3, ($end - $start + 3));
491
				//DEBUG echo "[$start $end $tst]\n";
492
				$result = $this->process_ais_raw( $tst, "" );
493
				$last_pos = $end + 1;
494
			} else break;
495
		}
496
		if ($last_pos > 0) $cbuf = substr($cbuf, $last_pos); // move...
497
		if (strlen($cbuf) > 1024) $cbuf = ""; // prevent overflow simple mode...
498
		return $result;
499
	}
500
501
	// incoming data from serial or IP comms
502
	public function process_ais_line($cbuf) {
503
		$result = new stdClass();
0 ignored issues
show
$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...
504
		$start = strpos($cbuf,"VDM");
505
		$tst = substr($cbuf, $start - 3);
506
		$result = $this->process_ais_raw( $tst, "" );
507
		return $result;
508
	}
509
510
	/* AIS Encoding
511
	*/
512
	private function mk_ais_lat( $lat ) {
513
		//$lat = 1.2569;
514
		if ($lat<0.0) {
515
			$lat = -$lat;
516
			$neg=true;
517
		} else $neg=false;
518
		$latd = 0x00000000;
0 ignored issues
show
$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...
519
		$latd = intval ($lat * 600000.0);
520
		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...
521
			$latd = ~$latd;
522
			$latd+=1;
523
			$latd &= 0x07FFFFFF;
524
		}
525
		return $latd;
526
	}
527
528
	private function mk_ais_lon( $lon ) {
529
		//$lon = 103.851;
530
		if ($lon<0.0) {
531
			$lon = -$lon;
532
			$neg=true;
533
		} else $neg=false;
534
		$lond = 0x00000000;
0 ignored issues
show
$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...
535
		$lond = intval ($lon * 600000.0);
536
		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...
537
			$lond = ~$lond;
538
			$lond+=1;
539
			$lond &= 0x0FFFFFFF;
540
		}
541
		return $lond;
542
	}
543
544
	private function char2bin($name, $max_len) {
545
		$len = strlen($name);
546
		if ($len > $max_len) $name = substr($name,0,$max_len);
547
		if ($len < $max_len) $pad = str_repeat('0', ($max_len - $len) * 6);
548
		else $pad = '';
549
		$rv = '';
550
		$ais_chars = array(
551
		    '@'=>0, 'A'=>1, 'B'=>2, 'C'=>3, 'D'=>4, 'E'=>5, 'F'=>6, 'G'=>7, 'H'=>8, 'I'=>9,
552
		    'J'=>10, 'K'=>11, 'L'=>12, 'M'=>13, 'N'=>14, 'O'=>15, 'P'=>16, 'Q'=>17, 'R'=>18, 'S'=>19,
553
		    'T'=>20, 'U'=>21, 'V'=>22, 'W'=>23, 'X'=>24, 'Y'=>25, 'Z'=>26, '['=>27, '\\'=>28, ']'=>29,
554
		    '^'=>30, '_'=>31, ' '=>32, '!'=>33, '\"'=>34, '#'=>35, '$'=>36, '%'=>37, '&'=>38, '\''=>39,
555
		    '('=>40, ')'=>41, '*'=>42, '+'=>43, ','=>44, '-'=>45, '.'=>46, '/'=>47, '0'=>48, '1'=>49,
556
		    '2'=>50, '3'=>51, '4'=>52, '5'=>53, '6'=>54, '7'=>55, '8'=>56, '9'=>57, ':'=>58, ';'=>59,
557
		    '<'=>60, '='=>61, '>'=>62, '?'=>63
558
		);
559
		// "
560
		$_a = str_split($name);
561
		if (!empty($_a)) {
562
			foreach ($_a as $_1) {
563
				if (isset($ais_chars[$_1])) $dec = $ais_chars[$_1];
564
				else $dec = 0;
565
				$bin = str_pad(decbin( $dec ), 6, '0', STR_PAD_LEFT);
566
				$rv .= $bin;
567
				//echo "$_1 $dec ($bin)<br/>";
568
			}
569
		}
570
		return $rv.$pad;
571
	}
572
573
	private function mk_ais($_enc, $_part=1,$_total=1,$_seq='',$_ch='A') {
574
		$len_bit = strlen($_enc);
575
		$rem6 = $len_bit % 6;
576
		$pad6_len = 0;
577
		if ($rem6) $pad6_len = 6 - $rem6;
578
		//echo  $pad6_len.'<br>';
579
		$_enc .= str_repeat("0", $pad6_len); // pad the text...
580
		$len_enc = strlen($_enc) / 6;
581
		//echo $_enc.' '.$len_enc.'<br/>';
582
		$itu = '';
583
		for ($i=0; $i<$len_enc; $i++) {
584
			$offset = $i * 6;
585
			$dec = bindec(substr($_enc,$offset,6));
586
			if ($dec < 40) $dec += 48;
587
			else $dec += 56;
588
			//echo chr($dec)." $dec<br/>";
589
			$itu .= chr($dec);
590
		}
591
		// add checksum
592
		$chksum = 0;
593
		$itu = "AIVDM,$_part,$_total,$_seq,$_ch,".$itu.",0";
594
		$len_itu = strlen($itu);
595
		for ($i=0; $i<$len_itu; $i++) {
596
			$chksum ^= ord( $itu[$i] );
597
		}
598
		$hex_arr = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
599
		$lsb = $chksum & 0x0F;
600
		if ($lsb >=0 && $lsb <= 15 ) $lsbc = $hex_arr[$lsb];
601
		else $lsbc = '0';
602
		$msb = (($chksum & 0xF0) >> 4) & 0x0F;
603
		if ($msb >=0 && $msb <= 15 ) $msbc = $hex_arr[$msb];
604
		else $msbc = '0';
605
		$itu = '!'.$itu."*{$msbc}{$lsbc}\r\n";
606
		return $itu;
607
	}
608
609
	public function parse($buffer) {
610
		$data = $this->process_ais_buf($buffer);
611
		if (!is_object($data)) return array();
612
		$result = array();
613
		if ($data->lon != 0) $result['longitude'] = $data->lon;
614
		if ($data->lat != 0) $result['latitude'] = $data->lat;
615
		$result['ident'] = trim($data->name);
616
		$result['timestamp'] = $data->ts;
617
		$result['mmsi'] = $data->mmsi;
618
		if ($data->sog != -1.0) $result['speed'] = $data->sog;
619
		if ($data->cog != 0) $result['heading'] = $data->cog;
620
		/*
621
		    $ro->cls = 0; // AIS class undefined, also indicate unparsed msg
622
		    $ro->id = bindec(substr($_aisdata,0,6));
623
		*/
624
		return $result;
625
	}
626
627
	public function mmsitype($mmsi) {
628
		if (strlen($mmsi) == 9) {
629
			if (substr($mmsi,0,3) == '974') return 'EPIRB (Emergency Position Indicating Radio Beacon) AIS';
630
			elseif (substr($mmsi,0,3) == '972') return 'MOB (Man Overboard) device';
631
			elseif (substr($mmsi,0,3) == '970') return 'AIS SART (Search and Rescue Transmitter)';
632
			elseif (substr($mmsi,0,3) == '111') return 'SAR (Search and Rescue) aircraft';
633
			elseif (substr($mmsi,0,2) == '98') return 'Auxiliary craft associated with a parent ship';
634
			elseif (substr($mmsi,0,2) == '99') return 'Aids to Navigation';
635
			elseif (substr($mmsi,0,2) == '00') return 'Coastal stations';
636
			elseif (substr($mmsi,0,1) == '0') return 'Group of ships';
637
			else return 'Ship';
638
		}
639
640
	
641
	}
642
643
	public function parse_line($buffer) {
644
		global $globalDebug;
645
		$result = array();
646
		$start = strpos($buffer,"VDM");
647
		$tst = substr($buffer, $start - 3);
648
		$data = $this->process_ais_raw( $tst, "" );
649
		if (!is_object($data)) {
650
			//if ($globalDebug) echo '==== Line format not supported : '.$buffer."\n";
651
			return array();
652
		}
653
		if ($data->lon != 0) $result['longitude'] = $data->lon;
654
		if ($data->lat != 0) $result['latitude'] = $data->lat;
655
		$result['ident'] = trim(str_replace('@','',$data->name));
656
		$result['timestamp'] = $data->ts;
657
		$result['mmsi'] = $data->mmsi;
658
		if (strlen($result['mmsi']) == 8 && substr($result['mmsi'],0,3) == '669') $result['mmsi'] = '3'.$result['mmsi'];
659
		$result['mmsi_type'] = $this->mmsitype($result['mmsi']);
660
		if ($data->sog != -1.0) $result['speed'] = $data->sog;
661
		if ($data->heading !== '') $result['heading'] = $data->heading;
662
		elseif ($data->cog != 0) $result['heading'] = $data->cog;
663
		if ($data->status != '') $result['status'] = $data->status;
664
		if ($data->statusid !== '') $result['statusid'] = $data->statusid;
665
		if ($data->type !== '') $result['type'] = $data->type;
666
		if ($data->typeid !== '') $result['typeid'] = $data->typeid;
667
		if ($data->imo !== '') $result['imo'] = $data->imo;
668
		if ($data->callsign !== '') $result['callsign'] = trim(str_replace('@','',$data->callsign));
669
		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 !== '') {
670
			$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');
671
			if ($eta_ts != '') $result['eta_ts'] = $eta_ts;
672
		} elseif (is_numeric($data->eta_hour) && is_numeric($data->eta_minute)) {
673
			$eta_ts = strtotime(date('Y-m-d').' '.sprintf("%02d",$data->eta_hour).':'.sprintf("%02d",$data->eta_minute).':00');
674
			if ($eta_ts != '') $result['eta_ts'] = $eta_ts;
675
		}
676
		if ($data->destination != '') {
677
			$dest = trim(str_replace('@','',$data->destination));
678
			if ($dest != '') $result['destination'] = $dest;
679
		}
680
		$result['all'] = (array) $data;
681
		/*
682
		    $ro->cls = 0; // AIS class undefined, also indicate unparsed msg
683
		    $ro->id = bindec(substr($_aisdata,0,6));
684
		*/
685
		return $result;
686
	}
687
	
688
	public function famaprs_to_ais($data) {
0 ignored issues
show
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...
689
		/*
690
		// In dev. Not yet finished.
691
		$result = array();
692
		$result['id'] = str_pad(decbin($data['id']),6,'0',STR_PAD_LEFT);
693
		$result['noidea'] = str_pad(decbin(0), 2, '0', STR_PAD_LEFT);
694
		$result['mmsi'] = str_pad(decbin($data['mmsi']),30,'0',STR_PAD_LEFT);
695
		//$result['noidea2'] = str_pad(decbin(0), 2, '0', STR_PAD_LEFT);
696
		$result['statusid'] = str_pad(decbin($data['status_id']),4,'0',STR_PAD_LEFT);
697
		//$result['statusid'] = str_pad(decbin($data['status_id']),2,'0',STR_PAD_LEFT);
698
		
699
		//$result['callsign'] = $this->char2bin($data['callsign'],20);
700
		if ($id >= 1 && $id <= 3) {
701
			$result['noidea2'] = str_pad(decbin(0), 8, '0', STR_PAD_LEFT);
702
			$result['sog'] = str_pad(decbin($data['speed']*10),10,'0',STR_PAD_LEFT);
703
			$result['longitude'] = str_pad(decbin($this->mk_ais_lon($data['longitude'])),28,'0',STR_PAD_LEFT);
704
			$result['latitude'] = str_pad(decbin($this->mk_ais_lat($data['latitude'])),27,'0',STR_PAD_LEFT);
705
			$result['cog'] = str_pad(decbin($data['heading']*10),12,'0',STR_PAD_LEFT);
706
		} else if ($id == 4) {
707
			//$ro->lon = $this->make_lonf(bindec(substr($_aisdata,79,28)));
708
			//$ro->lat = $this->make_latf(bindec(substr($_aisdata,107,27)));
709
			$result['longitude'] = str_pad(decbin($this->mk_ais_lon($data['longitude'])),28,'0',STR_PAD_LEFT);
710
			$result['latitude'] = str_pad(decbin($this->mk_ais_lat($data['latitude'])),27,'0',STR_PAD_LEFT);
711
		} else if ($id == 5) {
712
			$result['imo'] = str_pad(decbin($data['imo']),30,'0',STR_PAD_LEFT);
713
			$result['callsign'] = $this->char2bin($data['callsign'],42);
714
			$result['name'] = $this->char2bin($data['ident'],120);
715
			$ro->typeid = bindec(substr($_aisdata,232,8));
716
			$ro->type = $this->getShipType($ro->typeid);
717
			//$ro->to_bow = bindec(substr($_aisdata,240,9));
718
			//$ro->to_stern = bindec(substr($_aisdata,249,9));
719
			//$ro->to_port = bindec(substr($_aisdata,258,6));
720
			//$ro->to_starboard = bindec(substr($_aisdata,264,6));
721
			$ro->eta_month = bindec(substr($_aisdata,274,4));
722
			$ro->eta_day = bindec(substr($_aisdata,278,5));
723
			$ro->eta_hour = bindec(substr($_aisdata,283,5));
724
			$ro->eta_minute = bindec(substr($_aisdata,288,6));
725
			//$ro->draught = bindec(substr($_aisdata,294,8));
726
			$ro->destination = $this->binchar($_aisdata,302,120);
727
		} else if ($id == 9) {
728
			// Search and Rescue aircraft position report
729
		} else if ($id == 18) {
730
			$ro->sog = bindec(substr($_aisdata,46,10))/10;
731
			$ro->lon = $this->make_lonf(bindec(substr($_aisdata,57,28)));
732
			$ro->lat = $this->make_latf(bindec(substr($_aisdata,85,27)));
733
			$ro->cog = bindec(substr($_aisdata,112,12))/10;
734
			$ro->heading = bindec(substr($_aisdata,124,9));
735
			if ($ro->heading == 511) $ro->heading = '';
736
		} else if ($id == 19) {
737
			$ro->cog = bindec(substr($_aisdata,112,12))/10;
738
			$ro->sog = bindec(substr($_aisdata,46,10))/10;
739
			$ro->lon = str_pad($this->mk_ais_lon($data['longitude']),28,'0',STR_PAD_LEFT);
740
			$ro->lat = $this->mk_ais_lat(bindec(substr($_aisdata,89,27)));
741
			$ro->name = $this->binchar($_aisdata,143,120);
742
			$ro->cls = 2; // class B
743
			$ro->heading = bindec(substr($_aisdata,124,9));
744
			if ($ro->heading == 511) $ro->heading = '';
745
			$ro->typeid = bindec(substr($_aisdata,263,8));
746
			$ro->type = $this->getShipType($ro->typeid);
747
			//$ro->to_bow = bindec(substr($_aisdata,271,9));
748
			//$ro->to_stern = bindec(substr($_aisdata,280,9));
749
			//$ro->to_port = bindec(substr($_aisdata,289,6));
750
			//$ro->to_starboard = bindec(substr($_aisdata,295,6));
751
		} else if ($id == 21) {
752
			$ro->lon = $this->make_lonf(bindec(substr($_aisdata,164,28)));
753
			$ro->lat = $this->make_latf(bindec(substr($_aisdata,192,27)));
754
			$ro->name = $this->binchar($_aisdata,43,120);
755
			//$ro->to_bow = bindec(substr($_aisdata,219,9));
756
			//$ro->to_stern = bindec(substr($_aisdata,228,9));
757
			//$ro->to_port = bindec(substr($_aisdata,237,6));
758
			//$ro->to_starboard = bindec(substr($_aisdata,243,6));
759
		} else if ($id == 24) {
760
			$pn = bindec(substr($_aisdata,38,2));
761
			if ($pn == 0) {
762
				$ro->name = $this->binchar($_aisdata,40,120);
763
			}
764
			$ro->typeid = bindec(substr($_aisdata,40,8));
765
			$ro->type = $this->getShipType($ro->typeid);
766
			$ro->callsign = $this->binchar($_aisdata,90,42);
767
			//$ro->to_bow = bindec(substr($_aisdata,132,9));
768
			//$ro->to_stern = bindec(substr($_aisdata,141,9));
769
			//$ro->to_port = bindec(substr($_aisdata,150,6));
770
			//$ro->to_starboard = bindec(substr($_aisdata,156,6));
771
		} else if ($id == 27) {
772
			$ro->cog = bindec(substr($_aisdata,85,9));
773
			if ($ro->cog == 511) $ro->cog = 0.0;
774
			$ro->sog = bindec(substr($_aisdata,79,6));
775
			if ($ro->sog == 63) $ro->sog = 0.0;
776
			$ro->lon = $this->make_lonf(bindec(substr($_aisdata,44,18))*10);
777
			$ro->lat = $this->make_latf(bindec(substr($_aisdata,62,17))*10);
778
			$ro->cls = 1; // class A
779
		
780
		}
781
		$ro->statusid = bindec(substr($_aisdata,38,4));
782
		$ro->status = $this->getStatus($ro->statusid);
783
784
		return $this->mk_ais(implode('',$result));
785
		*/
786
	}
787
}
788