APRSMarine   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 43
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 43
rs 10
c 0
b 0
f 0
wmc 16
lcom 0
cbo 2

1 Method

Rating   Name   Duplication   Size   Complexity  
F addLiveMarineData() 0 41 16
1
<?php
2
/**
3
 * This class is part of FlightAirmap. It's used for APRS
4
 *
5
 * Copyright (c) Ycarus (Yannick Chabanois) at Zugaina <[email protected]>
6
 * Licensed under AGPL license.
7
 * For more information see: https://www.flightairmap.com/
8
*/
9
10
require_once(dirname(__FILE__).'/settings.php');
11
require_once(dirname(__FILE__).'/class.Common.php');
12
require_once(dirname(__FILE__).'/class.GeoidHeight.php');
13
14
class aprs {
15
	private $socket;
16
	private $connected = false;
17
18
	protected $symbols = array('/!' => 'Police',
19
		'/#' => 'DIGI',
20
		'/$' => 'Phone',
21
		'/%' => 'DX Cluster',
22
		'/&' => 'HF Gateway',
23
		"/'" => 'Aircraft (small)',
24
		'/(' => 'Mobile Satellite Station',
25
		'/)' => 'WheelChair',
26
		'/*' => 'Snowmobile',
27
		'/+' => 'Red Cross',
28
		'/,' => 'Reverse L Shape',
29
		'/-' => 'House QTH (VHF)',
30
		'/.' => 'X',
31
		'//' => 'Dot',
32
		'/0' => '0',
33
		'/1' => '1',
34
		'/2' => '2',
35
		'/3' => '3',
36
		'/4' => '4',
37
		'/5' => '5',
38
		'/6' => '6',
39
		'/7' => '7',
40
		'/8' => '8',
41
		'/9' => '9',
42
		'/:' => 'Fire',
43
		'/;' => 'Campground',
44
		'/<' => 'Motorcycle',
45
		'/=' => 'Railroad Engine',
46
		'/>' => 'Car',
47
		'/?' => 'Server for Files',
48
		'/@' => 'HC Future Predict',
49
		'/A' => 'Aid Station',
50
		'/B' => 'BBS',
51
		'/C' => 'Canoe',
52
		'/E' => 'Eyeball',
53
		'/G' => 'Grid Square',
54
		'/H' => 'Hotel',
55
		'/I' => 'TCP-IP',
56
		'/K' => 'School',
57
		'/M' => 'MacAPRS',
58
		'/N' => 'NTS Station',
59
		'/O' => 'Balloon',
60
		'/P' => 'Police',
61
		'/Q' => 'T.B.D.',
62
		'/R' => 'Recreational Vehicle',
63
		'/S' => 'Shuttle',
64
		'/T' => 'SSTV',
65
		'/U' => 'Bus',
66
		'/V' => 'ATV',
67
		'/W' => 'National Weather Service Site',
68
		'/X' => 'Helicopter',
69
		'/Y' => 'Yacht (Sail)',
70
		'/Z' => 'WinAPRS',
71
		'/[' => 'Jogger',
72
		'/]' => 'PBBS',
73
		'/^' => 'Large Aircraft',
74
		'/_' => 'Weather Station',
75
		'/`' => 'Dish Antenna',
76
		'/a' => 'Ambulance',
77
		'/b' => 'Bike',
78
		'/c' => 'T.B.D.',
79
		'/d' => 'Dial Garage (Fire Department)',
80
		'/e' => 'Horse (Equestrian)',
81
		'/f' => 'Firetruck',
82
		'/g' => 'Glider',
83
		'/h' => 'Hospital',
84
		'/i' => 'IOTA (Islands On The Air)',
85
		'/j' => 'Jeep',
86
		'/k' => 'Truck',
87
		'/l' => 'Laptop',
88
		'/m' => 'Mic-Repeater',
89
		'/n' => 'Node',
90
		'/o' => 'EOC',
91
		'/p' => 'Rover (Puppy)',
92
		'/q' => 'Grid SQ Shown Above 128 Miles',
93
		'/r' => 'Antenna',
94
		'/s' => 'Ship (Power Boat)',
95
		'/t' => 'Truck Stop',
96
		'/u' => 'Truck (18 Wheeler)',
97
		'/v' => 'Van',
98
		'/w' => 'Water Station',
99
		'/x' => 'xAPRS (UNIX)',
100
		'/y' => 'Yagi At QTH',
101
		'\!' => 'Emergency',
102
		'\#' => 'No. Digi',
103
		'\$' => 'Bank',
104
		'\&' => "No. Diam'd",
105
		"\'" => 'Crash site',
106
		'\(' => 'Cloudy',
107
		'\)' => 'MEO',
108
		'\*' => 'Snow',
109
		'\+' => 'Church',
110
		'\,' => 'Girl Scout',
111
		'\-' => 'Home (HF)',
112
		'\.' => 'Unknown Position',
113
		'\/' => 'Destination',
114
		'\0' => 'No. Circle',
115
		'\9' => 'Petrol Station',
116
		'\:' => 'Hail',
117
		'\;' => 'Park',
118
		'\<' => 'Gale Fl',
119
		'\>' => 'No. Car',
120
		'\?' => 'Info Kiosk',
121
		'\@' => 'Hurricane',
122
		'\A' => 'No. Box',
123
		'\B' => 'Snow blowing',
124
		'\C' => 'Cost Guard',
125
		'\D' => 'Drizzle',
126
		'\E' => 'Smoke',
127
		'\F' => 'Freeze Rain',
128
		'\G' => 'Snow Shower',
129
		'\H' => 'Haze',
130
		'\I' => 'Rain Shower',
131
		'\J' => 'Lightning',
132
		'\K' => 'Kenwood',
133
		'\L' => 'Lighthouse',
134
		'\N' => 'Nav Buoy',
135
		'\O' => 'Rocket',
136
		'\P' => 'Parking',
137
		'\Q' => 'Quake',
138
		'\R' => 'Restaurant',
139
		'\S' => 'Sat/Pacsat',
140
		'\T' => 'Thunderstorm',
141
		'\U' => 'Sunny',
142
		'\V' => 'VORTAC',
143
		'\W' => 'No. WXS',
144
		'\X' => 'Pharmacy',
145
		'\[' => 'Wall Cloud',
146
		'\^' => 'No. Plane',
147
		'\_' => 'No. WX Stn',
148
		'\`' => 'Rain',
149
		'\a' => 'No. Diamond',
150
		'\b' => 'Dust Blowing',
151
		'\c' => 'No. CivDef',
152
		'\d' => 'DX Spot',
153
		'\e' => 'Sleet',
154
		'\f' => 'Funnel Cld',
155
		'\g' => 'Gale',
156
		'\h' => 'HAM store',
157
		'\i' => 'No. Black Box',
158
		'\j' => 'WorkZone',
159
		'\k' => 'SUV',
160
		'\l' => 'Aera Locations',
161
		'\m' => 'Milepost',
162
		'\n' => 'No. Triang',
163
		'\o' => 'Circle sm',
164
		'\p' => 'Part Cloud',
165
		'\r' => 'Restrooms',
166
		'\s' => 'No. Boat',
167
		'\t' => 'Tornado',
168
		'\u' => 'No. Truck',
169
		'\v' => 'No. Van',
170
		'\w' => 'Flooding',
171
		'\y' => 'Sky Warn',
172
		'\z' => 'No. Shelter',
173
		'\{' => 'Fog',
174
		'\|' => 'TNC Stream SW',
175
		'\~' => 'TNC Stream SW');
176
177
	private function urshift($n, $s) {
178
		return ($n >= 0) ? ($n >> $s) :
179
		    (($n & 0x7fffffff) >> $s) | 
180
		    (0x40000000 >> ($s - 1));
181
	}
182
183
	/*
184
	 * Parse APRS line
185
	 * @param String $input APRS data
186
	 * @return Array Return parsed APRS data
187
	*/
188
	public function parse($input) {
189
		global $globalDebug;
190
		$debug = false;
191
		$result = array();
192
		$input_len = strlen($input);
193
		
194
		/* Find the end of header checking for NULL bytes while doing it. */
195
		$splitpos = strpos($input,':');
196
		
197
		/* Check that end was found and body has at least one byte. */
198
		if ($splitpos == 0 || $splitpos + 1 == $input_len || $splitpos === FALSE) {
199
			if ($globalDebug) echo '!!! APRS invalid : '.$input."\n";
200
			return false;
201
		}
202
		
203
		if ($debug) echo 'input : '.$input."\n";
204
		/* Save header and body. */
205
		$body = substr($input,$splitpos+1,$input_len);
206
		$body_len = strlen($body);
0 ignored issues
show
Unused Code introduced by
$body_len 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...
207
		$header = substr($input,0,$splitpos);
208
		if ($debug) echo 'header : '.$header."\n";
209
		
210
		/* Parse source, target and path. */
211
		//FLRDF0A52>APRS,qAS,LSTB
212
		if (preg_match('/^([A-Z0-9\\-]{1,9})>(.*)$/',$header,$matches)) {
213
			$ident = $matches[1];
214
			$all_elements = $matches[2];
215
			if ($ident == 'AIRCRAFT') {
216
				$result['format_source'] = 'famaprs';
217
				$result['source_type'] = 'modes';
218
			} elseif ($ident == 'MARINE') {
219
				$result['format_source'] = 'famaprs';
220
				$result['source_type'] = 'ais';
221
			} else {
222
				if ($debug) echo 'ident : '.$ident."\n";
223
				$result['ident'] = $ident;
224
			}
225
		} else {
226
			if ($debug) 'No ident'."\n";
227
			return false;
228
		}
229
		$elements = explode(',',$all_elements);
230
		$source = end($elements);
231
		$result['source'] = $source;
232
		foreach ($elements as $element) {
233
			if (preg_match('/^([a-zA-Z0-9-]{1,9})([*]?)$/',$element)) {
234
			//if ($element == 'TCPIP*') return false;
235
			} elseif (!preg_match('/^([0-9A-F]{32})$/',$element)) {
236
				if ($debug) echo 'element : '.$element."\n";
237
				return false;
238
			}
239
			/*
240
			} elseif (preg_match('/^([0-9A-F]{32})$/',$element)) {
241
				//echo "ok";
242
			} else {
243
				return false;
244
			}
245
			*/
246
		}
247
		
248
		$type = substr($body,0,1);
249
		if ($debug) echo 'type : '.$type."\n";
250
		if ($type == ';') {
251
			if (isset($result['source_type']) && $result['source_type'] == 'modes') {
252
				$result['address'] = trim(substr($body,1,9));
253
			} elseif (isset($result['source_type']) && $result['source_type'] == 'ais') {
254
				$result['mmsi'] = trim(substr($body,1,9));
255
			} else $result['ident'] = trim(substr($body,1,9));
256
		} elseif ($type == ',') {
257
			// Invalid data or test data
258
			return false;
259
		}
260
		
261
		// Check for Timestamp
262
		$find = false;
263
		$body_parse = substr($body,1);
264
		if (preg_match('/^;(.){9}\*/',$body,$matches)) {
265
			$body_parse = substr($body_parse,10);
266
			$find = true;
267
		}
268
		if (preg_match('/^`(.*)\//',$body,$matches)) {
269
			$body_parse = substr($body_parse,strlen($matches[1])-1);
270
			$find = true;
271
		}
272
		if (preg_match("/^'(.*)\//",$body,$matches)) {
273
			$body_parse = substr($body_parse,strlen($matches[1])-1);
274
			$find = true;
275
		}
276
		if (preg_match('/^([0-9]{2})([0-9]{2})([0-9]{2})([zh\\/])/',$body_parse,$matches)) {
277
			$find = true;
278
			$timestamp = $matches[0];
279
			if ($matches[4] == 'h') {
280
				$timestamp = strtotime(date('Ymd').' '.$matches[1].':'.$matches[2].':'.$matches[3]);
281
				/*
282
				if (time() + 3900 < $timestamp) $timestamp -= 86400;
283
				elseif (time() - 82500 > $timestamp) $timestamp += 86400;
284
				*/
285
			} elseif ($matches[4] == 'z' || $matches[4] == '/') {
286
				// This work or not ?
287
				$timestamp = strtotime(date('Ym').$matches[1].' '.$matches[2].':'.$matches[3]);
288
			}
289
			$body_parse = substr($body_parse,7);
290
			$result['timestamp'] = $timestamp;
291
		}
292
		if (preg_match('/^([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/',$body_parse,$matches)) {
293
			$find = true;
294
			$timestamp = strtotime(date('Y').$matches[1].$matches[2].' '.$matches[3].':'.$matches[4]);
295
			$body_parse = substr($body_parse,8);
296
			$result['timestamp'] = $timestamp;
297
		}
298
		//if (strlen($body_parse) > 19) {
299
		if (preg_match('/^([0-9]{2})([0-7 ][0-9 ]\\.[0-9 ]{2})([NnSs])(.)([0-9]{3})([0-7 ][0-9 ]\\.[0-9 ]{2})([EeWw])(.)/',$body_parse,$matches)) {
300
			$find = true;
301
			// 4658.70N/00707.78Ez
302
			$sind = strtoupper($matches[3]);
303
			$wind = strtoupper($matches[7]);
304
			$lat_deg = $matches[1];
305
			$lat_min = $matches[2];
306
			$lon_deg = $matches[5];
307
			$lon_min = $matches[6];
308
			$symbolll = $matches[4];
309
			//$symbol_table = $matches[4];
310
			$lat = intval($lat_deg);
311
			$lon = intval($lon_deg);
312
			if ($lat > 89 || $lon > 179) return false;
313
			/*
314
			    $tmp_5b = str_replace('.','',$lat_min);
315
			    if (preg_match('/^([0-9]{0,4})( {0,4})$/',$tmp_5b,$matches)) {
316
			        print_r($matches);
317
			    }
318
			    */
319
			$latitude = $lat + floatval($lat_min)/60;
320
			$longitude = $lon + floatval($lon_min)/60;
321
			if ($sind == 'S') $latitude = 0-$latitude;
322
			if ($wind == 'W') $longitude = 0-$longitude;
323
			$result['latitude'] = $latitude;
324
			$result['longitude'] = $longitude;
325
			$body_parse = substr($body_parse,18);
326
			$body_parse_len = strlen($body_parse);
0 ignored issues
show
Unused Code introduced by
$body_parse_len 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...
327
		}
328
		$body_parse_len = strlen($body_parse);
329
		if ($body_parse_len > 0) {
330
			/*
331
			if (!isset($result['timestamp']) && !isset($result['latitude'])) {
332
				$body_split = str_split($body);
333
				$symbol_code = $body_split[0];
334
				$body_parse = substr($body,1);
335
				$body_parse_len = strlen($body_parse);
336
			} else { 
337
			if ($find === false) {
338
				$body_split = str_split($body);
339
				$symbol_code = $body_split[0];
340
				$body_parse = substr($body,1);
341
				$body_parse_len = strlen($body_parse);
342
			} else { 
343
			*/
344
			if ($find) {
345
				$body_split = str_split($body_parse);
346
				$symbol_code = $body_split[0];
347
				if (!isset($symbolll) || $symbolll == '/') $symbol_code = '/'.$symbol_code;
348
				else $symbol_code = '\\'.$symbol_code;
349
				//'
350
				//if ($type != ';' && $type != '>') {
351
				if ($type != '') {
352
					$body_parse = substr($body_parse,1);
353
					$body_parse_len = strlen($body_parse);
354
					$result['symbol_code'] = $symbol_code;
355
					if (isset($this->symbols[$symbol_code])) $result['symbol'] = $this->symbols[$symbol_code];
356
					if ($symbol_code != '_') {
357
					}
358
					if ($body_parse_len >= 7) {
359
						if (preg_match('/^([0-9\\. ]{3})\\/([0-9\\. ]{3})/',$body_parse)) {
360
							$course = substr($body_parse,0,3);
361
							$tmp_s = intval($course);
362
							if ($tmp_s >= 1 && $tmp_s <= 360) $result['heading'] = intval($course);
363
							$speed = substr($body_parse,4,3);
364
							if ($speed != '...') {
365
								$result['speed'] = intval($speed);
366
							}
367
							$body_parse = substr($body_parse,7);
368
						}
369
						// Check PHGR, PHG, RNG
370
					} 
371
					/*
372
					else if ($body_parse_len > 0) {
373
						$rest = $body_parse;
374
					}
375
					*/
376
					if (strlen($body_parse) > 0) {
377
						if (preg_match('/\\/A=(-[0-9]{5}|[0-9]{6})/',$body_parse,$matches)) {
378
							$altitude = intval($matches[1]);
379
							$result['altitude'] = $altitude;
380
							//$body_parse = trim(substr($body_parse,strlen($matches[0])));
381
							$body_parse = trim(preg_replace('/\\/A=(-[0-9]{5}|[0-9]{6})/','',$body_parse));
382
						}
383
					}
384
					// Telemetry
385
					/*
386
					if (preg_match('/^([0-9]+),(-?)([0-9]{1,6}|[0-9]+\\.[0-9]+|\\.[0-9]+)?,(-?)([0-9]{1,6}|[0-9]+\\.[0-9]+|\\.[0-9]+)?,(-?)([0-9]{1,6}|[0-9]+\\.[0-9]+|\\.[0-9]+)?,(-?)([0-9]{1,6}|[0-9]+\\.[0-9]+|\\.[0-9]+)?,(-?)([0-9]{1,6}|[0-9]+\\.[0-9]+|\\.[0-9]+)?,([01]{0,8})/',$body_parse,$matches)) {
387
						// Nothing yet...
388
					}
389
					*/
390
					// DAO
391
					if (preg_match('/^!([0-9A-Z]{3})/',$body_parse,$matches)) {
392
						$dao = $matches[1];
393
						if (preg_match('/^([A-Z])([0-9]{2})/',$dao)) {
394
							$dao_split = str_split($dao);
395
							$lat_off = (($dao_split[1])-48.0)*0.001/60.0;
396
							$lon_off = (($dao_split[2])-48.0)*0.001/60.0;
397
							if ($result['latitude'] < 0) $result['latitude'] -= $lat_off;
398
							else $result['latitude'] += $lat_off;
399
							if ($result['longitude'] < 0) $result['longitude'] -= $lon_off;
400
							else $result['longitude'] += $lon_off;
401
						}
402
						$body_parse = substr($body_parse,6);
403
					}
404
					if (preg_match('/CS=([0-9A-Z_]*)/',$body_parse,$matches)) {
405
						$result['ident'] = str_replace('_',' ',$matches[1]);
406
					}
407
					if (preg_match('/SQ=([0-9]{4})/',$body_parse,$matches)) {
408
						$result['squawk'] = $matches[1];
409
					}
410
					if (preg_match('/AI=([0-9A-Z]{4})/',$body_parse,$matches)) {
411
						$result['aircraft_icao'] = $matches[1];
412
					}
413
					if (preg_match('/VR=([-0-9]*)/',$body_parse,$matches)) {
414
						$result['verticalrate'] = $matches[1];
415
					}
416
					if (preg_match('/TI=([0-9]*)/',$body_parse,$matches)) {
417
						$result['typeid'] = $matches[1];
418
					}
419
					if (preg_match('/SI=([0-9]*)/',$body_parse,$matches)) {
420
						$result['statusid'] = $matches[1];
421
					}
422
					if (preg_match('/IMO=([0-9]{7})/',$body_parse,$matches)) {
423
						$result['imo'] = $matches[1];
424
					}
425
					if (preg_match('/AD=([0-9]*)/',$body_parse,$matches)) {
426
						$result['arrival_date'] = $matches[1];
427
					}
428
					if (preg_match('/AC=([0-9A-Z_]*)/',$body_parse,$matches)) {
429
						$result['arrival_code'] = str_replace('_',' ',$matches[1]);
430
					}
431
					// OGN comment
432
					//if (preg_match('/^id([0-9A-F]{8}) ([+-])([0-9]{3,4})fpm ([+-])([0-9.]{3,4})rot (.*)$/',$body_parse,$matches)) {
433
					if (preg_match('/^id([0-9A-F]{8})/',$body_parse,$matches)) {
434
						$id = $matches[1];
435
						//$mode = substr($id,0,2);
436
						$address = substr($id,2);
437
						$addressType = (intval(substr($id,0,2),16))&3;
438
						if ($addressType == 0) $result['addresstype'] = "RANDOM";
439
						elseif ($addressType == 1) $result['addresstype'] = "ICAO";
440
						elseif ($addressType == 2) $result['addresstype'] = "FLARM";
441
						elseif ($addressType == 3) $result['addresstype'] = "OGN";
442
						$aircraftType = $this->urshift(((intval(substr($id,0,2),16)) & 0b1111100),2);
443
						$result['aircrafttype_code'] = $aircraftType;
444
						if ($aircraftType == 0) $result['aircrafttype'] = "UNKNOWN";
445
						elseif ($aircraftType == 1) $result['aircrafttype'] = "GLIDER";
446
						elseif ($aircraftType == 2) $result['aircrafttype'] = "TOW_PLANE";
447
						elseif ($aircraftType == 3) $result['aircrafttype'] = "HELICOPTER_ROTORCRAFT";
448
						elseif ($aircraftType == 4) $result['aircrafttype'] = "PARACHUTE";
449
						elseif ($aircraftType == 5) $result['aircrafttype'] = "DROP_PLANE";
450
						elseif ($aircraftType == 6) $result['aircrafttype'] = "HANG_GLIDER";
451
						elseif ($aircraftType == 7) $result['aircrafttype'] = "PARA_GLIDER";
452
						elseif ($aircraftType == 8) $result['aircrafttype'] = "POWERED_AIRCRAFT";
453
						elseif ($aircraftType == 9) $result['aircrafttype'] = "JET_AIRCRAFT";
454
						elseif ($aircraftType == 10) $result['aircrafttype'] = "UFO";
455
						elseif ($aircraftType == 11) $result['aircrafttype'] = "BALLOON";
456
						elseif ($aircraftType == 12) $result['aircrafttype'] = "AIRSHIP";
457
						elseif ($aircraftType == 13) $result['aircrafttype'] = "UAV";
458
						elseif ($aircraftType == 15) $result['aircrafttype'] = "STATIC_OBJECT";
459
						$stealth = (intval(substr($id,0,2), 16) & 0b10000000) != 0;
460
						$result['stealth'] = $stealth;
461
						$result['address'] = $address;
462
					}
463
					//Comment
464
					$result['comment'] = trim($body_parse);
465
					// parse weather
466
					if (preg_match('/^_{0,1}([0-9 \\.\\-]{3})\\/([0-9 \\.]{3})g([0-9 \\.]+)t(-{0,1}[0-9 \\.]+)/',$body_parse,$matches)) {
467
						$result['wind_dir'] = intval($matches[1]);
468
						$result['wind_speed'] = round(intval($matches[2])*1.60934,1);
469
						$result['wind_gust'] = round(intval($matches[3])*1.60934,1);
470
						$result['temp'] = round(5/9*((intval($matches[4]))-32),1);
471
						$body_parse = substr($body_parse,strlen($matches[0])+1);
472
					} elseif (preg_match('/^_{0,1}c([0-9 \\.\\-]{3})s([0-9 \\.]{3})g([0-9 \\.]+)t(-{0,1}[0-9 \\.]+)/',$body_parse,$matches)) {
473
						$result['wind_dir'] = intval($matches[1]);
474
						$result['wind_speed'] = round($matches[2]*1.60934,1);
475
						$result['wind_gust'] = round($matches[3]*1.60934,1);
476
						$result['temp'] = round(5/9*(($matches[4])-32),1);
477
						$body_parse = substr($body_parse,strlen($matches[0])+1);
478
					} elseif (preg_match('/^_{0,1}([0-9 \\.\\-]{3})\\/([0-9 \\.]{3})t(-{0,1}[0-9 \\.]+)/',$body_parse,$matches)) {
479
						$result['wind_dir'] = intval($matches[1]);
480
						$result['wind_speed'] = round($matches[2]*1.60934,1);
481
						$result['wind_gust'] = round($matches[3]*1.60934,1);
482
						$body_parse = substr($body_parse,strlen($matches[0])+1);
483
					} elseif (preg_match('/^_{0,1}([0-9 \\.\\-]{3})\\/([0-9 \\.]{3})g([0-9 \\.]+)/',$body_parse,$matches)) {
484
						$result['wind_dir'] = intval($matches[1]);
485
						$result['wind_speed'] = round($matches[2]*1.60934,1);
486
						$result['wind_gust'] = round($matches[3]*1.60934,1);
487
						$body_parse = substr($body_parse,strlen($matches[0])+1);
488
					}
489
					// temperature
490
					//g012t088r000p000P000h38b10110
491
					//g011t086r000p000P000h29b10198
492
					if (!isset($result['temp']) && strlen($body_parse) > 0 && preg_match('/^g([0-9 \\.]{3})t([0-9 \\.]{3,4})r([0-9 \\.]{3})p([0-9 \\.]{3})P([0-9 \\.]{3})h([0-9 \\.]{2,3})b([0-9 \\.]{5})/',$body_parse,$matches)) {
493
						if ($matches[1] != '...') $result['wind_gust'] = round($matches[1]*1.60934,1);
494
						if ($matches[2] != '...') $result['temp'] = round(5/9*((intval($matches[2]))-32),1);
495
						if ($matches[3] != '...') $result['rain'] = round((intval($matches[3])/100)*25.1,1);
496
						if ($matches[4] != '...') $result['precipitation'] = round((intval($matches[4])/100)*25.1,1);
497
						if ($matches[5] != '...') $result['precipitation24h'] = round((intval($matches[5])/100)*25.1,1);
498
						if ($matches[6] != '...') $result['humidity'] = intval($matches[6]);
499
						if ($matches[7] != '...') $result['pressure'] = round((intval($matches[7])/10),1);
500
						$body_parse = substr($body_parse,strlen($matches[0]));
501
					} elseif (!isset($result['temp']) && strlen($body_parse) > 0 && preg_match('/^g([0-9 \\.]{3})t([0-9 \\.]{3,4})r([0-9 \\.]{3})P([0-9 \\.]{3})p([0-9 \\.]{3})h([0-9 \\.]{2,3})b([0-9 \\.]{5})/',$body_parse,$matches)) {
502
						if ($matches[1] != '...') $result['wind_gust'] = round($matches[1]*1.60934,1);
503
						if ($matches[2] != '...') $result['temp'] = round(5/9*((intval($matches[2]))-32),1);
504
						if ($matches[3] != '...') $result['rain'] = round((intval($matches[3])/100)*25.1,1);
505
						if ($matches[5] != '...') $result['precipitation'] = round((intval($matches[5])/100)*25.1,1);
506
						if ($matches[4] != '...') $result['precipitation24h'] = round((intval($matches[4])/100)*25.1,1);
507
						if ($matches[6] != '...') $result['humidity'] = intval($matches[6]);
508
						if ($matches[7] != '...') $result['pressure'] = round((intval($matches[7])/10),1);
509
						$body_parse = substr($body_parse,strlen($matches[0]));
510
					} elseif (!isset($result['temp']) && strlen($body_parse) > 0 && preg_match('/^g([0-9 \\.]{3})t([0-9 \\.]{3})r([0-9 \\.]{3})p([0-9 \\.]{3})P([0-9 \\.]{3})b([0-9 \\.]{5})h([0-9 \\.]{2})/',$body_parse,$matches)) {
511
						if ($matches[1] != '...') $result['wind_gust'] = round($matches[1]*1.60934,1);
512
						if ($matches[2] != '...') $result['temp'] = round(5/9*((intval($matches[2]))-32),1);
513
						if ($matches[3] != '...') $result['rain'] = round((intval($matches[3])/100)*25.1,1);
514
						if ($matches[4] != '...') $result['precipitation'] = round((intval($matches[4])/100)*25.1,1);
515
						if ($matches[5] != '...') $result['precipitation24h'] = round((intval($matches[5])/100)*25.1,1);
516
						if ($matches[7] != '...') $result['humidity'] = intval($matches[7]);
517
						if ($matches[6] != '...') $result['pressure'] = round((intval($matches[6])/10),1);
518
						$body_parse = substr($body_parse,strlen($matches[0]));
519
					} elseif (!isset($result['temp']) && strlen($body_parse) > 0 && preg_match('/^g([0-9 \\.]{3})t([0-9 \\.]{3})r([0-9 \\.]{3})P([0-9 \\.]{3})b([0-9 \\.]{5})h([0-9 \\.]{2})/',$body_parse,$matches)) {
520
						if ($matches[1] != '...') $result['wind_gust'] = round($matches[1]*1.60934,1);
521
						if ($matches[2] != '...') $result['temp'] = round(5/9*((intval($matches[2]))-32),1);
522
						if ($matches[3] != '...') $result['rain'] = round((intval($matches[3])/100)*25.1,1);
523
						if ($matches[4] != '...') $result['precipitation24h'] = round((intval($matches[4])/100)*25.1,1);
524
						if ($matches[6] != '...') $result['humidity'] = intval($matches[6]);
525
						if ($matches[5] != '...') $result['pressure'] = round((intval($matches[5])/10),1);
526
						$body_parse = substr($body_parse,strlen($matches[0]));
527
					} elseif (!isset($result['temp']) && strlen($body_parse) > 0 && preg_match('/^g([0-9 \\.]{3})t([0-9 \\.]{3})r([0-9 \\.]{3})p([0-9 \\.]{3})b([0-9 \\.]{5})h([0-9 \\.]{2})/',$body_parse,$matches)) {
528
						if ($matches[1] != '...') $result['wind_gust'] = round($matches[1]*1.60934,1);
529
						if ($matches[2] != '...') $result['temp'] = round(5/9*((intval($matches[2]))-32),1);
530
						if ($matches[3] != '...') $result['rain'] = round((intval($matches[3])/100)*25.1,1);
531
						if ($matches[4] != '...') $result['precipitation'] = round((intval($matches[4])/100)*25.1,1);
532
						if ($matches[6] != '...') $result['humidity'] = intval($matches[6]);
533
						if ($matches[5] != '...') $result['pressure'] = round((intval($matches[5])/10),1);
534
						$body_parse = substr($body_parse,strlen($matches[0]));
535
					} elseif (!isset($result['temp']) && strlen($body_parse) > 0 && preg_match('/^g([0-9 \\.]{3})t([0-9 \\.]{3})r([0-9 \\.]{3})p([0-9 \\.]{3})h([0-9 \\.]{2})b([0-9 \\.]{5})/',$body_parse,$matches)) {
536
						if ($matches[1] != '...') $result['wind_gust'] = round($matches[1]*1.60934,1);
537
						if ($matches[2] != '...') $result['temp'] = round(5/9*((intval($matches[2]))-32),1);
538
						if ($matches[3] != '...') $result['rain'] = round((intval($matches[3])/100)*25.1,1);
539
						if ($matches[4] != '...') $result['precipitation'] = round((intval($matches[4])/100)*25.1,1);
540
						if ($matches[5] != '...') $result['humidity'] = intval($matches[5]);
541
						if ($matches[6] != '...') $result['pressure'] = round((intval($matches[6])/10),1);
542
						$body_parse = substr($body_parse,strlen($matches[0]));
543
					} elseif (!isset($result['temp']) && strlen($body_parse) > 0 && preg_match('/^g([0-9 \\.]{3})t([0-9 \\.]{3})h([0-9 \\.]{2})b([0-9 \\.]{5})/',$body_parse,$matches)) {
544
						if ($matches[1] != '...') $result['wind_gust'] = round($matches[1]*1.60934,1);
545
						if ($matches[2] != '...') $result['temp'] = round(5/9*((intval($matches[2]))-32),1);
546
						if ($matches[2] != '...') $result['humidity'] = intval($matches[3]);
547
						if ($matches[4] != '...') $result['pressure'] = round((intval($matches[4])/10),1);
548
						$body_parse = substr($body_parse,strlen($matches[0]));
549
					} elseif (!isset($result['temp']) && strlen($body_parse) > 0 && preg_match('/^g([0-9 \\.]{3})t([0-9 \\.]{3})r([0-9 \\.]{2,3})h([0-9 \\.]{2})b([0-9 \\.]{5})/',$body_parse,$matches)) {
550
						if ($matches[1] != '...') $result['wind_gust'] = round($matches[1]*1.60934,1);
551
						if ($matches[2] != '...') $result['temp'] = round(5/9*((intval($matches[2]))-32),1);
552
						if ($matches[3] != '...') $result['rain'] = round((intval($matches[3])/100)*25.1,1);
553
						if ($matches[4] != '...') $result['humidity'] = intval($matches[4]);
554
						if ($matches[5] != '...') $result['pressure'] = round((intval($matches[5])/10),1);
555
						$body_parse = substr($body_parse,strlen($matches[0]));
556
					}
557
					$result['comment'] = trim($body_parse);
558
				}
559
			} else $result['comment'] = trim($body_parse);
560
		}
561
		if (isset($result['latitude'])) $result['latitude'] = round($result['latitude'],4);
562
		if (isset($result['longitude'])) $result['longitude'] = round($result['longitude'],4);
563
		if ($debug) print_r($result);
564
		return $result;
565
	}
566
567
	/*
568
	 * Connect to APRS server
569
	*/
570
	public function connect() {
571
		global $globalAPRSversion, $globalServerAPRSssid, $globalServerAPRSpass,$globalName, $globalServerAPRShost, $globalServerAPRSport;
572
		$aprs_connect = 0;
0 ignored issues
show
Unused Code introduced by
$aprs_connect 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...
573
		$aprs_keep = 120;
0 ignored issues
show
Unused Code introduced by
$aprs_keep 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...
574
		$aprs_last_tx = time();
0 ignored issues
show
Unused Code introduced by
$aprs_last_tx 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...
575
		if (isset($globalAPRSversion)) $aprs_version = $globalAPRSversion;
576
		else $aprs_version = 'FlightAirMap '.str_replace(' ','_',$globalName);
577
		if (isset($globalServerAPRSssid)) $aprs_ssid = $globalServerAPRSssid;
578
		else $aprs_ssid = substr('FAM'.strtoupper(str_replace(' ','_',$globalName)),0,8);
579
		if (isset($globalServerAPRSpass)) $aprs_pass = $globalServerAPRSpass;
580
		else $aprs_pass = '-1';
581
		$aprs_filter  = '';
0 ignored issues
show
Unused Code introduced by
$aprs_filter 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...
582
		$aprs_login = "user {$aprs_ssid} pass {$aprs_pass} vers {$aprs_version}\n";
583
		$Common = new Common();
584
		$s = $Common->create_socket($globalServerAPRShost,$globalServerAPRSport,$errno,$errstr);
585
		if ($s !== false) {
586
			echo 'Connected to APRS server! '."\n";
587
			$authstart = time();
588
			$this->socket = $s;
589
			$send = socket_send( $this->socket  , $aprs_login , strlen($aprs_login) , 0 );
0 ignored issues
show
Unused Code introduced by
$send 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...
590
			socket_set_option($this->socket,SOL_SOCKET,SO_KEEPALIVE,1);
591
			while ($msgin = socket_read($this->socket, 1000,PHP_NORMAL_READ)) {
592
				if (strpos($msgin, "$aprs_ssid verified") !== FALSE) {
593
					echo 'APRS user verified !'."\n";
594
					$this->connected = true;
595
					return true;
596
					break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
597
				}
598
				if (time()-$authstart > 5) {
599
					echo 'APRS timeout'."\n";
600
					break;
601
				}
602
			}
603
		}
604
	}
605
606
	/*
607
	 * Disconnect from APRS server
608
	*/
609
	public function disconnect() {
610
		socket_close($this->socket);
611
	}
612
613
	/*
614
	 * Send data to APRS server
615
	 * @param String $data Data to send
616
	*/
617
	public function send($data) {
618
		global $globalDebug;
619
		if ($this->connected === false) $this->connect();
620
		$send = socket_send( $this->socket  , $data , strlen($data),0);
621
		if ($send === FALSE) {
622
			if ($globalDebug) echo 'Reconnect...';
623
			socket_close($this->socket);
624
			$this->connect();
625
		}
626
	}
627
}
628
629
class APRSSpotter extends APRS {
630
	public function addLiveSpotterData($id,$ident,$aircraft_icao,$departure_airport,$arrival_airport,$latitude,$longitude,$waypoints,$altitude,$altitude_real,$heading,$speed,$datetime,$departure_airport_time,$arrival_airport_time,$squawk,$route_stop,$hex,$putinarchive,$registration,$pilot_id,$pilot_name, $verticalrate, $noarchive, $ground,$format_source,$source_name,$over_country) {
0 ignored issues
show
Unused Code introduced by
The parameter $id 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 $departure_airport 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 $arrival_airport 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 $waypoints 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 $altitude 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 $departure_airport_time 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 $arrival_airport_time 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 $route_stop 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 $putinarchive 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 $registration 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 $pilot_id 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 $pilot_name 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 $noarchive 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 $ground 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 $format_source 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 $source_name 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 $over_country 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...
631
		$Common = new Common();
632
		date_default_timezone_set('UTC');
633
		if ($latitude != '' && $longitude != '') {
634
			$lat = $latitude;
0 ignored issues
show
Unused Code introduced by
$lat 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...
635
			$long = $longitude;
0 ignored issues
show
Unused Code introduced by
$long 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...
636
			$latitude = $Common->convertDM($latitude,'latitude');
637
			$longitude = $Common->convertDM($longitude,'longitude');
638
			$coordinate = sprintf("%02d",$latitude['deg']).str_pad(number_format($latitude['min'],2,'.',''),5,'0',STR_PAD_LEFT).$latitude['NSEW'].'/'.sprintf("%03d",$longitude['deg']).str_pad(number_format($longitude['min'],2,'.',''),5,'0',STR_PAD_LEFT).$longitude['NSEW'];
639
			$w1 = abs(ceil(($latitude['min'] - number_format($latitude['min'],2,'.',''))*1000));
640
			$w2 = abs(ceil(($longitude['min'] - number_format($longitude['min'],2,'.',''))*1000));
641
			$w = $w1.$w2;
642
			//$w = '00';
643
			$custom = '';
644
			if ($ident != '') {
645
				if ($custom != '') $custom .= '/';
646
				$custom .= 'CS='.$ident;
647
			}
648
			if ($squawk != '') {
649
				if ($custom != '') $custom .= '/';
650
				$custom .= 'SQ='.$squawk;
651
			}
652
			if ($verticalrate != '') {
653
				if ($custom != '') $custom .= '/';
654
				$custom .= 'VR='.$verticalrate;
655
			}
656
			if ($aircraft_icao != '' && $aircraft_icao != 'NA') {
657
				if ($custom != '') $custom .= '/';
658
				$custom .= 'AI='.$aircraft_icao;
659
			}
660
			if ($custom != '') $custom = ' '.$custom;
661
			/*
662
			// Use AMSL altitude
663
			$GeoidClass = new GeoidHeight();
664
			$geoid= round($GeoidClass->get($lat,$long)*3.28084,2);
665
			$altitude_real = round($altitude_real + $geoid);
666
			*/
667
			$this->send('AIRCRAFT>APRS,TCPIP*:;'.$hex.'   *'.date('His',strtotime($datetime)).'h'.$coordinate.'^'.str_pad($heading,3,'0',STR_PAD_LEFT).'/'.str_pad($speed,3,'0',STR_PAD_LEFT).'/A='.str_pad($altitude_real,6,'0',STR_PAD_LEFT).' !W'.$w.'!'.$custom."\n");
668
		}
669
	}
670
}
671
class APRSMarine extends APRS {
672
	public function addLiveMarineData($id, $ident, $latitude, $longitude, $heading, $speed,$datetime, $putinarchive,$mmsi,$type,$typeid,$imo,$callsign,$arrival_code,$arrival_date,$status,$statusid,$noarchive,$format_source,$source_name,$over_country) {
0 ignored issues
show
Unused Code introduced by
The parameter $id 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 $putinarchive 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 $type 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 $callsign 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 $status 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 $noarchive 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 $format_source 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 $source_name 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 $over_country 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...
673
		$Common = new Common();
674
		date_default_timezone_set('UTC');
675
		if ($latitude != '' && $longitude != '') {
676
			$latitude = $Common->convertDM($latitude,'latitude');
677
			$longitude = $Common->convertDM($longitude,'longitude');
678
			$coordinate = sprintf("%02d",$latitude['deg']).str_pad(number_format($latitude['min'],2,'.',''),5,'0',STR_PAD_LEFT).$latitude['NSEW'].'/'.sprintf("%03d",$longitude['deg']).str_pad(number_format($longitude['min'],2,'.',''),5,'0',STR_PAD_LEFT).$longitude['NSEW'];
679
			$w1 = abs(ceil(($latitude['min'] - number_format($latitude['min'],2,'.',''))*1000));
680
			$w2 = abs(ceil(($longitude['min'] - number_format($longitude['min'],2,'.',''))*1000));
681
			$w = $w1.$w2;
682
			//$w = '00';
683
			$custom = '';
684
			if ($ident != '') {
685
				if ($custom != '') $custom .= '/';
686
				$custom .= 'CS='.str_replace(' ','_',$ident);
687
			}
688
			if ($typeid != '') {
689
				if ($custom != '') $custom .= '/';
690
				$custom .= 'TI='.$typeid;
691
			}
692
			if ($statusid != '') {
693
				if ($custom != '') $custom .= '/';
694
				$custom .= 'SI='.$statusid;
695
			}
696
			if ($imo != '') {
697
				if ($custom != '') $custom .= '/';
698
				$custom .= 'IMO='.$imo;
699
			}
700
			if ($arrival_date != '') {
701
				if ($custom != '') $custom .= '/';
702
				$custom .= 'AD='.strtotime($arrival_date);
703
			}
704
			if ($arrival_code != '') {
705
				if ($custom != '') $custom .= '/';
706
				$custom .= 'AC='.str_replace(' ','_',$arrival_code);
707
			}
708
			if ($custom != '') $custom = ' '.$custom;
709
			$altitude = 0;
710
			$this->send('MARINE>APRS,TCPIP*:;'.$mmsi.'*'.date('His',strtotime($datetime)).'h'.$coordinate.'s'.str_pad($heading,3,'0',STR_PAD_LEFT).'/'.str_pad($speed,3,'0',STR_PAD_LEFT).'/A='.str_pad($altitude,6,'0',STR_PAD_LEFT).' !W'.$w.'!'.$custom."\n");
711
		}
712
	}
713
}
714
//$aprs = new aprs();
715
//print_r($aprs->parse('MARINE>APRS,TCPIP*,qAS,FAMAIS-1:;366577000*145838h4739.48N/12222.14Ws222/000/A=000000 !W23! SI=5'));
716
//print_r($aprs->parse('MARINE>APRS,TCPIP*,qAS,FAMAIS-1:;413905111*121816h7959.29S/02626.78Es105/001/A=000000 !W15! CS=GUIPINGNANHUO5599/TI=70'));
717
718
?>