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 
11 #include "uvoice_os.h"
12 #include "uvoice_types.h"
13 #include "uvoice_player.h"
14 
15 #include "uvoice_config.h"
16 #include "uvoice_common.h"
17 #include "uvoice_play.h"
18 
19 #include "uvoice_cache.h"
20 
21 
net_download_work(net_cache_t * nc)22 int net_download_work(net_cache_t *nc)
23 {
24     int filepath_len;
25     char *filepath;
26     os_file_t fp;
27     int rd_ret = 0;
28     int load_size;
29     int i = 0;
30     int ret;
31 
32     if (!nc) {
33         M_LOGE("nc null !\n");
34         return -1;
35     }
36 
37     os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
38 
39     ret = os_access(PLAYER_SOURCE_DLOAD_DIR, OS_F_OK);
40     if (ret != 0) {
41         ret = os_mkdir(PLAYER_SOURCE_DLOAD_DIR);
42         if (ret) {
43             M_LOGE("create %s failed %d!\n",
44                     PLAYER_SOURCE_DLOAD_DIR, ret);
45             os_mutex_unlock(nc->lock);
46             return -1;
47         }
48         M_LOGD("create dir: %s\n", PLAYER_SOURCE_DLOAD_DIR);
49     }
50 
51     filepath_len = strlen(PLAYER_SOURCE_DLOAD_DIR) +
52         strlen(nc->filename) + 4;
53     filepath = snd_zalloc(filepath_len, AFM_EXTN);
54     if (!filepath) {
55         M_LOGE("alloc file path failed !\n");
56         os_mutex_unlock(nc->lock);
57         return -1;
58     }
59 
60     snprintf(filepath, filepath_len, "%s/%s",
61         PLAYER_SOURCE_DLOAD_DIR, nc->filename);
62 
63     M_LOGI("download to %s\n", filepath);
64     ret = os_access(filepath, OS_W_OK | OS_R_OK | OS_F_OK);
65     if (ret == 0) {
66         M_LOGW("file exist\n");
67         snd_free(filepath);
68         os_mutex_unlock(nc->lock);
69         goto __exit;
70     }
71 
72     fp = os_fopen(filepath, "wb+");
73     if (OS_FILE_OPEN_FAIL(fp)) {
74         M_LOGE("open %s failed !\n", filepath);
75         snd_free(filepath);
76         os_mutex_unlock(nc->lock);
77         return -1;
78     }
79 
80     if (nc->head_data_size > 0) {
81         ret = os_fwrite(nc->buffer, 1, nc->head_data_size, fp);
82         if (os_ferror(fp) || ret != nc->head_data_size) {
83             M_LOGE("write head data failed %d!\n", os_ferror(fp));
84             os_fclose(fp);
85             snd_free(filepath);
86             nc->head_data_size = 0;
87             os_mutex_unlock(nc->lock);
88             return -1;
89         }
90         M_LOGD("save head data %u\n", nc->head_data_size);
91         nc->load_length += nc->head_data_size;
92         nc->head_data_size = 0;
93     }
94 
95     load_size = MIN(nc->buffer_size,
96         nc->content_length - nc->load_length);
97 
98     nc->download = 1;
99 
100     os_mutex_unlock(nc->lock);
101 
102     while (load_size > 0) {
103         rd_ret = nc->cache_load(nc->priv, nc->buffer, load_size);
104         if (rd_ret < 0) {
105             M_LOGE("read failed !\n");
106             break;
107         } else if (rd_ret == 0) {
108             M_LOGD("read end\n");
109             break;
110         }
111 
112         os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
113         ret = os_fwrite(nc->buffer, 1, rd_ret, fp);
114         if (os_ferror(fp) || ret != rd_ret) {
115             M_LOGE("write failed %d!\n", os_ferror(fp));
116             os_mutex_unlock(nc->lock);
117             break;
118         }
119         nc->load_length += rd_ret;
120         load_size = MIN(load_size,
121             nc->content_length - nc->load_length);
122         if (++i == 50) {
123             M_LOGI("download %d/%d\n",
124                 nc->load_length, nc->content_length);
125             i = 0;
126         }
127 
128         if (!nc->download) {
129             M_LOGI("download abort\n");
130             os_mutex_unlock(nc->lock);
131             break;
132         }
133         os_mutex_unlock(nc->lock);
134     }
135 
136     os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
137 
138     os_fclose(fp);
139 
140     if (!nc->download) {
141         ret = os_remove(filepath);
142         if (ret)
143             M_LOGE("delete failed %d!\n", ret);
144         else
145             M_LOGD("file delete\n");
146     } else {
147         M_LOGI("download %d/%d\n",
148             nc->load_length, nc->content_length);
149         M_LOGI("download complete\n");
150     }
151 
152     snd_free(filepath);
153     if (nc->cplt_waiting) {
154         nc->cplt_waiting = 0;
155         os_sem_signal(nc->cplt_sem);
156     }
157     os_mutex_unlock(nc->lock);
158 
159 __exit:
160     return 0;
161 }
162 
new_download_abort(net_cache_t * nc)163 int new_download_abort(net_cache_t *nc)
164 {
165     if (!nc) {
166         M_LOGW("nc null\n");
167         return -1;
168     }
169 
170     os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
171     if (nc->download) {
172         nc->download = 0;
173         nc->cplt_waiting = 1;
174         M_LOGD("wait cplt\n");
175         os_mutex_unlock(nc->lock);
176         if (os_sem_wait(nc->cplt_sem, 15000)) {
177             M_LOGE("wait cplt timeout !\n");
178             nc->cplt_waiting = 0;
179             return -1;
180         }
181 
182         M_LOGD("download abort\n");
183     } else {
184         M_LOGW("no download\n");
185         os_mutex_unlock(nc->lock);
186     }
187     return 0;
188 }
189 
net_download_create(void)190 net_cache_t *net_download_create(void)
191 {
192     net_cache_t *nc = snd_zalloc(sizeof(net_cache_t), AFM_EXTN);
193     if (!nc) {
194         M_LOGE("alloc net cache failed !\n");
195         return NULL;
196     }
197 
198     nc->cache_config.place = CACHE_NONE;
199     nc->buffer_size = 2048;
200     nc->buffer = snd_zalloc(nc->buffer_size, AFM_MAIN);
201     if (!nc->buffer) {
202         M_LOGE("alloc buffer failed !\n");
203         snd_free(nc);
204         return NULL;
205     }
206 
207     nc->lock = os_mutex_new();
208     nc->cplt_sem = os_sem_new(0);
209     return nc;
210 }
211 
net_download_release(net_cache_t * nc)212 int net_download_release(net_cache_t *nc)
213 {
214     if (!nc) {
215         M_LOGE("nc null !\n");
216         return -1;
217     }
218 
219     os_sem_free(nc->cplt_sem);
220     os_mutex_free(nc->lock);
221     snd_free(nc->buffer);
222     snd_free(nc);
223     return 0;
224 }
225 
226