1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "hfp_ag_command_processor.h"
17 
18 #include <algorithm>
19 #include <regex>
20 #include <string>
21 
22 #include "hfp_ag_audio_connection.h"
23 #include "hfp_ag_defines.h"
24 #include "hfp_ag_profile_event_sender.h"
25 #include "log_util.h"
26 #include "packet.h"
27 #include "securec.h"
28 
29 namespace OHOS {
30 namespace bluetooth {
31 std::unordered_map<std::string, HfpAgCommandProcessor::HfpAgAtHandler> HfpAgCommandProcessor::g_atCmdMap = {
32     std::make_pair<std::string, HfpAgAtHandler>("AT+BRSF", {&HfpAgCommandProcessor::AtEmptyFn,
33                                                             &HfpAgCommandProcessor::BrsfSetter,
34                                                             &HfpAgCommandProcessor::AtEmptyFn,
35                                                             &HfpAgCommandProcessor::AtEmptyFn}),
36     std::make_pair<std::string, HfpAgAtHandler>("AT+CCWA", {&HfpAgCommandProcessor::AtEmptyFn,
37                                                             &HfpAgCommandProcessor::CcwaSetter,
38                                                             &HfpAgCommandProcessor::AtEmptyFn,
39                                                             &HfpAgCommandProcessor::AtEmptyFn}),
40     std::make_pair<std::string, HfpAgAtHandler>("AT+CLIP", {&HfpAgCommandProcessor::AtEmptyFn,
41                                                             &HfpAgCommandProcessor::ClipSetter,
42                                                             &HfpAgCommandProcessor::AtEmptyFn,
43                                                             &HfpAgCommandProcessor::AtEmptyFn}),
44     std::make_pair<std::string, HfpAgAtHandler>("AT+CMER", {&HfpAgCommandProcessor::AtEmptyFn,
45                                                             &HfpAgCommandProcessor::CmerSetter,
46                                                             &HfpAgCommandProcessor::AtEmptyFn,
47                                                             &HfpAgCommandProcessor::AtEmptyFn}),
48     std::make_pair<std::string, HfpAgAtHandler>("AT+CMEE", {&HfpAgCommandProcessor::AtEmptyFn,
49                                                             &HfpAgCommandProcessor::CmeeSetter,
50                                                             &HfpAgCommandProcessor::AtEmptyFn,
51                                                             &HfpAgCommandProcessor::AtEmptyFn}),
52     std::make_pair<std::string, HfpAgAtHandler>("AT+BCC", {&HfpAgCommandProcessor::AtEmptyFn,
53                                                            &HfpAgCommandProcessor::AtEmptyFn,
54                                                            &HfpAgCommandProcessor::AtEmptyFn,
55                                                            &HfpAgCommandProcessor::BccExecuter}),
56     std::make_pair<std::string, HfpAgAtHandler>("ATA", {&HfpAgCommandProcessor::AtEmptyFn,
57                                                         &HfpAgCommandProcessor::AtEmptyFn,
58                                                         &HfpAgCommandProcessor::AtEmptyFn,
59                                                         &HfpAgCommandProcessor::AtaExecuter}),
60     std::make_pair<std::string, HfpAgAtHandler>("ATD", {&HfpAgCommandProcessor::AtEmptyFn,
61                                                         &HfpAgCommandProcessor::AtEmptyFn,
62                                                         &HfpAgCommandProcessor::AtEmptyFn,
63                                                         &HfpAgCommandProcessor::AtdExecuter}),
64     std::make_pair<std::string, HfpAgAtHandler>("AT+VGS", {&HfpAgCommandProcessor::AtEmptyFn,
65                                                            &HfpAgCommandProcessor::VgsSetter,
66                                                            &HfpAgCommandProcessor::AtEmptyFn,
67                                                            &HfpAgCommandProcessor::AtEmptyFn}),
68     std::make_pair<std::string, HfpAgAtHandler>("AT+VGM", {&HfpAgCommandProcessor::AtEmptyFn,
69                                                            &HfpAgCommandProcessor::VgmSetter,
70                                                            &HfpAgCommandProcessor::AtEmptyFn,
71                                                            &HfpAgCommandProcessor::AtEmptyFn}),
72     std::make_pair<std::string, HfpAgAtHandler>("AT+CHLD", {&HfpAgCommandProcessor::AtEmptyFn,
73                                                             &HfpAgCommandProcessor::ChldSetter,
74                                                             &HfpAgCommandProcessor::ChldTester,
75                                                             &HfpAgCommandProcessor::AtEmptyFn}),
76     std::make_pair<std::string, HfpAgAtHandler>("AT+CHUP", {&HfpAgCommandProcessor::AtEmptyFn,
77                                                             &HfpAgCommandProcessor::AtEmptyFn,
78                                                             &HfpAgCommandProcessor::AtEmptyFn,
79                                                             &HfpAgCommandProcessor::ChupExecuter}),
80     std::make_pair<std::string, HfpAgAtHandler>("AT+CIND", {&HfpAgCommandProcessor::CindGetter,
81                                                             &HfpAgCommandProcessor::AtEmptyFn,
82                                                             &HfpAgCommandProcessor::CindTester,
83                                                             &HfpAgCommandProcessor::AtEmptyFn}),
84     std::make_pair<std::string, HfpAgAtHandler>("AT+VTS", {&HfpAgCommandProcessor::AtEmptyFn,
85                                                            &HfpAgCommandProcessor::VtsSetter,
86                                                            &HfpAgCommandProcessor::AtEmptyFn,
87                                                            &HfpAgCommandProcessor::AtEmptyFn}),
88     std::make_pair<std::string, HfpAgAtHandler>("AT+BLDN", {&HfpAgCommandProcessor::AtEmptyFn,
89                                                             &HfpAgCommandProcessor::AtEmptyFn,
90                                                             &HfpAgCommandProcessor::AtEmptyFn,
91                                                             &HfpAgCommandProcessor::BldnExecuter}),
92     std::make_pair<std::string, HfpAgAtHandler>("AT+BVRA", {&HfpAgCommandProcessor::AtEmptyFn,
93                                                             &HfpAgCommandProcessor::BvraSetter,
94                                                             &HfpAgCommandProcessor::AtEmptyFn,
95                                                             &HfpAgCommandProcessor::AtEmptyFn}),
96     std::make_pair<std::string, HfpAgAtHandler>("AT+NREC", {&HfpAgCommandProcessor::AtEmptyFn,
97                                                             &HfpAgCommandProcessor::NrecSetter,
98                                                             &HfpAgCommandProcessor::AtEmptyFn,
99                                                             &HfpAgCommandProcessor::AtEmptyFn}),
100     std::make_pair<std::string, HfpAgAtHandler>("AT+CNUM", {&HfpAgCommandProcessor::AtEmptyFn,
101                                                             &HfpAgCommandProcessor::AtEmptyFn,
102                                                             &HfpAgCommandProcessor::AtEmptyFn,
103                                                             &HfpAgCommandProcessor::CnumExecuter}),
104     std::make_pair<std::string, HfpAgAtHandler>("AT+CLCC", {&HfpAgCommandProcessor::AtEmptyFn,
105                                                             &HfpAgCommandProcessor::AtEmptyFn,
106                                                             &HfpAgCommandProcessor::AtEmptyFn,
107                                                             &HfpAgCommandProcessor::ClccExecuter}),
108     std::make_pair<std::string, HfpAgAtHandler>("AT+COPS", {&HfpAgCommandProcessor::CopsGetter,
109                                                             &HfpAgCommandProcessor::CopsSetter,
110                                                             &HfpAgCommandProcessor::AtEmptyFn,
111                                                             &HfpAgCommandProcessor::AtEmptyFn}),
112     std::make_pair<std::string, HfpAgAtHandler>("AT+BIA", {&HfpAgCommandProcessor::AtEmptyFn,
113                                                            &HfpAgCommandProcessor::BiaSetter,
114                                                            &HfpAgCommandProcessor::AtEmptyFn,
115                                                            &HfpAgCommandProcessor::AtEmptyFn}),
116     std::make_pair<std::string, HfpAgAtHandler>("AT+BCS", {&HfpAgCommandProcessor::AtEmptyFn,
117                                                            &HfpAgCommandProcessor::BcsSetter,
118                                                            &HfpAgCommandProcessor::AtEmptyFn,
119                                                            &HfpAgCommandProcessor::AtEmptyFn}),
120     std::make_pair<std::string, HfpAgAtHandler>("AT+BIND", {&HfpAgCommandProcessor::BindGetter,
121                                                             &HfpAgCommandProcessor::BindSetter,
122                                                             &HfpAgCommandProcessor::BindTester,
123                                                             &HfpAgCommandProcessor::AtEmptyFn}),
124     std::make_pair<std::string, HfpAgAtHandler>("AT+BIEV", {&HfpAgCommandProcessor::AtEmptyFn,
125                                                             &HfpAgCommandProcessor::BievSetter,
126                                                             &HfpAgCommandProcessor::AtEmptyFn,
127                                                             &HfpAgCommandProcessor::AtEmptyFn}),
128     std::make_pair<std::string, HfpAgAtHandler>("AT+BAC", {&HfpAgCommandProcessor::AtEmptyFn,
129                                                            &HfpAgCommandProcessor::BacSetter,
130                                                            &HfpAgCommandProcessor::AtEmptyFn,
131                                                            &HfpAgCommandProcessor::AtEmptyFn}),
132     std::make_pair<std::string, HfpAgAtHandler>("AT+BTRH", {&HfpAgCommandProcessor::BtrhGetter,
133                                                             &HfpAgCommandProcessor::BtrhSetter,
134                                                             &HfpAgCommandProcessor::AtEmptyFn,
135                                                             &HfpAgCommandProcessor::AtEmptyFn}),
136     std::make_pair<std::string, HfpAgAtHandler>("AT+CKPD", {&HfpAgCommandProcessor::AtEmptyFn,
137                                                             &HfpAgCommandProcessor::CkpdSetter,
138                                                             &HfpAgCommandProcessor::AtEmptyFn,
139                                                             &HfpAgCommandProcessor::AtEmptyFn}),
140     std::make_pair<std::string, HfpAgAtHandler>("AT+BINP", {&HfpAgCommandProcessor::AtEmptyFn,
141                                                             &HfpAgCommandProcessor::BinpSetter,
142                                                             &HfpAgCommandProcessor::AtEmptyFn,
143                                                             &HfpAgCommandProcessor::AtEmptyFn}),
144 };
145 
StoiTryCatch(HfpAgDataConnection & dataConn,const std::string & arg)146 int HfpAgCommandProcessor::StoiTryCatch(HfpAgDataConnection &dataConn, const std::string &arg)
147 {
148     try {
149         return std::stoi(arg);
150     } catch (std::exception &e) {
151         LOG_ERROR("[HFP AG]%{public}s():Catch exception %{public}s", __FUNCTION__, e.what());
152         SendErrorCode(dataConn, HFP_AG_ERROR_AG_FAILURE);
153         return 0;
154     }
155 }
156 
GetInstance()157 HfpAgCommandProcessor &HfpAgCommandProcessor::GetInstance()
158 {
159     static HfpAgCommandProcessor instance;
160     return instance;
161 }
162 
SendErrorCode(const HfpAgDataConnection & dataConn,int errorCode)163 void HfpAgCommandProcessor::SendErrorCode(const HfpAgDataConnection &dataConn, int errorCode)
164 {
165     if (dataConn.cmeeEnabled_) {
166         SendAtCommand(dataConn, "+CME ERROR: " + std::to_string(errorCode));
167     } else {
168         SendAtCommand(dataConn, "ERROR");
169     }
170 }
171 
SendAtCommand(const HfpAgDataConnection & dataConn,const std::string & command)172 void HfpAgCommandProcessor::SendAtCommand(const HfpAgDataConnection &dataConn, const std::string &command)
173 {
174     LOG_INFO("[HFP AG]%{public}s():Send Command[%{public}s]", __FUNCTION__, command.c_str());
175     std::string fullCommand(HEAD + command + TAIL);
176     std::size_t cmdLength = fullCommand.length();
177     Packet *packet = PacketMalloc(0, 0, cmdLength);
178     Buffer *buf = PacketContinuousPayload(packet);
179     void *data = BufferPtr(buf);
180     (void)memcpy_s(data, cmdLength, fullCommand.c_str(), cmdLength);
181     dataConn.WriteData(*packet);
182     PacketFree(packet);
183 }
184 
Handle(HfpAgDataConnection & dataConn,const std::string & cmd,const std::string & arg,int cmdType)185 void HfpAgCommandProcessor::Handle(
186     HfpAgDataConnection &dataConn, const std::string &cmd, const std::string &arg, int cmdType)
187 {
188     LOG_INFO("[HFP AG]%{public}s():cmd[%{public}s], arg[%{public}s], Type[%{public}d]", __FUNCTION__,
189         cmd.c_str(), arg.c_str(), cmdType);
190     auto it = g_atCmdMap.find(cmd);
191     if (it == g_atCmdMap.end()) {
192         SendErrorCode(dataConn, HFP_AG_ERROR_AG_FAILURE);
193         LOG_ERROR("[HFP AG]%{public}s():%{public}s command handler not found", __FUNCTION__, cmd.c_str());
194         return;
195     }
196 
197     switch (cmdType) {
198         case HFP_AG_CMD_SET:
199             (this->*(it->second.setter))(dataConn, arg);
200             break;
201         case HFP_AG_CMD_GET:
202             (this->*(it->second.getter))(dataConn, arg);
203             break;
204         case HFP_AG_CMD_TEST:
205             (this->*(it->second.tester))(dataConn, arg);
206             break;
207         case HFP_AG_CMD_EXEC:
208             (this->*(it->second.executer))(dataConn, arg);
209             break;
210         case HFP_AG_CMD_UNKNOWN:
211             LOG_INFO("[HFP AG]%{public}s():HFP_AG_CMD_UNKNOWN", __FUNCTION__);
212             break;
213         default:
214             LOG_INFO("[HFP AG]%{public}s():default", __FUNCTION__);
215             break;
216     }
217     return;
218 }
219 
AtEmptyFn(HfpAgDataConnection & dataConn,const std::string & arg)220 void HfpAgCommandProcessor::AtEmptyFn(HfpAgDataConnection &dataConn, const std::string &arg)
221 {
222     LOG_WARN("[HFP AG]%{public}s():Unsupported at command arg[%{public}s]", __FUNCTION__, arg.c_str());
223     SendErrorCode(dataConn, HFP_AG_ERROR_AG_FAILURE);
224 }
225 
AtaExecuter(HfpAgDataConnection & dataConn,const std::string & arg)226 void HfpAgCommandProcessor::AtaExecuter(HfpAgDataConnection &dataConn, const std::string &arg)
227 {
228     SendAtCommand(dataConn, OK);
229     HfpAgProfileEventSender::GetInstance().AnswerCall(dataConn.remoteAddr_);
230 }
231 
AtdExecuter(HfpAgDataConnection & dataConn,const std::string & arg)232 void HfpAgCommandProcessor::AtdExecuter(HfpAgDataConnection &dataConn, const std::string &arg)
233 {
234     std::string number = arg;
235     number.erase(remove_if(number.begin(), number.end(), isspace), number.end());
236     int type = HFP_AG_NUMBER_DIAL;
237 
238     if (number.length() <= ATD_VALID_LENGTH) {  // number should contains a number and a ';'
239         SendErrorCode(dataConn, HFP_AG_ERROR_INVALID_CHARS_IN_DIAL_STRING);
240         return;
241     }
242 
243     if (number.at(0) == '>') {  // ATD> memory dial
244         const std::regex baseRegex("[^\\d>;]");
245         if (std::regex_search(number, baseRegex) || number.at(number.length() - 1) != ';') {
246             SendErrorCode(dataConn, HFP_AG_ERROR_INVALID_CHARS_IN_DIAL_STRING);
247             return;
248         }
249 
250         type = HFP_AG_MEMORY_DIAL;
251         number = number.substr(1, number.length() - ATD_VALID_LENGTH);
252     } else {  // specific number dial
253         const std::regex baseRegex("[^\\d*#+;]");
254         if (std::regex_search(number, baseRegex) || number.at(number.length() - 1) != ';') {
255             SendErrorCode(dataConn, HFP_AG_ERROR_INVALID_CHARS_IN_DIAL_STRING);
256             return;
257         }
258         number = number.substr(0, number.length() - 1);
259     }
260     HfpAgProfileEventSender::GetInstance().DialOutCall(dataConn.remoteAddr_, number, type);
261 }
262 
VgsSetter(HfpAgDataConnection & dataConn,const std::string & arg)263 void HfpAgCommandProcessor::VgsSetter(HfpAgDataConnection &dataConn, const std::string &arg)
264 {
265     int val = StoiTryCatch(dataConn, arg);
266     SendAtCommand(dataConn, OK);
267     HfpAgProfileEventSender::GetInstance().HfVolumeChanged(dataConn.remoteAddr_, HFP_AG_VOLUME_TYPE_SPK, val);
268 }
VgmSetter(HfpAgDataConnection & dataConn,const std::string & arg)269 void HfpAgCommandProcessor::VgmSetter(HfpAgDataConnection &dataConn, const std::string &arg)
270 {
271     int val = StoiTryCatch(dataConn, arg);
272     SendAtCommand(dataConn, OK);
273     HfpAgProfileEventSender::GetInstance().HfVolumeChanged(dataConn.remoteAddr_, HFP_AG_VOLUME_TYPE_MIC, val);
274 }
275 
CcwaSetter(HfpAgDataConnection & dataConn,const std::string & arg)276 void HfpAgCommandProcessor::CcwaSetter(HfpAgDataConnection &dataConn, const std::string &arg)
277 {
278     dataConn.ccwaEnabled_ = StoiTryCatch(dataConn, arg);
279     SendAtCommand(dataConn, OK);
280 }
281 
ChldSetter(HfpAgDataConnection & dataConn,const std::string & arg)282 void HfpAgCommandProcessor::ChldSetter(HfpAgDataConnection &dataConn, const std::string &arg)
283 {
284     int chld = StoiTryCatch(dataConn, arg);
285     LOG_INFO("[HFP AG] ChldSetter chld = %{public}d, arg = %{public}s", chld, arg.c_str());
286     if (!(dataConn.g_localFeatures & HFP_AG_FEATURES_ENHANCED_CALL_CONTROL) &&
287         (dataConn.remoteFeatures_ & HFP_AG_HF_FEATURES_ENHANCED_CALL_CONTROL)) {
288         if (chld != CHLD_RELEASE_ALL_HELD_CALLS && chld != CHLD_RELEASE_ACTIVE_ACCPET_OTHER &&
289             chld != CHLD_RELEASE_HOLD_ACCPET_OTHER && chld != CHLD_ADD_CALL_TO_CONVERSATION &&
290             chld != CHLD_CONNECT_TWO_CALL && chld != CHLD_RELEASE_INDEX_ONE && chld != CHLD_RELEASE_INDEX_TWO &&
291             chld != CHLD_CONSULTATION_INDEX_ONE && chld != CHLD_CONSULTATION_INDEX_TWO) {
292             // we does not support enhanced call control(AT+CHLD=1<idx> / AT+CHLD=2<idx>)
293             SendErrorCode(dataConn, HFP_AG_ERROR_AG_FAILURE);
294             return;
295         }
296     }
297 
298     HfpAgProfileEventSender::GetInstance().HoldCall(dataConn.remoteAddr_, chld);
299 }
300 
ChldTester(HfpAgDataConnection & dataConn,const std::string & arg)301 void HfpAgCommandProcessor::ChldTester(HfpAgDataConnection &dataConn, const std::string &arg)
302 {
303     if ((dataConn.sdpInfo_.remoteVersion >= HFP_AG_HFP_VERSION_1_5) &&
304         (dataConn.g_localFeatures & HFP_AG_FEATURES_ENHANCED_CALL_CONTROL) &&
305         (dataConn.remoteFeatures_ & HFP_AG_HF_FEATURES_ENHANCED_CALL_CONTROL)) {
306         SendAtCommand(dataConn, "+CHLD: " + HfpAgDataConnection::CHLD_ECC_SETTINGS);
307     } else {
308         SendAtCommand(dataConn, "+CHLD: " + HfpAgDataConnection::CHLD_SETTINGS);
309     }
310 
311     if (!dataConn.slcConnected_ && !((dataConn.g_localFeatures & HFP_AG_FEATURES_HF_INDICATORS) &&
312         (dataConn.remoteFeatures_ & HFP_AG_HF_FEATURES_HF_INDICATORS))) {
313         dataConn.SetSlcConnectState(true);
314         HfpAgProfileEventSender::GetInstance().UpdateConnectState(dataConn.remoteAddr_, HFP_AG_SLC_ESTABLISHED_EVT);
315     }
316     SendAtCommand(dataConn, OK);
317 }
318 
ChupExecuter(HfpAgDataConnection & dataConn,const std::string & arg)319 void HfpAgCommandProcessor::ChupExecuter(HfpAgDataConnection &dataConn, const std::string &arg)
320 {
321     if (HfpAgAudioConnection::GetActiveDevice().compare(dataConn.remoteAddr_) != 0) {
322         HILOGI("[HFP AG] AT+CHUP failed because of device is not active, activeAddr[%{public}s], "
323             "remoteAddr_[%{public}s]", GetEncryptAddr(HfpAgAudioConnection::GetActiveDevice()).c_str(),
324             GetEncryptAddr(dataConn.remoteAddr_).c_str());
325         SendErrorCode(dataConn, HFP_AG_ERROR_OPERATION_NOT_ALLOWED);
326     } else {
327         SendAtCommand(dataConn, OK);
328         HfpAgProfileEventSender::GetInstance().HangupCall(dataConn.remoteAddr_);
329     }
330 }
331 
CindGetter(HfpAgDataConnection & dataConn,const std::string & arg)332 void HfpAgCommandProcessor::CindGetter(HfpAgDataConnection &dataConn, const std::string &arg)
333 {
334     HfpAgProfileEventSender::GetInstance().GetAgIndicator(dataConn.remoteAddr_);
335 }
336 
CindTester(HfpAgDataConnection & dataConn,const std::string & arg)337 void HfpAgCommandProcessor::CindTester(HfpAgDataConnection &dataConn, const std::string &arg)
338 {
339     SendAtCommand(dataConn, "+CIND: " + HfpAgDataConnection::CIND_SETTINGS);
340     SendAtCommand(dataConn, OK);
341 }
342 
ClipSetter(HfpAgDataConnection & dataConn,const std::string & arg)343 void HfpAgCommandProcessor::ClipSetter(HfpAgDataConnection &dataConn, const std::string &arg)
344 {
345     dataConn.clipEnabled_ = StoiTryCatch(dataConn, arg);
346     SendAtCommand(dataConn, OK);
347 }
348 
CmerSetter(HfpAgDataConnection & dataConn,const std::string & arg)349 void HfpAgCommandProcessor::CmerSetter(HfpAgDataConnection &dataConn, const std::string &arg)
350 {
351     int data[CMER_ELEMENTS_NUMBER] = {-1, -1, -1, -1};
352     int offset = 0;
353 
354     int res = sscanf_s(arg.c_str(), "%d,%d,%d,%d%n", &data[CMER_MODE_INDEX], &data[CMER_KEYP_INDEX],
355         &data[CMER_DISP_INDEX], &data[CMER_IND_INDEX], &offset);
356     HILOGI("[HFP AG]CmerSetter:(%{public}d,%{public}d,%{public}d,%{public}d), res:%{public}d), offset:%{public}d",
357         data[CMER_MODE_INDEX], data[CMER_KEYP_INDEX], data[CMER_DISP_INDEX], data[CMER_IND_INDEX], res, offset);
358     if (res != CMER_ELEMENTS_NUMBER || offset == 0) {
359         goto error;
360     } else {
361         if (data[CMER_MODE_INDEX] == CMER_MODE_FOR_HFP && data[CMER_IND_INDEX] == 1) {
362             dataConn.cmerEnabled_ = true;
363         } else if (data[CMER_MODE_INDEX] == CMER_MODE_FOR_HFP && data[CMER_IND_INDEX] == 0) {
364             dataConn.cmerEnabled_ = false;
365         } else {
366             goto error;
367         }
368     }
369 
370     if (!dataConn.slcConnected_ && !((dataConn.g_localFeatures & HFP_AG_FEATURES_THREE_WAY) &&
371         (dataConn.remoteFeatures_ & HFP_AG_HF_FEATURES_THREE_WAY))) {
372         dataConn.SetSlcConnectState(true);
373         HfpAgProfileEventSender::GetInstance().UpdateConnectState(dataConn.remoteAddr_, HFP_AG_SLC_ESTABLISHED_EVT);
374     }
375     SendAtCommand(dataConn, OK);
376     return;
377 
378 error:
379     SendAtCommand(dataConn, ERROR);
380 }
381 
VtsSetter(HfpAgDataConnection & dataConn,const std::string & arg)382 void HfpAgCommandProcessor::VtsSetter(HfpAgDataConnection &dataConn, const std::string &arg)
383 {
384     if (arg.length() == 1) {
385         uint8_t code = arg[0];
386         if ((code >= '0' && code <= '9') || code == '*' || code == '#') {
387             HfpAgProfileEventSender::GetInstance().SendDtmf(dataConn.remoteAddr_, code);
388         } else {
389             goto error;
390         }
391     } else {
392         goto error;
393     }
394     return;
395 
396 error:
397     SendErrorCode(dataConn, HFP_AG_ERROR_AG_FAILURE);
398     LOG_ERROR("[HFP HF]%{public}s():receive invalid dtmf code", __FUNCTION__);
399 }
400 
BldnExecuter(HfpAgDataConnection & dataConn,const std::string & arg)401 void HfpAgCommandProcessor::BldnExecuter(HfpAgDataConnection &dataConn, const std::string &arg)
402 {
403     HfpAgProfileEventSender::GetInstance().DialOutCall(dataConn.remoteAddr_, "", HFP_AG_LAST_NUMBER_REDIAL);
404 }
405 
BvraSetter(HfpAgDataConnection & dataConn,const std::string & arg)406 void HfpAgCommandProcessor::BvraSetter(HfpAgDataConnection &dataConn, const std::string &arg)
407 {
408     int bvra = StoiTryCatch(dataConn, arg);
409     HfpAgProfileEventSender::GetInstance().VoiceRecognitionStateChanged(dataConn.remoteAddr_, bvra);
410 }
411 
BrsfSetter(HfpAgDataConnection & dataConn,const std::string & arg)412 void HfpAgCommandProcessor::BrsfSetter(HfpAgDataConnection &dataConn, const std::string &arg)
413 {
414     dataConn.remoteFeatures_ = StoiTryCatch(dataConn, arg);
415     uint32_t features = dataConn.g_localFeatures;
416     if (dataConn.sdpInfo_.remoteVersion < HFP_AG_HFP_VERSION_1_7) {
417         features &= HFP_AG_1_6_FEATURES_MASK;
418     }
419 
420     std::string cmd = "+BRSF: " + std::to_string(features);
421     SendAtCommand(dataConn, cmd);
422     SendAtCommand(dataConn, OK);
423 }
424 
NrecSetter(HfpAgDataConnection & dataConn,const std::string & arg)425 void HfpAgCommandProcessor::NrecSetter(HfpAgDataConnection &dataConn, const std::string &arg)
426 {
427     if (dataConn.g_localFeatures & HFP_AG_FEATURES_ECNR) {
428         int nrec = StoiTryCatch(dataConn, arg);
429         if (nrec == 0 || nrec == 1) {
430             SendAtCommand(dataConn, OK);
431             HfpAgProfileEventSender::GetInstance().EnableNoiseReduction(dataConn.remoteAddr_, nrec);
432         } else {
433             SendErrorCode(dataConn, HFP_AG_ERROR_AG_FAILURE);
434         }
435     } else {
436         SendErrorCode(dataConn, HFP_AG_ERROR_OPERATION_NOT_SUPPORTED);
437     }
438 }
439 
CnumExecuter(HfpAgDataConnection & dataConn,const std::string & arg)440 void HfpAgCommandProcessor::CnumExecuter(HfpAgDataConnection &dataConn, const std::string &arg)
441 {
442     HfpAgProfileEventSender::GetInstance().GetSubscriberNumber(dataConn.remoteAddr_);
443 }
444 
ClccExecuter(HfpAgDataConnection & dataConn,const std::string & arg)445 void HfpAgCommandProcessor::ClccExecuter(HfpAgDataConnection &dataConn, const std::string &arg)
446 {
447     if (!(dataConn.g_localFeatures & HFP_AG_FEATURES_ENHANCED_CALL_STATUS)) {
448         SendErrorCode(dataConn, HFP_AG_ERROR_AG_FAILURE);
449         return;
450     }
451     HfpAgProfileEventSender::GetInstance().GetCurrentCalls(dataConn.remoteAddr_);
452 }
453 
CopsGetter(HfpAgDataConnection & dataConn,const std::string & arg)454 void HfpAgCommandProcessor::CopsGetter(HfpAgDataConnection &dataConn, const std::string &arg)
455 {
456     HfpAgProfileEventSender::GetInstance().GetNetworkOperater(dataConn.remoteAddr_);
457 }
458 
CopsSetter(HfpAgDataConnection & dataConn,const std::string & arg)459 void HfpAgCommandProcessor::CopsSetter(HfpAgDataConnection &dataConn, const std::string &arg)
460 {
461     if (arg == "3,0") {  // set name format to long alphanumeric
462         SendAtCommand(dataConn, OK);
463     } else {
464         SendErrorCode(dataConn, HFP_AG_ERROR_AG_FAILURE);
465     }
466 }
467 
CmeeSetter(HfpAgDataConnection & dataConn,const std::string & arg)468 void HfpAgCommandProcessor::CmeeSetter(HfpAgDataConnection &dataConn, const std::string &arg)
469 {
470     if (dataConn.g_localFeatures & HFP_AG_FEATURES_EXTEND_ERROR_CODE) {
471         int cmee = StoiTryCatch(dataConn, arg);
472         dataConn.cmeeEnabled_ = static_cast<bool>(cmee);
473         SendAtCommand(dataConn, OK);
474     } else {
475         SendErrorCode(dataConn, HFP_AG_ERROR_OPERATION_NOT_SUPPORTED);
476     }
477 }
478 
BiaSetter(HfpAgDataConnection & dataConn,const std::string & arg)479 void HfpAgCommandProcessor::BiaSetter(HfpAgDataConnection &dataConn, const std::string &arg)
480 {
481     size_t i;
482     int indId;
483     size_t len = arg.length();
484     int biaMaskOut = dataConn.biaMaskOut_;
485     for (i = 0, indId = 1; i < len && indId <= MAX_AG_INDICATORS; i++) {
486         if (arg.c_str()[i] == ',') {
487             indId++;
488             continue;
489         }
490 
491         if (arg.c_str()[i] == '0') {
492             biaMaskOut |= 1 << indId;
493         } else if (arg.c_str()[i] == '1') {
494             biaMaskOut &= ~(1 << indId);
495         } else {
496             break;
497         }
498 
499         if (i + 1 < len) {
500             if (arg.c_str()[i + 1] != ',') {
501                 break;
502             }
503         } else {
504             continue;
505         }
506     }
507 
508     LOG_INFO("[HFP AG]%{public}s(): i[%zu], indId[%{public}d], len[%zu]", __FUNCTION__, i, indId, len);
509 
510     if (i == len) {
511         SendAtCommand(dataConn, OK);
512 
513         dataConn.biaMaskOut_ = biaMaskOut;
514         bool service = !(biaMaskOut & (1 << HFP_AG_INDICATOR_SERVICE));
515         bool roam = !(biaMaskOut & (1 << HFP_AG_INDICATOR_ROAMING_STATE));
516         bool signal = !(biaMaskOut & (1 << HFP_AG_INDICATOR_SIGNAL_STRENGTH));
517         bool battery = !(biaMaskOut & (1 << HFP_AG_INDICATOR_BATTERY_LEVEL));
518 
519         HfpAgTransferData data = {service, roam, signal, battery};
520         HfpAgProfileEventSender::GetInstance().ProcessAtBia(dataConn.remoteAddr_, data);
521     } else {
522         SendErrorCode(dataConn, HFP_AG_ERROR_INVALID_INDEX);
523     }
524 }
525 
BccExecuter(HfpAgDataConnection & dataConn,const std::string & arg)526 void HfpAgCommandProcessor::BccExecuter(HfpAgDataConnection &dataConn, const std::string &arg)
527 {
528     if (HfpAgAudioConnection::GetActiveDevice().compare(dataConn.remoteAddr_) != 0) {
529         SendErrorCode(dataConn, HFP_AG_ERROR_OPERATION_NOT_ALLOWED);
530         HILOGI("[HFP AG] AT+BCC be rejected because activeAddr[%{public}s], remoteAddr[%{public}s]",
531             GetEncryptAddr(HfpAgAudioConnection::GetActiveDevice()).c_str(),
532             GetEncryptAddr(dataConn.remoteAddr_).c_str());
533     } else {
534         SendAtCommand(dataConn, OK);
535         HfpAgProfileEventSender::GetInstance().ProcessAtBcc(dataConn.remoteAddr_);
536     }
537 }
538 
BcsSetter(HfpAgDataConnection & dataConn,const std::string & arg)539 void HfpAgCommandProcessor::BcsSetter(HfpAgDataConnection &dataConn, const std::string &arg)
540 {
541     dataConn.remoteSelectedCodec_ = StoiTryCatch(dataConn, arg);
542     dataConn.codecNegotiating_ = false;
543     if (dataConn.remoteSelectedCodec_ == dataConn.localSelectedCodec_) {
544         dataConn.inUseCodec_ = dataConn.remoteSelectedCodec_;
545         SendAtCommand(dataConn, OK);
546         HfpAgProfileEventSender::GetInstance().ProcessAtBcs(dataConn.remoteAddr_);
547     } else {
548         LOG_ERROR("[HFP AG]%{public}s():Setup code connection failed", __FUNCTION__);
549         SendErrorCode(dataConn, HFP_AG_ERROR_AG_FAILURE);
550     }
551 }
552 
BindGetter(HfpAgDataConnection & dataConn,const std::string & arg)553 void HfpAgCommandProcessor::BindGetter(HfpAgDataConnection &dataConn, const std::string &arg)
554 {
555     std::string cmd;
556     for (auto &indicator : dataConn.localHfIndicators_) {
557         if (indicator.isSupported) {
558             cmd = "+BIND: " + std::to_string(indicator.anum) + "," + std::to_string(indicator.isEnabled);
559             SendAtCommand(dataConn, cmd);
560         }
561     }
562 
563     if (!dataConn.slcConnected_) {
564         dataConn.SetSlcConnectState(true);
565         HfpAgProfileEventSender::GetInstance().UpdateConnectState(dataConn.remoteAddr_, HFP_AG_SLC_ESTABLISHED_EVT);
566     }
567     SendAtCommand(dataConn, OK);
568 }
569 
BindSetter(HfpAgDataConnection & dataConn,const std::string & arg)570 void HfpAgCommandProcessor::BindSetter(HfpAgDataConnection &dataConn, const std::string &arg)
571 {
572     bool isFirst = true;
573     std::string event;
574     std::regex regex("\\,");
575     std::vector<std::string> out(
576         std::sregex_token_iterator(arg.begin(), arg.end(), regex, -1), std::sregex_token_iterator());
577     for (auto &s : out) {
578         HfpAgDataConnection::HfIndicator indicator;
579         indicator.anum = StoiTryCatch(dataConn, s);
580         dataConn.remoteHfIndicators_.push_back(indicator);
581         if (isFirst) {
582             event = event + std::to_string(indicator.anum);
583         } else {
584             event = "," + event + std::to_string(indicator.anum);
585         }
586         isFirst = false;
587     }
588 
589     SendAtCommand(dataConn, OK);
590     HfpAgProfileEventSender::GetInstance().ProcessATBind(dataConn.remoteAddr_, event);
591 }
592 
BindTester(HfpAgDataConnection & dataConn,const std::string & arg)593 void HfpAgCommandProcessor::BindTester(HfpAgDataConnection &dataConn, const std::string &arg)
594 {
595     bool isFirst = true;
596     std::string cmd;
597 
598     for (auto &indicator : dataConn.localHfIndicators_) {
599         if (indicator.isSupported) {
600             if (isFirst) {
601                 cmd = cmd + std::to_string(indicator.anum);
602             } else {
603                 cmd = cmd + "," + std::to_string(indicator.anum);
604             }
605             isFirst = false;
606         }
607     }
608 
609     cmd = "(" + cmd + ")";
610     cmd = "+BIND: " + cmd;
611     SendAtCommand(dataConn, cmd);
612     SendAtCommand(dataConn, OK);
613 }
614 
BievSetter(HfpAgDataConnection & dataConn,const std::string & arg)615 void HfpAgCommandProcessor::BievSetter(HfpAgDataConnection &dataConn, const std::string &arg)
616 {
617     int index;
618     int anumOut;
619     uint16_t anum;
620     uint16_t value;
621     std::regex regex("\\,");
622     std::vector<std::string> out(
623         std::sregex_token_iterator(arg.begin(), arg.end(), regex, -1), std::sregex_token_iterator());
624     if (out.size() != BIEV_ARGS_VALID_LENGTH) {
625         goto INDEX_ERROR;
626     }
627 
628     anumOut = StoiTryCatch(dataConn, out[0]);
629     if (anumOut <= 0 || anumOut > LOCAL_HF_IND_NUM) {
630         goto INDEX_ERROR;
631     } else {
632         anum = anumOut;
633     }
634 
635     for (index = 0; index < static_cast<int>(dataConn.localHfIndicators_.size()); index++) {
636         if (anum == dataConn.localHfIndicators_[index].anum) {
637             break;
638         }
639     }
640 
641     if (index == static_cast<int>(dataConn.localHfIndicators_.size()) ||
642         !dataConn.localHfIndicators_[index].isEnabled || !dataConn.localHfIndicators_[index].isSupported) {
643         goto INDEX_ERROR;
644     }
645 
646     value = StoiTryCatch(dataConn, out[1]);
647     if (value < dataConn.localHfIndicators_[index].minVal || value > dataConn.localHfIndicators_[index].maxVal) {
648         SendErrorCode(dataConn, HFP_AG_ERROR_AG_FAILURE);
649         return;
650     } else {
651         SendAtCommand(dataConn, OK);
652         HfpAgProfileEventSender::GetInstance().SendHfIndicator(dataConn.remoteAddr_, ++index, value);
653         return;
654     }
655 
656 INDEX_ERROR:
657     SendErrorCode(dataConn, HFP_AG_ERROR_INVALID_INDEX);
658     return;
659 }
660 
BacSetter(HfpAgDataConnection & dataConn,const std::string & arg)661 void HfpAgCommandProcessor::BacSetter(HfpAgDataConnection &dataConn, const std::string &arg)
662 {
663     std::regex regex("\\,");
664     std::vector<std::string> out(
665         std::sregex_token_iterator(arg.begin(), arg.end(), regex, -1), std::sregex_token_iterator());
666 
667     int currentRemoteCodec = HFP_AG_CODEC_NONE;
668     for (auto &s : out) {
669         if (s.find("1") != std::string::npos) {
670             currentRemoteCodec |= HFP_AG_CODEC_CVSD;
671         }
672         if (s.find("2") != std::string::npos) {
673             currentRemoteCodec |= HFP_AG_CODEC_MSBC;
674         }
675     }
676 
677     if (currentRemoteCodec != dataConn.remoteSupportCodecs_) {
678         LOG_INFO("[HFP AG]%{public}s():Remote support codecs updated, currentRemoteCodec[%{public}d], "
679             "remoteSupportCodecs_[%{public}d]", __FUNCTION__, currentRemoteCodec, dataConn.remoteSupportCodecs_);
680         dataConn.remoteSupportCodecsUpdated_ = true;
681     }
682     dataConn.remoteSupportCodecs_ = currentRemoteCodec;
683 
684     SendAtCommand(dataConn, OK);
685 
686     // If no AT+BCS is received, but instead an AT+BAC is received after sending +BCS,
687     // the procedure shall end but may be restarted by the AG after re-selecting codec ID
688     // based on the information in the just received AT+BAC.
689     if (dataConn.codecNegotiating_) {
690         LOG_INFO("[HFP AG]%{public}s():Codec negotiation failed", __FUNCTION__);
691         HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(
692             dataConn.remoteAddr_, HFP_AG_CODEC_NEGOTIATION_FAILED);
693     }
694 }
695 
BtrhGetter(HfpAgDataConnection & dataConn,const std::string & arg)696 void HfpAgCommandProcessor::BtrhGetter(HfpAgDataConnection &dataConn, const std::string &arg)
697 {
698     LOG_INFO("[HFP AG]%{public}s():BtrhGetter arg = %{public}s", __FUNCTION__, arg.c_str());
699     HfpAgProfileEventSender::GetInstance().GetResponseHoldState(dataConn.remoteAddr_, HFP_AG_GET_BTRH_EVT);
700 }
701 
BtrhSetter(HfpAgDataConnection & dataConn,const std::string & arg)702 void HfpAgCommandProcessor::BtrhSetter(HfpAgDataConnection &dataConn, const std::string &arg)
703 {
704     LOG_INFO("[HFP AG]%{public}s():BtrhSetter arg = %{public}s", __FUNCTION__, arg.c_str());
705     int btrh = StoiTryCatch(dataConn, arg);
706     HfpAgProfileEventSender::GetInstance().SetResponseHoldState(dataConn.remoteAddr_, HFP_AG_GET_BTRH_EVT, btrh);
707 }
708 
BinpSetter(HfpAgDataConnection & dataConn,const std::string & arg)709 void HfpAgCommandProcessor::BinpSetter(HfpAgDataConnection &dataConn, const std::string &arg)
710 {
711     LOG_INFO("[HFP AG]%{public}s():BinpGetter arg = %{public}s", __FUNCTION__, arg.c_str());
712     HfpAgProfileEventSender::GetInstance().GetVoiceTagNumber(dataConn.remoteAddr_);
713 }
714 
CkpdSetter(HfpAgDataConnection & dataConn,const std::string & arg)715 void HfpAgCommandProcessor::CkpdSetter(HfpAgDataConnection &dataConn, const std::string &arg)
716 {
717     SendAtCommand(dataConn, OK);
718     HfpAgProfileEventSender::GetInstance().ProcessCKpdEvent(dataConn.remoteAddr_);
719 }
720 }  // namespace bluetooth
721 }  // namespace OHOS