fix checking rule of strncpy
[platform/core/multimedia/libmm-wfd.git] / src / mm_wfd_sink.c
1 /*
2  * libmm-wfd
3  *
4  * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
7  * Maksym Ukhanov <m.ukhanov@samsung.com>, Hyunjun Ko <zzoon.ko@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23 #include <gst/gst.h>
24
25 #include "mm_wfd_sink_util.h"
26 #include "mm_wfd_sink.h"
27 #include "mm_wfd_sink_priv.h"
28 #include "mm_wfd_sink_dlog.h"
29
30 int mm_wfd_sink_create(MMHandleType *wfd_sink)
31 {
32         mm_wfd_sink_t *new_wfd_sink = NULL;
33         int result = MM_ERROR_NONE;
34
35         wfd_sink_debug_fenter();
36
37         wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
38
39         result = _mm_wfd_sink_create(&new_wfd_sink);
40         if (result != MM_ERROR_NONE) {
41                 wfd_sink_error("fail to create wi-fi display sink handle. ret[%d]", result);
42                 *wfd_sink = (MMHandleType)NULL;
43                 return result;
44         }
45
46         /* init wfd lock */
47         g_mutex_init(&new_wfd_sink->cmd_lock);
48
49         *wfd_sink = (MMHandleType)new_wfd_sink;
50
51         wfd_sink_debug_fleave();
52
53         return result;
54
55 }
56
57 int mm_wfd_sink_prepare(MMHandleType wfd_sink)
58 {
59         int result = MM_ERROR_NONE;
60
61         wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
62
63         MMWFDSINK_CMD_LOCK(wfd_sink);
64         result = _mm_wfd_sink_prepare((mm_wfd_sink_t *)wfd_sink);
65         MMWFDSINK_CMD_UNLOCK(wfd_sink);
66
67         return result;
68 }
69
70 int mm_wfd_sink_connect(MMHandleType wfd_sink, const char *uri)
71 {
72         int result = MM_ERROR_NONE;
73
74         wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
75         wfd_sink_return_val_if_fail(uri, MM_ERROR_WFD_INVALID_ARGUMENT);
76
77         MMWFDSINK_CMD_LOCK(wfd_sink);
78         result = _mm_wfd_sink_connect((mm_wfd_sink_t *)wfd_sink, uri);
79         MMWFDSINK_CMD_UNLOCK(wfd_sink);
80
81         return result;
82 }
83
84 int mm_wfd_sink_start(MMHandleType wfd_sink)
85 {
86         int result = MM_ERROR_NONE;
87
88         wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
89
90         MMWFDSINK_CMD_LOCK(wfd_sink);
91         result = _mm_wfd_sink_start((mm_wfd_sink_t *)wfd_sink);
92         MMWFDSINK_CMD_UNLOCK(wfd_sink);
93
94         return result;
95 }
96
97 int mm_wfd_sink_pause(MMHandleType wfd_sink)
98 {
99         int result = MM_ERROR_NONE;
100
101         wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
102
103         MMWFDSINK_CMD_LOCK(wfd_sink);
104         result = _mm_wfd_sink_pause((mm_wfd_sink_t *)wfd_sink);
105         MMWFDSINK_CMD_UNLOCK(wfd_sink);
106
107         return result;
108 }
109
110 int mm_wfd_sink_resume(MMHandleType wfd_sink)
111 {
112         int result = MM_ERROR_NONE;
113
114         wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
115
116         MMWFDSINK_CMD_LOCK(wfd_sink);
117         result = _mm_wfd_sink_resume((mm_wfd_sink_t *)wfd_sink);
118         MMWFDSINK_CMD_UNLOCK(wfd_sink);
119
120         return result;
121 }
122
123 int mm_wfd_sink_disconnect(MMHandleType wfd_sink)
124 {
125         int result = MM_ERROR_NONE;
126
127         wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
128
129         MMWFDSINK_CMD_LOCK(wfd_sink);
130         result = _mm_wfd_sink_disconnect((mm_wfd_sink_t *)wfd_sink);
131         MMWFDSINK_CMD_UNLOCK(wfd_sink);
132
133         return result;
134 }
135
136 int mm_wfd_sink_unprepare(MMHandleType wfd_sink)
137 {
138         int result = MM_ERROR_NONE;
139
140         wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
141
142         MMWFDSINK_CMD_LOCK(wfd_sink);
143         result = _mm_wfd_sink_unprepare((mm_wfd_sink_t *)wfd_sink);
144         MMWFDSINK_CMD_UNLOCK(wfd_sink);
145
146         return result;
147 }
148
149 int mm_wfd_sink_destroy(MMHandleType wfd_sink)
150 {
151         int result = MM_ERROR_NONE;
152         mm_wfd_sink_t *sink_handle = NULL;
153
154         wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
155
156         MMWFDSINK_CMD_LOCK(wfd_sink);
157         result = _mm_wfd_sink_destroy((mm_wfd_sink_t *)wfd_sink);
158         MMWFDSINK_CMD_UNLOCK(wfd_sink);
159
160         g_mutex_clear(&(((mm_wfd_sink_t *)wfd_sink)->cmd_lock));
161
162         sink_handle = (mm_wfd_sink_t *)wfd_sink;
163         MMWFDSINK_FREEIF(sink_handle);
164
165         return result;
166 }
167
168 int mm_wfd_sink_set_message_callback(MMHandleType wfd_sink, MMWFDMessageCallback callback, void *user_data)
169 {
170         int result = MM_ERROR_NONE;
171
172         wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
173
174         MMWFDSINK_CMD_LOCK(wfd_sink);
175         result = _mm_wfd_set_message_callback((mm_wfd_sink_t *)wfd_sink, callback, user_data);
176         MMWFDSINK_CMD_UNLOCK(wfd_sink);
177
178         return result;
179 }
180
181 int mm_wfd_sink_set_attribute(MMHandleType wfd_sink,  char **err_attr_name, const char *first_attribute_name, ...)
182 {
183         int result = MM_ERROR_NONE;
184         va_list var_args;
185
186         wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
187         wfd_sink_return_val_if_fail(first_attribute_name, MM_ERROR_WFD_INVALID_ARGUMENT);
188
189         MMWFDSINK_CMD_LOCK(wfd_sink);
190         va_start(var_args, first_attribute_name);
191         result = _mmwfd_set_attribute(MMWFDSINK_GET_ATTRS(wfd_sink), err_attr_name, first_attribute_name, var_args);
192         va_end(var_args);
193         MMWFDSINK_CMD_UNLOCK(wfd_sink);
194
195         return result;
196 }
197
198 int mm_wfd_sink_get_video_resolution(MMHandleType wfd_sink, gint *width, gint *height)
199 {
200         mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
201
202         wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
203         wfd_sink_return_val_if_fail(width, MM_ERROR_WFD_INVALID_ARGUMENT);
204         wfd_sink_return_val_if_fail(height, MM_ERROR_WFD_INVALID_ARGUMENT);
205
206         *width = wfd->stream_info.video_stream_info.width;
207         *height = wfd->stream_info.video_stream_info.height;
208
209         return MM_ERROR_NONE;
210 }
211
212 int mm_wfd_sink_get_video_framerate(MMHandleType wfd_sink, gint *frame_rate)
213 {
214         mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
215
216         wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
217         wfd_sink_return_val_if_fail(frame_rate, MM_ERROR_WFD_INVALID_ARGUMENT);
218
219         *frame_rate = wfd->stream_info.video_stream_info.frame_rate;
220
221         return MM_ERROR_NONE;
222 }
223
224 int mm_wfd_sink_set_resolution(MMHandleType wfd_sink,  gint resolution)
225 {
226         int result = MM_ERROR_NONE;
227
228         wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
229         MMWFDSINK_CMD_LOCK(wfd_sink);
230         result = _mm_wfd_sink_set_resolution((mm_wfd_sink_t *)wfd_sink, resolution);
231         MMWFDSINK_CMD_UNLOCK(wfd_sink);
232
233         return result;
234 }
235
236 int mm_wfd_sink_get_negotiated_video_codec(MMHandleType wfd_sink,  gint *codec)
237 {
238         int result = MM_ERROR_NONE;
239         mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
240         MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
241
242         wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
243         wfd_sink_return_val_if_fail(codec, MM_ERROR_WFD_INVALID_ARGUMENT);
244
245         MMWFDSINK_CMD_LOCK(wfd);
246
247         MMWFDSINK_PRINT_STATE(wfd);
248         cur_state = MMWFDSINK_CURRENT_STATE(wfd);
249         if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
250                 cur_state != MM_WFD_SINK_STATE_PLAYING &&
251                 cur_state != MM_WFD_SINK_STATE_PAUSED) {
252
253                 wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
254                 result = MM_ERROR_WFD_INVALID_STATE;
255         } else {
256                 *codec = wfd->stream_info.video_stream_info.codec;
257         }
258
259         MMWFDSINK_CMD_UNLOCK(wfd);
260
261         wfd_sink_debug_fleave();
262
263         return result;
264 }
265
266 int mm_wfd_sink_get_negotiated_video_resolution(MMHandleType wfd_sink,  gint *width, gint *height)
267 {
268         int result = MM_ERROR_NONE;
269         mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
270         MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
271
272         wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
273         wfd_sink_return_val_if_fail(width, MM_ERROR_WFD_INVALID_ARGUMENT);
274         wfd_sink_return_val_if_fail(height, MM_ERROR_WFD_INVALID_ARGUMENT);
275
276         MMWFDSINK_CMD_LOCK(wfd);
277
278         MMWFDSINK_PRINT_STATE(wfd);
279         cur_state = MMWFDSINK_CURRENT_STATE(wfd);
280         if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
281                 cur_state != MM_WFD_SINK_STATE_PLAYING &&
282                 cur_state != MM_WFD_SINK_STATE_PAUSED) {
283
284                 wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
285                 result = MM_ERROR_WFD_INVALID_STATE;
286         } else {
287                 *width = wfd->stream_info.video_stream_info.width;
288                 *height = wfd->stream_info.video_stream_info.height;
289         }
290
291         MMWFDSINK_CMD_UNLOCK(wfd);
292
293         wfd_sink_debug_fleave();
294
295         return result;
296 }
297
298 int mm_wfd_sink_get_negotiated_video_frame_rate(MMHandleType wfd_sink,  gint *frame_rate)
299 {
300         int result = MM_ERROR_NONE;
301         mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
302         MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
303
304         wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
305         wfd_sink_return_val_if_fail(frame_rate, MM_ERROR_WFD_INVALID_ARGUMENT);
306
307         MMWFDSINK_CMD_LOCK(wfd);
308
309         MMWFDSINK_PRINT_STATE(wfd);
310         cur_state = MMWFDSINK_CURRENT_STATE(wfd);
311         if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
312                 cur_state != MM_WFD_SINK_STATE_PLAYING &&
313                 cur_state != MM_WFD_SINK_STATE_PAUSED) {
314
315                 wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
316                 result = MM_ERROR_WFD_INVALID_STATE;
317         } else {
318                 *frame_rate = wfd->stream_info.video_stream_info.frame_rate;
319         }
320
321         MMWFDSINK_CMD_UNLOCK(wfd);
322
323         wfd_sink_debug_fleave();
324
325         return result;
326 }
327
328 int mm_wfd_sink_get_negotiated_audio_codec(MMHandleType wfd_sink,  gint *codec)
329 {
330         int result = MM_ERROR_NONE;
331         mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
332         MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
333
334         wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
335         wfd_sink_return_val_if_fail(codec, MM_ERROR_WFD_INVALID_ARGUMENT);
336
337         MMWFDSINK_CMD_LOCK(wfd);
338
339         MMWFDSINK_PRINT_STATE(wfd);
340         cur_state = MMWFDSINK_CURRENT_STATE(wfd);
341         if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
342                 cur_state != MM_WFD_SINK_STATE_PLAYING &&
343                 cur_state != MM_WFD_SINK_STATE_PAUSED) {
344
345                 wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
346                 result = MM_ERROR_WFD_INVALID_STATE;
347         } else {
348                 *codec = wfd->stream_info.audio_stream_info.codec;
349         }
350
351         MMWFDSINK_CMD_UNLOCK(wfd);
352
353         wfd_sink_debug_fleave();
354
355         return result;
356 }
357
358 int mm_wfd_sink_get_negotiated_audio_channel(MMHandleType wfd_sink,  gint *channel)
359 {
360         int result = MM_ERROR_NONE;
361         mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
362         MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
363
364         wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
365         wfd_sink_return_val_if_fail(channel, MM_ERROR_WFD_INVALID_ARGUMENT);
366
367         MMWFDSINK_CMD_LOCK(wfd);
368
369         MMWFDSINK_PRINT_STATE(wfd);
370         cur_state = MMWFDSINK_CURRENT_STATE(wfd);
371         if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
372                 cur_state != MM_WFD_SINK_STATE_PLAYING &&
373                 cur_state != MM_WFD_SINK_STATE_PAUSED) {
374
375                 wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
376                 result = MM_ERROR_WFD_INVALID_STATE;
377         } else {
378                 *channel = wfd->stream_info.audio_stream_info.channels;
379         }
380
381         MMWFDSINK_CMD_UNLOCK(wfd);
382
383         wfd_sink_debug_fleave();
384
385         return result;
386 }
387
388 int mm_wfd_sink_get_negotiated_audio_sample_rate(MMHandleType wfd_sink,  gint *sample_rate)
389 {
390         int result = MM_ERROR_NONE;
391         mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
392         MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
393
394         wfd_sink_debug_fenter();
395
396         wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
397         wfd_sink_return_val_if_fail(sample_rate, MM_ERROR_WFD_INVALID_ARGUMENT);
398
399         MMWFDSINK_CMD_LOCK(wfd);
400
401         MMWFDSINK_PRINT_STATE(wfd);
402         cur_state = MMWFDSINK_CURRENT_STATE(wfd);
403         if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
404                 cur_state != MM_WFD_SINK_STATE_PLAYING &&
405                 cur_state != MM_WFD_SINK_STATE_PAUSED) {
406
407                 wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
408                 result = MM_ERROR_WFD_INVALID_STATE;
409         } else {
410                 *sample_rate = wfd->stream_info.audio_stream_info.sample_rate;
411         }
412
413         MMWFDSINK_CMD_UNLOCK(wfd);
414
415         wfd_sink_debug_fleave();
416
417         return result;
418 }
419
420 int mm_wfd_sink_get_negotiated_audio_bitwidth(MMHandleType wfd_sink,  gint *bitwidth)
421 {
422         int result = MM_ERROR_NONE;
423         mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
424         MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
425
426         wfd_sink_debug_fenter();
427
428         wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
429         wfd_sink_return_val_if_fail(bitwidth, MM_ERROR_WFD_INVALID_ARGUMENT);
430
431         MMWFDSINK_CMD_LOCK(wfd);
432
433         MMWFDSINK_PRINT_STATE(wfd);
434         cur_state = MMWFDSINK_CURRENT_STATE(wfd);
435         if (cur_state != MM_WFD_SINK_STATE_CONNECTED &&
436                 cur_state != MM_WFD_SINK_STATE_PLAYING &&
437                 cur_state != MM_WFD_SINK_STATE_PAUSED) {
438
439                 wfd_sink_error("This function must be called after MM_WFD_SINK_STATE_CONNECTED");
440                 result = MM_ERROR_WFD_INVALID_STATE;
441         } else {
442                 *bitwidth = wfd->stream_info.audio_stream_info.bitwidth;
443         }
444
445         MMWFDSINK_CMD_UNLOCK(wfd);
446
447         wfd_sink_debug_fleave();
448
449         return result;
450 }