1 //
2 // Copyright (C) 2020 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #include <android-base/logging.h>
17 #include <gtest/gtest.h>
18 #include <stdlib.h>
19 
20 #include <filesystem>
21 #include <fstream>
22 
23 #include "common/libs/fs/shared_select.h"
24 #include "common/libs/utils/files.h"
25 #include "host/commands/assemble_cvd/flags_defaults.h"
26 #include "host/commands/modem_simulator/channel_monitor.h"
27 #include "host/commands/modem_simulator/device_config.h"
28 #include "host/commands/modem_simulator/modem_simulator.h"
29 #include "host/libs/config/cuttlefish_config.h"
30 namespace fs = std::filesystem;
31 
32 static const char *myiccfile =
33 #include "iccfile.txt"
34     ;
35 
36 static const std::string tmp_test_dir = std::string(fs::temp_directory_path()) +
37                                         std::string("/cuttlefish_modem_test");
38 using namespace cuttlefish;
39 
40 class ModemServiceTest : public ::testing::Test {
41  protected:
SetUpTestSuite()42   static void SetUpTestSuite() {
43     {
44       cuttlefish::CuttlefishConfig tmp_config_obj;
45       std::string config_file = tmp_test_dir + "/.cuttlefish_config.json";
46       tmp_config_obj.set_root_dir(tmp_test_dir + "/cuttlefish");
47       std::vector<int> instance_nums;
48       for (int i = 0; i < 1; i++) {
49         instance_nums.push_back(cuttlefish::GetInstance() + i);
50       }
51       for (const auto &num : instance_nums) {
52         auto instance = tmp_config_obj.ForInstance(num);  // Trigger creation in map
53         instance.set_ril_dns(CF_DEFAULTS_RIL_DNS);
54       }
55 
56       for (auto instance : tmp_config_obj.Instances()) {
57         fs::create_directories(instance.instance_dir());
58         if (!tmp_config_obj.SaveToFile(
59                 instance.PerInstancePath("cuttlefish_config.json"))) {
60           LOG(ERROR) << "Unable to save copy config object";
61           return;
62         }
63         std::string icfilename =
64             instance.PerInstancePath("/iccprofile_for_sim0.xml");
65         std::ofstream offile = modem::DeviceConfig::open_ofstream_crossplat(icfilename.c_str(), std::ofstream::out);
66         offile << std::string(myiccfile);
67         offile.close();
68         fs::copy_file(instance.PerInstancePath("/cuttlefish_config.json"),
69                       config_file, fs::copy_options::overwrite_existing);
70       }
71 
72       ::setenv("CUTTLEFISH_CONFIG_FILE", config_file.c_str(), 1);
73     }
74     cuttlefish::SharedFD ril_shared_fd, modem_shared_fd;
75     if (!SharedFD::SocketPair(AF_LOCAL, SOCK_STREAM, 0, &ril_shared_fd,
76                               &modem_shared_fd)) {
77       LOG(ERROR) << "Unable to create client socket pair: " << strerror(errno);
78     }
79     ASSERT_TRUE(ril_shared_fd->IsOpen());
80     ASSERT_TRUE(modem_shared_fd->IsOpen());
81 
82     NvramConfig::InitNvramConfigService(1, 1);
83 
84     ril_side_ = new Client(ril_shared_fd);
85     modem_side_ = new Client(modem_shared_fd);
86     modem_simulator_ = new ModemSimulator(0);
87 
88     cuttlefish::SharedFD server;
89     auto channel_monitor =
90         std::make_unique<ChannelMonitor>(*modem_simulator_, server);
91     modem_simulator_->Initialize(std::move(channel_monitor));
92   }
93 
TearDownTestSuite()94   static void TearDownTestSuite() {
95     delete ril_side_;
96     delete modem_side_;
97     delete modem_simulator_;
98     fs::remove_all(tmp_test_dir);
99   };
100 
SendCommand(std::string command,std::string prefix="")101   void SendCommand(std::string command, std::string prefix = "") {
102     command_prefix_ = prefix;
103     modem_simulator_->DispatchCommand(*modem_side_, command);
104   }
105 
ReadCommandResponse(std::vector<std::string> & response)106   void ReadCommandResponse(std::vector<std::string>& response) {
107     do {
108       std::vector<char> buffer(4096);  // kMaxCommandLength
109       auto bytes_read =
110           ril_side_->client_read_fd_->Read(buffer.data(), buffer.size());
111       if (bytes_read <= 0) {
112         // Close here to ensure the other side gets reset if it's still
113         // connected
114         ril_side_->client_read_fd_->Close();
115         ril_side_->client_write_fd_->Close();
116         LOG(WARNING) << "Detected close from the other side";
117         break;
118       }
119 
120       std::string& incomplete_command = ril_side_->incomplete_command;
121 
122       // Add the incomplete command from the last read
123       auto commands = std::string{incomplete_command.data()};
124       commands.append(buffer.data());
125 
126       incomplete_command.clear();
127       incomplete_command.resize(0);
128 
129       // replacing '\n' with '\r'
130       commands = android::base::StringReplace(commands, "\n", "\r", true);
131 
132       // split into commands and dispatch
133       size_t pos = 0, r_pos = 0;  // '\r' or '\n'
134       while (r_pos != std::string::npos) {
135         r_pos = commands.find('\r', pos);
136         if (r_pos != std::string::npos) {
137           auto command = commands.substr(pos, r_pos - pos);
138           if (command.size() > 0) {  // "\r\r" ?
139             LOG(DEBUG) << "AT< " << command;
140             if (IsFinalResponseSuccess(command) || IsFinalResponseError(command)) {
141               response.push_back(command);
142               return;
143             } else if (IsIntermediateResponse(command)) {
144               response.push_back(command);
145             } else {
146               ; // Ignore unsolicited command
147             }
148           }
149           pos = r_pos + 1;  // skip '\r'
150         } else if (pos < commands.length()) {  // incomplete command
151           incomplete_command = commands.substr(pos);
152           LOG(VERBOSE) << "incomplete command: " << incomplete_command;
153         }
154       }
155     } while (true);
156 
157     // read response
158   }
159 
IsFinalResponseSuccess(std::string response)160   inline bool IsFinalResponseSuccess(std::string response) {
161     auto iter = kFinalResponseSuccess.begin();
162     for (; iter != kFinalResponseSuccess.end(); ++iter) {
163       if (*iter == response) {
164         return true;
165       }
166     }
167 
168     return false;
169   }
170 
IsFinalResponseError(std::string response)171   inline bool IsFinalResponseError(std::string response) {
172     auto iter = kFinalResponseError.begin();
173     for (; iter != kFinalResponseError.end(); ++iter) {
174       if (response.compare(0, iter->size(), *iter) == 0) {
175         return true;
176       }
177     }
178 
179     return false;
180   }
181 
IsIntermediateResponse(std::string response)182   inline bool IsIntermediateResponse(std::string response) {
183     if (response.compare(0, command_prefix_.size(), command_prefix_) == 0) {
184       return true;
185     }
186 
187     return false;
188   }
189 
openLogicalChannel(std::string & name)190   int openLogicalChannel(std::string& name) {
191     // Create and send command
192     std::string command = "AT+CCHO=";
193     command.append(name);
194     std::vector<std::string> response;
195     SendCommand(command);
196     ReadCommandResponse(response);
197     int channel = std::stoi(response[0]);
198     return channel;
199   }
200 
closeLogicalChannel(int channel)201   bool closeLogicalChannel(int channel) {
202     std::string command = "AT+CCHC=";
203     command += std::to_string(channel);
204     std::vector<std::string> response;
205     SendCommand(command);
206     ReadCommandResponse(response);
207     std::string expect = "+CCHC";
208     return (response[0].compare(0, expect.size(), expect) == 0);
209   }
210 
211   const std::vector<std::string> kFinalResponseSuccess = {"OK", "CONNECT", "> "};
212   const std::vector<std::string> kFinalResponseError = {
213       "ERROR",
214       "+CMS ERROR:",
215       "+CME ERROR:",
216       "NO CARRIER", /* sometimes! */
217       "NO ANSWER",
218       "NO DIALTONE",
219   };
220 
221   static Client* ril_side_;
222   static Client* modem_side_;
223   static ModemSimulator* modem_simulator_;
224 
225   // For distinguishing the response from command response or unsolicited command
226   std::string command_prefix_;
227 };
228 
229 ModemSimulator* ModemServiceTest::modem_simulator_ = nullptr;
230 Client* ModemServiceTest::ril_side_ = nullptr;
231 Client* ModemServiceTest::modem_side_ = nullptr;
232 
233 /* Sim Service Test */
TEST_F(ModemServiceTest,GetIccCardStatus)234 TEST_F(ModemServiceTest, GetIccCardStatus) {
235   const char *expects[]  = {"+CPIN: READY",
236                             "OK"};
237 
238   std::string command = "AT+CPIN?";
239   std::vector<std::string> response;
240   SendCommand(command, "+CPIN:");
241   ReadCommandResponse(response);
242   ASSERT_EQ(response.size(), 2);
243   ASSERT_STREQ(response[0].c_str(), expects[0]);
244   ASSERT_STREQ(response[1].c_str(), expects[1]);
245 }
246 
TEST_F(ModemServiceTest,ChangeOrEnterPIN)247 TEST_F(ModemServiceTest, ChangeOrEnterPIN) {
248   std::vector<std::string> commands = {"AT+CPIN=1234,0000",
249                                        "AT+CPIN=1111,2222",};
250   std::vector<std::string> expects  = {"OK",
251                                        "+CME ERROR: 16",};
252   std::vector<std::string> response;
253   auto expects_iter = expects.begin();
254   for (auto iter = commands.begin(); iter != commands.end(); ++iter, ++expects_iter) {
255     SendCommand(*iter);
256     ReadCommandResponse(response);
257     ASSERT_STREQ(response[0].c_str(), (*expects_iter).c_str());
258     response.clear();
259   }
260 }
261 
TEST_F(ModemServiceTest,SIM_IO)262 TEST_F(ModemServiceTest, SIM_IO) {
263   std::vector<std::string> commands = {"AT+CRSM=192,12258,0,0,15",
264                                        "AT+CRSM=192,28436,0,0,15",
265                                        "AT+CRSM=220,28618,1,4,5,0000000000"};
266   std::vector<std::string> expects  = {"+CRSM: 144,0,62178202412183022FE28A01058B032F06038002000A880110",
267                                        "+CRSM: 106,130",
268                                        "+CRSM: 144,0"};
269 
270   std::vector<std::string> response;
271   auto expects_iter = expects.begin();
272   for (auto iter = commands.begin(); iter != commands.end(); ++iter, ++expects_iter) {
273     SendCommand(*iter);
274     ReadCommandResponse(response);
275     ASSERT_EQ(response.size(), 2);
276     ASSERT_STREQ(response[0].c_str(), (*expects_iter).c_str());
277     response.clear();
278   }
279 }
280 
TEST_F(ModemServiceTest,GetIMSI)281 TEST_F(ModemServiceTest, GetIMSI) {
282   std::string command = "AT+CIMI";
283   std::vector<std::string> response;
284   SendCommand(command);
285   ReadCommandResponse(response);
286   ASSERT_EQ(response.size(), 2);
287   const char *expect = "460110031689666";
288   ASSERT_STREQ(response[0].c_str(),expect);
289 }
290 
TEST_F(ModemServiceTest,GetIccId)291 TEST_F(ModemServiceTest, GetIccId) {
292   std::string command = "AT+CICCID";
293   std::vector<std::string> response;
294   SendCommand(command);
295   ReadCommandResponse(response);
296   ASSERT_EQ(response.size(), 2);
297   const char *expect = "89860318640220133897";
298   ASSERT_STREQ(response[0].c_str(),expect);
299 }
300 
TEST_F(ModemServiceTest,FacilityLock)301 TEST_F(ModemServiceTest, FacilityLock) {
302   std::vector<std::string> commands =
303         { "AT+CLCK=\"FD\",2,"",7",
304           "AT+CLCK=\"SC\",2,"",7",
305           "AT+CLCK=\"SC\",1,\"1234\",7",
306           "AT+CLCK=\"SC\",1,\"023000\",7"
307   };
308   std::vector<std::string> expects =
309         { "+CLCK: 0",
310           "+CLCK: 0",
311           "+CME ERROR: 16",
312           "+CME ERROR: 16"
313   };
314   std::vector<std::string> response;
315   auto expects_iter = expects.begin();
316   for (auto iter = commands.begin(); iter != commands.end(); ++iter, ++expects_iter) {
317     SendCommand(*iter);
318     ReadCommandResponse(response);
319     ASSERT_STREQ(response[0].c_str(), (*expects_iter).c_str());
320     response.clear();
321   }
322 }
323 
TEST_F(ModemServiceTest,OpenLogicalChannel)324 TEST_F(ModemServiceTest, OpenLogicalChannel) {
325   std::string command= "A000000063504B43532D3135";
326   int firstChannel = openLogicalChannel(command);
327   ASSERT_EQ(firstChannel, 1);
328 
329   command= "A000000063504B43532D3135";
330   int secondChannel = openLogicalChannel(command);
331   ASSERT_GE(secondChannel, 1);
332 
333   closeLogicalChannel(firstChannel);
334   closeLogicalChannel(secondChannel);
335 }
336 
TEST_F(ModemServiceTest,CloseLogicalChannel)337 TEST_F(ModemServiceTest, CloseLogicalChannel) {
338   std::string command= "A000000063504B43532D3135";
339   int channel = openLogicalChannel(command);
340   ASSERT_EQ(channel, 1);
341 
342   ASSERT_FALSE(closeLogicalChannel(channel + 3));
343   ASSERT_TRUE(closeLogicalChannel(channel));
344 }
345 
TEST_F(ModemServiceTest,TransmitLogicalChannel)346 TEST_F(ModemServiceTest, TransmitLogicalChannel) {
347   std::string command= "A000000063504B43532D3135";
348   int channel = openLogicalChannel(command);
349   ASSERT_EQ(channel, 1);
350   command = "AT+CGLA=";
351   command += channel;
352   command += ",10,80caff4000";
353   std::vector<std::string> response;
354   SendCommand(command);
355   ReadCommandResponse(response);
356   const char *expect = "+CME ERROR: 21";
357   ASSERT_STREQ(response[0].c_str(),expect);
358   ASSERT_TRUE(closeLogicalChannel(channel));
359 }
360 
361 /* Network Service Test */
TEST_F(ModemServiceTest,testRadioPowerReq)362 TEST_F(ModemServiceTest, testRadioPowerReq) {
363   std::string command = "AT+CFUN?";
364   std::vector<std::string> response;
365   SendCommand(command, "+CFUN:");
366   ReadCommandResponse(response);
367   ASSERT_EQ(response.size(), 2);
368   ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
369 }
370 
TEST_F(ModemServiceTest,testSetRadioPower)371 TEST_F(ModemServiceTest, testSetRadioPower) {
372   std::string command = "AT+CFUN=1";
373   std::vector<std::string> response;
374   SendCommand(command);
375   ReadCommandResponse(response);
376   ASSERT_EQ(response.size(), 1);
377   ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
378 }
379 
TEST_F(ModemServiceTest,testSignalStrength)380 TEST_F(ModemServiceTest, testSignalStrength) {
381   std::string command = "AT+CSQ";
382   std::vector<std::string> response;
383   SendCommand(command, "+CSQ:");
384   ReadCommandResponse(response);
385   ASSERT_EQ(response.size(), 2);
386   ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
387 }
388 
TEST_F(ModemServiceTest,testQueryNetworkSelectionMode)389 TEST_F(ModemServiceTest, testQueryNetworkSelectionMode) {
390   std::string command = "AT+COPS?";
391   std::vector<std::string> response;
392   SendCommand(command, "+COPS:");
393   ReadCommandResponse(response);
394   ASSERT_EQ(response.size(), 2);
395   ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
396 }
397 
TEST_F(ModemServiceTest,testRequestOperator)398 TEST_F(ModemServiceTest, testRequestOperator) {
399   std::string command = "AT+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?";
400   std::vector<std::string> response;
401   SendCommand(command, "+COPS:");
402   ReadCommandResponse(response);
403   ASSERT_EQ(response.size(), 4);
404 }
405 
TEST_F(ModemServiceTest,testVoiceNetworkRegistration)406 TEST_F(ModemServiceTest, testVoiceNetworkRegistration) {
407   std::string command = "AT+CREG?";
408   std::vector<std::string> response;
409   SendCommand(command, "+CREG:");
410   ReadCommandResponse(response);
411   ASSERT_EQ(response.size(), 2);
412   ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
413 }
414 
TEST_F(ModemServiceTest,testDataNetworkRegistration)415 TEST_F(ModemServiceTest, testDataNetworkRegistration) {
416   std::string command = "AT+CGREG?";
417   std::vector<std::string> response;
418   SendCommand(command, "+CGREG:");
419   ReadCommandResponse(response);
420   ASSERT_EQ(response.size(), 2);
421   ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
422 }
423 
TEST_F(ModemServiceTest,testDataNetworkRegistrationWithLte2)424 TEST_F(ModemServiceTest, testDataNetworkRegistrationWithLte2) {
425   std::string command = "AT+CEREG?";
426   std::vector<std::string> response;
427   SendCommand(command, "+CEREG:");
428   ReadCommandResponse(response);
429   ASSERT_EQ(response.size(), 2);
430   ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
431 }
432 
TEST_F(ModemServiceTest,testGetPreferredNetworkType)433 TEST_F(ModemServiceTest, testGetPreferredNetworkType) {
434   std::string command = "AT+CTEC?";
435   std::vector<std::string> response;
436   SendCommand(command, "+CTEC:");
437   ReadCommandResponse(response);
438   ASSERT_EQ(response.size(), 2);
439   ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
440 }
441 
TEST_F(ModemServiceTest,testQuerySupportedTechs)442 TEST_F(ModemServiceTest, testQuerySupportedTechs) {
443   std::string command = "AT+CTEC=?";
444   std::vector<std::string> response;
445   SendCommand(command, "+CTEC:");
446   ReadCommandResponse(response);
447   ASSERT_EQ(response.size(), 2);
448   ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
449 }
450 
TEST_F(ModemServiceTest,testSetPreferredNetworkType)451 TEST_F(ModemServiceTest, testSetPreferredNetworkType) {
452   std::string command = "AT+CTEC=1,\"201\"";
453   std::vector<std::string> response;
454   SendCommand(command, "+CTEC:");
455   ReadCommandResponse(response);
456   ASSERT_EQ(response.size(), 2);
457   ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
458 }
459 
460 /* Call Service Test */
TEST_F(ModemServiceTest,testCurrentCalls)461 TEST_F(ModemServiceTest, testCurrentCalls) {
462   std::string command = "AT+CLCC";
463   std::vector<std::string> response;
464   SendCommand(command, "+CLCC:");
465   ReadCommandResponse(response);
466   ASSERT_EQ(response.size(), 1);
467 }
468 
TEST_F(ModemServiceTest,testHangup)469 TEST_F(ModemServiceTest, testHangup) {
470   for (int i = 0; i < 5; i ++) {
471     std::stringstream ss;
472     ss.clear();
473     ss << "AT+CHLD=" << i;
474     SendCommand(ss.str());
475   }
476   std::vector<std::string> response;
477   ReadCommandResponse(response);
478   ASSERT_EQ(response.size(), 1);
479   ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
480 }
481 
TEST_F(ModemServiceTest,testMute)482 TEST_F(ModemServiceTest, testMute) {
483   std::string command = "AT+CMUT=1";
484   std::vector<std::string> response;
485   SendCommand(command);
486   ReadCommandResponse(response);
487   ASSERT_EQ(response.size(), 1);
488   ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
489 }
490 
TEST_F(ModemServiceTest,testSendDtmf)491 TEST_F(ModemServiceTest, testSendDtmf) {
492   std::string command = "AT+VTS=1";
493   std::vector<std::string> response;
494   SendCommand(command);
495   ReadCommandResponse(response);
496   ASSERT_EQ(response.size(), 1);
497   ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
498 }
499 
TEST_F(ModemServiceTest,testExitEmergencyMode)500 TEST_F(ModemServiceTest, testExitEmergencyMode) {
501   std::string command = "AT+WSOS=0";
502   std::vector<std::string> response;
503   SendCommand(command);
504   ReadCommandResponse(response);
505   ASSERT_EQ(response.size(), 1);
506   ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
507 }
508 
509 /* Data Service Test */
TEST_F(ModemServiceTest,SetPDPContext)510 TEST_F(ModemServiceTest, SetPDPContext) {
511   std::string command = "AT+CGDCONT=1,\"IPV4V6\",\"ctlte\",,0,0";
512   std::vector<std::string> response;
513   SendCommand(command);
514   ReadCommandResponse(response);
515   ASSERT_EQ(response.size(), 1);
516   ASSERT_STREQ(response.at(0).c_str(), kFinalResponseSuccess[0].c_str());
517 }
518 
TEST_F(ModemServiceTest,QueryPDPContextList)519 TEST_F(ModemServiceTest, QueryPDPContextList) {
520   for (int i = 1; i < 5; i ++) {
521     std::stringstream ss;
522     ss.clear();
523     ss << "AT+CGDCONT=" << i << ",\"IPV4V6\",\"ctlte\",,0,0";
524     SendCommand(ss.str());
525   }
526   std::string command = "AT+CGDCONT?";
527   std::vector<std::string> response;
528   SendCommand(command, "+CGDCONT:");
529   ReadCommandResponse(response);
530   const char *result = response[response.size() - 1].c_str();
531   ASSERT_EQ(response.size(), 1);
532   ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
533 }
534 
TEST_F(ModemServiceTest,ActivateDataCall)535 TEST_F(ModemServiceTest, ActivateDataCall) {
536   std::string command = "AT+CGACT= 1,0";
537   std::vector<std::string> response;
538   SendCommand(command);
539   ReadCommandResponse(response);
540   const char *result = response[0].c_str();
541   ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
542 }
543 
TEST_F(ModemServiceTest,QueryDataCallList)544 TEST_F(ModemServiceTest, QueryDataCallList) {
545   std::string command = "AT+CGACT?";
546   std::vector<std::string> response;
547   SendCommand(command, "+CGACT:");
548   ReadCommandResponse(response);
549   const char *result = response[response.size() - 1].c_str();
550   ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
551 }
552 
TEST_F(ModemServiceTest,ReadDynamicParamTrue)553 TEST_F(ModemServiceTest, ReadDynamicParamTrue) {
554   std::string command = "AT+CGCONTRDP=1";
555   std::vector<std::string> response;
556   SendCommand(command);
557   ReadCommandResponse(response);
558   const char *result = response[response.size() - 1].c_str();
559   ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
560 }
561 
TEST_F(ModemServiceTest,ReadDynamicParamFalse)562 TEST_F(ModemServiceTest, ReadDynamicParamFalse) {
563   std::string command = "AT+CGCONTRDP=10";
564   std::vector<std::string> response;
565   SendCommand(command);
566   ReadCommandResponse(response);
567   const char *result = response[response.size() - 1].c_str();
568   const char *expect = "+CME ERROR: 21";
569   ASSERT_STREQ(result, expect);
570 }
571 
TEST_F(ModemServiceTest,EnterDataState)572 TEST_F(ModemServiceTest, EnterDataState) {
573   std::string command = "AT+CGDATA=1,1";
574   std::vector<std::string> response;
575   SendCommand(command);
576   ReadCommandResponse(response);
577   const char *result = response[response.size() - 1].c_str();
578   ASSERT_STREQ(result, kFinalResponseSuccess[1].c_str());
579 }
580 
581 /* SMS Service Test */
TEST_F(ModemServiceTest,SendSMS)582 TEST_F(ModemServiceTest, SendSMS) {
583   std::string command = "AT+CMGS=35";
584   std::vector<std::string> response;
585   SendCommand(command);
586   ReadCommandResponse(response);
587   const char *result = response[response.size() - 1].c_str();
588   const char *expect = "> ";
589   ASSERT_STREQ(result, expect);
590   command = "0001000D91688118109844F0000017AFD7903AB55A9BBA69D639D4ADCBF99E3DCCAE9701^Z";
591   //command += '\032';
592   SendCommand(command);
593   ReadCommandResponse(response);
594   // TODO (bohu) for some reason the following asserts fail, fix them
595   // ASSERT_EQ(response.size(), 3);
596   // ASSERT_STREQ(response[response.size() - 1].c_str(),
597   // kFinalResponseSuccess[0].c_str());
598 }
599 
TEST_F(ModemServiceTest,WriteSMSToSim)600 TEST_F(ModemServiceTest, WriteSMSToSim) {
601   std::string command = "AT+CMGW=24,3";
602   std::vector<std::string> response;
603   SendCommand(command);
604   ReadCommandResponse(response);
605   const char *result = response[response.size() - 1].c_str();
606   const char *expect = "> ";
607   ASSERT_STREQ(result, expect);
608   command = "00240B815123106351F100000240516054410005C8329BFD06^Z";
609   SendCommand(command);
610   ReadCommandResponse(response);
611   ASSERT_EQ(response.size(), 3);
612   ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
613 }
614 
TEST_F(ModemServiceTest,SMSAcknowledge)615 TEST_F(ModemServiceTest, SMSAcknowledge) {
616   std::string command = "AT+CNMA=1";
617   std::vector<std::string> response;
618   SendCommand(command);
619   ReadCommandResponse(response);
620   const char *result = response[response.size() - 1].c_str();
621   ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
622 }
623 
TEST_F(ModemServiceTest,DeleteSmsOnSimTure)624 TEST_F(ModemServiceTest, DeleteSmsOnSimTure) {
625   std::string command = "AT+CMGD=1";
626   std::vector<std::string> response;
627   SendCommand(command);
628   ReadCommandResponse(response);
629   const char *result = response[0].c_str();
630   ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
631 }
632 
TEST_F(ModemServiceTest,DeleteSmsOnSimFalse)633 TEST_F(ModemServiceTest, DeleteSmsOnSimFalse) {
634   std::string command = "AT+CMGD=1";
635   std::vector<std::string> response;
636   SendCommand(command);
637   ReadCommandResponse(response);
638   const char *result = response[0].c_str();
639   const char *expect = "+CME ERROR: 21";
640   ASSERT_STREQ(result, expect);
641 }
642 
TEST_F(ModemServiceTest,SetBroadcastConfig)643 TEST_F(ModemServiceTest, SetBroadcastConfig) {
644   std::string command = "AT+CSCB=0,\"4356\",\"0-255\"";
645   std::vector<std::string> response;
646   SendCommand(command);
647   ReadCommandResponse(response);
648   const char *result = response[0].c_str();
649   ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
650 }
651 
TEST_F(ModemServiceTest,GetBroadcastConfig)652 TEST_F(ModemServiceTest, GetBroadcastConfig) {
653   std::string command = "AT+CSCB?";
654   std::vector<std::string> response;
655   SendCommand(command);
656   ReadCommandResponse(response);
657   ASSERT_EQ(response.size(), 2);
658   const char *result = response[response.size() - 1].c_str();
659   ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
660 }
661 
TEST_F(ModemServiceTest,SetSmscAddress)662 TEST_F(ModemServiceTest, SetSmscAddress) {
663   std::string command = "AT+CSCA=\"91688115667566F4\",16";
664   std::vector<std::string> response;
665   SendCommand(command);
666   ReadCommandResponse(response);
667   ASSERT_EQ(response.size(), 1);
668   const char *result = response[response.size() - 1].c_str();
669   ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
670 }
671 
TEST_F(ModemServiceTest,GetSmscAddress)672 TEST_F(ModemServiceTest, GetSmscAddress) {
673   std::string command = "AT+CSCA?";
674   std::vector<std::string> response;
675   SendCommand(command);
676   ReadCommandResponse(response);
677   ASSERT_EQ(response.size(), 2);
678   const char *result = response[response.size() - 1].c_str();
679   ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
680 }
681 
682 /* SUP Service Test */
TEST_F(ModemServiceTest,testUSSD)683 TEST_F(ModemServiceTest, testUSSD) {
684   std::string command = "AT+CUSD=1";
685   std::vector<std::string> response;
686   SendCommand(command);
687   ReadCommandResponse(response);
688   ASSERT_EQ(response.size(), 1);
689   ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
690 }
691 
TEST_F(ModemServiceTest,testCLIR)692 TEST_F(ModemServiceTest, testCLIR) {
693   std::string command = "AT+CLIR=2";
694   std::vector<std::string> response;
695   SendCommand(command);
696   ReadCommandResponse(response);
697   ASSERT_EQ(response.size(), 1);
698   ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
699 }
700 
TEST_F(ModemServiceTest,testQueryCLIR)701 TEST_F(ModemServiceTest, testQueryCLIR) {
702   std::string command = "AT+CLIR?";
703   std::vector<std::string> response;
704   SendCommand(command, "+CLIR:");
705   ReadCommandResponse(response);
706   ASSERT_EQ(response.size(), 2);
707 }
708 
TEST_F(ModemServiceTest,testCallWaiting)709 TEST_F(ModemServiceTest, testCallWaiting) {
710   std::string command = "AT+CCWA";
711   std::vector<std::string> response;
712   SendCommand(command, "+CCWA:");
713   ReadCommandResponse(response);
714   ASSERT_EQ(response.size(), 1);
715   ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
716 }
717 
TEST_F(ModemServiceTest,testCLIP)718 TEST_F(ModemServiceTest, testCLIP) {
719   std::string command = "AT+CLIP?";
720   std::vector<std::string> response;
721   SendCommand(command, "+CLIP:");
722   ReadCommandResponse(response);
723   ASSERT_EQ(response.size(), 2);
724 }
725 
TEST_F(ModemServiceTest,testCallForward)726 TEST_F(ModemServiceTest, testCallForward) {
727   std::string command = "AT+CCFCU=1,1,2,145,\"10086\"";
728   std::vector<std::string> response;
729   SendCommand(command, "+CCFCU:");
730   ReadCommandResponse(response);
731   ASSERT_EQ(response.size(), 1);
732 }
733 
734 /* STK Service Test */
TEST_F(ModemServiceTest,ReportStkServiceIsRunning)735 TEST_F(ModemServiceTest, ReportStkServiceIsRunning) {
736   std::string command = "AT+CUSATD?";
737   std::vector<std::string> response;
738   SendCommand(command);
739   ReadCommandResponse(response);
740   ASSERT_EQ(response.size(), 2);
741   const char *result = response[0].c_str();
742   const char *expect = "+CUSATD: 0,1";
743   ASSERT_STREQ(result, expect);
744 }
745 
TEST_F(ModemServiceTest,SendEnvelope)746 TEST_F(ModemServiceTest, SendEnvelope) {
747   std::string command = "AT+CUSATT=\"810301250002028281830100\"";
748   std::vector<std::string> response;
749   SendCommand(command);
750   ReadCommandResponse(response);
751   ASSERT_EQ(response.size(), 2);
752   const char *result = response[0].c_str();
753   const char *expect = "+CUSATT: 0";
754   ASSERT_STREQ(result, expect);
755 }
756 
TEST_F(ModemServiceTest,GetSendTerminalResponseToSim)757 TEST_F(ModemServiceTest, GetSendTerminalResponseToSim) {
758   std::string command = "AT+CUSATE=\"D3078202018190014E\"";
759   std::vector<std::string> response;
760   SendCommand(command);
761   ReadCommandResponse(response);
762   ASSERT_EQ(response.size(), 2);
763   const char *result = response[0].c_str();
764   const char *expect = "+CUSATE: 0";
765   ASSERT_STREQ(result, expect);
766 }
767 
768 /* Misc Service Test */
TEST_F(ModemServiceTest,GetIMEI)769 TEST_F(ModemServiceTest, GetIMEI) {
770   std::string command = "AT+CGSN";
771   std::vector<std::string> response;
772   SendCommand(command);
773   ReadCommandResponse(response);
774   ASSERT_EQ(response.size(), 2);
775   const char *result = response[0].c_str();
776   const char *expect = "867400022047199";
777   ASSERT_STREQ(result, expect);
778 }
779