1 /*
2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3 *
4 */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <signal.h>
11 #include <errno.h>
12
13 #include "uvoice_os.h"
14 #include "uvoice_types.h"
15 #include "uvoice_mlist.h"
16
17 #include "uvoice_config.h"
18
19
20 #define SOURCE_LIST_INDEX_KEY "mlist_index"
21
22
23 typedef struct {
24 int count;
25 int index;
26 char source[128];
27 os_mutex_t lock;
28 } mlist_t;
29
30 static mlist_t *g_src_list;
31
mlist_source_show(void)32 int mlist_source_show(void)
33 {
34 mlist_t *src_list = g_src_list;
35 char *listpath;
36 os_file_t *list_fp;
37 char file_name[128];
38 int index = 0;
39 char *ptr = NULL;
40 int len;
41
42 if (!src_list) {
43 M_LOGE("src_list null !\n");
44 return -1;
45 }
46
47 os_mutex_lock(src_list->lock, OS_WAIT_FOREVER);
48
49 len = strlen(PLAYER_SOURCE_LIST_DIR) +
50 strlen(PLAYER_SOURCE_LIST_NAME) + 4;
51 listpath = snd_zalloc(len, AFM_EXTN);
52 if (!listpath) {
53 M_LOGE("alloc list path failed !\n");
54 os_mutex_unlock(src_list->lock);
55 return -1;
56 }
57
58 snprintf(listpath, len, "%s/%s",
59 PLAYER_SOURCE_LIST_DIR, PLAYER_SOURCE_LIST_NAME);
60
61 list_fp = os_fopen(listpath, "r");
62 if (!list_fp) {
63 M_LOGE("list not found, please scan\n");
64 snd_free(listpath);
65 os_mutex_unlock(src_list->lock);
66 return -1;
67 }
68
69 while (!os_feof(list_fp)) {
70 memset(file_name, 0, sizeof(file_name));
71 os_fgets(file_name, sizeof(file_name), list_fp);
72
73 if (file_name[strlen(file_name) - 1] == '\n')
74 file_name[strlen(file_name) - 1] = '\0';
75
76 ptr = strchr(file_name, '/');
77 if (!ptr)
78 continue;
79
80 ptr += 1;
81 index = atoi(ptr);
82
83 ptr = strchr(ptr, '/');
84 if (!ptr)
85 continue;
86
87 ptr += 1;
88 M_LOGI("No.%d %s\n", index, ptr);
89 }
90
91 os_fclose(list_fp);
92 snd_free(listpath);
93 os_mutex_unlock(src_list->lock);
94 return 0;
95 }
96
mlist_source_scan(void)97 int mlist_source_scan(void)
98 {
99 mlist_t *src_list = g_src_list;
100 char *listpath;
101 int listpath_len;
102 os_file_t *list_fp;
103 os_dir_t *dir;
104 os_dirent_t *content = NULL;
105 media_format_t format = MEDIA_FMT_UNKNOWN;
106 int index = 0;
107 bool curr_source_found = false;
108 int ret;
109
110 if (!src_list) {
111 M_LOGE("src_list null !\n");
112 return -1;
113 }
114
115 os_mutex_lock(src_list->lock, OS_WAIT_FOREVER);
116
117 ret = access(PLAYER_SOURCE_LIST_DIR, F_OK);
118 if (ret) {
119 ret = os_mkdir(PLAYER_SOURCE_LIST_DIR);
120 if (ret) {
121 M_LOGE("create %s failed %d!\n",
122 PLAYER_SOURCE_LIST_DIR, ret);
123 os_mutex_unlock(src_list->lock);
124 return -1;
125 }
126 M_LOGD("create dir: %s\n", PLAYER_SOURCE_LIST_DIR);
127 }
128
129 listpath_len = strlen(PLAYER_SOURCE_LIST_DIR) +
130 strlen(PLAYER_SOURCE_LIST_NAME) + 2;
131 listpath = snd_zalloc(listpath_len, AFM_EXTN);
132 if (!listpath) {
133 M_LOGE("alloc list path failed !\n");
134 os_mutex_unlock(src_list->lock);
135 return -1;
136 }
137
138 snprintf(listpath, listpath_len, "%s/%s",
139 PLAYER_SOURCE_LIST_DIR, PLAYER_SOURCE_LIST_NAME);
140
141 list_fp = os_fopen(listpath, "w+");
142 if (!list_fp) {
143 M_LOGE("open %s failed !\n", listpath);
144 snd_free(listpath);
145 os_mutex_unlock(src_list->lock);
146 return -1;
147 }
148
149 dir = os_opendir(PLAYER_SOURCE_LIST_DIR);
150 if (!dir) {
151 M_LOGE("open %s failed !\n", PLAYER_SOURCE_LIST_DIR);
152 os_fclose(list_fp);
153 snd_free(listpath);
154 os_mutex_unlock(src_list->lock);
155 return -1;
156 }
157
158 while (1) {
159 content = os_readdir(dir);
160 if (!content)
161 break;
162
163 #ifdef __os_alios_things__
164 if (content->d_type & (AM_DIR | AM_HID | AM_ARC | AM_SYS))
165 continue;
166 #else
167 if (!(content->d_type & (DT_REG)))
168 continue;
169 #endif
170
171 format = MEDIA_FMT_UNKNOWN;
172 format_parse_byname(content->d_name, &format);
173 if (format == MEDIA_FMT_UNKNOWN)
174 continue;
175
176 if (strlen(content->d_name) + strlen("fs:") +
177 strlen(PLAYER_SOURCE_LIST_DIR) > 126)
178 continue;
179
180 index++;
181 if (os_fprintf(list_fp, "/%d/%s\n", index, content->d_name) < 0) {
182 M_LOGE("write list failed !\n");
183 index--;
184 continue;
185 }
186
187 if (src_list->index > 0) {
188
189 if (strlen(src_list->source) <=
190 (strlen("fs:") + strlen(PLAYER_SOURCE_LIST_DIR) + 1)) {
191 M_LOGE("source name invalid\n");
192 continue;
193 }
194
195 if (!strncmp(content->d_name, (char *)src_list->source +
196 strlen("fs:") + strlen(PLAYER_SOURCE_LIST_DIR) + 1,
197 strlen(content->d_name))) {
198 curr_source_found = true;
199 if (src_list->index != index) {
200 M_LOGI("update index %d\n", index);
201 src_list->index = index;
202 ret = os_kv_set(SOURCE_LIST_INDEX_KEY,
203 &src_list->index,
204 sizeof(src_list->index), 0);
205 if (ret) {
206 M_LOGW("kv set failed %d!\n", ret);
207 ret = -1;
208 goto __exit;
209 }
210 }
211 }
212 }
213
214 //M_LOGD("No.%d %s\n", index, content->d_name);
215 }
216
217 if (src_list->count != index)
218 src_list->count = index;
219 M_LOGD("list count %d\n", src_list->count);
220
221 __exit:
222 os_closedir(dir);
223 os_fclose(list_fp);
224 snd_free(listpath);
225
226 if (!curr_source_found && src_list->index > 0) {
227 M_LOGD("set default index\n");
228 src_list->index = 0;
229 os_mutex_unlock(src_list->lock);
230 if (mlist_index_set(1)) {
231 M_LOGE("set index failed !\n");
232 ret = -1;
233 }
234 } else {
235 os_mutex_unlock(src_list->lock);
236 }
237
238 return ret;
239 }
240
mlist_source_get(int index,char * path,int len)241 int mlist_source_get(int index, char *path, int len)
242 {
243 mlist_t *src_list = g_src_list;
244 char file_name[128];
245 int listpath_len;
246 char *listpath;
247 os_file_t *list_fp;
248 char *ptr = NULL;
249 int file_index = 0;
250 int ret = -1;
251
252 if (!src_list) {
253 M_LOGE("src_list null !\n");
254 return -1;
255 }
256
257 if (!path) {
258 M_LOGE("path null !\n");
259 return -1;
260 }
261
262 if (len < 0) {
263 M_LOGE("len %d invalid!\n", len);
264 return -1;
265 }
266
267 os_mutex_lock(src_list->lock, OS_WAIT_FOREVER);
268
269 if (index <= 0 || index > src_list->count) {
270 M_LOGE("index %d count %d\n",
271 index, src_list->count);
272 os_mutex_unlock(src_list->lock);
273 return -1;
274 }
275
276 listpath_len = strlen(PLAYER_SOURCE_LIST_DIR) +
277 strlen(PLAYER_SOURCE_LIST_NAME) + 4;
278 listpath = snd_zalloc(listpath_len, AFM_EXTN);
279 if (!listpath) {
280 M_LOGE("alloc list path failed !\n");
281 os_mutex_unlock(src_list->lock);
282 return -1;
283 }
284
285 snprintf(listpath, listpath_len, "%s/%s",
286 PLAYER_SOURCE_LIST_DIR, PLAYER_SOURCE_LIST_NAME);
287
288 list_fp = os_fopen(listpath, "r");
289 if (!list_fp) {
290 M_LOGE("open %s failed !\n", listpath);
291 snd_free(listpath);
292 os_mutex_unlock(src_list->lock);
293 return -1;
294 }
295
296 while (!os_feof(list_fp)) {
297 memset(file_name, 0, sizeof(file_name));
298 os_fgets(file_name, sizeof(file_name), list_fp);
299
300 if (file_name[strlen(file_name) - 1] == '\n')
301 file_name[strlen(file_name) - 1] = '\0';
302
303 ptr = strchr(file_name, '/');
304 if (!ptr)
305 continue;
306 ptr += 1;
307
308 file_index = atoi(ptr);
309 if (file_index <= 0)
310 continue;
311
312 //M_LOGD("index %d, name: %s\n", file_index, file_name);
313
314 if (file_index == index) {
315
316 ptr = strchr(ptr, '/');
317 if (!ptr)
318 continue;
319 ptr += 1;
320
321 if (strchr(ptr, '/'))
322 continue;
323
324 if (strlen(ptr) + strlen("fs:") +
325 strlen(PLAYER_SOURCE_LIST_DIR) + 2 > len) {
326 M_LOGE("name %s length %d too long !\n",
327 ptr, strlen(ptr));
328 ret = -1;
329 break;
330 }
331
332 snprintf(path, len, "fs:%s/%s",
333 PLAYER_SOURCE_LIST_DIR, ptr);
334 //M_LOGD("found /%d/%s\n", index, path);
335
336 ret = 0;
337 break;
338 }
339 }
340
341 os_fclose(list_fp);
342 snd_free(listpath);
343
344 os_mutex_unlock(src_list->lock);
345 return ret;
346 }
347
mlist_source_del(int index)348 int mlist_source_del(int index)
349 {
350 mlist_t *src_list = g_src_list;
351 char file_path[128];
352 int ret = 0;
353
354 if (!src_list) {
355 M_LOGE("src_list null !\n");
356 return -1;
357 }
358
359 memset(file_path, 0, sizeof(file_path));
360
361 if (mlist_source_get(index, file_path, sizeof(file_path))) {
362 M_LOGE("get source name failed !\n");
363 return -1;
364 }
365
366 if (strncmp(file_path, "fs:", strlen("fs:"))) {
367 M_LOGE("source path invalid !\n");
368 return -1;
369 }
370
371 if (unlink((char *)file_path + strlen("fs:"))) {
372 M_LOGE("delete %s failed !\n", file_path);
373 return -1;
374 }
375
376 os_mutex_lock(src_list->lock, OS_WAIT_FOREVER);
377
378 if (src_list->index == index && index != 1) {
379 M_LOGD("set default index\n");
380 src_list->index = 1;
381 ret = os_kv_set(SOURCE_LIST_INDEX_KEY,
382 &src_list->index,
383 sizeof(src_list->index), 0);
384 if (ret) {
385 M_LOGE("kv set failed %d!\n", ret);
386 os_mutex_unlock(src_list->lock);
387 return -1;
388 }
389
390 memset(src_list->source, 0, sizeof(src_list->source));
391 os_mutex_unlock(src_list->lock);
392 if (mlist_source_get(src_list->index,
393 src_list->source,
394 sizeof(src_list->source))) {
395 M_LOGE("get source name failed !\n");
396 return -1;
397 }
398 } else {
399 os_mutex_unlock(src_list->lock);
400 }
401
402 if (mlist_source_scan()) {
403 M_LOGE("scan source failed !\n");
404 return -1;
405 }
406
407 M_LOGI("%s delete\n", file_path);
408 return 0;
409 }
410
mlist_index_get(int * index)411 int mlist_index_get(int *index)
412 {
413 mlist_t *src_list = g_src_list;
414 int kv_len;
415 int ret = 0;
416
417 if (!src_list) {
418 M_LOGE("src_list null !\n");
419 return -1;
420 }
421
422 os_mutex_lock(src_list->lock, OS_WAIT_FOREVER);
423
424 kv_len = sizeof(src_list->index);
425
426 if (src_list->index == 0) {
427 ret = os_kv_get(SOURCE_LIST_INDEX_KEY,
428 &src_list->index, &kv_len);
429 os_mutex_unlock(src_list->lock);
430 if (ret == -ENOENT) {
431 M_LOGD("set default index\n");
432 if (mlist_index_set(1)) {
433 M_LOGE("set source index failed !\n");
434 return -1;
435 }
436 } else if (ret) {
437 M_LOGE("kv get failed %d!\n", ret);
438 return -1;
439 }
440 } else {
441 os_mutex_unlock(src_list->lock);
442 }
443
444 if (strlen(src_list->source) <= 0) {
445 if (mlist_source_get(src_list->index,
446 src_list->source, sizeof(src_list->source))) {
447 M_LOGE("get source name failed !\n");
448 return -1;
449 }
450 }
451
452 *index = src_list->index;
453 M_LOGD("No.%d %s\n", *index,
454 (char *)src_list->source + strlen("fs:") +
455 strlen(PLAYER_SOURCE_LIST_DIR) + 1);
456
457 return 0;
458 }
459
mlist_index_set(int index)460 int mlist_index_set(int index)
461 {
462 mlist_t *src_list = g_src_list;
463 int kv_len;
464 int ret = 0;
465
466 if (!src_list) {
467 M_LOGE("src_list null !\n");
468 return -1;
469 }
470
471 os_mutex_lock(src_list->lock, OS_WAIT_FOREVER);
472
473 kv_len = sizeof(src_list->index);
474
475 if (src_list->index != index) {
476 src_list->index = index;
477 ret = os_kv_set(SOURCE_LIST_INDEX_KEY,
478 &src_list->index,
479 sizeof(src_list->index), 0);
480 if (ret) {
481 M_LOGE("kv set failed %d!\n", ret);
482 os_mutex_unlock(src_list->lock);
483 return -1;
484 }
485
486 M_LOGI("update source index %d\n", src_list->index);
487
488 os_mutex_unlock(src_list->lock);
489
490 memset(src_list->source, 0, sizeof(src_list->source));
491 if (mlist_source_get(index, src_list->source,
492 sizeof(src_list->source))) {
493 M_LOGE("get source name failed !\n");
494 return -1;
495 }
496 } else {
497 os_mutex_unlock(src_list->lock);
498 }
499
500 return 0;
501 }
502
mlist_init(void)503 int mlist_init(void)
504 {
505 mlist_t *src_list;
506 int index = 0;
507
508 src_list = snd_zalloc(sizeof(mlist_t), AFM_EXTN);
509 if (!src_list) {
510 M_LOGE("alloc src list failed !\n");
511 return -1;
512 }
513
514 src_list->lock = os_mutex_new();
515
516 g_src_list = src_list;
517
518 if (mlist_source_scan()) {
519 M_LOGE("scan source failed !\n");
520 return -1;
521 }
522
523 if (mlist_index_get(&index)) {
524 M_LOGE("get source index failed !\n");
525 return -1;
526 }
527
528 M_LOGD("mlist init\n");
529 return 0;
530 }
531
mlist_deinit(void)532 int mlist_deinit(void)
533 {
534 mlist_t *src_list = g_src_list;
535 if (!src_list) {
536 M_LOGE("src_list null !\n");
537 return -1;
538 }
539
540 os_mutex_free(src_list->lock);
541 snd_free(src_list);
542 g_src_list = NULL;
543
544 M_LOGD("mlist free\n");
545 return 0;
546 }
547
548