~ubuntu-branches/ubuntu/intrepid/gsmlib/intrepid

« back to all changes in this revision

Viewing changes to apps/gsmctl.cc

  • Committer: Bazaar Package Importer
  • Author(s): Mikael Hedin
  • Date: 2002-01-24 12:59:07 UTC
  • Revision ID: james.westby@ubuntu.com-20020124125907-b7qkpokx5283jdpu
Tags: upstream-1.8
ImportĀ upstreamĀ versionĀ 1.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// *************************************************************************
 
2
// * GSM TA/ME library
 
3
// *
 
4
// * File:    gsmctl.cc
 
5
// *
 
6
// * Purpose: GSM mobile phone control program
 
7
// *
 
8
// * Author:  Peter Hofmann (software@pxh.de)
 
9
// *
 
10
// * Created: 11.7.1999
 
11
// *************************************************************************
 
12
 
 
13
#ifdef HAVE_CONFIG_H
 
14
#include <gsm_config.h>
 
15
#endif
 
16
#include <gsmlib/gsm_nls.h>
 
17
#include <string>
 
18
#if defined(HAVE_GETOPT_LONG) || defined(WIN32)
 
19
#include <getopt.h>
 
20
#endif
 
21
#include <strstream>
 
22
#include <stdio.h>
 
23
#include <stdlib.h>
 
24
#include <errno.h>
 
25
#include <gsmlib/gsm_me_ta.h>
 
26
#include <gsmlib/gsm_util.h>
 
27
#include <gsmlib/gsm_sysdep.h>
 
28
#ifdef WIN32
 
29
#include <gsmlib/gsm_win32_serial.h>
 
30
#else
 
31
#include <gsmlib/gsm_unix_serial.h>
 
32
#include <unistd.h>
 
33
#endif
 
34
#include <iostream>
 
35
 
 
36
using namespace std;
 
37
using namespace gsmlib;
 
38
 
 
39
// my ME
 
40
 
 
41
static MeTa *m;
 
42
 
 
43
// information parameters
 
44
 
 
45
enum InfoParameter {AllInfo, // print all info
 
46
                    MeInfo,     // MeInfo must be first!
 
47
                    OperatorInfo,
 
48
                    CurrentOperatorInfo,
 
49
                    FacilityLockStateInfo,
 
50
                    FacilityLockCapabilityInfo,
 
51
                    PasswordInfo,
 
52
                    CLIPInfo,
 
53
                    CallForwardingInfo,
 
54
                    BatteryInfo,
 
55
                    BitErrorInfo,
 
56
                    SCAInfo,
 
57
                    CharSetInfo,
 
58
                    SignalInfo}; // SignalInfo must be last!
 
59
 
 
60
// operation parameters
 
61
 
 
62
// FIXME operations not implemented yet
 
63
 
 
64
// options
 
65
 
 
66
#ifdef HAVE_GETOPT_LONG
 
67
static struct option longOpts[] =
 
68
{
 
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}
 
77
};
 
78
#else
 
79
#define getopt_long(argc, argv, options, longopts, indexptr) \
 
80
  getopt(argc, argv, options)
 
81
#endif
 
82
 
 
83
// helper function, prints forwarding info
 
84
 
 
85
void printForwardReason(string s, ForwardInfo &info)
 
86
{
 
87
  cout << s << "  "
 
88
       << (info._active ? _("active ") : _("inactive "))
 
89
       << _("number: ") << info._number
 
90
       << _("  subaddr: ") << info._subAddr
 
91
       << _("  time: ") << info._time << endl;
 
92
}
 
93
 
 
94
// print information
 
95
 
 
96
static void printInfo(InfoParameter ip)
 
