⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gsm_me_ta.cc

📁 开发手机AT指令的源码
💻 CC
📖 第 1 页 / 共 3 页
字号:
// *************************************************************************// * GSM TA/ME library// *// * File:    gsm_me_ta.cc// *// * Purpose: Mobile Equipment/Terminal Adapter functions// *          (ETSI GSM 07.07)// *// * Author:  Peter Hofmann (software@pxh.de)// *// * Created: 10.5.1999// *************************************************************************#ifdef HAVE_CONFIG_H#include <gsm_config.h>#endif#include <gsmlib/gsm_nls.h>#include <gsmlib/gsm_me_ta.h>#include <gsmlib/gsm_parser.h>#include <gsmlib/gsm_sysdep.h>using namespace std;using namespace gsmlib;// Capabilities membersCapabilities::Capabilities() :  _hasSMSSCAprefix(true),  _hasSMSPDUmode(true),  _noCPBxParentheses(false),  _cpmsParamCount(-1),          // initialize to -1, must be set later by                                // setSMSStore() function  _omitsColon(true),            // FIXME  _veryShortCOPSanswer(false),  // Falcom A2-1  _wrongSMSStatusCode(false),   // Motorola Timeport 260  _CDSmeansCDSI(false),         // Nokia Cellular Card Phone RPE-1 GSM900 and                                // Nokia Card Phone RPM-1 GSM900/1800  _sendAck(false),              // send ack for directly routed SMS  _MotorolaModeCmd(false)       // send "+MODE=" to Motorola phone{}// MeTa membersvoid MeTa::init() throw(GsmException){  // Motorola 60t needs "+MODE=2" before it will respond to GSM commands;  // however it will identify itself with the mandatory ITU-T V.25ter  // generic TA control command "+GMM".  try  {    if (_at->chat("+GMM", "+GMM:") == "Motorola  60t Phone")    {      _capabilities._MotorolaModeCmd = true;      _capabilities._noCPBxParentheses = true;            // Put the phone in GSM command mode.  The expected response is      //     <CR><LF>OK<CR><LF>      //     <CR><LF>+MBAN: Copyright 2000 Motorola, Inc.<CR><LF>      _at->chat("+MODE=2", "", false, true);      _at->getLine();             // consume <CR><LF>      _at->getLine();             // consume +MBAN: ... <CR><LF>    }  }  catch (GsmException)  {    // ignore, may not work on all phones  }  // switch on extended error codes  // caution: may be ignored by some TAs, so allow it to fail  _at->chat("+CMEE=1", "", true, true);    // select SMS pdu mode  try  {    _at->chat("+CMGF=0");  }  catch (GsmException)  {    _capabilities._hasSMSPDUmode = false;  }  // now fill in capability object  MEInfo info = getMEInfo();    // Ericsson model 6050102  if ((info._manufacturer == "ERICSSON" &&      (info._model == "1100801" ||       info._model == "1140801")) ||      getenv("GSMLIB_SH888_FIX") != NULL)  {    // the Ericsson leaves out the service centre address    _capabilities._hasSMSSCAprefix = false;  }  // handle Falcom strangeness  if ((info._manufacturer == "Funkanlagen Leipoldt OHG" &&      info._revision == "01.95.F2") ||      getenv("GSMLIB_FALCOM_A2_1_FIX") != NULL)  {    _capabilities._veryShortCOPSanswer = true;  }  // handle Motorola SMS store bug - wrong status code  if ((info._manufacturer == "Motorola" &&       info._model == "L Series"))  {    _capabilities._wrongSMSStatusCode = true;  }    // handle Nokia Cellular Card Phone RPE-1 GSM900 and  // Nokia Card Phone RPM-1 GSM900/1800 bug - CDS means CDSI  if ((info._manufacturer == "Nokia Mobile Phones" &&       (info._model == "Nokia Cellular Card Phone RPE-1 GSM900" ||        info._model == "Nokia Card Phone RPM-1 GSM900/1800")))  {    _capabilities._CDSmeansCDSI = true;  }   // find out whether we are supposed to send an acknowledgment  Parser p(_at->chat("+CSMS?", "+CSMS:"));  _capabilities._sendAck = p.parseInt() >= 1;        // set GSM default character set  try  {    setCharSet("GSM");  }  catch (GsmException)  {    // ignore errors, some devices don't support this  }  // set default event handler  // necessary to handle at least RING indications that might  // otherwise confuse gsmlib  _at->setEventHandler(&_defaultEventHandler);}MeTa::MeTa(Ref<Port> port) throw(GsmException) : _port(port){  // initialize AT handling  _at = new GsmAt(*this);  init();}// MeTa::MeTa(Ref<GsmAt> at) throw(GsmException) ://   _at(at)// {//   init();// }void MeTa::setPIN(string pin) throw(GsmException){  _at->chat("+CPIN=\"" + pin + "\"");}string MeTa::getPINStatus() throw(GsmException){  Parser p(_at->chat("+CPIN?", "+CPIN:"));  return p.parseString();}void MeTa::setPhonebook(string phonebookName) throw(GsmException){  if (phonebookName != _lastPhonebookName)  {    _at->chat("+CPBS=\"" + phonebookName + "\"");    _lastPhonebookName = phonebookName;  }}string MeTa::setSMSStore(string smsStore, int storeTypes, bool needResultCode)  throw(GsmException){  if (_capabilities._cpmsParamCount == -1)  {    // count the number of parameters for the CPMS AT sequences    _capabilities._cpmsParamCount = 1;    Parser p(_at->chat("+CPMS=?", "+CPMS:"));    p.parseStringList();    while (p.parseComma(true))    {      ++_capabilities._cpmsParamCount;      p.parseStringList();    }  }  // optimatization: only set current SMS store if different from last call  // or the result code is needed  if (needResultCode || _lastSMSStoreName != smsStore)  {    _lastSMSStoreName = smsStore;    // build chat string    string chatString = "+CPMS=\"" + smsStore + "\"";    for (int i = 1; i < min(_capabilities._cpmsParamCount, storeTypes); ++i)      chatString += ",\"" + smsStore + "\"";    return _at->chat(chatString, "+CPMS:");  }  return "";}void MeTa::getSMSStore(string &readDeleteStore,                       string &writeSendStore,                       string &receiveStore) throw(GsmException){  Parser p(_at->chat("+CPMS?", "+CPMS:"));  writeSendStore = receiveStore = "";  readDeleteStore = p.parseString();  p.parseComma();  p.parseInt();  p.parseComma();  p.parseInt();  if (p.parseComma(true))  {    writeSendStore = p.parseString();    p.parseComma();    p.parseInt();    p.parseComma();    p.parseInt();    if (p.parseComma(true))    {      receiveStore = p.parseString();    }  }}void MeTa::waitEvent(GsmTime timeout) throw(GsmException){  if (_at->wait(timeout))    _at->chat();                // send AT, wait for OK, handle events}// aux function for MeTa::getMEInfo()static string stringVectorToString(const vector<string>& v,                                   char separator = '\n'){  if (v.empty())    return "";  // concatenate string in vector as rows  string result;  for (vector<string>::const_iterator i = v.begin();;)  {    string s = *i;    // remove leading and trailing "s    if (s.length() > 0 && s[0] == '"')      s.erase(s.begin());    if (s.length() > 0 && s[s.length() - 1] == '"')      s.erase(s.end() - 1);    result += s;    // don't add end line to last    if ( ++i == v.end() || !separator)      break;    result += separator;  }  return result;}MEInfo MeTa::getMEInfo() throw(GsmException){  MEInfo result;  // some TAs just return OK and no info line  // leave the info empty in this case  // some TAs return multirows with info like address, firmware version  result._manufacturer =    stringVectorToString(_at->chatv("+CGMI", "+CGMI:", false));  result._model = stringVectorToString(_at->chatv("+CGMM", "+CGMM:", false));  result._revision =    stringVectorToString(_at->chatv("+CGMR", "+CGMR:", false));  result._serialNumber =    stringVectorToString(_at->chatv("+CGSN", "+CGSN:", false),0);  return result;}vector<string> MeTa::getSupportedCharSets() throw(GsmException){  Parser p(_at->chat("+CSCS=?", "+CSCS:"));  // Some phones leave out the parentheses  return p.parseStringList(false, true);}    string MeTa::getCurrentCharSet() throw(GsmException){  if (_lastCharSet == "")  {    Parser p(_at->chat("+CSCS?", "+CSCS:"));    _lastCharSet = p.parseString();  }  return _lastCharSet;}void MeTa::setCharSet(string charSetName) throw(GsmException){  _at->chat("+CSCS=\"" + charSetName + "\"");  _lastCharSet = "";}string MeTa::getExtendedErrorReport() throw(GsmException){  return _at->chat("+CEER", "+CEER:");}void MeTa::dial(string number) throw(GsmException){  _at->chat("D" + number + ";");}void MeTa::answer() throw(GsmException){  _at->chat("A");}void MeTa::hangup() throw(GsmException){  _at->chat("H");}vector<OPInfo> MeTa::getAvailableOPInfo() throw(GsmException){  vector<OPInfo> result;  vector<string> responses = _at->chatv("+COPS=?", "+COPS:");  // special treatment for Falcom A2-1, answer looks like  //   responses.push_back("(1,29341),(3,29340)");  if (_capabilities._veryShortCOPSanswer)  {    if (responses.size() == 1)    {      Parser p(responses[0]);      while (p.parseChar('(', true))      {        OPInfo opi;        opi._status = (OPStatus)p.parseInt();        p.parseComma();        opi._numericName = p.parseInt();        p.parseChar(')');        p.parseComma(true);        result.push_back(opi);      }    }  }  else    // some formats I have encountered...    //responses.push_back("2,,,31017,,(0,1),(2)");    //responses.push_back("(3,\"UK CELLNET\",\"CLNET\",\"23410\"),"     //                    "(3,\"ONE2 ONE\",\"ONE2ONE\",\"23430\"),"    //                    "(3,\"ORANGE\",\"ORANGE\",\"23433\")");    //responses.push_back("(2,\"D1-TELEKOM\",,26201),"    //                    "(3,\"D2  PRIVAT\",,26202),,(0,1,3,4),(0,2)");    // some phones arbitrarily split the response into several lines    //responses.push_back("(1,\"AMENA\",,\"21403\"),"    //                    "(3,\"MOVISTAR\",,\"21407\"),");    //responses.push_back("(3,\"E VODAFONE\",,\"21401\"),,(0,1),(2)");    // GSM modems might return    // 1. quadruplets of info enclosed in brackets separated by comma    // 2. several lines of quadruplets of info enclosed in brackets    // 3. several lines of quadruplets without brackets and additional    //    info at EOL (e.g. Nokia 8290)    for (vector<string>::iterator i = responses.begin();         i != responses.end(); ++i)    {//       while (i->length() > 0 && ! isprint((*i)[i->length() - 1]))//         i->erase(i->length() - 1, 1);      bool expectClosingParenthesis = false;      Parser p(*i);      while (1)      {        OPInfo opi;        expectClosingParenthesis = p.parseChar('(', true);        int status = p.parseInt(true);        opi._status = (status == NOT_SET ? UnknownOPStatus : (OPStatus)status);        p.parseComma();        opi._longName = p.parseString(true);        p.parseComma();        opi._shortName = p.parseString(true);        p.parseComma();        try        {          opi._numericName = p.parseInt(true);        }        catch (GsmException &e)        {          if (e.getErrorClass() == ParserError)          {            // the Ericsson GM12 GSM modem returns the numeric ID as string            string s = p.parseString();            opi._numericName = checkNumber(s);          }          else            throw e;        }        if (expectClosingParenthesis) p.parseChar(')');        result.push_back(opi);        if (! p.parseComma(true)) break;        // two commas ",," mean the list is finished        if (p.getEol() == "" || p.parseComma(true)) break;      }      // without brackets, the ME/TA must use format 3.      if (! expectClosingParenthesis) break;    }  return result;}OPInfo MeTa::getCurrentOPInfo() throw(GsmException){  OPInfo result;  // 1. This exception thing is necessary because not all ME/TA combinations  // might support all the formats and then return "ERROR".  // 2. Additionally some modems return "ERROR" for all "COPS=3,n" command  // and report only one format with the "COPS?" command (e.g. Nokia 8290).  // get long format  try  {    try    {      _at->chat("+COPS=3,0");    }    catch (GsmException &e)    {      if (e.getErrorClass() != ChatError) throw;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -