• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "host/commands/modem_simulator/modem_service.h"
17 
18 #include <android-base/logging.h>
19 
20 #include <cstring>
21 
22 #include "host/commands/modem_simulator/device_config.h"
23 
24 namespace cuttlefish {
25 
26 const std::string ModemService::kCmeErrorOperationNotAllowed      = "+CME ERROR: 3";
27 const std::string ModemService::kCmeErrorOperationNotSupported    = "+CME ERROR: 4";
28 const std::string ModemService::kCmeErrorSimNotInserted           = "+CME ERROR: 10";
29 const std::string ModemService::kCmeErrorSimPinRequired           = "+CME ERROR: 11";
30 const std::string ModemService::kCmeErrorSimPukRequired           = "+CME ERROR: 12";
31 const std::string ModemService::kCmeErrorSimBusy                  = "+CME ERROR: 14";
32 const std::string ModemService::kCmeErrorIncorrectPassword        = "+CME ERROR: 16";
33 const std::string ModemService::kCmeErrorMemoryFull               = "+CME ERROR: 20";
34 const std::string ModemService::kCmeErrorInvalidIndex             = "+CME ERROR: 21";
35 const std::string ModemService::kCmeErrorNotFound                 = "+CME ERROR: 22";
36 const std::string ModemService::kCmeErrorInvalidCharactersInTextString = "+CME ERROR: 27";
37 const std::string ModemService::kCmeErrorNoNetworkService         = "+CME ERROR: 30";
38 const std::string ModemService::kCmeErrorNetworkNotAllowedEmergencyCallsOnly = "+CME ERROR: 32";
39 const std::string ModemService::kCmeErrorInCorrectParameters      = "+CME ERROR: 50";
40 const std::string ModemService::kCmeErrorNetworkNotAttachedDueToMTFunctionalRestrictions = "+CME ERROR: 53";
41 const std::string ModemService::kCmeErrorFixedDialNumberOnlyAllowed = "+CME ERROR: 56";
42 
43 const std::string ModemService::kCmsErrorOperationNotAllowed      = "+CMS ERROR: 302";
44 const std::string ModemService::kCmsErrorOperationNotSupported    = "+CMS ERROR: 303";
45 const std::string ModemService::kCmsErrorInvalidPDUModeParam      = "+CMS ERROR: 304";
46 const std::string ModemService::kCmsErrorSCAddressUnknown         = "+CMS ERROR: 304";
47 
48 const std::pair<int, int> ModemService::kRemotePortRange =
49     std::make_pair(6520, 6527);
50 
CommandHandler(const std::string & command,f_func handler)51 CommandHandler::CommandHandler(const std::string& command, f_func handler)
52     : command_prefix(command),
53       match_mode(FULL_MATCH),
54       f_command_handler(handler) {}
55 
CommandHandler(const std::string & command,p_func handler)56 CommandHandler::CommandHandler(const std::string& command, p_func handler)
57     : command_prefix(command),
58       match_mode(PARTIAL_MATCH),
59       p_command_handler(handler) {}
60 
Compare(const std::string & command) const61 int CommandHandler::Compare(const std::string& command) const {
62   int result = -1;
63   if (match_mode == PARTIAL_MATCH) {
64     result = command.compare(2, command_prefix.size(), command_prefix);  // skip "AT"
65   } else {
66     result = command.compare(2, command.size(), command_prefix);
67   }
68   return result;
69 }
70 
HandleCommand(const Client & client,std::string & command) const71 void CommandHandler::HandleCommand(const Client& client,
72                                    std::string& command) const {
73   if (match_mode == PARTIAL_MATCH && p_command_handler != nullptr) {
74     (*p_command_handler)(client, command);
75   } else if (match_mode == FULL_MATCH && f_command_handler != nullptr) {
76     (*f_command_handler)(client);
77   } else {
78     LOG(ERROR) << "Mismatched mode and handler, CHECK!";
79   }
80 }
81 
ModemService(int32_t service_id,std::vector<CommandHandler> command_handlers,ChannelMonitor * channel_monitor,ThreadLooper * thread_looper)82 ModemService::ModemService(int32_t service_id,
83                            std::vector<CommandHandler> command_handlers,
84                            ChannelMonitor* channel_monitor,
85                            ThreadLooper* thread_looper)
86     : service_id_(service_id),
87       command_handlers_(command_handlers),
88       thread_looper_(thread_looper),
89       channel_monitor_(channel_monitor) {}
90 
HandleModemCommand(const Client & client,std::string command)91 bool ModemService::HandleModemCommand(const Client& client,
92                                       std::string command) {
93   for (auto& handler : command_handlers_) {
94     if (handler.Compare(command) == 0) {
95       handler.HandleCommand(client, command);
96       return true;
97     }
98   }
99 
100   return false;
101 }
102 
HandleCommandDefaultSupported(const Client & client)103 void ModemService::HandleCommandDefaultSupported(const Client& client) {
104   std::string response{"OK\r"};
105   client.SendCommandResponse(response);
106 }
107 
SendUnsolicitedCommand(std::string unsol_command)108 void ModemService::SendUnsolicitedCommand(std::string unsol_command) {
109   if (channel_monitor_) {
110     channel_monitor_->SendUnsolicitedCommand(unsol_command);
111     ;
112   }
113 }
114 
ConnectToRemoteCvd(std::string port)115 cuttlefish::SharedFD ModemService::ConnectToRemoteCvd(std::string port) {
116   std::string remote_sock_name = "modem_simulator" + port;
117   auto remote_sock = cuttlefish::SharedFD::SocketLocalClient(
118       remote_sock_name.c_str(), true, SOCK_STREAM);
119   if (!remote_sock->IsOpen()) {
120     LOG(ERROR) << "Failed to connect to remote cuttlefish: " << port
121                << ", error: " << strerror(errno);
122   }
123   return remote_sock;
124 }
125 
SendCommandToRemote(cuttlefish::SharedFD remote_client,std::string response)126 void ModemService::SendCommandToRemote(cuttlefish::SharedFD remote_client, std::string response) {
127   if (channel_monitor_) {
128     channel_monitor_->SendRemoteCommand(remote_client, response);
129     ;
130   }
131 }
132 
CloseRemoteConnection(cuttlefish::SharedFD remote_client)133 void ModemService::CloseRemoteConnection(cuttlefish::SharedFD remote_client) {
134   if (channel_monitor_) {
135     channel_monitor_->CloseRemoteConnection(remote_client);
136     ;
137   }
138 }
139 
GetHostId()140 std::string ModemService::GetHostId() {
141   return std::to_string(cuttlefish::modem::DeviceConfig::host_id());
142 }
143 
144 }  // namespace cuttlefish
145