97
{
 
98
  switch (ip)
 
99
  {
 
100
  case MeInfo:
 
101
  {
 
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;
 
107
    break;
 
108
  }
 
109
  case OperatorInfo:
 
110
  {
 
111
    int count = 0;
 
112
    vector<OPInfo> opis = m->getAvailableOPInfo();
 
113
    for (vector<OPInfo>::iterator i = opis.begin(); i != opis.end(); ++i)
 
114
    {
 
115
      cout << "<OP" << count << _(">  Status: ");
 
116
      switch (i->_status)
 
117
      {
 
118
      case UnknownOPStatus: cout << _("unknown"); break;
 
119
      case CurrentOPStatus: cout << _("current"); break;
 
120
      case AvailableOPStatus: cout << _("available"); break;
 
121
      case ForbiddenOPStatus: cout << _("forbidden"); break;
 
122
      }
 
123
      cout << _("  Long name: '") << i->_longName << "' "
 
124
           << _("  Short name: '") << i->_shortName << "' "
 
125
           << _("  Numeric name: ") << i->_numericName << endl;
 
126
      ++count;
 
127
    }
 
128
    break;
 
129
  }
 
130
  case CurrentOperatorInfo:
 
131
  {
 
132
    OPInfo opi = m->getCurrentOPInfo();
 
133
    cout << "<CURROP0>"
 
134
         << _("  Long name: '") << opi._longName << "' "
 
135
         << _("  Short name: '") << opi._shortName << "' "
 
136
         << _("  Numeric name: ") << opi._numericName
 
137
         << _("  Mode: ");
 
138
    switch (opi._mode)
 
139
    {
 
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;
 
144
    }
 
145
    cout << endl;
 
146
    break;
 
147
  }
 
148
  case FacilityLockStateInfo:
 
149
  {
 
150
    int count = 0;
 
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")
 
154
      {
 
155
        cout << "<FLSTAT" << count <<  ">  '" << *i << "'";
 
156
        try
 
157
        {
 
158
          if (m->getFacilityLockStatus(*i, VoiceFacility))
 
159
            cout << _("  Voice");
 
160
        }
 
161
        catch (GsmException &e)
 
162
        {
 
163
          cout << _("  unknown");
 
164
        }
 
165
        try
 
166
        {
 
167
        if (m->getFacilityLockStatus(*i, DataFacility))
 
168
          cout << _("  Data");
 
169
        }
 
170
        catch (GsmException &e)
 
171
        {
 
172
          cout << _("  unknown");
 
173
        }
 
174
        try
 
175
        {
 
176
        if (m->getFacilityLockStatus(*i, FaxFacility))
 
177
          cout << _("  Fax");
 
178
        }
 
179
        catch (GsmException &e)
 
180
        {
 
181
          cout << _("  unknown");
 
182
        }
 
183
        cout << endl;
 
184
        ++count;
 
185
      }
 
186
    break;
 
187
  }
 
188
  case FacilityLockCapabilityInfo:
 
189
  {
 
190
    cout << "<FLCAP0>  ";
 
191
    vector<string> fclc = m->getFacilityLockCapabilities();
 
192
    for (vector<string>::iterator i = fclc.begin(); i != fclc.end(); ++i)
 
193
      cout << "'" << *i << "' ";
 
194
    cout << endl;
 
195
    break;
 
196
  }
 
197
  case PasswordInfo:
 
198
  {
 
199
    vector<PWInfo> pwi = m->getPasswords();
 
200
    int count = 0;
 
201
    for (vector<PWInfo>::iterator i = pwi.begin(); i != pwi.end(); ++i)
 
202
    {
 
203
      cout << "<PW" << count <<  ">  '"
 
204
           << i->_facility << "' " << i->_maxPasswdLen << endl;
 
205
      ++count;
 
206
    }
 
207
    break;
 
208
  }
 
209
  case CLIPInfo:
 
210
  {
 
211
    cout << "<CLIP0>  " << (m->getNetworkCLIP() ? _("on") : _("off")) << endl;
 
212
    break;
 
213
  }
 
214
  case CallForwardingInfo:
 
215
  {
 
216
    for (int r = 0; r < 4; ++r)
 
217
    {
 
218
      string text;
 
219
      switch (r)
 
220
      {
 
221
      case 0: text = _("UnconditionalReason"); break;
 
222
      case 1: text = _("MobileBusyReason"); break;
 
223
      case 2: text = _("NoReplyReason"); break;
 
224
      case 3: text = _("NotReachableReason"); break;
 
225
      }
 
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);
 
234
    }
 
235
    break;
 
236
  }
 
237
  case BatteryInfo:
 
238
  {
 
239
    cout << "<BATT0>  ";
 
240
    int bcs = m->getBatteryChargeStatus();
 
241
    switch (bcs)
 
242
    {
 
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")
 
245
                 << endl; break;
 
246
    case 2: cout << _("2 ME does not have a battery connected") << endl; break;
 
247
    case 3:
 
248
      cout << _("3 Recognized power fault, calls inhibited") << endl;
 
249
      break;
 
250
    }
 
251
    cout << "<BATT1>  " << m->getBatteryCharge() << endl;
 
252
    break;
 
253
  }
 
254
  case BitErrorInfo:
 
255
  {
 
256
    cout << "<BITERR0>  " << m->getBitErrorRate() << endl;
 
257
    break;
 
258
  }
 
259
  case SCAInfo:
 
260
  {
 
261
    cout << "<SCA0>  " << m->getServiceCentreAddress() << endl;
 
262
    break;
 
263
  }
 
264
  case CharSetInfo:
 
265
  {
 
266
    cout << "<CSET0>  ";
 
267
    vector<string> cs = m->getSupportedCharSets();
 
268
    for (vector<string>::iterator i = cs.begin(); i != cs.end(); ++i)
 
269
      cout << "'" << *i << "' ";
 
270
    cout << endl;
 
271
    cout << "<CSET1>  '" << m->getCurrentCharSet() << "'" << endl;
 
272
    break;
 
273
  }
 
274
  case SignalInfo:
 
275
  {
 
276
    cout << "<SIG0>  " << m->getSignalStrength() << endl;
 
277
    break;
 
278
  }
 
279
  default:
 
280
    assert(0);
 
281
    break;
 
282
  }
 
