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) {
55 pos += 1; // npos + 1 = 0
56 }
57 command_.remove_prefix(std::min(pos, command_.size()));
58 return str;
59 }
60
61 /**
62 * Parses the next base 10 integer in the AT command and convert to upper case
63 * hex string
64 * returns the hex string on success and "" on fail
65 * updates command_
66 *
67 * Specially, for AT+CRSM
68 */
GetNextStrDeciToHex()69 std::string CommandParser::GetNextStrDeciToHex() {
70 std::string str;
71 int value = GetNextInt();
72 if (value == -1) {
73 return {};
74 } else {
75 std::stringstream ss;
76 ss << std::hex << std::uppercase << value;
77 return ss.str();
78 }
79 }
80
parse_int(const std::string & snumber,int base)81 static int parse_int(const std::string& snumber, int base) {
82 if (snumber.empty()) {
83 return -1;
84 }
85 const char* p = snumber.c_str();
86 char* p_end = nullptr;
87 errno = 0;
88 const long lval = std::strtol(p, &p_end, base);
89 if (p == p_end) {
90 return -1;
91 }
92 const bool range_error = errno == ERANGE;
93
94 if (range_error) {
95 return -1;
96 }
97 return lval;
98 }
99
100 /**
101 * Parses the next base 10 integer in the AT command
102 * returns the value on success and -1 on fail
103 * updates command_
104 */
GetNextInt()105 int CommandParser::GetNextInt() {
106 if (command_.empty()) {
107 return -1;
108 }
109 std::string sub(GetNextStr(','));
110
111 int value = parse_int(sub, 10);
112
113 return value;
114 }
115
116 /**
117 * Parses the next base 16 integer in the AT command
118 * returns the value on success and -1 on fail
119 * updates command_
120 */
GetNextHexInt()121 int CommandParser::GetNextHexInt() {
122 if (command_.empty()) {
123 return -1;
124 }
125
126 std::string sub(GetNextStr(','));
127 int value = parse_int(sub, 16);
128 return value;
129 }
130
131 } // namespace cuttlefish
132