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