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

Contents of /smsdaemon/ModemTransceiver.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 178 - (show annotations) (download)
Fri Dec 12 12:13:05 2008 UTC (15 years, 5 months ago) by torben
File size: 4825 byte(s)
Completed modemtransceivers multipart concatenate function

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

Properties

Name Value
svn:mergeinfo

  ViewVC Help
Powered by ViewVC 1.1.20