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