TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / src / anbox / qemu / gsm_message_processor.cpp
1 /*
2  * Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
3  *
4  * This program is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 3, as published
6  * by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranties of
10  * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11  * PURPOSE.  See the GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program.  If not, see <http://www.gnu.org/licenses/>.
15  *
16  */
17
18 #include "anbox/qemu/gsm_message_processor.h"
19 #include "anbox/logger.h"
20 #include "anbox/qemu/at_parser.h"
21
22 #include <algorithm>
23 #include <functional>
24
25 using namespace std::placeholders;
26
27 namespace anbox {
28 namespace qemu {
29 GsmMessageProcessor::GsmMessageProcessor(
30     const std::shared_ptr<network::SocketMessenger> &messenger)
31     : messenger_(messenger), parser_(std::make_shared<AtParser>()) {
32   auto ok_reply = [&](const std::string &) { send_reply("OK"); };
33
34   parser_->register_command("E0Q0V1", ok_reply);
35   parser_->register_command("S0=0", ok_reply);
36   parser_->register_command(
37       "+CTEC", std::bind(&GsmMessageProcessor::handle_ctec, this, _1));
38   parser_->register_command("+CMEE=1", ok_reply);
39   parser_->register_command("+CCWA=1", ok_reply);
40   parser_->register_command("+CMOD=0", ok_reply);
41   parser_->register_command("+CMUT=0", ok_reply);
42   parser_->register_command("+CSSN=0,1", ok_reply);
43   parser_->register_command("+COLP=0", ok_reply);
44   parser_->register_command("+CSCS=\"HEX\"", ok_reply);
45   parser_->register_command("+CUSD=1", ok_reply);
46   parser_->register_command("+CGEREP=1,0", ok_reply);
47   parser_->register_command(
48       "+CMGF", std::bind(&GsmMessageProcessor::handle_cmgf, this, _1));
49   parser_->register_command("%CPI=3", ok_reply);
50   parser_->register_command("%CSTAT=1", ok_reply);
51   parser_->register_command(
52       "+CREG", std::bind(&GsmMessageProcessor::handle_creg, this, _1));
53   parser_->register_command(
54       "+CGREG", std::bind(&GsmMessageProcessor::handle_cgreg, this, _1));
55   parser_->register_command(
56       "+CFUN", std::bind(&GsmMessageProcessor::handle_cfun, this, _1));
57 }
58
59 GsmMessageProcessor::~GsmMessageProcessor() {}
60
61 bool GsmMessageProcessor::process_data(const std::vector<std::uint8_t> &data) {
62   for (const auto &byte : data) buffer_.push_back(byte);
63
64   parser_->process_data(buffer_);
65   return true;
66 }
67
68 void GsmMessageProcessor::send_reply(const std::string &message) {
69   auto reply = utils::string_format("%s\rOK\n", message);
70   std::vector<std::uint8_t> data;
71   std::copy(reply.begin(), reply.end(), std::back_inserter(data));
72   messenger_->send(reinterpret_cast<const char *>(data.data()), data.size());
73 }
74
75 void GsmMessageProcessor::handle_ctec(const std::string &command) {
76   if (command == "+CTEC=?")
77     send_reply("+CTEC: 0,1,2,3");
78   else if (command == "+CTEC?")
79     send_reply(utils::string_format(
80         "+CTEC: %d,%x", static_cast<unsigned int>(technology::gsm), 0x0f));
81 }
82
83 void GsmMessageProcessor::handle_cmgf(const std::string &command) {
84   if (command == "+CMGF=0") send_reply("");
85 }
86
87 void GsmMessageProcessor::handle_creg(const std::string &command) {
88   if (command == "+CREG=?")
89     send_reply("+CREG: (0-2)");
90   else if (command == "+CREG?")
91     send_reply(utils::string_format("+CREF: %d,%d", 0, 0));
92   else if (utils::string_starts_with(command, "+CREG="))
93     send_reply("");
94 }
95
96 void GsmMessageProcessor::handle_cgreg(const std::string &command) {
97   if (command == "+CGREG=?")
98     send_reply("+CGREG: (0-2)");
99   else if (command == "+CGREG?")
100     send_reply(utils::string_format("+CGREG: %d,%d", 0, 0));
101   else if (utils::string_starts_with(command, "+CGREG="))
102     send_reply("");
103 }
104
105 void GsmMessageProcessor::handle_cfun(const std::string &command) {
106   if (command == "+CFUN?")
107     send_reply(utils::string_format("+CFUN: %d", 1));
108   else if (utils::string_starts_with(command, "+CFUN="))
109     send_reply("");
110 }
111 }  // namespace qemu
112 }  // namespace anbox