--- gsmlib-1.8/ext/README.sieme Wed Jan 16 20:10:07 2002 +++ gsmlib-1.8-SieMe/ext/README.sieme Wed Jan 16 20:09:55 2002 @@ -0,0 +1,75 @@ +Extended support for Siemens mobile phones via gsmlib +----------------------------------------------------- + +* Hardware: + +Supported phones: S25, S35, S45, ME45, SL45 +Tested phones: S45, ME45 + +* Feature list: + + - ACM: Output ACM (accumulated call meter) and ACMmax => maybe not + + - BNR/BNW: Binary read and write => yes, xfer + + - CID: Output card ID => maybe + + - CKS: Output SIM card status => maybe + + - CNI: Output call number information => maybe + + - DBR: Database Read => yes, phonebook + + - DLD: Delete the "last number redial" memory => maybe dangerous? + + - GAUTH: Select Type of Authentication for PPP => no + + - ICO: Icon control => no + + - LCK: Switch locks on and off => yes, lock/unlock + + - LNG: Language settings => maybe + + - MGL: List SMS => no + + - MGO: SMS overflow indicator => no + + - MGR: Read SMS (same as AT+CMGR) => no + + - MSO: Switch device off => maybe not + + - NFS: Select NF hardware => maybe + + - NFV: Set the volume => maybe + + - PBC: Seek in telephone book => no + + - PBG: Sorted telephone book => yes + + - PBS: Select a telephone book => yes + + - PIC: Output PIN counter => maybe + + - PLM: Read the PLMN list => yes + + - PLR/PLW: read/write preferred-operator list => yes + + - PST: Play Signal Tone => yes + + - PWD: Change password to a lock => maybe + + - RTC: Set the ringing tone => yes + + - STK: SIM toolkit => no + + +* Additional References + +http://www.s45-world.net/vissie.htm + + +* Author and contact + +Christian W. Zuckschwerdt +http://triq.net/gsm.html + diff -ruN gsmlib-1.8/ext/Makefile.am gsmlib-1.8-SieMe/ext/Makefile.am --- gsmlib-1.8/ext/Makefile.am Mon Dec 17 22:56:44 2001 +++ gsmlib-1.8-SieMe/ext/Makefile.am Wed Jan 16 19:59:09 2002 @@ -23,10 +23,14 @@ gsminclude_HEADERS = gsm_sie_me.h # build programs -bin_PROGRAMS = gsmsiectl +bin_PROGRAMS = gsmsiectl gsmsiexfer # build gsmsiectl from gsmsiectl.cc and libgsmme.la gsmsiectl_SOURCES = gsmsiectl.cc gsmsiectl_LDADD = ../gsmlib/libgsmme.la libgsmext.la $(INTLLIBS) + +# build gsmsiexfer from gsmsiexfer.cc and libgsmme.la +gsmsiexfer_SOURCES = gsmsiexfer.cc +gsmsiexfer_LDADD = ../gsmlib/libgsmme.la libgsmext.la $(INTLLIBS) diff -ruN gsmlib-1.8/ext/gsm_sie_me.cc gsmlib-1.8-SieMe/ext/gsm_sie_me.cc --- gsmlib-1.8/ext/gsm_sie_me.cc Sun Dec 16 18:26:10 2001 +++ gsmlib-1.8-SieMe/ext/gsm_sie_me.cc Wed Jan 16 19:47:45 2002 @@ -1,10 +1,25 @@ +// ************************************************************************* +// * 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 +#include using namespace std; using namespace gsmlib; @@ -101,7 +116,7 @@ _at->chat("^SRTC=" + intToStr(tone) + "," + intToStr(volume)); } -void SieMe:: ringingToneOn() throw(GsmException) // (AT^SRTC) +void SieMe:: playRingingTone() throw(GsmException) { // get ringing bool Parser p(_at->chat("^SRTC?", "^SRTC:")); @@ -113,10 +128,10 @@ int ringing = p.parseInt(); if (ringing == 0) - _at->chat("^SRTC"); + toggleRingingTone(); } -void SieMe::ringingToneOff() throw(GsmException) // (AT^SRTC) +void SieMe::stopRingingTone() throw(GsmException) { // get ringing bool Parser p(_at->chat("^SRTC?", "^SRTC:")); @@ -128,7 +143,7 @@ int ringing = p.parseInt(); if (ringing == 1) - _at->chat("^SRTC"); + toggleRingingTone(); } void SieMe::toggleRingingTone() throw(GsmException) // (AT^SRTC) @@ -137,47 +152,106 @@ } // Siemens get supported binary read -vector SieMe::getSupportedBinaryReads() throw(GsmException) +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.parseStringList(); + return p.parseParameterRangeList(); } // Siemens get supported binary write -vector SieMe::getSupportedBinaryWrites() throw(GsmException) +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.parseStringList(); + return p.parseParameterRangeList(); } // Siemens Binary Read -void SieMe::getBinary(string binary) throw(GsmException) // (AT^SBNR) +BinaryObject SieMe::getBinary(string type, int subtype) throw(GsmException) { - // same as chat() above but also get pdu if expectPdu == true - //string chat(string atCommand, - // string response, - // string &pdu, - // bool ignoreErrors = false, - // bool expectPdu = true, - // bool acceptEmptyResponse = false) throw(GsmException); - - // same as above, but expect several response lines - //vector chatv(string atCommand = "", - // string response = "", - // bool ignoreErrors = false) + // 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 binary) throw(GsmException) // (AT^SBNW) +void SieMe::setBinary(string type, int subtype, BinaryObject obj) + throw(GsmException) { - // send pdu (wait for and send - // at the end - // return text after response - //string sendPdu(string atCommand, string response, - // string pdu) 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; + } } + + + + diff -ruN gsmlib-1.8/ext/gsm_sie_me.h gsmlib-1.8-SieMe/ext/gsm_sie_me.h --- gsmlib-1.8/ext/gsm_sie_me.h Sun Dec 16 18:18:50 2001 +++ gsmlib-1.8-SieMe/ext/gsm_sie_me.h Wed Jan 16 19:47:35 2002 @@ -1,13 +1,21 @@ -/* - * According to - * AT command set for S45 Siemens mobile phones, v1.8, 26. July 2001 - * Common AT prefix is "^S" (two characters, not the control code!) - */ - +// ************************************************************************* +// * 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 @@ -16,6 +24,17 @@ 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 { @@ -29,12 +48,12 @@ // get the current phonebook in the Siemens ME - vector getSupportedPhonebooks() throw(GsmException); // (AT^SPBS=?) - // 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 + // set the current phonebook in the Siemens ME // remember the last phonebook set for optimisation void setPhonebook(string phonebookName) throw(GsmException); // (AT^SPBS=) @@ -56,23 +75,24 @@ // Siemens set ringing tone void setRingingTone(int tone, int volume) throw(GsmException);// (AT^SRTC=) // Siemens set ringing tone on - void ringingToneOn() throw(GsmException); // (AT^SRTC) + void playRingingTone() throw(GsmException); // Siemens set ringing tone of - void ringingToneOff() throw(GsmException); // (AT^SRTC) + void stopRingingTone() throw(GsmException); // Siemens toggle ringing tone void toggleRingingTone() throw(GsmException); // (AT^SRTC) // Siemens get supported binary read - vector getSupportedBinaryReads() throw(GsmException); // (AT^SBNR=?) + vector getSupportedBinaryReads() throw(GsmException); // Siemens get supported binary write - vector getSupportedBinaryWrites() throw(GsmException); // (AT^SBNW=?) + vector getSupportedBinaryWrites() throw(GsmException); // Siemens Binary Read - void getBinary(string binary) throw(GsmException); // (AT^SBNR) + BinaryObject getBinary(string type, int subtype) throw(GsmException); // Siemens Binary Write - void setBinary(string binary) throw(GsmException); // (AT^SBNW) + void setBinary(string type, int subtype, BinaryObject obj) + throw(GsmException); }; }; diff -ruN gsmlib-1.8/ext/gsmsiectl.cc gsmlib-1.8-SieMe/ext/gsmsiectl.cc --- gsmlib-1.8/ext/gsmsiectl.cc Sun Dec 16 18:26:40 2001 +++ gsmlib-1.8-SieMe/ext/gsmsiectl.cc Wed Jan 16 19:48:04 2002 @@ -5,9 +5,9 @@ // * // * Purpose: GSM Siemens mobile phone control program // * -// * Author: Christian W. Zuckschwerdt (zany@triq.net) +// * Author: Christian W. Zuckschwerdt // * -// * Created: 15.12.2001 +// * Created: 2001-12-15 // ************************************************************************* #ifdef HAVE_CONFIG_H @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #ifdef WIN32 @@ -100,7 +100,19 @@ void printIntRange(IntRange ir) { - cout << "(" << ir._low << "-" << ir._high << ")"; + 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 @@ -319,14 +331,20 @@ case BinaryInfo: { cout << " "; - vector br = m->getSupportedBinaryReads(); - for (vector::iterator i = br.begin(); i != br.end(); ++i) - cout << "'" << *i << "' "; + vector bnr = m->getSupportedBinaryReads(); + for (vector::iterator i = bnr.begin(); i != bnr.end(); ++i) + { + printParameterRange(*i); + cout << " "; + } cout << endl; cout << " "; - vector bw = m->getSupportedBinaryWrites(); - for (vector::iterator i = bw.begin(); i != bw.end(); ++i) - cout << "'" << *i << "' "; + vector bnw = m->getSupportedBinaryWrites(); + for (vector::iterator i = bnw.begin(); i != bnw.end(); ++i) + { + printParameterRange(*i); + cout << " "; + } cout << endl; break; } diff -ruN gsmlib-1.8/ext/gsmsiexfer.cc gsmlib-1.8-SieMe/ext/gsmsiexfer.cc --- gsmlib-1.8/ext/gsmsiexfer.cc Thu Jan 1 01:00:00 1970 +++ gsmlib-1.8-SieMe/ext/gsmsiexfer.cc Wed Jan 16 19:48:10 2002 @@ -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; +} diff -ruN gsmlib-1.8/gsmlib/gsm_at.cc gsmlib-1.8-SieMe/gsmlib/gsm_at.cc --- gsmlib-1.8/gsmlib/gsm_at.cc Thu Nov 29 22:36:38 2001 +++ gsmlib-1.8-SieMe/gsmlib/gsm_at.cc Wed Jan 16 19:57:18 2002 @@ -265,8 +265,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; @@ -334,6 +334,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)) { diff -ruN gsmlib-1.8/gsmlib/gsm_at.h gsmlib-1.8-SieMe/gsmlib/gsm_at.h --- gsmlib-1.8/gsmlib/gsm_at.h Tue Aug 29 08:00:33 2000 +++ gsmlib-1.8-SieMe/gsmlib/gsm_at.h Wed Jan 16 19:53:47 2002 @@ -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); diff -ruN gsmlib-1.8/gsmlib/gsm_parser.cc gsmlib-1.8-SieMe/gsmlib/gsm_parser.cc --- gsmlib-1.8/gsmlib/gsm_parser.cc Sun Dec 3 22:58:32 2000 +++ gsmlib-1.8-SieMe/gsmlib/gsm_parser.cc Wed Jan 16 19:53:14 2002 @@ -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; diff -ruN gsmlib-1.8/gsmlib/gsm_parser.h gsmlib-1.8-SieMe/gsmlib/gsm_parser.h --- gsmlib-1.8/gsmlib/gsm_parser.h Thu Jul 19 23:52:11 2001 +++ gsmlib-1.8-SieMe/gsmlib/gsm_parser.h Wed Jan 16 19:52:30 2002 @@ -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" diff -ruN gsmlib-1.8/gsmlib/gsm_util.h gsmlib-1.8-SieMe/gsmlib/gsm_util.h --- gsmlib-1.8/gsmlib/gsm_util.h Sun Dec 2 09:15:12 2001 +++ gsmlib-1.8-SieMe/gsmlib/gsm_util.h Wed Jan 16 19:51:49 2002 @@ -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