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/command_parser.h"
17
18 #include <sstream>
19 #include <string>
20
21 namespace cuttlefish {
22
23 /**
24 * Parses the next string between double quotes
25 * returns the string on success and "" on fail
26 * updates command_
27 */
GetNextStr()28 std::string_view CommandParser::GetNextStr() {
29 auto fpos = command_.find('\"');
30 if (fpos == std::string_view::npos) {
31 return {};
32 }
33
34 auto spos = command_.find('\"', fpos + 1);
35 if (spos == std::string_view::npos) {
36 command_ = command_.substr(fpos + 1);
37 return {};
38 }
39
40 auto str = command_.substr(fpos + 1, (spos - fpos - 1));
41 command_ = command_.substr(spos + 1);
42 SkipComma();
43 return str;
44 }
45
46 /**
47 * Parses the next string before the flag
48 * If flag not exists, returns the whole command_
49 * updates command_
50 */
GetNextStr(char flag)51 std::string_view CommandParser::GetNextStr(char flag) {
52 auto pos = command_.find(flag);
53 auto str = command_.substr(0, pos);
54 if (pos != std::string_view::npos) pos += 1; // npos + 1 = 0
55 command_.remove_prefix(std::min(pos, command_.size()));
56 return str;
57 }
58
59 /**
60 * Parses the next base 10 integer in the AT command and convert to upper case
61 * hex string
62 * returns the hex string on success and "" on fail
63 * updates command_
64 *
65 * Specially, for AT+CRSM
66 */
GetNextStrDeciToHex()67 std::string CommandParser::GetNextStrDeciToHex() {
68 std::string str;
69 int value = GetNextInt();
70 if (value == -1) {
71 return {};
72 } else {
73 std::stringstream ss;
74 ss << std::hex << std::uppercase << value;
75 return ss.str();
76 }
77 }
78
parse_int(const std::string & snumber,int base)79 static int parse_int(const std::string& snumber, int base) {
80 if (snumber.empty()) return -1;
81 const char* p = snumber.c_str();
82 char* p_end = nullptr;
83 errno = 0;
84 const long lval = std::strtol(p, &p_end, base);
85 if (p == p_end) {
86 return -1;
87 }
88 const bool range_error = errno == ERANGE;
89
90 if (range_error) return -1;
91 return lval;
92 }
93
94 /**
95 * Parses the next base 10 integer in the AT command
96 * returns the value on success and -1 on fail
97 * updates command_
98 */
GetNextInt()99 int CommandParser::GetNextInt() {
100 if (command_.empty()) {
101 return -1;
102 }
103 std::string sub(GetNextStr(','));
104
105 int value = parse_int(sub, 10);
106
107 return value;
108 }
109
110 /**
111 * Parses the next base 16 integer in the AT command
112 * returns the value on success and -1 on fail
113 * updates command_
114 */
GetNextHexInt()115 int CommandParser::GetNextHexInt() {
116 if (command_.empty()) {
117 return -1;
118 }
119
120 std::string sub(GetNextStr(','));
121 int value = parse_int(sub, 16);
122 return value;
123 }
124
125 } // namespace cuttlefish
126