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_profile.h"
17 
18 #include "btm.h"
19 #include "hfp_hf_command_processor.h"
20 #include "hfp_hf_defines.h"
21 #include "hfp_hf_profile_event_sender.h"
22 #include "hfp_hf_sdp_server.h"
23 #include "interface_profile.h"
24 #include "power_manager.h"
25 
26 namespace OHOS {
27 namespace bluetooth {
28 #define HFP_HF_RETURN_IF_NOT_CONNECTED(state)                                       \
29     do {                                                                            \
30         if (!state) {                                                               \
31             LOG_ERROR("[HFP HF]%{public}s():SLC connection not established", __FUNCTION__); \
32             return false;                                                           \
33         }                                                                           \
34     } while (0)
35 
36 #define HFP_HF_RETURN_IF_NOT_ENABLED(enable)                              \
37     do {                                                                  \
38         if (!enable) {                                                    \
39             LOG_ERROR("[HFP HF]%{public}s():function not allowed", __FUNCTION__); \
40             return false;                                                 \
41         }                                                                 \
42     } while (0)
43 
44 #define HFP_HF_RETURN_IF_NO_FEATURE(feature, mask)                         \
45     do {                                                                   \
46         if (!(feature & mask)) {                                           \
47             LOG_ERROR("[HFP HF]%{public}s():feature not supported", __FUNCTION__); \
48             return false;                                                  \
49         }                                                                  \
50     } while (0)
51 
52 #define HFP_HF_RETURN_IF_INDICATOR_EQUAL(ind1, ind2)                                                    \
53     do {                                                                                                \
54         if (ind1 == ind2) {                                                                             \
55             LOG_WARN("[HFP HF]%{public}s():Indicator wouldn't be sent for its value not change", __FUNCTION__); \
56             return true;                                                                                \
57         }                                                                                               \
58     } while (0)
59 
RegisterService()60 int HfpHfProfile::RegisterService()
61 {
62     HfpHfDataConnection::Init();
63     HfpHfDataConnectionServer &connectionServer = HfpHfDataConnectionServer::GetInstance();
64     int ret = HfpHfSdpServer::GetInstance().RegisterSdpService(connectionServer.AssignLocalScn());
65     HFP_HF_RETURN_IF_FAIL(ret);
66 
67     BTM_AddLocalRfcommScnForLogging(BTM_HCI_LOG_FILTER_MODULE_HFP, connectionServer.GetLocalScn());
68 
69     ret = connectionServer.RegisterServer();
70     HFP_HF_RETURN_IF_FAIL(ret);
71 
72     ret = HfpHfAudioConnection::Register();
73     HFP_HF_RETURN_IF_FAIL(ret);
74 
75     return ret;
76 }
77 
DeregisterService()78 int HfpHfProfile::DeregisterService()
79 {
80     HfpHfDataConnectionServer &connectionServer = HfpHfDataConnectionServer::GetInstance();
81     int ret = HfpHfSdpServer::GetInstance().DeregisterSdpService();
82     HFP_HF_RETURN_IF_FAIL(ret);
83 
84     BTM_RemoveLocalRfcommScnChannelForLogging(BTM_HCI_LOG_FILTER_MODULE_HFP, connectionServer.GetLocalScn());
85 
86     ret = connectionServer.RemoveServer();
87     HFP_HF_RETURN_IF_FAIL(ret);
88 
89     ret = HfpHfAudioConnection::Deregister();
90     HFP_HF_RETURN_IF_FAIL(ret);
91 
92     HfpHfDataConnection::CleanUp();
93     return ret;
94 }
95 
HfpHfProfile(std::string address)96 HfpHfProfile::HfpHfProfile(std::string address) : address_(address)
97 {
98 }
99 
Init()100 void HfpHfProfile::Init()
101 {
102     dataConn_.SetRemoteAddr(address_);
103     audioConn_.SetRemoteAddr(address_);
104     commandProcessor_.Init(address_);
105 }
106 
DoServiceDiscovery(int role)107 int HfpHfProfile::DoServiceDiscovery(int role)
108 {
109     dataConn_.SetRole(role);
110     return sdpClient_.DoDiscovery(address_, role);
111 }
112 
ServiceDiscoveryResult()113 int HfpHfProfile::ServiceDiscoveryResult()
114 {
115     int role = dataConn_.GetRole();
116     if (!sdpClient_.FindAttributes(address_, role)) {
117         LOG_ERROR("[HFP HF]%{public}s():FindAttributes() error", __FUNCTION__);
118         return HFP_HF_FAILURE;
119     }
120     dataConn_.SetSdpInfo(sdpClient_.GetRemoteSdpInfo());
121     if (HFP_HF_INITIATOR == role) {
122         EstablishDataConnection();
123     }
124     return HFP_HF_SUCCESS;
125 }
126 
EstablishDataConnection()127 int HfpHfProfile::EstablishDataConnection()
128 {
129     RawAddress rawAddr(address_);
130     BtAddr btAddr;
131     rawAddr.ConvertToUint8(btAddr.addr);
132     btAddr.type = BT_PUBLIC_DEVICE_ADDRESS;
133     BTM_AddRemoteRfcommScnForLogging(BTM_HCI_LOG_FILTER_MODULE_HFP, dataConn_.GetRemoteScn(), &btAddr);
134     return dataConn_.Connect();
135 }
136 
ReleaseDataConnection() const137 int HfpHfProfile::ReleaseDataConnection() const
138 {
139     return dataConn_.Disconnect();
140 }
141 
AcceptDataConnection(uint16_t handle)142 int HfpHfProfile::AcceptDataConnection(uint16_t handle)
143 {
144     DoServiceDiscovery(HFP_HF_ACCEPTOR);
145     dataServer_.AcceptConnection(handle);
146     dataConn_.SetConnectionHandle(handle);
147     return HFP_HF_SUCCESS;
148 }
149 
EstablishServiceLevelConnection()150 int HfpHfProfile::EstablishServiceLevelConnection()
151 {
152     commandProcessor_.ConnectSlc(dataConn_);
153     return HFP_HF_SUCCESS;
154 }
155 
ReadData()156 int HfpHfProfile::ReadData()
157 {
158     HfpHfCommandParser::GetInstance().Read(dataConn_, commandProcessor_);
159     return HFP_HF_SUCCESS;
160 }
161 
ProcessSlcEstablished()162 void HfpHfProfile::ProcessSlcEstablished()
163 {
164     IPowerManager::GetInstance().StatusUpdate(RequestStatus::CONNECT_ON, PROFILE_NAME_HFP_HF, RawAddress(address_));
165     if (!QuerySubscriberInfo()) {
166         LOG_ERROR("[HFP HF]%{public}s():can't query the subscriber information!", __FUNCTION__);
167     }
168     dataConn_.SetSlcConnectState(true);
169 }
170 
SetupCodecConnection()171 int HfpHfProfile::SetupCodecConnection()
172 {
173     if (dataConn_.IsCodecNegotiationSupport()) {
174         isCodecSetupInitiator_ = true;
175         SendBcc();
176     } else {
177         dataConn_.inUseCodec_ = HFP_HF_CODEC_CVSD;
178         EstablishAudioConnection();
179     }
180 
181     return HFP_HF_SUCCESS;
182 }
183 
EstablishAudioConnection()184 int HfpHfProfile::EstablishAudioConnection()
185 {
186     audioConn_.SetSupportFeatures(dataConn_.IsEscoSupport(), dataConn_.IsEscoS4Support(), dataConn_.inUseCodec_);
187     audioConn_.ConnectAudio();
188     return HFP_HF_SUCCESS;
189 }
190 
ReleaseAudioConnection() const191 int HfpHfProfile::ReleaseAudioConnection() const
192 {
193     audioConn_.DisconnectAudio();
194     return HFP_HF_SUCCESS;
195 }
196 
AcceptAudioConnection()197 int HfpHfProfile::AcceptAudioConnection()
198 {
199     audioConn_.SetSupportFeatures(dataConn_.IsEscoSupport(), dataConn_.IsEscoS4Support(), dataConn_.inUseCodec_);
200     audioConn_.AcceptAudioConnection();
201     return HFP_HF_SUCCESS;
202 }
203 
RejectAudioConnection() const204 int HfpHfProfile::RejectAudioConnection() const
205 {
206     audioConn_.RejectAudioConnection();
207     return HFP_HF_SUCCESS;
208 }
209 
ProcessAudioConnReqInAudioConnecting()210 int HfpHfProfile::ProcessAudioConnReqInAudioConnecting()
211 {
212     if (isCodecSetupInitiator_ == false) {
213         return HFP_HF_FAILURE;
214     }
215 
216     if (HfpHfAudioConnection::IsAudioConnected() == false) {
217         AcceptAudioConnection();
218     }
219     return HFP_HF_SUCCESS;
220 }
221 
RestorCodecSetupRole()222 int HfpHfProfile::RestorCodecSetupRole()
223 {
224     isCodecSetupInitiator_ = false;
225     return HFP_HF_SUCCESS;
226 }
227 
QueryCurrentCalls()228 bool HfpHfProfile::QueryCurrentCalls()
229 {
230     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
231 
232     std::string cmd("AT+CLCC");
233     commandProcessor_.SendAtCommand(dataConn_, cmd, HfpHfCommandProcessor::AT_CLCC_EXECUTER);
234     return true;
235 }
236 
QueryOperatorName(bool isQuery)237 bool HfpHfProfile::QueryOperatorName(bool isQuery)
238 {
239     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
240 
241     std::string cmd("AT+COPS");
242     int commandId;
243     if (isQuery) {
244         cmd.append("?");
245         commandId = HfpHfCommandProcessor::AT_COPS_GETTER;
246     } else {
247         cmd.append("=3,0");
248         commandId = HfpHfCommandProcessor::AT_COPS_SETTER;
249     }
250     commandProcessor_.SendAtCommand(dataConn_, cmd, commandId);
251     return true;
252 }
253 
QuerySubscriberInfo()254 bool HfpHfProfile::QuerySubscriberInfo()
255 {
256     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
257 
258     std::string cmd("AT+CNUM");
259     commandProcessor_.SendAtCommand(dataConn_, cmd, HfpHfCommandProcessor::AT_CNUM_EXECUTER);
260     return true;
261 }
262 
SendDtmf(uint8_t code)263 bool HfpHfProfile::SendDtmf(uint8_t code)
264 {
265     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
266 
267     std::string cmd("AT+VTS=");
268     cmd += code;
269     commandProcessor_.SendAtCommand(dataConn_, cmd, HfpHfCommandProcessor::AT_VTS_SETTER);
270     return true;
271 }
272 
SetHfVolume(int volume,int type)273 bool HfpHfProfile::SetHfVolume(int volume, int type)
274 {
275     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
276 
277     // Make sure volume is in the range 0-15
278     int value = (volume > 15) ? 15 : volume;
279     value = (value < 0) ? 0 : value;
280 
281     std::string cmd("AT+");
282     int commandId = HfpHfCommandProcessor::AT_COMMAND_NONE;
283     if (type == HFP_HF_VOLUME_TYPE_SPK) {
284         cmd.append("VGS");
285         commandId = HfpHfCommandProcessor::AT_VGS_SETTER;
286     } else if (type == HFP_HF_VOLUME_TYPE_MIC) {
287         cmd.append("VGM");
288         commandId = HfpHfCommandProcessor::AT_VGM_SETTER;
289     } else {
290         LOG_ERROR("[HFP HF]%{public}s():invalid type for volume!", __FUNCTION__);
291         return false;
292     }
293     cmd.append("=" + std::to_string(value));
294     commandProcessor_.SendAtCommand(dataConn_, cmd, commandId);
295     return true;
296 }
297 
OpenVoiceRecognition()298 bool HfpHfProfile::OpenVoiceRecognition()
299 {
300     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
301     HFP_HF_RETURN_IF_NO_FEATURE(dataConn_.remoteFeatures_, HFP_HF_AG_FEATURES_VOICE_RECOGNITION);
302 
303     std::string cmd("AT+BVRA=1");
304     commandProcessor_.SendAtCommand(dataConn_, cmd, HfpHfCommandProcessor::AT_BVRA_1_SETTER);
305     return true;
306 }
307 
CloseVoiceRecognition()308 bool HfpHfProfile::CloseVoiceRecognition()
309 {
310     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
311     HFP_HF_RETURN_IF_NO_FEATURE(dataConn_.remoteFeatures_, HFP_HF_AG_FEATURES_VOICE_RECOGNITION);
312 
313     std::string cmd("AT+BVRA=0");
314     commandProcessor_.SendAtCommand(dataConn_, cmd, HfpHfCommandProcessor::AT_BVRA_0_SETTER);
315     return true;
316 }
317 
DialOutCall(const std::string & number)318 bool HfpHfProfile::DialOutCall(const std::string &number)
319 {
320     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
321 
322     if (number.length() == 0) {
323         LOG_ERROR("[HFP HF]%{public}s():Invalid call number", __FUNCTION__);
324         return false;
325     }
326 
327     std::string cmd("ATD");
328     cmd.append(number + ";");
329     commandProcessor_.SendAtCommand(dataConn_, cmd, HfpHfCommandProcessor::AT_ATD_EXECUTER);
330     return true;
331 }
332 
DialMemory(int memory)333 bool HfpHfProfile::DialMemory(int memory)
334 {
335     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
336 
337     std::string cmd("ATD>");
338     cmd.append(std::to_string(memory) + ";");
339     commandProcessor_.SendAtCommand(dataConn_, cmd, HfpHfCommandProcessor::AT_ATD_EXECUTER);
340     return true;
341 }
342 
SendVoiceTag(int index)343 bool HfpHfProfile::SendVoiceTag(int index)
344 {
345     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
346 
347     std::string cmd("AT+BINP");
348     cmd.append("=" + std::to_string(index));
349     commandProcessor_.SendAtCommand(dataConn_, cmd, HfpHfCommandProcessor::AT_BINP_SETTER);
350     return true;
351 }
352 
SendKeyPressed()353 bool HfpHfProfile::SendKeyPressed()
354 {
355     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
356 
357     std::string cmd("AT+CKPD=200");
358     commandProcessor_.SendAtCommand(dataConn_, cmd, HfpHfCommandProcessor::AT_CKPD_SETTER);
359     return true;
360 }
361 
362 
SendAta()363 bool HfpHfProfile::SendAta()
364 {
365     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
366 
367     std::string cmd("ATA");
368     commandProcessor_.SendAtCommand(dataConn_, cmd, HfpHfCommandProcessor::AT_ATA_EXECUTER);
369     return true;
370 }
371 
SendChld(int action,int idx)372 bool HfpHfProfile::SendChld(int action, int idx)
373 {
374     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
375 
376     std::string cmd("AT+CHLD");
377     cmd.append("=" + std::to_string(action));
378     if (idx > 0) {
379         cmd.append(std::to_string(idx));
380     }
381     commandProcessor_.SendAtCommand(dataConn_, cmd, HfpHfCommandProcessor::AT_CHLD_SETTER);
382     return true;
383 }
384 
SendChup()385 bool HfpHfProfile::SendChup()
386 {
387     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
388 
389     std::string cmd("AT+CHUP");
390     commandProcessor_.SendAtCommand(dataConn_, cmd, HfpHfCommandProcessor::AT_CHUP_EXECUTER);
391     return true;
392 }
393 
SendBtrh(int action)394 bool HfpHfProfile::SendBtrh(int action)
395 {
396     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
397 
398     std::string cmd("AT+BTRH");
399     cmd.append("=" + std::to_string(action));
400     commandProcessor_.SendAtCommand(dataConn_, cmd, HfpHfCommandProcessor::AT_CHLD_SETTER);
401     return true;
402 }
403 
SendBcc()404 bool HfpHfProfile::SendBcc()
405 {
406     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
407 
408     std::string cmd("AT+BCC");
409     commandProcessor_.SendAtCommand(dataConn_, cmd, HfpHfCommandProcessor::AT_BCC_EXECUTER);
410     return true;
411 }
412 
CallLastDialedNumber()413 bool HfpHfProfile::CallLastDialedNumber()
414 {
415     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
416 
417     std::string cmd("AT+BLDN");
418     commandProcessor_.SendAtCommand(dataConn_, cmd, HfpHfCommandProcessor::AT_BLDN_EXECUTER);
419     return true;
420 }
421 
CloseRemoteNrec()422 bool HfpHfProfile::CloseRemoteNrec()
423 {
424     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
425     HFP_HF_RETURN_IF_NO_FEATURE(dataConn_.remoteFeatures_, HFP_HF_AG_FEATURES_ECNR);
426 
427     std::string cmd("AT+NREC=0");
428     commandProcessor_.SendAtCommand(dataConn_, cmd, HfpHfCommandProcessor::AT_NREC_SETTER);
429     return true;
430 }
431 
ReportBatteryLevel(uint32_t battery)432 bool HfpHfProfile::ReportBatteryLevel(uint32_t battery)
433 {
434     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
435     HFP_HF_RETURN_IF_NOT_ENABLED(dataConn_.localHfIndicators_[0].isEnabled);
436     HFP_HF_RETURN_IF_INDICATOR_EQUAL(battery, dataConn_.localHfIndicators_[0].value);
437 
438     dataConn_.localHfIndicators_[0].value = battery;
439     return ReportHfIndicator(HFP_HF_INDICATOR_BATTERY_LEVEL, battery);
440 }
441 
ReportDriverSafety(uint32_t safety)442 bool HfpHfProfile::ReportDriverSafety(uint32_t safety)
443 {
444     HFP_HF_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
445     HFP_HF_RETURN_IF_NOT_ENABLED(dataConn_.localHfIndicators_[1].isEnabled);
446     HFP_HF_RETURN_IF_INDICATOR_EQUAL(safety, dataConn_.localHfIndicators_[1].value);
447 
448     dataConn_.localHfIndicators_[1].value = safety;
449     return ReportHfIndicator(HFP_HF_INDICATOR_DRIVER_SAFETY, safety);
450 }
451 
ReportHfIndicator(int indicator,int value)452 bool HfpHfProfile::ReportHfIndicator(int indicator, int value)
453 {
454     auto it = std::find_if(dataConn_.remoteHfIndicators_.begin(),
455         dataConn_.remoteHfIndicators_.end(),
456         [&](const HfpHfDataConnection::HfIndicator &hfIndicator) {
457             return (hfIndicator.anum == indicator &&
458                 (hfIndicator.isEnabled == false || hfIndicator.isSupported == false));
459         });
460 
461     if (it != dataConn_.remoteHfIndicators_.end()) {
462         LOG_INFO("[HFP HF]%{public}s():Remote device not support/enable indicator[%{public}d]",
463             __FUNCTION__, indicator);
464         return true;
465     }
466 
467     std::string cmd("AT+BIEV=");
468     cmd.append(std::to_string(indicator) + "," + std::to_string(value));
469     commandProcessor_.SendAtCommand(dataConn_, cmd, HfpHfCommandProcessor::AT_BIEV_SETTER);
470     return true;
471 }
472 
RemoveStateMachine()473 void HfpHfProfile::RemoveStateMachine()
474 {
475     commandProcessor_.CleanUp();
476     HfpHfProfileEventSender::GetInstance().RemoveSateMachine(address_);
477 }
478 
SendAtCommand(int cmdId,const std::string & arg)479 void HfpHfProfile::SendAtCommand(int cmdId, const std::string &arg)
480 {
481     switch (cmdId) {
482         case HfpHfCommandProcessor::AT_NREC_SETTER:
483             CloseRemoteNrec();
484             break;
485         case HfpHfCommandProcessor::AT_ATA_EXECUTER:
486             SendAta();
487             break;
488         case HfpHfCommandProcessor::AT_CLCC_EXECUTER:
489             QueryCurrentCalls();
490             break;
491         case HfpHfCommandProcessor::AT_BLDN_EXECUTER:
492             CallLastDialedNumber();
493             break;
494         case HfpHfCommandProcessor::AT_ATD_EXECUTER:
495             DialMemory(std::stoi(arg));
496             break;
497         default:
498             break;
499     }
500 }
501 
ProcessAudioConnectRequest()502 void HfpHfProfile::ProcessAudioConnectRequest()
503 {
504     if (HfpHfAudioConnection::IsAudioConnected()) {
505         RejectAudioConnection();
506     } else {
507         AcceptAudioConnection();
508     }
509 }
510 
RemoveRemoteScnLoging() const511 void HfpHfProfile::RemoveRemoteScnLoging() const
512 {
513     if (dataConn_.GetRole() == HFP_HF_INITIATOR) {
514         RawAddress rawAddr(address_);
515         BtAddr btAddr;
516         rawAddr.ConvertToUint8(btAddr.addr);
517         btAddr.type = BT_PUBLIC_DEVICE_ADDRESS;
518         BTM_RemoveRemoteRfcommScnChannelForLogging(BTM_HCI_LOG_FILTER_MODULE_HFP, dataConn_.GetRemoteScn(), &btAddr);
519     }
520 }
521 }  // namespace bluetooth
522 }  // namespace OHOS
523