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 <cstring>
19 
20 #include <android-base/logging.h>
21 
22 #include "host/commands/modem_simulator/device_config.h"
23 
24 namespace cuttlefish {
25 
CommandHandler(const std::string & command,f_func handler)26 CommandHandler::CommandHandler(const std::string& command, f_func handler)
27     : command_prefix(command),
28       match_mode(FULL_MATCH),
29       f_command_handler(handler) {}
30 
CommandHandler(const std::string & command,p_func handler)31 CommandHandler::CommandHandler(const std::string& command, p_func handler)
32     : command_prefix(command),
33       match_mode(PARTIAL_MATCH),
34       p_command_handler(handler) {}
35 
Compare(const std::string & command) const36 int CommandHandler::Compare(const std::string& command) const {
37   int result = -1;
38   if (match_mode == PARTIAL_MATCH) {
39     result = command.compare(2, command_prefix.size(), command_prefix);  // skip "AT"
40   } else {
41     result = command.compare(2, command.size(), command_prefix);
42   }
43   return result;
44 }
45 
HandleCommand(const Client & client,std::string & command) const46 void CommandHandler::HandleCommand(const Client& client,
47                                    std::string& command) const {
48   if (match_mode == PARTIAL_MATCH && p_command_handler != nullptr) {
49     (*p_command_handler)(client, command);
50   } else if (match_mode == FULL_MATCH && f_command_handler != nullptr) {
51     (*f_command_handler)(client);
52   } else {
53     LOG(ERROR) << "Mismatched mode and handler, CHECK!";
54   }
55 }
56 
ModemService(int32_t service_id,std::vector<CommandHandler> command_handlers,ChannelMonitor * channel_monitor,ThreadLooper * thread_looper)57 ModemService::ModemService(int32_t service_id,
58                            std::vector<CommandHandler> command_handlers,
59                            ChannelMonitor* channel_monitor,
60                            ThreadLooper* thread_looper)
61     : service_id_(service_id),
62       command_handlers_(command_handlers),
63       thread_looper_(thread_looper),
64       channel_monitor_(channel_monitor) {}
65 
HandleModemCommand(const Client & client,std::string command)66 bool ModemService::HandleModemCommand(const Client& client,
67                                       std::string command) {
68   for (auto& handler : command_handlers_) {
69     if (handler.Compare(command) == 0) {
70       handler.HandleCommand(client, command);
71       return true;
72     }
73   }
74 
75   return false;
76 }
77 
HandleCommandDefaultSupported(const Client & client)78 void ModemService::HandleCommandDefaultSupported(const Client& client) {
79   std::string response{"OK\r"};
80   client.SendCommandResponse(response);
81 }
82 
SendUnsolicitedCommand(std::string unsol_command)83 void ModemService::SendUnsolicitedCommand(std::string unsol_command) {
84   if (channel_monitor_) {
85     channel_monitor_->SendUnsolicitedCommand(unsol_command);
86     ;
87   }
88 }
89 
ConnectToRemoteCvd(std::string port)90 cuttlefish::SharedFD ModemService::ConnectToRemoteCvd(std::string port) {
91   std::string remote_sock_name = "modem_simulator" + port;
92   auto remote_sock = cuttlefish::SharedFD::SocketLocalClient(
93       remote_sock_name.c_str(), true, SOCK_STREAM);
94   if (!remote_sock->IsOpen()) {
95     LOG(ERROR) << "Failed to connect to remote cuttlefish: " << port
96                << ", error: " << strerror(errno);
97   }
98   return remote_sock;
99 }
100 
SendCommandToRemote(ClientId remote_client,std::string response)101 void ModemService::SendCommandToRemote(ClientId remote_client,
102                                        std::string response) {
103   if (channel_monitor_) {
104     channel_monitor_->SendRemoteCommand(remote_client, response);
105     ;
106   }
107 }
108 
CloseRemoteConnection(ClientId remote_client)109 void ModemService::CloseRemoteConnection(ClientId remote_client) {
110   if (channel_monitor_) {
111     channel_monitor_->CloseRemoteConnection(remote_client);
112     ;
113   }
114 }
115 
GetHostId()116 std::string ModemService::GetHostId() {
117   return std::to_string(cuttlefish::modem::DeviceConfig::host_id());
118 }
119 
120 }  // namespace cuttlefish
121