1
// *************************************************************************
6
// * Purpose: GSM mobile phone control program
8
// * Author: Peter Hofmann (software@pxh.de)
10
// * Created: 11.7.1999
11
// *************************************************************************
14
#include <gsm_config.h>
16
#include <gsmlib/gsm_nls.h>
18
#if defined(HAVE_GETOPT_LONG) || defined(WIN32)
25
#include <gsmlib/gsm_me_ta.h>
26
#include <gsmlib/gsm_util.h>
27
#include <gsmlib/gsm_sysdep.h>
29
#include <gsmlib/gsm_win32_serial.h>
31
#include <gsmlib/gsm_unix_serial.h>
37
using namespace gsmlib;
43
// information parameters
45
enum InfoParameter {AllInfo, // print all info
46
MeInfo, // MeInfo must be first!
49
FacilityLockStateInfo,
50
FacilityLockCapabilityInfo,
58
SignalInfo}; // SignalInfo must be last!
60
// operation parameters
62
// FIXME operations not implemented yet
66
#ifdef HAVE_GETOPT_LONG
67
static struct option longOpts[] =
69
{"xonxoff", no_argument, (int*)NULL, 'X'},
70
{"operation", required_argument, (int*)NULL, 'o'},
71
{"device", required_argument, (int*)NULL, 'd'},
72
{"baudrate", required_argument, (int*)NULL, 'b'},
73
{"init", required_argument, (int*)NULL, 'I'},
74
{"help", no_argument, (int*)NULL, 'h'},
75
{"version", no_argument, (int*)NULL, 'v'},
76
{(char*)NULL, 0, (int*)NULL, 0}
79
#define getopt_long(argc, argv, options, longopts, indexptr) \
80
getopt(argc, argv, options)
83
// helper function, prints forwarding info
85
void printForwardReason(string s, ForwardInfo &info)
88
<< (info._active ? _("active ") : _("inactive "))
89
<< _("number: ") << info._number
90
<< _(" subaddr: ") << info._subAddr
91
<< _(" time: ") << info._time << endl;
96
static void printInfo(InfoParameter ip)
102
MEInfo mei = m->getMEInfo();
103
cout << _("<ME0> Manufacturer: ") << mei._manufacturer << endl
104
<< _("<ME1> Model: ") << mei._model << endl
105
<< _("<ME2> Revision: ") << mei._revision << endl
106
<< _("<ME3> Serial Number: ") << mei._serialNumber << endl;
112
vector<OPInfo> opis = m->getAvailableOPInfo();
113
for (vector<OPInfo>::iterator i = opis.begin(); i != opis.end(); ++i)
115
cout << "<OP" << count << _("> Status: ");
118
case UnknownOPStatus: cout << _("unknown"); break;
119
case CurrentOPStatus: cout << _("current"); break;
120
case AvailableOPStatus: cout << _("available"); break;
121
case ForbiddenOPStatus: cout << _("forbidden"); break;
123
cout << _(" Long name: '") << i->_longName << "' "
124
<< _(" Short name: '") << i->_shortName << "' "
125
<< _(" Numeric name: ") << i->_numericName << endl;
130
case CurrentOperatorInfo:
132
OPInfo opi = m->getCurrentOPInfo();
134
<< _(" Long name: '") << opi._longName << "' "
135
<< _(" Short name: '") << opi._shortName << "' "
136
<< _(" Numeric name: ") << opi._numericName
140
case AutomaticOPMode: cout << _("automatic"); break;
141
case ManualOPMode: cout << _("manual"); break;
142
case DeregisterOPMode: cout << _("deregister"); break;
143
case ManualAutomaticOPMode: cout << _("manual/automatic"); break;
148
case FacilityLockStateInfo:
151
vector<string> fclc = m->getFacilityLockCapabilities();
152
for (vector<string>::iterator i = fclc.begin(); i != fclc.end(); ++i)
153
if (*i != "AB" && *i != "AG" && *i != "AC")
155
cout << "<FLSTAT" << count << "> '" << *i << "'";
158
if (m->getFacilityLockStatus(*i, VoiceFacility))
161
catch (GsmException &e)
163
cout << _(" unknown");
167
if (m->getFacilityLockStatus(*i, DataFacility))
170
catch (GsmException &e)
172
cout << _(" unknown");
176
if (m->getFacilityLockStatus(*i, FaxFacility))
179
catch (GsmException &e)
181
cout << _(" unknown");
188
case FacilityLockCapabilityInfo:
191
vector<string> fclc = m->getFacilityLockCapabilities();
192
for (vector<string>::iterator i = fclc.begin(); i != fclc.end(); ++i)
193
cout << "'" << *i << "' ";
199
vector<PWInfo> pwi = m->getPasswords();
201
for (vector<PWInfo>::iterator i = pwi.begin(); i != pwi.end(); ++i)
203
cout << "<PW" << count << "> '"
204
<< i->_facility << "' " << i->_maxPasswdLen << endl;
211
cout << "<CLIP0> " << (m->getNetworkCLIP() ? _("on") : _("off")) << endl;
214
case CallForwardingInfo:
216
for (int r = 0; r < 4; ++r)
221
case 0: text = _("UnconditionalReason"); break;
222
case 1: text = _("MobileBusyReason"); break;
223
case 2: text = _("NoReplyReason"); break;
224
case 3: text = _("NotReachableReason"); break;
226
ForwardInfo voice, fax, data;
227
m->getCallForwardInfo((ForwardReason)r, voice, fax, data);
228
cout << "<FORW" << r << ".";
229
printForwardReason("0> " + text + _(" Voice"), voice);
230
cout << "<FORW" << r << ".";
231
printForwardReason("1> " + text + _(" Data"), data);
232
cout << "<FORW" << r << ".";
233
printForwardReason("2> " + text + _(" Fax"), fax);
240
int bcs = m->getBatteryChargeStatus();
243
case 0: cout << _("0 ME is powered by the battery") << endl; break;
244
case 1: cout << _("1 ME has a battery connected, but is not powered by it")
246
case 2: cout << _("2 ME does not have a battery connected") << endl; break;
248
cout << _("3 Recognized power fault, calls inhibited") << endl;
251
cout << "<BATT1> " << m->getBatteryCharge() << endl;
256
cout << "<BITERR0> " << m->getBitErrorRate() << endl;
261
cout << "<SCA0> " << m->getServiceCentreAddress() << endl;
267
vector<string> cs = m->getSupportedCharSets();
268
for (vector<string>::iterator i = cs.begin(); i != cs.end(); ++i)
269
cout << "'" << *i << "' ";
271
cout << "<CSET1> '" << m->getCurrentCharSet() << "'" << endl;
276
cout << "<SIG0> " << m->getSignalStrength() << endl;
285
// convert facility class string of the form "", "all", or any combination
286
// of "v" (voice), "d" (data), or "f" (fax) to numeric form
288
FacilityClass strToFacilityClass(string facilityClassS)
290
facilityClassS = lowercase(facilityClassS);
291
FacilityClass facilityClass = (FacilityClass)0;
292
if (facilityClassS == "all" || facilityClassS == "")
293
return (FacilityClass)ALL_FACILITIES;
295
// OR in facility class bits
296
for (unsigned int i = 0; i < facilityClassS.length(); ++i)
297
if (facilityClassS[i] == 'v')
298
facilityClass = (FacilityClass)(facilityClass | VoiceFacility);
299
else if (facilityClassS[i] == 'd')
300
facilityClass = (FacilityClass)(facilityClass | DataFacility);
301
else if (facilityClassS[i] == 'f')
302
facilityClass = (FacilityClass)(facilityClass | FaxFacility);
305
stringPrintf(_("unknown facility class parameter '%c'"),
306
facilityClassS[i]), ParameterError);
308
return facilityClass;
311
// check if argc - optind is in range min..max
312
// throw exception otherwise
314
void checkParamCount(int optind, int argc, int min, int max)
316
int paramCount = argc - optind;
317
if (paramCount < min)
318
throw GsmException(stringPrintf(_("not enough parameters, minimum number "
319
"of parameters is %d"), min),
321
else if (paramCount > max)
322
throw GsmException(stringPrintf(_("too many parameters, maximum number "
323
"of parameters is %d"), max),
329
int main(int argc, char *argv[])
333
// handle command line options
334
string device = "/dev/mobilephone";
337
string initString = DEFAULT_INIT_STRING;
338
bool swHandshake = false;
342
while((opt = getopt_long(argc, argv, "I:o:d:b:hvX", longOpts, &dummy))
362
cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"),
363
VERSION, __DATE__) << endl;
367
cerr << argv[0] << _(": [-b baudrate][-d device][-h]"
368
"[-I init string][-o operation]\n"
369
" [-v][-X]{parameters}") << endl
371
<< _(" -b, --baudrate baudrate to use for device "
374
<< _(" -d, --device sets the destination device to "
375
"connect to") << endl
376
<< _(" -h, --help prints this message") << endl
377
<< _(" -I, --init device AT init sequence") << endl
378
<< _(" -o, --operation operation to perform on the mobile \n"
379
" phone with the specified parameters")
381
<< _(" -v, --version prints version and exits") << endl
382
<< _(" -X, --xonxoff switch on software handshake") << endl
384
<< _(" parameters parameters to use for the operation\n"
385
" (if an operation is given) or\n"
386
" a specification which kind of\n"
387
" information to read from the mobile "
390
<< _("Refer to gsmctl(1) for details on the available parameters"
396
throw GsmException(_("unknown option"), ParameterError);
400
// open the port and ME/TA
410
baudRateStrToSpeed(baudrate),
411
initString, swHandshake));
414
{ // process info parameters
415
for (int i = optind; i < argc; ++i)
417
string param = lowercase(argv[i]);
419
for (int ip = MeInfo; ip <= SignalInfo; ++ip)
420
printInfo((InfoParameter)ip);
421
else if (param == "me")
423
else if (param == "op")
424
printInfo(OperatorInfo);
425
else if (param == "currop")
426
printInfo(CurrentOperatorInfo);
427
else if (param == "flstat")
428
printInfo(FacilityLockStateInfo);
429
else if (param == "flcap")
430
printInfo(FacilityLockCapabilityInfo);
431
else if (param == "pw")
432
printInfo(PasswordInfo);
433
else if (param == "clip")
435
else if (param == "forw")
436
printInfo(CallForwardingInfo);
437
else if (param == "batt")
438
printInfo(BatteryInfo);
439
else if (param == "biterr")
440
printInfo(BitErrorInfo);
441
else if (param == "sig")
442
printInfo(SignalInfo);
443
else if (param == "sca")
445
else if (param == "cset")
446
printInfo(CharSetInfo);
449
stringPrintf(_("unknown information parameter '%s'"),
455
{ // process operation
456
operation = lowercase(operation);
457
if (operation == "dial")
460
checkParamCount(optind, argc, 1, 1);
462
m->dial(argv[optind]);
464
// wait for keypress from stdin
468
else if (operation == "setop")
470
// setop: opmode numeric FIXME allow long and numeric too
471
checkParamCount(optind, argc, 2, 2);
472
string opmodeS = lowercase(argv[optind]);
474
if (opmodeS == "automatic")
475
opmode = AutomaticOPMode;
476
else if (opmodeS == "manual")
477
opmode = ManualOPMode;
478
else if (opmodeS == "deregister")
479
opmode = DeregisterOPMode;
480
else if (opmodeS == "manualautomatic")
481
opmode = ManualAutomaticOPMode;
483
throw GsmException(stringPrintf(_("unknown opmode parameter '%s'"),
484
opmodeS.c_str()), ParameterError);
486
m->setCurrentOPInfo(opmode, "" , "", checkNumber(argv[optind + 1]));
488
else if (operation == "lock")
490
// lock: facility [facilityclass] [passwd]
491
checkParamCount(optind, argc, 1, 3);
492
string passwd = (argc - optind == 3) ?
493
(string)argv[optind + 2] : (string)"";
495
m->lockFacility(argv[optind],
496
(argc - optind >= 2) ?
497
strToFacilityClass(argv[optind + 1]) :
498
(FacilityClass)ALL_FACILITIES,
501
else if (operation == "unlock")
503
// unlock: facility [facilityclass] [passwd]
504
checkParamCount(optind, argc, 1, 3);
505
string passwd = argc - optind == 3 ? argv[optind + 2] : "";
507
m->unlockFacility(argv[optind],
508
(argc - optind >= 2) ?
509
strToFacilityClass(argv[optind + 1]) :
510
(FacilityClass)ALL_FACILITIES,
513
else if (operation == "setpw")
515
// set password: facility oldpasswd newpasswd
516
checkParamCount(optind, argc, 1, 3);
517
string oldPasswd = argc - optind >= 2 ? argv[optind + 1] : "";
518
string newPasswd = argc - optind == 3 ? argv[optind + 2] : "";
520
m->setPassword(argv[optind], oldPasswd, newPasswd);
522
else if (operation == "forw")
524
// call forwarding: mode reason number [facilityclass] [forwardtime]
525
checkParamCount(optind, argc, 2, 5);
527
// get optional parameters facility class and forwardtime
528
int forwardTime = argc - optind == 5 ? checkNumber(argv[optind + 4]) :
530
FacilityClass facilityClass =
531
argc - optind >= 4 ? strToFacilityClass(argv[optind + 3]) :
532
(FacilityClass)ALL_FACILITIES;
534
// get forward reason
535
string reasonS = lowercase(argv[optind + 1]);
536
ForwardReason reason;
537
if (reasonS == "unconditional")
538
reason = UnconditionalReason;
539
else if (reasonS == "mobilebusy")
540
reason = MobileBusyReason;
541
else if (reasonS == "noreply")
542
reason = NoReplyReason;
543
else if (reasonS == "notreachable")
544
reason = NotReachableReason;
545
else if (reasonS == "all")
547
else if (reasonS == "allconditional")
548
reason = AllConditionalReasons;
551
stringPrintf(_("unknown forward reason parameter '%s'"),
552
reasonS.c_str()), ParameterError);
555
string modeS = lowercase(argv[optind]);
557
if (modeS == "disable")
559
else if (modeS == "enable")
561
else if (modeS == "register")
562
mode = RegistrationMode;
563
else if (modeS == "erase")
567
stringPrintf(_("unknown forward mode parameter '%s'"),
568
modeS.c_str()), ParameterError);
570
m->setCallForwarding(reason, mode,
571
(argc - optind >= 3) ? argv[optind + 2] : "",
573
facilityClass, forwardTime);
575
else if (operation == "setsca")
578
checkParamCount(optind, argc, 1, 1);
579
m->setServiceCentreAddress(argv[optind]);
581
else if (operation == "cset")
583
// set charset: string
584
checkParamCount(optind, argc, 1, 1);
585
m->setCharSet(argv[optind]);
588
throw GsmException(stringPrintf(_("unknown operation '%s'"),
589
operation.c_str()), ParameterError);
592
catch (GsmException &ge)
594
cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl;