1 /*
2 * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
3 * Not a contribution.
4 *
5 * Copyright (C) 2013 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20 #define LOG_TAG "voice_extn"
21 /*#define LOG_NDEBUG 0*/
22 #define LOG_NDDEBUG 0
23
24 #include <errno.h>
25 #include <math.h>
26 #include <cutils/log.h>
27 #include <cutils/str_parms.h>
28 #include <sys/ioctl.h>
29 #include <sound/voice_params.h>
30 #include <stdlib.h>
31
32 #include "audio_hw.h"
33 #include "voice.h"
34 #include "platform.h"
35 #include "platform_api.h"
36 #include "voice_extn.h"
37
38 #define AUDIO_PARAMETER_KEY_VSID "vsid"
39 #define AUDIO_PARAMETER_KEY_CALL_STATE "call_state"
40 #define AUDIO_PARAMETER_KEY_AUDIO_MODE "audio_mode"
41 #define AUDIO_PARAMETER_KEY_ALL_CALL_STATES "all_call_states"
42 #define AUDIO_PARAMETER_KEY_DEVICE_MUTE "device_mute"
43 #define AUDIO_PARAMETER_KEY_DIRECTION "direction"
44 #define AUDIO_PARAMETER_KEY_IN_CALL "in_call"
45
46 #define VOICE_EXTN_PARAMETER_VALUE_MAX_LEN 256
47
48 #define VOICE2_VSID 0x10DC1000
49 #define VOLTE_VSID 0x10C02000
50 #define QCHAT_VSID 0x10803000
51 #define VOWLAN_VSID 0x10002000
52 #define ALL_VSID 0xFFFFFFFF
53
54 /* Voice Session Indices */
55 #define VOICE2_SESS_IDX (VOICE_SESS_IDX + 1)
56 #define VOLTE_SESS_IDX (VOICE_SESS_IDX + 2)
57 #define QCHAT_SESS_IDX (VOICE_SESS_IDX + 3)
58 #define VOWLAN_SESS_IDX (VOICE_SESS_IDX + 4)
59
60 /* Call States */
61 #define CALL_HOLD (BASE_CALL_STATE + 2)
62 #define CALL_LOCAL_HOLD (BASE_CALL_STATE + 3)
63
64 struct pcm_config pcm_config_incall_music = {
65 .channels = 1,
66 .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
67 .period_size = LOW_LATENCY_OUTPUT_PERIOD_SIZE,
68 .period_count = LOW_LATENCY_OUTPUT_PERIOD_COUNT,
69 .format = PCM_FORMAT_S16_LE,
70 .start_threshold = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
71 .stop_threshold = INT_MAX,
72 .avail_min = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
73 };
74
75 int voice_extn_is_call_state_active(struct audio_device *adev, bool *is_call_active);
76
is_valid_call_state(int call_state)77 static bool is_valid_call_state(int call_state)
78 {
79 if (call_state < CALL_INACTIVE || call_state > CALL_LOCAL_HOLD)
80 return false;
81 else
82 return true;
83 }
84
is_valid_vsid(uint32_t vsid)85 static bool is_valid_vsid(uint32_t vsid)
86 {
87 if (vsid == VOICE_VSID ||
88 vsid == VOICE2_VSID ||
89 vsid == VOLTE_VSID ||
90 vsid == QCHAT_VSID ||
91 vsid == VOWLAN_VSID)
92 return true;
93 else
94 return false;
95 }
96
voice_extn_get_usecase_for_session_idx(const int index)97 static audio_usecase_t voice_extn_get_usecase_for_session_idx(const int index)
98 {
99 audio_usecase_t usecase_id = -1;
100
101 switch(index) {
102 case VOICE_SESS_IDX:
103 usecase_id = USECASE_VOICE_CALL;
104 break;
105
106 case VOICE2_SESS_IDX:
107 usecase_id = USECASE_VOICE2_CALL;
108 break;
109
110 case VOLTE_SESS_IDX:
111 usecase_id = USECASE_VOLTE_CALL;
112 break;
113
114 case QCHAT_SESS_IDX:
115 usecase_id = USECASE_QCHAT_CALL;
116 break;
117
118 case VOWLAN_SESS_IDX:
119 usecase_id = USECASE_VOWLAN_CALL;
120 break;
121
122 default:
123 ALOGE("%s: Invalid voice session index\n", __func__);
124 }
125
126 return usecase_id;
127 }
128
get_session_id_with_state(struct audio_device * adev,int call_state)129 static uint32_t get_session_id_with_state(struct audio_device *adev,
130 int call_state)
131 {
132 struct voice_session *session = NULL;
133 int i = 0;
134 uint32_t session_id = 0;
135
136 for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
137 session = &adev->voice.session[i];
138 if(session->state.current == call_state){
139 session_id = session->vsid;
140 break;
141 }
142 }
143
144 return session_id;
145 }
146
update_calls(struct audio_device * adev)147 static int update_calls(struct audio_device *adev)
148 {
149 int i = 0;
150 audio_usecase_t usecase_id = 0;
151 enum voice_lch_mode lch_mode;
152 struct voice_session *session = NULL;
153 int fd = 0;
154 int ret = 0;
155
156 ALOGD("%s: enter:", __func__);
157
158 for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
159 usecase_id = voice_extn_get_usecase_for_session_idx(i);
160 session = &adev->voice.session[i];
161 ALOGD("%s: cur_state=%d new_state=%d vsid=%x",
162 __func__, session->state.current, session->state.new, session->vsid);
163
164 switch(session->state.new)
165 {
166 case CALL_ACTIVE:
167 switch(session->state.current)
168 {
169 case CALL_INACTIVE:
170 ALOGD("%s: INACTIVE -> ACTIVE vsid:%x", __func__, session->vsid);
171 ret = voice_start_usecase(adev, usecase_id);
172 if(ret < 0) {
173 ALOGE("%s: voice_start_usecase() failed for usecase: %d\n",
174 __func__, usecase_id);
175 } else {
176 session->state.current = session->state.new;
177 }
178 break;
179
180 case CALL_HOLD:
181 ALOGD("%s: HOLD -> ACTIVE vsid:%x", __func__, session->vsid);
182 session->state.current = session->state.new;
183 break;
184
185 case CALL_LOCAL_HOLD:
186 ALOGD("%s: LOCAL_HOLD -> ACTIVE vsid:%x", __func__, session->vsid);
187 lch_mode = VOICE_LCH_STOP;
188 ret = platform_update_lch(adev->platform, session, lch_mode);
189 if (ret < 0)
190 ALOGE("%s: lch mode update failed, ret = %d", __func__, ret);
191 else
192 session->state.current = session->state.new;
193 break;
194
195 default:
196 ALOGV("%s: CALL_ACTIVE cannot be handled in state=%d vsid:%x",
197 __func__, session->state.current, session->vsid);
198 break;
199 }
200 break;
201
202 case CALL_INACTIVE:
203 switch(session->state.current)
204 {
205 case CALL_ACTIVE:
206 case CALL_HOLD:
207 case CALL_LOCAL_HOLD:
208 ALOGD("%s: ACTIVE/HOLD/LOCAL_HOLD -> INACTIVE vsid:%x", __func__, session->vsid);
209 ret = voice_stop_usecase(adev, usecase_id);
210 if(ret < 0) {
211 ALOGE("%s: voice_stop_usecase() failed for usecase: %d\n",
212 __func__, usecase_id);
213 } else {
214 session->state.current = session->state.new;
215 }
216 break;
217
218 default:
219 ALOGV("%s: CALL_INACTIVE cannot be handled in state=%d vsid:%x",
220 __func__, session->state.current, session->vsid);
221 break;
222 }
223 break;
224
225 case CALL_HOLD:
226 switch(session->state.current)
227 {
228 case CALL_ACTIVE:
229 ALOGD("%s: CALL_ACTIVE -> HOLD vsid:%x", __func__, session->vsid);
230 session->state.current = session->state.new;
231 break;
232
233 case CALL_LOCAL_HOLD:
234 ALOGD("%s: CALL_LOCAL_HOLD -> HOLD vsid:%x", __func__, session->vsid);
235 lch_mode = VOICE_LCH_STOP;
236 ret = platform_update_lch(adev->platform, session, lch_mode);
237 if (ret < 0)
238 ALOGE("%s: lch mode update failed, ret = %d", __func__, ret);
239 else
240 session->state.current = session->state.new;
241 break;
242
243 default:
244 ALOGV("%s: CALL_HOLD cannot be handled in state=%d vsid:%x",
245 __func__, session->state.current, session->vsid);
246 break;
247 }
248 break;
249
250 case CALL_LOCAL_HOLD:
251 switch(session->state.current)
252 {
253 case CALL_ACTIVE:
254 case CALL_HOLD:
255 ALOGD("%s: ACTIVE/CALL_HOLD -> LOCAL_HOLD vsid:%x", __func__,
256 session->vsid);
257 lch_mode = VOICE_LCH_START;
258 ret = platform_update_lch(adev->platform, session, lch_mode);
259 if (ret < 0)
260 ALOGE("%s: lch mode update failed, ret = %d", __func__, ret);
261 else
262 session->state.current = session->state.new;
263 break;
264
265 default:
266 ALOGV("%s: CALL_LOCAL_HOLD cannot be handled in state=%d vsid:%x",
267 __func__, session->state.current, session->vsid);
268 break;
269 }
270 break;
271
272 default:
273 break;
274 } //end out switch loop
275 } //end for loop
276
277 return ret;
278 }
279
update_call_states(struct audio_device * adev,const uint32_t vsid,const int call_state)280 static int update_call_states(struct audio_device *adev,
281 const uint32_t vsid, const int call_state)
282 {
283 struct voice_session *session = NULL;
284 int i = 0;
285 bool is_call_active;
286
287 for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
288 if (vsid == adev->voice.session[i].vsid) {
289 session = &adev->voice.session[i];
290 break;
291 }
292 }
293
294 if (session) {
295 session->state.new = call_state;
296 voice_extn_is_call_state_active(adev, &is_call_active);
297 ALOGD("%s is_call_active:%d in_call:%d, mode:%d\n",
298 __func__, is_call_active, adev->voice.in_call, adev->mode);
299 /* Dont start voice call before device routing for voice usescases has
300 * occured, otherwise voice calls will be started unintendedly on
301 * speaker.
302 */
303 if (is_call_active ||
304 (adev->voice.in_call && adev->mode == AUDIO_MODE_IN_CALL)) {
305 /* Device routing is not triggered for voice calls on the subsequent
306 * subs, Hence update the call states if voice call is already
307 * active on other sub.
308 */
309 update_calls(adev);
310 }
311 } else {
312 return -EINVAL;
313 }
314
315 return 0;
316
317 }
318
voice_extn_get_active_session_id(struct audio_device * adev,uint32_t * session_id)319 int voice_extn_get_active_session_id(struct audio_device *adev,
320 uint32_t *session_id)
321 {
322 *session_id = get_session_id_with_state(adev, CALL_ACTIVE);
323 return 0;
324 }
325
voice_extn_is_call_state_active(struct audio_device * adev,bool * is_call_active)326 int voice_extn_is_call_state_active(struct audio_device *adev, bool *is_call_active)
327 {
328 struct voice_session *session = NULL;
329 int i = 0;
330 *is_call_active = false;
331
332 for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
333 session = &adev->voice.session[i];
334 if(session->state.current != CALL_INACTIVE){
335 *is_call_active = true;
336 break;
337 }
338 }
339
340 return 0;
341 }
342
voice_extn_is_in_call_rec_stream(struct stream_in * in,bool * in_call_rec)343 int voice_extn_is_in_call_rec_stream(struct stream_in *in, bool *in_call_rec)
344 {
345 *in_call_rec = false;
346
347 if(in->source == AUDIO_SOURCE_VOICE_DOWNLINK ||
348 in->source == AUDIO_SOURCE_VOICE_UPLINK ||
349 in->source == AUDIO_SOURCE_VOICE_CALL) {
350 *in_call_rec = true;
351 }
352
353 return 0;
354 }
355
voice_extn_init(struct audio_device * adev)356 void voice_extn_init(struct audio_device *adev)
357 {
358 adev->voice.session[VOICE_SESS_IDX].vsid = VOICE_VSID;
359 adev->voice.session[VOICE2_SESS_IDX].vsid = VOICE2_VSID;
360 adev->voice.session[VOLTE_SESS_IDX].vsid = VOLTE_VSID;
361 adev->voice.session[QCHAT_SESS_IDX].vsid = QCHAT_VSID;
362 adev->voice.session[VOWLAN_SESS_IDX].vsid = VOWLAN_VSID;
363 }
364
voice_extn_get_session_from_use_case(struct audio_device * adev,const audio_usecase_t usecase_id,struct voice_session ** session)365 int voice_extn_get_session_from_use_case(struct audio_device *adev,
366 const audio_usecase_t usecase_id,
367 struct voice_session **session)
368 {
369
370 switch(usecase_id)
371 {
372 case USECASE_VOICE_CALL:
373 *session = &adev->voice.session[VOICE_SESS_IDX];
374 break;
375
376 case USECASE_VOICE2_CALL:
377 *session = &adev->voice.session[VOICE2_SESS_IDX];
378 break;
379
380 case USECASE_VOLTE_CALL:
381 *session = &adev->voice.session[VOLTE_SESS_IDX];
382 break;
383
384 case USECASE_QCHAT_CALL:
385 *session = &adev->voice.session[QCHAT_SESS_IDX];
386 break;
387
388 case USECASE_VOWLAN_CALL:
389 *session = &adev->voice.session[VOWLAN_SESS_IDX];
390 break;
391
392 default:
393 ALOGE("%s: Invalid usecase_id:%d\n", __func__, usecase_id);
394 *session = NULL;
395 return -EINVAL;
396 }
397
398 return 0;
399 }
400
voice_extn_start_call(struct audio_device * adev)401 int voice_extn_start_call(struct audio_device *adev)
402 {
403 /* Start voice calls on sessions whose call state has been
404 * udpated.
405 */
406 ALOGV("%s: enter:", __func__);
407 return update_calls(adev);
408 }
409
voice_extn_stop_call(struct audio_device * adev)410 int voice_extn_stop_call(struct audio_device *adev)
411 {
412 int i;
413 int ret = 0;
414
415 ALOGV("%s: enter:", __func__);
416
417 /* If BT device is enabled and voice calls are ended, telephony will call
418 * set_mode(AUDIO_MODE_NORMAL) which will trigger audio policy manager to
419 * set routing with device BT A2DP profile. Hence end all voice calls when
420 * set_mode(AUDIO_MODE_NORMAL) before BT A2DP profile is selected.
421 */
422 if (adev->mode == AUDIO_MODE_NORMAL) {
423 ALOGD("%s: end all calls", __func__);
424 for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
425 adev->voice.session[i].state.new = CALL_INACTIVE;
426 }
427
428 ret = update_calls(adev);
429 }
430
431 return ret;
432 }
433
voice_extn_set_parameters(struct audio_device * adev,struct str_parms * parms)434 int voice_extn_set_parameters(struct audio_device *adev,
435 struct str_parms *parms)
436 {
437 char *str;
438 int value;
439 int ret = 0, err;
440 char *kv_pairs = str_parms_to_str(parms);
441 char str_value[256] = {0};
442
443 ALOGV_IF(kv_pairs != NULL, "%s: enter: %s", __func__, kv_pairs);
444
445 err = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_VSID, &value);
446 if (err >= 0) {
447 str_parms_del(parms, AUDIO_PARAMETER_KEY_VSID);
448 uint32_t vsid = value;
449 int call_state = -1;
450 err = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_CALL_STATE, &value);
451 if (err >= 0) {
452 call_state = value;
453 str_parms_del(parms, AUDIO_PARAMETER_KEY_CALL_STATE);
454 } else {
455 ALOGE("%s: call_state key not found", __func__);
456 ret = -EINVAL;
457 goto done;
458 }
459
460 if (is_valid_vsid(vsid) && is_valid_call_state(call_state)) {
461 ret = update_call_states(adev, vsid, call_state);
462 } else {
463 ALOGE("%s: invalid vsid:%x or call_state:%d",
464 __func__, vsid, call_state);
465 ret = -EINVAL;
466 goto done;
467 }
468 }
469
470 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_DEVICE_MUTE, str_value,
471 sizeof(str_value));
472 if (err >= 0) {
473 str_parms_del(parms, AUDIO_PARAMETER_KEY_DEVICE_MUTE);
474 bool mute = false;
475
476 if (!strncmp("true", str_value, sizeof("true"))) {
477 mute = true;
478 }
479
480 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_DIRECTION, str_value,
481 sizeof(str_value));
482 if (err >= 0) {
483 str_parms_del(parms, AUDIO_PARAMETER_KEY_DIRECTION);
484 } else {
485 ALOGE("%s: direction key not found", __func__);
486 ret = -EINVAL;
487 goto done;
488 }
489
490 ret = platform_set_device_mute(adev->platform, mute, str_value);
491 if (ret != 0) {
492 ALOGE("%s: Failed to set mute err:%d", __func__, ret);
493 ret = -EINVAL;
494 goto done;
495 }
496 }
497
498 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_IN_CALL, str_value,
499 sizeof(str_value));
500 if (err >= 0) {
501 str_parms_del(parms, AUDIO_PARAMETER_KEY_IN_CALL);
502 if (!strncmp("true", str_value, sizeof("true"))) {
503 adev->voice.is_in_call = true;
504 }
505 }
506
507 done:
508 ALOGV("%s: exit with code(%d)", __func__, ret);
509 free(kv_pairs);
510 return ret;
511 }
512
get_all_call_states_str(const struct audio_device * adev,char * value)513 static int get_all_call_states_str(const struct audio_device *adev,
514 char *value)
515 {
516 int ret = 0;
517 char *cur_ptr = value;
518 int i, len=0;
519
520 for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
521 snprintf(cur_ptr, VOICE_EXTN_PARAMETER_VALUE_MAX_LEN - len,
522 "%d:%d,",adev->voice.session[i].vsid,
523 adev->voice.session[i].state.current);
524 len = strlen(cur_ptr);
525 cur_ptr = cur_ptr + len;
526 }
527 ALOGV("%s:value=%s", __func__, value);
528 return ret;
529 }
530
voice_extn_get_parameters(const struct audio_device * adev,struct str_parms * query,struct str_parms * reply)531 void voice_extn_get_parameters(const struct audio_device *adev,
532 struct str_parms *query,
533 struct str_parms *reply)
534 {
535 int ret;
536 char value[VOICE_EXTN_PARAMETER_VALUE_MAX_LEN] = {0};
537 char *str = str_parms_to_str(query);
538 int val = 0;
539
540 ALOGV_IF(str != NULL, "%s: enter %s", __func__, str);
541 free(str);
542
543 ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_IN_CALL, value,
544 sizeof(value));
545 if (ret >=0) {
546 if (adev->voice.is_in_call)
547 val = 1;
548 str_parms_add_int(reply, AUDIO_PARAMETER_KEY_IN_CALL, val);
549 }
550
551 ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_AUDIO_MODE, value,
552 sizeof(value));
553 if (ret >= 0) {
554 str_parms_add_int(reply, AUDIO_PARAMETER_KEY_AUDIO_MODE, adev->mode);
555 }
556
557 ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_ALL_CALL_STATES,
558 value, sizeof(value));
559 if (ret >= 0) {
560 ret = get_all_call_states_str(adev, value);
561 if (ret) {
562 ALOGE("%s: Error fetching call states, err:%d", __func__, ret);
563 return;
564 }
565 str_parms_add_str(reply, AUDIO_PARAMETER_KEY_ALL_CALL_STATES, value);
566 }
567 voice_extn_compress_voip_get_parameters(query, reply);
568
569 str = str_parms_to_str(reply);
570 ALOGV_IF(str != NULL, "%s: exit: returns \"%s\"", __func__, str);
571 free(str);
572 }
573
voice_extn_out_get_parameters(struct stream_out * out,struct str_parms * query,struct str_parms * reply)574 void voice_extn_out_get_parameters(struct stream_out *out,
575 struct str_parms *query,
576 struct str_parms *reply)
577 {
578 voice_extn_compress_voip_out_get_parameters(out, query, reply);
579 }
580
voice_extn_in_get_parameters(struct stream_in * in,struct str_parms * query,struct str_parms * reply)581 void voice_extn_in_get_parameters(struct stream_in *in,
582 struct str_parms *query,
583 struct str_parms *reply)
584 {
585 voice_extn_compress_voip_in_get_parameters(in, query, reply);
586 }
587
588 #ifdef INCALL_MUSIC_ENABLED
voice_extn_check_and_set_incall_music_usecase(struct audio_device * adev,struct stream_out * out)589 int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev,
590 struct stream_out *out)
591 {
592 uint32_t session_id = 0;
593
594 session_id = get_session_id_with_state(adev, CALL_LOCAL_HOLD);
595 if (session_id == VOICE_VSID) {
596 out->usecase = USECASE_INCALL_MUSIC_UPLINK;
597 } else if (session_id == VOICE2_VSID) {
598 out->usecase = USECASE_INCALL_MUSIC_UPLINK2;
599 } else {
600 ALOGE("%s: Invalid session id %x", __func__, session_id);
601 return -EINVAL;
602 }
603
604 out->config = pcm_config_incall_music;
605 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_MONO;
606 out->channel_mask = AUDIO_CHANNEL_OUT_MONO;
607
608 return 0;
609 }
610 #endif
611
612