|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Ham::APRS::DeviceID;  | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Ham::APRS::DeviceID - APRS device identifier  | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SYNOPSIS  | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   use Ham::APRS::FAP qw(parseaprs);  | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   use Ham::APRS::DeviceID;  | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   use Data::Dumper;  | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $aprspacket = 'OH2RDP>APZMDR,OH2RDG*,WIDE:!6028.51N/02505.68E#PHG7220/RELAY,WIDE, OH2AP Jarvenpaa';  | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my %packet;  | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $retval = parseaprs($aprspacket, \%packet);  | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   if ($retval == 1) {  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   	Ham::APRS::DeviceID::identify(\%packet);  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   	  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   	if (defined $packet{'deviceid'}) {  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   	    print Dumper($packet{'deviceid'});  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   	}  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 ABSTRACT  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This module attempts to identify the manufacturer, model and   | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 software version of an APRS transmitter. It looks at details found  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 in the parsed APRS packet (as provided by Ham::APRS::FAP) and updates  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the hash with the identification information, if possible.  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The module comes with a device identification database, which is  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 simply a copy of the YAML master file maintained separately  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 at: L  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DESCRIPTION  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Unless a debugging mode is enabled, all errors and warnings are reported  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 through the API (as opposed to printing on STDERR or STDOUT), so that  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 they can be reported nicely on the user interface of an application.  | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This module requires a reasonably recent L module,  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L to load the device identification database and  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L for finding it.  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 EXPORT  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 None by default.  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 FUNCTION REFERENCE  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
54
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
1833451
 | 
 use strict;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
117
 | 
    | 
| 
55
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
13
 | 
 use warnings;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
121
 | 
    | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #use Data::Dumper;  | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 require Exporter;  | 
| 
60
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
1601
 | 
 use YAML::Tiny;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15417
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
198
 | 
    | 
| 
61
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
1880
 | 
 use File::ShareDir ':ALL';  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15835
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3596
 | 
    | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our @ISA = qw(Exporter);  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Items to export into callers namespace by default. Note: do not export  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # names by default without a very good reason. Use EXPORT_OK instead.  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Do not simply export all your public functions/methods/constants.  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # This allows declaration	use Ham::APRS::FAP ':all';  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # will save memory.  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ##our %EXPORT_TAGS = (  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ##	'all' => [ qw(  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ##  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ##	) ],  | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ##);  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our @EXPORT_OK = (  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ##	@{ $EXPORT_TAGS{'all'} },  | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'&identify',  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ##our @EXPORT = qw(  | 
| 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ##	  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ##);  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $VERSION = '2.02';  | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Preloaded methods go here.  | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # no debugging by default  | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $debug = 0;  | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %result_messages = (  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'unknown' => 'Unsupported packet format',  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'no_dstcall' => 'Packet has no destination callsign',  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'no_format' => 'Packet has no defined format',  | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'mice_no_comment' => 'Mic-e packet with no comment defined',  | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'mice_no_deviceid' => 'Mic-e packet with no device identifier in comment',  | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'no_id' => 'No device identification found',  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # these functions are used to report warnings and parser errors  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # from the module  | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _a_err($$;$)  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 {  | 
| 
108
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
 	my ($rethash, $errcode, $val) = @_;  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
110
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$rethash->{'deviceid_resultcode'} = $errcode;  | 
| 
111
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$rethash->{'deviceid_resultmsg'}  | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		= defined $result_messages{$errcode}  | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		? $result_messages{$errcode} : $errcode;  | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
115
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$rethash->{'deviceid_resultmsg'} .= ': ' . $val if (defined $val);  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
117
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	if ($debug > 0) {  | 
| 
118
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		warn "Ham::APRS::DeviceID ERROR $errcode: " . $rethash->{'deviceid_resultmsg'} . "\n";  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
121
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	return 0;  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _a_warn($$;$)  | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 {  | 
| 
126
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
 	my ($rethash, $errcode, $val) = @_;  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
128
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	push @{ $rethash->{'deviceid_warncodes'} }, $errcode;  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
130
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	if ($debug > 0) {  | 
| 
131
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		warn "Ham::APRS::DeviceID WARNING $errcode: "  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		    . (defined $result_messages{$errcode}  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		      ? $result_messages{$errcode} : $errcode)  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		    . (defined $val ? ": $val" : '')  | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		    . "\n";  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
138
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	return 0;  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item debug($enable)  | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Enables (debug(1)) or disables (debug(0)) debugging.  | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 When debugging is enabled, warnings and errors are emitted using the warn() function,  | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 which will normally result in them being printed on STDERR. Succesfully  | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 printed packets will be also printed on STDOUT in a human-readable  | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 format.  | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 When debugging is disabled, nothing will be printed on STDOUT or STDERR -  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 all errors and parsing results need to be collected from the returned  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 hash reference.  | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub debug($)  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 {  | 
| 
163
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
 	my $dval = shift @_;  | 
| 
164
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	if ($dval) {  | 
| 
165
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$debug = 1;  | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	} else {  | 
| 
167
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$debug = 0;  | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Prebaked responses for "legacy" devices, including the VX-8 which has a  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # space (0x20) character as the last byte, which commonly gets eaten by  | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # UI-View  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %response = (  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'd7' => {  | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'vendor' => 'Kenwood',  | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'model' => 'TH-D7',  | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'class' => 'ht',  | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'messaging' => 1,  | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	},  | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'd72' => {  | 
| 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'vendor' => 'Kenwood',  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'model' => 'TH-D72',  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'class' => 'ht',  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'messaging' => 1,  | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	},  | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'd700' => {  | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'vendor' => 'Kenwood',  | 
| 
191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'model' => 'TM-D700',  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'class' => 'rig',  | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'messaging' => 1,  | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	},  | 
| 
195
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'd710' => {  | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'vendor' => 'Kenwood',  | 
| 
197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'model' => 'TM-D710',  | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'class' => 'rig',  | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'messaging' => 1,  | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	},  | 
| 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'vx8' => {  | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'vendor' => 'Yaesu',  | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'model' => 'VX-8',  | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'class' => 'ht',  | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'messaging' => 1,  | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	},  | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'unknown' => {  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'vendor' => 'Unknown',  | 
| 
209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		'model' => 'Other Mic-E',  | 
| 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %mice_codes;  | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %fixed_dstcalls;  | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my @dstcall_regexps;  | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %regexp_prefix;  | 
| 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # init: load YAML definitions  | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _load_tocalls(@)  | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 {  | 
| 
225
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
29
 | 
 	my(@tcl) = @_;  | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
227
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
 	foreach my $t (@tcl) {  | 
| 
228
 | 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
312
 | 
 		my $tocall = $t->{'tocall'};  | 
| 
229
 | 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
254
 | 
 		delete $t->{'tocall'};  | 
| 
230
 | 
360
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
938
 | 
 		if ($tocall =~ /^[A-Z0-9]+$/) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
231
 | 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
145
 | 
 			$fixed_dstcalls{$tocall} = $t;  | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} elsif ($tocall =~ /^([A-Z0-9]+)([n\?\*]+)([A-Z0-9]*)$/) {  | 
| 
233
 | 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
221
 | 
 			my $prefix = $1;  | 
| 
234
 | 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
172
 | 
 			my $r = $2; # glob (n for numbers, ?/* for single/multi)  | 
| 
235
 | 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
180
 | 
 			my $suffix = $3;  | 
| 
236
 | 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
212
 | 
 			$r =~ s/n/\\d/g;  | 
| 
237
 | 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
339
 | 
 			$r =~ s/\?/./g;  | 
| 
238
 | 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
209
 | 
 			$r =~ s/\*/.*/g;  | 
| 
239
 | 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
256
 | 
 			$r = $prefix . '(' . $r . $suffix . ')';  | 
| 
240
 | 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
388
 | 
 			push @dstcall_regexps, [ $r, $t ];  | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} else {  | 
| 
242
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			die "tocall '$tocall' too hard to parse";  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _load_mice(@)  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 {  | 
| 
250
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
7
 | 
 	my(@tcl) = @_;  | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
252
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
 	foreach my $t (@tcl) {  | 
| 
253
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
 		my $suffix = $t->{'suffix'};  | 
| 
254
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
 		delete $t->{'suffix'};  | 
| 
255
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
85
 | 
 		$mice_codes{$suffix} = $t;  | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
259
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _load()  | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 {  | 
| 
262
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
8
 | 
 	my $src = dist_file('Ham-APRS-DeviceID', 'tocalls.yaml');  | 
| 
263
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
418
 | 
 	my $yaml = YAML::Tiny->new;  | 
| 
264
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
 	my $c = YAML::Tiny->read($src);  | 
| 
265
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
83511
 | 
 	if (!defined $c) {  | 
| 
266
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		die "Failed to read in $src: " . YAML::Tiny->errstr . "\n";  | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# get the first document of YAML  | 
| 
270
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
 	$c = $c->[0];  | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
272
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
 	_load_tocalls(@{ $c->{'tocalls'} });  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
    | 
| 
273
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 	_load_mice(@{ $c->{'mice'} });  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
    | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
278
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # init code: compile the regular expressions to speed up matching  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _compile_regexps()  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 {  | 
| 
283
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
12
 | 
 	for (my $i = 0; $i <= $#dstcall_regexps; $i++) {  | 
| 
284
 | 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
162
 | 
 		my $dmatch = $dstcall_regexps[$i];  | 
| 
285
 | 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
179
 | 
 		my($regexp, $response) = @$dmatch;  | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		  | 
| 
287
 | 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1618
 | 
 		my $compiled = qr/^$regexp$/;  | 
| 
288
 | 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
596
 | 
 		$dstcall_regexps[$i] = [ $regexp, $response, $compiled ];  | 
| 
289
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
290
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
293
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # init: optimize regexps with an initial hash lookup  | 
| 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
296
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _optimize_regexps()  | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 {  | 
| 
298
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
9
 | 
 	my @left;  | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
300
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
 	for (my $i = 0; $i <= $#dstcall_regexps; $i++) {  | 
| 
301
 | 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
162
 | 
 		my $dmatch = $dstcall_regexps[$i];  | 
| 
302
 | 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
192
 | 
 		my($regexp, $response, $compiled) = @$dmatch;  | 
| 
303
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		  | 
| 
304
 | 
258
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
466
 | 
 		if ($regexp =~ /^([^\(]{2,5})(\(.*)$/) {  | 
| 
305
 | 
258
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
357
 | 
 			if (!defined $regexp_prefix{$1} ) {  | 
| 
306
 | 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
649
 | 
 				$regexp_prefix{$1} = [ $dmatch ];  | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			} else {  | 
| 
308
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 				push @{ $regexp_prefix{$1} }, $dmatch;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
    | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} else {  | 
| 
311
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			push @left, $dmatch;  | 
| 
312
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			warn "optimize: leaving $regexp over\n";  | 
| 
313
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
316
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
 	@dstcall_regexps = @left;  | 
| 
317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
319
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 _load();  | 
| 
320
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 _compile_regexps();  | 
| 
321
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 _optimize_regexps();  | 
| 
322
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over  | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item identify($hashref)  | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
327
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Tries to identify the device.  | 
| 
328
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
331
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub identify($)  | 
| 
334
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 {  | 
| 
335
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
  
1
  
 | 
5008
 | 
 	my($p) = @_;  | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
337
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
 	$p->{'deviceid_resultcode'} = '';  | 
| 
338
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
339
 | 
22
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
33
 | 
 	return _a_err($p, 'no_format') if (!defined $p->{'format'});  | 
| 
340
 | 
22
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
31
 | 
 	return _a_err($p, 'no_dstcall') if (!defined $p->{'dstcallsign'});  | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
342
 | 
22
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
39
 | 
 	if ($p->{'format'} eq 'mice') {  | 
| 
343
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		#warn Dumper($p);  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		#warn "comment: " . $p->{'comment'} . "\n";  | 
| 
345
 | 
17
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
20
 | 
 		if (!defined $p->{'comment'}) {  | 
| 
346
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			return _a_err($p, 'mice_no_comment');  | 
| 
347
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
348
 | 
17
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
110
 | 
 		if ($p->{'comment'} =~ s/^>(.*)=$/$1/) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
349
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
 			$p->{'deviceid'} = $response{'d72'};  | 
| 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} elsif ($p->{'comment'} =~ s/^>//) {  | 
| 
351
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 			$p->{'deviceid'} = $response{'d7'};  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} elsif ($p->{'comment'} =~ s/^\](.*)=$/$1/) {  | 
| 
353
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
 			$p->{'deviceid'} = $response{'d710'};  | 
| 
354
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} elsif ($p->{'comment'} =~ s/^\]//) {  | 
| 
355
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 			$p->{'deviceid'} = $response{'d700'};  | 
| 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} elsif ($p->{'comment'} =~ s/^`(.*)_\s*$/$1/) {  | 
| 
357
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			# vx-8 has a space as the last character, which commonly gets eaten by ui-view,  | 
| 
358
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			# so handle it with a relaxed regexp  | 
| 
359
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
 			$p->{'deviceid'} = $response{'vx8'};  | 
| 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} elsif ($p->{'comment'} =~ /^([`\'])(.*)(..)$/) {  | 
| 
361
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
 			my($b, $s, $code) = ($1, $2, $3);  | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			  | 
| 
363
 | 
7
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
 			if (defined $mice_codes{$code}) {  | 
| 
364
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
 				$p->{'deviceid'} = $mice_codes{$code};  | 
| 
365
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
 				$p->{'comment'} = $s;  | 
| 
366
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			} else {  | 
| 
367
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 				$p->{'deviceid'} = $response{'unknown'};  | 
| 
368
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 				$p->{'comment'} = $s . $code;  | 
| 
369
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
370
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
14
 | 
 			$p->{'messaging'} = 1 if ($b eq '`');  | 
| 
371
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
372
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		  | 
| 
373
 | 
17
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
23
 | 
 		if ($p->{'deviceid'}) {  | 
| 
374
 | 
17
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
29
 | 
 			$p->{'messaging'} = 1 if ($p->{'deviceid'}->{'messaging'});  | 
| 
375
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
 			return 1;  | 
| 
376
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
377
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		  | 
| 
378
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		return _a_err($p, 'mice_no_deviceid');  | 
| 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
380
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
381
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
 	if (defined $fixed_dstcalls{$p->{'dstcallsign'}}) {  | 
| 
382
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 		$p->{'deviceid'} = $fixed_dstcalls{$p->{'dstcallsign'}};  | 
| 
383
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 		return 1;  | 
| 
384
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
385
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
386
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
 	foreach my $len (5, 4, 3, 2) {  | 
| 
387
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
 		my $prefix = substr($p->{'dstcallsign'}, 0, $len);  | 
| 
388
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
14
 | 
 		if (defined $regexp_prefix{$prefix}) {  | 
| 
389
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
 			foreach my $dmatch (@{ $regexp_prefix{$prefix} }) {  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
    | 
| 
390
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
 				my($regexp, $response, $compiled) = @$dmatch;  | 
| 
391
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				#warn "trying '$regexp' against " . $p->{'dstcallsign'} . "\n";  | 
| 
392
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
26
 | 
 				if ($p->{'dstcallsign'} =~ $compiled) {  | 
| 
393
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					#warn "match!\n";  | 
| 
394
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
 					my %copy = %{ $response };  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
    | 
| 
395
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
 					$p->{'deviceid'} = \%copy;  | 
| 
396
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  | 
| 
397
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
 					if ($response->{'version_regexp'}) {  | 
| 
398
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 						#warn "version_regexp set: $1 from " . $p->{'dstcallsign'} . " using " . $regexp . "\n";  | 
| 
399
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 						$p->{'deviceid'}->{'version'} = $1;  | 
| 
400
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 						delete $p->{'deviceid'}->{'version_regexp'};  | 
| 
401
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					}  | 
| 
402
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  | 
| 
403
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
 					return 1;  | 
| 
404
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				}  | 
| 
405
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
406
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
407
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
408
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
409
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	return _a_err($p, 'no_id');  | 
| 
410
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
411
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
412
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
413
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
414
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |