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