1 /*
2  * Copyright (C) 2018 Knowles Electronics
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "SoundTriggerHAL"
18 #define LOG_NDEBUG 0
19 
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <malloc.h>
23 #include <poll.h>
24 #include <pthread.h>
25 #include <sys/ioctl.h>
26 #include <sys/prctl.h>
27 #include <log/log.h>
28 #include <cutils/uevent.h>
29 #include <cutils/properties.h>
30 #include <math.h>
31 #include <dlfcn.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <unistd.h>
35 #include <sys/timerfd.h>
36 
37 #include <hardware/hardware.h>
38 #include <hardware_legacy/power.h>
39 
40 #include "cvq_ioctl.h"
41 #include "sound_trigger_hw_iaxxx.h"
42 #include "sound_trigger_intf.h"
43 
44 #define MAX_GENERIC_SOUND_MODELS    (9)
45 #define MAX_KEY_PHRASES             (1)
46 #define MAX_MODELS                  (MAX_GENERIC_SOUND_MODELS + MAX_KEY_PHRASES)
47 
48 #define MAX_USERS                   (1)
49 #define MAX_BUFFER_MS               (3000)
50 #define POWER_CONSUMPTION           (0) // TBD
51 #define ST_HAL_VERSION              (1)
52 
53 #define UEVENT_MSG_LEN              (1024)
54 
55 #define OK_GOOGLE_KW_ID             (0)
56 #define AMBIENT_KW_ID               (1)
57 #define ENTITY_KW_ID                (2)
58 #define WAKEUP_KW_ID                (3)
59 #define USELESS_KW_ID               (999)
60 
61 #define CVQ_ENDPOINT                    (IAXXX_SYSID_PLUGIN_1_OUT_EP_0)
62 #define MUSIC_BUF_ENDPOINT              (IAXXX_SYSID_PLUGIN_3_OUT_EP_1)
63 
64 #define IAXXX_VQ_EVENT_STR          "IAXXX_VQ_EVENT"
65 #define IAXXX_RECOVERY_EVENT_STR    "IAXXX_RECOVERY_EVENT"
66 #define IAXXX_FW_DWNLD_SUCCESS_STR  "IAXXX_FW_DWNLD_SUCCESS"
67 #define IAXXX_FW_CRASH_EVENT_STR    "IAXXX_CRASH_EVENT"
68 
69 #define WAKE_LOCK_NAME "sthal_wake_lock"
70 
71 #define CARD_NAME                          "iaxxx"
72 #define SOUND_TRIGGER_MIXER_PATH_BASE      "/vendor/etc/sound_trigger_mixer_paths"
73 #define SOUND_TRIGGER_MIXER_PATH_XML       "/vendor/etc/sound_trigger_mixer_paths_default.xml"
74 
75 #define MAX_SND_CARD    (8)
76 #define RETRY_NUMBER    (10)
77 #define RETRY_US        (500000)
78 #define TUNNEL_TIMEOUT  5
79 
80 #define SENSOR_CREATE_WAIT_TIME_IN_S   (1)
81 #define SENSOR_CREATE_WAIT_MAX_COUNT   (5)
82 
83 #define CHRE_CREATE_WAIT_TIME_IN_S   (1)
84 #define CHRE_CREATE_WAIT_MAX_COUNT   (5)
85 
86 #define ST_DEVICE_HANDSET_MIC 1
87 
88 #ifdef __LP64__
89 #define ADNC_STRM_LIBRARY_PATH "/vendor/lib64/hw/adnc_strm.primary.default.so"
90 #else
91 #define ADNC_STRM_LIBRARY_PATH "/vendor/lib/hw/adnc_strm.primary.default.so"
92 #endif
93 
94 static const struct sound_trigger_properties hw_properties = {
95     "Knowles Electronics",      // implementor
96     "Continous VoiceQ",         // description
97     1,                          // version
98     // Version UUID
99     { 0x80f7dcd5, 0xbb62, 0x4816, 0xa931, {0x9c, 0xaa, 0x52, 0x5d, 0xf5, 0xc7}},
100     MAX_MODELS,                 // max_sound_models
101     MAX_KEY_PHRASES,            // max_key_phrases
102     MAX_USERS,                  // max_users
103     RECOGNITION_MODE_VOICE_TRIGGER | // recognition_mode
104     RECOGNITION_MODE_GENERIC_TRIGGER,
105     true,                       // capture_transition
106     MAX_BUFFER_MS,              // max_capture_ms
107     true,                      // concurrent_capture
108     false,                      // trigger_in_event
109     POWER_CONSUMPTION           // power_consumption_mw
110 };
111 
112 struct model_info {
113     void *recognition_cookie;
114     void *sound_model_cookie;
115     sound_model_handle_t model_handle;
116     sound_trigger_uuid_t uuid;
117     recognition_callback_t recognition_callback;
118     sound_model_callback_t sound_model_callback;
119     struct sound_trigger_recognition_config *config;
120     int kw_id;
121     sound_trigger_sound_model_type_t type;
122 
123     void *data;
124     int data_sz;
125     bool is_loaded;
126     bool is_active;
127     bool is_state_query;
128 };
129 
130 struct knowles_sound_trigger_device {
131     struct sound_trigger_hw_device device;
132     struct model_info models[MAX_MODELS];
133     sound_trigger_uuid_t authkw_model_uuid;
134     pthread_t callback_thread;
135     pthread_t monitor_thread;
136     pthread_t transitions_thread;
137     pthread_mutex_t lock;
138     pthread_cond_t transition_cond;
139     pthread_cond_t tunnel_create;
140     pthread_cond_t sensor_create;
141     pthread_cond_t chre_create;
142     int opened;
143     int send_sock;
144     int recv_sock;
145     struct sound_trigger_recognition_config *last_keyword_detected_config;
146 
147     // Information about streaming
148     int is_streaming;
149     void *adnc_cvq_strm_lib;
150     int (*adnc_strm_open)(bool, int, int);
151     size_t (*adnc_strm_read)(long, void *, size_t);
152     int (*adnc_strm_close)(long);
153     long adnc_strm_handle[MAX_MODELS];
154     struct timespec adnc_strm_last_read[MAX_MODELS];
155 
156     sound_trigger_uuid_t hotword_model_uuid;
157     sound_trigger_uuid_t sensor_model_uuid;
158     sound_trigger_uuid_t ambient_model_uuid;
159     sound_trigger_uuid_t chre_model_uuid;
160     sound_trigger_uuid_t entity_model_uuid;
161     sound_trigger_uuid_t wakeup_model_uuid;
162 
163     int last_detected_model_type;
164     bool is_mic_route_enabled;
165     bool is_bargein_route_enabled;
166     bool is_chre_loaded;
167     bool is_buffer_package_loaded;
168     bool is_sensor_route_enabled;
169     bool is_src_package_loaded;
170     bool is_st_hal_ready;
171     int hotword_buffer_enable;
172     int music_buffer_enable;
173     bool is_sensor_destroy_in_prog;
174     bool is_chre_destroy_in_prog;
175 
176     // conditions indicate AHAL and mic concurrency status
177     bool is_concurrent_capture;
178     bool is_con_mic_route_enabled;
179     bool is_ahal_media_recording;
180     bool is_ahal_in_voice_voip_mode;
181     bool is_ahal_voice_voip_stop;
182     bool is_ahal_voice_voip_start;
183 
184     unsigned int current_enable;
185     unsigned int recover_model_list;
186     unsigned int rx_active_count;
187     transit_case_t transit_case;
188 
189     struct audio_route *route_hdl;
190     struct mixer *mixer;
191     struct iaxxx_odsp_hw *odsp_hdl;
192 
193     void *audio_hal_handle;
194     audio_hw_call_back_t audio_hal_cb;
195     unsigned int sthal_prop_api_version;
196 
197     int snd_crd_num;
198     char mixer_path_xml[NAME_MAX_SIZE];
199     bool fw_reset_done_by_hal;
200 
201     // sensor stop signal event
202     timer_t ss_timer;
203     bool ss_timer_created;
204 
205     // Chre stop signal event
206     timer_t chre_timer;
207     bool chre_timer_created;
208 };
209 
210 /*
211  * Since there's only ever one sound_trigger_device, keep it as a global so
212  * that other people can dlopen this lib to get at the streaming audio.
213  */
214 
215 static struct knowles_sound_trigger_device g_stdev =
216 {
217     .lock = PTHREAD_MUTEX_INITIALIZER,
218     .tunnel_create = PTHREAD_COND_INITIALIZER,
219     .sensor_create = PTHREAD_COND_INITIALIZER,
220     .chre_create = PTHREAD_COND_INITIALIZER
221 };
222 
223 static struct timespec reset_time = {0};
224 
get_sthal_mode(struct knowles_sound_trigger_device * stdev)225 static enum sthal_mode get_sthal_mode(struct knowles_sound_trigger_device *stdev)
226 {
227     enum sthal_mode stmode = CON_DISABLED_ST;
228 
229     if (stdev->is_ahal_in_voice_voip_mode == true) {
230         stmode = IN_CALL;
231         goto exit;
232     }
233 
234     if (stdev->is_concurrent_capture == false) {
235         if (stdev->is_ahal_media_recording == true)
236           stmode = CON_DISABLED_CAPTURE;
237         else
238           stmode = CON_DISABLED_ST;
239         goto exit;
240     }
241 
242     if (stdev->is_con_mic_route_enabled == true ) {
243         stmode = CON_ENABLED_CAPTURE_ST;
244         goto exit;
245     } else {
246         stmode = CON_ENABLED_ST;
247         goto exit;
248     }
249 
250     ALOGW("%s: Invalid ST mode, use defualt mode", __func__);
251 
252 exit:
253     //ALOGV("%s: ST mode is %d", __func__, stmode);
254     return stmode;
255 }
256 
can_enable_chre(struct knowles_sound_trigger_device * stdev)257 static bool can_enable_chre(struct knowles_sound_trigger_device *stdev)
258 {
259     bool ret = false;
260     enum sthal_mode stm = get_sthal_mode(stdev);
261 
262     if (stm == CON_ENABLED_CAPTURE_ST ||
263         stm == CON_ENABLED_ST ||
264         stm == CON_DISABLED_ST)
265         ret = true;
266     return ret;
267 }
268 
can_update_recover_list(struct knowles_sound_trigger_device * stdev)269 static bool can_update_recover_list(struct knowles_sound_trigger_device *stdev)
270 {
271     bool ret = false;
272     enum sthal_mode stm = get_sthal_mode(stdev);
273 
274     if (stm == IN_CALL || stm == CON_DISABLED_CAPTURE)
275         ret = true;
276     return ret;
277 }
278 
is_mic_controlled_by_ahal(struct knowles_sound_trigger_device * stdev)279 static bool is_mic_controlled_by_ahal(struct knowles_sound_trigger_device *stdev)
280 {
281     bool ret = false;
282 
283     if (get_sthal_mode(stdev) == CON_ENABLED_CAPTURE_ST)
284         ret = true;
285     return ret;
286 }
287 
check_uuid_equality(sound_trigger_uuid_t uuid1,sound_trigger_uuid_t uuid2)288 static bool check_uuid_equality(sound_trigger_uuid_t uuid1,
289                                 sound_trigger_uuid_t uuid2)
290 {
291     if (uuid1.timeLow != uuid2.timeLow ||
292         uuid1.timeMid != uuid2.timeMid ||
293         uuid1.timeHiAndVersion != uuid2.timeHiAndVersion ||
294         uuid1.clockSeq != uuid2.clockSeq) {
295         return false;
296     }
297 
298     for (int i = 0; i < 6; i++) {
299         if(uuid1.node[i] != uuid2.node[i]) {
300             return false;
301         }
302     }
303 
304     return true;
305 }
306 
str_to_uuid(char * uuid_str,sound_trigger_uuid_t * uuid)307 bool str_to_uuid(char* uuid_str, sound_trigger_uuid_t* uuid)
308 {
309     if (uuid_str == NULL) {
310         ALOGI("Invalid str_to_uuid input.");
311         return false;
312     }
313 
314     int tmp[10];
315     if (sscanf(uuid_str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
316             tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5,
317             tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
318         ALOGI("Invalid UUID, got: %s", uuid_str);
319         return false;
320     }
321     uuid->timeLow = (unsigned int)tmp[0];
322     uuid->timeMid = (unsigned short)tmp[1];
323     uuid->timeHiAndVersion = (unsigned short)tmp[2];
324     uuid->clockSeq = (unsigned short)tmp[3];
325     uuid->node[0] = (unsigned char)tmp[4];
326     uuid->node[1] = (unsigned char)tmp[5];
327     uuid->node[2] = (unsigned char)tmp[6];
328     uuid->node[3] = (unsigned char)tmp[7];
329     uuid->node[4] = (unsigned char)tmp[8];
330     uuid->node[5] = (unsigned char)tmp[9];
331 
332     return true;
333 }
334 
find_empty_model_slot(struct knowles_sound_trigger_device * st_dev)335 static int find_empty_model_slot(struct knowles_sound_trigger_device *st_dev)
336 {
337     int i = -1;
338     for (i = 0; i < MAX_MODELS; i++) {
339         if (st_dev->models[i].is_loaded == false)
340             break;
341     }
342 
343     if (i >= MAX_MODELS) {
344         i = -1;
345     }
346 
347     return i;
348 }
349 
find_handle_for_kw_id(struct knowles_sound_trigger_device * st_dev,int kw_id)350 static int find_handle_for_kw_id(
351                         struct knowles_sound_trigger_device *st_dev, int kw_id)
352 {
353     int i = 0;
354     for (i = 0; i < MAX_MODELS; i++) {
355         if (kw_id == st_dev->models[i].kw_id)
356             break;
357     }
358 
359     return i;
360 }
361 
find_handle_for_uuid(struct knowles_sound_trigger_device * stdev,sound_trigger_uuid_t uuid)362 static int find_handle_for_uuid(
363                         struct knowles_sound_trigger_device *stdev,
364                         sound_trigger_uuid_t uuid)
365 {
366     int i = 0;
367     for (i = 0; i < MAX_MODELS; i++) {
368         if (check_uuid_equality(uuid, stdev->models[i].uuid))
369             break;
370     }
371 
372     if (i == MAX_MODELS)
373         return -1;
374     else
375         return i;
376 }
377 
is_any_model_active(struct knowles_sound_trigger_device * stdev)378 static bool is_any_model_active(struct knowles_sound_trigger_device *stdev) {
379     int i = 0;
380     for (i = 0; i < MAX_MODELS; i++) {
381         if (stdev->models[i].is_active == true) {
382             break;
383         }
384     }
385 
386     if (i == MAX_MODELS)
387         return false;
388     else
389         return true;
390 }
391 
is_any_model_loaded(struct knowles_sound_trigger_device * stdev)392 static bool is_any_model_loaded(struct knowles_sound_trigger_device *stdev) {
393     int i = 0;
394     for (i = 0; i < MAX_MODELS; i++) {
395         if (stdev->models[i].is_loaded == true) {
396             break;
397         }
398     }
399 
400     if (i == MAX_MODELS)
401         return false;
402     else
403         return true;
404 }
405 
reg_hal_event_session(struct sound_trigger_recognition_config * config,sound_model_handle_t handle)406 static void reg_hal_event_session(
407                                 struct sound_trigger_recognition_config *config,
408                                 sound_model_handle_t handle)
409 {
410     struct knowles_sound_trigger_device *stdev = &g_stdev;
411     struct sound_trigger_event_info event_info;
412     /*
413      * Register config and capture_handle of trigger sound model to audio hal
414      * It only register while request capturing buffer.
415      */
416     if (config->capture_requested && stdev->audio_hal_cb) {
417         ALOGD("%s: ST_EVENT_SESSION_REGISTER capture_handle %d model %p",
418             __func__, config->capture_handle, &stdev->models[handle]);
419         event_info.st_ses.p_ses = (void *)&stdev->models[handle];
420         event_info.st_ses.config = stdev_hotword_pcm_config;
421         event_info.st_ses.capture_handle = config->capture_handle;
422         event_info.st_ses.pcm = NULL;
423         stdev->audio_hal_cb(ST_EVENT_SESSION_REGISTER, &event_info);
424     }
425 }
426 
dereg_hal_event_session(struct sound_trigger_recognition_config * config,sound_model_handle_t handle)427 static void dereg_hal_event_session(
428                                 struct sound_trigger_recognition_config *config,
429                                 sound_model_handle_t handle)
430 {
431     struct knowles_sound_trigger_device *stdev = &g_stdev;
432     struct sound_trigger_event_info event_info;
433     /*
434      * Indicate to audio hal that streaming is stopped.
435      * Stop capturing data from STHAL.
436      */
437     if (config->capture_requested && stdev->audio_hal_cb) {
438         ALOGD("%s: ST_EVENT_SESSION_DEREGISTER capture_handle %d model %p",
439             __func__, config->capture_handle, &stdev->models[handle]);
440         event_info.st_ses.p_ses = (void *)&stdev->models[handle];
441         event_info.st_ses.capture_handle = config->capture_handle;
442         event_info.st_ses.pcm = NULL;
443         stdev->audio_hal_cb(ST_EVENT_SESSION_DEREGISTER, &event_info);
444     }
445 }
446 
447 
stdev_keyphrase_event_alloc(sound_model_handle_t handle,struct sound_trigger_recognition_config * config,int recognition_status)448 static char *stdev_keyphrase_event_alloc(sound_model_handle_t handle,
449                                 struct sound_trigger_recognition_config *config,
450                                 int recognition_status)
451 {
452     char *data;
453     struct sound_trigger_phrase_recognition_event *event;
454     data = (char *)calloc(1,
455                         sizeof(struct sound_trigger_phrase_recognition_event));
456     if (!data)
457         return NULL;
458     event = (struct sound_trigger_phrase_recognition_event *)data;
459     event->common.status = recognition_status;
460     event->common.type = SOUND_MODEL_TYPE_KEYPHRASE;
461     event->common.model = handle;
462     event->common.capture_available = false;
463 
464     if (config) {
465         unsigned int i;
466 
467         event->num_phrases = config->num_phrases;
468         if (event->num_phrases > SOUND_TRIGGER_MAX_PHRASES)
469             event->num_phrases = SOUND_TRIGGER_MAX_PHRASES;
470         for (i = 0; i < event->num_phrases; i++)
471             memcpy(&event->phrase_extras[i],
472                 &config->phrases[i],
473                 sizeof(struct sound_trigger_phrase_recognition_extra));
474     }
475 
476     event->num_phrases = 1;
477     event->phrase_extras[0].confidence_level = 100;
478     event->phrase_extras[0].num_levels = 1;
479     event->phrase_extras[0].levels[0].level = 100;
480     event->phrase_extras[0].levels[0].user_id = 0;
481     /*
482      * Signify that all the data is comming through streaming
483      * and not through the buffer.
484      */
485     event->common.capture_available = true;
486     event->common.capture_delay_ms = 0;
487     event->common.capture_preamble_ms = 0;
488     event->common.audio_config = AUDIO_CONFIG_INITIALIZER;
489     event->common.audio_config.sample_rate = 16000;
490     event->common.audio_config.channel_mask = AUDIO_CHANNEL_IN_MONO;
491     event->common.audio_config.format = AUDIO_FORMAT_PCM_16_BIT;
492 
493     return data;
494 }
495 
stdev_generic_event_alloc(int model_handle,void * payload,unsigned int payload_size,int recognition_status)496 static char *stdev_generic_event_alloc(int model_handle, void *payload,
497                                     unsigned int payload_size,
498                                     int recognition_status)
499 {
500     char *data;
501     struct sound_trigger_generic_recognition_event *event;
502 
503     data = (char *)calloc(1,
504                         sizeof(struct sound_trigger_generic_recognition_event) +
505                         payload_size);
506     if (!data) {
507         ALOGE("%s: Failed to allocate memory for recog event", __func__);
508         return NULL;
509     }
510 
511     event = (struct sound_trigger_generic_recognition_event *)data;
512     event->common.status = recognition_status;
513     event->common.type = SOUND_MODEL_TYPE_GENERIC;
514     event->common.model = model_handle;
515 
516     /*
517      * Signify that all the data is comming through streaming and
518      * not through the buffer.
519      */
520     event->common.capture_available = true;
521     event->common.audio_config = AUDIO_CONFIG_INITIALIZER;
522     event->common.audio_config.sample_rate = 16000;
523     event->common.audio_config.channel_mask = AUDIO_CHANNEL_IN_MONO;
524     event->common.audio_config.format = AUDIO_FORMAT_PCM_16_BIT;
525 
526     if (payload && payload_size > 0) {
527         ALOGD("%s: Attach payload in the event", __func__);
528         event->common.data_size = payload_size;
529         event->common.data_offset =
530                         sizeof(struct sound_trigger_generic_recognition_event);
531 
532         memcpy((data + event->common.data_offset), payload, payload_size);
533     }
534 
535     return data;
536 }
537 
stdev_close_term_sock(struct knowles_sound_trigger_device * stdev)538 static void stdev_close_term_sock(struct knowles_sound_trigger_device *stdev)
539 {
540     if (stdev->send_sock >= 0) {
541         close(stdev->send_sock);
542         stdev->send_sock = -1;
543     }
544 
545     if (stdev->recv_sock >= 0) {
546         close(stdev->recv_sock);
547         stdev->recv_sock = -1;
548     }
549 }
550 
is_uuid_in_recover_list(struct knowles_sound_trigger_device * stdev,sound_model_handle_t handle)551 static bool is_uuid_in_recover_list(struct knowles_sound_trigger_device *stdev,
552                                     sound_model_handle_t handle)
553 {
554     int mask = 0;
555     sound_trigger_uuid_t target_uuid = stdev->models[handle].uuid;
556 
557     if (check_uuid_equality(target_uuid, stdev->chre_model_uuid)) {
558         mask = CHRE_MASK;
559     } else if (check_uuid_equality(target_uuid, stdev->hotword_model_uuid) ||
560                check_uuid_equality(target_uuid, stdev->wakeup_model_uuid)) {
561         mask = PLUGIN1_MASK;
562     } else if (check_uuid_equality(target_uuid, stdev->ambient_model_uuid) ||
563                check_uuid_equality(target_uuid, stdev->entity_model_uuid)) {
564         mask = PLUGIN2_MASK;
565     } else {
566        //ALOGV("%s: Invalid uuid.", __func__);
567     }
568 
569     return (stdev->recover_model_list & mask) ? true : false;
570 }
571 
update_recover_list(struct knowles_sound_trigger_device * stdev,sound_model_handle_t handle,bool enable)572 static void update_recover_list(struct knowles_sound_trigger_device *stdev,
573                                 sound_model_handle_t handle,
574                                 bool enable)
575 {
576     int mask = 0;
577 
578     sound_trigger_uuid_t target_uuid = stdev->models[handle].uuid;
579 
580     ALOGD("%s: handle %d enable %d", __func__, handle, enable);
581     if (check_uuid_equality(target_uuid, stdev->chre_model_uuid)) {
582         mask = CHRE_MASK;
583     } else if (check_uuid_equality(target_uuid, stdev->hotword_model_uuid) ||
584                check_uuid_equality(target_uuid, stdev->wakeup_model_uuid)) {
585         mask = PLUGIN1_MASK;
586     } else if (check_uuid_equality(target_uuid, stdev->ambient_model_uuid) ||
587                check_uuid_equality(target_uuid, stdev->entity_model_uuid)) {
588         mask = PLUGIN2_MASK;
589     } else {
590        //ALOGV("%s: Invalid uuid.", __func__);
591     }
592 
593     if (enable)
594         stdev->recover_model_list |= mask;
595     else
596         stdev->recover_model_list &= ~mask;
597 
598     return;
599 }
600 
check_and_setup_src_package(struct knowles_sound_trigger_device * stdev)601 static int check_and_setup_src_package(
602                                     struct knowles_sound_trigger_device *stdev)
603 {
604     int err = 0;
605 
606     if (stdev->is_src_package_loaded == false) {
607         err = setup_src_package(stdev->odsp_hdl);
608         if (err != 0) {
609             ALOGE("%s: Failed to load SRC package", __func__);
610             goto exit;
611         } else {
612             ALOGD("%s: SRC package loaded", __func__);
613             stdev->is_src_package_loaded = true;
614         }
615     } else {
616         ALOGD("%s: SRC package is already loaded", __func__);
617     }
618 
619 exit:
620     return err;
621 }
622 
check_and_destroy_src_package(struct knowles_sound_trigger_device * stdev)623 static int check_and_destroy_src_package(
624                                     struct knowles_sound_trigger_device *stdev)
625 {
626     int err = 0;
627 
628     if (!is_any_model_active(stdev) && stdev->is_src_package_loaded == true) {
629         err = destroy_src_package(stdev->odsp_hdl);
630         if (err != 0) {
631             ALOGE("%s: Failed to destroy SRC package", __func__);
632             goto exit;
633         } else {
634             ALOGD("%s: SRC package destroy", __func__);
635             stdev->is_src_package_loaded = false;
636         }
637     }
638 
639 exit:
640     return err;
641 }
642 
check_and_setup_buffer_package(struct knowles_sound_trigger_device * stdev)643 static int check_and_setup_buffer_package(
644                                     struct knowles_sound_trigger_device *stdev)
645 {
646     int err = 0;
647 
648     if (stdev->is_buffer_package_loaded == false) {
649         err = setup_buffer_package(stdev->odsp_hdl);
650         if (err != 0) {
651             ALOGE("%s: Failed to load Buffer package", __func__);
652             goto exit;
653         } else {
654             ALOGD("%s: Buffer package loaded", __func__);
655             stdev->is_buffer_package_loaded = true;
656         }
657     } else {
658         ALOGD("%s: Buffer package is already loaded", __func__);
659     }
660 
661 exit:
662     return err;
663 }
664 
check_and_destroy_buffer_package(struct knowles_sound_trigger_device * stdev)665 static int check_and_destroy_buffer_package(
666                                     struct knowles_sound_trigger_device *stdev)
667 {
668     int err = 0;
669 
670     if (!is_any_model_active(stdev) &&
671         stdev->is_buffer_package_loaded &&
672         (!stdev->is_sensor_destroy_in_prog &&
673         !stdev->is_sensor_route_enabled) &&
674         (!stdev->is_chre_destroy_in_prog &&
675         !stdev->is_chre_loaded)) {
676 
677         err = destroy_buffer_package(stdev->odsp_hdl);
678         if (err != 0) {
679             ALOGE("%s: Failed to destroy Buffer package", __func__);
680             goto exit;
681         } else {
682             ALOGD("%s: Buffer package destroy", __func__);
683             stdev->is_buffer_package_loaded = false;
684         }
685     }
686 
687 exit:
688     return err;
689 }
690 
setup_package(struct knowles_sound_trigger_device * stdev,struct model_info * model)691 static int setup_package(struct knowles_sound_trigger_device *stdev,
692                         struct model_info *model)
693 {
694     int err = 0;
695 
696     if (check_uuid_equality(model->uuid, stdev->chre_model_uuid)) {
697         if (!(stdev->current_enable & CHRE_MASK)) {
698             err = setup_chre_package(stdev->odsp_hdl);
699             if (err != 0) {
700                 ALOGE("Failed to load CHRE package");
701                 goto exit;
702             }
703         }
704         stdev->current_enable = stdev->current_enable | CHRE_MASK;
705     } else if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid)) {
706         if (!(stdev->current_enable & PLUGIN1_MASK)) {
707             err = setup_hotword_package(stdev->odsp_hdl);
708             if (err != 0) {
709                 ALOGE("Failed to load Hotword package");
710                 goto exit;
711             }
712         }
713         err = write_model(stdev->odsp_hdl, model->data, model->data_sz,
714                         model->kw_id);
715         if (err != 0) {
716             ALOGE("Failed to write Hotword model");
717             goto exit;
718         }
719 
720         //setup model state.
721         stdev->current_enable = stdev->current_enable | HOTWORD_MASK;
722         err = set_hotword_state(stdev->odsp_hdl, stdev->current_enable);
723         if (err != 0) {
724             ALOGE("Failed to set Hotword state");
725             goto exit;
726         }
727     } else if (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid)) {
728         if (!(stdev->current_enable & PLUGIN1_MASK)) {
729             err = setup_hotword_package(stdev->odsp_hdl);
730             if (err != 0) {
731                 ALOGE("Failed to load Hotword package");
732                 goto exit;
733             }
734         }
735         err = write_model(stdev->odsp_hdl, model->data, model->data_sz,
736                         model->kw_id);
737         if (err != 0) {
738             ALOGE("Failed to write Wakeup model");
739             goto exit;
740         }
741 
742         //setup model state.
743         stdev->current_enable = stdev->current_enable | WAKEUP_MASK;
744         err = set_hotword_state(stdev->odsp_hdl, stdev->current_enable);
745         if (err != 0) {
746             ALOGE("Failed to set Wakeup state");
747             goto exit;
748         }
749     } else if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid)) {
750         if (!(stdev->current_enable & PLUGIN2_MASK)) {
751             err = setup_ambient_package(stdev->odsp_hdl);
752             if (err != 0) {
753                 ALOGE("Failed to load Ambient package");
754                 goto exit;
755             }
756         } else {
757             // tear down plugin2 for writing new model data.
758             err = tear_ambient_state(stdev->odsp_hdl,
759                                     stdev->current_enable);
760         }
761         err = write_model(stdev->odsp_hdl, model->data,
762                         model->data_sz, model->kw_id);
763         if (err != 0) {
764             ALOGE("Failed to write Ambient model");
765             goto exit;
766         }
767 
768         //setup model state.
769         stdev->current_enable = stdev->current_enable | AMBIENT_MASK;
770         err = set_ambient_state(stdev->odsp_hdl, stdev->current_enable);
771         if (err != 0) {
772             ALOGE("Failed to set Ambient state");
773             goto exit;
774         }
775 
776     } else if (check_uuid_equality(model->uuid, stdev->entity_model_uuid)) {
777         if (!(stdev->current_enable & PLUGIN2_MASK)) {
778             err = setup_ambient_package(stdev->odsp_hdl);
779             if (err != 0) {
780                 ALOGE("Failed to load Ambient package");
781                 goto exit;
782             }
783         } else {
784             // tear down plugin2 for writing new model data.
785             err = tear_ambient_state(stdev->odsp_hdl,
786                                     stdev->current_enable);
787         }
788         err = write_model(stdev->odsp_hdl, model->data,
789                         model->data_sz, model->kw_id);
790         if (err != 0) {
791             ALOGE("Failed to write Entity model");
792             goto exit;
793         }
794 
795         //setup model state.
796         stdev->current_enable = stdev->current_enable | ENTITY_MASK;
797         err = set_ambient_state(stdev->odsp_hdl, stdev->current_enable);
798         if (err != 0) {
799             ALOGE("Failed to set Entity state");
800             goto exit;
801         }
802     }
803 
804 exit:
805     return err;
806 }
807 
setup_buffer(struct knowles_sound_trigger_device * stdev,struct model_info * model,bool enabled)808 static int setup_buffer(struct knowles_sound_trigger_device *stdev,
809                         struct model_info *model,
810                         bool enabled)
811 {
812     int err = 0;
813     if (enabled) {
814         if ((check_uuid_equality(model->uuid, stdev->hotword_model_uuid))
815             || (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))) {
816 
817             stdev->hotword_buffer_enable++;
818             if (stdev->hotword_buffer_enable > 1)
819                 goto exit;
820 
821             err = setup_howord_buffer(stdev->odsp_hdl);
822             if (err != 0) {
823                 stdev->hotword_buffer_enable--;
824                 ALOGE("Failed to create the buffer plugin");
825                 goto exit;
826             }
827         } else if ((check_uuid_equality(model->uuid, stdev->ambient_model_uuid))
828             || (check_uuid_equality(model->uuid, stdev->entity_model_uuid))) {
829 
830             stdev->music_buffer_enable++;
831             if (stdev->music_buffer_enable > 1)
832                 goto exit;
833 
834             err = setup_music_buffer(stdev->odsp_hdl);
835             if (err != 0) {
836                 stdev->music_buffer_enable--;
837                 ALOGE("Failed to load music buffer package");
838                 goto exit;
839             }
840         }
841     } else {
842         if ((check_uuid_equality(model->uuid, stdev->hotword_model_uuid))
843            || (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))) {
844             if (stdev->hotword_buffer_enable == 0) {
845                 ALOGW("Invalid call for setup buffer");
846                 goto exit;
847             }
848             stdev->hotword_buffer_enable--;
849             if (stdev->hotword_buffer_enable != 0)
850                 goto exit;
851 
852             err = destroy_howord_buffer(stdev->odsp_hdl);
853 
854             if (err != 0) {
855                 ALOGE("Failed to unload hotword buffer package");
856                 goto exit;
857             }
858 
859         } else if ((check_uuid_equality(model->uuid, stdev->ambient_model_uuid))
860            || (check_uuid_equality(model->uuid, stdev->entity_model_uuid))) {
861             if (stdev->music_buffer_enable == 0) {
862                 ALOGW("Invalid call for setup buffer");
863                 goto exit;
864             }
865             stdev->music_buffer_enable--;
866             if (stdev->music_buffer_enable != 0)
867                 goto exit;
868 
869             err = destroy_music_buffer(stdev->odsp_hdl);
870             if (err != 0) {
871                 ALOGE("Failed to unload music buffer package");
872                 goto exit;
873             }
874        }
875     }
876 
877 exit:
878     return err;
879 }
880 
destroy_package(struct knowles_sound_trigger_device * stdev,struct model_info * model)881 static int destroy_package(struct knowles_sound_trigger_device *stdev,
882                         struct model_info *model)
883 {
884     int err = 0;
885 
886     if (check_uuid_equality(model->uuid, stdev->chre_model_uuid)) {
887         stdev->current_enable = stdev->current_enable & ~CHRE_MASK;
888         if (!(stdev->current_enable & CHRE_MASK)) {
889             err = destroy_chre_package(stdev->odsp_hdl);
890             if (err != 0) {
891                 ALOGE("Failed to destroy CHRE package");
892                 goto exit;
893             }
894         }
895     } else if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid)) {
896         err = tear_hotword_state(stdev->odsp_hdl, HOTWORD_MASK);
897         if (err != 0) {
898             ALOGE("Failed to tear Hotword state");
899             goto exit;
900         }
901 
902         err = flush_model(stdev->odsp_hdl, model->kw_id);
903         if (err != 0) {
904             ALOGE("Failed to flush Hotword model");
905             goto exit;
906         }
907         stdev->current_enable = stdev->current_enable & ~HOTWORD_MASK;
908 
909         if (!(stdev->current_enable & PLUGIN1_MASK)) {
910             err = destroy_hotword_package(stdev->odsp_hdl);
911             if (err != 0) {
912                 ALOGE("Failed to destroy Hotword package");
913                 goto exit;
914             }
915         }
916 
917     } else if (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid)) {
918         err = tear_hotword_state(stdev->odsp_hdl, WAKEUP_MASK);
919         if (err != 0) {
920             ALOGE("Failed to tear Wakeup state");
921             goto exit;
922         }
923 
924         err = flush_model(stdev->odsp_hdl, model->kw_id);
925         if (err != 0) {
926             ALOGE("Failed to flush Wakeup model");
927             goto exit;
928         }
929         stdev->current_enable = stdev->current_enable & ~WAKEUP_MASK;
930 
931         if (!(stdev->current_enable & PLUGIN1_MASK)) {
932             err = destroy_hotword_package(stdev->odsp_hdl);
933             if (err != 0) {
934                 ALOGE("Failed to destroy Hotword package");
935                 goto exit;
936             }
937         }
938 
939     } else if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid)) {
940         err = tear_ambient_state(stdev->odsp_hdl, AMBIENT_MASK);
941         if (err != 0) {
942             ALOGE("Failed to tear Ambient state");
943             goto exit;
944         }
945 
946         err = flush_model(stdev->odsp_hdl, model->kw_id);
947         if (err != 0) {
948             ALOGE("Failed to flush Ambient model");
949             goto exit;
950         }
951         stdev->current_enable = stdev->current_enable & ~AMBIENT_MASK;
952 
953         if (!(stdev->current_enable & PLUGIN2_MASK)) {
954             err = destroy_ambient_package(stdev->odsp_hdl);
955             if (err != 0) {
956                 ALOGE("Failed to destroy Ambient package");
957                 goto exit;
958             }
959         }
960     } else if (check_uuid_equality(model->uuid, stdev->entity_model_uuid)) {
961         err = tear_ambient_state(stdev->odsp_hdl, ENTITY_MASK);
962         if (err != 0) {
963             ALOGE("Failed to tear Entity state");
964             goto exit;
965         }
966 
967         err = flush_model(stdev->odsp_hdl, model->kw_id);
968         if (err != 0) {
969             ALOGE("Failed to flush Entity model");
970             goto exit;
971         }
972         stdev->current_enable = stdev->current_enable & ~ENTITY_MASK;
973 
974         if (!(stdev->current_enable & PLUGIN2_MASK)) {
975             err = destroy_ambient_package(stdev->odsp_hdl);
976             if (err != 0) {
977                 ALOGE("Failed to destroy Ambient package");
978                 goto exit;
979             }
980         }
981     }
982 exit:
983     return err;
984 }
985 
set_package_route(struct knowles_sound_trigger_device * stdev,sound_trigger_uuid_t uuid,bool bargein)986 static int set_package_route(struct knowles_sound_trigger_device *stdev,
987                             sound_trigger_uuid_t uuid,
988                             bool bargein)
989 {
990     int ret = 0;
991     /*
992      *[TODO] Add correct error return value for package route
993      * b/119390722 for tracing.
994      */
995     if (check_uuid_equality(uuid, stdev->chre_model_uuid)) {
996         if (stdev->is_chre_loaded == true) {
997             set_chre_audio_route(stdev->route_hdl, bargein);
998         }
999     } else if (check_uuid_equality(uuid, stdev->hotword_model_uuid)) {
1000         if (!((stdev->current_enable & PLUGIN1_MASK) & ~HOTWORD_MASK)) {
1001             set_hotword_route(stdev->route_hdl, bargein);
1002         }
1003     } else if (check_uuid_equality(uuid, stdev->wakeup_model_uuid)) {
1004         if (!((stdev->current_enable & PLUGIN1_MASK) & ~WAKEUP_MASK)) {
1005             set_hotword_route(stdev->route_hdl, bargein);
1006         }
1007     } else if (check_uuid_equality(uuid, stdev->ambient_model_uuid)) {
1008         if (!((stdev->current_enable & PLUGIN2_MASK) & ~AMBIENT_MASK)) {
1009             set_ambient_route(stdev->route_hdl, bargein);
1010         }
1011     } else if (check_uuid_equality(uuid, stdev->entity_model_uuid)) {
1012         if (!((stdev->current_enable & PLUGIN2_MASK) & ~ENTITY_MASK)) {
1013             set_ambient_route(stdev->route_hdl, bargein);
1014         }
1015     }
1016 
1017     return ret;
1018 }
1019 
tear_package_route(struct knowles_sound_trigger_device * stdev,sound_trigger_uuid_t uuid,bool bargein)1020 static int tear_package_route(struct knowles_sound_trigger_device *stdev,
1021                             sound_trigger_uuid_t uuid,
1022                             bool bargein)
1023 {
1024     int ret = 0;
1025     /*
1026      *[TODO] Add correct error return value for package route
1027      * b/119390722 for tracing.
1028      */
1029     if (check_uuid_equality(uuid, stdev->chre_model_uuid)) {
1030         if (stdev->is_chre_loaded == true) {
1031             tear_chre_audio_route(stdev->route_hdl, bargein);
1032         }
1033     } else if (check_uuid_equality(uuid, stdev->hotword_model_uuid)) {
1034         if (!((stdev->current_enable & PLUGIN1_MASK) & ~HOTWORD_MASK))
1035             tear_hotword_route(stdev->route_hdl, bargein);
1036     } else if (check_uuid_equality(uuid, stdev->wakeup_model_uuid)) {
1037         if (!((stdev->current_enable & PLUGIN1_MASK) & ~WAKEUP_MASK))
1038             tear_hotword_route(stdev->route_hdl, bargein);
1039     } else if (check_uuid_equality(uuid, stdev->ambient_model_uuid)) {
1040         if (!((stdev->current_enable & PLUGIN2_MASK) & ~AMBIENT_MASK))
1041             tear_ambient_route(stdev->route_hdl, bargein);
1042     } else if (check_uuid_equality(uuid, stdev->entity_model_uuid)) {
1043         if (!((stdev->current_enable & PLUGIN2_MASK) & ~ENTITY_MASK))
1044             tear_ambient_route(stdev->route_hdl, bargein);
1045     }
1046 
1047     return ret;
1048 }
1049 
async_setup_aec(struct knowles_sound_trigger_device * stdev)1050 static int async_setup_aec(struct knowles_sound_trigger_device *stdev)
1051 {
1052     int ret = 0;
1053     if (stdev->rx_active_count > 0 &&
1054         stdev->is_bargein_route_enabled != true &&
1055         stdev->is_mic_route_enabled != false) {
1056         ALOGD("%s: Bargein enabling", __func__);
1057         if (is_mic_controlled_by_ahal(stdev) == false) {
1058             ret = enable_mic_route(stdev->route_hdl, false,
1059                                 INTERNAL_OSCILLATOR);
1060             if (ret != 0) {
1061                 ALOGE("Failed to disable mic route with INT OSC");
1062                 goto exit;
1063             }
1064         }
1065         ret = setup_src_plugin(stdev->odsp_hdl, SRC_AMP_REF);
1066         if (ret != 0) {
1067             ALOGE("Failed to load SRC-amp package");
1068             goto exit;
1069         }
1070         ret = enable_src_route(stdev->route_hdl, true, SRC_AMP_REF);
1071         if (ret != 0) {
1072             ALOGE("Failed to enable SRC-amp route");
1073             goto exit;
1074         }
1075 
1076         ret = setup_aec_package(stdev->odsp_hdl);
1077         if (ret != 0) {
1078             ALOGE("Failed to load AEC package");
1079             goto exit;
1080         }
1081         ret = enable_bargein_route(stdev->route_hdl, true);
1082         if (ret != 0) {
1083             ALOGE("Failed to enable buffer route");
1084             goto exit;
1085         }
1086 
1087         if (is_mic_controlled_by_ahal(stdev) == false) {
1088             ret = enable_amp_ref_route(stdev->route_hdl, true, STRM_16K);
1089             if (ret != 0) {
1090                 ALOGE("Failed to enable amp-ref route");
1091                 goto exit;
1092             }
1093             ret = enable_mic_route(stdev->route_hdl, true,
1094                                 EXTERNAL_OSCILLATOR);
1095             if (ret != 0) {
1096                 ALOGE("Failed to enable mic route with EXT OSC");
1097                 goto exit;
1098             }
1099         } else {
1100             // main mic is turned by media recording
1101             ret = enable_amp_ref_route(stdev->route_hdl, true, STRM_48K);
1102             if (ret != 0) {
1103                 ALOGE("Failed to enable amp-ref route");
1104                 goto exit;
1105             }
1106         }
1107         stdev->is_bargein_route_enabled = true;
1108 
1109         if (stdev->hotword_buffer_enable) {
1110             ret = tear_hotword_buffer_route(stdev->route_hdl,
1111                                 !stdev->is_bargein_route_enabled);
1112             if (ret != 0) {
1113                 ALOGE("Failed to tear old buffer route");
1114                 goto exit;
1115             }
1116             ret = set_hotword_buffer_route(stdev->route_hdl,
1117                                 stdev->is_bargein_route_enabled);
1118             if (ret != 0) {
1119                 ALOGE("Failed to enable buffer route");
1120                 goto exit;
1121             }
1122         }
1123 
1124         if (stdev->music_buffer_enable) {
1125             ret = tear_music_buffer_route(stdev->route_hdl,
1126                                 !stdev->is_bargein_route_enabled);
1127             if (ret != 0) {
1128                 ALOGE("Failed to tear old music buffer route");
1129                 goto exit;
1130             }
1131             ret = set_music_buffer_route(stdev->route_hdl,
1132                                 stdev->is_bargein_route_enabled);
1133             if (ret != 0) {
1134                 ALOGE("Failed to enable buffer route");
1135                 goto exit;
1136             }
1137         }
1138 
1139         // Check each model, if it is active then update it's route
1140         for (int i = 0; i < MAX_MODELS; i++) {
1141             if (stdev->models[i].is_active == true) {
1142                 // teardown the package route without bargein
1143                 ret = tear_package_route(stdev,
1144                                         stdev->models[i].uuid,
1145                                         !stdev->is_bargein_route_enabled);
1146                 if (ret != 0) {
1147                     ALOGE("Failed to tear old package route");
1148                     goto exit;
1149                 }
1150                 // resetup the package route with bargein
1151                 ret = set_package_route(stdev,
1152                                         stdev->models[i].uuid,
1153                                         stdev->is_bargein_route_enabled);
1154                 if (ret != 0) {
1155                     ALOGE("Failed to enable package route");
1156                     goto exit;
1157                 }
1158             }
1159         }
1160     } else {
1161         ALOGD("%s: Bargein is already enabled", __func__);
1162     }
1163 
1164 exit:
1165     return ret;
1166 }
1167 
handle_input_source(struct knowles_sound_trigger_device * stdev,bool enable)1168 static int handle_input_source(struct knowles_sound_trigger_device *stdev,
1169                             bool enable)
1170 {
1171     int err = 0;
1172     enum clock_type ct = INTERNAL_OSCILLATOR;
1173     enum strm_type strmt = STRM_16K;
1174 
1175     if (stdev->rx_active_count > 0) {
1176         ct = EXTERNAL_OSCILLATOR;
1177     }
1178 
1179     if (is_mic_controlled_by_ahal(stdev) == true) {
1180         strmt = STRM_48K;
1181     }
1182 
1183     /*
1184      *[TODO] Add correct error return value for input source route
1185      * b/119390722 for tracing.
1186      */
1187     if (enable) {
1188         if (stdev->is_mic_route_enabled == false) {
1189             err = check_and_setup_src_package(stdev);
1190             if (err != 0) {
1191                 ALOGE("Fail to setup src Package");
1192                 goto exit;
1193             }
1194             err = setup_src_plugin(stdev->odsp_hdl, SRC_MIC);
1195             if (err != 0) {
1196                 ALOGE("Failed to load SRC package");
1197                 goto exit;
1198             }
1199             err = enable_src_route(stdev->route_hdl, true, SRC_MIC);
1200             if (err != 0) {
1201                 ALOGE("Failed to enable SRC-mic route");
1202                 goto exit;
1203             }
1204         }
1205         if (stdev->rx_active_count > 0 &&
1206             stdev->is_bargein_route_enabled == false) {
1207             err = setup_src_plugin(stdev->odsp_hdl, SRC_AMP_REF);
1208             if (err != 0) {
1209                 ALOGE("Failed to load SRC-amp package");
1210                 goto exit;
1211             }
1212             err = enable_src_route(stdev->route_hdl, true, SRC_AMP_REF);
1213             if (err != 0) {
1214                 ALOGE("Failed to enable SRC-amp route");
1215                 goto exit;
1216             }
1217 
1218             err = setup_aec_package(stdev->odsp_hdl);
1219             if (err != 0) {
1220                 ALOGE("Failed to load AEC package");
1221                 // We didn't load AEC package so don't setup the routes
1222                 goto exit;
1223             }
1224 
1225             // Enable the bargein route if not enabled
1226             err = enable_bargein_route(stdev->route_hdl, true);
1227             if (err != 0) {
1228                 ALOGE("Failed to enable buffer route");
1229                 goto exit;
1230             }
1231             err = enable_amp_ref_route(stdev->route_hdl, true, strmt);
1232             if (err != 0) {
1233                 ALOGE("Failed to amp-ref route");
1234                 goto exit;
1235             }
1236             stdev->is_bargein_route_enabled = true;
1237         }
1238         if (stdev->is_mic_route_enabled == false) {
1239             if (is_mic_controlled_by_ahal(stdev) == false) {
1240                 err = enable_mic_route(stdev->route_hdl, true, ct);
1241                 if (err != 0) {
1242                     ALOGE("Failed to enable mic route");
1243                     goto exit;
1244                 }
1245             }
1246             stdev->is_mic_route_enabled = true;
1247         }
1248     } else {
1249         if (!is_any_model_active(stdev)) {
1250             ALOGD("None of keywords are active");
1251             if (stdev->rx_active_count > 0 &&
1252                 stdev->is_bargein_route_enabled == true) {
1253                 // Just disable the route and update the route status but retain
1254                 // bargein status
1255                 err = enable_bargein_route(stdev->route_hdl, false);
1256                 if (err != 0) {
1257                     ALOGE("Failed to disable bargein route");
1258                     goto exit;
1259                 }
1260                 err = destroy_aec_package(stdev->odsp_hdl);
1261                 if (err != 0) {
1262                     ALOGE("Failed to unload AEC package");
1263                     goto exit;
1264                 }
1265                 err = enable_src_route(stdev->route_hdl, false, SRC_AMP_REF);
1266                 if (err != 0) {
1267                     ALOGE("Failed to disable SRC-amp route");
1268                     goto exit;
1269                 }
1270                 err = destroy_src_plugin(stdev->odsp_hdl, SRC_AMP_REF);
1271                 if (err != 0) {
1272                     ALOGE("Failed to unload SRC-amp package");
1273                     goto exit;
1274                 }
1275                 err = enable_amp_ref_route(stdev->route_hdl, false, strmt);
1276                 if (err != 0) {
1277                     ALOGE("Failed to amp-ref route");
1278                     goto exit;
1279                 }
1280                 stdev->is_bargein_route_enabled = false;
1281            }
1282            if (stdev->is_mic_route_enabled == true) {
1283                // Close SRC package
1284                err = enable_src_route(stdev->route_hdl, false, SRC_MIC);
1285                if (err != 0) {
1286                    ALOGE("Failed to disable SRC-mic route");
1287                    goto exit;
1288                }
1289                err = destroy_src_plugin(stdev->odsp_hdl, SRC_MIC);
1290                if (err != 0) {
1291                    ALOGE("Failed to unload SRC-mic package");
1292                    goto exit;
1293                }
1294                if (is_mic_controlled_by_ahal(stdev) == false) {
1295                    err = enable_mic_route(stdev->route_hdl, false, ct);
1296                    if (err != 0) {
1297                        ALOGE("Failed to disable mic route");
1298                        goto exit;
1299                    }
1300                }
1301                stdev->is_mic_route_enabled = false;
1302                err = check_and_destroy_src_package(stdev);
1303                if (err != 0) {
1304                    ALOGE("Fail to destroy src Package");
1305                    goto exit;
1306                }
1307            }
1308        }
1309     }
1310 
1311 exit:
1312     return err;
1313 }
1314 
update_rx_conditions(struct knowles_sound_trigger_device * stdev,audio_event_type_t event,struct audio_event_info * config)1315 static void update_rx_conditions(struct knowles_sound_trigger_device *stdev,
1316                                  audio_event_type_t event,
1317                                  struct audio_event_info *config)
1318 {
1319     if (event == AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE) {
1320         if (stdev->rx_active_count > 0) {
1321             stdev->rx_active_count--;
1322         } else {
1323             ALOGW("%s: unexpected rx inactive event", __func__);
1324         }
1325     } else if (event == AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE) {
1326         if (!(config->device_info.device & AUDIO_DEVICE_OUT_SPEAKER)) {
1327             ALOGD("%s: Playback device doesn't include SPEAKER.",
1328                   __func__);
1329         } else {
1330             stdev->rx_active_count++;
1331         }
1332     } else {
1333         ALOGW("%s: invalid event %d", __func__, event);
1334     }
1335     ALOGD("%s: updated rx_concurrency as %d", __func__,
1336           stdev->rx_active_count);
1337 }
1338 
1339 
update_sthal_conditions(struct knowles_sound_trigger_device * stdev,audio_event_type_t event,struct audio_event_info * config)1340 static void update_sthal_conditions(struct knowles_sound_trigger_device *stdev,
1341                                     audio_event_type_t event,
1342                                     struct audio_event_info *config)
1343 {
1344     if (event == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE) {
1345         // get correct voice/voip mode in sthal
1346         if (stdev->is_ahal_in_voice_voip_mode == false &&
1347             stdev->is_ahal_voice_voip_stop == true &&
1348             stdev->is_ahal_media_recording == true) {
1349             ALOGD("%s: voice/voip didn't start, treat it as media recording inactive",
1350                   __func__);
1351             stdev->is_ahal_voice_voip_stop = false;
1352             stdev->is_ahal_media_recording = false;
1353         } else if (stdev->is_ahal_voice_voip_stop == true) {
1354             ALOGD("%s: voice/voip device is inactive", __func__);
1355             stdev->is_ahal_in_voice_voip_mode = false;
1356             stdev->is_ahal_voice_voip_stop = false;
1357         } else if (stdev->is_ahal_in_voice_voip_mode == true &&
1358                    stdev->is_ahal_voice_voip_stop == false &&
1359                    stdev->is_ahal_voice_voip_start == false) {
1360             ALOGD("%s: voice/voip usecase didn't start in incall mode, treat it as voice/voip is inactive",
1361                   __func__);
1362             stdev->is_ahal_in_voice_voip_mode = false;
1363         }
1364 
1365         if (stdev->is_concurrent_capture == true &&
1366             stdev->is_ahal_in_voice_voip_mode == false) {
1367             if (stdev->is_ahal_media_recording == true)
1368                 stdev->is_con_mic_route_enabled = true;
1369             else
1370                 stdev->is_con_mic_route_enabled = false;
1371             ALOGD("%s: update mic con %d", __func__,
1372                   stdev->is_con_mic_route_enabled);
1373         }
1374     } else if (event == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE) {
1375         if (stdev->is_ahal_in_voice_voip_mode == false &&
1376                 (config->u.usecase.type == USECASE_TYPE_VOICE_CALL ||
1377                  config->u.usecase.type == USECASE_TYPE_VOIP_CALL)) {
1378             ALOGD("%s: voice/voip is actvie, close ST mic and don't use mic concurrently",
1379                   __func__);
1380             stdev->is_ahal_in_voice_voip_mode = true;
1381         }
1382         if (config->u.usecase.type == USECASE_TYPE_PCM_CAPTURE) {
1383             stdev->is_ahal_media_recording = true;
1384         }
1385         if (stdev->is_concurrent_capture == true &&
1386             stdev->is_ahal_in_voice_voip_mode == false &&
1387             stdev->is_con_mic_route_enabled == false &&
1388             config->device_info.device == ST_DEVICE_HANDSET_MIC) {
1389             ALOGD("%s: enable mic concurrency", __func__);
1390                   stdev->is_con_mic_route_enabled = true;
1391         }
1392     } else if (event == AUDIO_EVENT_CAPTURE_STREAM_INACTIVE) {
1393         if (stdev->is_ahal_voice_voip_start == true &&
1394                 (config->u.usecase.type == USECASE_TYPE_VOICE_CALL ||
1395                  config->u.usecase.type == USECASE_TYPE_VOIP_CALL)) {
1396             stdev->is_ahal_voice_voip_stop = true;
1397             stdev->is_ahal_voice_voip_start = false;
1398         } else if (config->u.usecase.type == USECASE_TYPE_PCM_CAPTURE)
1399             stdev->is_ahal_media_recording = false;
1400     } else if (event == AUDIO_EVENT_CAPTURE_STREAM_ACTIVE) {
1401         if (config->u.usecase.type == USECASE_TYPE_VOICE_CALL ||
1402             config->u.usecase.type == USECASE_TYPE_VOIP_CALL) {
1403             stdev->is_ahal_voice_voip_start = true;
1404         }
1405     }
1406 }
1407 
do_handle_functions(struct knowles_sound_trigger_device * stdev,enum sthal_mode pre_mode,enum sthal_mode cur_mode,audio_event_type_t event)1408 static bool do_handle_functions(struct knowles_sound_trigger_device *stdev,
1409                                 enum sthal_mode pre_mode,
1410                                 enum sthal_mode cur_mode,
1411                                 audio_event_type_t event)
1412 {
1413     int ret = 0;
1414     int i = 0;
1415 
1416     ALOGD("+%s+: pre %d, cur %d, event %d", __func__, pre_mode, cur_mode, event);
1417 
1418     // handle event AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE
1419     if (event == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE) {
1420         if ((pre_mode == CON_DISABLED_ST && cur_mode == CON_DISABLED_CAPTURE) ||
1421             (pre_mode == CON_DISABLED_ST && cur_mode == IN_CALL) ||
1422             (pre_mode == CON_DISABLED_CAPTURE && cur_mode == IN_CALL) ||
1423             (pre_mode == CON_ENABLED_CAPTURE_ST && cur_mode == IN_CALL) ||
1424             (pre_mode == CON_ENABLED_ST && cur_mode == IN_CALL)) {
1425             // disable all ST
1426             // if tunnel is active, close it first
1427             for (i = 0; i < MAX_MODELS; i++) {
1428                 if (stdev->adnc_strm_handle[i] != 0) {
1429                     ALOGD("%s: stop tunnling for index:%d", __func__, i);
1430                     stdev->adnc_strm_close(stdev->adnc_strm_handle[i]);
1431                     stdev->adnc_strm_handle[i] = 0;
1432                     stdev->adnc_strm_last_read[i] = reset_time;
1433                 }
1434             }
1435             stdev->is_streaming = 0;
1436 
1437             for (i = 0; i < MAX_MODELS; i++) {
1438                 if (stdev->models[i].is_active == true) {
1439                     update_recover_list(stdev, i, true);
1440                     tear_package_route(stdev, stdev->models[i].uuid,
1441                                        stdev->is_bargein_route_enabled);
1442                     stdev->models[i].is_active = false;
1443                     if (!check_uuid_equality(stdev->models[i].uuid,
1444                                              stdev->chre_model_uuid))
1445                         destroy_package(stdev, &stdev->models[i]);
1446 
1447                     if ((stdev->hotword_buffer_enable) &&
1448                         !(stdev->current_enable & PLUGIN1_MASK)) {
1449                         tear_hotword_buffer_route(stdev->route_hdl,
1450                                                   stdev->is_bargein_route_enabled);
1451                     }
1452 
1453                     if ((stdev->music_buffer_enable) &&
1454                         !(stdev->current_enable & PLUGIN2_MASK)) {
1455                         tear_music_buffer_route(stdev->route_hdl,
1456                                                 stdev->is_bargein_route_enabled);
1457                     }
1458 
1459                     setup_buffer(stdev, &stdev->models[i], false);
1460                 }
1461             }
1462             handle_input_source(stdev, false);
1463             check_and_destroy_buffer_package(stdev);
1464         } else if (pre_mode == CON_ENABLED_ST && cur_mode == CON_ENABLED_CAPTURE_ST) {
1465             //reconfig mic
1466             if (stdev->is_mic_route_enabled == true) {
1467                 if (stdev->is_bargein_route_enabled == true) {
1468                     // close amp-ref first and reconfig it again with 48K after
1469                     // main mic is turned on by media recording
1470                     ret = enable_amp_ref_route(stdev->route_hdl, false, STRM_16K);
1471                     if (ret != 0) {
1472                         ALOGE("Failed to disable amp-ref route");
1473                         goto exit;
1474                     }
1475                     ret = enable_mic_route(stdev->route_hdl, false,
1476                                            EXTERNAL_OSCILLATOR);
1477                     if (ret != 0) {
1478                         ALOGE("Failed to disable mic route with EXT OSC");
1479                         goto exit;
1480                     }
1481 
1482                     ret = enable_amp_ref_route(stdev->route_hdl, true, STRM_48K);
1483                     if (ret != 0) {
1484                         ALOGE("Failed to enable amp-ref route");
1485                         goto exit;
1486                     }
1487                 } else {
1488                     ret = enable_mic_route(stdev->route_hdl, false,
1489                                            INTERNAL_OSCILLATOR);
1490                     if (ret != 0) {
1491                         ALOGE("Failed to disable mic route with INT OSC");
1492                         goto exit;
1493                     }
1494                 }
1495             } else {
1496                 ALOGD("%s: ST mic isn't enabled, recording mic is turned on",
1497                        __func__);
1498             }
1499         }
1500     }
1501 
1502     // handle event AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE
1503     if (event == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE) {
1504         if ((pre_mode == IN_CALL && cur_mode == CON_DISABLED_ST) ||
1505             (pre_mode == IN_CALL && cur_mode == CON_DISABLED_CAPTURE) ||
1506             (pre_mode == IN_CALL && cur_mode == CON_ENABLED_ST) ||
1507             (pre_mode == IN_CALL && cur_mode == CON_ENABLED_CAPTURE_ST) ||
1508             (pre_mode == CON_DISABLED_CAPTURE && cur_mode == CON_DISABLED_ST)) {
1509             //recover all STs
1510             for (i = 0; i < MAX_MODELS; i++) {
1511                 // recover all models from list
1512                 if (is_uuid_in_recover_list(stdev, i)) {
1513                     if (stdev->models[i].is_active == false) {
1514                         check_and_setup_buffer_package(stdev);
1515                         stdev->models[i].is_active = true;
1516                         handle_input_source(stdev, true);
1517 
1518                         setup_buffer(stdev, &stdev->models[i], true);
1519                         if (stdev->hotword_buffer_enable &&
1520                             !(stdev->current_enable & PLUGIN1_MASK)) {
1521                             set_hotword_buffer_route(stdev->route_hdl,
1522                                                      stdev->is_bargein_route_enabled);
1523                         }
1524                         if (stdev->music_buffer_enable &&
1525                             !(stdev->current_enable & PLUGIN2_MASK)) {
1526                             set_music_buffer_route(stdev->route_hdl,
1527                                                    stdev->is_bargein_route_enabled);
1528                         }
1529 
1530                         if (!check_uuid_equality(stdev->models[i].uuid,
1531                                                  stdev->chre_model_uuid))
1532                             setup_package(stdev, &stdev->models[i]);
1533                         set_package_route(stdev, stdev->models[i].uuid,
1534                                           stdev->is_bargein_route_enabled);
1535                     }
1536                 }
1537             }
1538             stdev->recover_model_list = 0;
1539         } else if (pre_mode == CON_ENABLED_CAPTURE_ST && cur_mode == CON_ENABLED_ST) {
1540             // reconfig mic
1541             if (stdev->is_mic_route_enabled == true) {
1542                 if (stdev->is_bargein_route_enabled == true) {
1543                     ret = enable_amp_ref_route(stdev->route_hdl, false, STRM_48K);
1544                     if (ret != 0) {
1545                         ALOGE("Failed to disable amp-ref route");
1546                         goto exit;
1547                     }
1548                     ret = enable_mic_route(stdev->route_hdl, true,
1549                                            EXTERNAL_OSCILLATOR);
1550                     if (ret != 0) {
1551                         ALOGE("Failed to enable mic route with EXT OSC");
1552                         goto exit;
1553                     }
1554                     // turn on amp-ref with 16khz
1555                     ret = enable_amp_ref_route(stdev->route_hdl, true, STRM_16K);
1556                     if (ret != 0) {
1557                         ALOGE("Failed to enable amp-ref route");
1558                         goto exit;
1559                     }
1560                 } else {
1561                     ret = enable_mic_route(stdev->route_hdl, true,
1562                                            INTERNAL_OSCILLATOR);
1563                     if (ret != 0) {
1564                         ALOGE("Failed to enable mic route with INT OSC");
1565                         goto exit;
1566                     }
1567                 }
1568             } else {
1569                 ALOGD("%s: ST mic isn't enabled, recording mic is turned off",
1570                       __func__);
1571             }
1572         }
1573     }
1574 
1575 exit:
1576     ALOGD("-%s-: pre %d, cur %d, event %d", __func__, pre_mode, cur_mode, event);
1577     return ret;
1578 }
1579 
1580 // stdev needs to be locked before calling this function
restart_recognition(struct knowles_sound_trigger_device * stdev)1581 static int restart_recognition(struct knowles_sound_trigger_device *stdev)
1582 {
1583     int err = 0;
1584     int i = 0;
1585     enum strm_type strmt = STRM_16K;
1586     enum clock_type ct = INTERNAL_OSCILLATOR;
1587     /*
1588      * The libaudioroute library doesn't set the mixer controls if previously
1589      * applied values are the same or the active_count > 0, so we need to
1590      * teardown the route so that it can clear up the value and active_count.
1591      * Then we could setup the routes again.
1592      */
1593 
1594     stdev->current_enable = 0;
1595     stdev->hotword_buffer_enable = 0;
1596     stdev->music_buffer_enable = 0;
1597 
1598     if (stdev->rx_active_count == 0 &&
1599         stdev->is_bargein_route_enabled == true) {
1600         /* rx stream is disabled during codec recovery.
1601          * Need to reset the enabled flag
1602          */
1603         stdev->is_bargein_route_enabled = false;
1604     }
1605 
1606     if (stdev->is_buffer_package_loaded == true) {
1607         err = setup_buffer_package(stdev->odsp_hdl);
1608         if (err != 0) {
1609             ALOGE("%s: Failed to restart Buffer package", __func__);
1610         }
1611     }
1612 
1613     if (stdev->is_src_package_loaded == true) {
1614         err = setup_src_package(stdev->odsp_hdl);
1615         if (err != 0) {
1616             ALOGE("%s: Failed to restart SRC package", __func__);
1617         }
1618     }
1619 
1620     /*
1621      * If ST mode is IN_CALL, make sure mic route as false,
1622      * that would be reloaded after ending the call
1623      */
1624     if (get_sthal_mode(stdev) == IN_CALL) {
1625         ALOGD("%s: ST mode is in_call, reset all routes", __func__);
1626 
1627         stdev->is_mic_route_enabled = false;
1628         stdev->is_bargein_route_enabled = false;
1629         for (i = 0; i < MAX_MODELS; i++) {
1630             if (stdev->models[i].is_active == true) {
1631                 update_recover_list(stdev, i, true);
1632                 stdev->models[i].is_active = false;
1633             }
1634         }
1635 
1636         // if chre enabled before crash during call, need to setup package for SLPI.
1637         if (stdev->is_chre_loaded == true) {
1638             err = setup_chre_package(stdev->odsp_hdl);
1639             if (err != 0) {
1640                 ALOGE("Failed to load CHRE package");
1641             }
1642             stdev->current_enable = stdev->current_enable | CHRE_MASK;
1643         }
1644         goto reload_oslo;
1645     }
1646 
1647 
1648     /*
1649      * Reset mic and src package if sound trigger recording is active
1650      * The src-mic, src-amp must be enable before AEC enable, because
1651      * the endpoint sequence control.
1652      */
1653     if (stdev->is_mic_route_enabled == true) {
1654         // recover src package if sound trigger recording is active
1655         err = setup_src_plugin(stdev->odsp_hdl, SRC_MIC);
1656         if (err != 0) {
1657             ALOGE("failed to load SRC package");
1658         }
1659         err = enable_src_route(stdev->route_hdl, true, SRC_MIC);
1660         if (err != 0) {
1661             ALOGE("Failed to restart SRC-mic route");
1662         }
1663         /*
1664          * RX stream was enabled during codec recovery.
1665          * Need to setup the barge-in package and routing.
1666          */
1667         if (stdev->rx_active_count > 0) {
1668             stdev->is_bargein_route_enabled = true;
1669             ct = EXTERNAL_OSCILLATOR;
1670             if (is_mic_controlled_by_ahal(stdev) == true) {
1671                 strmt = STRM_48K;
1672             }
1673             err = setup_src_plugin(stdev->odsp_hdl, SRC_AMP_REF);
1674             if (err != 0) {
1675                 ALOGE("failed to load SRC package");
1676             }
1677             err = enable_src_route(stdev->route_hdl, true, SRC_AMP_REF);
1678             if (err != 0) {
1679                 ALOGE("Failed to restart SRC-amp route");
1680             }
1681 
1682             err = setup_aec_package(stdev->odsp_hdl);
1683             if (err != 0) {
1684                 ALOGE("Failed to restart AEC package");
1685             }
1686             err = enable_bargein_route(stdev->route_hdl, true);
1687             if (err != 0) {
1688                 ALOGE("Failed to restart bargein route");
1689             }
1690             err = enable_amp_ref_route(stdev->route_hdl, true, strmt);
1691             if (err != 0) {
1692                 ALOGE("Failed to restart amp-ref route");
1693             }
1694         }
1695         // The stream 0 should be enable at last moment for the data alignment.
1696         if (is_mic_controlled_by_ahal(stdev) == false) {
1697             err = enable_mic_route(stdev->route_hdl, true, ct);
1698             if (err != 0) {
1699                 ALOGE("failed to restart mic route");
1700             }
1701         }
1702     }
1703 
1704     // Download all the keyword models files that were previously loaded
1705     for (i = 0; i < MAX_MODELS; i++) {
1706         if (stdev->models[i].is_active == true) {
1707             if (stdev->is_buffer_package_loaded == true) {
1708                 setup_buffer(stdev, &stdev->models[i], true);
1709             }
1710             if (check_uuid_equality(stdev->models[i].uuid, stdev->hotword_model_uuid) ||
1711                 (check_uuid_equality(stdev->models[i].uuid, stdev->wakeup_model_uuid))) {
1712                 if ((stdev->hotword_buffer_enable) &&
1713                     (!(stdev->current_enable & HOTWORD_MASK) ||
1714                       (stdev->current_enable & WAKEUP_MASK))) {
1715                     set_hotword_buffer_route(stdev->route_hdl,
1716                                             stdev->is_bargein_route_enabled);
1717                 }
1718             }
1719             if (check_uuid_equality(stdev->models[i].uuid, stdev->ambient_model_uuid) ||
1720                 (check_uuid_equality(stdev->models[i].uuid, stdev->entity_model_uuid))) {
1721                 if ((stdev->music_buffer_enable) &&
1722                     (!(stdev->current_enable & AMBIENT_MASK) ||
1723                       (stdev->current_enable & ENTITY_MASK))) {
1724                     set_music_buffer_route(stdev->route_hdl,
1725                                         stdev->is_bargein_route_enabled);
1726                 }
1727             }
1728             setup_package(stdev, &stdev->models[i]);
1729             set_package_route(stdev, stdev->models[i].uuid,
1730                             stdev->is_bargein_route_enabled);
1731         }
1732     }
1733 
1734 reload_oslo:
1735     // reload Oslo part after every package loaded to avoid HMD memory overlap
1736     // issue, b/128914464
1737     for (i = 0; i < MAX_MODELS; i++) {
1738         if (stdev->models[i].is_loaded == true) {
1739             if (check_uuid_equality(stdev->models[i].uuid,
1740                                     stdev->sensor_model_uuid)) {
1741                 // setup the sensor route
1742                 err = setup_sensor_package(stdev->odsp_hdl);
1743                 if (err != 0) {
1744                     ALOGE("%s: setup Sensor package failed", __func__);
1745                     goto exit;
1746                 }
1747 
1748                 err = set_sensor_route(stdev->route_hdl, true);
1749                 if (err != 0) {
1750                     ALOGE("%s: Sensor route fail", __func__);
1751                     goto exit;
1752                 }
1753                 stdev->is_sensor_route_enabled = true;
1754             }
1755         }
1756     }
1757     ALOGD("%s: recovery done", __func__);
1758 exit:
1759     return err;
1760 }
1761 
1762 // stdev needs to be locked before calling this function
crash_recovery(struct knowles_sound_trigger_device * stdev)1763 static int crash_recovery(struct knowles_sound_trigger_device *stdev)
1764 {
1765     int err = 0;
1766 
1767     set_default_apll_clk(stdev->mixer);
1768     setup_slpi_wakeup_event(stdev->odsp_hdl, true);
1769 
1770     // Redownload the keyword model files and start recognition
1771     err = restart_recognition(stdev);
1772     if (err != 0) {
1773         ALOGE("%s: ERROR: Failed to download the keyword models and restarting"
1774             " recognition", __func__);
1775         goto exit;
1776     }
1777 
1778     // Reset the flag only after successful recovery
1779     stdev->is_st_hal_ready = true;
1780 
1781 exit:
1782     return err;
1783 }
1784 
sensor_crash_handler(struct knowles_sound_trigger_device * stdev)1785 static void sensor_crash_handler(struct knowles_sound_trigger_device *stdev)
1786 {
1787     int i;
1788 
1789     if (stdev->is_sensor_destroy_in_prog == false)
1790         return;
1791 
1792     if (stdev->ss_timer_created) {
1793         timer_delete(stdev->ss_timer);
1794         stdev->ss_timer_created = false;
1795     }
1796 
1797     if (stdev->is_sensor_route_enabled == true) {
1798         for (i = 0; i < MAX_MODELS; i++) {
1799             if (check_uuid_equality(stdev->models[i].uuid,
1800                                     stdev->sensor_model_uuid) &&
1801                 stdev->models[i].is_loaded == true) {
1802                 stdev->models[i].is_loaded = false;
1803                 memset(&stdev->models[i].uuid, 0,
1804                        sizeof(sound_trigger_uuid_t));
1805                 break;
1806             }
1807         }
1808         stdev->is_sensor_route_enabled = false;
1809         stdev->current_enable &= ~OSLO_MASK;
1810     }
1811     stdev->is_sensor_destroy_in_prog = false;
1812 
1813     // There could be another thread waiting for us to destroy
1814     // so signal that thread, if no one is waiting then this signal
1815     // will have no effect
1816     pthread_cond_signal(&stdev->sensor_create);
1817 }
1818 
destroy_sensor_model(struct knowles_sound_trigger_device * stdev)1819 static void destroy_sensor_model(struct knowles_sound_trigger_device *stdev)
1820 {
1821     int ret, i;
1822     ALOGD("+%s+", __func__);
1823 
1824     if (stdev->is_sensor_route_enabled == true) {
1825         ret = set_sensor_route(stdev->route_hdl, false);
1826         if (ret != 0) {
1827             ALOGE("%s: tear Sensor route fail", __func__);
1828         }
1829         stdev->is_sensor_route_enabled = false;
1830 
1831         ret = destroy_sensor_package(stdev->odsp_hdl);
1832         if (ret != 0) {
1833             ALOGE("%s: destroy Sensor package failed %d",
1834                   __func__, ret);
1835         }
1836         stdev->current_enable = stdev->current_enable & ~OSLO_MASK;
1837     }
1838 
1839     // now we can change the flag
1840     for (i = 0 ; i < MAX_MODELS ; i++) {
1841         if (check_uuid_equality(stdev->models[i].uuid,
1842                                 stdev->sensor_model_uuid) &&
1843             stdev->models[i].is_loaded == true) {
1844             memset(&stdev->models[i].uuid, 0, sizeof(sound_trigger_uuid_t));
1845             stdev->models[i].is_loaded = false;
1846             break;
1847         }
1848     }
1849 
1850     stdev->is_sensor_destroy_in_prog = false;
1851     check_and_destroy_buffer_package(stdev);
1852 
1853     // There could be another thread waiting for us to destroy so signal that
1854     // thread, if no one is waiting then this signal will have no effect
1855     pthread_cond_signal(&stdev->sensor_create);
1856 
1857     ALOGD("-%s-", __func__);
1858 }
1859 
sensor_timeout_recover()1860 static void sensor_timeout_recover()
1861 {
1862     int err = 0;
1863     ALOGD("+%s+", __func__);
1864 
1865     struct knowles_sound_trigger_device *stdev = &g_stdev;
1866     pthread_mutex_lock(&stdev->lock);
1867     // We are here because we timed out so check if we still need to destroy
1868     // the sensor package, if yes then reset the firmware
1869     if (stdev->is_sensor_destroy_in_prog == true) {
1870         if (stdev->is_st_hal_ready) {
1871             stdev->is_st_hal_ready = false;
1872             // reset the firmware and wait for firmware download complete
1873             err = reset_fw(stdev->odsp_hdl);
1874             if (err == -1) {
1875                 ALOGE("%s: ERROR: Failed to reset the firmware %d(%s)",
1876                       __func__, errno, strerror(errno));
1877             }
1878             reset_all_route(stdev->route_hdl);
1879             sensor_crash_handler(stdev);
1880         }
1881     }
1882     pthread_mutex_unlock(&stdev->lock);
1883     ALOGD("-%s-", __func__);
1884 }
1885 
start_sensor_model(struct knowles_sound_trigger_device * stdev)1886 static int start_sensor_model(struct knowles_sound_trigger_device * stdev)
1887 {
1888     struct timespec ts;
1889     int wait_counter = 0, err = 0;
1890 
1891     while (stdev->is_sensor_destroy_in_prog == true &&
1892            wait_counter < SENSOR_CREATE_WAIT_MAX_COUNT) {
1893         // We wait for 1sec * MAX_COUNT times for the HOST 1 to respond, if
1894         // within that time we don't get any response, we will go ahead with the
1895         // sensor model creation. Note this might result in an error which would
1896         // be better than blocking the thread indefinitely.
1897         clock_gettime(CLOCK_REALTIME, &ts);
1898         ts.tv_sec += SENSOR_CREATE_WAIT_TIME_IN_S;
1899         err = pthread_cond_timedwait(&stdev->sensor_create, &stdev->lock, &ts);
1900         if (err == ETIMEDOUT) {
1901             ALOGE("%s: WARNING: Sensor create timed out after %ds",
1902                   __func__, SENSOR_CREATE_WAIT_TIME_IN_S);
1903             wait_counter++;
1904         }
1905     }
1906 
1907     // If firmware crashed when we are waiting
1908     if (stdev->is_st_hal_ready == false) {
1909         err = -EAGAIN;
1910         goto exit;
1911     }
1912 
1913     if (stdev->is_sensor_destroy_in_prog == true) {
1914         ALOGE("%s: ERROR: Waited for %ds but we didn't get the event from "
1915               "Host 1, and fw reset is not yet complete", __func__,
1916               SENSOR_CREATE_WAIT_TIME_IN_S * SENSOR_CREATE_WAIT_MAX_COUNT);
1917         err = -EAGAIN;
1918         goto exit;
1919     }
1920 
1921     // setup the sensor route
1922     err = check_and_setup_buffer_package(stdev);
1923     if (err != 0) {
1924         ALOGE("%s: ERROR: Failed to load the buffer package", __func__);
1925         goto exit;
1926     }
1927 
1928     if(stdev->is_sensor_route_enabled == false) {
1929         err = setup_sensor_package(stdev->odsp_hdl);
1930         if (err) {
1931             ALOGE("%s: Failed to setup sensor package", __func__);
1932             goto exit;
1933         }
1934         // Don't download the keyword model file, just setup the
1935         // sensor route
1936         err = set_sensor_route(stdev->route_hdl, true);
1937         if (err) {
1938             ALOGE("%s: Sensor route fail", __func__);
1939             goto exit;
1940         }
1941         stdev->is_sensor_route_enabled = true;
1942         stdev->current_enable = stdev->current_enable | OSLO_MASK;
1943     }
1944 
1945 exit:
1946     return err;
1947 }
1948 
chre_crash_handler(struct knowles_sound_trigger_device * stdev)1949 static void chre_crash_handler(struct knowles_sound_trigger_device *stdev)
1950 {
1951     int i;
1952 
1953     if (stdev->is_chre_destroy_in_prog == false)
1954         return;
1955 
1956     if (stdev->chre_timer_created) {
1957         timer_delete(stdev->chre_timer);
1958         stdev->chre_timer_created = false;
1959     }
1960 
1961     if (stdev->is_chre_loaded == true) {
1962         for (i = 0; i < MAX_MODELS; i++) {
1963             if (check_uuid_equality(stdev->models[i].uuid,
1964                                     stdev->chre_model_uuid)) {
1965                 stdev->models[i].is_active = false;
1966                 stdev->models[i].is_loaded = false;
1967                 memset(&stdev->models[i].uuid, 0,
1968                        sizeof(sound_trigger_uuid_t));
1969                 break;
1970             }
1971         }
1972         stdev->is_chre_loaded = false;
1973         stdev->current_enable &= ~CHRE_MASK;
1974     }
1975     stdev->is_chre_destroy_in_prog = false;
1976 
1977     // There could be another thread waiting for us to destroy
1978     // so signal that thread, if no one is waiting then this signal
1979     // will have no effect
1980     pthread_cond_signal(&stdev->chre_create);
1981 }
1982 
start_chre_model(struct knowles_sound_trigger_device * stdev,int model_id)1983 static int start_chre_model(struct knowles_sound_trigger_device *stdev,
1984                             int model_id)
1985 {
1986     struct timespec ts;
1987     int wait_counter = 0, err = 0;
1988 
1989     while (stdev->is_chre_destroy_in_prog == true &&
1990            wait_counter < CHRE_CREATE_WAIT_MAX_COUNT) {
1991         // We wait for 1sec * MAX_COUNT times for the HOST 1 to respond, if
1992         // within that time we don't get any response, we will go ahead with the
1993         // sensor model creation. Note this might result in an error which would
1994         // be better than blocking the thread indefinitely.
1995         clock_gettime(CLOCK_REALTIME, &ts);
1996         ts.tv_sec += CHRE_CREATE_WAIT_TIME_IN_S;
1997         err = pthread_cond_timedwait(&stdev->chre_create, &stdev->lock, &ts);
1998         if (err == ETIMEDOUT) {
1999             ALOGE("%s: WARNING: CHRE create timed out after %ds",
2000                     __func__, CHRE_CREATE_WAIT_TIME_IN_S);
2001             wait_counter++;
2002         }
2003     }
2004 
2005     // If firmware crashed when we are waiting
2006     if (stdev->is_st_hal_ready == false) {
2007         err = -EAGAIN;
2008         goto exit;
2009     }
2010 
2011     if (stdev->is_chre_destroy_in_prog == true) {
2012         ALOGE("%s: ERROR: Waited for %ds but we didn't get the event from "
2013               "Host 1, and fw reset is not yet complete", __func__,
2014               CHRE_CREATE_WAIT_TIME_IN_S * CHRE_CREATE_WAIT_MAX_COUNT);
2015         err = -EAGAIN;
2016         goto exit;
2017     }
2018 
2019     err = check_and_setup_buffer_package(stdev);
2020     if (err != 0) {
2021         ALOGE("%s: ERROR: Failed to load the buffer package", __func__);
2022         goto exit;
2023     }
2024 
2025     // add chre to recover list
2026     if (can_enable_chre(stdev)) {
2027         if(stdev->is_chre_loaded == false) {
2028             stdev->models[model_id].is_active = true;
2029             handle_input_source(stdev, true);
2030             setup_chre_package(stdev->odsp_hdl);
2031             set_chre_audio_route(stdev->route_hdl,
2032                                stdev->is_bargein_route_enabled);
2033             stdev->is_chre_loaded = true;
2034             stdev->current_enable = stdev->current_enable | CHRE_MASK;
2035         }
2036     } else {
2037         ALOGW("%s: device is in call, setup CHRE for SLPI",
2038               __func__);
2039         //Setup CHRE package and allow SLPI connect
2040         //during in-call mode.
2041         if (stdev->is_chre_loaded == false) {
2042             setup_chre_package(stdev->odsp_hdl);
2043             stdev->models[model_id].uuid = stdev->chre_model_uuid;
2044             stdev->is_chre_loaded = true;
2045             stdev->current_enable = stdev->current_enable | CHRE_MASK;
2046             if (can_update_recover_list(stdev) == true)
2047                 update_recover_list(stdev, model_id, true);
2048         }
2049     }
2050 
2051 exit:
2052     return err;
2053 }
2054 
destroy_chre_model(struct knowles_sound_trigger_device * stdev)2055 static void destroy_chre_model(struct knowles_sound_trigger_device *stdev)
2056 {
2057     int err = 0;
2058     ALOGD("+%s+", __func__);
2059 
2060     if (stdev->is_chre_loaded == true) {
2061         int i;
2062         tear_chre_audio_route(stdev->route_hdl,
2063                               stdev->is_bargein_route_enabled);
2064         err = destroy_chre_package(stdev->odsp_hdl);
2065         if (err != 0) {
2066             ALOGE("%s: ERROR: Failed to destroy chre package", __func__);
2067         }
2068 
2069         //Need force reset the flag for chre due to in-call state
2070         //The model is inactive, but need to clean if user disable it
2071         //during call.
2072         for (i = 0; i < MAX_MODELS; i++) {
2073             if (check_uuid_equality(stdev->models[i].uuid,
2074                                     stdev->chre_model_uuid)) {
2075                 stdev->models[i].is_active = false;
2076                 stdev->models[i].is_loaded = false;
2077                 memset(&stdev->models[i].uuid, 0,
2078                        sizeof(sound_trigger_uuid_t));
2079                 break;
2080             }
2081         }
2082         handle_input_source(stdev, false);
2083         stdev->is_chre_loaded = false;
2084         stdev->current_enable = stdev->current_enable & ~CHRE_MASK;
2085     }
2086 
2087     stdev->is_chre_destroy_in_prog = false;
2088 
2089     // setup the sensor route
2090     err = check_and_destroy_buffer_package(stdev);
2091     if (err != 0) {
2092         ALOGE("%s: ERROR: Failed to destroy buffer package", __func__);
2093     }
2094 
2095     // There could be another thread waiting for us to destroy so signal that
2096     // thread, if no one is waiting then this signal will have no effect
2097     pthread_cond_signal(&stdev->chre_create);
2098 
2099     ALOGD("-%s-", __func__);
2100 }
2101 
chre_timeout_recover()2102 static void chre_timeout_recover()
2103 {
2104     int err = 0;
2105     ALOGD("+%s+", __func__);
2106 
2107     struct knowles_sound_trigger_device *stdev = &g_stdev;
2108     pthread_mutex_lock(&stdev->lock);
2109     // We are here because we timed out so check if we still need to destroy
2110     // the chre package, if yes then reset the firmware
2111     if (stdev->is_chre_destroy_in_prog == true) {
2112         if (stdev->is_st_hal_ready) {
2113             stdev->is_st_hal_ready = false;
2114             // reset the firmware and wait for firmware download complete
2115             err = reset_fw(stdev->odsp_hdl);
2116             if (err == -1) {
2117                 ALOGE("%s: ERROR: Failed to reset the firmware %d(%s)",
2118                       __func__, errno, strerror(errno));
2119             }
2120             reset_all_route(stdev->route_hdl);
2121             chre_crash_handler(stdev);
2122         }
2123     }
2124     pthread_mutex_unlock(&stdev->lock);
2125     ALOGD("-%s-", __func__);
2126 }
2127 
transitions_thread_loop(void * context)2128 static void *transitions_thread_loop(void *context)
2129 {
2130     struct knowles_sound_trigger_device *stdev =
2131         (struct knowles_sound_trigger_device *)context;
2132 
2133     int err = 0;
2134     pthread_mutex_lock(&stdev->lock);
2135     while (1) {
2136             if (stdev->transit_case == TRANSIT_NONE)
2137                 pthread_cond_wait(&stdev->transition_cond, &stdev->lock);
2138 
2139             acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
2140             switch (stdev->transit_case) {
2141                 case TRANSIT_NONE:
2142                     break;
2143                 case TRANSIT_SETUP_AEC:
2144                     err = async_setup_aec(stdev);
2145                     break;
2146             }
2147             stdev->transit_case = TRANSIT_NONE;
2148             release_wake_lock(WAKE_LOCK_NAME);
2149     }
2150     pthread_mutex_unlock(&stdev->lock);
2151 }
2152 
2153 
monitor_thread_loop(void * context)2154 static void *monitor_thread_loop(void *context)
2155 {
2156     struct knowles_sound_trigger_device *stdev =
2157         (struct knowles_sound_trigger_device *)context;
2158     struct timespec now;
2159     double diff;
2160 
2161     pthread_mutex_lock(&stdev->lock);
2162     while (1) {
2163             if (!stdev->is_streaming)
2164                 pthread_cond_wait(&stdev->tunnel_create, &stdev->lock);
2165             pthread_mutex_unlock(&stdev->lock);
2166 
2167             sleep(TUNNEL_TIMEOUT);
2168 
2169             pthread_mutex_lock(&stdev->lock);
2170 
2171             acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
2172             clock_gettime(CLOCK_REALTIME, &now);
2173             for (int i = 0; i < MAX_MODELS; i++) {
2174                 if (stdev->adnc_strm_handle[i] != 0) {
2175                     diff = (now.tv_sec - stdev->adnc_strm_last_read[i].tv_sec)
2176                         + (double) ((now.tv_nsec) - (stdev->adnc_strm_last_read[i].tv_nsec))
2177                           / 1000000000.0;
2178 
2179                     if (diff > TUNNEL_TIMEOUT) {
2180                         ALOGE("%s: Waiting timeout for %f sec", __func__, diff);
2181                         stdev->adnc_strm_close(stdev->adnc_strm_handle[i]);
2182                         stdev->adnc_strm_handle[i] = 0;
2183                         stdev->is_streaming--;
2184                         stdev->adnc_strm_last_read[i] = reset_time;
2185                     }
2186                 }
2187             }
2188             release_wake_lock(WAKE_LOCK_NAME);
2189     }
2190     pthread_mutex_unlock(&stdev->lock);
2191 }
2192 
callback_thread_loop(void * context)2193 static void *callback_thread_loop(void *context)
2194 {
2195     struct knowles_sound_trigger_device *stdev =
2196         (struct knowles_sound_trigger_device *)context;
2197     struct pollfd fds[2];
2198     char msg[UEVENT_MSG_LEN];
2199     int exit_sockets[2];
2200     int err = 0;
2201     int i, n;
2202     int kwid = 0;
2203     struct iaxxx_get_event_info ge;
2204     void *payload = NULL;
2205     unsigned int payload_size = 0, fw_status = IAXXX_FW_IDLE;
2206     int fw_status_retries = 0;
2207 
2208     ALOGI("%s", __func__);
2209     prctl(PR_SET_NAME, (unsigned long)"sound trigger callback", 0, 0, 0);
2210 
2211     pthread_mutex_lock(&stdev->lock);
2212 
2213     if (socketpair(AF_UNIX, SOCK_STREAM, 0, exit_sockets) == -1) {
2214         ALOGE("%s: Failed to create termination socket", __func__);
2215         goto exit;
2216     }
2217 
2218     stdev_close_term_sock(stdev);
2219     stdev->send_sock = exit_sockets[0];
2220     stdev->recv_sock = exit_sockets[1];
2221 
2222     memset(fds, 0, 2 * sizeof(struct pollfd));
2223     int timeout = -1; // Wait for event indefinitely
2224     fds[0].events = POLLIN;
2225     fds[0].fd = uevent_open_socket(64*1024, true);
2226     if (fds[0].fd == -1) {
2227         ALOGE("Error opening socket for hotplug uevent errno %d(%s)",
2228             errno, strerror(errno));
2229         goto exit;
2230     }
2231     fds[1].events = POLLIN;
2232     fds[1].fd = stdev->recv_sock;
2233 
2234     ge.event_id = -1;
2235 
2236     // Try to get the firmware status, if we fail, try for 10 times with a gap
2237     // of 500ms, if we are unable to get the status after that then exit
2238     do {
2239         err = get_fw_status(stdev->odsp_hdl, &fw_status);
2240         if (err == -1) {
2241             ALOGE("%s: ERROR: Failed to get the firmware status %d(%s)",
2242                     __func__, errno, strerror(errno));
2243             usleep(RETRY_US);
2244             fw_status_retries++;
2245         }
2246     } while (err != 0 && fw_status_retries < RETRY_NUMBER);
2247 
2248     if (err != 0) {
2249         ALOGE("%s: ERROR: Failed to get firmware status after %d tries",
2250                 __func__, RETRY_NUMBER);
2251         goto exit;
2252     }
2253 
2254     if (fw_status == IAXXX_FW_ACTIVE) {
2255         stdev->is_st_hal_ready = false;
2256         // reset the firmware and wait for firmware download complete
2257         err = reset_fw(stdev->odsp_hdl);
2258         if (err == -1) {
2259             ALOGE("%s: ERROR: Failed to reset the firmware %d(%s)",
2260                     __func__, errno, strerror(errno));
2261         }
2262         stdev->fw_reset_done_by_hal = true;
2263     } else if (fw_status == IAXXX_FW_CRASH) {
2264         // Firmware has crashed wait till it recovers
2265         stdev->is_st_hal_ready = false;
2266     } else if (fw_status == IAXXX_FW_IDLE) {
2267         stdev->route_hdl = audio_route_init(stdev->snd_crd_num,
2268                                             stdev->mixer_path_xml);
2269         if (stdev->route_hdl == NULL) {
2270             ALOGE("Failed to init the audio_route library");
2271             goto exit;
2272         }
2273 
2274         set_default_apll_clk(stdev->mixer);
2275         setup_slpi_wakeup_event(stdev->odsp_hdl, true);
2276         stdev->is_st_hal_ready = true;
2277     }
2278     pthread_mutex_unlock(&stdev->lock);
2279 
2280     while (1) {
2281         err = poll(fds, 2, timeout);
2282 
2283         pthread_mutex_lock(&stdev->lock);
2284         if (err < 0) {
2285             ALOGE("%s: Error in poll: %d (%s)",
2286                 __func__, errno, strerror(errno));
2287             break;
2288         }
2289 
2290         if (fds[0].revents & POLLIN) {
2291             n = uevent_kernel_multicast_recv(fds[0].fd, msg, UEVENT_MSG_LEN);
2292             if (n <= 0) {
2293                 pthread_mutex_unlock(&stdev->lock);
2294                 continue;
2295             }
2296             for (i = 0; i < n;) {
2297                 if (strstr(msg + i, IAXXX_VQ_EVENT_STR)) {
2298                     ALOGI("%s", IAXXX_VQ_EVENT_STR);
2299 
2300                     err = get_event(stdev->odsp_hdl, &ge);
2301                     if (err == 0) {
2302                         if (ge.event_id == OK_GOOGLE_KW_ID) {
2303                             ALOGD("Eventid received is OK_GOOGLE_KW_ID %d",
2304                                 OK_GOOGLE_KW_ID);
2305                             kwid = OK_GOOGLE_KW_ID;
2306                         } else if (ge.event_id == AMBIENT_KW_ID) {
2307                             ALOGD("Eventid received is AMBIENT_KW_ID %d",
2308                                 AMBIENT_KW_ID);
2309                             kwid = AMBIENT_KW_ID;
2310                             reset_ambient_plugin(stdev->odsp_hdl);
2311                         } else if (ge.event_id == OSLO_EP_DISCONNECT) {
2312                             ALOGD("Eventid received is OSLO_EP_DISCONNECT %d",
2313                                   OSLO_EP_DISCONNECT);
2314                             if (stdev->is_sensor_destroy_in_prog == true) {
2315                                 // A timer would have been created during stop,
2316                                 // check and delete it
2317                                 if (stdev->ss_timer_created) {
2318                                     timer_delete(stdev->ss_timer);
2319                                     stdev->ss_timer_created = false;
2320                                 }
2321 
2322                                 destroy_sensor_model(stdev);
2323                             } else {
2324                                 ALOGE("Unexpected OSLO_EP_DISCONNECT received"
2325                                       ", ignoring..");
2326                             }
2327                             break;
2328                         } else if (ge.event_id == CHRE_EP_DISCONNECT) {
2329                             ALOGD("Eventid received is CHRE_EP_DISCONNECT %d",
2330                                   CHRE_EP_DISCONNECT);
2331                             if (stdev->is_chre_destroy_in_prog == true) {
2332                                 // A timer would have been created during stop,
2333                                 // check and delete it
2334                                 if (stdev->chre_timer_created) {
2335                                     timer_delete(stdev->chre_timer);
2336                                     stdev->chre_timer_created = false;
2337                                 }
2338 
2339                                 destroy_chre_model(stdev);
2340                             } else {
2341                                 ALOGE("Unexpected CHRE_EP_DISCONNECT received"
2342                                       ", ignoring..");
2343                             }
2344                             break;
2345                         } else if (ge.event_id == ENTITY_KW_ID) {
2346                             ALOGD("Eventid received is ENTITY_KW_ID %d",
2347                                 ENTITY_KW_ID);
2348                             kwid = ENTITY_KW_ID;
2349                         } else if (ge.event_id == WAKEUP_KW_ID) {
2350                             ALOGD("Eventid received is WAKEUP_KW_ID %d",
2351                                 WAKEUP_KW_ID);
2352                             kwid = WAKEUP_KW_ID;
2353                         } else {
2354                             ALOGE("Unknown event id received, ignoring %d",
2355                                 ge.event_id);
2356                         }
2357                         stdev->last_detected_model_type = kwid;
2358                         break;
2359                     } else {
2360                         ALOGE("get_event failed with error %d", err);
2361                     }
2362                 } else if (strstr(msg + i, IAXXX_RECOVERY_EVENT_STR)) {
2363                     /* If the ST HAL did the firmware reset then that means
2364                      * that the userspace crashed so we need to reinit the audio
2365                      * route library, if we didn't reset the firmware, then it
2366                      * was genuine firmware crash and we don't need to reinit
2367                      * the audio route library.
2368                      */
2369                     if (stdev->fw_reset_done_by_hal == true) {
2370                         stdev->route_hdl = audio_route_init(stdev->snd_crd_num,
2371                                                             stdev->mixer_path_xml);
2372                         if (stdev->route_hdl == NULL) {
2373                             ALOGE("Failed to init the audio_route library");
2374                             goto exit;
2375                         }
2376 
2377                         stdev->fw_reset_done_by_hal = false;
2378                     }
2379 
2380                     ALOGD("Firmware has redownloaded, start the recovery");
2381                     int err = crash_recovery(stdev);
2382                     if (err != 0) {
2383                         ALOGE("Crash recovery failed");
2384                     }
2385                 } else if (strstr(msg + i, IAXXX_FW_DWNLD_SUCCESS_STR)) {
2386                     ALOGD("Firmware downloaded successfully");
2387                     stdev->is_st_hal_ready = true;
2388                     set_default_apll_clk(stdev->mixer);
2389                 } else if (strstr(msg + i, IAXXX_FW_CRASH_EVENT_STR)) {
2390                     ALOGD("Firmware has crashed");
2391                     // Don't allow any op on ST HAL until recovery is complete
2392                     stdev->is_st_hal_ready = false;
2393                     reset_all_route(stdev->route_hdl);
2394                     stdev->is_streaming = 0;
2395 
2396                     // Firmware crashed, clear CHRE/Oslo timer and flags here
2397                     sensor_crash_handler(stdev);
2398                     chre_crash_handler(stdev);
2399                 }
2400 
2401                 i += strlen(msg + i) + 1;
2402             }
2403 
2404             if (ge.event_id == OK_GOOGLE_KW_ID ||
2405                 ge.event_id == AMBIENT_KW_ID ||
2406                 ge.event_id == ENTITY_KW_ID ||
2407                 ge.event_id == WAKEUP_KW_ID) {
2408                 ALOGD("%s: Keyword ID %d", __func__, kwid);
2409 
2410                 if (ge.data != 0) {
2411                     ALOGD("Size of payload is %d", ge.data);
2412                     payload_size = ge.data;
2413                     payload = malloc(payload_size);
2414                     if (payload != NULL) {
2415                         if (ge.event_id == AMBIENT_KW_ID ||
2416                             ge.event_id == ENTITY_KW_ID)
2417                             err = get_entity_param_blk(stdev->odsp_hdl,
2418                                                     payload,
2419                                                     payload_size);
2420                         else if (ge.event_id == OK_GOOGLE_KW_ID ||
2421                             ge.event_id == WAKEUP_KW_ID)
2422                             err = get_wakeup_param_blk(stdev->odsp_hdl,
2423                                                     payload,
2424                                                     payload_size);
2425                         if (err != 0) {
2426                             ALOGE("Failed to get payload data");
2427                             free(payload);
2428                             payload = NULL;
2429                             payload_size = 0;
2430                         }
2431                     } else {
2432                         ALOGE("Failed to allocate memory for payload");
2433                     }
2434                 }
2435                 int idx = find_handle_for_kw_id(stdev, kwid);
2436                 if (idx < MAX_MODELS && stdev->models[idx].is_active == true) {
2437                     int recognition_status = RECOGNITION_STATUS_SUCCESS;
2438                     if (stdev->models[idx].is_state_query == true) {
2439                         recognition_status =
2440                             RECOGNITION_STATUS_GET_STATE_RESPONSE;
2441 
2442                         // We need to send this only once, so reset now
2443                         stdev->models[idx].is_state_query = false;
2444                     }
2445                     if (stdev->models[idx].type == SOUND_MODEL_TYPE_KEYPHRASE) {
2446                         struct sound_trigger_phrase_recognition_event *event;
2447                         event = (struct sound_trigger_phrase_recognition_event*)
2448                                     stdev_keyphrase_event_alloc(
2449                                                 stdev->models[idx].model_handle,
2450                                                 stdev->models[idx].config,
2451                                                 recognition_status);
2452                         if (event) {
2453                             struct model_info *model;
2454                             model = &stdev->models[idx];
2455 
2456                             ALOGD("Sending recognition callback for id %d",
2457                                 kwid);
2458                             model->recognition_callback(&event->common,
2459                                                     model->recognition_cookie);
2460                             // Update the config so that it will be used
2461                             // during the streaming
2462                             stdev->last_keyword_detected_config = model->config;
2463 
2464                             free(event);
2465                         } else {
2466                             ALOGE("Failed to allocate memory for the event");
2467                         }
2468                     } else if (stdev->models[idx].type == SOUND_MODEL_TYPE_GENERIC) {
2469                         struct sound_trigger_generic_recognition_event *event;
2470                         event = (struct sound_trigger_generic_recognition_event*)
2471                                 stdev_generic_event_alloc(
2472                                             stdev->models[idx].model_handle,
2473                                             payload,
2474                                             payload_size,
2475                                             recognition_status);
2476                         if (event) {
2477                             struct model_info *model;
2478                             model = &stdev->models[idx];
2479 
2480                             ALOGD("Sending recognition callback for id %d",
2481                                 kwid);
2482                             model->recognition_callback(&event->common,
2483                                                     model->recognition_cookie);
2484                             // Update the config so that it will be used
2485                             // during the streaming
2486                             stdev->last_keyword_detected_config = model->config;
2487 
2488                             free(event);
2489                         } else {
2490                             ALOGE("Failed to allocate memory for the event");
2491                         }
2492                     }
2493                 } else {
2494                     ALOGE("Invalid id or keyword is not active, Subsume the event");
2495                 }
2496                 // Reset all event related data
2497                 ge.event_id = -1;
2498                 ge.data = 0;
2499                 kwid = -1;
2500             }
2501             // Free the payload data
2502             if (payload) {
2503                 free(payload);
2504                 payload = NULL;
2505                 payload_size = 0;
2506             }
2507         } else if (fds[1].revents & POLLIN) {
2508             read(fds[1].fd, &n, sizeof(n)); /* clear the socket */
2509             ALOGD("%s: Termination message", __func__);
2510             break;
2511         }
2512         else {
2513             ALOGI("%s: Message ignored", __func__);
2514         }
2515         pthread_mutex_unlock(&stdev->lock);
2516     }
2517 
2518 exit:
2519     stdev_close_term_sock(stdev);
2520     pthread_mutex_unlock(&stdev->lock);
2521 
2522     return (void *)(long)err;
2523 }
2524 
stdev_get_properties(const struct sound_trigger_hw_device * dev __unused,struct sound_trigger_properties * properties)2525 static int stdev_get_properties(
2526                             const struct sound_trigger_hw_device *dev __unused,
2527                             struct sound_trigger_properties *properties)
2528 {
2529     ALOGV("+%s+", __func__);
2530     if (properties == NULL)
2531         return -EINVAL;
2532     memcpy(properties, &hw_properties, sizeof(struct sound_trigger_properties));
2533     ALOGV("-%s-", __func__);
2534     return 0;
2535 }
2536 
stop_recognition(struct knowles_sound_trigger_device * stdev,sound_model_handle_t handle)2537 static int stop_recognition(struct knowles_sound_trigger_device *stdev,
2538                             sound_model_handle_t handle)
2539 {
2540     int status = 0;
2541     struct model_info *model = &stdev->models[handle];
2542 
2543     if (stdev->is_st_hal_ready == false) {
2544         ALOGE("%s: ST HAL is not ready yet", __func__);
2545         status = -EAGAIN;
2546         goto exit;
2547     }
2548 
2549     if (model->config != NULL) {
2550         dereg_hal_event_session(model->config, handle);
2551         free(model->config);
2552         model->config = NULL;
2553     }
2554 
2555     model->recognition_callback = NULL;
2556     model->recognition_cookie = NULL;
2557     if (check_uuid_equality(model->uuid, stdev->chre_model_uuid) ||
2558         check_uuid_equality(model->uuid, stdev->sensor_model_uuid)) {
2559         // This avoids any processing of chre/oslo.
2560         goto exit;
2561     }
2562     if (can_update_recover_list(stdev) == true) {
2563         update_recover_list(stdev, handle, false);
2564         model->is_active = false;
2565         goto exit;
2566     }
2567 
2568     if (stdev->adnc_strm_handle[handle] != 0) {
2569         ALOGD("%s: stop tunnling for index:%d", __func__, handle);
2570         stdev->adnc_strm_close(stdev->adnc_strm_handle[handle]);
2571         stdev->adnc_strm_handle[handle] = 0;
2572         stdev->is_streaming--;
2573         stdev->adnc_strm_last_read[handle] = reset_time;
2574     }
2575 
2576     model->is_active = false;
2577 
2578     tear_package_route(stdev, model->uuid, stdev->is_bargein_route_enabled);
2579 
2580     destroy_package(stdev, model);
2581 
2582 
2583     if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid) ||
2584         (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))) {
2585         if ((stdev->hotword_buffer_enable) &&
2586             !(stdev->current_enable & PLUGIN1_MASK)) {
2587             tear_hotword_buffer_route(stdev->route_hdl,
2588                                     stdev->is_bargein_route_enabled);
2589         }
2590     }
2591 
2592     if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid) ||
2593         (check_uuid_equality(model->uuid, stdev->entity_model_uuid))) {
2594         if ((stdev->music_buffer_enable) &&
2595             !(stdev->current_enable & PLUGIN2_MASK)) {
2596             tear_music_buffer_route(stdev->route_hdl,
2597                                 stdev->is_bargein_route_enabled);
2598         }
2599     }
2600 
2601     setup_buffer(stdev, model, false);
2602 
2603     handle_input_source(stdev, false);
2604 
2605     check_and_destroy_buffer_package(stdev);
2606 
2607 exit:
2608     return status;
2609 }
2610 
stdev_load_sound_model(const struct sound_trigger_hw_device * dev,struct sound_trigger_sound_model * sound_model,sound_model_callback_t callback,void * cookie,sound_model_handle_t * handle)2611 static int stdev_load_sound_model(const struct sound_trigger_hw_device *dev,
2612                                 struct sound_trigger_sound_model *sound_model,
2613                                 sound_model_callback_t callback,
2614                                 void *cookie,
2615                                 sound_model_handle_t *handle)
2616 {
2617     struct knowles_sound_trigger_device *stdev =
2618         (struct knowles_sound_trigger_device *)dev;
2619     int ret = 0;
2620     int kw_model_sz = 0;
2621     int i = 0;
2622 
2623     unsigned char *kw_buffer = NULL;
2624 
2625     ALOGD("+%s+", __func__);
2626     pthread_mutex_lock(&stdev->lock);
2627 
2628     if (stdev->is_st_hal_ready == false) {
2629         ALOGE("%s: ST HAL is not ready yet", __func__);
2630         ret = -EAGAIN;
2631         goto exit;
2632     }
2633 
2634     if (handle == NULL || sound_model == NULL) {
2635         ALOGE("%s: handle/sound_model is NULL", __func__);
2636         ret = -EINVAL;
2637         goto exit;
2638     }
2639 
2640     if (sound_model->data_size == 0 ||
2641         sound_model->data_offset < sizeof(struct sound_trigger_sound_model)) {
2642         ALOGE("%s: Invalid sound model data", __func__);
2643         ret = -EINVAL;
2644         goto exit;
2645     }
2646 
2647     // When a delayed CHRE/Oslo destroy process is in progress,
2648     // we should not skip the new model and return the existing handle
2649     // which will be destroyed soon.
2650     if ((check_uuid_equality(sound_model->vendor_uuid,
2651                              stdev->chre_model_uuid) &&
2652             stdev->is_chre_destroy_in_prog) ||
2653             (check_uuid_equality(sound_model->vendor_uuid,
2654                                  stdev->sensor_model_uuid) &&
2655             stdev->is_sensor_destroy_in_prog)) {
2656         ALOGD("%s: CHRE/Oslo destroy in progress, skipped handle check.",
2657               __func__);
2658     } else {
2659         i = find_handle_for_uuid(stdev, sound_model->vendor_uuid);
2660         if (i != -1) {
2661             ALOGW("%s: model is existed at index %d", __func__, i);
2662             *handle = i;
2663             goto exit;
2664         }
2665     }
2666 
2667     // Find an empty slot to load the model
2668     i = find_empty_model_slot(stdev);
2669     if (i == -1) {
2670         ALOGE("%s: Can't load model no free slots available", __func__);
2671         ret = -ENOSYS;
2672         goto exit;
2673     }
2674 
2675     kw_buffer = (unsigned char *) sound_model + sound_model->data_offset;
2676     kw_model_sz = sound_model->data_size;
2677     ALOGV("%s: kw_model_sz %d", __func__, kw_model_sz);
2678 
2679     stdev->models[i].data = malloc(kw_model_sz);
2680     if (stdev->models[i].data == NULL) {
2681         stdev->models[i].data_sz = 0;
2682         ALOGE("%s: could not allocate memory for keyword model data",
2683             __func__);
2684         ret = -ENOMEM;
2685         goto exit;
2686     } else {
2687         memcpy(stdev->models[i].data, kw_buffer, kw_model_sz);
2688         stdev->models[i].data_sz = kw_model_sz;
2689     }
2690 
2691     // Send the keyword model to the chip only for hotword and ambient audio
2692     if (check_uuid_equality(sound_model->vendor_uuid,
2693                             stdev->hotword_model_uuid)) {
2694         stdev->models[i].kw_id = OK_GOOGLE_KW_ID;
2695     } else if (check_uuid_equality(sound_model->vendor_uuid,
2696                                 stdev->wakeup_model_uuid)) {
2697         stdev->models[i].kw_id = WAKEUP_KW_ID;
2698     } else if (check_uuid_equality(sound_model->vendor_uuid,
2699                                 stdev->ambient_model_uuid)) {
2700         stdev->models[i].kw_id = AMBIENT_KW_ID;
2701     } else if (check_uuid_equality(sound_model->vendor_uuid,
2702                                 stdev->entity_model_uuid)) {
2703         stdev->models[i].kw_id = ENTITY_KW_ID;
2704     } else if (check_uuid_equality(sound_model->vendor_uuid,
2705                                 stdev->sensor_model_uuid)) {
2706         ret = start_sensor_model(stdev);
2707         if (ret) {
2708             ALOGE("%s: ERROR: Failed to start sensor model", __func__);
2709             goto error;
2710         }
2711         stdev->models[i].kw_id = USELESS_KW_ID;
2712     } else if (check_uuid_equality(sound_model->vendor_uuid,
2713                                 stdev->chre_model_uuid)) {
2714         ret = start_chre_model(stdev, i);
2715         if (ret) {
2716             ALOGE("%s: ERROR: Failed to start chre model", __func__);
2717             goto error;
2718         }
2719         stdev->models[i].kw_id = USELESS_KW_ID;
2720     } else {
2721         ALOGE("%s: ERROR: unknown keyword model file", __func__);
2722         ret = -EINVAL;
2723         goto error;
2724     }
2725 
2726     *handle = i;
2727     ALOGV("%s: Loading keyword model handle(%d) type(%d)", __func__,
2728         *handle, sound_model->type);
2729     // This will need to be replaced with UUID once they are fixed
2730     stdev->models[i].model_handle = *handle;
2731     stdev->models[i].type = sound_model->type;
2732     stdev->models[i].uuid = sound_model->vendor_uuid;
2733     stdev->models[i].sound_model_callback = callback;
2734     stdev->models[i].sound_model_cookie = cookie;
2735     stdev->models[i].recognition_callback = NULL;
2736     stdev->models[i].recognition_cookie = NULL;
2737 
2738     stdev->models[i].is_loaded = true;
2739 
2740 error:
2741     if (ret != 0) {
2742         if (stdev->models[i].data) {
2743             free(stdev->models[i].data);
2744             stdev->models[i].data = NULL;
2745             stdev->models[i].data_sz = 0;
2746         }
2747         if (!is_any_model_loaded(stdev) && stdev->is_buffer_package_loaded) {
2748             destroy_buffer_package(stdev->odsp_hdl);
2749             stdev->is_buffer_package_loaded = false;
2750         }
2751     }
2752 
2753 exit:
2754     pthread_mutex_unlock(&stdev->lock);
2755     ALOGD("-%s handle %d-", __func__, *handle);
2756     return ret;
2757 }
2758 
stdev_unload_sound_model(const struct sound_trigger_hw_device * dev,sound_model_handle_t handle)2759 static int stdev_unload_sound_model(const struct sound_trigger_hw_device *dev,
2760                                     sound_model_handle_t handle)
2761 {
2762     struct knowles_sound_trigger_device *stdev =
2763         (struct knowles_sound_trigger_device *)dev;
2764     int ret = 0;
2765     ALOGD("+%s handle %d+", __func__, handle);
2766     pthread_mutex_lock(&stdev->lock);
2767 
2768     if (stdev->is_st_hal_ready == false) {
2769         ALOGE("%s: ST HAL is not ready yet", __func__);
2770         ret = -EAGAIN;
2771         goto exit;
2772     }
2773 
2774     // Just confirm the model was previously loaded
2775     if (stdev->models[handle].is_loaded == false) {
2776         ALOGE("%s: Invalid model(%d) being called for unload",
2777                 __func__, handle);
2778         ret = -EINVAL;
2779         goto exit;
2780     }
2781 
2782     if (stdev->models[handle].is_active == true) {
2783         ret = stop_recognition(stdev, handle);
2784         if (ret)
2785             goto exit;
2786     }
2787 
2788     if (check_uuid_equality(stdev->models[handle].uuid,
2789                                 stdev->sensor_model_uuid)) {
2790         // Inform the Host 1 that sensor route/packages are about to be
2791         // torndown and then wait for confirmation from Host 1 that it can be
2792         // torndown. Also start a timer for 5 seconds, if the Host 1 doesn't
2793         // send us the event within 5 seconds we force remove the sensor pkgs
2794         if (stdev->is_sensor_route_enabled == true) {
2795             struct itimerspec ss_timer_spec;
2796             struct sigevent ss_sigevent;
2797 
2798             // Inform the host 1
2799             stdev->is_sensor_destroy_in_prog = true;
2800             trigger_sensor_destroy_event(stdev->odsp_hdl);
2801 
2802             // Start timer for 5 seconds
2803             ss_sigevent.sigev_notify = SIGEV_THREAD;
2804             ss_sigevent.sigev_notify_function = sensor_timeout_recover;
2805             ss_sigevent.sigev_notify_attributes = NULL;
2806 
2807             ss_timer_spec.it_interval.tv_sec = 0;
2808             ss_timer_spec.it_interval.tv_nsec = 0;
2809             ss_timer_spec.it_value.tv_sec =
2810                     SENSOR_CREATE_WAIT_TIME_IN_S * SENSOR_CREATE_WAIT_MAX_COUNT;
2811             ss_timer_spec.it_value.tv_nsec = 0;
2812 
2813             if (stdev->ss_timer_created) {
2814                 timer_delete(stdev->ss_timer);
2815                 stdev->ss_timer_created = false;
2816             }
2817 
2818             if (timer_create(CLOCK_REALTIME,
2819                              &ss_sigevent, &stdev->ss_timer) == -1) {
2820                 ALOGE("%s: Timer Create Failed", __func__);
2821             } else {
2822                 stdev->ss_timer_created = true;
2823                 if (timer_settime(stdev->ss_timer,
2824                                   0, &ss_timer_spec, NULL) == -1) {
2825                     ALOGE("%s: Timer Set Failed", __func__);
2826                 }
2827             }
2828         }
2829     } else if (check_uuid_equality(stdev->models[handle].uuid,
2830                                    stdev->chre_model_uuid)) {
2831         // remove chre from recover list
2832         if (can_update_recover_list(stdev) == true)
2833             update_recover_list(stdev, handle, false);
2834 
2835          // Disable the CHRE route
2836         if (stdev->is_chre_loaded == true) {
2837             struct itimerspec chre_timer_spec;
2838             struct sigevent chre_sigevent;
2839 
2840             // Inform the host 1
2841             stdev->is_chre_destroy_in_prog = true;
2842             trigger_chre_destroy_event(stdev->odsp_hdl);
2843 
2844             // Start timer for 5 seconds
2845             chre_sigevent.sigev_notify = SIGEV_THREAD;
2846             chre_sigevent.sigev_notify_function = chre_timeout_recover;
2847             chre_sigevent.sigev_notify_attributes = NULL;
2848 
2849             chre_timer_spec.it_interval.tv_sec = 0;
2850             chre_timer_spec.it_interval.tv_nsec = 0;
2851             chre_timer_spec.it_value.tv_sec =
2852                     CHRE_CREATE_WAIT_TIME_IN_S * CHRE_CREATE_WAIT_MAX_COUNT;
2853             chre_timer_spec.it_value.tv_nsec = 0;
2854 
2855             if (stdev->chre_timer_created) {
2856                 timer_delete(stdev->chre_timer);
2857                 stdev->chre_timer_created = false;
2858             }
2859 
2860             if (timer_create(CLOCK_REALTIME,
2861                              &chre_sigevent, &stdev->chre_timer) == -1) {
2862                 ALOGE("%s: Timer Create Failed", __func__);
2863             } else {
2864                 stdev->chre_timer_created = true;
2865                 if (timer_settime(stdev->chre_timer,
2866                                   0, &chre_timer_spec, NULL) == -1) {
2867                     ALOGE("%s: Timer Set Failed", __func__);
2868                 }
2869             }
2870         }
2871     }
2872 
2873     stdev->models[handle].sound_model_callback = NULL;
2874     stdev->models[handle].sound_model_cookie = NULL;
2875 
2876     if (!(check_uuid_equality(stdev->models[handle].uuid,
2877                               stdev->sensor_model_uuid) &&
2878             stdev->is_sensor_destroy_in_prog) &&
2879         !(check_uuid_equality(stdev->models[handle].uuid,
2880                               stdev->chre_model_uuid) &&
2881             stdev->is_chre_destroy_in_prog)) {
2882         memset(&stdev->models[handle].uuid, 0, sizeof(sound_trigger_uuid_t));
2883         stdev->models[handle].is_loaded = false;
2884     }
2885 
2886     if (stdev->models[handle].data) {
2887         free(stdev->models[handle].data);
2888         stdev->models[handle].data = NULL;
2889         stdev->models[handle].data_sz = 0;
2890     }
2891 
2892     ALOGD("%s: Successfully unloaded the model, handle - %d",
2893         __func__, handle);
2894 exit:
2895     pthread_mutex_unlock(&stdev->lock);
2896     ALOGD("-%s handle %d-", __func__, handle);
2897     return ret;
2898 }
2899 
stdev_start_recognition(const struct sound_trigger_hw_device * dev,sound_model_handle_t handle,const struct sound_trigger_recognition_config * config,recognition_callback_t callback,void * cookie)2900 static int stdev_start_recognition(
2901                         const struct sound_trigger_hw_device *dev,
2902                         sound_model_handle_t handle,
2903                         const struct sound_trigger_recognition_config *config,
2904                         recognition_callback_t callback,
2905                         void *cookie)
2906 {
2907     struct knowles_sound_trigger_device *stdev =
2908         (struct knowles_sound_trigger_device *)dev;
2909     int status = 0;
2910     struct model_info *model = &stdev->models[handle];
2911 
2912     ALOGD("%s stdev %p, sound model %d", __func__, stdev, handle);
2913 
2914     pthread_mutex_lock(&stdev->lock);
2915 
2916     if (stdev->is_st_hal_ready == false) {
2917         ALOGE("%s: ST HAL is not ready yet", __func__);
2918         status = -EAGAIN;
2919         goto exit;
2920     }
2921 
2922     if (callback == NULL) {
2923         ALOGE("%s: recognition_callback is null", __func__);
2924         status = -EINVAL;
2925         goto exit;
2926     }
2927 
2928     if (model->config != NULL) {
2929         dereg_hal_event_session(model->config, handle);
2930         free(model->config);
2931         model->config = NULL;
2932     }
2933 
2934     if (config != NULL) {
2935         model->config = (struct sound_trigger_recognition_config *)
2936                             malloc(sizeof(*config));
2937         if (model->config == NULL) {
2938             ALOGE("%s: Failed to allocate memory for model config", __func__);
2939             status = -ENOMEM;
2940             goto exit;
2941         }
2942 
2943         memcpy(model->config, config, sizeof(*config));
2944         reg_hal_event_session(model->config, handle);
2945 
2946         ALOGD("%s: Is capture requested %d",
2947             __func__, config->capture_requested);
2948     } else {
2949         ALOGD("%s: config is null", __func__);
2950         model->config = NULL;
2951     }
2952 
2953     model->recognition_callback = callback;
2954     model->recognition_cookie = cookie;
2955     if (check_uuid_equality(model->uuid, stdev->chre_model_uuid) ||
2956         check_uuid_equality(model->uuid, stdev->sensor_model_uuid)) {
2957         // This avoids any processing of chre/oslo.
2958         goto exit;
2959     }
2960     if (model->is_active == true) {
2961         // This model is already active, do nothing except updating callbacks,
2962         // configs and cookie
2963         goto exit;
2964     }
2965     if (can_update_recover_list(stdev) == true) {
2966         // Device is in voice/VoIP call, add model to recover list first
2967         // recover model once voice/VoIP is ended.
2968         update_recover_list(stdev, handle, true);
2969         goto exit;
2970     }
2971 
2972     status = check_and_setup_buffer_package(stdev);
2973     if (status != 0) {
2974         ALOGE("%s: ERROR: Failed to load the buffer package", __func__);
2975         goto exit;
2976     }
2977 
2978     model->is_active = true;
2979 
2980     handle_input_source(stdev, true);
2981 
2982     if (stdev->is_buffer_package_loaded == true) {
2983         setup_buffer(stdev, model, true);
2984     }
2985 
2986     if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid) ||
2987         (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))) {
2988         if ((stdev->hotword_buffer_enable) &&
2989             (!(stdev->current_enable & HOTWORD_MASK) ||
2990               (stdev->current_enable & WAKEUP_MASK))) {
2991             set_hotword_buffer_route(stdev->route_hdl,
2992                                     stdev->is_bargein_route_enabled);
2993         }
2994     }
2995 
2996     if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid) ||
2997         (check_uuid_equality(model->uuid, stdev->entity_model_uuid))) {
2998         if ((stdev->music_buffer_enable) &&
2999             (!(stdev->current_enable & AMBIENT_MASK) ||
3000               (stdev->current_enable & ENTITY_MASK))) {
3001             set_music_buffer_route(stdev->route_hdl,
3002                                 stdev->is_bargein_route_enabled);
3003         }
3004     }
3005 
3006     setup_package(stdev, model);
3007 
3008     set_package_route(stdev, model->uuid, stdev->is_bargein_route_enabled);
3009 
3010 exit:
3011     pthread_mutex_unlock(&stdev->lock);
3012     ALOGD("-%s sound model %d-", __func__, handle);
3013     return status;
3014 }
3015 
stdev_stop_recognition(const struct sound_trigger_hw_device * dev,sound_model_handle_t handle)3016 static int stdev_stop_recognition(
3017                         const struct sound_trigger_hw_device *dev,
3018                         sound_model_handle_t handle)
3019 {
3020     struct knowles_sound_trigger_device *stdev =
3021         (struct knowles_sound_trigger_device *)dev;
3022     int status = 0;
3023     pthread_mutex_lock(&stdev->lock);
3024     ALOGD("+%s sound model %d+", __func__, handle);
3025 
3026     status = stop_recognition(stdev, handle);
3027 
3028     if (status != 0)
3029         goto exit;
3030 
3031     ALOGD("-%s sound model %d-", __func__, handle);
3032 exit:
3033     pthread_mutex_unlock(&stdev->lock);
3034 
3035     return status;
3036 }
3037 
3038 /**
3039  * Get the state of a given model.
3040  * The model state is returned asynchronously as a RecognitionEvent via
3041  * the callback that was registered in StartRecognition().
3042  * @param modelHandle The handle of the sound model whose state is being
3043  *                    queried.
3044  * @return retval Operation completion status: 0 in case of success,
3045  *                -ENOSYS in case of invalid model handle,
3046  *                -ENOMEM in case of memory allocation failure,
3047  *                -ENODEV in case of initialization error,
3048  *                -EINVAL in case where a recognition event is already
3049  *                        being processed.
3050  */
stdev_get_model_state(const struct sound_trigger_hw_device * dev,sound_model_handle_t sound_model_handle)3051 static int stdev_get_model_state(const struct sound_trigger_hw_device *dev,
3052                                sound_model_handle_t sound_model_handle) {
3053     struct knowles_sound_trigger_device *stdev =
3054         (struct knowles_sound_trigger_device *)dev;
3055     struct model_info *model = &stdev->models[sound_model_handle];
3056     int ret = 0;
3057     ALOGD("+%s+", __func__);
3058     pthread_mutex_lock(&stdev->lock);
3059 
3060     if (!stdev->opened) {
3061         ALOGE("%s: stdev isn't initialized", __func__);
3062         ret = -ENODEV;
3063         goto exit;
3064     }
3065 
3066     if (stdev->is_st_hal_ready == false) {
3067         ALOGE("%s: ST HAL is not ready yet", __func__);
3068         ret = -ENODEV;
3069         goto exit;
3070     }
3071 
3072     if (model->is_active == false) {
3073         ALOGE("%s: ERROR: %d model is not active",
3074             __func__, sound_model_handle);
3075         ret = -ENOSYS;
3076         goto exit;
3077     }
3078 
3079     if (model->is_state_query == true) {
3080         ALOGE("%s: ERROR: model %d is already processing",
3081             __func__, sound_model_handle);
3082         ret = -EINVAL;
3083         goto exit;
3084     }
3085 
3086     model->is_state_query = true;
3087 
3088     if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid))
3089         ret = get_model_state(stdev->odsp_hdl, HOTWORD_INSTANCE_ID,
3090                             HOTWORD_SLOT_ID);
3091     else if (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))
3092         ret = get_model_state(stdev->odsp_hdl, HOTWORD_INSTANCE_ID,
3093                             WAKEUP_SLOT_ID);
3094     else if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid))
3095         ret = get_model_state(stdev->odsp_hdl, AMBIENT_INSTANCE_ID,
3096                             AMBIENT_SLOT_ID);
3097     else if (check_uuid_equality(model->uuid, stdev->entity_model_uuid)) {
3098         ret = get_model_state(stdev->odsp_hdl, AMBIENT_INSTANCE_ID,
3099                             ENTITY_SLOT_ID);
3100     } else {
3101         ALOGE("%s: ERROR: %d model is not supported",
3102             __func__, sound_model_handle);
3103         ret = -ENOSYS;
3104     }
3105 
3106     if (ret != 0) {
3107         model->is_state_query = false;
3108         ALOGE("%s: ERROR: Failed to get the model state", __func__);
3109     }
3110 
3111 exit:
3112     pthread_mutex_unlock(&stdev->lock);
3113     ALOGD("-%s-", __func__);
3114     return ret;
3115 }
3116 
stdev_close(hw_device_t * device)3117 static int stdev_close(hw_device_t *device)
3118 {
3119     struct knowles_sound_trigger_device *stdev =
3120         (struct knowles_sound_trigger_device *)device;
3121     int ret = 0;
3122     ALOGD("+%s+", __func__);
3123     pthread_mutex_lock(&stdev->lock);
3124 
3125     if (!stdev->opened) {
3126         ALOGE("%s: device already closed", __func__);
3127         ret = -EFAULT;
3128         goto exit;
3129     }
3130 
3131     if (stdev->is_st_hal_ready == false) {
3132         ALOGE("%s: ST HAL is not ready yet", __func__);
3133         ret = -EAGAIN;
3134         goto exit;
3135     }
3136 
3137     setup_slpi_wakeup_event(stdev->odsp_hdl, false);
3138 
3139     stdev->opened = false;
3140 
3141     if (stdev->send_sock >= 0)
3142         write(stdev->send_sock, "T", 1);
3143     pthread_join(stdev->callback_thread, (void **)NULL);
3144 
3145     if (stdev->route_hdl)
3146         audio_route_free(stdev->route_hdl);
3147     if (stdev->odsp_hdl)
3148         iaxxx_odsp_deinit(stdev->odsp_hdl);
3149 
3150     if (stdev->ss_timer_created) {
3151         timer_delete(stdev->ss_timer);
3152         stdev->ss_timer_created = false;
3153     }
3154 
3155 exit:
3156     pthread_mutex_unlock(&stdev->lock);
3157     ALOGD("-%s-", __func__);
3158     return ret;
3159 }
3160 
3161 __attribute__ ((visibility ("default")))
stdev_get_audio_handle()3162 audio_io_handle_t stdev_get_audio_handle()
3163 {
3164     if (g_stdev.last_keyword_detected_config == NULL) {
3165         ALOGI("%s: Config is NULL so returning audio handle as 0", __func__);
3166         return 0;
3167     }
3168 
3169     ALOGI("%s: Audio Handle is %d",
3170         __func__, g_stdev.last_keyword_detected_config->capture_handle);
3171 
3172     return g_stdev.last_keyword_detected_config->capture_handle;
3173 }
3174 
open_streaming_lib(struct knowles_sound_trigger_device * stdev)3175 static int open_streaming_lib(struct knowles_sound_trigger_device *stdev) {
3176     int ret = 0;
3177 
3178     if (access(ADNC_STRM_LIBRARY_PATH, R_OK) == 0) {
3179         stdev->adnc_cvq_strm_lib = dlopen(ADNC_STRM_LIBRARY_PATH, RTLD_NOW);
3180         if (stdev->adnc_cvq_strm_lib == NULL) {
3181             char const *err_str = dlerror();
3182             ALOGE("%s: module = %s error = %s", __func__,
3183                 ADNC_STRM_LIBRARY_PATH, err_str ? err_str : "unknown");
3184             ALOGE("%s: DLOPEN failed for %s", __func__, ADNC_STRM_LIBRARY_PATH);
3185         } else {
3186             ALOGV("%s: DLOPEN successful for %s",
3187                 __func__, ADNC_STRM_LIBRARY_PATH);
3188             for (int index = 0; index < MAX_MODELS; index++) {
3189                 stdev->adnc_strm_handle[index] = 0;
3190                 stdev->adnc_strm_last_read[index] = reset_time;
3191             }
3192             stdev->adnc_strm_open =
3193                 (int (*)(bool, int, int))dlsym(stdev->adnc_cvq_strm_lib,
3194                 "adnc_strm_open");
3195             stdev->adnc_strm_read =
3196                (size_t (*)(long, void *, size_t))dlsym(stdev->adnc_cvq_strm_lib,
3197                 "adnc_strm_read");
3198             stdev->adnc_strm_close =
3199                 (int (*)(long))dlsym(stdev->adnc_cvq_strm_lib,
3200                 "adnc_strm_close");
3201             if (!stdev->adnc_strm_open || !stdev->adnc_strm_read ||
3202                 !stdev->adnc_strm_close) {
3203                 ALOGE("%s: Error grabbing functions in %s", __func__,
3204                     ADNC_STRM_LIBRARY_PATH);
3205                 stdev->adnc_strm_open = 0;
3206                 stdev->adnc_strm_read = 0;
3207                 stdev->adnc_strm_close = 0;
3208             }
3209         }
3210     }
3211 
3212     return ret;
3213 }
3214 
find_stdev_mixer_path(int card_num,char * mixer_path_xml)3215 static struct mixer* find_stdev_mixer_path(int card_num, char *mixer_path_xml)
3216 {
3217     struct mixer *mixer = NULL;
3218     const char *in_snd_card_name;
3219     char *snd_card_name = NULL;
3220     char *tmp = NULL;
3221     char *platform = NULL;
3222     char *snd_card = NULL;
3223     char *device = NULL;
3224 
3225     mixer = mixer_open(card_num);
3226 
3227     if (!mixer) {
3228         ALOGE("%s: Unable to open the mixer: %d", __func__,
3229             card_num);
3230         return NULL;
3231     }
3232 
3233     in_snd_card_name = mixer_get_name(mixer);
3234     snd_card_name = strdup(in_snd_card_name);
3235 
3236     if (snd_card_name == NULL) {
3237         ALOGE("%s: snd_card_name is NULL", __func__);
3238         goto on_error;
3239     }
3240 
3241     platform = strtok_r(snd_card_name, "-", &tmp);
3242     if (platform == NULL) {
3243         ALOGE("%s: snd card is invalid", __func__);
3244         goto on_error;
3245     }
3246 
3247     snd_card = strtok_r(NULL, "-", &tmp);
3248     if (snd_card == NULL) {
3249         ALOGE("%s: snd card is invalid", __func__);
3250         goto on_error;
3251     }
3252 
3253     device = strtok_r(NULL, "-", &tmp);
3254     if (device != NULL) {
3255         snprintf(mixer_path_xml, NAME_MAX_SIZE, "%s_%s.xml",
3256                 SOUND_TRIGGER_MIXER_PATH_BASE, device);
3257     } else {
3258         ALOGE("%s: Unknown device, try to use default xml", __func__);
3259         snprintf(mixer_path_xml, NAME_MAX_SIZE, "%s",
3260                 SOUND_TRIGGER_MIXER_PATH_XML);
3261     }
3262 
3263     ALOGD("%s: using %s", __func__, mixer_path_xml);
3264 
3265 on_error:
3266     if (snd_card_name)
3267         free(snd_card_name);
3268     return mixer;
3269 }
3270 
find_sound_card()3271 static int find_sound_card() {
3272     int retry_num = 0, snd_card_num = 0, ret = -1;
3273     const char *snd_card_name;
3274     struct mixer *mixer = NULL;
3275     bool card_verifed[MAX_SND_CARD] = {false};
3276     const int retry_limit = property_get_int32("audio.snd_card.open.retries",
3277                                             RETRY_NUMBER);
3278     ALOGD("+%s+", __func__);
3279 
3280     for (;;) {
3281         if (snd_card_num >= MAX_SND_CARD) {
3282             if (retry_num++ >= retry_limit) {
3283                 ALOGE("%s: iaxxx sound card not found", __func__);
3284                 goto exit;
3285             }
3286             snd_card_num = 0;
3287             usleep(RETRY_US);
3288             continue;
3289         }
3290         if (card_verifed[snd_card_num]) {
3291             snd_card_num++;
3292             continue;
3293         }
3294 
3295         mixer = mixer_open(snd_card_num);
3296         if (!mixer) {
3297             snd_card_num++;
3298             continue;
3299         }
3300 
3301         snd_card_name = mixer_get_name(mixer);
3302         if (strstr(snd_card_name, CARD_NAME)) {
3303             ALOGD("%s: find card %d has iaxxx - %s",
3304                 __func__, snd_card_num, snd_card_name);
3305             ret = snd_card_num;
3306             break;
3307         }
3308 
3309         ALOGD("%s: sound card %s does NOT have iaxxx", __func__, snd_card_name);
3310         mixer_close(mixer);
3311         mixer = NULL;
3312         card_verifed[snd_card_num] = true;
3313         snd_card_num++;
3314     }
3315 
3316 exit:
3317     if (mixer)
3318         mixer_close(mixer);
3319 
3320     ALOGD("-%s-", __func__);
3321     return ret;
3322 }
3323 
load_audio_hal()3324 static int load_audio_hal()
3325 {
3326     char audio_hal_lib[100];
3327     void *sthal_prop_api_version = NULL;
3328     struct knowles_sound_trigger_device *stdev = &g_stdev;
3329     int ret = 0;
3330 
3331     snprintf(audio_hal_lib, sizeof(audio_hal_lib), "%s/%s.%s.so",
3332             AUDIO_HAL_LIBRARY_PATH, AUDIO_HAL_NAME_PREFIX,
3333             SOUND_TRIGGER_PLATFORM);
3334     if (access(audio_hal_lib, R_OK)) {
3335         ALOGE("%s: ERROR. %s not found", __func__, audio_hal_lib);
3336         return -ENOENT;
3337     }
3338 
3339     stdev->audio_hal_handle = dlopen(audio_hal_lib, RTLD_NOW);
3340     if (stdev->audio_hal_handle == NULL) {
3341         ALOGE("%s: ERROR. %s", __func__, dlerror());
3342         return -ENODEV;
3343     }
3344 
3345     stdev->audio_hal_cb = dlsym(stdev->audio_hal_handle, "audio_hw_call_back");
3346     if (stdev->audio_hal_cb == NULL) {
3347         ALOGE("%s: ERROR. %s", __func__, dlerror());
3348         ret = -ENODEV;
3349         goto error;
3350     }
3351 
3352     sthal_prop_api_version = dlsym(stdev->audio_hal_handle,
3353                                 "sthal_prop_api_version");
3354     if (sthal_prop_api_version == NULL) {
3355         stdev->sthal_prop_api_version = 0;
3356         ret = 0; /* passthru for backward compability */
3357     } else {
3358         stdev->sthal_prop_api_version = *(int *)sthal_prop_api_version;
3359         if (MAJOR_VERSION(stdev->sthal_prop_api_version) !=
3360             MAJOR_VERSION(STHAL_PROP_API_CURRENT_VERSION)) {
3361             ALOGE("%s: Incompatible API versions sthal:0x%x != ahal:0x%x",
3362                 __func__, STHAL_PROP_API_CURRENT_VERSION,
3363                 stdev->sthal_prop_api_version);
3364             goto error;
3365         }
3366         ALOGD("%s: ahal is using proprietary API version 0x%04x", __func__,
3367             stdev->sthal_prop_api_version);
3368     }
3369 
3370     ALOGD("%s: load AHAL successfully.", __func__);
3371     return ret;
3372 
3373 error:
3374     dlclose(stdev->audio_hal_handle);
3375     stdev->audio_hal_handle = NULL;
3376     return ret;
3377 }
3378 
stdev_open(const hw_module_t * module,const char * name,hw_device_t ** device)3379 static int stdev_open(const hw_module_t *module, const char *name,
3380         hw_device_t **device)
3381 {
3382     struct knowles_sound_trigger_device *stdev;
3383     int ret = 0, i = 0;
3384     int snd_card_num = 0;
3385 
3386     ALOGE("!! Knowles SoundTrigger v1!!");
3387 
3388     if (strcmp(name, SOUND_TRIGGER_HARDWARE_INTERFACE) != 0)
3389         return -EINVAL;
3390 
3391     if (device == NULL)
3392         return -EINVAL;
3393 
3394     stdev = &g_stdev;
3395     pthread_mutex_lock(&stdev->lock);
3396 
3397     snd_card_num = find_sound_card();
3398     if (snd_card_num == -1) {
3399         ALOGE("%s: Unable to find the sound card %s", __func__, CARD_NAME);
3400         ret = -EAGAIN;
3401         goto exit;
3402     }
3403 
3404     if (stdev->opened) {
3405         ALOGE("%s: Only one sountrigger can be opened at a time", __func__);
3406         ret = -EBUSY;
3407         goto exit;
3408     }
3409 
3410     ret = open_streaming_lib(stdev);
3411     if (ret != 0) {
3412         ALOGE("%s: Couldnot open the streaming library", __func__);
3413         goto error;
3414     }
3415 
3416     ret = load_audio_hal();
3417     if (ret != 0) {
3418         ALOGE("%s: Couldn't load AHAL", __func__);
3419         goto error;
3420     }
3421 
3422     stdev->device.common.tag = HARDWARE_DEVICE_TAG;
3423     stdev->device.common.version = SOUND_TRIGGER_DEVICE_API_VERSION_1_2;
3424     stdev->device.common.module = (struct hw_module_t *)module;
3425     stdev->device.common.close = stdev_close;
3426     stdev->device.get_properties = stdev_get_properties;
3427     stdev->device.load_sound_model = stdev_load_sound_model;
3428     stdev->device.unload_sound_model = stdev_unload_sound_model;
3429     stdev->device.start_recognition = stdev_start_recognition;
3430     stdev->device.stop_recognition = stdev_stop_recognition;
3431     stdev->device.get_model_state = stdev_get_model_state;
3432 
3433     stdev->opened = true;
3434     /* Initialize all member variable */
3435     for (i = 0; i < MAX_MODELS; i++) {
3436         stdev->models[i].type = SOUND_MODEL_TYPE_UNKNOWN;
3437         memset(&stdev->models[i].uuid, 0, sizeof(sound_trigger_uuid_t));
3438         stdev->models[i].config = NULL;
3439         stdev->models[i].data = NULL;
3440         stdev->models[i].data_sz = 0;
3441         stdev->models[i].is_loaded = false;
3442         stdev->models[i].is_active = false;
3443         stdev->last_keyword_detected_config = NULL;
3444         stdev->models[i].is_state_query = false;
3445     }
3446 
3447     stdev->is_mic_route_enabled = false;
3448     stdev->is_con_mic_route_enabled = false;
3449     stdev->is_ahal_in_voice_voip_mode = false;
3450     stdev->is_ahal_voice_voip_stop = false;
3451     stdev->is_ahal_voice_voip_start = false;
3452     stdev->is_bargein_route_enabled = false;
3453     stdev->is_chre_loaded = false;
3454     stdev->is_buffer_package_loaded = false;
3455     stdev->hotword_buffer_enable = 0;
3456     stdev->music_buffer_enable = 0;
3457     stdev->current_enable = 0;
3458     stdev->is_sensor_route_enabled = false;
3459     stdev->recover_model_list = 0;
3460     stdev->rx_active_count = 0;
3461     stdev->is_ahal_media_recording = false;
3462     stdev->is_concurrent_capture = hw_properties.concurrent_capture;
3463 
3464     stdev->is_sensor_destroy_in_prog = false;
3465     stdev->ss_timer_created = false;
3466 
3467     stdev->is_chre_destroy_in_prog = false;
3468     stdev->chre_timer_created = false;
3469 
3470     stdev->snd_crd_num = snd_card_num;
3471     stdev->fw_reset_done_by_hal = false;
3472 
3473     str_to_uuid(HOTWORD_AUDIO_MODEL, &stdev->hotword_model_uuid);
3474     str_to_uuid(WAKEUP_MODEL, &stdev->wakeup_model_uuid);
3475     str_to_uuid(SENSOR_MANAGER_MODEL, &stdev->sensor_model_uuid);
3476     str_to_uuid(AMBIENT_AUDIO_MODEL, &stdev->ambient_model_uuid);
3477     str_to_uuid(CHRE_AUDIO_MODEL, &stdev->chre_model_uuid);
3478     str_to_uuid(ENTITY_AUDIO_MODEL, &stdev->entity_model_uuid);
3479 
3480     stdev->odsp_hdl = iaxxx_odsp_init();
3481     if (stdev->odsp_hdl == NULL) {
3482         ALOGE("%s: Failed to get handle to ODSP HAL", __func__);
3483         ret = -EIO;
3484         goto error;
3485     }
3486     stdev->mixer = find_stdev_mixer_path(stdev->snd_crd_num, stdev->mixer_path_xml);
3487     if (stdev->mixer == NULL) {
3488         ALOGE("Failed to init the mixer");
3489         ret = -EAGAIN;
3490         goto error;
3491     }
3492 
3493     ALOGD("stdev before pthread_create %p", stdev);
3494     // Create a thread to handle all events from kernel
3495     pthread_create(&stdev->callback_thread, (const pthread_attr_t *) NULL,
3496                 callback_thread_loop, stdev);
3497 
3498     pthread_create(&stdev->monitor_thread, (const pthread_attr_t *) NULL,
3499                 monitor_thread_loop, stdev);
3500 
3501     pthread_create(&stdev->transitions_thread, (const pthread_attr_t *) NULL,
3502                 transitions_thread_loop, stdev);
3503 
3504     *device = &stdev->device.common; /* same address as stdev */
3505 exit:
3506     pthread_mutex_unlock(&stdev->lock);
3507     return ret;
3508 
3509 error:
3510     if (stdev->adnc_cvq_strm_lib)
3511         dlclose(stdev->adnc_cvq_strm_lib);
3512     if (stdev->audio_hal_handle)
3513         dlclose(stdev->audio_hal_handle);
3514     if (stdev->route_hdl)
3515         audio_route_free(stdev->route_hdl);
3516     if (stdev->odsp_hdl)
3517         iaxxx_odsp_deinit(stdev->odsp_hdl);
3518     if (stdev->mixer)
3519         mixer_close(stdev->mixer);
3520 
3521     pthread_mutex_unlock(&stdev->lock);
3522     return ret;
3523 }
3524 
3525 /* AHAL calls this callback to communicate with STHAL */
sound_trigger_hw_call_back(audio_event_type_t event,struct audio_event_info * config)3526 int sound_trigger_hw_call_back(audio_event_type_t event,
3527                             struct audio_event_info *config)
3528 {
3529     int ret = 0;
3530     int i = 0;
3531     int index = -1;
3532     struct knowles_sound_trigger_device *stdev = &g_stdev;
3533     enum sthal_mode pre_mode, cur_mode;
3534 
3535     if (!stdev)
3536         return -ENODEV;
3537 
3538     if (!stdev->opened) {
3539         ALOGE("%s: Error SoundTrigger has not been opened", __func__);
3540         return -EINVAL;
3541     }
3542 
3543     pthread_mutex_lock(&stdev->lock);
3544 
3545     // update conditions for mic concurrency whatever firmware status may be.
3546     if (event == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE ||
3547         event == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE ||
3548         event == AUDIO_EVENT_CAPTURE_STREAM_INACTIVE ||
3549         event == AUDIO_EVENT_CAPTURE_STREAM_ACTIVE) {
3550         pre_mode = get_sthal_mode(stdev);
3551         update_sthal_conditions(stdev, event, config);
3552         cur_mode = get_sthal_mode(stdev);
3553     }
3554 
3555     // update conditions for bargein whatever firmware status may be.
3556     if (event == AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE ||
3557         event == AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE) {
3558         update_rx_conditions(stdev, event, config);
3559     }
3560 
3561     if (stdev->is_st_hal_ready == false) {
3562         ALOGE("%s: ST HAL is not ready yet", __func__);
3563         ret = -EINVAL;
3564         goto exit;
3565     }
3566 
3567     switch (event) {
3568     case AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE:
3569     case AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE:
3570         ALOGD("%s: handle capture device event %d", __func__, event);
3571 
3572         //handle capture device on/off event
3573         do_handle_functions(stdev, pre_mode, cur_mode, event);
3574 
3575         break;
3576     case AUDIO_EVENT_CAPTURE_STREAM_INACTIVE:
3577     case AUDIO_EVENT_CAPTURE_STREAM_ACTIVE:
3578         ALOGD("%s: handle capture stream event %d, usecase %d",
3579               __func__, event, config->u.usecase.type);
3580 
3581         break;
3582     case AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE:
3583         ALOGD("%s: handle playback stream inactive", __func__);
3584 
3585         if (stdev->rx_active_count == 0) {
3586             if (stdev->is_mic_route_enabled != false) {
3587                 // Atleast one keyword model is active so update the routes
3588                 // Check if the bargein route is enabled if not enable bargein route
3589                 // Check each model, if it is active then update it's route
3590                 if (stdev->is_bargein_route_enabled != false) {
3591                     ALOGD("Bargein disabling");
3592                     stdev->is_bargein_route_enabled = false;
3593                     // Check each model, if it is active then update it's route
3594                     // Disable the bargein route
3595                     for (i = 0; i < MAX_MODELS; i++) {
3596                         if (stdev->models[i].is_active == true) {
3597                             // teardown the package route with bargein
3598                             ret = tear_package_route(stdev,
3599                                                     stdev->models[i].uuid,
3600                                                     !stdev->is_bargein_route_enabled);
3601                             if (ret != 0) {
3602                                 ALOGE("Failed to tear old package route");
3603                                 goto exit;
3604                             }
3605                             // resetup the package route with out bargein
3606                             ret = set_package_route(stdev,
3607                                                     stdev->models[i].uuid,
3608                                                     stdev->is_bargein_route_enabled);
3609                             if (ret != 0) {
3610                                 ALOGE("Failed to enable package route");
3611                                 goto exit;
3612                             }
3613                         }
3614                     }
3615 
3616                     //Switch buffer input source
3617                     if (stdev->hotword_buffer_enable) {
3618                         ret = tear_hotword_buffer_route(stdev->route_hdl,
3619                                             !stdev->is_bargein_route_enabled);
3620                         if (ret != 0) {
3621                             ALOGE("Failed to tear old buffer route");
3622                             goto exit;
3623                         }
3624                         ret = set_hotword_buffer_route(stdev->route_hdl,
3625                                             stdev->is_bargein_route_enabled);
3626                         if (ret != 0) {
3627                             ALOGE("Failed to enable buffer route");
3628                             goto exit;
3629                         }
3630                     }
3631 
3632                     if (stdev->music_buffer_enable) {
3633                         ret = tear_music_buffer_route(stdev->route_hdl,
3634                                             !stdev->is_bargein_route_enabled);
3635                         if (ret != 0) {
3636                             ALOGE("Failed to tear old music buffer route");
3637                             goto exit;
3638                         }
3639                         ret = set_music_buffer_route(stdev->route_hdl,
3640                                             stdev->is_bargein_route_enabled);
3641                         if (ret != 0) {
3642                             ALOGE("Failed to enable buffer route");
3643                             goto exit;
3644                         }
3645                     }
3646 
3647                     ret = enable_bargein_route(stdev->route_hdl, false);
3648                     if (ret != 0) {
3649                         ALOGE("Failed to enable buffer route");
3650                         goto exit;
3651                     }
3652 
3653                     ret = destroy_aec_package(stdev->odsp_hdl);
3654                     if (ret != 0) {
3655                         ALOGE("Failed to unload AEC package");
3656                         goto exit;
3657                     }
3658 
3659                     ret = enable_src_route(stdev->route_hdl, false, SRC_AMP_REF);
3660                     if (ret != 0) {
3661                         ALOGE("Failed to disable SRC-amp route");
3662                         goto exit;
3663                     }
3664 
3665                     ret = destroy_src_plugin(stdev->odsp_hdl, SRC_AMP_REF);
3666                     if (ret != 0) {
3667                         ALOGE("Failed to unload SRC-amp package");
3668                         goto exit;
3669                     }
3670 
3671                     if (is_mic_controlled_by_ahal(stdev) == false) {
3672                         ret = enable_amp_ref_route(stdev->route_hdl, false, STRM_16K);
3673                         if (ret != 0) {
3674                             ALOGE("Failed to disable amp-ref route");
3675                             goto exit;
3676                         }
3677                         ret = enable_mic_route(stdev->route_hdl, false,
3678                                             EXTERNAL_OSCILLATOR);
3679                         if (ret != 0) {
3680                             ALOGE("Failed to disable mic route with INT OSC");
3681                             goto exit;
3682                         }
3683                         ret = enable_mic_route(stdev->route_hdl, true,
3684                                             INTERNAL_OSCILLATOR);
3685                         if (ret != 0) {
3686                             ALOGE("Failed to enable mic route with EXT OSC");
3687                             goto exit;
3688                         }
3689                     } else {
3690                         // main mic is turned by media record, close it by 48khz
3691                         ret = enable_amp_ref_route(stdev->route_hdl, false, STRM_48K);
3692                         if (ret != 0) {
3693                             ALOGE("Failed to disable amp-ref route");
3694                             goto exit;
3695                         }
3696                     }
3697                 } else {
3698                     ALOGW("%s: barge-in isn't enabled", __func__);
3699                 }
3700             }
3701         } else {
3702             ALOGD("%s: rx stream is still active", __func__);
3703         }
3704         break;
3705     case AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE:
3706         ALOGD("%s: handle playback stream active", __func__);
3707 
3708         if (stdev->rx_active_count > 0) {
3709             if (stdev->is_mic_route_enabled != false) {
3710                 // Atleast one keyword model is active so update the routes
3711                 // Check if the bargein route is enabled if not enable bargein route
3712                 // Check each model, if it is active then update it's route
3713                 stdev->transit_case = TRANSIT_SETUP_AEC;
3714                 pthread_cond_signal(&stdev->transition_cond);
3715             }
3716         } else {
3717             ALOGW("%s: unexpeted stream active event", __func__);
3718         }
3719         break;
3720     case AUDIO_EVENT_STOP_LAB:
3721         /* Close Stream Driver */
3722         for (i = 0; i < MAX_MODELS; i++) {
3723             if (stdev->models[i].is_active &&
3724                 stdev->models[i].config &&
3725                 (stdev->models[i].config->capture_handle ==
3726                  config->u.ses_info.capture_handle)) {
3727                 index = i;
3728                 break;
3729             }
3730         }
3731 
3732         /*
3733          * Close unused adnc if ...
3734          * 1. No capture handle is found
3735          * 2. Model is inactive
3736          * 3. adnc stream handle is existed
3737          */
3738         if (index == -1 && stdev->is_streaming > 0) {
3739             ALOGD("%s: close unused adnc handle, cap_handle:%d", __func__,
3740                   config->u.ses_info.capture_handle);
3741             for (i = 0; i < MAX_MODELS; i++) {
3742                 if (stdev->adnc_strm_handle[i] != 0 &&
3743                     !stdev->models[i].is_active) {
3744                     stdev->adnc_strm_close(stdev->adnc_strm_handle[i]);
3745                     stdev->adnc_strm_handle[i] = 0;
3746                     stdev->is_streaming--;
3747                     stdev->adnc_strm_last_read[i] = reset_time;
3748                 }
3749             }
3750             goto exit;
3751         }
3752 
3753         ALOGD("%s: close streaming %d, cap_handle:%d, index:%d",
3754               __func__, event, config->u.ses_info.capture_handle, index);
3755         if (index != -1 && stdev->adnc_strm_handle[index] != 0) {
3756             stdev->adnc_strm_close(stdev->adnc_strm_handle[index]);
3757             stdev->adnc_strm_handle[index] = 0;
3758             stdev->is_streaming--;
3759             stdev->adnc_strm_last_read[index] = reset_time;
3760         }
3761 
3762         break;
3763 
3764     case AUDIO_EVENT_SSR:
3765         /*[TODO] Do we need to handle adsp SSR event ? */
3766         ALOGD("%s: handle audio subsystem restart %d", __func__, event);
3767         break;
3768 
3769     case AUDIO_EVENT_READ_SAMPLES:
3770         /* It is possible to change session info, check config */
3771         if (config->u.aud_info.ses_info == NULL) {
3772             ALOGE("%s: Invalid config, event:%d", __func__, event);
3773             ret = -EINVAL;
3774             goto exit;
3775         }
3776 
3777         for (i = 0; i < MAX_MODELS; i++) {
3778             if (stdev->models[i].is_active &&
3779                 stdev->models[i].config &&
3780                 (stdev->models[i].config->capture_handle ==
3781                  config->u.aud_info.ses_info->capture_handle)) {
3782                 index = i;
3783                 break;
3784             }
3785         }
3786 
3787         /* Open Stream Driver */
3788         if (index != -1 && stdev->adnc_strm_handle[index] == 0) {
3789             if (stdev->adnc_strm_open == NULL) {
3790                 ALOGE("%s: Error adnc streaming not supported", __func__);
3791             } else {
3792                 bool keyword_stripping_enabled = false;
3793                 int stream_end_point;
3794                 switch (stdev->last_detected_model_type) {
3795                     case OK_GOOGLE_KW_ID:
3796                         stream_end_point = CVQ_ENDPOINT;
3797                         break;
3798                     case AMBIENT_KW_ID:
3799                     case ENTITY_KW_ID:
3800                         stream_end_point = MUSIC_BUF_ENDPOINT;
3801                         break;
3802                     default:
3803                         stream_end_point = CVQ_ENDPOINT;
3804                         break;
3805                 };
3806                 stdev->adnc_strm_handle[index] = stdev->adnc_strm_open(
3807                                             keyword_stripping_enabled, 0,
3808                                             stream_end_point);
3809                 if (stdev->adnc_strm_handle[index]) {
3810                     ALOGD("Successfully opened adnc strm! index %d handle %d",
3811                           index, config->u.aud_info.ses_info->capture_handle);
3812                     stdev->is_streaming++;
3813 
3814                     clock_gettime(CLOCK_REALTIME, &stdev->adnc_strm_last_read[index]);
3815                     if (stdev->is_streaming == 1)
3816                         pthread_cond_signal(&stdev->tunnel_create);
3817                 } else {
3818                     ALOGE("%s: DSP is currently not streaming", __func__);
3819                 }
3820             }
3821         }
3822 
3823         if (index != -1 && stdev->adnc_strm_handle[index] != 0) {
3824             //ALOGD("%s: soundtrigger HAL adnc_strm_read", __func__);
3825             clock_gettime(CLOCK_REALTIME, &stdev->adnc_strm_last_read[index]);
3826             pthread_mutex_unlock(&stdev->lock);
3827             stdev->adnc_strm_read(stdev->adnc_strm_handle[index],
3828                                 config->u.aud_info.buf,
3829                                 config->u.aud_info.num_bytes);
3830             pthread_mutex_lock(&stdev->lock);
3831         } else {
3832             ALOGE("%s: soundtrigger is not streaming", __func__);
3833         }
3834 
3835         break;
3836 
3837     case AUDIO_EVENT_NUM_ST_SESSIONS:
3838     case AUDIO_EVENT_DEVICE_CONNECT:
3839     case AUDIO_EVENT_DEVICE_DISCONNECT:
3840     case AUDIO_EVENT_SVA_EXEC_MODE:
3841     case AUDIO_EVENT_SVA_EXEC_MODE_STATUS:
3842         ALOGV("%s: useless event %d", __func__, event);
3843         break;
3844 
3845     default:
3846         ALOGW("%s: Unknown event %d", __func__, event);
3847         break;
3848     }
3849 
3850 exit:
3851     pthread_mutex_unlock(&stdev->lock);
3852     return ret;
3853 }
3854 
3855 static struct hw_module_methods_t hal_module_methods = {
3856     .open = stdev_open,
3857 };
3858 
3859 struct sound_trigger_module HAL_MODULE_INFO_SYM = {
3860     .common = {
3861         .tag = HARDWARE_MODULE_TAG,
3862         .module_api_version = SOUND_TRIGGER_MODULE_API_VERSION_1_0,
3863         .hal_api_version = HARDWARE_HAL_API_VERSION,
3864         .id = SOUND_TRIGGER_HARDWARE_MODULE_ID,
3865         .name = "Knowles Sound Trigger HAL",
3866         .author = "Knowles Electronics",
3867         .methods = &hal_module_methods,
3868     },
3869 };
3870