1 /*
2  * Copyright (C) 2021-2022 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_profile.h"
17 
18 #include "btm.h"
19 #include "hfp_ag_command_processor.h"
20 #include "hfp_ag_defines.h"
21 #include "hfp_ag_profile_event_sender.h"
22 #include "hfp_ag_sdp_server.h"
23 #include "interface_profile.h"
24 #include "power_manager.h"
25 
26 namespace OHOS {
27 namespace bluetooth {
28 #define HFP_AG_RETURN_IF_NOT_CONNECTED(state)                                       \
29     do {                                                                            \
30         if (!state) {                                                               \
31             LOG_ERROR("[HFP AG]%{public}s():SLC connection not established", __FUNCTION__); \
32             return HFP_AG_FAILURE;                                                  \
33         }                                                                           \
34     } while (0)
35 
36 #define HFP_AG_RETURN_IF_NOT_ENABLED(enable)                                 \
37     do {                                                                  \
38         if (!enable) {                                                    \
39             LOG_ERROR("[HFP AG]%{public}s():function not allowed", __FUNCTION__); \
40             return HFP_AG_FAILURE;                                        \
41         }                                                                 \
42     } while (0)
43 
44 #define HFP_AG_RETURN_IF_NO_FEATURE(feature, mask)                         \
45     do {                                                                   \
46         if (!(feature & mask)) {                                           \
47             LOG_ERROR("[HFP AG]%{public}s():feature not supported", __FUNCTION__); \
48             return HFP_AG_FAILURE;                                         \
49         }                                                                  \
50     } while (0)
51 
52 #define HFP_AG_RETURN_IF_INDICATOR_EQUAL(ind1, ind2)                                                    \
53     do {                                                                                                \
54         if (ind1 == ind2) {                                                                             \
55             LOG_WARN("[HFP AG]%{public}s():Indicator wouldn't be sent for its value not change", __FUNCTION__); \
56             return HFP_AG_SUCCESS;                                                                      \
57         }                                                                                               \
58     } while (0)
59 
RegisterService()60 int HfpAgProfile::RegisterService()
61 {
62     HfpAgDataConnection::Init();
63 
64     HfpAgDataConnectionServer &connectionServer = HfpAgDataConnectionServer::GetInstance();
65     int ret = HfpAgSdpServer::GetInstance().RegisterSdpService(connectionServer.AssignLocalScn());
66     HFP_AG_RETURN_IF_FAIL(ret);
67 
68     BTM_AddLocalRfcommScnForLogging(BTM_HCI_LOG_FILTER_MODULE_HFP, connectionServer.GetLocalScn());
69 
70     ret = connectionServer.RegisterServer();
71     HFP_AG_RETURN_IF_FAIL(ret);
72 
73     ret = HfpAgAudioConnection::Register();
74     HFP_AG_RETURN_IF_FAIL(ret);
75 
76     return ret;
77 }
78 
DeregisterService()79 int HfpAgProfile::DeregisterService()
80 {
81     HfpAgDataConnectionServer &connectionServer = HfpAgDataConnectionServer::GetInstance();
82     int ret = HfpAgSdpServer::GetInstance().DeregisterSdpService();
83     HFP_AG_RETURN_IF_FAIL(ret);
84 
85     BTM_RemoveLocalRfcommScnChannelForLogging(BTM_HCI_LOG_FILTER_MODULE_HFP, connectionServer.GetLocalScn());
86 
87     ret = connectionServer.RemoveServer();
88     HFP_AG_RETURN_IF_FAIL(ret);
89 
90     ret = HfpAgAudioConnection::Deregister();
91     HFP_AG_RETURN_IF_FAIL(ret);
92 
93     HfpAgDataConnection::CleanUp();
94 
95     return ret;
96 }
97 
HfpAgProfile(const std::string & address)98 HfpAgProfile::HfpAgProfile(const std::string &address) : address_(address)
99 {
100 }
101 
Init()102 void HfpAgProfile::Init()
103 {
104     dataConn_.SetRemoteAddr(address_);
105     audioConn_.SetRemoteAddr(address_);
106 }
107 
DoServiceDiscovery(int role,int handle)108 int HfpAgProfile::DoServiceDiscovery(int role, int handle)
109 {
110     if (HFP_AG_ACCEPTOR == role) {
111         tempRfcommHandle_ = handle;
112     }
113 
114     dataConn_.SetRole(role);
115     return sdpClient_.DoDiscovery(address_, role);
116 }
117 
ServiceDiscoveryResult()118 int HfpAgProfile::ServiceDiscoveryResult()
119 {
120     int role = dataConn_.GetRole();
121     if (!sdpClient_.FindAttributes(address_, role)) {
122         LOG_ERROR("[HFP AG]%{public}s():FindAttributes() error", __FUNCTION__);
123         return HFP_AG_FAILURE;
124     }
125     dataConn_.SetSdpInfo(sdpClient_.GetRemoteSdpInfo());
126 
127     if (HFP_AG_INITIATOR == role) {
128         EstablishDataConnection();
129     } else {
130         AcceptDataConnection(tempRfcommHandle_);
131         tempRfcommHandle_ = -1;
132     }
133     return HFP_AG_SUCCESS;
134 }
135 
EstablishDataConnection()136 int HfpAgProfile::EstablishDataConnection()
137 {
138     RawAddress rawAddr(address_);
139     BtAddr btAddr;
140     rawAddr.ConvertToUint8(btAddr.addr);
141     btAddr.type = BT_PUBLIC_DEVICE_ADDRESS;
142     BTM_AddRemoteRfcommScnForLogging(BTM_HCI_LOG_FILTER_MODULE_HFP, dataConn_.GetRemoteScn(), &btAddr);
143     return dataConn_.Connect();
144 }
145 
ReleaseDataConnection() const146 int HfpAgProfile::ReleaseDataConnection() const
147 {
148     return dataConn_.Disconnect();
149 }
150 
AcceptDataConnection(uint16_t handle)151 int HfpAgProfile::AcceptDataConnection(uint16_t handle)
152 {
153     dataServer_.AcceptConnection(handle);
154     dataConn_.SetConnectionHandle(handle);
155     return HFP_AG_SUCCESS;
156 }
157 
ReadData()158 int HfpAgProfile::ReadData()
159 {
160     RawAddress rawAddress = RawAddress(address_);
161     IPowerManager::GetInstance().StatusUpdate(RequestStatus::BUSY, PROFILE_NAME_HFP_AG, rawAddress);
162     HfpAgCommandParser::GetInstance().Read(dataConn_);
163     if (HfpAgAudioConnection::IsAudioConnected(address_)) {
164         IPowerManager::GetInstance().StatusUpdate(RequestStatus::SCO_ON, PROFILE_NAME_HFP_AG, rawAddress);
165     } else {
166         IPowerManager::GetInstance().StatusUpdate(RequestStatus::IDLE, PROFILE_NAME_HFP_AG, rawAddress);
167     }
168     return HFP_AG_SUCCESS;
169 }
170 
ProcessSlcEstablished()171 void HfpAgProfile::ProcessSlcEstablished()
172 {
173     IPowerManager::GetInstance().StatusUpdate(RequestStatus::CONNECT_ON, PROFILE_NAME_HFP_AG, RawAddress(address_));
174     dataConn_.SetSlcConnectState(true);
175     InitInbandRingTone();
176 }
177 
InitInbandRingTone()178 void HfpAgProfile::InitInbandRingTone()
179 {
180     int action = HFP_AG_INBAND_RING_DISABLE;
181     uint32_t localFeatures = HfpAgDataConnection::GetLocalFeatures();
182     if ((localFeatures & HFP_AG_FEATURES_IN_BAND_RING) == HFP_AG_FEATURES_IN_BAND_RING) {
183         action = HFP_AG_INBAND_RING_ENABLE;
184     }
185     SetInbandRingTone(action);
186 
187     if (!dataConn_.ringTimer_) {
188         dataConn_.ringTimer_ = std::make_unique<utility::Timer>(std::bind(&HfpAgProfile::RingTimeout, this));
189     }
190 }
191 
SendRingAndClip()192 void HfpAgProfile::SendRingAndClip()
193 {
194     if (dataConn_.callsetupInd_ != HFP_AG_CALLSETUP_INCOMING) {
195         return;
196     }
197 
198     // Send command RING
199     SendRing();
200 
201     // Send incoming call line identification
202     NotifyCallingLineIdentification(dataConn_.clipType_, dataConn_.clipNumber_);
203 
204     // Start Ring timer again
205     if (dataConn_.ringTimer_ != nullptr) {
206         dataConn_.ringTimer_->Start(HfpAgDataConnection::RING_TIMEOUT_MS, false);
207     }
208 }
209 
RingTimeout()210 void HfpAgProfile::RingTimeout()
211 {
212     HfpAgProfileEventSender::GetInstance().SendRingAndClip(address_);
213 }
214 
SetupCodecConnection()215 int HfpAgProfile::SetupCodecConnection()
216 {
217     if (dataConn_.IsCodecNegotiationSupport()) {
218         if (dataConn_.remoteSupportCodecsUpdated_) {
219             if ((dataConn_.localDemandCodec_ & HFP_AG_CODEC_MSBC) &&
220                 (dataConn_.g_localSupportCodecs & HFP_AG_CODEC_MSBC) &&
221                 (dataConn_.remoteSupportCodecs_ & HFP_AG_CODEC_MSBC)) {
222                 dataConn_.codecNegotiating_ = true;
223                 commandProcessor_.SendAtCommand(dataConn_, "+BCS: 2");
224                 dataConn_.localSelectedCodec_ = HFP_AG_CODEC_MSBC;
225             } else {
226                 dataConn_.codecNegotiating_ = true;
227                 commandProcessor_.SendAtCommand(dataConn_, "+BCS: 1");
228                 dataConn_.localSelectedCodec_ = HFP_AG_CODEC_CVSD;
229             }
230             dataConn_.remoteSupportCodecsUpdated_ = false;
231         } else {
232             EstablishAudioConnection();
233         }
234     } else {
235         dataConn_.inUseCodec_ = HFP_AG_CODEC_CVSD;
236         EstablishAudioConnection();
237     }
238 
239     return HFP_AG_SUCCESS;
240 }
241 
SetupCodecCvsd()242 int HfpAgProfile::SetupCodecCvsd()
243 {
244     if (dataConn_.IsCodecNegotiationSupport()) {
245         dataConn_.codecNegotiating_ = true;
246         commandProcessor_.SendAtCommand(dataConn_, "+BCS: 1");
247         dataConn_.localSelectedCodec_ = HFP_AG_CODEC_CVSD;
248     } else {
249         dataConn_.inUseCodec_ = HFP_AG_CODEC_CVSD;
250         EstablishAudioConnection();
251     }
252 
253     return HFP_AG_SUCCESS;
254 }
255 
EstablishAudioConnection()256 int HfpAgProfile::EstablishAudioConnection()
257 {
258     audioConn_.SetSupportFeatures(dataConn_.IsEscoSupport(), dataConn_.IsEscoS4Support(), dataConn_.inUseCodec_);
259     audioConn_.ConnectAudio();
260     return HFP_AG_SUCCESS;
261 }
262 
PostAudioConnectionEstablishment()263 void HfpAgProfile::PostAudioConnectionEstablishment()
264 {
265     if (scoPostProcess_ == true) {
266         SendRingAndClip();
267         scoPostProcess_ = false;
268     }
269 }
270 
ReleaseAudioConnection() const271 int HfpAgProfile::ReleaseAudioConnection() const
272 {
273     audioConn_.DisconnectAudio();
274     return HFP_AG_SUCCESS;
275 }
276 
ProcessAudioConnectRequest()277 bool HfpAgProfile::ProcessAudioConnectRequest()
278 {
279     if (HfpAgAudioConnection::GetActiveDevice() == address_) {
280         AcceptAudioConnection();
281         return true;
282     } else {
283         RejectAudioConnection();
284         return false;
285     }
286 }
287 
AcceptAudioConnection()288 int HfpAgProfile::AcceptAudioConnection()
289 {
290     audioConn_.SetSupportFeatures(dataConn_.IsEscoSupport(), dataConn_.IsEscoS4Support(), dataConn_.inUseCodec_);
291     audioConn_.AcceptAudioConnection();
292     return HFP_AG_SUCCESS;
293 }
294 
RejectAudioConnection() const295 int HfpAgProfile::RejectAudioConnection() const
296 {
297     audioConn_.RejectAudioConnection();
298     return HFP_AG_SUCCESS;
299 }
300 
ActivateVoiceRecognition()301 int HfpAgProfile::ActivateVoiceRecognition()
302 {
303     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
304     HFP_AG_RETURN_IF_NO_FEATURE(dataConn_.remoteFeatures_, HFP_AG_HF_FEATURES_VOICE_RECOGNITION);
305 
306     std::string cmd("+BVRA: 1");
307     commandProcessor_.SendAtCommand(dataConn_, cmd);
308 
309     if (HfpAgAudioConnection::IsAudioConnected(address_) == false) {
310         HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(address_, HFP_AG_CONNECT_AUDIO_EVT);
311     }
312     return HFP_AG_SUCCESS;
313 }
314 
DeactivateVoiceRecognition() const315 int HfpAgProfile::DeactivateVoiceRecognition() const
316 {
317     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
318     HFP_AG_RETURN_IF_NO_FEATURE(dataConn_.remoteFeatures_, HFP_AG_HF_FEATURES_VOICE_RECOGNITION);
319 
320     std::string cmd("+BVRA: 0");
321     commandProcessor_.SendAtCommand(dataConn_, cmd);
322     return HFP_AG_SUCCESS;
323 }
324 
SetMicrophoneGain(int val) const325 int HfpAgProfile::SetMicrophoneGain(int val) const
326 {
327     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
328 
329     // Make sure volume is in the range 0-15
330     int value = (val > 15) ? 15 : val;
331     value = (value < 0) ? 0 : value;
332 
333     std::string cmd("+VGM: ");
334     cmd.append(std::to_string(value));
335     commandProcessor_.SendAtCommand(dataConn_, cmd);
336     return HFP_AG_SUCCESS;
337 }
338 
SetSpeakerVolume(int val) const339 int HfpAgProfile::SetSpeakerVolume(int val) const
340 {
341     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
342 
343     // Make sure volume is in the range 0-15
344     int value = (val > 15) ? 15 : val;
345     value = (value < 0) ? 0 : value;
346 
347     std::string cmd("+VGS: ");
348     cmd.append(std::to_string(value));
349     commandProcessor_.SendAtCommand(dataConn_, cmd);
350     return HFP_AG_SUCCESS;
351 }
352 
SetInbandRingTone(int action)353 int HfpAgProfile::SetInbandRingTone(int action)
354 {
355     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
356 
357     dataConn_.inBandRingTone_ = action;
358 
359     std::string cmd("+BSIR: ");
360     cmd.append(std::to_string(action));
361     commandProcessor_.SendAtCommand(dataConn_, cmd);
362     return HFP_AG_SUCCESS;
363 }
364 
SetActiveDevice(const std::string & address)365 void HfpAgProfile::SetActiveDevice(const std::string &address)
366 {
367     HfpAgAudioConnection::SetActiveDevice(address);
368 }
369 
GetActiveDevice()370 std::string HfpAgProfile::GetActiveDevice()
371 {
372     return HfpAgAudioConnection::GetActiveDevice();
373 }
374 
375 // Should send OK command after all subscriber number having been sent.
SendSubscriberNumberInformation(uint16_t type,const std::string & number,int service)376 int HfpAgProfile::SendSubscriberNumberInformation(uint16_t type, const std::string &number, int service)
377 {
378     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
379 
380     dataConn_.subscriberNumber_ = number;
381 
382     std::string cmd("+CNUM: ");
383     cmd.append(",\"" + number + "\"," + std::to_string(type) + ",," + std::to_string(service));
384     commandProcessor_.SendAtCommand(dataConn_, cmd);
385     return HFP_AG_SUCCESS;
386 }
387 
SendResultCode(int result) const388 int HfpAgProfile::SendResultCode(int result) const
389 {
390     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
391 
392     std::string cmd("");
393     switch (result) {
394         case HFP_AG_RESULT_OK:
395             cmd.append("OK");
396             break;
397         case HFP_AG_RESULT_RING:
398             cmd.append("RING");
399             break;
400         case HFP_AG_RESULT_NO_CARRIER:
401             cmd.append("NO CARRIER");
402             break;
403         case HFP_AG_RESULT_ERROR:
404             cmd.append("ERROR");
405             break;
406         case HFP_AG_RESULT_BUSY:
407             cmd.append("BUSY");
408             break;
409         case HFP_AG_RESULT_NO_ANSWER:
410             cmd.append("NO ANSWER");
411             break;
412         case HFP_AG_RESULT_DELAYED:
413             cmd.append("DELAYED");
414             break;
415         case HFP_AG_RESULT_BLOCKLISTED:
416             cmd.append("BLOCKLISTED");
417             break;
418         default:
419             LOG_ERROR("[HFP AG]%{public}s():Unknown HfpAgResultType[%{public}d]", __FUNCTION__, result);
420             return HFP_AG_FAILURE;
421     }
422     commandProcessor_.SendAtCommand(dataConn_, cmd);
423     return HFP_AG_SUCCESS;
424 }
425 
ReportCallStatus(uint32_t call)426 int HfpAgProfile::ReportCallStatus(uint32_t call)
427 {
428     if (mockState_ != HFP_AG_MOCK) {
429         HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
430         HFP_AG_RETURN_IF_INDICATOR_EQUAL(call, dataConn_.callInd_);
431     }
432 
433     dataConn_.callInd_ = call;
434     return ReportAgIndicator(HFP_AG_INDICATOR_CALL, call);
435 }
436 
ReportIndicators(const CindIndicators & indicators)437 int HfpAgProfile::ReportIndicators(const CindIndicators &indicators)
438 {
439     dataConn_.serviceInd_ = indicators.status;
440     dataConn_.callInd_ = indicators.call;
441     dataConn_.callsetupInd_ = indicators.callsetup;
442     dataConn_.callheldInd_ = indicators.callheld;
443     dataConn_.signalInd_ = indicators.signal;
444     dataConn_.roamInd_ = indicators.roam;
445     dataConn_.batteryInd_ = indicators.battchg;
446 
447     std::string cmd = "+CIND: " + std::to_string(dataConn_.serviceInd_) + "," + std::to_string(dataConn_.callInd_) +
448                       "," + std::to_string(dataConn_.callsetupInd_) + "," + std::to_string(dataConn_.callheldInd_) +
449                       "," + std::to_string(dataConn_.signalInd_) + "," + std::to_string(dataConn_.roamInd_) + "," +
450                       std::to_string(dataConn_.batteryInd_);
451 
452     commandProcessor_.SendAtCommand(dataConn_, cmd);
453     commandProcessor_.SendAtCommand(dataConn_, "OK");
454     return HFP_AG_SUCCESS;
455 }
456 
ReportCallsetupStatus(uint32_t callsetup)457 int HfpAgProfile::ReportCallsetupStatus(uint32_t callsetup)
458 {
459     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
460     HFP_AG_RETURN_IF_INDICATOR_EQUAL(callsetup, dataConn_.callsetupInd_);
461 
462     dataConn_.callsetupInd_ = callsetup;
463     return ReportAgIndicator(HFP_AG_INDICATOR_CALLSETUP, callsetup);
464 }
465 
ReportCallheldStatus(uint32_t callheld)466 int HfpAgProfile::ReportCallheldStatus(uint32_t callheld)
467 {
468     if (mockState_ != HFP_AG_MOCK) {
469         HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
470     }
471 
472     dataConn_.callheldInd_ = callheld;
473     return ReportAgIndicator(HFP_AG_INDICATOR_CALLHELD, callheld);
474 }
475 
ReportResponseHoldStatus(uint32_t state,int test)476 int HfpAgProfile::ReportResponseHoldStatus(uint32_t state, int test)
477 {
478     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
479     std::string cmd("+BTRH: ");
480     cmd.append(std::to_string(state));
481     commandProcessor_.SendAtCommand(dataConn_, cmd);
482     return HFP_AG_SUCCESS;
483 }
484 
ReportRegistrationStatus(uint32_t status)485 int HfpAgProfile::ReportRegistrationStatus(uint32_t status)
486 {
487     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
488     HFP_AG_RETURN_IF_NOT_ENABLED(dataConn_.serviceIndicatorEnabled_);
489     HFP_AG_RETURN_IF_INDICATOR_EQUAL(status, dataConn_.serviceInd_);
490 
491     dataConn_.serviceInd_ = status;
492     return ReportAgIndicator(HFP_AG_INDICATOR_SERVICE, status);
493 }
494 
ReportSignalStrength(uint32_t signal)495 int HfpAgProfile::ReportSignalStrength(uint32_t signal)
496 {
497     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
498     HFP_AG_RETURN_IF_NOT_ENABLED(dataConn_.signalStrengthIndicatorEnabled_);
499     HFP_AG_RETURN_IF_INDICATOR_EQUAL(signal, dataConn_.signalInd_);
500 
501     dataConn_.signalInd_ = signal;
502     return ReportAgIndicator(HFP_AG_INDICATOR_SIGNAL_STRENGTH, signal);
503 }
504 
ReportRoamingState(uint32_t state)505 int HfpAgProfile::ReportRoamingState(uint32_t state)
506 {
507     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
508     HFP_AG_RETURN_IF_NOT_ENABLED(dataConn_.roamIndicatorEnabled_);
509     HFP_AG_RETURN_IF_INDICATOR_EQUAL(state, dataConn_.roamInd_);
510 
511     dataConn_.roamInd_ = state;
512     return ReportAgIndicator(HFP_AG_INDICATOR_ROAMING_STATE, state);
513 }
514 
ReportBatteryLevel(uint32_t battery)515 int HfpAgProfile::ReportBatteryLevel(uint32_t battery)
516 {
517     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
518     HFP_AG_RETURN_IF_NOT_ENABLED(dataConn_.batteryIndicatorEnabled_);
519     HFP_AG_RETURN_IF_INDICATOR_EQUAL(battery, dataConn_.batteryInd_);
520 
521     dataConn_.batteryInd_ = battery;
522     return ReportAgIndicator(HFP_AG_INDICATOR_BATTERY_LEVEL, battery);
523 }
524 
ReportCurrentNetworkOperator(const std::string & operatorName)525 int HfpAgProfile::ReportCurrentNetworkOperator(const std::string &operatorName)
526 {
527     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
528 
529     dataConn_.operatorName_ = operatorName;
530 
531     std::string cmd("+COPS: ");
532     cmd.append(std::to_string(HFP_AG_COPS_MODE_SET_FORMAT) + "," + std::to_string(HFP_AG_COPS_FORMAT_LONG) + ",\"" +
533                operatorName + "\"");
534     commandProcessor_.SendAtCommand(dataConn_, cmd);
535     SendResultCode(HFP_AG_RESULT_OK);
536     return HFP_AG_SUCCESS;
537 }
538 
PhoneStateChange(const HfpAgPhoneState & phoneState)539 int HfpAgProfile::PhoneStateChange(const HfpAgPhoneState &phoneState)
540 {
541     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
542 
543     LOG_INFO("[HFP AG]%{public}s():preCallState_[%{public}s], preNumActiveCalls_[%{public}d], "
544         "preNumHeldCalls_[%{public}d], currentCallState[%{public}s], activeNum[%{public}d], heldNum[%{public}d]",
545         __FUNCTION__, GetCallState(preCallState_).c_str(), preNumActiveCalls_, preNumHeldCalls_,
546         GetCallState(phoneState.callState).c_str(), phoneState.activeNum, phoneState.heldNum);
547 
548     switch (phoneState.callState) {
549         case HFP_AG_CALL_STATE_DIALING:
550             ProcessCurrentCallStateDialing(phoneState.activeNum, phoneState.heldNum);
551             break;
552         case HFP_AG_CALL_STATE_ALERTING:
553             ProcessCurrentCallStateAlerting();
554             break;
555         case HFP_AG_CALL_STATE_INCOMING:
556             ProcessCurrentCallStateIncominging(
557                 phoneState.activeNum, phoneState.heldNum, phoneState.type, phoneState.number);
558             break;
559         case HFP_AG_CALL_STATE_IDLE:
560             ProcessCurrentCallStateIdle(phoneState.activeNum, phoneState.heldNum);
561             break;
562         default:
563             LOG_WARN("[HFP AG]%{public}s():Ignore current call state[%{public}d]", __FUNCTION__, phoneState.callState);
564             return HFP_AG_SUCCESS;
565     }
566 
567     if (preNumActiveCalls_ == 1 && preNumHeldCalls_ == 1 &&  phoneState.activeNum == 1 && phoneState.heldNum == 0) {
568         ReportCallheldStatus(HFP_AG_CALLHELD_INACTIVE);
569     }
570 
571     SetCallStates(phoneState.heldNum, phoneState.activeNum, phoneState.callState);
572     return HFP_AG_SUCCESS;
573 }
574 
ReportCurrentCallList(const HfpAgCallList & clcc) const575 int HfpAgProfile::ReportCurrentCallList(const HfpAgCallList &clcc) const
576 {
577     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
578 
579     // This means that the current call list all has been transmitted
580     if (clcc.index == 0) {
581         SendResultCode(HFP_AG_RESULT_OK);
582     } else {
583         std::string cmd("+CLCC: ");
584         cmd.append(std::to_string(clcc.index) + "," + std::to_string(clcc.dir) + "," + std::to_string(clcc.state) +
585                    "," + std::to_string(clcc.mode) + "," + std::to_string(clcc.mpty));
586         if (clcc.number.length() > 0) {
587             if ((clcc.type == HFP_AG_CALL_NUMBER_INTERNATIONAL) && (clcc.number.at(0) != '+')) {
588                 cmd.append(",\"+" + clcc.number + "\"," + std::to_string(clcc.type));
589             } else {
590                 cmd.append(",\"" + clcc.number + "\"," + std::to_string(clcc.type));
591             }
592         }
593 
594         commandProcessor_.SendAtCommand(dataConn_, cmd);
595     }
596     return HFP_AG_SUCCESS;
597 }
598 
ResponesOK() const599 void HfpAgProfile::ResponesOK() const
600 {
601     SendResultCode(HFP_AG_RESULT_OK);
602 }
603 
ReportCallStatusByCallNums(int numActive,int numHeld)604 int HfpAgProfile::ReportCallStatusByCallNums(int numActive, int numHeld)
605 {
606     int state = HFP_AG_CALL_INACTIVE;
607     if ((numActive + numHeld) > 0) {
608         state = HFP_AG_CALL_ACTIVE;
609     }
610     if (preNumActiveCalls_ == 1 && preNumHeldCalls_ == 0 && numActive == 1 && numHeld == 0) {
611         return HFP_AG_SUCCESS;
612     }
613 
614     ReportCallStatus(state);
615     return HFP_AG_SUCCESS;
616 }
617 
ReportCallheldStatusByCallNums(int numActive,int numHeld)618 int HfpAgProfile::ReportCallheldStatusByCallNums(int numActive, int numHeld)
619 {
620     int state = HFP_AG_CALLHELD_INACTIVE;
621     if (numHeld > 0) {
622         if (numActive > 0) {
623             state = HFP_AG_CALLHELD_ACTIVE;
624         } else {
625             state = HFP_AG_CALLHELD_NOACTIVE;
626         }
627     }
628     return HFP_AG_SUCCESS;
629 }
630 
ReportAgIndicator(int indicator,int value) const631 int HfpAgProfile::ReportAgIndicator(int indicator, int value) const
632 {
633     if (dataConn_.cmerEnabled_) {
634         std::string cmd("+CIEV: ");
635         cmd.append(std::to_string(indicator) + "," + std::to_string(value));
636         commandProcessor_.SendAtCommand(dataConn_, cmd);
637     }
638     return HFP_AG_SUCCESS;
639 }
640 
NotifyCallingLineIdentification(uint16_t type,const std::string & number) const641 int HfpAgProfile::NotifyCallingLineIdentification(uint16_t type, const std::string &number) const
642 {
643     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
644     HFP_AG_RETURN_IF_NOT_ENABLED(dataConn_.clipEnabled_);
645 
646     std::string cmd("+CLIP: ");
647     if ((type == HFP_AG_CALL_NUMBER_INTERNATIONAL) && (number.at(0) != '+')) {
648         cmd.append("\"+" + number + "\"," + std::to_string(type));
649     } else {
650         cmd.append("\"" + number + "\"," + std::to_string(type));
651     }
652     commandProcessor_.SendAtCommand(dataConn_, cmd);
653     return HFP_AG_SUCCESS;
654 }
655 
NotifyIncomingCallWaiting(uint16_t type,const std::string & number) const656 int HfpAgProfile::NotifyIncomingCallWaiting(uint16_t type, const std::string &number) const
657 {
658     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
659     HFP_AG_RETURN_IF_NOT_ENABLED(dataConn_.ccwaEnabled_);
660 
661     std::string cmd("+CCWA: ");
662     if ((type == HFP_AG_CALL_NUMBER_INTERNATIONAL) && (number.at(0) != '+')) {
663         cmd.append("\"+" + number + "\"," + std::to_string(type));
664     } else {
665         cmd.append("\"" + number + "\"," + std::to_string(type));
666     }
667     commandProcessor_.SendAtCommand(dataConn_, cmd);
668     return HFP_AG_SUCCESS;
669 }
670 
SendBinp(std::string number) const671 void HfpAgProfile::SendBinp(std::string number) const
672 {
673     std::string cmd("+BINP: ");
674     cmd.append(number);
675     if (!number.empty()) {
676         commandProcessor_.SendAtCommand(dataConn_, cmd);
677         SendResultCode(HFP_AG_RESULT_OK);
678     } else {
679         SendResultCode(HFP_AG_RESULT_ERROR);
680     }
681 }
682 
SendRing() const683 int HfpAgProfile::SendRing() const
684 {
685     HFP_AG_RETURN_IF_NOT_CONNECTED(dataConn_.slcConnected_);
686 
687     std::string cmd("RING");
688     commandProcessor_.SendAtCommand(dataConn_, cmd);
689     return HFP_AG_SUCCESS;
690 }
691 
ProcessCurrentCallStateDialing(int numActive,int numHeld)692 int HfpAgProfile::ProcessCurrentCallStateDialing(int numActive, int numHeld)
693 {
694     // Report callsetup indicator: outgoing
695     ReportCallsetupStatus(HFP_AG_CALLSETUP_OUTGOING);
696 
697     // Report callheld indicator: no active and have held
698     if ((numActive == 0) && (numHeld > 0)) {
699         ReportCallheldStatus(HFP_AG_CALLHELD_NOACTIVE);
700     }
701 
702     // Connect SCO if not have been established
703     auto isAudioConnected = HfpAgAudioConnection::IsAudioConnected(address_);
704     if ((preNumActiveCalls_ == 0) && (preNumHeldCalls_ == 0) && isAudioConnected == false) {
705         HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(address_, HFP_AG_CONNECT_AUDIO_EVT);
706     }
707     return HFP_AG_SUCCESS;
708 }
709 
ProcessCurrentCallStateAlerting()710 int HfpAgProfile::ProcessCurrentCallStateAlerting()
711 {
712     // Report callsetup indicator: alerting
713     ReportCallsetupStatus(HFP_AG_CALLSETUP_ALERTING);
714     return HFP_AG_SUCCESS;
715 }
716 
ProcessCurrentCallStateIncominging(int numActive,int numHeld,uint16_t type,const std::string & number)717 int HfpAgProfile::ProcessCurrentCallStateIncominging(
718     int numActive, int numHeld, uint16_t type, const std::string &number)
719 {
720     if (preCallState_ == HFP_AG_CALL_STATE_INCOMING) {
721         // If active or held calls changed
722         if ((numActive != preNumActiveCalls_) || (numHeld != preNumHeldCalls_)) {
723             // If calls swapped, do nothing
724             if ((numActive == preNumHeldCalls_) && (numHeld == preNumActiveCalls_)) {
725                 return HFP_AG_SUCCESS;
726             }
727 
728             // Report callheld indicator due to numActive and numHeld
729             ReportCallheldStatusByCallNums(numActive, numHeld);
730 
731             // Report call indicator due to numActive and numHeld
732             ReportCallStatusByCallNums(numActive, numHeld);
733         }
734         return HFP_AG_SUCCESS;
735     }
736 
737     // If have active or held calls
738     if ((numActive > 0) || (numHeld > 0)) {
739         // Send incoming call waiting
740         NotifyIncomingCallWaiting(type, number);
741         ReportCallsetupStatus(HFP_AG_CALLSETUP_INCOMING);
742         return HFP_AG_SUCCESS;
743     }
744 
745     // Report callsetup indicator incoming
746     ReportCallsetupStatus(HFP_AG_CALLSETUP_INCOMING);
747 
748     dataConn_.clipNumber_ = number;
749     dataConn_.clipType_ = type;
750     SendRingAndClip();
751     LOG_INFO("inBandRingTone_ %{public}d", dataConn_.inBandRingTone_);
752     auto isAudioConnected = HfpAgAudioConnection::IsAudioConnected(address_);
753     if ((preNumActiveCalls_ == 0) && (preNumHeldCalls_ == 0) &&
754         (dataConn_.inBandRingTone_ == HFP_AG_INBAND_RING_ENABLE) &&
755         (isAudioConnected == false)) {
756         HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(address_, HFP_AG_CONNECT_AUDIO_EVT);
757         scoPostProcess_ = true;
758     }
759 
760     return HFP_AG_SUCCESS;
761 }
762 
ProcessCurrentCallStateIdle(int numActive,int numHeld)763 int HfpAgProfile::ProcessCurrentCallStateIdle(int numActive, int numHeld)
764 {
765     HILOGI("[HFP AG]:Pre-CallState[%{public}s], numActive:%{public}d, numHeld:%{public}d",
766         GetCallState(preCallState_).c_str(), numActive, numHeld);
767     if (dataConn_.ringTimer_ != nullptr) {
768         dataConn_.ringTimer_->Stop();
769     }
770     dataConn_.clipNumber_ = "";
771     dataConn_.clipType_ = 0;
772 
773     switch (preCallState_) {
774         case HFP_AG_CALL_STATE_DIALING:
775         case HFP_AG_CALL_STATE_ALERTING:
776             ProcessPreviousCallStateDialingAlerting(numActive, numHeld);
777             break;
778         case HFP_AG_CALL_STATE_INCOMING:
779             ProcessPreviousCallStateIncoming(numActive, numHeld);
780             break;
781         case HFP_AG_CALL_STATE_IDLE:
782             ProcessPreviousCallStateIdle(numActive, numHeld);
783             break;
784         default:
785             LOG_WARN("[HFP AG]%{public}s():Ignore Pre-CallState[%{public}d]", __FUNCTION__, preCallState_);
786             break;
787     }
788 
789     auto isAudioConnected = HfpAgAudioConnection::IsAudioConnected(address_);
790     if (numActive == 0 && numHeld == 0 && isAudioConnected == true) {
791         HILOGI("[HFP AG]:No call exist , disconnect sco");
792         HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(address_, HFP_AG_DISCONNECT_AUDIO_EVT);
793     }
794 
795     return HFP_AG_SUCCESS;
796 }
797 
ProcessPreviousCallStateDialingAlerting(int numActive,int numHeld)798 int HfpAgProfile::ProcessPreviousCallStateDialingAlerting(int numActive, int numHeld)
799 {
800     // If have more active calls, report call indicator: active
801     if (numActive > preNumActiveCalls_) {
802         ReportCallStatus(HFP_AG_CALL_ACTIVE);
803     }
804 
805     // Report callheld indicator due to numActive and numHeld
806     ReportCallheldStatusByCallNums(numActive, numHeld);
807 
808     // Report callsetup indicator: none
809     ReportCallsetupStatus(HFP_AG_CALLSETUP_NONE);
810     return HFP_AG_SUCCESS;
811 }
812 
ProcessPreviousCallStateIncoming(int numActive,int numHeld)813 int HfpAgProfile::ProcessPreviousCallStateIncoming(int numActive, int numHeld)
814 {
815     // If have more active calls, report call indicator: active
816     if (numActive > preNumActiveCalls_) {
817         ReportCallStatus(HFP_AG_CALL_ACTIVE);
818 
819         // Connect SCO if not have been established
820         auto isAudioConnected = HfpAgAudioConnection::IsAudioConnected(address_);
821         if ((preNumActiveCalls_ == 0) && (preNumHeldCalls_ == 0) && isAudioConnected == false) {
822             HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(address_, HFP_AG_CONNECT_AUDIO_EVT);
823         }
824     }
825 
826     // Report callsetup indicator: none
827     ReportCallsetupStatus(HFP_AG_CALLSETUP_NONE);
828 
829     // Report callheld indicator: have active and have held
830     if ((numHeld >= preNumHeldCalls_) && numHeld > 0) {
831         ReportCallheldStatus(HFP_AG_CALLHELD_ACTIVE);
832     }
833 
834     return HFP_AG_SUCCESS;
835 }
836 
ProcessPreviousCallStateIdle(int numActive,int numHeld)837 int HfpAgProfile::ProcessPreviousCallStateIdle(int numActive, int numHeld)
838 {
839     // Make callheld indicator INACTIVE if active and held calls swapped
840     if ((numHeld > 0) && (numActive > 0) && (numActive == preNumHeldCalls_) && (numHeld == preNumActiveCalls_)) {
841         dataConn_.callheldInd_ = HFP_AG_CALLHELD_INACTIVE;
842         // Connect SCO when there are new calls
843     } else if (((numActive > 0) || (numHeld > 0)) && (preNumActiveCalls_ == 0) && (preNumHeldCalls_ == 0)) {
844         auto isAudioConnected = HfpAgAudioConnection::IsAudioConnected(address_);
845         if ((isAudioConnected == false) && (address_ == HfpAgAudioConnection::GetActiveDevice())) {
846             HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(address_, HFP_AG_CONNECT_AUDIO_EVT);
847         }
848     }
849 
850     // Report callheld indicator due to numActive and numHeld
851     ReportCallheldStatusByCallNums(numActive, numHeld);
852 
853     // Report call indicator due to numActive and numHeld
854     ReportCallStatusByCallNums(numActive, numHeld);
855 
856     // Report callsetup indicator: none
857     ReportCallsetupStatus(HFP_AG_CALLSETUP_NONE);
858 
859     // Send NO CARRIER if service is not available
860     if ((numActive == 0) && (numHeld == 0) && (dataConn_.serviceInd_ == HFP_AG_SERVICE_NOT_AVAILABLE) &&
861         ((preNumActiveCalls_ > 0) || (preNumHeldCalls_ > 0))) {
862         SendResultCode(HFP_AG_RESULT_NO_CARRIER);
863     }
864     return HFP_AG_SUCCESS;
865 }
866 
startMock(int state)867 void HfpAgProfile::startMock(int state)
868 {
869     mockState_ = state;
870 }
871 
SetCallStates(int numHeld,int numActive,int callState)872 void HfpAgProfile::SetCallStates(int numHeld, int numActive, int callState)
873 {
874     preNumHeldCalls_ = numHeld;
875     preNumActiveCalls_ = numActive;
876     preCallState_ = callState;
877 }
878 
ProcessBia(bool service,bool roam,bool signal,bool battery)879 void HfpAgProfile::ProcessBia(bool service, bool roam, bool signal, bool battery)
880 {
881     dataConn_.serviceIndicatorEnabled_ = service;
882     dataConn_.roamIndicatorEnabled_ = roam;
883     dataConn_.signalStrengthIndicatorEnabled_ = signal;
884     dataConn_.batteryIndicatorEnabled_ = battery;
885 }
886 
RemoveStateMachine()887 void HfpAgProfile::RemoveStateMachine()
888 {
889     HfpAgProfileEventSender::GetInstance().RemoveStateMachine(address_);
890 }
891 
IsAudioConnected(const std::string & address)892 bool HfpAgProfile::IsAudioConnected(const std::string &address)
893 {
894     return HfpAgAudioConnection::IsAudioConnected(address);
895 }
896 
RemoveRemoteScnLoging() const897 void HfpAgProfile::RemoveRemoteScnLoging() const
898 {
899     if (dataConn_.GetRole() == HFP_AG_INITIATOR) {
900         RawAddress rawAddr(address_);
901         BtAddr btAddr;
902         rawAddr.ConvertToUint8(btAddr.addr);
903         btAddr.type = BT_PUBLIC_DEVICE_ADDRESS;
904         BTM_RemoveRemoteRfcommScnChannelForLogging(BTM_HCI_LOG_FILTER_MODULE_HFP, dataConn_.GetRemoteScn(), &btAddr);
905     }
906 }
907 
GetCallState(int state)908 std::string HfpAgProfile::GetCallState(int state)
909 {
910     switch (state) {
911         case HFP_AG_CALL_STATE_ACTIVE:
912             return "HFP_AG_CALL_STATE_ACTIVE";
913         case HFP_AG_CALL_STATE_HELD:
914             return "HFP_AG_CALL_STATE_HELD";
915         case HFP_AG_CALL_STATE_DIALING:
916             return "HFP_AG_CALL_STATE_DIALING";
917         case HFP_AG_CALL_STATE_ALERTING:
918             return "HFP_AG_CALL_STATE_ALERTING";
919         case HFP_AG_CALL_STATE_INCOMING:
920             return "HFP_AG_CALL_STATE_INCOMING";
921         case HFP_AG_CALL_STATE_WAITING:
922             return "HFP_AG_CALL_STATE_WAITING";
923         case HFP_AG_CALL_STATE_IDLE:
924             return "HFP_AG_CALL_STATE_IDLE";
925         case HFP_AG_CALL_STATE_DISCONNECTED:
926             return "HFP_AG_CALL_STATE_DISCONNECTED";
927         case HFP_AG_CALL_STATE_DISCONNECTING:
928             return "HFP_AG_CALL_STATE_DISCONNECTING";
929         default:
930             return "Unknown";
931     }
932 }
933 }  // namespace bluetooth
934 }  // namespace OHOS
935