1 package FS::part_export::grandstream;
3 use base 'FS::part_export';
4 use vars qw($DEBUG $me %info $GAPSLITE_HOME $JAVA_HOME);
9 use FS::CGI qw(rooturl);
14 $me = '[' . __PACKAGE__ . ']';
15 $GAPSLITE_HOME = '/usr/local/src/GS_CFG_GEN/';
17 my @java = qw( /usr/lib/jvm/default-java/ /usr/java/default/
18 /usr/lib/jvm/java-6-sun/
19 /usr/lib/jvm/java-1.4.2-gcj-4.1-1.4.2.0/
20 ); #add more common places distros and people put their JREs
22 $JAVA_HOME = (grep { -e $_ } @java)[0];
24 tie my %options, 'Tie::IxHash',
25 'upload' => { label=>'Enable upload to TFTP server via SSH',
28 'user' => { label=>'User name for SSH to TFTP server' },
29 'tftproot' => { label=>'Directory in which to upload configuration' },
30 'java_home' => { label=>'Path to java to be used',
33 'gapslite_home' => { label=>'Path to grandstream configuration tool',
34 default=>$GAPSLITE_HOME,
36 'template' => { label=>'Configuration template',
38 notes=>'Type or paste the configuration template here',
43 'svc' => [ qw( part_device ) ], # svc_phone
44 'desc' => 'Provision phone numbers to Grandstream Networks phones/ATAs',
45 'options' => \%options,
46 'notes' => 'Provision phone numbers to Grandstream Networks phones/ATAs. Requires a Java runtime environment and the Grandstream configuration tool to be installed.',
49 sub rebless { shift; }
51 sub gs_create_config {
52 my($self, $mac, %opt) = (@_);
54 if ( $FS::svc_Common::noexport_hack ) {
55 carp 'gs_create_config() suppressed by noexport_hack'
56 if $self->option('debug') || $DEBUG;
63 warn "gs_create_config called with mac of $mac\n" if $DEBUG;
64 $mac = sprintf('%012s', lc($mac));
65 my $dir = '%%%FREESIDE_CONF%%%/cache.'. $FS::UID::datasrc;
67 my $fh = new File::Temp(
68 TEMPLATE => "grandstream.$mac.XXXXXXXX",
73 my $filename = $fh->filename;
75 #my $template = new Text::Template (
77 # SOURCE => $self->option('template'),
78 # DELIMITERS => $delimiters,
82 #$template->compile or die "Can't compile template: $Text::Template::ERROR\n";
84 #my $config = $template->fill_in( HASH => { mac_addr => $mac } );
86 print $fh $self->option('template') or die "print failed: $!";
89 #system( "export GAPSLITE_HOME=$GAPSLITE_HOME; export JAVA_HOME=$JAVA_HOME; ".
90 # "cd $dir; $GAPSLITE_HOME/bin/encode.sh $mac $filename $dir/cfg$mac"
92 # or die "grandstream encode failed: $!";
94 my @cmd = ( "$JAVA_HOME/bin/java",
95 '-classpath', "$GAPSLITE_HOME/lib/gapslite.jar:$GAPSLITE_HOME/lib/bcprov-jdk14-124.jar:$GAPSLITE_HOME/config",
96 'com.grandstream.cmd.TextEncoder',
97 $mac, $filename, "$dir/cfg$mac",
99 run \@cmd, '>&', \$out_and_err
100 or die "grandstream encode failed: $out_and_err";
104 open my $encoded, "$dir/cfg$mac" or die "open cfg$mac failed: $!";
109 if ($self->option('upload')) {
110 my $scp = new Net::SCP ( {
111 'host' => $self->machine,
112 'user' => $self->option('user'),
113 'cwd' => $self->option('tftproot'),
116 $scp->put( "$dir/cfg$mac" ) or die "upload failed: ". $scp->errstr;
120 $content = <$encoded>;
124 unlink "$dir/cfg$mac";
130 my($self, $mac) = (shift, shift);
132 return unless $mac; # be more alarmed? Or check upstream?
134 $self->gs_create_config($mac, 'upload' => 1);
139 my($self, $mac) = (shift, shift);
141 if ( $FS::svc_Common::noexport_hack ) {
142 carp 'gs_delete() suppressed by noexport_hack'
143 if $self->option('debug') || $DEBUG;
147 $mac = sprintf('%012s', lc($mac));
149 ssh_cmd( user => $self->option('user'),
150 host => $self->machine,
152 args => [ '-f', $self->option('tftproot'). "/cfg$mac" ],
158 sub ssh_cmd { #subroutine, not method
160 &Net::SSH::ssh_cmd( { @_ } );
164 # my( $self, $svc_phone ) = (shift, shift);
165 # $self->gs_create($svc_phone->mac_addr);
169 sub _export_replace {
170 # my( $self, $new_svc, $old_svc ) = (shift, shift, shift);
171 # $self->gs_delete($old_svc->mac_addr);
172 # $self->gs_create($new_svc->mac_addr);
177 # my( $self, $svc_phone ) = (shift, shift);
178 # $self->gs_delete($svc_phone->mac_addr);
182 sub _export_suspend {
186 sub _export_unsuspend {
190 sub export_device_insert {
191 my( $self, $svc_phone, $phone_device ) = (shift, shift, shift);
192 $self->gs_create($phone_device->mac_addr);
196 sub export_device_delete {
197 my( $self, $svc_phone, $phone_device ) = (shift, shift, shift);
198 $self->gs_delete($phone_device->mac_addr);
202 sub export_device_config {
203 my( $self, $svc_phone, $phone_device ) = (shift, shift, shift);
206 # if ($phone_device) {
207 $mac = $phone_device->mac_addr;
209 # $mac = $svc_phone->mac_addr;
212 return '' unless $mac; # be more alarmed? Or check upstream?
214 $self->gs_create_config($mac);
218 sub export_device_replace {
219 my( $self, $svc_phone, $new_svc_or_device, $old_svc_or_device ) =
220 (shift, shift, shift, shift);
222 $self->gs_delete($old_svc_or_device->mac_addr);
223 $self->gs_create($new_svc_or_device->mac_addr);
229 my($self, $svc_phone, $arrayref) = (shift, shift, shift);
231 return; # remove if we actually support being an export for svc_phone;
233 my @deviceparts = map { $_->devicepart } $self->export_device;
234 my @devices = grep { my $part = $_->devicepart;
235 scalar( grep { $_ == $part } @deviceparts );
236 } $svc_phone->phone_device;
238 my $export = $self->exportnum;
239 my $fsurl = rooturl();
241 foreach my $device ( @devices ) {
242 next unless $device->mac_addr;
243 my $num = $device->devicenum;
245 qq!<A HREF="$fsurl/misc/phone_device_config.html?exportnum=$export;devicenum=$num">!.
246 qq! Phone config </A>!;
248 } elsif ($svc_phone->mac_addr) {
249 my $num = $svc_phone->svcnum;
251 qq!<A HREF="$fsurl/misc/phone_device_config.html?exportnum=$export;svcnum=$num">!.
252 qq! Phone config </A>!;
257 sub export_device_links {
258 my($self, $svc_phone, $device, $arrayref) = (shift, shift, shift, shift);
259 warn "export_device_links $self $svc_phone $device $arrayref\n" if $DEBUG;
260 return unless $device && $device->mac_addr;
261 my $export = $self->exportnum;
262 my $fsurl = rooturl();
263 my $num = $device->devicenum;
265 qq!<A HREF="$fsurl/misc/phone_device_config.html?exportnum=$export;devicenum=$num">!.
266 qq! Phone config </A>!;