diff --git a/lib/Huawei/Hilink.pm b/lib/Huawei/Hilink.pm new file mode 100755 index 0000000000000000000000000000000000000000..79ee3d268bfbef45ef4a2add1b4685ee3720c069 --- /dev/null +++ b/lib/Huawei/Hilink.pm @@ -0,0 +1,252 @@ +#!/usr/bin/perl + +package Huawei::Hilink; + +use strict; + +use Data::Dumper; +$Data::Dumper::Indent= 1; + +use HTTP::Request; +use LWP::UserAgent; +use XML::Simple; + +my $verbose= 0; +my $debug= 0; + +my %queries= +( + 'information' => { api => '/api/device/information', auth => 'none' }, + 'signal' => { api => '/api/device/signal', auth => 'none' }, + 'module-switch' => { api => '/api/global/module-switch', auth => 'none' }, + 'current-plmn' => { api => '/api/net/current-plmn', auth => 'none' }, + 'net-mode' => { api => '/api/net/net-mode', auth => 'none' }, + 'basic-settings' => { api => '/api/wlan/basic-settings', auth => 'none' }, + 'converged-status' => { api => '/api/monitoring/converged-status', auth => 'none' }, + + 'traffic-statistics' => { api => '/api/monitoring/traffic-statistics', auth => 'token' }, + 'status' => { api => '/api/monitoring/status', auth => 'token' }, + + # does not work + 'sms-list' => { api => '/api/sms/sms-list', auth => 'token' }, + 'sms' => { api => '/api/sms', auth => 'none' }, + 'ussd' => { api => '/api/ussd/get', auth => 'none' }, + 'sdc' => { api => '/api/sdcard/sdcard', auth => 'none' }, +); + +__PACKAGE__->main() unless caller(); + +sub new +{ + my $class= shift; + my @pars= @_; + + my $self= bless ({}, $class); + $self->set(@_); +} + +sub set +{ + my $self= shift; + my %par= @_; + foreach my $par (keys %par) { $self->{$par}= $par{$par} } + $self; +} + +sub get_session +{ + my $self= shift; + + return ($self->{_session_id}, $self->{_token}) if (exists($self->{_session_id}) && exists ($self->{_token})); + + my $url= 'http://' . $self->{gwip} . '/api/webserver/SesTokInfo'; + my $ua= $self->{_ua} || ($self->{_ua}= new LWP::UserAgent()); + my $resp= $ua->get($url); + + unless ($resp->is_success) + { + print __LINE__, " ua failed: ", $resp->status_line, "\n"; + return (undef, undef); + } + my $sess= $resp->decoded_content; + + # print __LINE__, " sess=[$sess]\n" if ($debug); + my $ref= XMLin($sess); + # print __LINE__, " ref: ", Dumper($ref); + return ($self->{_session_id}= $ref->{SesInfo}, $self->{_token}= $ref->{TokInfo}) if (defined ($ref)); + + (undef, undef); +} + +sub send_sms +{ + my $self= shift; + my $phone= shift; + my $message= shift; + + my ($session_id, $token)= $self->get_session(); + unless (defined ($session_id)) + { + print __LINE__, " no session_id obtained\n" if ($debug); + return undef; + } + + print __LINE__, " send-sms phone=[$phone] message=[$message]\n" if ($debug); + + my $url= 'http://'. $self->{gwip}. '/api/sms/send-sms'; + +=begin comment + + my @cmd= ('curl', $url, + '-H', 'Cookie: '. $session_id, '-H', '__RequestVerificationToken: ' . $token, + '--data', "<?xml version='1.0' encoding='UTF-8'?><request><Index>-1</Index><Phones><Phone>$phone</Phone></Phones><Sca></Sca><Content>$message</Content><Length>-1</Length><Reserved>1</Reserved><Date>-1</Date></request>"); + push (@cmd, '-v') if ($debug); + + print __LINE__, " cmd: ", join(' ', @cmd), "\n" if ($debug); + system(@cmd); + +=end comment +=cut + + my $submit_data= "<?xml version='1.0' encoding='UTF-8'?><request><Index>-1</Index><Phones><Phone>$phone</Phone></Phones><Sca></Sca><Content>$message</Content><Length>-1</Length><Reserved>1</Reserved><Date>-1</Date></request>"; + + my $ua= $self->{_ua} || ($self->{_ua}= new LWP::UserAgent()); + $ua->default_header('Cookie', $session_id); + $ua->default_header(':__RequestVerificationToken', $token); # prevent header name canonication, see perldoc HTTP::Headers under NON-CANONICALIZED FIELD NAMES + + my $resp= $ua->post($url, 'Content-Type' => 'text/html', 'Content' => $submit_data); + unless ($resp->is_success) + { + print __LINE__, " ua failed: ", $resp->status_line, "\n"; + return (undef, undef); + } + my $result_data= $resp->decoded_content; + my $ref= XMLin($result_data); + print __LINE__, " ref: ", Dumper($ref); + + 1; +} + +sub list_sms +{ + my $self= shift; + my $page_index= shift || 1; + + # see: python/dopstar-huawei-modem-python-api-client-02f93dc + my $url= 'http://'. $self->{gwip} . '/api/sms/sms-list'; + my $ua= $self->{_ua} || ($self->{_ua}= new LWP::UserAgent()); + + my ($session_id, $token)= $self->get_session(); + $ua->default_header('Cookie', $session_id); + $ua->default_header(':__RequestVerificationToken', $token); + $ua->default_header('X-Requested-With', 'XMLHttpRequest'); # + + my $submit_data= <<"EOX"; +<request> + <PageIndex>1</PageIndex> + <ReadCount>10</ReadCount> + <BoxType>1</BoxType> + <SortType>0</SortType> + <Ascending>0</Ascending> + <UnreadPreferred>1</UnreadPreferred> +</request> +EOX + my $resp= $ua->post($url, 'Content-Type' => 'text/html', 'Content' => $submit_data); + unless ($resp->is_success) + { + print __LINE__, " ua failed: ", $resp->status_line, "\n"; + return (undef, undef); + } + my $result_data= $resp->decoded_content; + my $ref= XMLin($result_data); + print __LINE__, " ref: ", Dumper($ref); + +} + +sub query +{ + my $self= shift; + my $op_code= shift; + + my $info= $queries{$op_code}; + unless (defined ($info)) + { + print __LINE__, " invalid query\n" if ($debug); + return undef; + } + + my $url= 'http://'. $self->{gwip} . $info->{api}; + my $ua= $self->{_ua} || ($self->{_ua}= new LWP::UserAgent()); + + if ($info->{auth} eq 'token') + { + my ($session_id, $token)= $self->get_session(); + unless (defined ($session_id)) + { + print __LINE__, " no session_id obtained\n" if ($debug); + return undef; + } + + $ua->default_header('Cookie', $session_id); + $ua->default_header(':__RequestVerificationToken', $token); + # $ua->default_header('X-Requested-With', 'XMLHttpRequest'); + } + +# push (@cmd, '-v') if ($debug); +# print __LINE__, " cmd: ", join(' ', @cmd), "\n" if ($debug); +# system(@cmd); + + my $resp= $ua->get($url); + unless ($resp->is_success) + { + print __LINE__, " ua failed: ", $resp->status_line, "\n"; + return (undef, undef); + } + my $data= $resp->decoded_content; + my $ref= XMLin($data); + print __LINE__, " ref: ", Dumper($ref); + + 1; +} + +sub main +{ + my @PARS; + my $gwip= '192.168.8.1'; + while (my $arg= shift (@ARGV)) + { + if ($arg eq '--') {} + elsif ($arg =~ /^--(.*)/) + { my ($opt, $val)= split('-', $1, 2); + if ($opt eq 'debug') { $debug= 1; } + } + elsif ($arg =~ /^-/) {} + else { push (@PARS, $arg); } + } + + unless (@PARS) + { + system('perldoc', $0); + exit(1); + } + + my $obj= new Huawei::Hilink (gwip => $gwip); + + my $op_code= shift (@PARS); + print __LINE__, " op_code=[$op_code]\n" if ($debug); + if ($op_code eq 'send-sms') { $obj->send_sms(@PARS); } + elsif ($op_code eq 'list-sms') { $obj->list_sms(@PARS); } + elsif (exists($queries{$op_code})) { $obj->query($op_code); } + + print __LINE__, " obj: ", Dumper($obj) if ($debug); + + exit(0); +} + +1; + +__END__ + +=head1 AUTHOR + +