283
}
 
284
 
 
285
// convert facility class string of the form "", "all", or any combination
 
286
// of "v" (voice), "d" (data), or "f" (fax) to numeric form
 
287
 
 
288
FacilityClass strToFacilityClass(string facilityClassS)
 
289
{
 
290
  facilityClassS = lowercase(facilityClassS);
 
291
  FacilityClass facilityClass = (FacilityClass)0;
 
292
  if (facilityClassS == "all" || facilityClassS == "")
 
293
    return (FacilityClass)ALL_FACILITIES;
 
294
 
 
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);
 
303
    else
 
304
      throw GsmException(
 
305
        stringPrintf(_("unknown facility class parameter '%c'"),
 
306
                     facilityClassS[i]), ParameterError);
 
307
 
 
308
  return facilityClass;
 
309
}
 
310
 
 
311
// check if argc - optind is in range min..max
 
312
// throw exception otherwise
 
313
 
 
314
void checkParamCount(int optind, int argc, int min, int max)
 
315
{
 
316
  int paramCount = argc - optind;
 
317
  if (paramCount < min)
 
318
    throw GsmException(stringPrintf(_("not enough parameters, minimum number "
 
319
                                      "of parameters is %d"), min),
 
320
                       ParameterError);
 
321
  else if (paramCount > max)
 
322
    throw GsmException(stringPrintf(_("too many parameters, maximum number "
 
323
                                      "of parameters is %d"), max),
 
324
                       ParameterError);
 
325
}
 
326
 
 
327
// *** main program
 
328
 
 
329
int main(int argc, char *argv[])
 
