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

📄 gsm_at.cc

📁 对各种手机进行编程的工具包源码gsmlib 1.9版本。
💻 CC
字号:
// *************************************************************************// * GSM TA/ME library// *// * File:    gsm_at.cc// *// * Purpose: Utility classes for AT command sequence handling// *// * Author:  Peter Hofmann (software@pxh.de)// *// * Created: 3.5.1999// *************************************************************************#ifdef HAVE_CONFIG_H#include <gsm_config.h>#endif#include <gsmlib/gsm_at.h>#include <gsmlib/gsm_nls.h>#include <gsmlib/gsm_util.h>#include <gsmlib/gsm_error.h>#include <gsmlib/gsm_event.h>#include <gsmlib/gsm_me_ta.h>#include <ctype.h>#include <strstream>using namespace std;using namespace gsmlib;// GsmAt membersbool GsmAt::matchResponse(string answer, string responseToMatch){  if (answer.substr(0, responseToMatch.length()) == responseToMatch)    return true;  else    // some TAs omit the ':' at the end of the response    if (_meTa.getCapabilities()._omitsColon &&        responseToMatch[responseToMatch.length() - 1] == ':' &&        answer.substr(0, responseToMatch.length() - 1) ==         responseToMatch.substr(0, responseToMatch.length() - 1))      return true;  return false;}string GsmAt::cutResponse(string answer, string responseToMatch){  if (answer.substr(0, responseToMatch.length()) == responseToMatch)    return normalize(answer.substr(responseToMatch.length(),                                   answer.length() -                                   responseToMatch.length()));  else    // some TAs omit the ':' at the end of the response    if (_meTa.getCapabilities()._omitsColon &&        responseToMatch[responseToMatch.length() - 1] == ':' &&        answer.substr(0, responseToMatch.length() - 1) ==         responseToMatch.substr(0, responseToMatch.length() - 1))      return normalize(answer.substr(responseToMatch.length() - 1,                                     answer.length() -                                     responseToMatch.length() + 1));  assert(0);  return "";}void GsmAt::throwCmeException(string s) throw(GsmException){  if (matchResponse(s, "ERROR"))    throw GsmException(_("unspecified ME/TA error"), ChatError);  bool meError = matchResponse(s, "+CME ERROR:");  if (meError)    s = cutResponse(s, "+CME ERROR:");  else    s = cutResponse(s, "+CMS ERROR:");  istrstream is(s.c_str());  int error;  is >> error;  throw GsmException(_("ME/TA error '") +                     (meError ? getMEErrorText(error) :                      getSMSErrorText(error)) +                     "' " +                     stringPrintf(_("(code %s)"), s.c_str()),                     ChatError, error);}GsmAt::GsmAt(MeTa &meTa) :  _meTa(meTa), _port(meTa.getPort()), _eventHandler(NULL){}string GsmAt::chat(string atCommand, string response,                   bool ignoreErrors, bool acceptEmptyResponse)  throw(GsmException){  string dummy;  return chat(atCommand, response, dummy, ignoreErrors, false,              acceptEmptyResponse);}string GsmAt::chat(string atCommand, string response, string &pdu,                   bool ignoreErrors, bool expectPdu,                   bool acceptEmptyResponse) throw(GsmException){  string s;  bool gotOk = false;           // special handling for empty SMS entries  // send AT command  putLine("AT" + atCommand);  // and gobble up CR/LF (and possibly echoed characters if echo can't be  // switched off)  do  {    s = normalize(getLine());  }  while (s.length() == 0 || s == "AT" + atCommand);  // handle errors  if (matchResponse(s, "+CME ERROR:") || matchResponse(s, "+CMS ERROR:"))    if (ignoreErrors)      return "";    else      throwCmeException(s);  if (matchResponse(s, "ERROR"))    if (ignoreErrors)      return "";    else      throw GsmException(_("ME/TA error '<unspecified>' (code not known)"),                          ChatError, -1);  // return if response is "OK" and caller says this is OK  if (acceptEmptyResponse && s == "OK")    return "";  // handle PDU if one is expected  if (expectPdu)  {    string ps;    do    {      ps = normalize(getLine());    }    while (ps.length() == 0 && ps != "OK");    if (ps == "OK")      gotOk = true;    else    {      pdu = ps;      // remove trailing zero added by some devices (e.g. Falcom A2-1)      if (pdu.length() > 0 && pdu[pdu.length() - 1] == 0)        pdu.erase(pdu.length() - 1);    }  }  // handle expected response  if (response.length() == 0)   // no response expected  {    if (s == "OK") return "";    // else fall through to error  }  else  {    string result;    // some TA/TEs don't prefix their response with the response string    // as proscribed by the standard: just handle either case    if (matchResponse(s, response))      result = cutResponse(s, response);    else      result = s;    if (gotOk)      return result;    else    {      // get the final "OK"      do      {        s = normalize(getLine());      }      while (s.length() == 0);      if (s == "OK") return result;      // else fall through to error    }  }  throw GsmException(    stringPrintf(_("unexpected response '%s' when sending 'AT%s'"),                 s.c_str(), atCommand.c_str()),    ChatError);}vector<string> GsmAt::chatv(string atCommand, string response,                            bool ignoreErrors) throw(GsmException){  string s;  vector<string> result;  // send AT command  putLine("AT" + atCommand);  // and gobble up CR/LF (and possibly echoed characters if echo can't be  // switched off)  do  {    s = normalize(getLine());  }  while (s.length() == 0 || s == "AT" + atCommand);  // handle errors  if (matchResponse(s, "+CME ERROR:") || matchResponse(s, "+CMS ERROR:"))    if (ignoreErrors)      return result;    else      throwCmeException(s);  if (matchResponse(s, "ERROR"))    if (ignoreErrors)      return result;    else      throw GsmException(_("ME/TA error '<unspecified>' (code not known)"),                          ChatError, -1);  // push all lines that are not empty  // cut response prefix if it is there  // stop when an OK line is read  while (1)  {    if (s == "OK")      return result;    // some TA/TEs don't prefix their response with the response string    // as proscribed by the standard: just handle either case    if (response.length() != 0 && matchResponse(s, response))      result.push_back(cutResponse(s, response));    else      result.push_back(s);    // get next line    do    {      s = normalize(getLine());    }    while (s.length() == 0);    reportProgress();  }  // never reached  assert(0);  return result;}string GsmAt::normalize(string s){  size_t start = 0, end = s.length();  bool changed = true;  while (start < end && changed)  {    changed = false;    if (isspace(s[start]))    {      ++start;      changed = true;    }    else      if (isspace(s[end - 1]))      {        --end;        changed = true;      }  }  return s.substr(start, end - start);}string GsmAt::sendPdu(string atCommand, string response, string pdu,                      bool acceptEmptyResponse) throw(GsmException){  string s;  bool errorCondition = false;  bool retry = false;  int c;  do  {    putLine("AT" + atCommand);    // read first of two bytes "> "    c = readByte();        // there have been reports that some phones give spurious CRs    if (c == CR)      c = readByte();    if (c == '+' || c == 'E')   // error or unsolicited result code    {      _port->putBack(c);      s = normalize(getLine());      errorCondition = (s != "");            retry = ! errorCondition;      // The following code is for the unlikely case that the TA wants      // to resume PDU sending after an unsolicited result code.      // For the time being I have decided that it is better to retry      // in this case.//       if (! errorCondition)//       {//         // readByte() times out after TIMEOUT_SECS (gsm_port.h) seconds //         try//         {//           c = readByte();//           retry = c != '>';     // TA still expects PDU if c == '>'//           if (retry)//              _port->putBack(c);//         }//         catch (GsmException &e)//         {//           retry = true;         // TA does not expect PDU anymore, retry//         }//       }    }  }  while (retry);  if (! errorCondition)  {        if (c != '>' || readByte() != ' ')      throw GsmException(_("unexpected character in PDU handshake"),                         ChatError);        putLine(pdu + "\032", false); // write pdu followed by CTRL-Z    do    {      s = normalize(getLine());    }    while (s.length() == 0 || s == pdu);  }  // handle errors  if (matchResponse(s, "+CME ERROR:") || matchResponse(s, "+CMS ERROR:"))    throwCmeException(s);  if (matchResponse(s, "ERROR"))    throw GsmException(_("ME/TA error '<unspecified>' (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))  {    string result = cutResponse(s, response);    // get the final "OK"    do    {      s = normalize(getLine());    }    while (s.length() == 0);    if (s == "OK") return result;    // else fall through to error  }  throw GsmException(    stringPrintf(_("unexpected response '%s' when sending 'AT%s'"),                 s.c_str(), atCommand.c_str()),    ChatError);}string GsmAt::getLine() throw(GsmException){  if (_eventHandler == (GsmEvent*)NULL)    return _port->getLine();  else  {    bool eventOccurred;    string result;    do    {      eventOccurred = false;      result = _port->getLine();      string s = normalize(result);      if (matchResponse(s, "+CMT:") ||          matchResponse(s, "+CBM:") ||          matchResponse(s, "+CDS:") ||          matchResponse(s, "+CMTI:") ||          matchResponse(s, "+CBMI:") ||          matchResponse(s, "+CDSI:") ||          matchResponse(s, "RING") ||          // hack: the +CLIP? sequence returns +CLIP: n,m          // which is NOT an unsolicited result code          (matchResponse(s, "+CLIP:") && s.length() > 10))      {        _eventHandler->dispatch(s, *this);        eventOccurred = true;      }    }    while (eventOccurred);    return result;  }}void GsmAt::putLine(string line,                    bool carriageReturn) throw(GsmException){  _port->putLine(line, carriageReturn);  // remove empty echo line  if (carriageReturn)    getLine();}bool GsmAt::wait(GsmTime timeout) throw(GsmException){  return _port->wait(timeout);}int GsmAt::readByte() throw(GsmException){  return _port->readByte();}GsmEvent *GsmAt::setEventHandler(GsmEvent *newHandler){  GsmEvent *result = _eventHandler;  _eventHandler = newHandler;  return result;}

⌨️ 快捷键说明

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