#!/usr/bin/perl ## $Id: huawei-ussd,v 1.5 2015/06/08 09:05:03 pdc Exp $ use Getopt::Std; # devel/p5-Getopt-Long use Device::Gsm::Pdu; # comms/p5-Device-Gsm use Encode; # defaults $opt_r = "/dev/ttyUSB2"; $opt_s = "/dev/ttyUSB0"; $opt_r = "/dev/cuaU0.2"; $opt_s = "/dev/cuaU0.2"; $opt_r = "/dev/huawei0.2"; $opt_s = "/dev/huawei0.2"; my $USAGE = <<__EOU; Usage: $0 [-r input_port] [-s output_port] [-n] [-h] [-v] [-w] ussd_msg Description: Send and receive 7-bit PDU-encoded USSD messages. Written and tested for Huawei E1550 GSM/UMTS USB modem. Options: -r port Port to receive data from. Default: $opt_r -s port Port to send AT commands to. Default: $opt_s -n Do not send any data to port. Useful with -v. -h Print this help. -v Be verbose. -w reply workaround (try it if script can not decode reply) __EOU sub HELP_MESSAGE {print "$USAGE\n"; exit 64;} sub VERSION_MESSAGE {}; getopts ('r:s:hnvw'); $opt_v=1; HELP_MESSAGE() and exit if (! defined $ARGV[0]) or defined($opt_h); print "USSD MSG: $ARGV[0]\n" if $opt_v; my $ussd_req = Device::Gsm::Pdu::encode_text7($ARGV[0]); $ussd_req =~ s/^..//; print "PDU ENCODED: $ussd_req\n" if $opt_v; my $ussd_reply; if (! $opt_n) { print STDERR "open send port...\n"; #open (SENDPORT, '+<', $opt_s) or die "Can't send open '$opt_s': $!\n"; open (SENDPORT, '+>', $opt_s) or die "Can't send open '$opt_s': $!\n"; print STDERR "sending...\n"; print SENDPORT 'AT+CUSD=1,',$ussd_req,",15\r\n"; close SENDPORT; open (RCVPORT, $opt_r) or die "Can't recv open '$opt_r': $!\n"; print "Waiting for USSD reply...\n" if $opt_v; while () { chomp; die "USSD ERROR\n" if $_ eq "+CUSD: 2"; if (/^\+CUSD: [01],\"([A-F0-9]+)\"/) { $ussd_reply = $1; print "PDU USSD REPLY: $ussd_reply\n" if $opt_v; last; } elsif(/^\+CME ERROR/) { print "$_\n"; } elsif(/^NO CARRIER/) { die "$_\n"; } else { print ">>> $_\n" if $_!~/^\s*$/ && $opt_v }; print "Got unknown USSD message: $_\n" if /^\+CUSD:/ and $opt_v; } } if ($ussd_reply) { if(!$opt_w && $ussd_reply=~/^04|^..04|^....04/) { # utf16 my $s=pack('H*', $ussd_reply); $decoded_ussd_reply=decode('UTF-16BE', $s); } unless(defined $decoded_ussd_reply) { $decoded_ussd_reply = $opt_w ? pack('H*', $ussd_reply) : Device::Gsm::Pdu::decode_text7('ff'.$ussd_reply); } if($ENV{charset}=~/KOI/) { $decoded_ussd_reply = encode('koi8-u',$decoded_ussd_reply) } print STDOUT "USSD REPLY: $decoded_ussd_reply\n"; } else { print "No USSD reply!\n"; }