330
{
 
331
  try
 
332
  {
 
333
    // handle command line options
 
334
    string device = "/dev/mobilephone";
 
335
    string operation;
 
336
    string baudrate;
 
337
    string initString = DEFAULT_INIT_STRING;
 
338
    bool swHandshake = false;
 
339
 
 
340
    int opt;
 
341
    int dummy;
 
342
    while((opt = getopt_long(argc, argv, "I:o:d:b:hvX", longOpts, &dummy))
 
343
          != -1)
 
344
      switch (opt)
 
345
      {
 
346
      case 'X':
 
347
        swHandshake = true;
 
348
        break;
 
349
      case 'I':
 
350
        initString = optarg;
 
351
        break;
 
352
      case 'd':
 
353
        device = optarg;
 
354
        break;
 
355
      case 'o':
 
356
        operation = optarg;
 
357
        break;
 
358
      case 'b':
 
359
        baudrate = optarg;
 
360
        break;
 
361
      case 'v':
 
362
        cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"),
 
363
                                        VERSION, __DATE__) << endl;
 
364
        exit(0);
 
365
        break;
 
366
      case 'h':
 
367
        cerr << argv[0] << _(": [-b baudrate][-d device][-h]"
 
368
                             "[-I init string][-o operation]\n"
 
369
                             "  [-v][-X]{parameters}") << endl
 
370
             << endl
 
371
             << _("  -b, --baudrate    baudrate to use for device "
 
372
                  "(default: 38400)")
 
373
             << endl
 
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")
 
380
             << endl
 
381
             << _("  -v, --version     prints version and exits") << endl
 
382
             << _("  -X, --xonxoff     switch on software handshake") << endl
 
383
             << 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 "
 
388
                  "phone")
 
389
             << endl << endl
 
390
             << _("Refer to gsmctl(1) for details on the available parameters"
 
391
                  " and operations.")
 
392
             << endl << endl;
 
393
        exit(0);
 
394
        break;
 
395
      case '?':
 
396
        throw GsmException(_("unknown option"), ParameterError);
 
397
        break;
 
398
      }
 
399
 
 
400
    // open the port and ME/TA
 
401
    m = new MeTa(new
 
402
#ifdef WIN32
 
403
                 Win32SerialPort
 
404
#else
 
405
                 UnixSerialPort
 
406
#endif
 
407
                 (device,
 
408
                  baudrate == "" ?
 
409
                  DEFAULT_BAUD_RATE :
 
410
                  baudRateStrToSpeed(baudrate),
 
411
                  initString, swHandshake));
 
412
    
 
413
    if (operation == "")
 
414
    {                           // process info parameters
 
415
      for (int i = optind; i < argc; ++i)
 
416
      {
 
417
        string param = lowercase(argv[i]);
 
418
        if (param == "all")
 
419
          for (int ip = MeInfo; ip <= SignalInfo; ++ip)
 
420
            printInfo((InfoParameter)ip);
 
421
        else if (param == "me")
 
422
          printInfo(MeInfo);
 
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")
 
434
          printInfo(CLIPInfo);
 
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")
 
444
          printInfo(SCAInfo);
 
445
        else if (param == "cset")
 
446
          printInfo(CharSetInfo);
 
447
        else
 
448
          throw GsmException(
 
449
            stringPrintf(_("unknown information parameter '%s'"),
 
450
                         param.c_str()),
 
451
            ParameterError);
 
452
      }
 
453
    }
 
454
    else
 
