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_hf_command_processor.h"
17 
18 #include <regex>
19 
20 #include "adapter_config.h"
21 #include "hfp_hf_profile_event_sender.h"
22 #include "log.h"
23 #include "securec.h"
24 
25 namespace OHOS {
26 namespace bluetooth {
27 std::unordered_map<std::string, HfpHfCommandProcessor::HfpHfAtHandler> HfpHfCommandProcessor::g_atCmdMap = {
28     std::make_pair<std::string, HfpHfAtHandler>("OK", {&HfpHfCommandProcessor::ProcessOK}),
29     std::make_pair<std::string, HfpHfAtHandler>("ERROR", {&HfpHfCommandProcessor::ProcessErrorCmd}),
30     std::make_pair<std::string, HfpHfAtHandler>("+CME ERROR:", {&HfpHfCommandProcessor::ProcessCmeError}),
31     std::make_pair<std::string, HfpHfAtHandler>("RING", {&HfpHfCommandProcessor::ProcessRing}),
32     std::make_pair<std::string, HfpHfAtHandler>("+CLIP:", {&HfpHfCommandProcessor::ProcessClip}),
33     std::make_pair<std::string, HfpHfAtHandler>("+BRSF:", {&HfpHfCommandProcessor::ProcessBrsf}),
34     std::make_pair<std::string, HfpHfAtHandler>("+CIND:", {&HfpHfCommandProcessor::ProcessCind}),
35     std::make_pair<std::string, HfpHfAtHandler>("+CHLD:", {&HfpHfCommandProcessor::ProcessChld}),
36     std::make_pair<std::string, HfpHfAtHandler>("+BIND:", {&HfpHfCommandProcessor::ProcessBind}),
37     std::make_pair<std::string, HfpHfAtHandler>("+CIEV:", {&HfpHfCommandProcessor::ProcessCiev}),
38     std::make_pair<std::string, HfpHfAtHandler>("+CCWA:", {&HfpHfCommandProcessor::ProcessCcwa}),
39     std::make_pair<std::string, HfpHfAtHandler>("+BCS:", {&HfpHfCommandProcessor::ProcessBcs}),
40     std::make_pair<std::string, HfpHfAtHandler>("+CLCC:", {&HfpHfCommandProcessor::ProcessClcc}),
41     std::make_pair<std::string, HfpHfAtHandler>("+BSIR:", {&HfpHfCommandProcessor::ProcessBsir}),
42     std::make_pair<std::string, HfpHfAtHandler>("+BVRA:", {&HfpHfCommandProcessor::ProcessBvra}),
43     std::make_pair<std::string, HfpHfAtHandler>("+CNUM:", {&HfpHfCommandProcessor::ProcessCnum}),
44     std::make_pair<std::string, HfpHfAtHandler>("+VGM:", {&HfpHfCommandProcessor::ProcessVgm}),
45     std::make_pair<std::string, HfpHfAtHandler>("+VGS:", {&HfpHfCommandProcessor::ProcessVgs}),
46     std::make_pair<std::string, HfpHfAtHandler>("+COPS:", {&HfpHfCommandProcessor::ProcessCops}),
47     std::make_pair<std::string, HfpHfAtHandler>("+BTRH:", {&HfpHfCommandProcessor::ProcessBtrh}),
48     std::make_pair<std::string, HfpHfAtHandler>("BUSY", {&HfpHfCommandProcessor::ProcessBusy}),
49     std::make_pair<std::string, HfpHfAtHandler>("DELAYED", {&HfpHfCommandProcessor::ProcessDelayed}),
50     std::make_pair<std::string, HfpHfAtHandler>("NO CARRIER", {&HfpHfCommandProcessor::ProcessNoCarrier}),
51     std::make_pair<std::string, HfpHfAtHandler>("NO ANSWER", {&HfpHfCommandProcessor::ProcessNoAnswer}),
52     std::make_pair<std::string, HfpHfAtHandler>("BLOCKLISTED", {&HfpHfCommandProcessor::ProcessBlocklisted}),
53 };
54 
GetAtCmdMap()55 std::unordered_map<std::string, HfpHfCommandProcessor::HfpHfAtHandler> &HfpHfCommandProcessor::GetAtCmdMap()
56 {
57     return g_atCmdMap;
58 }
59 
StoiTryCatch(const std::string & arg)60 int HfpHfCommandProcessor::StoiTryCatch(const std::string &arg)
61 {
62     try {
63         return std::stoi(arg);
64     } catch (std::exception &e) {
65         LOG_ERROR("[HFP HF]%{public}s():Catch exception %{public}s", __FUNCTION__, e.what());
66         return 0;
67     }
68 }
69 
Init(const std::string & address)70 void HfpHfCommandProcessor::Init(const std::string& address)
71 {
72     this->address_ = address;
73     AdapterConfig::GetInstance()->GetValue(HSP_HS_STATE_SECTION_NAME, HSP_HS_STATE_PROPERY_NAME, hspState_);
74     respTimer_ = std::make_unique<utility::Timer>(std::bind(&HfpHfCommandProcessor::RespondTimeout, this));
75 }
76 
ProcessCommand(HfpHfDataConnection & dataConn,const std::string & cmd,const std::string & arg)77 void HfpHfCommandProcessor::ProcessCommand(
78     HfpHfDataConnection &dataConn, const std::string &cmd, const std::string &arg)
79 {
80     LOG_DEBUG("[HFP HF]%{public}s():command[%{public}s], arg[%{public}s]", __FUNCTION__, cmd.c_str(), arg.c_str());
81 
82     auto it = g_atCmdMap.find(cmd);
83     if (it == g_atCmdMap.end()) {
84         LOG_ERROR("[HFP HF]%{public}s():%{public}s command handler not found", __FUNCTION__, cmd.c_str());
85         return;
86     }
87 
88     auto newArg = arg;
89     newArg.erase(remove_if(newArg.begin(), newArg.end(), isspace), newArg.end());
90 
91     (this->*(it->second.fn))(dataConn, newArg);
92 }
93 
ProcessOK(HfpHfDataConnection & dataConn,const std::string & arg)94 void HfpHfCommandProcessor::ProcessOK(HfpHfDataConnection &dataConn, const std::string &arg)
95 {
96     respTimer_->Stop();
97 
98     if (!dataConn.slcConnected_) {
99         ConnectSlc(dataConn);
100         return;
101     }
102 
103     HfpHfProfileEventSender &sender = HfpHfProfileEventSender::GetInstance();
104     switch (currentCommand_) {
105         case AT_COMMAND_NONE:
106         case AT_BIA_SETTER:
107         case AT_BCC_EXECUTER:
108         case AT_CLIP_SETTER:
109         case AT_BCS_SETTER:
110             break;
111         case AT_CLCC_EXECUTER:
112             sender.CurrentCallsReplyDone(dataConn.remoteAddr_);
113             break;
114         case AT_BVRA_1_SETTER:
115             sender.OpenVoiceRecognitionResult(dataConn.remoteAddr_, HFP_HF_AT_RESULT_OK);
116             break;
117         case AT_BVRA_0_SETTER:
118             sender.CloseVoiceRecognitionResult(dataConn.remoteAddr_, HFP_HF_AT_RESULT_OK);
119             break;
120         default:
121             sender.AtCmdResultReply(dataConn.remoteAddr_, HFP_HF_AT_RESULT_OK, 0);
122             break;
123     }
124 
125     currentCommand_ = AT_COMMAND_NONE;
126     SendQueuedAtCommand(dataConn);
127 }
128 
ProcessCmeError(HfpHfDataConnection & dataConn,const std::string & arg)129 void HfpHfCommandProcessor::ProcessCmeError(HfpHfDataConnection &dataConn, const std::string &arg)
130 {
131     const std::regex baseRegex("[^\\d]");
132     if (!std::regex_search(arg, baseRegex)) {
133         int errorCode = StoiTryCatch(arg);
134         if (errorCode != INVALID_CME_ERROR_CODE) {
135             ProcessErrorCode(dataConn, errorCode);
136         } else {
137             LOG_ERROR("[HFP HF]%{public}s():Invalid error code[%{public}s]", __FUNCTION__, arg.c_str());
138         }
139     } else {
140         LOG_ERROR("[HFP HF]%{public}s():Invalid error code[%{public}s]", __FUNCTION__, arg.c_str());
141     }
142 }
143 
ProcessErrorCmd(HfpHfDataConnection & dataConn,const std::string & arg)144 void HfpHfCommandProcessor::ProcessErrorCmd(HfpHfDataConnection &dataConn, const std::string &arg)
145 {
146     ProcessErrorCode(dataConn, INVALID_CME_ERROR_CODE);
147 }
148 
ProcessErrorCode(HfpHfDataConnection & dataConn,int errorCode)149 void HfpHfCommandProcessor::ProcessErrorCode(HfpHfDataConnection &dataConn, int errorCode)
150 {
151     respTimer_->Stop();
152 
153     if (!dataConn.slcConnected_) {
154         ConnectSlc(dataConn);
155         return;
156     }
157 
158     HfpHfProfileEventSender &sender = HfpHfProfileEventSender::GetInstance();
159     switch (currentCommand_) {
160         case AT_BIA_SETTER:
161         case AT_BCC_EXECUTER:
162         case AT_BCS_SETTER:
163         case AT_CLIP_SETTER:
164             break;
165         default:
166             if (errorCode == INVALID_CME_ERROR_CODE) {
167                 sender.AtCmdResultReply(dataConn.remoteAddr_, HFP_HF_AT_RESULT_ERROR, 0);
168             } else {
169                 sender.AtCmdResultReply(dataConn.remoteAddr_, HFP_HF_AT_RESULT_CME, errorCode);
170             }
171             break;
172     }
173 
174     currentCommand_ = AT_COMMAND_NONE;
175     SendQueuedAtCommand(dataConn);
176 }
177 
ProcessCops(HfpHfDataConnection & dataConn,const std::string & arg)178 void HfpHfCommandProcessor::ProcessCops(HfpHfDataConnection &dataConn, const std::string &arg)
179 {
180     uint8_t mode = 0;
181     char operatorName[OPERATOR_NAME_MAX_LEN] = {0};    // Operator name max length is 16
182 
183     int res = sscanf_s(arg.c_str(), "%hhi,0,\"%16[^\"]\"", &mode, operatorName, sizeof(operatorName));
184     if (res < COPS_ARGS_NUMBER) {
185         LOG_WARN("[HFP HF]%{public}s():Invalid command format arg[%{public}s]", __FUNCTION__, arg.c_str());
186         return;
187     }
188 
189     std::string name = std::string(operatorName);
190     HfpHfProfileEventSender::GetInstance().CurrentOperatorReply(dataConn.remoteAddr_, name);
191 }
192 
ProcessBtrh(HfpHfDataConnection & dataConn,const std::string & arg)193 void HfpHfCommandProcessor::ProcessBtrh(HfpHfDataConnection &dataConn, const std::string &arg)
194 {
195     int response = 0;
196 
197     int res = sscanf_s(arg.c_str(), "%d", &response);
198     if (res < 1) {
199         HILOGE("[HFP HF]ProcessBtrh failed, res:%{public}d, arg:%{public}s", res, arg.c_str());
200         return;
201     }
202 
203     HfpHfProfileEventSender::GetInstance().HoldResultReply(dataConn.remoteAddr_, response);
204 }
205 
ProcessBusy(HfpHfDataConnection & dataConn,const std::string & arg)206 void HfpHfCommandProcessor::ProcessBusy(HfpHfDataConnection &dataConn, const std::string &arg)
207 {
208     HfpHfProfileEventSender::GetInstance().AtCmdResultReply(
209         dataConn.remoteAddr_, HFP_HF_AT_RESULT_BUSY, INVALID_CME_ERROR_CODE);
210 }
211 
ProcessDelayed(HfpHfDataConnection & dataConn,const std::string & arg)212 void HfpHfCommandProcessor::ProcessDelayed(HfpHfDataConnection &dataConn, const std::string &arg)
213 {
214     HfpHfProfileEventSender::GetInstance().AtCmdResultReply(
215         dataConn.remoteAddr_, HFP_HF_AT_RESULT_DELAYED, INVALID_CME_ERROR_CODE);
216 }
217 
ProcessNoCarrier(HfpHfDataConnection & dataConn,const std::string & arg)218 void HfpHfCommandProcessor::ProcessNoCarrier(HfpHfDataConnection &dataConn, const std::string &arg)
219 {
220     HfpHfProfileEventSender::GetInstance().AtCmdResultReply(
221         dataConn.remoteAddr_, HFP_HF_AT_RESULT_NO_CARRIER, INVALID_CME_ERROR_CODE);
222 }
223 
ProcessNoAnswer(HfpHfDataConnection & dataConn,const std::string & arg)224 void HfpHfCommandProcessor::ProcessNoAnswer(HfpHfDataConnection &dataConn, const std::string &arg)
225 {
226     HfpHfProfileEventSender::GetInstance().AtCmdResultReply(
227         dataConn.remoteAddr_, HFP_HF_AT_RESULT_NO_ANSWER, INVALID_CME_ERROR_CODE);
228 }
229 
ProcessBlocklisted(HfpHfDataConnection & dataConn,const std::string & arg)230 void HfpHfCommandProcessor::ProcessBlocklisted(HfpHfDataConnection &dataConn, const std::string &arg)
231 {
232     HfpHfProfileEventSender::GetInstance().AtCmdResultReply(
233         dataConn.remoteAddr_, HFP_HF_AT_RESULT_BLOCKLISTED, INVALID_CME_ERROR_CODE);
234 }
235 
ProcessRing(HfpHfDataConnection & dataConn,const std::string & arg)236 void HfpHfCommandProcessor::ProcessRing(HfpHfDataConnection &dataConn, const std::string &arg)
237 {
238     HfpHfProfileEventSender::GetInstance().RingIndicationNotify(dataConn.remoteAddr_);
239 }
240 
ProcessClip(HfpHfDataConnection & dataConn,const std::string & arg)241 void HfpHfCommandProcessor::ProcessClip(HfpHfDataConnection &dataConn, const std::string &arg)
242 {
243     HfpHfProfileEventSender::GetInstance().Callinglineidentification(dataConn.remoteAddr_, arg);
244 }
245 
ProcessBrsf(HfpHfDataConnection & dataConn,const std::string & arg)246 void HfpHfCommandProcessor::ProcessBrsf(HfpHfDataConnection &dataConn, const std::string &arg)
247 {
248     dataConn.remoteFeatures_ = StoiTryCatch(arg);
249 }
250 
ProcessCindTester(HfpHfDataConnection & dataConn,std::string arg)251 void HfpHfCommandProcessor::ProcessCindTester(HfpHfDataConnection &dataConn, std::string arg)
252 {
253     int offset = 0;
254     uint32_t min = 0;
255     uint32_t max = 0;
256     uint32_t index = 0;
257     char name[INDICATOR_NAME_MAX_LEN] = {0};
258     const char *buf = arg.c_str();
259 
260     for (; ;) {
261         auto res = sscanf_s(buf, "(\"%16[^\"]\",(%u%*[-,]%u))%n", name, sizeof(name), &min, &max, &offset);
262         LOG_DEBUG("[HFP HF]%{public}s():name[%{public}s], min[%u], max[%u], offset[%{public}d], res[%{public}d]",
263             __FUNCTION__, name, min, max, offset, res);
264         if (res != CHLD_TEST_ARGS_NUMBER) {
265             LOG_WARN("[HFP HF]%{public}s():invalid command name[%{public}s], min[%u], max[%u], offset[%{public}d], "
266                 "res[%{public}d]", __FUNCTION__, name, min, max, offset, res);
267             return;
268         }
269 
270         HfpHfDataConnection::AgIndicator indicator {name, ++index, min, max, 0, true};
271         dataConn.remoteAgIndicators_.push_back(indicator);
272 
273         buf += offset;
274         if (*buf != ',') {
275             break;
276         }
277         buf++;
278     }
279 }
280 
ProcessClcc(HfpHfDataConnection & dataConn,const std::string & arg)281 void HfpHfCommandProcessor::ProcessClcc(HfpHfDataConnection &dataConn, const std::string &arg)
282 {
283     uint16_t idx = 0;
284     uint16_t dir = 0;
285     uint16_t status = 0;
286     uint16_t mode = 0;
287     uint16_t mprty = 0;
288     char number[PHONE_NUMBER_MAX_LEN] = {0};
289     uint16_t type = 0;
290     int offset = 0;
291 
292     const char *buf = arg.c_str();
293     int res = sscanf_s(buf, "%hu,%hu,%hu,%hu,%hu%n", &idx, &dir, &status, &mode, &mprty, &offset);
294     if (res < CLCC_ARGS_NUMBER || offset == 0) {
295         LOG_WARN("[HFP HF]%{public}s():Invalid command format arg[%{public}s]", __FUNCTION__, arg.c_str());
296         return;
297     }
298 
299     buf += offset;
300     offset = 0;
301 
302     /* check number and type */
303     if (*buf == ',') {
304         int res2 = sscanf_s(buf, ",\"%32[^\"]\",%hu%n", number, sizeof(number), &type, &offset);
305         if (res2 < 0) {
306             return;
307         }
308 
309         if (res2 == 0) {
310             res2 = sscanf_s(buf, ",\"\",%hu%n", &type, &offset);
311             if (res2 < 0) {
312                 return;
313             }
314 
315             /* number match failed */
316             res2++;
317             number[0] = '\0';
318         }
319 
320         if (res2 >= CHLD_SUB_ARGS_NUMBER) {
321             res += res2;
322             if (offset == 0) {
323                 LOG_WARN("[HFP HF]%{public}s():Invalid command format arg[%{public}s]", __FUNCTION__, arg.c_str());
324                 return;
325             }
326         }
327     }
328 
329     HfpHfCurrentCallData callData {idx, dir, status, mode, mprty, "", 0};
330     if (res > CLCC_ARGS_NUMBER + 1) {
331         callData.number = number;
332         callData.type = type;
333     }
334     HfpHfProfileEventSender::GetInstance().CurrentCallsReply(dataConn.remoteAddr_, callData);
335 }
336 
ProcessBsir(HfpHfDataConnection & dataConn,const std::string & arg)337 void HfpHfCommandProcessor::ProcessBsir(HfpHfDataConnection &dataConn, const std::string &arg)
338 {
339     int inBand = (arg.length() == 1) ? StoiTryCatch(arg) : 0;
340     HfpHfProfileEventSender::GetInstance().SetInBandRing(dataConn.remoteAddr_, inBand, false);
341 }
342 
ProcessBvra(HfpHfDataConnection & dataConn,const std::string & arg)343 void HfpHfCommandProcessor::ProcessBvra(HfpHfDataConnection &dataConn, const std::string &arg)
344 {
345     int bvra = (arg.length() == 1) ? StoiTryCatch(arg) : 0;
346     HfpHfProfileEventSender::GetInstance().VoiceRecognitionChanged(dataConn.remoteAddr_, bvra);
347 }
348 
ProcessCnum(HfpHfDataConnection & dataConn,const std::string & arg)349 void HfpHfCommandProcessor::ProcessCnum(HfpHfDataConnection &dataConn, const std::string &arg)
350 {
351     char number[PHONE_NUMBER_MAX_LEN] = {0};
352     uint16_t type;
353     // Indicates which service this phone number relates to. Shall be either 4 (voice) or 5 (fax).
354     uint16_t service = 0;
355 
356     int res = sscanf_s(arg.c_str(), ",\"%32[^\"]\",%hu,,%hu", number, sizeof(number), &type, &service);
357     if (res < CNUM_ARGS_NUMBER) {
358         LOG_WARN("[HFP HF]%{public}s():Invalid command format arg[%{public}s]", __FUNCTION__, arg.c_str());
359         return;
360     }
361 
362     HfpHfProfileEventSender::GetInstance().SubscriberNumberReply(dataConn.remoteAddr_, number, type);
363 }
364 
ProcessCindGetter(HfpHfDataConnection & dataConn,std::string arg)365 void HfpHfCommandProcessor::ProcessCindGetter(HfpHfDataConnection &dataConn, std::string arg)
366 {
367     size_t index = 0;
368     uint32_t value = 0;
369     int offset = 0;
370     const char *buf = arg.c_str();
371 
372     for (; ;) {
373         auto res = sscanf_s(buf, "%u%n", &value, &offset);
374         if (res != 1) {
375             LOG_WARN("[HFP HF]%{public}s():invalid command buf[%{public}s]", __FUNCTION__, buf);
376             return;
377         }
378 
379         auto size = dataConn.remoteAgIndicators_.size();
380         if (index < size) {
381             if ((value >= dataConn.remoteAgIndicators_[index].minVal) &&
382                 (value <= dataConn.remoteAgIndicators_[index].maxVal)) {
383                 dataConn.remoteAgIndicators_[index].value = value;
384             } else {
385                 dataConn.remoteAgIndicators_[index].value = dataConn.remoteAgIndicators_[index].minVal;
386             }
387         }
388 
389         buf += offset;
390         if (*buf != ',') {
391             break;
392         }
393 
394         index++;
395         buf++;
396     }
397 
398     for (auto it = dataConn.remoteAgIndicators_.begin(); it != dataConn.remoteAgIndicators_.end(); ++it) {
399         ProcessIndicator(dataConn, *it, it->value);
400     }
401 }
402 
ProcessCind(HfpHfDataConnection & dataConn,const std::string & arg)403 void HfpHfCommandProcessor::ProcessCind(HfpHfDataConnection &dataConn, const std::string &arg)
404 {
405     if (arg.at(0) == '(') {
406         // List items
407         ProcessCindTester(dataConn, arg);
408     } else {
409         // Get values
410         ProcessCindGetter(dataConn, arg);
411     }
412 }
413 
ProcessChld(HfpHfDataConnection & dataConn,const std::string & arg)414 void HfpHfCommandProcessor::ProcessChld(HfpHfDataConnection &dataConn, const std::string &arg)
415 {
416     if (arg.length() < CHLD_ARGS_MIN_LENGTH) {
417         LOG_WARN("[HFP HF]%{public}s():Invalid Chld command [%{public}s] from Ag!", __FUNCTION__, arg.c_str());
418     }
419 
420     std::string tmpStr = arg.substr(1, arg.length() - (CHLD_ARGS_MIN_LENGTH - 1));
421     std::regex regex("\\,");
422     std::vector<std::string> out(
423         std::sregex_token_iterator(tmpStr.begin(), tmpStr.end(), regex, -1), std::sregex_token_iterator());
424     for (auto s = out.begin(); s != out.end(); s++) {
425         if (*s == "0") {
426             dataConn.remoteChldFeatures_ |= CHLD_RELEASE_ALL;
427         } else if (*s == "1") {
428             dataConn.remoteChldFeatures_ |= CHLD_RELEASE_ALL_AND_ACCPET;
429         } else if (*s == "1x") {
430             dataConn.remoteChldFeatures_ |= CHLD_RELEASE_SPECIFIC;
431         } else if (*s == "2") {
432             dataConn.remoteChldFeatures_ |= CHLD_HOLD_ALL_AND_ACCPET;
433         } else if (*s == "2x") {
434             dataConn.remoteChldFeatures_ |= CHLD_HOLD_ALL_AND_PRIVATE;
435         } else if (*s == "3") {
436             dataConn.remoteChldFeatures_ |= CHLD_MERGE;
437         } else if (*s == "4") {
438             dataConn.remoteChldFeatures_ |= CHLD_EXPLICT_CALL_TRANSFER;
439         } else {
440             LOG_DEBUG("[HFP HF]%{public}s():Invalid Chld command [%{public}s] from Ag!", __FUNCTION__, (*s).c_str());
441         }
442     }
443 }
444 
ProcessListHfIndicators(HfpHfDataConnection & dataConn,const std::string & arg)445 void HfpHfCommandProcessor::ProcessListHfIndicators(
446     HfpHfDataConnection &dataConn, const std::string &arg)
447 {
448     char anums[HF_INDICATOR_MAX] = {0};  // assume peer device support 20 hf indicators at most.
449 
450     int res = sscanf_s(arg.c_str(), "(%20[^)]", anums, sizeof(anums));
451     if (res < 1) {
452         LOG_WARN("[HFP HF]%{public}s():invalid command arg[%{public}s]", __FUNCTION__, arg.c_str());
453     }
454 
455     std::string tmpStr = anums;
456     std::regex regex("\\,");
457     std::vector<std::string> out(
458         std::sregex_token_iterator(tmpStr.begin(), tmpStr.end(), regex, -1), std::sregex_token_iterator());
459     for (auto &s : out) {
460         bool isExist = false;
461         uint16_t anum = StoiTryCatch(s);
462 
463         auto it = std::find_if(dataConn.remoteHfIndicators_.begin(),
464             dataConn.remoteHfIndicators_.end(),
465             [&anum](const HfpHfDataConnection::HfIndicator &indicator) {
466                 return indicator.anum == anum;
467             });
468 
469         if (it != dataConn.remoteHfIndicators_.end()) {
470             isExist = true;
471         }
472 
473         if (!isExist) {
474             HfpHfDataConnection::HfIndicator hfIndicator = {anum, 0, 0, 0, true, true};
475             dataConn.remoteHfIndicators_.push_back(hfIndicator);
476         }
477     }
478 }
479 
ProcessChangeIndicatorState(HfpHfDataConnection & dataConn,const std::string & arg)480 void HfpHfCommandProcessor::ProcessChangeIndicatorState(
481     HfpHfDataConnection &dataConn, const std::string &arg)
482 {
483     uint16_t anum = 0;
484     uint16_t value = 0;
485 
486     int res = sscanf_s(arg.c_str(), "%hu,%hu", &anum, &value);
487     if (res != BIND_SET_ARGS_NUMBER) {
488         LOG_WARN("[HFP HF]%{public}s():invalid command arg[%{public}s]", __FUNCTION__, arg.c_str());
489     }
490 
491     for (auto &indicator : dataConn.remoteHfIndicators_) {
492         if (indicator.anum == anum) {
493             if (indicator.isEnabled == false && value == 1) {
494                 std::string cmd = "AT+BIEV=" + std::to_string(anum) + "," +
495                                   std::to_string(dataConn.localHfIndicators_[anum - 1].value);
496                 SendAtCommand(dataConn, cmd, HfpHfCommandProcessor::AT_BIEV_SETTER);
497             }
498             indicator.isEnabled = value;
499         }
500     }
501 }
502 
ProcessBind(HfpHfDataConnection & dataConn,const std::string & arg)503 void HfpHfCommandProcessor::ProcessBind(HfpHfDataConnection &dataConn, const std::string &arg)
504 {
505     if (arg.length() >= 1 && arg[0] == '(') {
506         // List hf indicators
507         ProcessListHfIndicators(dataConn, arg);
508     } else {
509         // Enable/Disable hf indicator
510         ProcessChangeIndicatorState(dataConn, arg);
511     }
512 }
513 
ProcessIndicator(HfpHfDataConnection & dataConn,HfpHfDataConnection::AgIndicator & it,uint32_t value)514 void HfpHfCommandProcessor::ProcessIndicator(
515     HfpHfDataConnection &dataConn, HfpHfDataConnection::AgIndicator &it, uint32_t value)
516 {
517     HfpHfProfileEventSender &sender = HfpHfProfileEventSender::GetInstance();
518 
519     if ((value >= it.minVal) && (value <= it.maxVal)) {
520         auto valueOrgi = it.value;
521         it.value = value;
522         if (it.name == "service") {
523             sender.NetworkStateChanged(dataConn.remoteAddr_, value);
524         } else if (it.name == "call") {
525             sender.CallStateNotify(dataConn.remoteAddr_, value);
526         } else if (it.name == "callsetup") {
527             sender.CallSetupStateNotify(dataConn.remoteAddr_, value);
528         } else if (it.name == "callheld") {
529             sender.CallHeldStateNotify(dataConn.remoteAddr_, value);
530         } else if (it.name == "signal") {
531             sender.NetworkSignalChanged(dataConn.remoteAddr_, value);
532         } else if (it.name == "roam") {
533             sender.NetworkRoamingChanged(dataConn.remoteAddr_, value);
534         } else if (it.name == "battchg") {
535             sender.BatteryLevelChanged(dataConn.remoteAddr_, value);
536         } else {
537             it.value = valueOrgi;
538             LOG_WARN("[HFP HF]%{public}s():Invalid indicator name [%{public}s]", __FUNCTION__, it.name.c_str());
539         }
540     } else {
541         LOG_WARN("[HFP HF]%{public}s():Indicator value is not valid indicator[%{public}s], value[%u]",
542             __FUNCTION__,
543             it.name.c_str(),
544             value);
545     }
546 }
547 
ProcessCiev(HfpHfDataConnection & dataConn,const std::string & arg)548 void HfpHfCommandProcessor::ProcessCiev(HfpHfDataConnection &dataConn, const std::string &arg)
549 {
550     uint32_t index = 0;
551     uint32_t value = 0;
552 
553     int res = sscanf_s(arg.c_str(), "%u,%u", &index, &value);
554     if (res < CIEV_ARGS_NUMBER) {
555         LOG_WARN("[HFP HF]%{public}s():invalid command arg[%{public}s]", __FUNCTION__, arg.c_str());
556     }
557 
558     auto it = std::find_if(dataConn.remoteAgIndicators_.begin(),
559         dataConn.remoteAgIndicators_.end(),
560         [&index](const HfpHfDataConnection::AgIndicator &indicator) {
561             return indicator.index == index;
562         });
563 
564     if (it != dataConn.remoteAgIndicators_.end()) {
565         ProcessIndicator(dataConn, *it, value);
566     }
567 }
568 
ProcessCcwa(HfpHfDataConnection & dataConn,const std::string & arg)569 void HfpHfCommandProcessor::ProcessCcwa(HfpHfDataConnection &dataConn, const std::string &arg)
570 {
571     char number[PHONE_NUMBER_MAX_LEN] = {0};
572     uint32_t type = 0;
573 
574     int res = sscanf_s(arg.c_str(), "\"%32[^\"]\",%u", number, sizeof(number), &type);
575     if (res < CCWA_ARGS_NUMBER) {
576         LOG_WARN("[HFP HF]%{public}s():invalid command format arg[%{public}s]", __FUNCTION__, arg.c_str());
577         return;
578     }
579 
580     HfpHfProfileEventSender::GetInstance().CallWaitingNotify(dataConn.remoteAddr_, std::string(number));
581 }
582 
ProcessVgm(HfpHfDataConnection & dataConn,const std::string & arg)583 void HfpHfCommandProcessor::ProcessVgm(HfpHfDataConnection &dataConn, const std::string &arg)
584 {
585     int val = StoiTryCatch(arg);
586     HfpHfProfileEventSender::GetInstance().SetVolume(dataConn.remoteAddr_, HFP_HF_VOLUME_TYPE_MIC, val);
587 }
588 
ProcessVgs(HfpHfDataConnection & dataConn,const std::string & arg)589 void HfpHfCommandProcessor::ProcessVgs(HfpHfDataConnection &dataConn, const std::string &arg)
590 {
591     int val = StoiTryCatch(arg);
592     HfpHfProfileEventSender::GetInstance().SetVolume(dataConn.remoteAddr_, HFP_HF_VOLUME_TYPE_SPK, val);
593 }
594 
ProcessSlcBrsf(HfpHfDataConnection & dataConn)595 void HfpHfCommandProcessor::ProcessSlcBrsf(HfpHfDataConnection &dataConn)
596 {
597     if ((dataConn.g_localFeatures & HFP_HF_FEATURES_CODEC_NEGOTIATION) &&
598         (dataConn.remoteFeatures_ & HFP_HF_AG_FEATURES_CODEC_NEGOTIATION)) {
599         SendAtBacSetter(dataConn);
600     } else {
601         SendAtCindTester(dataConn);
602     }
603 }
ProcessSlcCmer(HfpHfDataConnection & dataConn)604 void HfpHfCommandProcessor::ProcessSlcCmer(HfpHfDataConnection &dataConn)
605 {
606     if ((dataConn.g_localFeatures & HFP_HF_FEATURES_THREE_WAY) &&
607         (dataConn.remoteFeatures_ & HFP_HF_AG_FEATURES_THREE_WAY)) {
608         SendAtChldTester(dataConn);
609     } else {
610         ProcessSlcConnected(dataConn);
611     }
612 }
ProcessSlcChld(HfpHfDataConnection & dataConn)613 void HfpHfCommandProcessor::ProcessSlcChld(HfpHfDataConnection &dataConn)
614 {
615     if ((dataConn.g_localFeatures & HFP_HF_FEATURES_HF_INDICATORS) &&
616         (dataConn.remoteFeatures_ & HFP_HF_AG_FEATURES_HF_INDICATORS)) {
617         SendAtBindSetter(dataConn);
618     } else {
619         ProcessSlcConnected(dataConn);
620     }
621 }
622 
ProcessSlcConnected(HfpHfDataConnection & dataConn)623 void HfpHfCommandProcessor::ProcessSlcConnected(HfpHfDataConnection &dataConn)
624 {
625     HfpHfProfileEventSender &sender = HfpHfProfileEventSender::GetInstance();
626     dataConn.SetSlcConnectState(true);
627     sender.UpdateConnectState(dataConn.remoteAddr_, HFP_HF_SLC_ESTABLISHED_EVT);
628     currentCommand_ = AT_COMMAND_NONE;
629 
630     if (dataConn.remoteFeatures_ & HFP_HF_AG_FEATURES_IN_BAND_RING) {
631         sender.SetInBandRing(dataConn.remoteAddr_, 1, true);
632     }
633 
634     SendAtCommand(dataConn, "AT+COPS=3,0", HfpHfCommandProcessor::AT_COPS_SETTER);
635     SendAtBiaSetter(dataConn);
636     SendAtCommand(dataConn, "AT+CLIP=1", HfpHfCommandProcessor::AT_CLIP_SETTER);
637     SendAtCommand(dataConn, "AT+CCWA=1", HfpHfCommandProcessor::AT_CCWA_SETTER);
638     SendAtCommand(dataConn, "AT+CMEE=1", HfpHfCommandProcessor::AT_CCME_SETTER);
639 
640     LOG_DEBUG("[HFP HF]%{public}s():Service level connection established!!!", __FUNCTION__);
641 }
642 
ConnectSlc(HfpHfDataConnection & dataConn)643 void HfpHfCommandProcessor::ConnectSlc(HfpHfDataConnection &dataConn)
644 {
645     if (dataConn.slcConnected_) {
646         LOG_WARN("[HFP HF]%{public}s():Service level Connection already connected!!!", __FUNCTION__);
647         return;
648     }
649 
650     LOG_DEBUG("[HFP HF]%{public}s():currentCommand_[%{public}d]", __FUNCTION__, currentCommand_);
651     switch (currentCommand_) {
652         case AT_COMMAND_NONE:
653             SendAtBrsfSetter(dataConn);
654             break;
655         case AT_BRSF_SETTER:
656             ProcessSlcBrsf(dataConn);
657             break;
658         case AT_BAC_SETTER:
659             SendAtCindTester(dataConn);
660             break;
661         case AT_CIND_TESTER:
662             SendAtCindGetter(dataConn);
663             break;
664         case AT_CIND_GETTER:
665             SendAtCmerSetter(dataConn);
666             break;
667         case AT_CMER_EXECUTER:
668             ProcessSlcCmer(dataConn);
669             break;
670         case AT_CHLD_TESTER:
671             ProcessSlcChld(dataConn);
672             break;
673         case AT_BIND_SETTER:
674             SendAtBindTester(dataConn);
675             break;
676         case AT_BIND_TESTER:
677             SendAtBindGetter(dataConn);
678             break;
679         case AT_BIND_GETTER:
680             ProcessSlcConnected(dataConn);
681             break;
682         default:
683             LOG_ERROR("[HFP HF]%{public}s():invalid commandId[%{public}d] in slc connection command",
684                 __FUNCTION__, currentCommand_);
685             HfpHfProfileEventSender::GetInstance().UpdateConnectState(dataConn.remoteAddr_, HFP_HF_DISCONNECT_EVT);
686             break;
687     }
688 }
689 
ProcessBcs(HfpHfDataConnection & dataConn,const std::string & arg)690 void HfpHfCommandProcessor::ProcessBcs(HfpHfDataConnection &dataConn, const std::string &arg)
691 {
692     dataConn.remoteSelectedCodec_ = StoiTryCatch(arg);
693     if (dataConn.remoteSelectedCodec_ & dataConn.g_localSupportCodecs) {
694         dataConn.inUseCodec_ = dataConn.remoteSelectedCodec_;
695         SendAtCommand(dataConn, "AT+BCS=" + arg, AT_BCS_SETTER);
696     } else {
697         /* Hfp profile 4.11.3
698          The AG shall always respond with OK if the ID received in AT+BCS is the same as the one sent,
699          and with ERROR otherwise. If no AT+BCS is received, but instead an AT+BAC is received after sending +BCS,
700          the procedure shall end but may be restarted by the AG after re-selecting codec ID based on the information
701          in the just received AT+BAC. */
702         SendAtBacSetter(dataConn);
703         LOG_ERROR("[HFP HF]%{public}s():Setup code connection failed, send BAC again!", __FUNCTION__);
704     }
705 }
706 
SendAtBrsfSetter(HfpHfDataConnection & dataConn)707 void HfpHfCommandProcessor::SendAtBrsfSetter(HfpHfDataConnection &dataConn)
708 {
709     LOG_DEBUG("[HFP HF]%{public}s()", __FUNCTION__);
710     std::string cmd = "AT+BRSF=" + std::to_string(dataConn.g_localFeatures);
711     SendAtCommand(dataConn, cmd, AT_BRSF_SETTER);
712 }
713 
SendAtBacSetter(HfpHfDataConnection & dataConn)714 void HfpHfCommandProcessor::SendAtBacSetter(HfpHfDataConnection &dataConn)
715 {
716     LOG_DEBUG("[HFP HF]%{public}s()", __FUNCTION__);
717     std::string cmd = "AT+BAC=";
718     if (dataConn.g_localFeatures & HFP_HF_FEATURES_CODEC_NEGOTIATION) {
719         cmd = cmd + "1,2";
720     } else {
721         cmd = cmd + "1";
722     }
723     SendAtCommand(dataConn, cmd, AT_BAC_SETTER);
724 }
725 
SendAtCindTester(HfpHfDataConnection & dataConn)726 void HfpHfCommandProcessor::SendAtCindTester(HfpHfDataConnection &dataConn)
727 {
728     LOG_DEBUG("[HFP HF]%{public}s()", __FUNCTION__);
729     std::string cmd = "AT+CIND=?";
730     SendAtCommand(dataConn, cmd, AT_CIND_TESTER);
731 }
732 
SendAtCindGetter(HfpHfDataConnection & dataConn)733 void HfpHfCommandProcessor::SendAtCindGetter(HfpHfDataConnection &dataConn)
734 {
735     LOG_DEBUG("[HFP HF]%{public}s()", __FUNCTION__);
736     std::string cmd = "AT+CIND?";
737     SendAtCommand(dataConn, cmd, AT_CIND_GETTER);
738 }
739 
SendAtCmerSetter(HfpHfDataConnection & dataConn)740 void HfpHfCommandProcessor::SendAtCmerSetter(HfpHfDataConnection &dataConn)
741 {
742     LOG_DEBUG("[HFP HF]%{public}s()", __FUNCTION__);
743     std::string cmd = "AT+CMER=3,0,0,1";
744     SendAtCommand(dataConn, cmd, AT_CMER_EXECUTER);
745 }
746 
SendAtChldTester(HfpHfDataConnection & dataConn)747 void HfpHfCommandProcessor::SendAtChldTester(HfpHfDataConnection &dataConn)
748 {
749     LOG_DEBUG("[HFP HF]%{public}s()", __FUNCTION__);
750     std::string cmd = "AT+CHLD=?";
751     SendAtCommand(dataConn, cmd, AT_CHLD_TESTER);
752 }
753 
SendAtBindSetter(HfpHfDataConnection & dataConn)754 void HfpHfCommandProcessor::SendAtBindSetter(HfpHfDataConnection &dataConn)
755 {
756     LOG_DEBUG("[HFP HF]%{public}s()", __FUNCTION__);
757     std::string cmd = "AT+BIND=" + HfpHfDataConnection::BIND_SETTINGS;
758     SendAtCommand(dataConn, cmd, AT_BIND_SETTER);
759 }
760 
SendAtBindGetter(HfpHfDataConnection & dataConn)761 void HfpHfCommandProcessor::SendAtBindGetter(HfpHfDataConnection &dataConn)
762 {
763     LOG_DEBUG("[HFP HF]%{public}s()", __FUNCTION__);
764     std::string cmd = "AT+BIND?";
765     SendAtCommand(dataConn, cmd, AT_BIND_GETTER);
766 }
767 
SendAtBiaSetter(HfpHfDataConnection & dataConn)768 void HfpHfCommandProcessor::SendAtBiaSetter(HfpHfDataConnection &dataConn)
769 {
770     LOG_DEBUG("[HFP HF]%{public}s()", __FUNCTION__);
771 
772     std::string cmd("AT+BIA=");
773     auto size = dataConn.remoteAgIndicators_.size();
774     for (size_t i = 0; i < size; i++) {
775         auto it = std::find_if(dataConn.remoteAgIndicators_.begin(),
776             dataConn.remoteAgIndicators_.end(),
777             [&i](const HfpHfDataConnection::AgIndicator &indicator) {
778                 return i == indicator.index;
779             });
780 
781         int value = 0;
782         if (it != dataConn.remoteAgIndicators_.end()) {
783             value = it->isEnabled ? 1 : 0;
784         }
785 
786         if (i < size - 1) {
787             cmd.append(std::to_string(value) + ",");
788         } else {
789             cmd.append(std::to_string(value));
790         }
791     }
792     SendAtCommand(dataConn, cmd, HfpHfCommandProcessor::AT_BIA_SETTER);
793 }
794 
SendAtBindTester(HfpHfDataConnection & dataConn)795 void HfpHfCommandProcessor::SendAtBindTester(HfpHfDataConnection &dataConn)
796 {
797     LOG_DEBUG("[HFP HF]%{public}s()", __FUNCTION__);
798     std::string cmd = "AT+BIND=?";
799     SendAtCommand(dataConn, cmd, AT_BIND_TESTER);
800 }
801 
RespondTimeout()802 void HfpHfCommandProcessor::RespondTimeout()
803 {
804     LOG_DEBUG("[HFP HF]%{public}s()", __FUNCTION__);
805     if (hspState_ == HSP_HS_STATE_HSP) {
806         LOG_INFO("[HFP HF] hsp only remove time out");
807         return;
808     }
809     HfpHfProfileEventSender& instance = HfpHfProfileEventSender::GetInstance();
810     instance.GetDispatchter()->PostTask(
811         std::bind(&HfpHfProfileEventSender::UpdateConnectState, &instance, address_, HFP_HF_DISCONNECT_EVT));
812 }
813 
SendAtCommand(HfpHfDataConnection & dataConn,const std::string & command,int commandId)814 void HfpHfCommandProcessor::SendAtCommand(
815     HfpHfDataConnection &dataConn, const std::string &command, int commandId)
816 {
817     std::string fullCommand(command + "\r");
818     if (currentCommand_ == AT_COMMAND_NONE || !dataConn.slcConnected_ || (hspState_ == HSP_HS_STATE_HSP)) {
819         LOG_DEBUG("[HFP HF]%{public}s(): commandId[%{public}d], command[%{public}s]",
820             __FUNCTION__, commandId, command.c_str());
821         currentCommand_ = commandId;
822         std::size_t cmdLength = fullCommand.length();
823         Packet *packet = PacketMalloc(0, 0, cmdLength);
824         Buffer *buf = PacketContinuousPayload(packet);
825         void *data = BufferPtr(buf);
826         if (memcpy_s(data, cmdLength, fullCommand.c_str(), cmdLength) != EOK) {
827             LOG_DEBUG("[HFP HF]%{public}s(): memcpy_s fail", __FUNCTION__);
828             return;
829         }
830         dataConn.WriteData(*packet);
831         PacketFree(packet);
832         respTimer_->Start(RESPOND_TIMEOUT_MS, false);
833     } else {
834         commandQueue_.push(std::make_tuple(command, commandId));
835     }
836 }
837 
SendQueuedAtCommand(HfpHfDataConnection & dataConn)838 void HfpHfCommandProcessor::SendQueuedAtCommand(HfpHfDataConnection &dataConn)
839 {
840     if (commandQueue_.size() == 0) {
841         return;
842     }
843 
844     auto command = commandQueue_.front();
845     commandQueue_.pop();
846     LOG_DEBUG(
847         "[HFP HF]%{public}s() commandId[%{public}d], command[%{public}s]",
848             __FUNCTION__, std::get<1>(command), std::get<0>(command).c_str());
849     SendAtCommand(dataConn, std::get<0>(command), std::get<1>(command));
850 }
851 
CleanUp()852 void HfpHfCommandProcessor::CleanUp()
853 {
854     respTimer_->Stop();
855     commandQueue_ = {};
856     currentCommand_ = AT_COMMAND_NONE;
857 }
858 }  // namespace bluetooth
859 }  // namespace OHOS