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     "", //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         get_hotword_info(stdev->odsp_hdl,
2256                         &stdev->hotword_version,
2257                         &hw_properties.supported_model_arch);
2258         // reset the firmware and wait for firmware download complete
2259         err = reset_fw(stdev->odsp_hdl);
2260         if (err == -1) {
2261             ALOGE("%s: ERROR: Failed to reset the firmware %d(%s)",
2262                     __func__, errno, strerror(errno));
2263         }
2264         stdev->fw_reset_done_by_hal = true;
2265     } else if (fw_status == IAXXX_FW_CRASH) {
2266         // Firmware has crashed wait till it recovers
2267         stdev->is_st_hal_ready = false;
2268     } else if (fw_status == IAXXX_FW_IDLE) {
2269         err = get_hotword_info(stdev->odsp_hdl,
2270                             &stdev->hotword_version,
2271                             &hw_properties.supported_model_arch);
2272         if (stdev->hotword_version == HOTWORD_DEFAULT_VER) {
2273             /* This is unlikely use-case, the codec is abnormal at the beginning
2274              * reset_fw the firmware to recovery.
2275              */
2276             stdev->is_st_hal_ready = false;
2277             err = reset_fw(stdev->odsp_hdl);
2278             if (err == -1) {
2279                 ALOGE("%s: ERROR: Failed to reset the firmware %d(%s)",
2280                       __func__, errno, strerror(errno));
2281             }
2282             stdev->fw_reset_done_by_hal = true;
2283         } else {
2284             stdev->route_hdl = audio_route_init(stdev->snd_crd_num,
2285                                             stdev->mixer_path_xml);
2286             if (stdev->route_hdl == NULL) {
2287                 ALOGE("Failed to init the audio_route library");
2288                 goto exit;
2289             }
2290             set_default_apll_clk(stdev->mixer);
2291             setup_slpi_wakeup_event(stdev->odsp_hdl, true);
2292             stdev->is_st_hal_ready = true;
2293         }
2294     }
2295     pthread_mutex_unlock(&stdev->lock);
2296 
2297     while (1) {
2298         err = poll(fds, 2, timeout);
2299 
2300         pthread_mutex_lock(&stdev->lock);
2301         if (err < 0) {
2302             ALOGE("%s: Error in poll: %d (%s)",
2303                 __func__, errno, strerror(errno));
2304             break;
2305         }
2306 
2307         if (fds[0].revents & POLLIN) {
2308             n = uevent_kernel_multicast_recv(fds[0].fd, msg, UEVENT_MSG_LEN);
2309             if (n <= 0) {
2310                 pthread_mutex_unlock(&stdev->lock);
2311                 continue;
2312             }
2313             for (i = 0; i < n;) {
2314                 if (strstr(msg + i, IAXXX_VQ_EVENT_STR)) {
2315                     ALOGI("%s", IAXXX_VQ_EVENT_STR);
2316 
2317                     err = get_event(stdev->odsp_hdl, &ge);
2318                     if (err == 0) {
2319                         if (ge.event_id == OK_GOOGLE_KW_ID) {
2320                             kwid = OK_GOOGLE_KW_ID;
2321                         } else if (ge.event_id == AMBIENT_KW_ID) {
2322                             kwid = AMBIENT_KW_ID;
2323                             reset_ambient_plugin(stdev->odsp_hdl);
2324                         } else if (ge.event_id == OSLO_EP_DISCONNECT) {
2325                             ALOGD("Eventid received is OSLO_EP_DISCONNECT %d",
2326                                   OSLO_EP_DISCONNECT);
2327                             if (stdev->is_sensor_destroy_in_prog == true) {
2328                                 // A timer would have been created during stop,
2329                                 // check and delete it
2330                                 if (stdev->ss_timer_created) {
2331                                     timer_delete(stdev->ss_timer);
2332                                     stdev->ss_timer_created = false;
2333                                 }
2334 
2335                                 destroy_sensor_model(stdev);
2336                             } else {
2337                                 ALOGE("Unexpected OSLO_EP_DISCONNECT received"
2338                                       ", ignoring..");
2339                             }
2340                             break;
2341                         } else if (ge.event_id == CHRE_EP_DISCONNECT) {
2342                             ALOGD("Eventid received is CHRE_EP_DISCONNECT %d",
2343                                   CHRE_EP_DISCONNECT);
2344                             if (stdev->is_chre_destroy_in_prog == true) {
2345                                 // A timer would have been created during stop,
2346                                 // check and delete it
2347                                 if (stdev->chre_timer_created) {
2348                                     timer_delete(stdev->chre_timer);
2349                                     stdev->chre_timer_created = false;
2350                                 }
2351 
2352                                 destroy_chre_model(stdev);
2353                             } else {
2354                                 ALOGE("Unexpected CHRE_EP_DISCONNECT received"
2355                                       ", ignoring..");
2356                             }
2357                             break;
2358                         } else if (ge.event_id == ENTITY_KW_ID) {
2359                             kwid = ENTITY_KW_ID;
2360                         } else if (ge.event_id == WAKEUP_KW_ID) {
2361                             kwid = WAKEUP_KW_ID;
2362                         } else {
2363                             ALOGE("Unknown event id received, ignoring %d",
2364                                 ge.event_id);
2365                         }
2366                         break;
2367                     } else {
2368                         ALOGE("get_event failed with error %d", err);
2369                     }
2370                 } else if (strstr(msg + i, IAXXX_RECOVERY_EVENT_STR)) {
2371                     /* If the ST HAL did the firmware reset then that means
2372                      * that the userspace crashed so we need to reinit the audio
2373                      * route library, if we didn't reset the firmware, then it
2374                      * was genuine firmware crash and we don't need to reinit
2375                      * the audio route library.
2376                      */
2377                     ALOGD("Firmware has redownloaded, start the recovery");
2378                     if (stdev->fw_reset_done_by_hal == true) {
2379                         stdev->route_hdl = audio_route_init(stdev->snd_crd_num,
2380                                                             stdev->mixer_path_xml);
2381                         if (stdev->route_hdl == NULL) {
2382                             ALOGE("Failed to init the audio_route library");
2383                             goto exit;
2384                         }
2385 
2386                         stdev->fw_reset_done_by_hal = false;
2387                     }
2388 
2389                     int err = crash_recovery(stdev);
2390                     if (err != 0) {
2391                         ALOGE("Crash recovery failed");
2392                     }
2393                     pthread_cond_signal(&stdev->firmware_ready_cond);
2394                 } else if (strstr(msg + i, IAXXX_FW_DWNLD_SUCCESS_STR)) {
2395                     ALOGD("Firmware downloaded successfully");
2396                     stdev->is_st_hal_ready = true;
2397                     set_default_apll_clk(stdev->mixer);
2398                 } else if (strstr(msg + i, IAXXX_FW_CRASH_EVENT_STR)) {
2399                     ALOGD("Firmware has crashed");
2400                     // Don't allow any op on ST HAL until recovery is complete
2401                     stdev->is_st_hal_ready = false;
2402                     reset_all_route(stdev->route_hdl);
2403                     stdev->is_streaming = 0;
2404 
2405                     // Firmware crashed, clear CHRE/Oslo timer and flags here
2406                     sensor_crash_handler(stdev);
2407                     chre_crash_handler(stdev);
2408                 }
2409 
2410                 i += strlen(msg + i) + 1;
2411             }
2412 
2413             if (ge.event_id == OK_GOOGLE_KW_ID ||
2414                 ge.event_id == AMBIENT_KW_ID ||
2415                 ge.event_id == ENTITY_KW_ID ||
2416                 ge.event_id == WAKEUP_KW_ID) {
2417                 ALOGD("%s: Keyword ID %d", __func__, kwid);
2418 
2419                 if (ge.data != 0) {
2420                     ALOGD("Size of payload is %d", ge.data);
2421                     payload_size = ge.data;
2422                     payload = malloc(payload_size);
2423                     if (payload != NULL) {
2424                         if (ge.event_id == AMBIENT_KW_ID ||
2425                             ge.event_id == ENTITY_KW_ID)
2426                             err = get_entity_param_blk(stdev->odsp_hdl,
2427                                                     payload,
2428                                                     payload_size);
2429                         else if (ge.event_id == OK_GOOGLE_KW_ID ||
2430                             ge.event_id == WAKEUP_KW_ID)
2431                             err = get_wakeup_param_blk(stdev->odsp_hdl,
2432                                                     payload,
2433                                                     payload_size);
2434                         if (err != 0) {
2435                             ALOGE("Failed to get payload data");
2436                             free(payload);
2437                             payload = NULL;
2438                             payload_size = 0;
2439                         }
2440                     } else {
2441                         ALOGE("Failed to allocate memory for payload");
2442                     }
2443                 }
2444                 int idx = find_handle_for_kw_id(stdev, kwid);
2445                 if (idx < MAX_MODELS && stdev->models[idx].is_active == true) {
2446                     int recognition_status = RECOGNITION_STATUS_SUCCESS;
2447                     if (stdev->models[idx].is_state_query == true) {
2448                         recognition_status =
2449                             RECOGNITION_STATUS_GET_STATE_RESPONSE;
2450 
2451                         // We need to send this only once, so reset now
2452                         stdev->models[idx].is_state_query = false;
2453                     }
2454                     if (stdev->models[idx].type == SOUND_MODEL_TYPE_KEYPHRASE &&
2455                         stdev->adnc_strm_handle[idx] == 0) {
2456                         struct sound_trigger_phrase_recognition_event *event;
2457                         event = (struct sound_trigger_phrase_recognition_event*)
2458                                     stdev_keyphrase_event_alloc(
2459                                                 stdev->models[idx].model_handle,
2460                                                 stdev->models[idx].config,
2461                                                 recognition_status);
2462                         if (event) {
2463                             struct model_info *model;
2464                             model = &stdev->models[idx];
2465 
2466                             ALOGD("Sending recognition callback for id %d",
2467                                 kwid);
2468                             /* Exit the critical section of interaction with
2469                              * firmware, release the lock to avoid deadlock
2470                              * when processing recognition event */
2471                             pthread_mutex_unlock(&stdev->lock);
2472                             model->recognition_callback(&event->common,
2473                                                     model->recognition_cookie);
2474                             pthread_mutex_lock(&stdev->lock);
2475 
2476                             free(event);
2477                         } else {
2478                             ALOGE("Failed to allocate memory for the event");
2479                         }
2480                     } else if (stdev->models[idx].type == SOUND_MODEL_TYPE_GENERIC &&
2481                                stdev->adnc_strm_handle[idx] == 0) {
2482                         struct sound_trigger_generic_recognition_event *event;
2483                         event = (struct sound_trigger_generic_recognition_event*)
2484                                 stdev_generic_event_alloc(
2485                                             stdev->models[idx].model_handle,
2486                                             payload,
2487                                             payload_size,
2488                                             recognition_status);
2489                         if (event) {
2490                             struct model_info *model;
2491                             model = &stdev->models[idx];
2492 
2493                             ALOGD("Sending recognition callback for id %d",
2494                                 kwid);
2495                             /* Exit the critical section of interaction with
2496                              * firmware, release the lock to avoid deadlock
2497                              * when processing recognition event */
2498                             pthread_mutex_unlock(&stdev->lock);
2499                             model->recognition_callback(&event->common,
2500                                                     model->recognition_cookie);
2501                             pthread_mutex_lock(&stdev->lock);
2502                             free(event);
2503                         } else {
2504                             ALOGE("Failed to allocate memory for the event");
2505                         }
2506                     } else if (stdev->adnc_strm_handle[idx] != 0) {
2507                         ALOGD("model %d is streaming.", idx);
2508                     }
2509                 } else {
2510                     ALOGE("Invalid id or keyword is not active, Subsume the event");
2511                 }
2512                 // Reset all event related data
2513                 ge.event_id = -1;
2514                 ge.data = 0;
2515                 kwid = -1;
2516             }
2517             // Free the payload data
2518             if (payload) {
2519                 free(payload);
2520                 payload = NULL;
2521                 payload_size = 0;
2522             }
2523         } else if (fds[1].revents & POLLIN) {
2524             read(fds[1].fd, &n, sizeof(n)); /* clear the socket */
2525             ALOGD("%s: Termination message", __func__);
2526             break;
2527         }
2528         else {
2529             ALOGI("%s: Message ignored", __func__);
2530         }
2531         pthread_mutex_unlock(&stdev->lock);
2532     }
2533 
2534 exit:
2535     stdev_close_term_sock(stdev);
2536     pthread_mutex_unlock(&stdev->lock);
2537 
2538     return (void *)(long)err;
2539 }
2540 
stdev_get_properties(const struct sound_trigger_hw_device * dev __unused,struct sound_trigger_properties * properties)2541 static int stdev_get_properties(
2542                             const struct sound_trigger_hw_device *dev __unused,
2543                             struct sound_trigger_properties *properties)
2544 {
2545     ALOGV("+%s+", __func__);
2546     if (properties == NULL)
2547         return -EINVAL;
2548     memcpy(properties, &hw_properties.base, sizeof(struct sound_trigger_properties));
2549     ALOGV("-%s-", __func__);
2550     return 0;
2551 }
2552 
2553 /*  Insert a decimal numeral for Prefix into the beginning of String.
2554     Length specifies the total number of bytes available at str.
2555 */
int_prefix_str(char * str,size_t str_len,int prefix,const char * prefix_format)2556 static int int_prefix_str(char *str, size_t str_len, int prefix, const char *prefix_format)
2557 {
2558     int prefix_len = snprintf(NULL, 0, prefix_format, prefix);
2559     size_t str_cur_len = strlen(str);
2560 
2561     if (str_len < prefix_len + str_cur_len + 1)
2562     {
2563         ALOGE("%s: Error, not enough space in string to insert prefix: %d, %s\n",
2564                 __func__, prefix, str);
2565         return -1;
2566     }
2567 
2568     //  Move the string to make room for the prefix.
2569     memmove(str + prefix_len, str, str_cur_len + 1);
2570 
2571     /*  Remember the first character, because snprintf will overwrite it with a
2572         null character.
2573     */
2574     char tmp = str[0];
2575 
2576     snprintf(str, prefix_len + 1, prefix_format, prefix);
2577     str[prefix_len] = tmp;
2578     return 0;
2579 }
2580 
stdev_get_properties_extended(const struct sound_trigger_hw_device * dev __unused)2581 static const struct sound_trigger_properties_header* stdev_get_properties_extended(
2582                             const struct sound_trigger_hw_device *dev __unused)
2583 {
2584     struct knowles_sound_trigger_device *stdev =
2585           (struct knowles_sound_trigger_device *)dev;
2586     ALOGV("+%s+", __func__);
2587     pthread_mutex_lock(&stdev->lock);
2588     if (hw_properties.header.version >= SOUND_TRIGGER_DEVICE_API_VERSION_1_3) {
2589         hw_properties.base.version = stdev->hotword_version;
2590 
2591         /* Per GMS requirement new to Android R, the supported_model_arch field
2592            must be the Google hotword firmware version comma separated with the
2593            supported_model_arch platform identifier.
2594         */
2595         int_prefix_str(hw_properties.supported_model_arch, SOUND_TRIGGER_MAX_STRING_LEN,
2596                 hw_properties.base.version, "%u,");
2597         ALOGW("SoundTrigger supported model arch identifier is %s",
2598                 hw_properties.supported_model_arch);
2599     } else {
2600         ALOGE("STHAL Version is %u", hw_properties.header.version);
2601         pthread_mutex_unlock(&stdev->lock);
2602         return NULL;
2603     }
2604 
2605     pthread_mutex_unlock(&stdev->lock);
2606     ALOGV("-%s-", __func__);
2607     return &hw_properties.header;
2608 }
2609 
2610 
stop_recognition(struct knowles_sound_trigger_device * stdev,sound_model_handle_t handle)2611 static int stop_recognition(struct knowles_sound_trigger_device *stdev,
2612                             sound_model_handle_t handle)
2613 {
2614     int status = 0;
2615     struct model_info *model = &stdev->models[handle];
2616 
2617     if (model->config != NULL) {
2618         dereg_hal_event_session(model->config, handle);
2619         free(model->config);
2620         model->config = NULL;
2621     }
2622 
2623     model->recognition_callback = NULL;
2624     model->recognition_cookie = NULL;
2625     if (check_uuid_equality(model->uuid, stdev->chre_model_uuid) ||
2626         check_uuid_equality(model->uuid, stdev->sensor_model_uuid)) {
2627         // This avoids any processing of chre/oslo.
2628         goto exit;
2629     }
2630     if (can_update_recover_list(stdev) == true) {
2631         update_recover_list(stdev, handle, false);
2632         model->is_active = false;
2633         goto exit;
2634     }
2635     if (model->is_active == false) {
2636         ALOGW("%s: the model was disabled already", __func__);
2637         goto exit;
2638     }
2639 
2640     if (stdev->adnc_strm_handle[handle] != 0) {
2641         ALOGD("%s: stop tunnling for index:%d", __func__, handle);
2642         stdev->adnc_strm_close(stdev->adnc_strm_handle[handle]);
2643         stdev->adnc_strm_handle[handle] = 0;
2644         stdev->is_streaming--;
2645         stdev->adnc_strm_last_read[handle] = reset_time;
2646     }
2647 
2648     model->is_active = false;
2649 
2650     tear_package_route(stdev, model->uuid, stdev->is_bargein_route_enabled);
2651 
2652     destroy_package(stdev, model);
2653 
2654 
2655     if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid) ||
2656         (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))) {
2657         if ((stdev->hotword_buffer_enable) &&
2658             !(stdev->current_enable & PLUGIN1_MASK)) {
2659             tear_hotword_buffer_route(stdev->route_hdl,
2660                                     stdev->is_bargein_route_enabled);
2661         }
2662     }
2663 
2664     if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid) ||
2665         (check_uuid_equality(model->uuid, stdev->entity_model_uuid))) {
2666         if ((stdev->music_buffer_enable) &&
2667             !(stdev->current_enable & PLUGIN2_MASK)) {
2668             tear_music_buffer_route(stdev->route_hdl,
2669                                 stdev->is_bargein_route_enabled);
2670         }
2671     }
2672 
2673     setup_buffer(stdev, model, false);
2674 
2675     handle_input_source(stdev, false);
2676 
2677     check_and_destroy_buffer_package(stdev);
2678 
2679 exit:
2680     return status;
2681 }
2682 
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)2683 static int stdev_load_sound_model(const struct sound_trigger_hw_device *dev,
2684                                 struct sound_trigger_sound_model *sound_model,
2685                                 sound_model_callback_t callback,
2686                                 void *cookie,
2687                                 sound_model_handle_t *handle)
2688 {
2689     struct knowles_sound_trigger_device *stdev =
2690         (struct knowles_sound_trigger_device *)dev;
2691     int ret = 0;
2692     int kw_model_sz = 0;
2693     int i = 0;
2694     sound_trigger_uuid_t empty_uuid = {0};
2695     unsigned char *kw_buffer = NULL;
2696 
2697     ALOGD("+%s+", __func__);
2698     pthread_mutex_lock(&stdev->lock);
2699 
2700     ret = check_firmware_ready(stdev);
2701     if (ret != 0)
2702         goto exit;
2703 
2704     if (handle == NULL || sound_model == NULL) {
2705         ALOGE("%s: handle/sound_model is NULL", __func__);
2706         ret = -EINVAL;
2707         goto exit;
2708     }
2709 
2710     if (sound_model->data_size == 0 ||
2711         sound_model->data_offset < sizeof(struct sound_trigger_sound_model)) {
2712         ALOGE("%s: Invalid sound model data", __func__);
2713         ret = -EINVAL;
2714         goto exit;
2715     }
2716 
2717     if (check_uuid_equality(sound_model->vendor_uuid, empty_uuid)) {
2718         ALOGE("%s Invalid vendor uuid", __func__);
2719         ret = -EINVAL;
2720         goto exit;
2721     }
2722 
2723     // When a delayed CHRE/Oslo destroy process is in progress,
2724     // we should not skip the new model and return the existing handle
2725     // which will be destroyed soon.
2726     if ((check_uuid_equality(sound_model->vendor_uuid,
2727                              stdev->chre_model_uuid) &&
2728             stdev->is_chre_destroy_in_prog) ||
2729             (check_uuid_equality(sound_model->vendor_uuid,
2730                                  stdev->sensor_model_uuid) &&
2731             stdev->is_sensor_destroy_in_prog)) {
2732         ALOGD("%s: CHRE/Oslo destroy in progress, skipped handle check.",
2733               __func__);
2734     } else {
2735         i = find_handle_for_uuid(stdev, sound_model->vendor_uuid);
2736         if (i != -1) {
2737             ALOGW("%s: model is existed at index %d", __func__, i);
2738             *handle = i;
2739             goto exit;
2740         }
2741     }
2742 
2743     // Find an empty slot to load the model
2744     i = find_empty_model_slot(stdev);
2745     if (i == -1) {
2746         ALOGE("%s: Can't load model no free slots available", __func__);
2747         ret = -ENOSYS;
2748         goto exit;
2749     }
2750 
2751     kw_buffer = (unsigned char *) sound_model + sound_model->data_offset;
2752     kw_model_sz = sound_model->data_size;
2753     ALOGV("%s: kw_model_sz %d", __func__, kw_model_sz);
2754 
2755     stdev->models[i].data = malloc(kw_model_sz);
2756     if (stdev->models[i].data == NULL) {
2757         stdev->models[i].data_sz = 0;
2758         ALOGE("%s: could not allocate memory for keyword model data",
2759             __func__);
2760         ret = -ENOMEM;
2761         goto exit;
2762     } else {
2763         memcpy(stdev->models[i].data, kw_buffer, kw_model_sz);
2764         stdev->models[i].data_sz = kw_model_sz;
2765     }
2766 
2767     // Send the keyword model to the chip only for hotword and ambient audio
2768     if (check_uuid_equality(sound_model->vendor_uuid,
2769                             stdev->hotword_model_uuid)) {
2770         stdev->models[i].kw_id = OK_GOOGLE_KW_ID;
2771     } else if (check_uuid_equality(sound_model->vendor_uuid,
2772                                 stdev->wakeup_model_uuid)) {
2773         stdev->models[i].kw_id = WAKEUP_KW_ID;
2774     } else if (check_uuid_equality(sound_model->vendor_uuid,
2775                                 stdev->ambient_model_uuid)) {
2776         stdev->models[i].kw_id = AMBIENT_KW_ID;
2777     } else if (check_uuid_equality(sound_model->vendor_uuid,
2778                                 stdev->entity_model_uuid)) {
2779         stdev->models[i].kw_id = ENTITY_KW_ID;
2780     } else if (check_uuid_equality(sound_model->vendor_uuid,
2781                                 stdev->sensor_model_uuid)) {
2782         ret = start_sensor_model(stdev);
2783         if (ret) {
2784             ALOGE("%s: ERROR: Failed to start sensor model", __func__);
2785             goto error;
2786         }
2787         stdev->models[i].kw_id = USELESS_KW_ID;
2788     } else if (check_uuid_equality(sound_model->vendor_uuid,
2789                                 stdev->chre_model_uuid)) {
2790         ret = start_chre_model(stdev, i);
2791         if (ret) {
2792             ALOGE("%s: ERROR: Failed to start chre model", __func__);
2793             goto error;
2794         }
2795         stdev->models[i].kw_id = USELESS_KW_ID;
2796     } else {
2797         ALOGE("%s: ERROR: unknown model uuid", __func__);
2798         ret = -EINVAL;
2799         goto error;
2800     }
2801 
2802     *handle = i;
2803     ALOGV("%s: Loading model handle(%d) type(%d)", __func__,
2804         *handle, sound_model->type);
2805     // This will need to be replaced with UUID once they are fixed
2806     stdev->models[i].model_handle = *handle;
2807     stdev->models[i].type = sound_model->type;
2808     stdev->models[i].uuid = sound_model->vendor_uuid;
2809     stdev->models[i].sound_model_callback = callback;
2810     stdev->models[i].sound_model_cookie = cookie;
2811     stdev->models[i].recognition_callback = NULL;
2812     stdev->models[i].recognition_cookie = NULL;
2813 
2814     stdev->models[i].is_loaded = true;
2815 
2816 error:
2817     if (ret != 0) {
2818         if (stdev->models[i].data) {
2819             free(stdev->models[i].data);
2820             stdev->models[i].data = NULL;
2821             stdev->models[i].data_sz = 0;
2822         }
2823         if (!is_any_model_loaded(stdev) && stdev->is_buffer_package_loaded) {
2824             destroy_buffer_package(stdev->odsp_hdl);
2825             stdev->is_buffer_package_loaded = false;
2826         }
2827     }
2828 
2829 exit:
2830     pthread_mutex_unlock(&stdev->lock);
2831     ALOGD("-%s handle %d-", __func__, *handle);
2832     return ret;
2833 }
2834 
stdev_unload_sound_model(const struct sound_trigger_hw_device * dev,sound_model_handle_t handle)2835 static int stdev_unload_sound_model(const struct sound_trigger_hw_device *dev,
2836                                     sound_model_handle_t handle)
2837 {
2838     struct knowles_sound_trigger_device *stdev =
2839         (struct knowles_sound_trigger_device *)dev;
2840     int ret = 0;
2841     ALOGD("+%s handle %d+", __func__, handle);
2842     pthread_mutex_lock(&stdev->lock);
2843 
2844     ret = check_firmware_ready(stdev);
2845     if (ret != 0)
2846         goto exit;
2847 
2848     // Just confirm the model was previously loaded
2849     if (stdev->models[handle].is_loaded == false) {
2850         ALOGE("%s: Invalid model(%d) being called for unload",
2851                 __func__, handle);
2852         ret = -EINVAL;
2853         goto exit;
2854     }
2855 
2856     if (stdev->models[handle].is_active == true) {
2857         ret = stop_recognition(stdev, handle);
2858         if (ret)
2859             goto exit;
2860     }
2861 
2862     if (check_uuid_equality(stdev->models[handle].uuid,
2863                                 stdev->sensor_model_uuid)) {
2864         // Inform the Host 1 that sensor route/packages are about to be
2865         // torndown and then wait for confirmation from Host 1 that it can be
2866         // torndown. Also start a timer for 5 seconds, if the Host 1 doesn't
2867         // send us the event within 5 seconds we force remove the sensor pkgs
2868         if (stdev->is_sensor_route_enabled == true) {
2869             struct itimerspec ss_timer_spec;
2870             struct sigevent ss_sigevent;
2871 
2872             // Inform the host 1
2873             stdev->is_sensor_destroy_in_prog = true;
2874             trigger_sensor_destroy_event(stdev->odsp_hdl);
2875 
2876             // Start timer for 5 seconds
2877             ss_sigevent.sigev_notify = SIGEV_THREAD;
2878             ss_sigevent.sigev_notify_function = sensor_timeout_recover;
2879             ss_sigevent.sigev_notify_attributes = NULL;
2880 
2881             ss_timer_spec.it_interval.tv_sec = 0;
2882             ss_timer_spec.it_interval.tv_nsec = 0;
2883             ss_timer_spec.it_value.tv_sec =
2884                     SENSOR_CREATE_WAIT_TIME_IN_S * SENSOR_CREATE_WAIT_MAX_COUNT;
2885             ss_timer_spec.it_value.tv_nsec = 0;
2886 
2887             if (stdev->ss_timer_created) {
2888                 timer_delete(stdev->ss_timer);
2889                 stdev->ss_timer_created = false;
2890             }
2891 
2892             if (timer_create(CLOCK_REALTIME,
2893                              &ss_sigevent, &stdev->ss_timer) == -1) {
2894                 ALOGE("%s: Timer Create Failed", __func__);
2895             } else {
2896                 stdev->ss_timer_created = true;
2897                 if (timer_settime(stdev->ss_timer,
2898                                   0, &ss_timer_spec, NULL) == -1) {
2899                     ALOGE("%s: Timer Set Failed", __func__);
2900                 }
2901             }
2902         }
2903     } else if (check_uuid_equality(stdev->models[handle].uuid,
2904                                    stdev->chre_model_uuid)) {
2905         // remove chre from recover list
2906         if (can_update_recover_list(stdev) == true)
2907             update_recover_list(stdev, handle, false);
2908 
2909          // Disable the CHRE route
2910         if (stdev->is_chre_loaded == true) {
2911             struct itimerspec chre_timer_spec;
2912             struct sigevent chre_sigevent;
2913 
2914             // Inform the host 1
2915             stdev->is_chre_destroy_in_prog = true;
2916             trigger_chre_destroy_event(stdev->odsp_hdl);
2917 
2918             // Start timer for 5 seconds
2919             chre_sigevent.sigev_notify = SIGEV_THREAD;
2920             chre_sigevent.sigev_notify_function = chre_timeout_recover;
2921             chre_sigevent.sigev_notify_attributes = NULL;
2922 
2923             chre_timer_spec.it_interval.tv_sec = 0;
2924             chre_timer_spec.it_interval.tv_nsec = 0;
2925             chre_timer_spec.it_value.tv_sec =
2926                     CHRE_CREATE_WAIT_TIME_IN_S * CHRE_CREATE_WAIT_MAX_COUNT;
2927             chre_timer_spec.it_value.tv_nsec = 0;
2928 
2929             if (stdev->chre_timer_created) {
2930                 timer_delete(stdev->chre_timer);
2931                 stdev->chre_timer_created = false;
2932             }
2933 
2934             if (timer_create(CLOCK_REALTIME,
2935                              &chre_sigevent, &stdev->chre_timer) == -1) {
2936                 ALOGE("%s: Timer Create Failed", __func__);
2937             } else {
2938                 stdev->chre_timer_created = true;
2939                 if (timer_settime(stdev->chre_timer,
2940                                   0, &chre_timer_spec, NULL) == -1) {
2941                     ALOGE("%s: Timer Set Failed", __func__);
2942                 }
2943             }
2944         }
2945     }
2946 
2947     stdev->models[handle].sound_model_callback = NULL;
2948     stdev->models[handle].sound_model_cookie = NULL;
2949 
2950     if (!(check_uuid_equality(stdev->models[handle].uuid,
2951                               stdev->sensor_model_uuid) &&
2952             stdev->is_sensor_destroy_in_prog) &&
2953         !(check_uuid_equality(stdev->models[handle].uuid,
2954                               stdev->chre_model_uuid) &&
2955             stdev->is_chre_destroy_in_prog)) {
2956         memset(&stdev->models[handle].uuid, 0, sizeof(sound_trigger_uuid_t));
2957         stdev->models[handle].is_loaded = false;
2958     }
2959 
2960     if (stdev->models[handle].data) {
2961         free(stdev->models[handle].data);
2962         stdev->models[handle].data = NULL;
2963         stdev->models[handle].data_sz = 0;
2964     }
2965 
2966     ALOGD("%s: Successfully unloaded the model, handle - %d",
2967         __func__, handle);
2968 exit:
2969     pthread_mutex_unlock(&stdev->lock);
2970     ALOGD("-%s handle %d-", __func__, handle);
2971     return ret;
2972 }
2973 
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)2974 static int stdev_start_recognition(
2975                         const struct sound_trigger_hw_device *dev,
2976                         sound_model_handle_t handle,
2977                         const struct sound_trigger_recognition_config *config,
2978                         recognition_callback_t callback,
2979                         void *cookie)
2980 {
2981     struct knowles_sound_trigger_device *stdev =
2982         (struct knowles_sound_trigger_device *)dev;
2983     int status = 0;
2984     struct model_info *model = &stdev->models[handle];
2985 
2986     ALOGD("%s stdev %p, sound model %d", __func__, stdev, handle);
2987     pthread_mutex_lock(&stdev->lock);
2988 
2989     status = check_firmware_ready(stdev);
2990     if (status != 0)
2991         goto exit;
2992 
2993     if (callback == NULL) {
2994         ALOGE("%s: recognition_callback is null", __func__);
2995         status = -EINVAL;
2996         goto exit;
2997     }
2998 
2999     if (model->config != NULL) {
3000         dereg_hal_event_session(model->config, handle);
3001         free(model->config);
3002         model->config = NULL;
3003     }
3004 
3005     if (config != NULL) {
3006         model->config = (struct sound_trigger_recognition_config *)
3007                             malloc(sizeof(*config));
3008         if (model->config == NULL) {
3009             ALOGE("%s: Failed to allocate memory for model config", __func__);
3010             status = -ENOMEM;
3011             goto exit;
3012         }
3013 
3014         memcpy(model->config, config, sizeof(*config));
3015         reg_hal_event_session(model->config, handle);
3016 
3017         ALOGD("%s: Is capture requested %d",
3018             __func__, config->capture_requested);
3019     } else {
3020         ALOGD("%s: config is null", __func__);
3021         model->config = NULL;
3022     }
3023 
3024     model->recognition_callback = callback;
3025     model->recognition_cookie = cookie;
3026     if (check_uuid_equality(model->uuid, stdev->chre_model_uuid) ||
3027         check_uuid_equality(model->uuid, stdev->sensor_model_uuid)) {
3028         // This avoids any processing of chre/oslo.
3029         goto exit;
3030     }
3031     if (model->is_active == true) {
3032         // This model is already active, do nothing except updating callbacks,
3033         // configs and cookie
3034         goto exit;
3035     }
3036     if (can_update_recover_list(stdev) == true) {
3037         // Device is in voice/VoIP call, add model to recover list first
3038         // recover model once voice/VoIP is ended.
3039         update_recover_list(stdev, handle, true);
3040         goto exit;
3041     }
3042 
3043     status = check_and_setup_buffer_package(stdev);
3044     if (status != 0) {
3045         ALOGE("%s: ERROR: Failed to load the buffer package", __func__);
3046     }
3047 
3048     model->is_active = true;
3049 
3050     handle_input_source(stdev, true);
3051 
3052     if (stdev->is_buffer_package_loaded == true) {
3053         setup_buffer(stdev, model, true);
3054     }
3055 
3056     if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid) ||
3057         (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))) {
3058         if ((stdev->hotword_buffer_enable) &&
3059             (!(stdev->current_enable & HOTWORD_MASK) ||
3060               (stdev->current_enable & WAKEUP_MASK))) {
3061             set_hotword_buffer_route(stdev->route_hdl,
3062                                     stdev->is_bargein_route_enabled);
3063         }
3064     }
3065 
3066     if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid) ||
3067         (check_uuid_equality(model->uuid, stdev->entity_model_uuid))) {
3068         if ((stdev->music_buffer_enable) &&
3069             (!(stdev->current_enable & AMBIENT_MASK) ||
3070               (stdev->current_enable & ENTITY_MASK))) {
3071             set_music_buffer_route(stdev->route_hdl,
3072                                 stdev->is_bargein_route_enabled);
3073         }
3074     }
3075 
3076     setup_package(stdev, model);
3077 
3078     set_package_route(stdev, model->uuid, stdev->is_bargein_route_enabled);
3079 
3080 exit:
3081     pthread_mutex_unlock(&stdev->lock);
3082     ALOGD("-%s sound model %d-", __func__, handle);
3083     return status;
3084 }
3085 
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)3086 static int stdev_start_recognition_extended(
3087                         const struct sound_trigger_hw_device *dev,
3088                         sound_model_handle_t sound_model_handle,
3089                         const struct sound_trigger_recognition_config_header *header,
3090                         recognition_callback_t callback,
3091                         void *cookie)
3092 {
3093     struct sound_trigger_recognition_config_extended_1_3 *config_1_3 =
3094                  (struct sound_trigger_recognition_config_extended_1_3 *)header;
3095     int status = 0;
3096 
3097     if (header->version >= SOUND_TRIGGER_DEVICE_API_VERSION_1_3) {
3098         /* Use old version before we have real usecase */
3099         ALOGD("%s: Running 2_3", __func__);
3100         status = stdev_start_recognition(dev, sound_model_handle,
3101                                         &config_1_3->base,
3102                                         callback,
3103                                         cookie);
3104     } else {
3105         /* Rollback into old start recognition */
3106         ALOGD("%s: Running 2_1", __func__);
3107         status = stdev_start_recognition(dev, sound_model_handle,
3108                                         &config_1_3->base,
3109                                         callback,
3110                                         cookie);
3111     }
3112 
3113     return status;
3114 }
3115 
3116 
stdev_stop_recognition(const struct sound_trigger_hw_device * dev,sound_model_handle_t handle)3117 static int stdev_stop_recognition(
3118                         const struct sound_trigger_hw_device *dev,
3119                         sound_model_handle_t handle)
3120 {
3121     struct knowles_sound_trigger_device *stdev =
3122         (struct knowles_sound_trigger_device *)dev;
3123     int status = 0;
3124     ALOGD("+%s sound model %d+", __func__, handle);
3125     pthread_mutex_lock(&stdev->lock);
3126 
3127     status = check_firmware_ready(stdev);
3128     if (status != 0)
3129         goto exit;
3130 
3131     status = stop_recognition(stdev, handle);
3132 
3133     if (status != 0)
3134         goto exit;
3135 
3136     ALOGD("-%s sound model %d-", __func__, handle);
3137 exit:
3138     pthread_mutex_unlock(&stdev->lock);
3139 
3140     return status;
3141 }
3142 
3143 /**
3144  * Get the state of a given model.
3145  * The model state is returned asynchronously as a RecognitionEvent via
3146  * the callback that was registered in StartRecognition().
3147  * @param modelHandle The handle of the sound model whose state is being
3148  *                    queried.
3149  * @return retval Operation completion status: 0 in case of success,
3150  *                -ENOSYS in case of invalid model handle,
3151  *                -ENOMEM in case of memory allocation failure,
3152  *                -ENODEV in case of initialization error,
3153  *                -EINVAL in case where a recognition event is already
3154  *                        being processed.
3155  */
stdev_get_model_state(const struct sound_trigger_hw_device * dev,sound_model_handle_t sound_model_handle)3156 static int stdev_get_model_state(const struct sound_trigger_hw_device *dev,
3157                                sound_model_handle_t sound_model_handle) {
3158     struct knowles_sound_trigger_device *stdev =
3159         (struct knowles_sound_trigger_device *)dev;
3160     struct model_info *model = &stdev->models[sound_model_handle];
3161     int ret = 0;
3162     ALOGD("+%s+", __func__);
3163     pthread_mutex_lock(&stdev->lock);
3164 
3165     ret = check_firmware_ready(stdev);
3166     if (ret != 0)
3167         goto exit;
3168 
3169     if (!stdev->opened) {
3170         ALOGE("%s: stdev isn't initialized", __func__);
3171         ret = -ENODEV;
3172         goto exit;
3173     }
3174 
3175     if (model->is_active == false &&
3176         !is_uuid_in_recover_list(stdev, sound_model_handle)) {
3177         ALOGE("%s: ERROR: %d model is not active",
3178             __func__, sound_model_handle);
3179         ret = -ENOSYS;
3180         goto exit;
3181     } else if (is_uuid_in_recover_list(stdev, sound_model_handle)) {
3182         ALOGD("%s: Ignore %d model request due to call active",
3183             __func__, sound_model_handle);
3184         goto exit;
3185     }
3186 
3187     if (model->is_state_query == true) {
3188         ALOGE("%s: ERROR: model %d is already processing",
3189             __func__, sound_model_handle);
3190         ret = -EINVAL;
3191         goto exit;
3192     }
3193 
3194     model->is_state_query = true;
3195 
3196     if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid))
3197         ret = get_model_state(stdev->odsp_hdl, HOTWORD_INSTANCE_ID,
3198                             HOTWORD_SLOT_ID);
3199     else if (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))
3200         ret = get_model_state(stdev->odsp_hdl, HOTWORD_INSTANCE_ID,
3201                             WAKEUP_SLOT_ID);
3202     else if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid))
3203         ret = get_model_state(stdev->odsp_hdl, AMBIENT_INSTANCE_ID,
3204                             AMBIENT_SLOT_ID);
3205     else if (check_uuid_equality(model->uuid, stdev->entity_model_uuid)) {
3206         ret = get_model_state(stdev->odsp_hdl, AMBIENT_INSTANCE_ID,
3207                             ENTITY_SLOT_ID);
3208     } else {
3209         ALOGE("%s: ERROR: %d model is not supported",
3210             __func__, sound_model_handle);
3211         ret = -ENOSYS;
3212     }
3213 
3214     if (ret != 0) {
3215         model->is_state_query = false;
3216         ALOGE("%s: ERROR: Failed to get the model state", __func__);
3217     }
3218 
3219 exit:
3220     pthread_mutex_unlock(&stdev->lock);
3221     ALOGD("-%s-", __func__);
3222     return ret;
3223 }
3224 
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)3225 static int stdev_query_parameter(
3226                     const struct sound_trigger_hw_device *dev __unused,
3227                     sound_model_handle_t sound_model_handle __unused,
3228                     sound_trigger_model_parameter_t model_param __unused,
3229                     sound_trigger_model_parameter_range_t* param_range)
3230 {
3231     ALOGW("%s: NOT SUPPORTED", __func__);
3232     param_range->is_supported = false;
3233     return 0;
3234 }
3235 
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)3236 static int stdev_set_parameter(
3237                            const struct sound_trigger_hw_device *dev __unused,
3238                            sound_model_handle_t sound_model_handle __unused,
3239                            sound_trigger_model_parameter_t model_param __unused,
3240                            int32_t value __unused)
3241 {
3242     ALOGW("%s: NOT SUPPORTED", __func__);
3243     return -EINVAL;
3244 }
3245 
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)3246 static int stdev_get_parameter(
3247                            const struct sound_trigger_hw_device *dev __unused,
3248                            sound_model_handle_t sound_model_handle __unused,
3249                            sound_trigger_model_parameter_t model_param __unused,
3250                            int32_t* value __unused)
3251 {
3252     ALOGW("%s: NOT SUPPORTED", __func__);
3253     return -EINVAL;
3254 }
3255 
3256 
stdev_close(hw_device_t * device)3257 static int stdev_close(hw_device_t *device)
3258 {
3259     struct knowles_sound_trigger_device *stdev =
3260         (struct knowles_sound_trigger_device *)device;
3261     int ret = 0;
3262     ALOGD("+%s+", __func__);
3263     pthread_mutex_lock(&stdev->lock);
3264 
3265     ret = check_firmware_ready(stdev);
3266     if (ret != 0)
3267         goto exit;
3268 
3269     if (!stdev->opened) {
3270         ALOGE("%s: device already closed", __func__);
3271         ret = -EFAULT;
3272         goto exit;
3273     }
3274 
3275     setup_slpi_wakeup_event(stdev->odsp_hdl, false);
3276 
3277     stdev->opened = false;
3278 
3279     if (stdev->send_sock >= 0)
3280         write(stdev->send_sock, "T", 1);
3281     pthread_join(stdev->callback_thread, (void **)NULL);
3282 
3283     if (stdev->route_hdl)
3284         audio_route_free(stdev->route_hdl);
3285     if (stdev->odsp_hdl)
3286         iaxxx_odsp_deinit(stdev->odsp_hdl);
3287 
3288     if (stdev->ss_timer_created) {
3289         timer_delete(stdev->ss_timer);
3290         stdev->ss_timer_created = false;
3291     }
3292 
3293 exit:
3294     pthread_mutex_unlock(&stdev->lock);
3295     ALOGD("-%s-", __func__);
3296     return ret;
3297 }
3298 
open_streaming_lib(struct knowles_sound_trigger_device * stdev)3299 static int open_streaming_lib(struct knowles_sound_trigger_device *stdev) {
3300     int ret = 0;
3301 
3302     if (access(ADNC_STRM_LIBRARY_PATH, R_OK) == 0) {
3303         stdev->adnc_cvq_strm_lib = dlopen(ADNC_STRM_LIBRARY_PATH, RTLD_NOW);
3304         if (stdev->adnc_cvq_strm_lib == NULL) {
3305             char const *err_str = dlerror();
3306             ALOGE("%s: module = %s error = %s", __func__,
3307                 ADNC_STRM_LIBRARY_PATH, err_str ? err_str : "unknown");
3308             ALOGE("%s: DLOPEN failed for %s", __func__, ADNC_STRM_LIBRARY_PATH);
3309         } else {
3310             ALOGV("%s: DLOPEN successful for %s",
3311                 __func__, ADNC_STRM_LIBRARY_PATH);
3312             for (int index = 0; index < MAX_MODELS; index++) {
3313                 stdev->adnc_strm_handle[index] = 0;
3314                 stdev->adnc_strm_last_read[index] = reset_time;
3315             }
3316             stdev->adnc_strm_open =
3317                 (int (*)(bool, int, int))dlsym(stdev->adnc_cvq_strm_lib,
3318                 "adnc_strm_open");
3319             stdev->adnc_strm_read =
3320                (size_t (*)(long, void *, size_t))dlsym(stdev->adnc_cvq_strm_lib,
3321                 "adnc_strm_read");
3322             stdev->adnc_strm_close =
3323                 (int (*)(long))dlsym(stdev->adnc_cvq_strm_lib,
3324                 "adnc_strm_close");
3325             if (!stdev->adnc_strm_open || !stdev->adnc_strm_read ||
3326                 !stdev->adnc_strm_close) {
3327                 ALOGE("%s: Error grabbing functions in %s", __func__,
3328                     ADNC_STRM_LIBRARY_PATH);
3329                 stdev->adnc_strm_open = 0;
3330                 stdev->adnc_strm_read = 0;
3331                 stdev->adnc_strm_close = 0;
3332             }
3333         }
3334     }
3335 
3336     return ret;
3337 }
3338 
find_stdev_mixer_path(int card_num,char * mixer_path_xml)3339 static struct mixer* find_stdev_mixer_path(int card_num, char *mixer_path_xml)
3340 {
3341     struct mixer *mixer = NULL;
3342     const char *in_snd_card_name;
3343     char *snd_card_name = NULL;
3344     char *tmp = NULL;
3345     char *platform = NULL;
3346     char *snd_card = NULL;
3347     char *device = NULL;
3348 
3349     mixer = mixer_open(card_num);
3350 
3351     if (!mixer) {
3352         ALOGE("%s: Unable to open the mixer: %d", __func__,
3353             card_num);
3354         return NULL;
3355     }
3356 
3357     in_snd_card_name = mixer_get_name(mixer);
3358     snd_card_name = strdup(in_snd_card_name);
3359 
3360     if (snd_card_name == NULL) {
3361         ALOGE("%s: snd_card_name is NULL", __func__);
3362         goto on_error;
3363     }
3364 
3365     platform = strtok_r(snd_card_name, "-", &tmp);
3366     if (platform == NULL) {
3367         ALOGE("%s: snd card is invalid", __func__);
3368         goto on_error;
3369     }
3370 
3371     snd_card = strtok_r(NULL, "-", &tmp);
3372     if (snd_card == NULL) {
3373         ALOGE("%s: snd card is invalid", __func__);
3374         goto on_error;
3375     }
3376 
3377     device = strtok_r(NULL, "-", &tmp);
3378     if (device != NULL) {
3379         snprintf(mixer_path_xml, NAME_MAX_SIZE, "%s_%s.xml",
3380                 SOUND_TRIGGER_MIXER_PATH_BASE, device);
3381     } else {
3382         ALOGE("%s: Unknown device, try to use default xml", __func__);
3383         snprintf(mixer_path_xml, NAME_MAX_SIZE, "%s",
3384                 SOUND_TRIGGER_MIXER_PATH_XML);
3385     }
3386 
3387     ALOGD("%s: using %s", __func__, mixer_path_xml);
3388 
3389 on_error:
3390     if (snd_card_name)
3391         free(snd_card_name);
3392     return mixer;
3393 }
3394 
find_sound_card()3395 static int find_sound_card() {
3396     int retry_num = 0, snd_card_num = 0, ret = -1;
3397     const char *snd_card_name;
3398     struct mixer *mixer = NULL;
3399     bool card_verifed[MAX_SND_CARD] = {false};
3400     const int retry_limit = property_get_int32("vendor.audio.snd_card.open.retries",
3401                                             RETRY_NUMBER);
3402     ALOGD("+%s+", __func__);
3403 
3404     for (;;) {
3405         if (snd_card_num >= MAX_SND_CARD) {
3406             if (retry_num++ >= retry_limit) {
3407                 ALOGE("%s: iaxxx sound card not found", __func__);
3408                 goto exit;
3409             }
3410             snd_card_num = 0;
3411             usleep(RETRY_US);
3412             continue;
3413         }
3414         if (card_verifed[snd_card_num]) {
3415             snd_card_num++;
3416             continue;
3417         }
3418 
3419         mixer = mixer_open(snd_card_num);
3420         if (!mixer) {
3421             snd_card_num++;
3422             continue;
3423         }
3424 
3425         snd_card_name = mixer_get_name(mixer);
3426         if (strstr(snd_card_name, CARD_NAME)) {
3427             ALOGD("%s: find card %d has iaxxx - %s",
3428                 __func__, snd_card_num, snd_card_name);
3429             ret = snd_card_num;
3430             break;
3431         }
3432 
3433         ALOGD("%s: sound card %s does NOT have iaxxx", __func__, snd_card_name);
3434         mixer_close(mixer);
3435         mixer = NULL;
3436         card_verifed[snd_card_num] = true;
3437         snd_card_num++;
3438     }
3439 
3440 exit:
3441     if (mixer)
3442         mixer_close(mixer);
3443 
3444     ALOGD("-%s-", __func__);
3445     return ret;
3446 }
3447 
load_audio_hal()3448 static int load_audio_hal()
3449 {
3450     char audio_hal_lib[100];
3451     void *sthal_prop_api_version = NULL;
3452     struct knowles_sound_trigger_device *stdev = &g_stdev;
3453     int ret = 0;
3454 
3455     snprintf(audio_hal_lib, sizeof(audio_hal_lib), "%s/%s.%s.so",
3456             AUDIO_HAL_LIBRARY_PATH, AUDIO_HAL_NAME_PREFIX,
3457             SOUND_TRIGGER_PLATFORM);
3458     if (access(audio_hal_lib, R_OK)) {
3459         ALOGE("%s: ERROR. %s not found", __func__, audio_hal_lib);
3460         return -ENOENT;
3461     }
3462 
3463     stdev->audio_hal_handle = dlopen(audio_hal_lib, RTLD_NOW);
3464     if (stdev->audio_hal_handle == NULL) {
3465         ALOGE("%s: ERROR. %s", __func__, dlerror());
3466         return -ENODEV;
3467     }
3468 
3469     stdev->audio_hal_cb = dlsym(stdev->audio_hal_handle, "audio_hw_call_back");
3470     if (stdev->audio_hal_cb == NULL) {
3471         ALOGE("%s: ERROR. %s", __func__, dlerror());
3472         ret = -ENODEV;
3473         goto error;
3474     }
3475 
3476     sthal_prop_api_version = dlsym(stdev->audio_hal_handle,
3477                                 "sthal_prop_api_version");
3478     if (sthal_prop_api_version == NULL) {
3479         stdev->sthal_prop_api_version = 0;
3480         ret = 0; /* passthru for backward compability */
3481     } else {
3482         stdev->sthal_prop_api_version = *(int *)sthal_prop_api_version;
3483         if (MAJOR_VERSION(stdev->sthal_prop_api_version) !=
3484             MAJOR_VERSION(STHAL_PROP_API_CURRENT_VERSION)) {
3485             ALOGE("%s: Incompatible API versions sthal:0x%x != ahal:0x%x",
3486                 __func__, STHAL_PROP_API_CURRENT_VERSION,
3487                 stdev->sthal_prop_api_version);
3488             goto error;
3489         }
3490         ALOGD("%s: ahal is using proprietary API version 0x%04x", __func__,
3491             stdev->sthal_prop_api_version);
3492     }
3493 
3494     ALOGD("%s: load AHAL successfully.", __func__);
3495     return ret;
3496 
3497 error:
3498     dlclose(stdev->audio_hal_handle);
3499     stdev->audio_hal_handle = NULL;
3500     return ret;
3501 }
3502 
stdev_open(const hw_module_t * module,const char * name,hw_device_t ** device)3503 static int stdev_open(const hw_module_t *module, const char *name,
3504         hw_device_t **device)
3505 {
3506     struct knowles_sound_trigger_device *stdev;
3507     int ret = 0, i = 0;
3508     int snd_card_num = 0;
3509 
3510     ALOGE("!! Knowles SoundTrigger v1!!");
3511 
3512     if (strcmp(name, SOUND_TRIGGER_HARDWARE_INTERFACE) != 0)
3513         return -EINVAL;
3514 
3515     if (device == NULL)
3516         return -EINVAL;
3517 
3518     stdev = &g_stdev;
3519     pthread_mutex_lock(&stdev->lock);
3520 
3521     snd_card_num = find_sound_card();
3522     if (snd_card_num == -1) {
3523         ALOGE("%s: Unable to find the sound card %s", __func__, CARD_NAME);
3524         ret = -EAGAIN;
3525         goto exit;
3526     }
3527 
3528     if (stdev->opened) {
3529         ALOGE("%s: Only one sountrigger can be opened at a time", __func__);
3530         ret = -EBUSY;
3531         goto exit;
3532     }
3533 
3534     ret = open_streaming_lib(stdev);
3535     if (ret != 0) {
3536         ALOGE("%s: Couldnot open the streaming library", __func__);
3537         goto error;
3538     }
3539 
3540     ret = load_audio_hal();
3541     if (ret != 0) {
3542         ALOGE("%s: Couldn't load AHAL", __func__);
3543         goto error;
3544     }
3545 
3546     stdev->device.common.tag = HARDWARE_DEVICE_TAG;
3547     stdev->device.common.version = SOUND_TRIGGER_DEVICE_API_VERSION_1_3;
3548     stdev->device.common.module = (struct hw_module_t *)module;
3549     stdev->device.common.close = stdev_close;
3550     stdev->device.get_properties = stdev_get_properties;
3551     stdev->device.load_sound_model = stdev_load_sound_model;
3552     stdev->device.unload_sound_model = stdev_unload_sound_model;
3553     stdev->device.start_recognition = stdev_start_recognition;
3554     stdev->device.start_recognition_extended = stdev_start_recognition_extended;
3555     stdev->device.stop_recognition = stdev_stop_recognition;
3556     stdev->device.get_model_state = stdev_get_model_state;
3557     stdev->device.query_parameter = stdev_query_parameter;
3558     stdev->device.set_parameter = stdev_set_parameter;
3559     stdev->device.get_parameter = stdev_get_parameter;
3560     stdev->device.get_properties_extended = stdev_get_properties_extended;
3561 
3562     stdev->opened = true;
3563     stdev->send_sock = -1;
3564     stdev->recv_sock = -1;
3565 
3566     /* Initialize all member variable */
3567     for (i = 0; i < MAX_MODELS; i++) {
3568         stdev->models[i].type = SOUND_MODEL_TYPE_UNKNOWN;
3569         memset(&stdev->models[i].uuid, 0, sizeof(sound_trigger_uuid_t));
3570         stdev->models[i].config = NULL;
3571         stdev->models[i].data = NULL;
3572         stdev->models[i].data_sz = 0;
3573         stdev->models[i].is_loaded = false;
3574         stdev->models[i].is_active = false;
3575         stdev->models[i].is_state_query = false;
3576     }
3577 
3578     stdev->is_mic_route_enabled = false;
3579     stdev->is_con_mic_route_enabled = false;
3580     stdev->is_ahal_in_voice_voip_mode = false;
3581     stdev->is_ahal_voice_voip_stop = false;
3582     stdev->is_ahal_voice_voip_start = false;
3583     stdev->is_bargein_route_enabled = false;
3584     stdev->is_chre_loaded = false;
3585     stdev->is_buffer_package_loaded = false;
3586     stdev->hotword_buffer_enable = 0;
3587     stdev->music_buffer_enable = 0;
3588     stdev->current_enable = 0;
3589     stdev->is_sensor_route_enabled = false;
3590     stdev->recover_model_list = 0;
3591     stdev->rx_active_count = 0;
3592     stdev->is_ahal_media_recording = false;
3593     stdev->is_concurrent_capture = hw_properties.base.concurrent_capture;
3594 
3595     stdev->is_sensor_destroy_in_prog = false;
3596     stdev->ss_timer_created = false;
3597 
3598     stdev->is_chre_destroy_in_prog = false;
3599     stdev->chre_timer_created = false;
3600 
3601     stdev->snd_crd_num = snd_card_num;
3602     stdev->fw_reset_done_by_hal = false;
3603     stdev->hotword_version = 0;
3604 
3605     str_to_uuid(HOTWORD_AUDIO_MODEL, &stdev->hotword_model_uuid);
3606     str_to_uuid(WAKEUP_MODEL, &stdev->wakeup_model_uuid);
3607     str_to_uuid(SENSOR_MANAGER_MODEL, &stdev->sensor_model_uuid);
3608     str_to_uuid(AMBIENT_AUDIO_MODEL, &stdev->ambient_model_uuid);
3609     str_to_uuid(CHRE_AUDIO_MODEL, &stdev->chre_model_uuid);
3610     str_to_uuid(ENTITY_AUDIO_MODEL, &stdev->entity_model_uuid);
3611 
3612     stdev->odsp_hdl = iaxxx_odsp_init();
3613     if (stdev->odsp_hdl == NULL) {
3614         ALOGE("%s: Failed to get handle to ODSP HAL", __func__);
3615         ret = -EIO;
3616         goto error;
3617     }
3618     stdev->mixer = find_stdev_mixer_path(stdev->snd_crd_num, stdev->mixer_path_xml);
3619     if (stdev->mixer == NULL) {
3620         ALOGE("Failed to init the mixer");
3621         ret = -EAGAIN;
3622         goto error;
3623     }
3624 
3625     ALOGD("stdev before pthread_create %p", stdev);
3626     // Create a thread to handle all events from kernel
3627     pthread_create(&stdev->callback_thread, (const pthread_attr_t *) NULL,
3628                 callback_thread_loop, stdev);
3629 
3630     pthread_create(&stdev->monitor_thread, (const pthread_attr_t *) NULL,
3631                 monitor_thread_loop, stdev);
3632 
3633     pthread_create(&stdev->transitions_thread, (const pthread_attr_t *) NULL,
3634                 transitions_thread_loop, stdev);
3635 
3636     *device = &stdev->device.common; /* same address as stdev */
3637 exit:
3638     pthread_mutex_unlock(&stdev->lock);
3639     return ret;
3640 
3641 error:
3642     if (stdev->adnc_cvq_strm_lib)
3643         dlclose(stdev->adnc_cvq_strm_lib);
3644     if (stdev->audio_hal_handle)
3645         dlclose(stdev->audio_hal_handle);
3646     if (stdev->route_hdl)
3647         audio_route_free(stdev->route_hdl);
3648     if (stdev->odsp_hdl)
3649         iaxxx_odsp_deinit(stdev->odsp_hdl);
3650     if (stdev->mixer)
3651         mixer_close(stdev->mixer);
3652 
3653     pthread_mutex_unlock(&stdev->lock);
3654     return ret;
3655 }
3656 
3657 /* AHAL calls this callback to communicate with STHAL */
sound_trigger_hw_call_back(audio_event_type_t event,struct audio_event_info * config)3658 int sound_trigger_hw_call_back(audio_event_type_t event,
3659                             struct audio_event_info *config)
3660 {
3661     int ret = 0;
3662     int i = 0;
3663     int index = -1;
3664     struct knowles_sound_trigger_device *stdev = &g_stdev;
3665     enum sthal_mode pre_mode, cur_mode;
3666 
3667     if (!stdev)
3668         return -ENODEV;
3669 
3670     if (!stdev->opened) {
3671         ALOGE("%s: Error SoundTrigger has not been opened", __func__);
3672         return -EINVAL;
3673     }
3674 
3675     pthread_mutex_lock(&stdev->lock);
3676 
3677     // update conditions for mic concurrency whatever firmware status may be.
3678     if (event == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE ||
3679         event == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE ||
3680         event == AUDIO_EVENT_CAPTURE_STREAM_INACTIVE ||
3681         event == AUDIO_EVENT_CAPTURE_STREAM_ACTIVE) {
3682         pre_mode = get_sthal_mode(stdev);
3683         update_sthal_conditions(stdev, event, config);
3684         cur_mode = get_sthal_mode(stdev);
3685     }
3686 
3687     // update conditions for bargein whatever firmware status may be.
3688     if (event == AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE ||
3689         event == AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE) {
3690         update_rx_conditions(stdev, event, config);
3691     }
3692 
3693     if (stdev->is_st_hal_ready == false) {
3694         ALOGE("%s: ST HAL is not ready yet", __func__);
3695         ret = -EINVAL;
3696         goto exit;
3697     }
3698 
3699     switch (event) {
3700     case AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE:
3701     case AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE:
3702         ALOGD("%s: handle capture device event %d", __func__, event);
3703 
3704         //handle capture device on/off event
3705         do_handle_functions(stdev, pre_mode, cur_mode, event);
3706 
3707         break;
3708     case AUDIO_EVENT_CAPTURE_STREAM_INACTIVE:
3709     case AUDIO_EVENT_CAPTURE_STREAM_ACTIVE:
3710         ALOGD("%s: handle capture stream event %d, usecase %d",
3711               __func__, event, config->u.usecase.type);
3712 
3713         break;
3714     case AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE:
3715         ALOGD("%s: handle playback stream inactive", __func__);
3716 
3717         if (stdev->rx_active_count == 0) {
3718             if (stdev->is_mic_route_enabled != false) {
3719                 // Atleast one keyword model is active so update the routes
3720                 // Check if the bargein route is enabled if not enable bargein route
3721                 // Check each model, if it is active then update it's route
3722                 if (stdev->is_bargein_route_enabled != false) {
3723                     ALOGD("Bargein disabling");
3724                     stdev->is_bargein_route_enabled = false;
3725                     // Check each model, if it is active then update it's route
3726                     // Disable the bargein route
3727                     for (i = 0; i < MAX_MODELS; i++) {
3728                         if (stdev->models[i].is_active == true) {
3729                             // teardown the package route with bargein
3730                             ret = tear_package_route(stdev,
3731                                                     stdev->models[i].uuid,
3732                                                     !stdev->is_bargein_route_enabled);
3733                             if (ret != 0) {
3734                                 ALOGE("Failed to tear old package route");
3735                             }
3736                             // resetup the package route with out bargein
3737                             ret = set_package_route(stdev,
3738                                                     stdev->models[i].uuid,
3739                                                     stdev->is_bargein_route_enabled);
3740                             if (ret != 0) {
3741                                 ALOGE("Failed to enable package route");
3742                             }
3743                         }
3744                     }
3745 
3746                     //Switch buffer input source
3747                     if (stdev->hotword_buffer_enable) {
3748                         ret = tear_hotword_buffer_route(stdev->route_hdl,
3749                                             !stdev->is_bargein_route_enabled);
3750                         if (ret != 0) {
3751                             ALOGE("Failed to tear old buffer route");
3752                         }
3753                         ret = set_hotword_buffer_route(stdev->route_hdl,
3754                                             stdev->is_bargein_route_enabled);
3755                         if (ret != 0) {
3756                             ALOGE("Failed to enable buffer route");
3757                         }
3758                     }
3759 
3760                     if (stdev->music_buffer_enable) {
3761                         ret = tear_music_buffer_route(stdev->route_hdl,
3762                                             !stdev->is_bargein_route_enabled);
3763                         if (ret != 0) {
3764                             ALOGE("Failed to tear old music buffer route");
3765                         }
3766                         ret = set_music_buffer_route(stdev->route_hdl,
3767                                             stdev->is_bargein_route_enabled);
3768                         if (ret != 0) {
3769                             ALOGE("Failed to enable buffer route");
3770                         }
3771                     }
3772 
3773                     ret = enable_bargein_route(stdev->route_hdl, false);
3774                     if (ret != 0) {
3775                         ALOGE("Failed to enable buffer route");
3776                     }
3777 
3778                     ret = destroy_aec_package(stdev->odsp_hdl);
3779                     if (ret != 0) {
3780                         ALOGE("Failed to destroy AEC package");
3781                     }
3782 
3783                     ret = enable_src_route(stdev->route_hdl, false, SRC_AMP_REF);
3784                     if (ret != 0) {
3785                         ALOGE("Failed to disable SRC-amp route");
3786                     }
3787 
3788                     ret = destroy_src_plugin(stdev->odsp_hdl, SRC_AMP_REF);
3789                     if (ret != 0) {
3790                         ALOGE("Failed to destroy SRC-amp package");
3791                     }
3792 
3793                     if (is_mic_controlled_by_ahal(stdev) == false) {
3794                         ret = enable_amp_ref_route(stdev->route_hdl, false, STRM_16K);
3795                         if (ret != 0) {
3796                             ALOGE("Failed to disable amp-ref route");
3797                         }
3798                         ret = enable_mic_route(stdev->route_hdl, false,
3799                                             EXTERNAL_OSCILLATOR);
3800                         if (ret != 0) {
3801                             ALOGE("Failed to disable mic route with INT OSC");
3802                         }
3803                         ret = enable_mic_route(stdev->route_hdl, true,
3804                                             INTERNAL_OSCILLATOR);
3805                         if (ret != 0) {
3806                             ALOGE("Failed to enable mic route with EXT OSC");
3807                         }
3808                     } else {
3809                         // main mic is turned by media record, close it by 48khz
3810                         ret = enable_amp_ref_route(stdev->route_hdl, false, STRM_48K);
3811                         if (ret != 0) {
3812                             ALOGE("Failed to disable amp-ref route");
3813                         }
3814                     }
3815                 } else {
3816                     ALOGW("%s: barge-in isn't enabled", __func__);
3817                 }
3818             }
3819         } else {
3820             ALOGD("%s: rx stream is still active", __func__);
3821         }
3822         break;
3823     case AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE:
3824         ALOGD("%s: handle playback stream active", __func__);
3825 
3826         if (stdev->rx_active_count > 0) {
3827             if (stdev->is_mic_route_enabled != false) {
3828                 // Atleast one keyword model is active so update the routes
3829                 // Check if the bargein route is enabled if not enable bargein route
3830                 // Check each model, if it is active then update it's route
3831                 stdev->transit_case = TRANSIT_SETUP_AEC;
3832                 pthread_cond_signal(&stdev->transition_cond);
3833             }
3834         } else {
3835             ALOGW("%s: unexpeted stream active event", __func__);
3836         }
3837         break;
3838     case AUDIO_EVENT_STOP_LAB:
3839         /* Close Stream Driver */
3840         for (i = 0; i < MAX_MODELS; i++) {
3841             if (stdev->models[i].is_active &&
3842                 stdev->models[i].config &&
3843                 (stdev->models[i].config->capture_handle ==
3844                  config->u.ses_info.capture_handle)) {
3845                 index = i;
3846                 break;
3847             }
3848         }
3849 
3850         /*
3851          * Close unused adnc if ...
3852          * 1. No capture handle is found
3853          * 2. Model is inactive
3854          * 3. adnc stream handle is existed
3855          */
3856         if (index == -1 && stdev->is_streaming > 0) {
3857             ALOGD("%s: close unused adnc handle, cap_handle:%d", __func__,
3858                   config->u.ses_info.capture_handle);
3859             for (i = 0; i < MAX_MODELS; i++) {
3860                 if (stdev->adnc_strm_handle[i] != 0 &&
3861                     !stdev->models[i].is_active) {
3862                     stdev->adnc_strm_close(stdev->adnc_strm_handle[i]);
3863                     stdev->adnc_strm_handle[i] = 0;
3864                     stdev->is_streaming--;
3865                     stdev->adnc_strm_last_read[i] = reset_time;
3866                 }
3867             }
3868             goto exit;
3869         }
3870 
3871         ALOGD("%s: close streaming %d, cap_handle:%d, index:%d",
3872               __func__, event, config->u.ses_info.capture_handle, index);
3873         if (index != -1 && stdev->adnc_strm_handle[index] != 0) {
3874             stdev->adnc_strm_close(stdev->adnc_strm_handle[index]);
3875             stdev->adnc_strm_handle[index] = 0;
3876             stdev->is_streaming--;
3877             stdev->adnc_strm_last_read[index] = reset_time;
3878         }
3879 
3880         break;
3881 
3882     case AUDIO_EVENT_SSR:
3883         /*[TODO] Do we need to handle adsp SSR event ? */
3884         ALOGD("%s: handle audio subsystem restart %d", __func__, event);
3885         break;
3886 
3887     case AUDIO_EVENT_READ_SAMPLES:
3888         /* It is possible to change session info, check config */
3889         if (config->u.aud_info.ses_info == NULL) {
3890             ALOGE("%s: Invalid config, event:%d", __func__, event);
3891             ret = -EINVAL;
3892             goto exit;
3893         }
3894 
3895         for (i = 0; i < MAX_MODELS; i++) {
3896             if (stdev->models[i].is_active &&
3897                 stdev->models[i].config &&
3898                 (stdev->models[i].config->capture_handle ==
3899                  config->u.aud_info.ses_info->capture_handle)) {
3900                 index = i;
3901                 break;
3902             }
3903         }
3904 
3905         /* There is not valid model to provide pcm samples. */
3906         if (i == MAX_MODELS) {
3907             ret = -EINVAL;
3908             goto exit;
3909         }
3910 
3911         /* Open Stream Driver */
3912         if (index != -1 && stdev->adnc_strm_handle[index] == 0) {
3913             if (stdev->adnc_strm_open == NULL) {
3914                 ALOGE("%s: Error adnc streaming not supported", __func__);
3915             } else {
3916                 bool keyword_stripping_enabled = false;
3917                 int stream_end_point;
3918                 if (check_uuid_equality(stdev->models[index].uuid,
3919                                         stdev->hotword_model_uuid)) {
3920                     stream_end_point = CVQ_ENDPOINT;
3921                 } else if (check_uuid_equality(stdev->models[index].uuid,
3922                                         stdev->ambient_model_uuid)) {
3923                     stream_end_point = MUSIC_BUF_ENDPOINT;
3924                 } else if (check_uuid_equality(stdev->models[index].uuid,
3925                                         stdev->entity_model_uuid)) {
3926                     stream_end_point = MUSIC_BUF_ENDPOINT;
3927                 } else {
3928                     stream_end_point = CVQ_ENDPOINT;
3929                 }
3930                 stdev->adnc_strm_handle[index] = stdev->adnc_strm_open(
3931                                             keyword_stripping_enabled, 0,
3932                                             stream_end_point);
3933                 if (stdev->adnc_strm_handle[index]) {
3934                     ALOGD("Opened adnc index %d handle %d endpoint 0x%x",
3935                           index, config->u.aud_info.ses_info->capture_handle,
3936                           stream_end_point);
3937                     stdev->is_streaming++;
3938 
3939                     clock_gettime(CLOCK_REALTIME, &stdev->adnc_strm_last_read[index]);
3940                     if (stdev->is_streaming == 1)
3941                         pthread_cond_signal(&stdev->tunnel_create);
3942                 } else {
3943                     ALOGE("%s: DSP is currently not streaming", __func__);
3944                 }
3945             }
3946         }
3947 
3948         if (index != -1 && stdev->adnc_strm_handle[index] != 0) {
3949             //ALOGD("%s: soundtrigger HAL adnc_strm_read", __func__);
3950             clock_gettime(CLOCK_REALTIME, &stdev->adnc_strm_last_read[index]);
3951             pthread_mutex_unlock(&stdev->lock);
3952             stdev->adnc_strm_read(stdev->adnc_strm_handle[index],
3953                                 config->u.aud_info.buf,
3954                                 config->u.aud_info.num_bytes);
3955             pthread_mutex_lock(&stdev->lock);
3956         } else {
3957             ALOGE("%s: soundtrigger is not streaming", __func__);
3958         }
3959 
3960         break;
3961 
3962     case AUDIO_EVENT_NUM_ST_SESSIONS:
3963     case AUDIO_EVENT_DEVICE_CONNECT:
3964     case AUDIO_EVENT_DEVICE_DISCONNECT:
3965     case AUDIO_EVENT_SVA_EXEC_MODE:
3966     case AUDIO_EVENT_SVA_EXEC_MODE_STATUS:
3967         ALOGV("%s: useless event %d", __func__, event);
3968         break;
3969 
3970     default:
3971         ALOGW("%s: Unknown event %d", __func__, event);
3972         break;
3973     }
3974 
3975 exit:
3976     pthread_mutex_unlock(&stdev->lock);
3977     return ret;
3978 }
3979 
3980 static struct hw_module_methods_t hal_module_methods = {
3981     .open = stdev_open,
3982 };
3983 
3984 struct sound_trigger_module HAL_MODULE_INFO_SYM = {
3985     .common = {
3986         .tag = HARDWARE_MODULE_TAG,
3987         .module_api_version = SOUND_TRIGGER_MODULE_API_VERSION_1_0,
3988         .hal_api_version = HARDWARE_HAL_API_VERSION,
3989         .id = SOUND_TRIGGER_HARDWARE_MODULE_ID,
3990         .name = "Knowles Sound Trigger HAL",
3991         .author = "Knowles Electronics",
3992         .methods = &hal_module_methods,
3993     },
3994 };
3995