455
    {                           // process operation
 
456
      operation = lowercase(operation);
 
457
      if (operation == "dial")
 
458
      {
 
459
        // dial: number
 
460
        checkParamCount(optind, argc, 1, 1);
 
461
 
 
462
        m->dial(argv[optind]);
 
463
        
 
464
        // wait for keypress from stdin
 
465
        char c;
 
466
        read(1, &c, 1);
 
467
      }
 
468
      else if (operation == "setop")
 
469
      {
 
470
        // setop: opmode numeric FIXME allow long and numeric too
 
471
        checkParamCount(optind, argc, 2, 2);
 
472
        string opmodeS = lowercase(argv[optind]);
 
473
        OPModes opmode;
 
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;
 
482
        else
 
483
          throw GsmException(stringPrintf(_("unknown opmode parameter '%s'"),
 
484
                                          opmodeS.c_str()), ParameterError);
 
485
 
 
486
        m->setCurrentOPInfo(opmode, "" , "", checkNumber(argv[optind + 1]));
 
487
      }
 
488
      else if (operation == "lock")
 
489
      {
 
490
        // lock: facility [facilityclass] [passwd]
 
491
        checkParamCount(optind, argc, 1, 3);
 
492
        string passwd = (argc - optind == 3) ?
 
493
          (string)argv[optind + 2] : (string)"";
 
494
        
 
495
        m->lockFacility(argv[optind],
 
496
                        (argc - optind >= 2) ?
 
497
                        strToFacilityClass(argv[optind + 1]) :
 
498
                        (FacilityClass)ALL_FACILITIES,
 
499
                        passwd);
 
500
      }
 
501
      else if (operation == "unlock")
 
502
      {
 
503
        // unlock: facility [facilityclass] [passwd]
 
504
        checkParamCount(optind, argc, 1, 3);
 
505
        string passwd = argc - optind == 3 ? argv[optind + 2] : "";
 
506
        
 
507
        m->unlockFacility(argv[optind],
 
508
                          (argc - optind >= 2) ?
 
509
                          strToFacilityClass(argv[optind + 1]) :
 
510
                          (FacilityClass)ALL_FACILITIES,
 
511
                          passwd);
 
512
      }
 
513
      else if (operation == "setpw")
 
514
      {
 
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] : "";
 
519
 
 
520
        m->setPassword(argv[optind], oldPasswd, newPasswd);
 
521
      }
 
522
      else if (operation == "forw")
 
523
      {
 
524
        // call forwarding: mode reason number [facilityclass] [forwardtime]
 
525
        checkParamCount(optind, argc, 2, 5);
 
526
 
 
527
        // get optional parameters facility class and forwardtime
 
528
        int forwardTime = argc - optind == 5 ? checkNumber(argv[optind + 4]) :
 
529
          NOT_SET;
 
530
        FacilityClass facilityClass =
 
531
          argc - optind >= 4 ? strToFacilityClass(argv[optind + 3]) :
 
532
          (FacilityClass)ALL_FACILITIES;
 
533
        
 
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")
 
546
          reason = AllReasons;
 
547
        else if (reasonS == "allconditional")
 
548
          reason = AllConditionalReasons;
 
549
        else
 
550
          throw GsmException(
 
551
            stringPrintf(_("unknown forward reason parameter '%s'"),
 
552
                         reasonS.c_str()), ParameterError);
 
553
        
 
554
        // get mode
 
555
        string modeS = lowercase(argv[optind]);
 
556
        ForwardMode mode;
 
557
        if (modeS == "disable")
 
558
          mode = DisableMode;
 
559
        else if (modeS == "enable")
 
560
          mode = EnableMode;
 
561
        else if (modeS == "register")
 
562
          mode = RegistrationMode;
 
563
        else if (modeS == "erase")
 
564
          mode = ErasureMode;
 
565
        else
 
566
          throw GsmException(
 
567
            stringPrintf(_("unknown forward mode parameter '%s'"),
 
568
                         modeS.c_str()), ParameterError);
 
569
 
 
570
        m->setCallForwarding(reason, mode,
 
571
                             (argc - optind >= 3) ? argv[optind + 2] : "",
 
572
                             "", // subaddr
 
573
                             facilityClass, forwardTime);
 
574
      }
 
575
      else if (operation == "setsca")
 
576
      {
 
577
        // set sca: number
 
578
        checkParamCount(optind, argc, 1, 1);
 
579
        m->setServiceCentreAddress(argv[optind]);
 
580
      }
 
581
      else if (operation == "cset")
 
582
      {
 
583
        // set charset: string
 
584
        checkParamCount(optind, argc, 1, 1);
 
585
        m->setCharSet(argv[optind]);
 
586
      }
 
587
      else
 
588
         throw GsmException(stringPrintf(_("unknown operation '%s'"),
 
589
                                         operation.c_str()), ParameterError);
 
590
    }
 
591
  }
 
592
  catch (GsmException &ge)
 
593
  {
 
594
    cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl;
 
595
    return 1;
 
596
  }
 
597
  return 0;
 
598
}