--- gsmlib-1.7/apps/Makefile.am Fri Jan 5 23:25:32 2001 +++ gsmlib-1.7-SieMe/apps/Makefile.am Sun Dec 16 19:42:51 2001 @@ -13,7 +13,8 @@ INCLUDES = -I.. -bin_PROGRAMS = gsmsmsstore gsmctl gsmsmsd gsmpb gsmsendsms +bin_PROGRAMS = gsmsmsstore gsmctl gsmsmsd gsmpb gsmsendsms \ + gsmsiectl gsmsiexfer # build gsmsmsd from gsmsmsd.cc and libgsmme.la gsmsmsd_SOURCES = gsmsmsd.cc @@ -34,3 +35,11 @@ # build gsmsmsstore from gsmsmsstore.cc and libgsmme.la gsmsmsstore_SOURCES = gsmsmsstore.cc gsmsmsstore_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) + +# build gsmsiectl from gsmsiectl.cc and libgsmme.la +gsmsiectl_SOURCES = gsmsiectl.cc +gsmsiectl_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) + +# build gsmsiexfer from gsmsiexfer.cc and libgsmme.la +gsmsiexfer_SOURCES = gsmsiexfer.cc +gsmsiexfer_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS) --- gsmlib-1.7/apps/gsmsiectl.cc Sat Dec 15 21:49:29 2001 +++ gsmlib-1.7-SieMe/apps/gsmsiectl.cc Sun Dec 16 21:25:21 2001 @@ -0,0 +1,698 @@ +// ************************************************************************* +// * GSM TA/ME library +// * +// * File: gsmsiectl.cc +// * +// * Purpose: GSM Siemens mobile phone control program +// * +// * Author: Christian W. Zuckschwerdt +// * +// * Created: 2001-12-15 +// ************************************************************************* + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#if defined(HAVE_GETOPT_LONG) || defined(WIN32) +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef WIN32 +#include +#else +#include +#include +#endif +#include + +using namespace std; +using namespace gsmlib; + +// my ME + +static SieMe *m; + +// information parameters + +enum InfoParameter {AllInfo, // print all info + MeInfo, // MeInfo must be first! + OperatorInfo, + CurrentOperatorInfo, + FacilityLockStateInfo, + FacilityLockCapabilityInfo, + PasswordInfo, + CLIPInfo, + CallForwardingInfo, + BatteryInfo, + BitErrorInfo, + SCAInfo, + CharSetInfo, + PhonebookInfo, // extended Siemens info + SignalToneInfo, + RingingToneInfo, + BinaryInfo, + SignalInfo}; // SignalInfo must be last! + +// operation parameters + +// FIXME operations not implemented yet + +// options + +#ifdef HAVE_GETOPT_LONG +static struct option longOpts[] = +{ + {"xonxoff", no_argument, (int*)NULL, 'X'}, + {"operation", required_argument, (int*)NULL, 'o'}, + {"device", required_argument, (int*)NULL, 'd'}, + {"baudrate", required_argument, (int*)NULL, 'b'}, + {"init", required_argument, (int*)NULL, 'I'}, + {"help", no_argument, (int*)NULL, 'h'}, + {"version", no_argument, (int*)NULL, 'v'}, + {(char*)NULL, 0, (int*)NULL, 0} +}; +#else +#define getopt_long(argc, argv, options, longopts, indexptr) \ + getopt(argc, argv, options) +#endif + +// helper function, prints forwarding info + +void printForwardReason(string s, ForwardInfo &info) +{ + cout << s << " " + << (info._active ? _("active ") : _("inactive ")) + << _("number: ") << info._number + << _(" subaddr: ") << info._subAddr + << _(" time: ") << info._time << endl; +} + +// helper function, prints integer range + +void printIntRange(IntRange ir) +{ + cout << "(" << ir._low; + if (ir._high != NOT_SET) + cout << "-" << ir._high; + cout << ")"; +} + +// helper function, prints parameter range + +void printParameterRange(ParameterRange pr) +{ + cout << "(\"" << pr._parameter << "\","; + printIntRange(pr._range); + cout << ")"; +} + +// print information + +static void printInfo(InfoParameter ip) +{ + switch (ip) + { + case MeInfo: + { + MEInfo mei = m->getMEInfo(); + cout << _(" Manufacturer: ") << mei._manufacturer << endl + << _(" Model: ") << mei._model << endl + << _(" Revision: ") << mei._revision << endl + << _(" Serial Number: ") << mei._serialNumber << endl; + break; + } + case OperatorInfo: + { + int count = 0; + vector opis = m->getAvailableOPInfo(); + for (vector::iterator i = opis.begin(); i != opis.end(); ++i) + { + cout << " Status: "); + switch (i->_status) + { + case UnknownOPStatus: cout << _("unknown"); break; + case CurrentOPStatus: cout << _("current"); break; + case AvailableOPStatus: cout << _("available"); break; + case ForbiddenOPStatus: cout << _("forbidden"); break; + } + cout << _(" Long name: '") << i->_longName << "' " + << _(" Short name: '") << i->_shortName << "' " + << _(" Numeric name: ") << i->_numericName << endl; + ++count; + } + break; + } + case CurrentOperatorInfo: + { + OPInfo opi = m->getCurrentOPInfo(); + cout << "" + << _(" Long name: '") << opi._longName << "' " + << _(" Short name: '") << opi._shortName << "' " + << _(" Numeric name: ") << opi._numericName + << _(" Mode: "); + switch (opi._mode) + { + case AutomaticOPMode: cout << _("automatic"); break; + case ManualOPMode: cout << _("manual"); break; + case DeregisterOPMode: cout << _("deregister"); break; + case ManualAutomaticOPMode: cout << _("manual/automatic"); break; + } + cout << endl; + break; + } + case FacilityLockStateInfo: + { + int count = 0; + vector fclc = m->getFacilityLockCapabilities(); + for (vector::iterator i = fclc.begin(); i != fclc.end(); ++i) + if (*i != "AB" && *i != "AG" && *i != "AC") + { + cout << " '" << *i << "'"; + try + { + if (m->getFacilityLockStatus(*i, VoiceFacility)) + cout << _(" Voice"); + } + catch (GsmException &e) + { + cout << _(" unknown"); + } + try + { + if (m->getFacilityLockStatus(*i, DataFacility)) + cout << _(" Data"); + } + catch (GsmException &e) + { + cout << _(" unknown"); + } + try + { + if (m->getFacilityLockStatus(*i, FaxFacility)) + cout << _(" Fax"); + } + catch (GsmException &e) + { + cout << _(" unknown"); + } + cout << endl; + ++count; + } + break; + } + case FacilityLockCapabilityInfo: + { + cout << " "; + vector fclc = m->getFacilityLockCapabilities(); + for (vector::iterator i = fclc.begin(); i != fclc.end(); ++i) + cout << "'" << *i << "' "; + cout << endl; + break; + } + case PasswordInfo: + { + vector pwi = m->getPasswords(); + int count = 0; + for (vector::iterator i = pwi.begin(); i != pwi.end(); ++i) + { + cout << " '" + << i->_facility << "' " << i->_maxPasswdLen << endl; + ++count; + } + break; + } + case CLIPInfo: + { + cout << " " << (m->getNetworkCLIP() ? _("on") : _("off")) << endl; + break; + } + case CallForwardingInfo: + { + for (int r = 0; r < 4; ++r) + { + string text; + switch (r) + { + case 0: text = _("UnconditionalReason"); break; + case 1: text = _("MobileBusyReason"); break; + case 2: text = _("NoReplyReason"); break; + case 3: text = _("NotReachableReason"); break; + } + ForwardInfo voice, fax, data; + m->getCallForwardInfo((ForwardReason)r, voice, fax, data); + cout << " " + text + _(" Voice"), voice); + cout << " " + text + _(" Data"), data); + cout << " " + text + _(" Fax"), fax); + } + break; + } + case BatteryInfo: + { + cout << " "; + int bcs = m->getBatteryChargeStatus(); + switch (bcs) + { + case 0: cout << _("0 ME is powered by the battery") << endl; break; + case 1: cout << _("1 ME has a battery connected, but is not powered by it") + << endl; break; + case 2: cout << _("2 ME does not have a battery connected") << endl; break; + case 3: + cout << _("3 Recognized power fault, calls inhibited") << endl; + break; + } + cout << " " << m->getBatteryCharge() << endl; + break; + } + case BitErrorInfo: + { + cout << " " << m->getBitErrorRate() << endl; + break; + } + case SCAInfo: + { + cout << " " << m->getServiceCentreAddress() << endl; + break; + } + case CharSetInfo: + { + cout << " "; + vector cs = m->getSupportedCharSets(); + for (vector::iterator i = cs.begin(); i != cs.end(); ++i) + cout << "'" << *i << "' "; + cout << endl; + cout << " '" << m->getCurrentCharSet() << "'" << endl; + break; + } + case SignalInfo: + { + cout << " " << m->getSignalStrength() << endl; + break; + } + case PhonebookInfo: + { + cout << " "; + vector pb = m->getSupportedPhonebooks(); + for (vector::iterator i = pb.begin(); i != pb.end(); ++i) + cout << "'" << *i << "' "; + cout << endl; + cout << " '" << m->getCurrentPhonebook() << "'" << endl; + break; + } + case SignalToneInfo: + { + cout << " "; + IntRange st = m->getSupportedSignalTones(); + printIntRange(st); + cout << endl; +// cout << " '" << m->getCurrentSignalTone() << "'" << endl; + break; + } + case RingingToneInfo: + { + cout << " "; + IntRange rt = m->getSupportedRingingTones(); + printIntRange(rt); + cout << endl; + cout << " " << m->getCurrentRingingTone() << endl; + break; + } + case BinaryInfo: + { + cout << " "; + vector bnr = m->getSupportedBinaryReads(); + for (vector::iterator i = bnr.begin(); i != bnr.end(); ++i) + { + printParameterRange(*i); + cout << " "; + } + cout << endl; + cout << " "; + vector bnw = m->getSupportedBinaryWrites(); + for (vector::iterator i = bnw.begin(); i != bnw.end(); ++i) + { + printParameterRange(*i); + cout << " "; + } + cout << endl; + break; + } + default: + assert(0); + break; + } +} + +// convert facility class string of the form "", "all", or any combination +// of "v" (voice), "d" (data), or "f" (fax) to numeric form + +FacilityClass strToFacilityClass(string facilityClassS) +{ + facilityClassS = lowercase(facilityClassS); + FacilityClass facilityClass = (FacilityClass)0; + if (facilityClassS == "all" || facilityClassS == "") + return (FacilityClass)ALL_FACILITIES; + + // OR in facility class bits + for (unsigned int i = 0; i < facilityClassS.length(); ++i) + if (facilityClassS[i] == 'v') + facilityClass = (FacilityClass)(facilityClass | VoiceFacility); + else if (facilityClassS[i] == 'd') + facilityClass = (FacilityClass)(facilityClass | DataFacility); + else if (facilityClassS[i] == 'f') + facilityClass = (FacilityClass)(facilityClass | FaxFacility); + else + throw GsmException( + stringPrintf(_("unknown facility class parameter '%c'"), + facilityClassS[i]), ParameterError); + + return facilityClass; +} + +// check if argc - optind is in range min..max +// throw exception otherwise + +void checkParamCount(int optind, int argc, int min, int max) +{ + int paramCount = argc - optind; + if (paramCount < min) + throw GsmException(stringPrintf(_("not enough parameters, minimum number " + "of parameters is %d"), min), + ParameterError); + else if (paramCount > max) + throw GsmException(stringPrintf(_("too many parameters, maximum number " + "of parameters is %d"), max), + ParameterError); +} + +// *** main program + +int main(int argc, char *argv[]) +{ + try + { + // handle command line options + string device = "/dev/mobilephone"; + string operation; + string baudrate; + string initString = DEFAULT_INIT_STRING; + bool swHandshake = false; + + int opt; + int dummy; + while((opt = getopt_long(argc, argv, "I:o:d:b:hvX", longOpts, &dummy)) + != -1) + switch (opt) + { + case 'X': + swHandshake = true; + break; + case 'I': + initString = optarg; + break; + case 'd': + device = optarg; + break; + case 'o': + operation = optarg; + break; + case 'b': + baudrate = optarg; + break; + case 'v': + cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"), + VERSION, __DATE__) << endl; + exit(0); + break; + case 'h': + cerr << argv[0] << _(": [-b baudrate][-d device][-h]" + "[-I init string][-o operation]\n" + " [-v][-X]{parameters}") << endl + << endl + << _(" -b, --baudrate baudrate to use for device " + "(default: 38400)") + << endl + << _(" -d, --device sets the destination device to " + "connect to") << endl + << _(" -h, --help prints this message") << endl + << _(" -I, --init device AT init sequence") << endl + << _(" -o, --operation operation to perform on the mobile \n" + " phone with the specified parameters") + << endl + << _(" -v, --version prints version and exits") << endl + << _(" -X, --xonxoff switch on software handshake") << endl + << endl + << _(" parameters parameters to use for the operation\n" + " (if an operation is given) or\n" + " a specification which kind of\n" + " information to read from the mobile " + "phone") + << endl << endl + << _("Refer to gsmctl(1) for details on the available parameters" + " and operations.") + << endl << endl; + exit(0); + break; + case '?': + throw GsmException(_("unknown option"), ParameterError); + break; + } + + // open the port and ME/TA + m = new SieMe(new +#ifdef WIN32 + Win32SerialPort +#else + UnixSerialPort +#endif + (device, + baudrate == "" ? + DEFAULT_BAUD_RATE : + baudRateStrToSpeed(baudrate), + initString, swHandshake)); + + if (operation == "") + { // process info parameters + for (int i = optind; i < argc; ++i) + { + string param = lowercase(argv[i]); + if (param == "all") + for (int ip = MeInfo; ip <= SignalInfo; ++ip) + printInfo((InfoParameter)ip); + else if (param == "me") + printInfo(MeInfo); + else if (param == "op") + printInfo(OperatorInfo); + else if (param == "currop") + printInfo(CurrentOperatorInfo); + else if (param == "flstat") + printInfo(FacilityLockStateInfo); + else if (param == "flcap") + printInfo(FacilityLockCapabilityInfo); + else if (param == "pw") + printInfo(PasswordInfo); + else if (param == "clip") + printInfo(CLIPInfo); + else if (param == "forw") + printInfo(CallForwardingInfo); + else if (param == "batt") + printInfo(BatteryInfo); + else if (param == "biterr") + printInfo(BitErrorInfo); + else if (param == "sig") + printInfo(SignalInfo); + else if (param == "sca") + printInfo(SCAInfo); + else if (param == "cset") + printInfo(CharSetInfo); + else if (param == "pbook") + printInfo(PhonebookInfo); + else if (param == "signal") + printInfo(SignalToneInfo); + else if (param == "ring") + printInfo(RingingToneInfo); + else if (param == "binary") + printInfo(BinaryInfo); + else + throw GsmException( + stringPrintf(_("unknown information parameter '%s'"), + param.c_str()), + ParameterError); + } + } + else + { // process operation + operation = lowercase(operation); + if (operation == "dial") + { + // dial: number + checkParamCount(optind, argc, 1, 1); + + m->dial(argv[optind]); + + // wait for keypress from stdin + char c; + read(1, &c, 1); + } + else if (operation == "setop") + { + // setop: opmode numeric FIXME allow long and numeric too + checkParamCount(optind, argc, 2, 2); + string opmodeS = lowercase(argv[optind]); + OPModes opmode; + if (opmodeS == "automatic") + opmode = AutomaticOPMode; + else if (opmodeS == "manual") + opmode = ManualOPMode; + else if (opmodeS == "deregister") + opmode = DeregisterOPMode; + else if (opmodeS == "manualautomatic") + opmode = ManualAutomaticOPMode; + else + throw GsmException(stringPrintf(_("unknown opmode parameter '%s'"), + opmodeS.c_str()), ParameterError); + + m->setCurrentOPInfo(opmode, "" , "", checkNumber(argv[optind + 1])); + } + else if (operation == "lock") + { + // lock: facility [facilityclass] [passwd] + checkParamCount(optind, argc, 1, 3); + string passwd = (argc - optind == 3) ? + (string)argv[optind + 2] : (string)""; + + m->lockFacility(argv[optind], + (argc - optind >= 2) ? + strToFacilityClass(argv[optind + 1]) : + (FacilityClass)ALL_FACILITIES, + passwd); + } + else if (operation == "unlock") + { + // unlock: facility [facilityclass] [passwd] + checkParamCount(optind, argc, 1, 3); + string passwd = argc - optind == 3 ? argv[optind + 2] : ""; + + m->unlockFacility(argv[optind], + (argc - optind >= 2) ? + strToFacilityClass(argv[optind + 1]) : + (FacilityClass)ALL_FACILITIES, + passwd); + } + else if (operation == "setpw") + { + // set password: facility oldpasswd newpasswd + checkParamCount(optind, argc, 1, 3); + string oldPasswd = argc - optind >= 2 ? argv[optind + 1] : ""; + string newPasswd = argc - optind == 3 ? argv[optind + 2] : ""; + + m->setPassword(argv[optind], oldPasswd, newPasswd); + } + else if (operation == "forw") + { + // call forwarding: mode reason number [facilityclass] [forwardtime] + checkParamCount(optind, argc, 2, 5); + + // get optional parameters facility class and forwardtime + int forwardTime = argc - optind == 5 ? checkNumber(argv[optind + 4]) : + NOT_SET; + FacilityClass facilityClass = + argc - optind >= 4 ? strToFacilityClass(argv[optind + 3]) : + (FacilityClass)ALL_FACILITIES; + + // get forward reason + string reasonS = lowercase(argv[optind + 1]); + ForwardReason reason; + if (reasonS == "unconditional") + reason = UnconditionalReason; + else if (reasonS == "mobilebusy") + reason = MobileBusyReason; + else if (reasonS == "noreply") + reason = NoReplyReason; + else if (reasonS == "notreachable") + reason = NotReachableReason; + else if (reasonS == "all") + reason = AllReasons; + else if (reasonS == "allconditional") + reason = AllConditionalReasons; + else + throw GsmException( + stringPrintf(_("unknown forward reason parameter '%s'"), + reasonS.c_str()), ParameterError); + + // get mode + string modeS = lowercase(argv[optind]); + ForwardMode mode; + if (modeS == "disable") + mode = DisableMode; + else if (modeS == "enable") + mode = EnableMode; + else if (modeS == "register") + mode = RegistrationMode; + else if (modeS == "erase") + mode = ErasureMode; + else + throw GsmException( + stringPrintf(_("unknown forward mode parameter '%s'"), + modeS.c_str()), ParameterError); + + m->setCallForwarding(reason, mode, + (argc - optind >= 3) ? argv[optind + 2] : "", + "", // subaddr + facilityClass, forwardTime); + } + else if (operation == "setsca") + { + // set sca: number + checkParamCount(optind, argc, 1, 1); + m->setServiceCentreAddress(argv[optind]); + } + else if (operation == "cset") + { + // set charset: string + checkParamCount(optind, argc, 1, 1); + m->setCharSet(argv[optind]); + } + else if (operation == "signal") + { + // play signal tone: int + checkParamCount(optind, argc, 1, 1); + int tone = atoi(argv[optind]); + m->playSignalTone(tone); + } + else if (operation == "setrt") + { + // set ringing tone: int int + checkParamCount(optind, argc, 2, 2); + int tone = atoi(argv[optind]); + int volume = atoi(argv[optind + 1]); + m->setRingingTone(tone, volume); + } + else if (operation == "playrt") + { + // play/stop ringing tone + m->toggleRingingTone(); + } + else + throw GsmException(stringPrintf(_("unknown operation '%s'"), + operation.c_str()), ParameterError); + } + } + catch (GsmException &ge) + { + cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl; + return 1; + } + return 0; +} --- gsmlib-1.7/apps/gsmsiexfer.cc Sun Dec 16 23:12:41 2001 +++ gsmlib-1.7-SieMe/apps/gsmsiexfer.cc Sun Dec 16 21:13:56 2001 @@ -0,0 +1,292 @@ +// ************************************************************************* +// * GSM TA/ME library +// * +// * File: gsmsiexfer.cc +// * +// * Purpose: Siemens ME file transfer program +// * +// * Author: Christian W. Zuckschwerdt +// * +// * Created: 2001-12-16 +// ************************************************************************* + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#ifdef WIN32 +#include +#else +#include +#include +#endif +#if defined(HAVE_GETOPT_LONG) || defined(WIN32) +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace gsmlib; + +#ifdef HAVE_GETOPT_LONG +static struct option longOpts[] = +{ + {"xonxoff", no_argument, (int*)NULL, 'X'}, + {"init", required_argument, (int*)NULL, 'I'}, + {"destination", required_argument, (int*)NULL, 'd'}, + {"source", required_argument, (int*)NULL, 's'}, + {"baudrate", required_argument, (int*)NULL, 'b'}, + {"type", required_argument, (int*)NULL, 't'}, + {"subtype", required_argument, (int*)NULL, 'i'}, + {"help", no_argument, (int*)NULL, 'h'}, + {"version", no_argument, (int*)NULL, 'v'}, + {"verbose", no_argument, (int*)NULL, 'V'}, + {(char*)NULL, 0, (int*)NULL, 0} +}; +#else +#define getopt_long(argc, argv, options, longopts, indexptr) \ + getopt(argc, argv, options) +#endif + +// I f*ck up this file IO thing. + +// read binary object from stdin +BinaryObject readBinaryFile(istream &ifs, string filename) +{ + size_t size = 10000; // Bad coder, no biscuits! + BinaryObject bnr; + bnr._data = new unsigned char[size]; + ifs.read(bnr._data, size); + bnr._size = ifs.gcount(); + return bnr; +} + +// read binary object from file +BinaryObject readFile(string filename) +{ + // open the file + ifstream ifs(filename.c_str()); + if (ifs.bad()) + throw GsmException(stringPrintf(_("cannot open file '%s'"), + filename.c_str()), + OSError); + // and read the file + return readBinaryFile(ifs, filename); +} + +// read binary object from stdin +BinaryObject readFile(bool fromStdin) +{ + // read from stdin +// if (fromStdin) + return readBinaryFile(cin, (string)_("")); +} + +// write binary object to file +void writeBinaryFile(ostream &ofs, string filename, BinaryObject bnw) +{ + // well just dump the data + ofs.write(bnw._data, bnw._size); +} + +// write binary object +void writeFile(string filename, BinaryObject obj) +{ + // open the file + ofstream ofs(filename.c_str()); + if (ofs.bad()) + throw GsmException(stringPrintf(_("cannot open file '%s'"), + filename.c_str()), + OSError); + // and read the file + writeBinaryFile(ofs, filename, obj); +} + +// write binary object to stdout +void writeFile(bool toStdout, BinaryObject obj) +{ +// if (toStdout) + writeBinaryFile(cout, (string)_(""), obj); +} + +// *** main program + +int main(int argc, char *argv[]) +{ + try + { + // handle command line options + string destination; + string source; + string baudrate; + string type; + string subtype; + int subtypeN; + bool verbose = false; + string initString = DEFAULT_INIT_STRING; + bool swHandshake = false; + Ref sourceMeTa, destMeTa; + BinaryObject sourceObject; + + int opt; + int dummy; + while((opt = getopt_long(argc, argv, "XI:s:d:b:hvVt:i:", longOpts, + &dummy)) + != -1) + switch (opt) + { + case 'X': + swHandshake = true; + break; + case 'I': + initString = optarg; + break; + case 'V': + verbose = true; + break; + case 't': + type = optarg; + break; + case 'i': + subtype = optarg; + subtypeN = atoi(optarg); + break; + case 'd': + destination = optarg; + break; + case 's': + source = optarg; + break; + case 'b': + baudrate = optarg; + break; + case 'v': + cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"), + VERSION, __DATE__) << endl; + exit(0); + break; + case 'h': + cerr << argv[0] << _(": [-b baudrate][-c][-d device or file][-h]" + "[-I init string]\n" + " [-p phonebook name][-s device or file]" + "[-t charset][-v]" + "[-V][-y][-X]") << endl + << endl + << _(" -b, --baudrate baudrate to use for device " + "(default: 38400)") + << endl + << _(" -c, --copy copy source entries to destination") + << endl + << _(" -d, --destination sets the destination device to " + "connect \n" + " to, or the file to write") << endl + << _(" -D, --destination-backend sets the destination backend") + << endl + << _(" -h, --help prints this message") << endl + << _(" -i, --index takes index positions into account") + << endl + << _(" -I, --init device AT init sequence") << endl + << _(" -p, --phonebook name of phonebook to use") << endl + << _(" -s, --source sets the source device to connect to,\n" + " or the file to read") << endl + << _(" -t, --charset sets the character set to use for\n" + " phonebook entries") << endl + << _(" -S, --source-backend sets the source backend") + << endl + << _(" -v, --version prints version and exits") << endl + << _(" -V, --verbose print detailed progress messages") + << endl + << _(" -X, --xonxoff switch on software handshake") << endl + << _(" -y, --synchronize synchronize destination with source\n" + " entries (destination is overwritten)\n" + " (see gsmpb(1) for details)") + << endl << endl; + exit(0); + break; + case '?': + throw GsmException(_("unknown option"), ParameterError); + break; + } + + // check if all parameters all present + if (destination == "" || source == "") + throw GsmException(_("both source and destination must be given"), + ParameterError); + + // start accessing source mobile phone or file + if (source == "-") + sourceObject = readFile(true); + else if (isFile(source)) + sourceObject = readFile(source); + else + { + if (type == "") + throw GsmException(_("type be given"), ParameterError); + if (subtype == "") + throw GsmException(_("subtype be given"), ParameterError); + + sourceMeTa = new SieMe(new +#ifdef WIN32 + Win32SerialPort +#else + UnixSerialPort +#endif + (source, + baudrate == "" ? DEFAULT_BAUD_RATE : + baudRateStrToSpeed(baudrate), initString, + swHandshake)); + sourceObject = sourceMeTa->getBinary(type, subtypeN); + } + + // make sure destination.c_str file exists + if (destination != "") + { + try + { + ofstream f(destination.c_str(), ios::out | ios::app); + } + catch (exception) + { + } + } + + // start accessing destination mobile phone or file + if (destination == "-") + writeFile(true, sourceObject); + else if (isFile(destination)) + writeFile(destination, sourceObject); + else + { + if (type == "") + throw GsmException(_("type must be given"), ParameterError); + if (subtype == "") + throw GsmException(_("subtype must be given"), ParameterError); + + destMeTa = new SieMe(new +#ifdef WIN32 + Win32SerialPort +#else + UnixSerialPort +#endif + (destination, + baudrate == "" ? DEFAULT_BAUD_RATE : + baudRateStrToSpeed(baudrate), initString, + swHandshake)); + destMeTa->setBinary(type, subtypeN, sourceObject); + } + } + catch (GsmException &ge) + { + cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl; + return 1; + } + return 0; +} --- gsmlib-1.7/gsmlib/Makefile.am Sat Aug 4 22:14:36 2001 +++ gsmlib-1.7-SieMe/gsmlib/Makefile.am Sat Dec 15 14:08:40 2001 @@ -20,7 +20,7 @@ gsm_sms.cc gsm_sms_codec.cc gsm_sms_store.cc \ gsm_event.cc gsm_sorted_phonebook.cc \ gsm_sorted_sms_store.cc gsm_nls.cc \ - gsm_sorted_phonebook_base.cc gsm_cb.cc + gsm_sorted_phonebook_base.cc gsm_cb.cc gsm_sie_me.cc gsmincludedir = $(includedir)/gsmlib @@ -29,7 +29,7 @@ gsm_util.h gsm_me_ta.h gsm_port.h gsm_sms_store.h \ gsm_event.h gsm_sorted_phonebook.h \ gsm_sorted_sms_store.h gsm_map_key.h \ - gsm_sorted_phonebook_base.h gsm_cb.h + gsm_sorted_phonebook_base.h gsm_cb.h gsm_sie_me.h noinst_HEADERS = gsm_nls.h gsm_sysdep.h --- gsmlib-1.7/gsmlib/gsm_sie_me.cc Sat Dec 15 21:49:30 2001 +++ gsmlib-1.7-SieMe/gsmlib/gsm_sie_me.cc Sun Dec 16 22:48:33 2001 @@ -0,0 +1,257 @@ +// ************************************************************************* +// * GSM TA/ME library +// * +// * File: gsm_sie_me.cc +// * +// * Purpose: Mobile Equipment/Terminal Adapter and SMS functions +// * (According to "AT command set for S45 Siemens mobile phones" +// * v1.8, 26. July 2001 - Common AT prefix is "^S") +// * +// * Author: Christian W. Zuckschwerdt +// * +// * Created: 2001-12-15 +// ************************************************************************* + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include + +using namespace std; +using namespace gsmlib; + +// SieMe members + +void SieMe::init() throw(GsmException) +{ +} + +SieMe::SieMe(Ref port) throw(GsmException) : MeTa::MeTa(port) +{ + // initialize Siemens ME + + init(); +} + +vector SieMe::getSupportedPhonebooks() throw(GsmException) +{ + Parser p(_at->chat("^SPBS=?", "^SPBS:")); + return p.parseStringList(); +} + +string SieMe::getCurrentPhonebook() throw(GsmException) +{ + if (_lastPhonebookName == "") + { + Parser p(_at->chat("^SPBS?", "^SPBS:")); + // answer is e.g. ^SPBS: "SM",41,250 + _lastPhonebookName = p.parseString(); + p.parseComma(); + int _currentNumberOfEntries = p.parseInt(); + p.parseComma(); + int _maxNumberOfEntries = p.parseInt(); + } + return _lastPhonebookName; +} + +void SieMe::setPhonebook(string phonebookName) throw(GsmException) +{ + if (phonebookName != _lastPhonebookName) + { + _at->chat("^SPBS=\"" + phonebookName + "\""); + _lastPhonebookName = phonebookName; + } +} + + +IntRange SieMe:: getSupportedSignalTones() throw(GsmException) +{ + Parser p(_at->chat("^SPST=?", "^SPST:")); + // ^SPST: (0-4),(0,1) + IntRange typeRange = p.parseRange(); + p.parseComma(); + vector volumeList = p.parseIntList(); + return typeRange; +} + +void SieMe:: playSignalTone(int tone) throw(GsmException) +{ + _at->chat("^SPST=" + intToStr(tone) + ",1"); +} + +void SieMe:: stopSignalTone(int tone) throw(GsmException) +{ + _at->chat("^SPST=" + intToStr(tone) + ",0"); +} + + +IntRange SieMe::getSupportedRingingTones() throw(GsmException) // (AT^SRTC=?) +{ + Parser p(_at->chat("^SRTC=?", "^SRTC:")); + // ^SRTC: (0-42),(1-5) + IntRange typeRange = p.parseRange(); + p.parseComma(); + IntRange volumeRange = p.parseRange(); + return typeRange; +} + +int SieMe::getCurrentRingingTone() throw(GsmException) // (AT^SRTC?) +{ + Parser p(_at->chat("^SRTC?", "^SRTC:")); + // ^SRTC: 41,2,0 + int type = p.parseInt(); + p.parseComma(); + int volume = p.parseInt(); + p.parseComma(); + int ringing = p.parseInt(); + return type; +} + +void SieMe::setRingingTone(int tone, int volume) throw(GsmException) +{ + _at->chat("^SRTC=" + intToStr(tone) + "," + intToStr(volume)); +} + +void SieMe:: playRingingTone() throw(GsmException) +{ + // get ringing bool + Parser p(_at->chat("^SRTC?", "^SRTC:")); + // ^SRTC: 41,2,0 + int type = p.parseInt(); + p.parseComma(); + int volume = p.parseInt(); + p.parseComma(); + int ringing = p.parseInt(); + + if (ringing == 0) + toggleRingingTone(); +} + +void SieMe::stopRingingTone() throw(GsmException) +{ + // get ringing bool + Parser p(_at->chat("^SRTC?", "^SRTC:")); + // ^SRTC: 41,2,0 + int type = p.parseInt(); + p.parseComma(); + int volume = p.parseInt(); + p.parseComma(); + int ringing = p.parseInt(); + + if (ringing == 1) + toggleRingingTone(); +} + +void SieMe::toggleRingingTone() throw(GsmException) // (AT^SRTC) +{ + _at->chat("^SRTC"); +} + +// Siemens get supported binary read +vector SieMe::getSupportedBinaryReads() throw(GsmException) +{ + Parser p(_at->chat("^SBNR=?", "^SBNR:")); + // ^SBNR: ("bmp",(0-3)),("mid",(0-4)),("vcf",(0-500)),("vcs",(0-50)) + + return p.parseParameterRangeList(); +} + +// Siemens get supported binary write +vector SieMe::getSupportedBinaryWrites() throw(GsmException) +{ + Parser p(_at->chat("^SBNW=?", "^SBNW:")); + // ^SBNW: ("bmp",(0-3)),("mid",(0-4)),("vcf",(0-500)),("vcs",(0-50)),("t9d",(0)) + + return p.parseParameterRangeList(); +} + +// Siemens Binary Read +BinaryObject SieMe::getBinary(string type, int subtype) throw(GsmException) +{ + // expect several response lines + vector result; + result = _at->chatv("^SBNR=\"" + type + "\"," + intToStr(subtype), "^SBNR:"); + // "bmp",0,1,5 pdu "bmp",0,2,5 ... + // most likely to be PDUs of 382 chars (191 * 2) + string pdu; + int fragmentCount = 0; + for (vector::iterator i = result.begin(); i != result.end(); ++i) + { + ++fragmentCount; + // parse header + Parser p(*i); + string fragmentType = p.parseString(); + if (fragmentType != type) + throw GsmException(_("bad PDU type"), ChatError); + p.parseComma(); + int fragmentSubtype = p.parseInt(); + if (fragmentSubtype != subtype) + throw GsmException(_("bad PDU subtype"), ChatError); + p.parseComma(); + int fragmentNumber = p.parseInt(); + if (fragmentNumber != fragmentCount) + throw GsmException(_("bad PDU number"), ChatError); + p.parseComma(); + int numberOfFragments = p.parseInt(); + if (fragmentNumber > numberOfFragments) + throw GsmException(_("bad PDU number"), ChatError); + + // concat pdu fragment + ++i; + pdu += *i; + } + + BinaryObject bnr; + bnr._type = type; + bnr._subtype = subtype; + bnr._size = pdu.length() / 2; + bnr._data = new unsigned char[pdu.length() / 2]; + if (! hexToBuf(pdu, bnr._data)) + throw GsmException(_("bad hexadecimal PDU format"), ChatError); + + return bnr; +} + +// Siemens Binary Write +void SieMe::setBinary(string type, int subtype, BinaryObject obj) + throw(GsmException) +{ + if (obj._size <= 0) + throw GsmException(_("bad object"), ParameterError); + + // Limitation: The maximum pdu size is 176 bytes (or 352 characters) + // this should be a configurable field + int maxPDUsize = 176; + int numberOfPDUs = (obj._size + maxPDUsize - 1) / maxPDUsize; + unsigned char *p = obj._data; + + for (int i = 1; i <= numberOfPDUs; ++i) + { + // construct pdu + int size = maxPDUsize; + if (i == numberOfPDUs) + size = obj._size - (numberOfPDUs - 1) * maxPDUsize; + string pdu = bufToHex(p, size); + p += size; + + cout << "processing " << i << " of " << numberOfPDUs + << " of " << size << " bytes." << endl; + cout << "^SBNW=\"" + type + "\"," + intToStr(subtype) + "," + + intToStr(i) + "," + intToStr(numberOfPDUs) << endl; + cout << pdu << endl; + + _at->sendPdu("^SBNW=\"" + type + "\"," + intToStr(subtype) + "," + + intToStr(i) + "," + intToStr(numberOfPDUs), "", + pdu, true); + cout << "OK" << endl; + } +} + + + + + --- gsmlib-1.7/gsmlib/gsm_sie_me.h Sat Dec 15 21:49:30 2001 +++ gsmlib-1.7-SieMe/gsmlib/gsm_sie_me.h Sun Dec 16 20:41:41 2001 @@ -0,0 +1,99 @@ +// ************************************************************************* +// * GSM TA/ME library +// * +// * File: gsm_sie_me.h +// * +// * Purpose: Mobile Equipment/Terminal Adapter and SMS functions +// * (According to "AT command set for S45 Siemens mobile phones" +// * v1.8, 26. July 2001 - Common AT prefix is "^S") +// * +// * Author: Christian W. Zuckschwerdt +// * +// * Created: 2001-12-15 +// ************************************************************************* + +#ifndef GSM_SIE_ME_H +#define GSM_SIE_ME_H + +#include +#include +#include +#include + +using namespace std; + +namespace gsmlib +{ + // *** Siemens mobile phone binary objects (bitmap, midi, vcal, vcard) + + struct BinaryObject + { + string _type; // Object type + int _subtype; // Object subtype (storage number) + unsigned char *_data; // Object binary data + int _size; // Object data size + }; + + // *** this class allows extended access to Siemens moblie phones + + class SieMe : public MeTa + { + private: + // init ME/TA to sensible defaults + void init() throw(GsmException); + + public: + // initialize a new MeTa object given the port + SieMe(Ref port) throw(GsmException); + + + // get the current phonebook in the Siemens ME + vector getSupportedPhonebooks() throw(GsmException);// (AT^SPBS=?) + + // get the current phonebook in the Siemens ME + string getCurrentPhonebook() throw(GsmException); // (AT^SPBS?) + + // set the current phonebook in the Siemens ME + // remember the last phonebook set for optimisation + void setPhonebook(string phonebookName) throw(GsmException); // (AT^SPBS=) + + + // Siemens get supported signal tones + IntRange getSupportedSignalTones() throw(GsmException); // (AT^SPST=?) + + // Siemens set ringing tone + void playSignalTone(int tone) throw(GsmException); // (AT^SRTC=x,1) + + // Siemens set ringing tone + void stopSignalTone(int tone) throw(GsmException); // (AT^SRTC=x,0) + + + // Siemens get ringing tone + IntRange getSupportedRingingTones() throw(GsmException); // (AT^SRTC=?) + // Siemens get ringing tone + int getCurrentRingingTone() throw(GsmException); // (AT^SRTC?) + // Siemens set ringing tone + void setRingingTone(int tone, int volume) throw(GsmException);// (AT^SRTC=) + // Siemens set ringing tone on + void playRingingTone() throw(GsmException); + // Siemens set ringing tone of + void stopRingingTone() throw(GsmException); + // Siemens toggle ringing tone + void toggleRingingTone() throw(GsmException); // (AT^SRTC) + + // Siemens get supported binary read + vector getSupportedBinaryReads() throw(GsmException); + + // Siemens get supported binary write + vector getSupportedBinaryWrites() throw(GsmException); + + // Siemens Binary Read + BinaryObject getBinary(string type, int subtype) throw(GsmException); + + // Siemens Binary Write + void setBinary(string type, int subtype, BinaryObject obj) + throw(GsmException); + }; +}; + +#endif // GSM_ME_TA_H --- gsmlib-1.7/gsmlib/gsm_at.cc Sun Aug 5 23:55:50 2001 +++ gsmlib-1.7-SieMe/gsmlib/gsm_at.cc Sun Dec 16 22:38:12 2001 @@ -264,8 +264,8 @@ return s.substr(start, end - start); } -string GsmAt::sendPdu(string atCommand, string response, - string pdu) throw(GsmException) +string GsmAt::sendPdu(string atCommand, string response, string pdu, + bool acceptEmptyResponse) throw(GsmException) { string s; bool errorCondition = false; @@ -329,6 +329,10 @@ if (matchResponse(s, "ERROR")) throw GsmException(_("ME/TA error '' (code not known)"), ChatError, -1); + + // return if response is "OK" and caller says this is OK + if (acceptEmptyResponse && s == "OK") + return ""; if (matchResponse(s, response)) { --- gsmlib-1.7/gsmlib/gsm_at.h Tue Aug 29 08:00:33 2000 +++ gsmlib-1.7-SieMe/gsmlib/gsm_at.h Sun Dec 16 22:39:07 2001 @@ -86,8 +86,8 @@ // send pdu (wait for and send // at the end // return text after response - string sendPdu(string atCommand, string response, - string pdu) throw(GsmException); + string sendPdu(string atCommand, string response, string pdu, + bool acceptEmptyResponse = false) throw(GsmException); // functions from class Port string getLine() throw(GsmException); --- gsmlib-1.7/gsmlib/gsm_parser.cc Sun Dec 3 22:58:32 2000 +++ gsmlib-1.7-SieMe/gsmlib/gsm_parser.cc Sun Dec 16 15:05:06 2001 @@ -265,7 +265,39 @@ return result; } -IntRange Parser::parseRange(bool allowNoRange) +vector Parser::parseParameterRangeList(bool allowNoList) + throw(GsmException) +{ + // handle case of empty parameter + vector result; + if (checkEmptyParameter(allowNoList)) return result; + + result.push_back(parseParameterRange()); + while (parseComma(true)) + { + result.push_back(parseParameterRange()); + } + + return result; +} + +ParameterRange Parser::parseParameterRange(bool allowNoParameterRange) + throw(GsmException) +{ + // handle case of empty parameter + ParameterRange result; + if (checkEmptyParameter(allowNoParameterRange)) return result; + + parseChar('('); + result._parameter = parseString(); + parseComma(); + result._range = parseRange(false, true); + parseChar(')'); + + return result; +} + +IntRange Parser::parseRange(bool allowNoRange, bool allowNonRange) throw(GsmException) { // handle case of empty parameter @@ -274,8 +306,9 @@ parseChar('('); result._low = parseInt(); - parseChar('-'); - result._high = parseInt(); + // allow non-ranges is allowNonRange == true + if (parseChar('-', allowNonRange)) + result._high = parseInt(); parseChar(')'); return result; --- gsmlib-1.7/gsmlib/gsm_parser.h Thu Jul 19 23:52:11 2001 +++ gsmlib-1.7-SieMe/gsmlib/gsm_parser.h Sun Dec 16 15:02:00 2001 @@ -72,10 +72,23 @@ vector parseIntList(bool allowNoList = false) throw(GsmException); + // parse a list of parameter ranges (see below) + // the list can be empty (ie. == "" ) if allowNoList == true + vector parseParameterRangeList(bool allowNoList = false) + throw(GsmException); + + // parse a string plus its valid integer range of the + // form "("string",(1-125))" + // the parameter range may be absent if allowNoParameterRange == true + ParameterRange parseParameterRange(bool allowNoParameterRange = false) + throw(GsmException); + // parse an integer range of the form "(1-125)" // the range may be absent if allowNoRange == true // then IntRange::_high and _low are set to NOT_SET - IntRange parseRange(bool allowNoRange = false) + // the range may be short if allowNonRange == true + // then IntRange::_high is set to NOT_SET + IntRange parseRange(bool allowNoRange = false, bool allowNonRange = false) throw(GsmException); // parse an integer of the form "1234" --- gsmlib-1.7/gsmlib/gsm_util.h Fri Jan 19 21:29:57 2001 +++ gsmlib-1.7-SieMe/gsmlib/gsm_util.h Sun Dec 16 14:26:41 2001 @@ -63,6 +63,13 @@ IntRange() : _high(NOT_SET), _low(NOT_SET) {} }; + // A valid integer range for a given parameter + struct ParameterRange + { + string _parameter; + IntRange _range; + }; + // *** general-purpose pointer wrapper with reference counting class RefBase