/[projects]/smsdaemon/ModemTransceiver.cpp
ViewVC logotype

Annotation of /smsdaemon/ModemTransceiver.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 144 - (hide annotations) (download)
Sun Dec 7 16:27:34 2008 UTC (15 years, 5 months ago) by torben
Original Path: smsdaemon/GsmModem.cpp
File size: 4989 byte(s)
Refactor IGsmModem, in order to ease adding another sms transceiver

1 torben 26 /* using http://sourceforge.net/projects/libserial/
2     */
3    
4     #include <iostream>
5     #include <string>
6     #include <stdexcept>
7    
8     #include <time.h>
9    
10    
11 torben 132 #include "serialport/SerialPort.h"
12 torben 26
13     #include "GsmModem.h"
14    
15     #include "util.h"
16     #include "common.h"
17    
18 torben 63 #include "SmsPdu.h"
19 torben 142 #include "SmsHelper.h"
20 torben 26
21     using namespace std;
22    
23    
24    
25     GsmModem::GsmModem(SerialPort& serialport)
26     : m_port(serialport)
27     {
28     }
29    
30    
31    
32     string GsmModem::GetResponse()
33     {
34    
35     SerialPort::DataBuffer buf;
36     m_port.Read(buf);
37    
38     buf.push_back(0);
39    
40     std::string str((char*) &buf[0]);
41    
42     return str;
43     }
44    
45 torben 34
46 torben 26 string GsmModem::Command(string command, string term)
47     {
48     time_t start,now;
49     start = time(0);
50 torben 57 _timeout = false;
51 torben 26
52 torben 34 if (term != "> ")
53     command.append("\r"); //Dont append CarriageReturn if sending SMS
54    
55 torben 26 m_port.Write(command);
56    
57 torben 34 Util::Sleep(1);
58 torben 26 string response = GetResponse();
59    
60     unsigned int tlen = term.length();
61     while ( 1 )
62     {
63     if (response.length() >= tlen)
64     {
65     if (response.substr(response.length()-tlen,tlen) == term)
66     break;
67     }
68    
69     response += GetResponse();
70 torben 34 Util::Sleep(1);
71 torben 26
72     now = time(0);
73     if ( (now-start) > 10 )
74     {
75     Common::instance()->logMessage( string("GsmModem::Command time out --") + command);
76 torben 72 Common::instance()->logMessage( string("Modem responded: ") + Util::str_trim(response) );
77 torben 57 _timeout = true;
78 torben 26 break;
79     }
80     }
81    
82     Util::Sleep(5);
83    
84    
85     return response;
86     }
87    
88     vector<SMS> GsmModem::ReadSms(bool readAll)
89     {
90 torben 63
91 torben 75 Command( "AT+CMGF=0" ); //Set SMS format to PDU
92 torben 63
93 torben 26 const string search = "+CMGL: ";
94     std::string cmd = "AT+CMGL";
95     if (readAll)
96 torben 75 cmd.append("=4");
97 torben 26
98     string result = Command(cmd);
99    
100     vector<SMS> retval;
101     if (result.find(search) == string::npos)
102     return retval;
103    
104     result = result.substr(2, result.length() - 8); //remove trailing "\r\nOK\r\n" and initial "\r\n"
105    
106    
107     while ( 1 )
108     {
109     unsigned int endpos = result.find(search,5);
110    
111    
112     string sms_entry = result.substr(0,endpos);
113 torben 142 retval.push_back( SmsHelper::FromPduString(sms_entry) );;
114 torben 26
115     if (endpos == string::npos)
116     break;
117    
118     result = result.substr(endpos, result.length() - endpos);
119     }
120    
121     return retval;
122     }
123    
124 torben 59
125     void GsmModem::SendSmsPdu(std::string pdu, int len) //pdu inclussive leading "00"
126     {
127     Common::instance()->logMessage( string("SMS pdu send") );
128    
129     Command("AT+CMGF=0");
130     Util::Sleep(2);
131    
132     string line1 = "AT+CMGS=";
133     line1.append( Util::str_formatint(len) );
134     line1.append("\r");
135    
136    
137     Command(line1,"> ");
138    
139     pdu.append("\032"); // \032 == Ctrl+Z
140     Command( pdu );
141     Util::Sleep( 50 );
142     Common::instance()->smsCounter.outgoing++;
143     }
144    
145 torben 63 void GsmModem::SendSms(string to, string message, bool allowMultipart)
146 torben 26 {
147     Common::instance()->logMessage( string("SMS send to ") + to);
148    
149 torben 63 if (to.at(0) == '+')
150     to.erase(0,0);
151 torben 26
152 torben 135 vector<PduInfo> pdu_vec = SmsPdu::CreateSmsPdu(to, Util::str_latin2gsm(message), allowMultipart);
153 torben 26
154 torben 63 for (unsigned i=0; i<pdu_vec.size(); ++i)
155     {
156     PduInfo& pdu = pdu_vec[i];
157 torben 26
158 torben 63 SendSmsPdu(pdu.pdu, pdu.len);
159 torben 50 }
160 torben 136 Common::instance()->logMessage( "All PDU's send");
161 torben 26
162     }
163    
164     void GsmModem::DeleteSms(std::string smsIndex)
165     {
166     string cmd = "AT+CMGD=";
167     cmd.append(smsIndex);
168     Command(cmd);
169     }
170    
171     int GsmModem::DeleteAllSms()
172     {
173     vector<SMS> sms = ReadSms(true);
174    
175     for (unsigned int i= 0; i<sms.size(); ++i)
176     {
177 torben 142 DeleteSms( sms[i].GetIndex() );
178 torben 26 }
179     return sms.size();
180     }
181    
182    
183    
184 torben 105 void GsmModem::WaitForSimcard()
185     {
186     int start = time(0);
187     string result;
188    
189    
190     while (result != "^SSIM READY")
191     {
192     result += GetResponse();
193     result = Util::str_trim(result);
194    
195     if ( (time(0) - start) > 10)
196     throw std::runtime_error("Sim card timed out:");
197     Util::Sleep(100);
198     }
199    
200     }
201    
202     void GsmModem::HandlePincode()
203     {
204     string result = Command("AT+CPIN?");
205     result = Util::str_trim(result);
206     result.erase(result.length() -2, 2); //remove trailing ok
207     result = Util::str_trim(result);
208     if (result != "+CPIN: READY")
209     {
210     if (result == "+CPIN: SIM PIN")
211     {
212     Command("AT^SSET=1");
213     result = Command("AT+CPIN=0067");
214     if ( result.substr(result.length()-4, 4) != "OK\r\n")
215     throw std::runtime_error(string("Illegal pincode: ") + result);
216    
217     WaitForSimcard();
218     }
219     else
220     {
221     throw std::runtime_error(string("AT+CPIN? returned unhandled code: ") + result);
222     }
223    
224     }
225     }
226    
227 torben 26 void GsmModem::Init()
228     {
229 torben 58 Command( "AT" );
230 torben 57 if (_timeout)
231     throw std::runtime_error("Modem did not respond!");
232    
233 torben 58 Command( "ATZ" ); //Reset any previous setup
234    
235 torben 33 Command( "AT\\Q3" ); //Hardware flow control
236 torben 26
237     Command( "ATE0" ); //Disable echo
238    
239     Command ("AT^SM20=0,0" ); //No SM20 compability
240    
241 torben 83 //Command("AT+CGATT=1"); //GPRS Attach
242    
243     //Command("AT+CGSMS=2"); //SMS over GPRS preferred
244    
245 torben 105 HandlePincode();
246 torben 26 }
247 torben 59
248    
249 torben 67
250    
251     void DebugGsmModem::SendSms(std::string to, std::string message, bool allowMultipart)
252     {
253     _to=to;
254     _message = message;
255     _multipart = allowMultipart;
256    
257     if (_print)
258     {
259     cout << "DebugGsmModem::SendSms --------------" << endl;
260     cout << "To: " << to << endl;;
261     cout << "Message: " << message << endl;
262     cout << "Multipart: " << allowMultipart << endl;
263    
264     }
265     }
266    
267 torben 144 std::vector<SMS> DebugGsmModem::ReadSms(bool readAll)
268     {
269     vector<SMS> result;
270     return result;
271     }

  ViewVC Help
Powered by ViewVC 1.1.20