Initial release including wifi display based on gst-rtsp-server-1.4.1
[platform/upstream/gstreamer.git] / gst / rtsp-server / gstwfdmessage.c
1 /* GStreamer
2  * Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 /*
20  * Unless otherwise indicated, Source Code is licensed under MIT license.
21  * See further explanation attached in License Statement (distributed in the file
22  * LICENSE).
23  *
24  * Permission is hereby granted, free of charge, to any person obtaining a copy of
25  * this software and associated documentation files (the "Software"), to deal in
26  * the Software without restriction, including without limitation the rights to
27  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
28  * of the Software, and to permit persons to whom the Software is furnished to do
29  * so, subject to the following conditions:
30  *
31  * The above copyright notice and this permission notice shall be included in all
32  * copies or substantial portions of the Software.
33  *
34  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
37  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
39  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
40  * SOFTWARE.
41  */
42
43 /**
44  * SECTION:gstwfdmessage
45  * @short_description: Helper methods for dealing with WFD messages
46  *
47  * <refsect2>
48  * <para>
49  * The GstWFDMessage helper functions makes it easy to parse and create WFD
50  * messages.
51  * </para>
52  * </refsect2>
53  */
54
55 #ifdef HAVE_CONFIG_H
56 #include "config.h"
57 #endif
58
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include <string.h>
62
63 #include <gio/gio.h>
64
65 #include "gstwfdmessage.h"
66
67 #define EDID_BLOCK_SIZE 128
68
69 #define FREE_STRING(field)              g_free (field); (field) = NULL
70 #define REPLACE_STRING(field, val)      FREE_STRING(field); (field) = g_strdup (val)
71
72 static void
73 free_string (gchar ** str)
74 {
75   FREE_STRING (*str);
76 }
77
78 #define INIT_ARRAY(field, type, init_func)              \
79 G_STMT_START {                                          \
80   if (field) {                                          \
81     guint i;                                            \
82     for(i = 0; i < (field)->len; i++)                   \
83       init_func (&g_array_index ((field), type, i));    \
84     g_array_set_size ((field), 0);                      \
85   }                                                     \
86   else                                                  \
87     (field) = g_array_new (FALSE, TRUE, sizeof (type)); \
88 } G_STMT_END
89
90 #define FREE_ARRAY(field)         \
91 G_STMT_START {                    \
92   if (field)                      \
93     g_array_free ((field), TRUE); \
94   (field) = NULL;                 \
95 } G_STMT_END
96
97 #define DEFINE_STRING_SETTER(field)                                     \
98 GstWFDResult gst_wfd_message_set_##field (GstWFDMessage *msg, const gchar *val) { \
99   g_free (msg->field);                                                  \
100   msg->field = g_strdup (val);                                          \
101   return GST_WFD_OK;                                                    \
102 }
103 #define DEFINE_STRING_GETTER(field)                                     \
104 const gchar* gst_wfd_message_get_##field (const GstWFDMessage *msg) {   \
105   return msg->field;                                                    \
106 }
107
108 #define DEFINE_ARRAY_LEN(field)                                         \
109 guint gst_wfd_message_##field##_len (const GstWFDMessage *msg) {        \
110   return msg->field->len;                                               \
111 }
112 #define DEFINE_ARRAY_GETTER(method, field, type)                        \
113 const type * gst_wfd_message_get_##method (const GstWFDMessage *msg, guint idx) {  \
114   return &g_array_index (msg->field, type, idx);                        \
115 }
116 #define DEFINE_PTR_ARRAY_GETTER(method, field, type)                    \
117 const type gst_wfd_message_get_##method (const GstWFDMessage *msg, guint idx) {    \
118   return g_array_index (msg->field, type, idx);                         \
119 }
120 #define DEFINE_ARRAY_INSERT(method, field, intype, dup_method, type)         \
121 GstWFDResult gst_wfd_message_insert_##method (GstWFDMessage *msg, gint idx, intype val) {   \
122   type vt;                                                              \
123   type* v = &vt;                                                         \
124   dup_method (v, val);                                                  \
125   if (idx == -1)                                                        \
126     g_array_append_val (msg->field, vt);                                \
127   else                                                                  \
128     g_array_insert_val (msg->field, idx, vt);                           \
129   return GST_WFD_OK;                                                    \
130 }
131
132 #define DEFINE_ARRAY_REPLACE(method, field, intype, free_method, dup_method, type)         \
133 GstWFDResult gst_wfd_message_replace_##method (GstWFDMessage *msg, guint idx, intype val) {   \
134   type *v = &g_array_index (msg->field, type, idx);                   \
135   free_method (v);                                                    \
136   dup_method (v, val);                                                  \
137   return GST_WFD_OK;                                                    \
138 }
139 #define DEFINE_ARRAY_REMOVE(method, field, type, free_method)                        \
140 GstWFDResult gst_wfd_message_remove_##method (GstWFDMessage *msg, guint idx) {  \
141   type *v = &g_array_index (msg->field, type, idx);                     \
142   free_method (v);                                                      \
143   g_array_remove_index (msg->field, idx);                               \
144   return GST_WFD_OK;                                                    \
145 }
146 #define DEFINE_ARRAY_ADDER(method, type)                                \
147 GstWFDResult gst_wfd_message_add_##method (GstWFDMessage *msg, const type val) {   \
148   return gst_wfd_message_insert_##method (msg, -1, val);                \
149 }
150
151 #define dup_string(v,val) ((*v) = g_strdup (val))
152 #define INIT_STR_ARRAY(field) \
153     INIT_ARRAY (field, gchar *, free_string)
154 #define DEFINE_STR_ARRAY_GETTER(method, field) \
155     DEFINE_PTR_ARRAY_GETTER(method, field, gchar *)
156 #define DEFINE_STR_ARRAY_INSERT(method, field) \
157     DEFINE_ARRAY_INSERT (method, field, const gchar *, dup_string, gchar *)
158 #define DEFINE_STR_ARRAY_ADDER(method, field) \
159     DEFINE_ARRAY_ADDER (method, gchar *)
160 #define DEFINE_STR_ARRAY_REPLACE(method, field) \
161     DEFINE_ARRAY_REPLACE (method, field, const gchar *, free_string, dup_string, gchar *)
162 #define DEFINE_STR_ARRAY_REMOVE(method, field) \
163     DEFINE_ARRAY_REMOVE (method, field, gchar *, free_string)
164
165 static GstWFDMessage *gst_wfd_message_boxed_copy (GstWFDMessage * orig);
166 static void gst_wfd_message_boxed_free (GstWFDMessage * msg);
167
168 G_DEFINE_BOXED_TYPE (GstWFDMessage, gst_wfd_message, gst_wfd_message_boxed_copy,
169     gst_wfd_message_boxed_free);
170
171 static GstWFDMessage *
172 gst_wfd_message_boxed_copy (GstWFDMessage * orig)
173 {
174   GstWFDMessage *copy;
175
176   if (gst_wfd_message_copy (orig, &copy) == GST_WFD_OK)
177     return copy;
178
179   return NULL;
180 }
181
182 static void
183 gst_wfd_message_boxed_free (GstWFDMessage * msg)
184 {
185   gst_wfd_message_free (msg);
186 }
187
188 /**
189  * gst_wfd_message_new:
190  * @msg: (out) (transfer full): pointer to new #GstWFDMessage
191  *
192  * Allocate a new GstWFDMessage and store the result in @msg.
193  *
194  * Returns: a #GstWFDResult.
195  */
196 GstWFDResult
197 gst_wfd_message_new (GstWFDMessage ** msg)
198 {
199   GstWFDMessage *newmsg;
200
201   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
202
203   newmsg = g_new0 (GstWFDMessage, 1);
204
205   *msg = newmsg;
206
207   return gst_wfd_message_init (newmsg);
208 }
209
210 /**
211  * gst_wfd_message_init:
212  * @msg: a #GstWFDMessage
213  *
214  * Initialize @msg so that its contents are as if it was freshly allocated
215  * with gst_wfd_message_new(). This function is mostly used to initialize a message
216  * allocated on the stack. gst_wfd_message_uninit() undoes this operation.
217  *
218  * When this function is invoked on newly allocated data (with malloc or on the
219  * stack), its contents should be set to 0 before calling this function.
220  *
221  * Returns: a #GstWFDResult.
222  */
223 GstWFDResult
224 gst_wfd_message_init (GstWFDMessage * msg)
225 {
226   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
227
228   return GST_WFD_OK;
229 }
230
231 /**
232  * gst_wfd_message_uninit:
233  * @msg: a #GstWFDMessage
234  *
235  * Free all resources allocated in @msg. @msg should not be used anymore after
236  * this function. This function should be used when @msg was allocated on the
237  * stack and initialized with gst_wfd_message_init().
238  *
239  * Returns: a #GstWFDResult.
240  */
241 GstWFDResult
242 gst_wfd_message_uninit (GstWFDMessage * msg)
243 {
244   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
245
246   gst_wfd_message_init (msg);
247
248   return GST_WFD_OK;
249 }
250
251 /**
252  * gst_wfd_message_copy:
253  * @msg: a #GstWFDMessage
254  * @copy: (out) (transfer full): pointer to new #GstWFDMessage
255  *
256  * Allocate a new copy of @msg and store the result in @copy. The value in
257  * @copy should be release with gst_wfd_message_free function.
258  *
259  * Returns: a #GstWFDResult
260  *
261  * Since: 1.6
262  */
263 GstWFDResult
264 gst_wfd_message_copy (const GstWFDMessage * msg, GstWFDMessage ** copy)
265 {
266   GstWFDResult ret;
267   GstWFDMessage *cp;
268
269   if (msg == NULL)
270     return GST_WFD_EINVAL;
271
272   ret = gst_wfd_message_new (copy);
273   if (ret != GST_WFD_OK)
274     return ret;
275
276   cp = *copy;
277
278   /* TODO-WFD */
279   if (msg->client_rtp_ports) {
280     cp->client_rtp_ports = g_malloc (sizeof (GstWFDClientRtpPorts));
281     if (cp->client_rtp_ports) {
282       cp->client_rtp_ports->profile = g_strdup (msg->client_rtp_ports->profile);
283       cp->client_rtp_ports->rtp_port0 = msg->client_rtp_ports->rtp_port0;
284       cp->client_rtp_ports->rtp_port1 = msg->client_rtp_ports->rtp_port1;
285       cp->client_rtp_ports->mode = g_strdup (msg->client_rtp_ports->mode);
286     }
287   }
288
289   return GST_WFD_OK;
290 }
291
292
293 static void
294 _read_string_space_ended (gchar * dest, guint size, gchar * src)
295 {
296   guint idx = 0;
297
298   while (!g_ascii_isspace (*src) && *src != '\0') {
299     if (idx < size - 1)
300       dest[idx++] = *src;
301     src++;
302   }
303
304   if (size > 0)
305     dest[idx] = '\0';
306
307   return;
308 }
309
310 static void
311 _read_string_char_ended (gchar * dest, guint size, gchar del, gchar * src)
312 {
313   guint idx = 0;
314
315   while (*src != del && *src != '\0') {
316     if (idx < size - 1)
317       dest[idx++] = *src;
318     src++;
319   }
320
321   if (size > 0)
322     dest[idx] = '\0';
323
324   return;
325 }
326
327 static void
328 _read_string_attr_and_value (gchar * attr, gchar * value, guint tsize,
329     guint vsize, gchar del, gchar * src)
330 {
331   guint idx;
332
333   idx = 0;
334
335   while (*src != del && *src != '\0') {
336     if (idx < tsize - 1)
337       attr[idx++] = *src;
338     src++;
339   }
340
341   if (tsize > 0)
342     attr[idx] = '\0';
343
344   src++;
345   idx = 0;
346
347   while (*src != '\0') {
348     if (idx < vsize - 1)
349       value[idx++] = *src;
350     src++;
351   }
352
353   if (vsize > 0)
354     value[idx] = '\0';
355
356   return;
357 }
358
359 static void
360 gst_wfd_parse_attribute (gchar * buffer, GstWFDMessage * msg)
361 {
362   gchar attr[8192] = { 0 };
363   gchar value[8192] = { 0 };
364   gchar temp[8192] = { 0 };
365   gchar *p = buffer;
366   gchar *v = value;
367
368 #define WFD_SKIP_SPACE(q) if (*q && g_ascii_isspace (*q)) q++
369 #define WFD_SKIP_EQUAL(q) if (*q && *q == '=') q++
370 #define WFD_SKIP_COMMA(q) if (*q && g_ascii_ispunct (*q)) q++
371 #define WFD_READ_STRING(field) _read_string_space_ended (temp, sizeof (temp), v); v+=strlen(temp); REPLACE_STRING (field, temp)
372 #define WFD_READ_CHAR_END_STRING(field, del) _read_string_char_ended (temp, sizeof (temp), del, v); v+=strlen(temp); REPLACE_STRING (field, temp)
373 #define WFD_READ_UINT32(field) _read_string_space_ended (temp, sizeof (temp), v); v+=strlen(temp); field = strtoul (temp, NULL, 16)
374 #define WFD_READ_UINT32_DIGIT(field) _read_string_space_ended (temp, sizeof (temp), v); v+=strlen(temp); field = strtoul (temp, NULL, 10)
375
376   _read_string_attr_and_value (attr, value, sizeof (attr), sizeof (value), ':',
377       p);
378
379   if (!g_strcmp0 (attr, "wfd_audio_codecs")) {
380     msg->audio_codecs = g_new0 (GstWFDAudioCodeclist, 1);
381     if (strlen (v)) {
382       guint i = 0;
383       msg->audio_codecs->count = strlen (v) / 16;
384       msg->audio_codecs->list =
385           g_new0 (GstWFDAudioCodec, msg->audio_codecs->count);
386       for (; i < msg->audio_codecs->count; i++) {
387         WFD_SKIP_SPACE (v);
388         WFD_READ_STRING (msg->audio_codecs->list[i].audio_format);
389         WFD_SKIP_SPACE (v);
390         WFD_READ_UINT32 (msg->audio_codecs->list[i].modes);
391         WFD_SKIP_SPACE (v);
392         WFD_READ_UINT32 (msg->audio_codecs->list[i].latency);
393         WFD_SKIP_COMMA (v);
394       }
395     }
396   } else if (!g_strcmp0 (attr, "wfd_video_formats")) {
397     msg->video_formats = g_new0 (GstWFDVideoCodeclist, 1);
398     if (strlen (v)) {
399       msg->video_formats->count = 1;
400       msg->video_formats->list = g_new0 (GstWFDVideoCodec, 1);
401       WFD_SKIP_SPACE (v);
402       WFD_READ_UINT32 (msg->video_formats->list->native);
403       WFD_SKIP_SPACE (v);
404       WFD_READ_UINT32 (msg->video_formats->
405           list->preferred_display_mode_supported);
406       WFD_SKIP_SPACE (v);
407       WFD_READ_UINT32 (msg->video_formats->list->H264_codec.profile);
408       WFD_SKIP_SPACE (v);
409       WFD_READ_UINT32 (msg->video_formats->list->H264_codec.level);
410       WFD_SKIP_SPACE (v);
411       WFD_READ_UINT32 (msg->video_formats->list->H264_codec.
412           misc_params.CEA_Support);
413       WFD_SKIP_SPACE (v);
414       WFD_READ_UINT32 (msg->video_formats->list->H264_codec.
415           misc_params.VESA_Support);
416       WFD_SKIP_SPACE (v);
417       WFD_READ_UINT32 (msg->video_formats->list->H264_codec.
418           misc_params.HH_Support);
419       WFD_SKIP_SPACE (v);
420       WFD_READ_UINT32 (msg->video_formats->list->H264_codec.
421           misc_params.latency);
422       WFD_SKIP_SPACE (v);
423       WFD_READ_UINT32 (msg->video_formats->list->H264_codec.
424           misc_params.min_slice_size);
425       WFD_SKIP_SPACE (v);
426       WFD_READ_UINT32 (msg->video_formats->list->H264_codec.
427           misc_params.slice_enc_params);
428       WFD_SKIP_SPACE (v);
429       WFD_READ_UINT32 (msg->video_formats->list->H264_codec.
430           misc_params.frame_rate_control_support);
431       WFD_SKIP_SPACE (v);
432       if (msg->video_formats->list->preferred_display_mode_supported == 1) {
433         WFD_READ_UINT32 (msg->video_formats->list->H264_codec.max_hres);
434         WFD_SKIP_SPACE (v);
435         WFD_READ_UINT32 (msg->video_formats->list->H264_codec.max_vres);
436         WFD_SKIP_SPACE (v);
437       }
438     }
439   } else if (!g_strcmp0 (attr, "wfd_3d_formats")) {
440     msg->video_3d_formats = g_new0 (GstWFD3DFormats, 1);
441     if (strlen (v)) {
442       msg->video_3d_formats->count = 1;
443       msg->video_3d_formats->list = g_new0 (GstWFD3dCapList, 1);
444       WFD_SKIP_SPACE (v);
445       WFD_READ_UINT32 (msg->video_3d_formats->list->native);
446       WFD_SKIP_SPACE (v);
447       WFD_READ_UINT32 (msg->video_3d_formats->
448           list->preferred_display_mode_supported);
449       WFD_SKIP_SPACE (v);
450       WFD_READ_UINT32 (msg->video_3d_formats->list->H264_codec.profile);
451       WFD_SKIP_SPACE (v);
452       WFD_READ_UINT32 (msg->video_3d_formats->list->H264_codec.level);
453       WFD_SKIP_SPACE (v);
454       WFD_READ_UINT32 (msg->video_3d_formats->list->H264_codec.
455           misc_params.video_3d_capability);
456       WFD_SKIP_SPACE (v);
457       WFD_READ_UINT32 (msg->video_3d_formats->list->H264_codec.
458           misc_params.latency);
459       WFD_SKIP_SPACE (v);
460       WFD_READ_UINT32 (msg->video_3d_formats->list->H264_codec.
461           misc_params.min_slice_size);
462       WFD_SKIP_SPACE (v);
463       WFD_READ_UINT32 (msg->video_3d_formats->list->H264_codec.
464           misc_params.slice_enc_params);
465       WFD_SKIP_SPACE (v);
466       WFD_READ_UINT32 (msg->video_3d_formats->list->H264_codec.
467           misc_params.frame_rate_control_support);
468       WFD_SKIP_SPACE (v);
469       if (msg->video_formats->list->preferred_display_mode_supported == 1) {
470         WFD_READ_UINT32 (msg->video_formats->list->H264_codec.max_hres);
471         WFD_SKIP_SPACE (v);
472         WFD_READ_UINT32 (msg->video_formats->list->H264_codec.max_vres);
473         WFD_SKIP_SPACE (v);
474       }
475     }
476   } else if (!g_strcmp0 (attr, "wfd_content_protection")) {
477     msg->content_protection = g_new0 (GstWFDContentProtection, 1);
478     if (strlen (v)) {
479       WFD_SKIP_SPACE (v);
480       msg->content_protection->hdcp2_spec = g_new0 (GstWFDHdcp2Spec, 1);
481       if (strstr (v, "none")) {
482         msg->content_protection->hdcp2_spec->hdcpversion = g_strdup ("none");
483       } else {
484         WFD_READ_STRING (msg->content_protection->hdcp2_spec->hdcpversion);
485         WFD_SKIP_SPACE (v);
486         WFD_READ_STRING (msg->content_protection->hdcp2_spec->TCPPort);
487       }
488     }
489   } else if (!g_strcmp0 (attr, "wfd_display_edid")) {
490     msg->display_edid = g_new0 (GstWFDDisplayEdid, 1);
491     if (strlen (v)) {
492       WFD_SKIP_SPACE (v);
493       if (strstr (v, "none")) {
494         msg->display_edid->edid_supported = 0;
495       } else {
496         msg->display_edid->edid_supported = 1;
497         WFD_READ_UINT32 (msg->display_edid->edid_block_count);
498         WFD_SKIP_SPACE (v);
499         if (msg->display_edid->edid_block_count) {
500           gchar *edid_string = v;
501           int i = 0, j = 0;
502           guint32 payload_size =
503               EDID_BLOCK_SIZE * msg->display_edid->edid_block_count;
504           msg->display_edid->edid_payload = g_malloc (payload_size);
505           for (;
506               i < (EDID_BLOCK_SIZE * msg->display_edid->edid_block_count * 2);
507               j++) {
508             int k = 0, kk = 0;
509             if (edid_string[i] > 0x29 && edid_string[i] < 0x40)
510               k = edid_string[i] - 48;
511             else if (edid_string[i] > 0x60 && edid_string[i] < 0x67)
512               k = edid_string[i] - 87;
513             else if (edid_string[i] > 0x40 && edid_string[i] < 0x47)
514               k = edid_string[i] - 55;
515
516             if (edid_string[i + 1] > 0x29 && edid_string[i + 1] < 0x40)
517               kk = edid_string[i + 1] - 48;
518             else if (edid_string[i + 1] > 0x60 && edid_string[i + 1] < 0x67)
519               kk = edid_string[i + 1] - 87;
520             else if (edid_string[i + 1] > 0x40 && edid_string[i + 1] < 0x47)
521               kk = edid_string[i + 1] - 55;
522
523             msg->display_edid->edid_payload[j] = (k << 4) | kk;
524             i += 2;
525           }
526           //memcpy(msg->display_edid->edid_payload, v, payload_size);
527           v += (payload_size * 2);
528         } else
529           v += strlen (v);
530       }
531     }
532   } else if (!g_strcmp0 (attr, "wfd_coupled_sink")) {
533     msg->coupled_sink = g_new0 (GstWFDCoupledSink, 1);
534     if (strlen (v)) {
535       msg->coupled_sink->coupled_sink_cap = g_new0 (GstWFDCoupled_sink_cap, 1);
536       WFD_SKIP_SPACE (v);
537       WFD_READ_UINT32 (msg->coupled_sink->coupled_sink_cap->status);
538       WFD_SKIP_SPACE (v);
539       WFD_READ_STRING (msg->coupled_sink->coupled_sink_cap->sink_address);
540     }
541   } else if (!g_strcmp0 (attr, "wfd_trigger_method")) {
542     msg->trigger_method = g_new0 (GstWFDTriggerMethod, 1);
543     if (strlen (v)) {
544       WFD_SKIP_SPACE (v);
545       WFD_READ_STRING (msg->trigger_method->wfd_trigger_method);
546     }
547   } else if (!g_strcmp0 (attr, "wfd_presentation_URL")) {
548     msg->presentation_url = g_new0 (GstWFDPresentationUrl, 1);
549     if (strlen (v)) {
550       WFD_SKIP_SPACE (v);
551       WFD_READ_STRING (msg->presentation_url->wfd_url0);
552       WFD_SKIP_SPACE (v);
553       WFD_READ_STRING (msg->presentation_url->wfd_url1);
554     }
555   } else if (!g_strcmp0 (attr, "wfd_client_rtp_ports")) {
556     msg->client_rtp_ports = g_new0 (GstWFDClientRtpPorts, 1);
557     if (strlen (v)) {
558       WFD_SKIP_SPACE (v);
559       WFD_READ_STRING (msg->client_rtp_ports->profile);
560       WFD_SKIP_SPACE (v);
561       WFD_READ_UINT32_DIGIT (msg->client_rtp_ports->rtp_port0);
562       WFD_SKIP_SPACE (v);
563       WFD_READ_UINT32_DIGIT (msg->client_rtp_ports->rtp_port1);
564       WFD_SKIP_SPACE (v);
565       WFD_READ_STRING (msg->client_rtp_ports->mode);
566     }
567   } else if (!g_strcmp0 (attr, "wfd_route")) {
568     msg->route = g_new0 (GstWFDRoute, 1);
569     if (strlen (v)) {
570       WFD_SKIP_SPACE (v);
571       WFD_READ_STRING (msg->route->destination);
572     }
573   } else if (!g_strcmp0 (attr, "wfd_I2C")) {
574     msg->I2C = g_new0 (GstWFDI2C, 1);
575     if (strlen (v)) {
576       msg->I2C->I2CPresent = TRUE;
577       WFD_SKIP_SPACE (v);
578       WFD_READ_UINT32_DIGIT (msg->I2C->I2C_port);
579       if (msg->I2C->I2C_port)
580         msg->I2C->I2CPresent = TRUE;
581     }
582   } else if (!g_strcmp0 (attr, "wfd_av_format_change_timing")) {
583     msg->av_format_change_timing = g_new0 (GstWFDAVFormatChangeTiming, 1);
584     if (strlen (v)) {
585       WFD_SKIP_SPACE (v);
586       WFD_READ_UINT32 (msg->av_format_change_timing->PTS);
587       WFD_SKIP_SPACE (v);
588       WFD_READ_UINT32 (msg->av_format_change_timing->DTS);
589     }
590   } else if (!g_strcmp0 (attr, "wfd_preferred_display_mode")) {
591     msg->preferred_display_mode = g_new0 (GstWFDPreferredDisplayMode, 1);
592     if (strlen (v)) {
593       WFD_SKIP_SPACE (v);
594       if (!strstr (v, "none")) {
595         msg->preferred_display_mode->displaymodesupported = FALSE;
596       } else {
597         WFD_READ_UINT32 (msg->preferred_display_mode->p_clock);
598         WFD_SKIP_SPACE (v);
599         WFD_READ_UINT32 (msg->preferred_display_mode->H);
600         WFD_SKIP_SPACE (v);
601         WFD_READ_UINT32 (msg->preferred_display_mode->HB);
602         WFD_SKIP_SPACE (v);
603         WFD_READ_UINT32 (msg->preferred_display_mode->HSPOL_HSOFF);
604         WFD_SKIP_SPACE (v);
605         WFD_READ_UINT32 (msg->preferred_display_mode->HSW);
606         WFD_SKIP_SPACE (v);
607         WFD_READ_UINT32 (msg->preferred_display_mode->V);
608         WFD_SKIP_SPACE (v);
609         WFD_READ_UINT32 (msg->preferred_display_mode->VB);
610         WFD_SKIP_SPACE (v);
611         WFD_READ_UINT32 (msg->preferred_display_mode->VSPOL_VSOFF);
612         WFD_SKIP_SPACE (v);
613         WFD_READ_UINT32 (msg->preferred_display_mode->VSW);
614         WFD_SKIP_SPACE (v);
615         WFD_READ_UINT32 (msg->preferred_display_mode->VBS3D);
616         WFD_SKIP_SPACE (v);
617         WFD_READ_UINT32 (msg->preferred_display_mode->V2d_s3d_modes);
618         WFD_SKIP_SPACE (v);
619         WFD_READ_UINT32 (msg->preferred_display_mode->P_depth);
620         WFD_SKIP_SPACE (v);
621         WFD_READ_UINT32 (msg->preferred_display_mode->H264_codec.profile);
622         WFD_SKIP_SPACE (v);
623         WFD_READ_UINT32 (msg->preferred_display_mode->H264_codec.level);
624         WFD_SKIP_SPACE (v);
625         WFD_READ_UINT32 (msg->preferred_display_mode->H264_codec.
626             misc_params.CEA_Support);
627         WFD_SKIP_SPACE (v);
628         WFD_READ_UINT32 (msg->preferred_display_mode->H264_codec.
629             misc_params.VESA_Support);
630         WFD_SKIP_SPACE (v);
631         WFD_READ_UINT32 (msg->preferred_display_mode->H264_codec.
632             misc_params.HH_Support);
633         WFD_SKIP_SPACE (v);
634         WFD_READ_UINT32 (msg->preferred_display_mode->H264_codec.
635             misc_params.latency);
636         WFD_SKIP_SPACE (v);
637         WFD_READ_UINT32 (msg->preferred_display_mode->H264_codec.
638             misc_params.min_slice_size);
639         WFD_SKIP_SPACE (v);
640         WFD_READ_UINT32 (msg->preferred_display_mode->H264_codec.
641             misc_params.slice_enc_params);
642         WFD_SKIP_SPACE (v);
643         WFD_READ_UINT32 (msg->preferred_display_mode->H264_codec.
644             misc_params.frame_rate_control_support);
645         WFD_SKIP_SPACE (v);
646         WFD_READ_UINT32 (msg->preferred_display_mode->H264_codec.max_hres);
647         WFD_SKIP_SPACE (v);
648         WFD_READ_UINT32 (msg->preferred_display_mode->H264_codec.max_vres);
649         WFD_SKIP_SPACE (v);
650       }
651     }
652   } else if (!g_strcmp0 (attr, "wfd_uibc_capability")) {
653     msg->uibc_capability = g_new0 (GstWFDUibcCapability, 1);
654     if (strstr (v, "input_category_list")) {
655       gchar *tstring = NULL;
656       msg->uibc_capability->uibcsupported = TRUE;
657       WFD_SKIP_SPACE (v);
658       WFD_READ_CHAR_END_STRING (tstring, '=');
659       if (!g_strcmp0 (tstring, "input_category_list")) {
660         gchar temp[8192];
661         guint rem_len, read_len = 0;
662         WFD_READ_CHAR_END_STRING (tstring, ';');
663         rem_len = strlen (tstring);
664         do {
665           WFD_SKIP_SPACE (v);
666           _read_string_char_ended (temp, 8192, ',', tstring + read_len);
667           read_len += (strlen (temp) + 1);
668           if (strstr (temp, "GENERIC"))
669             msg->uibc_capability->input_category_list.input_cat |=
670                 GST_WFD_UIBC_INPUT_CAT_GENERIC;
671           else if (strstr (temp, "HIDC"))
672             msg->uibc_capability->input_category_list.input_cat |=
673                 GST_WFD_UIBC_INPUT_CAT_HIDC;
674           else
675             msg->uibc_capability->input_category_list.input_cat |=
676                 GST_WFD_UIBC_INPUT_CAT_UNKNOWN;
677         } while (read_len < rem_len);
678         v = strstr (v, "generic_cap_list");
679         WFD_READ_CHAR_END_STRING (tstring, '=');
680         if (!g_strcmp0 (tstring, "generic_cap_list")) {
681           gchar temp[8192];
682           guint rem_len, read_len = 0;
683           WFD_SKIP_SPACE (v);
684           WFD_READ_CHAR_END_STRING (tstring, ';');
685           rem_len = strlen (tstring);
686           do {
687             _read_string_char_ended (temp, 8192, ',', tstring + read_len);
688             read_len += (strlen (temp) + 1);
689             if (strstr (temp, "Keyboard"))
690               msg->uibc_capability->generic_cap_list.inp_type |=
691                   GST_WFD_UIBC_INPUT_TYPE_KEYBOARD;
692             else if (strstr (temp, "Mouse"))
693               msg->uibc_capability->generic_cap_list.inp_type |=
694                   GST_WFD_UIBC_INPUT_TYPE_MOUSE;
695             else if (strstr (temp, "SingleTouch"))
696               msg->uibc_capability->generic_cap_list.inp_type |=
697                   GST_WFD_UIBC_INPUT_TYPE_SINGLETOUCH;
698             else if (strstr (temp, "MultiTouch"))
699               msg->uibc_capability->generic_cap_list.inp_type |=
700                   GST_WFD_UIBC_INPUT_TYPE_MULTITOUCH;
701             else if (strstr (temp, "Joystick"))
702               msg->uibc_capability->generic_cap_list.inp_type |=
703                   GST_WFD_UIBC_INPUT_TYPE_JOYSTICK;
704             else if (strstr (temp, "Camera"))
705               msg->uibc_capability->generic_cap_list.inp_type |=
706                   GST_WFD_UIBC_INPUT_TYPE_CAMERA;
707             else if (strstr (temp, "Gesture"))
708               msg->uibc_capability->generic_cap_list.inp_type |=
709                   GST_WFD_UIBC_INPUT_TYPE_GESTURE;
710             else if (strstr (temp, "RemoteControl"))
711               msg->uibc_capability->generic_cap_list.inp_type |=
712                   GST_WFD_UIBC_INPUT_TYPE_REMOTECONTROL;
713             else
714               msg->uibc_capability->generic_cap_list.inp_type |=
715                   GST_WFD_UIBC_INPUT_TYPE_UNKNOWN;
716           } while (read_len < rem_len);
717         }
718         v = strstr (v, "hidc_cap_list");
719         WFD_SKIP_SPACE (v);
720         WFD_READ_CHAR_END_STRING (tstring, '=');
721         if (!g_strcmp0 (tstring, "hidc_cap_list")) {
722           gchar temp[8192];
723           gchar inp_type[8192];
724           gchar inp_path[8192];
725           guint rem_len, read_len = 0;
726           detailed_cap *temp_cap;
727           WFD_READ_CHAR_END_STRING (tstring, ';');
728           rem_len = strlen (tstring);
729           msg->uibc_capability->hidc_cap_list.next = g_new0 (detailed_cap, 1);
730           temp_cap = msg->uibc_capability->hidc_cap_list.next;
731           do {
732             msg->uibc_capability->hidc_cap_list.cap_count++;
733             _read_string_char_ended (temp, 8192, ',', tstring + read_len);
734             read_len += (strlen (temp) + 1);
735             _read_string_attr_and_value (inp_type, inp_path, sizeof (inp_type),
736                 sizeof (inp_path), '/', temp);
737             if (strstr (inp_type, "Keyboard"))
738               temp_cap->p.inp_type = GST_WFD_UIBC_INPUT_TYPE_KEYBOARD;
739             else if (strstr (inp_type, "Mouse"))
740               temp_cap->p.inp_type = GST_WFD_UIBC_INPUT_TYPE_MOUSE;
741             else if (strstr (inp_type, "SingleTouch"))
742               temp_cap->p.inp_type = GST_WFD_UIBC_INPUT_TYPE_SINGLETOUCH;
743             else if (strstr (inp_type, "MultiTouch"))
744               temp_cap->p.inp_type = GST_WFD_UIBC_INPUT_TYPE_MULTITOUCH;
745             else if (strstr (inp_type, "Joystick"))
746               temp_cap->p.inp_type = GST_WFD_UIBC_INPUT_TYPE_JOYSTICK;
747             else if (strstr (inp_type, "Camera"))
748               temp_cap->p.inp_type = GST_WFD_UIBC_INPUT_TYPE_CAMERA;
749             else if (strstr (inp_type, "Gesture"))
750               temp_cap->p.inp_type = GST_WFD_UIBC_INPUT_TYPE_GESTURE;
751             else if (strstr (inp_type, "RemoteControl"))
752               temp_cap->p.inp_type = GST_WFD_UIBC_INPUT_TYPE_REMOTECONTROL;
753             else
754               temp_cap->p.inp_type = GST_WFD_UIBC_INPUT_TYPE_UNKNOWN;
755
756             if (strstr (inp_path, "Infrared"))
757               temp_cap->p.inp_path = GST_WFD_UIBC_INPUT_PATH_INFRARED;
758             else if (strstr (inp_path, "USB"))
759               temp_cap->p.inp_path = GST_WFD_UIBC_INPUT_PATH_USB;
760             else if (strstr (inp_path, "BT"))
761               temp_cap->p.inp_path = GST_WFD_UIBC_INPUT_PATH_BT;
762             else if (strstr (inp_path, "Zigbee"))
763               temp_cap->p.inp_path = GST_WFD_UIBC_INPUT_PATH_ZIGBEE;
764             else if (strstr (inp_path, "Wi-Fi"))
765               temp_cap->p.inp_path = GST_WFD_UIBC_INPUT_PATH_WIFI;
766             else if (strstr (inp_path, "No-SP"))
767               temp_cap->p.inp_path = GST_WFD_UIBC_INPUT_PATH_NOSP;
768             else
769               temp_cap->p.inp_path = GST_WFD_UIBC_INPUT_PATH_UNKNOWN;
770             if (read_len < rem_len) {
771               temp_cap->next = g_new0 (detailed_cap, 1);
772               temp_cap = temp_cap->next;
773             }
774           } while (read_len < rem_len);
775         }
776         if (strstr (v, "port")) {
777           v = strstr (v, "port");
778           WFD_READ_CHAR_END_STRING (tstring, '=');
779           if (!g_strcmp0 (tstring, "port")) {
780             WFD_SKIP_EQUAL (v);
781             WFD_READ_CHAR_END_STRING (tstring, ';');
782             if (!strstr (tstring, "none")) {
783               msg->uibc_capability->tcp_port = strtoul (tstring, NULL, 10);
784             }
785           }
786         }
787       }
788     } else if (strstr (v, "none")) {
789       msg->uibc_capability->uibcsupported = FALSE;
790     }
791   } else if (!g_strcmp0 (attr, "wfd_uibc_setting")) {
792     msg->uibc_setting = g_new0 (GstWFDUibcSetting, 1);
793     if (strlen (v)) {
794       WFD_SKIP_SPACE (v);
795       if (!g_strcmp0 (v, "enable"))
796         msg->uibc_setting->uibc_setting = TRUE;
797       else
798         msg->uibc_setting->uibc_setting = FALSE;
799     }
800   } else if (!g_strcmp0 (attr, "wfd_standby_resume_capability")) {
801     msg->standby_resume_capability = g_new0 (GstWFDStandbyResumeCapability, 1);
802     if (strlen (v)) {
803       WFD_SKIP_SPACE (v);
804       if (!g_strcmp0 (v, "supported"))
805         msg->standby_resume_capability->standby_resume_cap = TRUE;
806       else
807         msg->standby_resume_capability->standby_resume_cap = FALSE;
808     }
809   } else if (!g_strcmp0 (attr, "wfd_standby")) {
810     msg->standby = g_new0 (GstWFDStandby, 1);
811     msg->standby->wfd_standby = TRUE;
812   } else if (!g_strcmp0 (attr, "wfd_connector_type")) {
813     msg->connector_type = g_new0 (GstWFDConnectorType, 1);
814     if (strlen (v)) {
815       msg->connector_type->supported = TRUE;
816       WFD_SKIP_SPACE (v);
817       WFD_READ_UINT32 (msg->connector_type->connector_type);
818     }
819   } else if (!g_strcmp0 (attr, "wfd_idr_request")) {
820     msg->idr_request = g_new0 (GstWFDIdrRequest, 1);
821     msg->idr_request->idr_request = TRUE;
822   }
823   return;
824 }
825
826 /**
827  * gst_wfd_message_parse_buffer:
828  * @data: the start of the buffer
829  * @size: the size of the buffer
830  * @msg: the result #GstSDPMessage
831  *
832  * Parse the contents of @size bytes pointed to by @data and store the result in
833  * @msg.
834  *
835  * Returns: #GST_SDP_OK on success.
836  */
837 GstWFDResult
838 gst_wfd_message_parse_buffer (const guint8 * data, guint size,
839     GstWFDMessage * msg)
840 {
841   gchar *p;
842   gchar buffer[255] = { 0 };
843   guint idx = 0;
844
845   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
846   g_return_val_if_fail (data != NULL, GST_WFD_EINVAL);
847   g_return_val_if_fail (size != 0, GST_WFD_EINVAL);
848
849   p = (gchar *) data;
850   while (TRUE) {
851
852     if (*p == '\0')
853       break;
854
855     idx = 0;
856     while (*p != '\n' && *p != '\r' && *p != '\0') {
857       if (idx < sizeof (buffer) - 1)
858         buffer[idx++] = *p;
859       p++;
860     }
861     buffer[idx] = '\0';
862     gst_wfd_parse_attribute (buffer, msg);
863
864     if (*p == '\0')
865       break;
866     p += 2;
867   }
868   return GST_WFD_OK;
869 }
870
871 /**
872  * gst_wfd_message_free:
873  * @msg: a #GstWFDMessage
874  *
875  * Free all resources allocated by @msg. @msg should not be used anymore after
876  * this function. This function should be used when @msg was dynamically
877  * allocated with gst_wfd_message_new().
878  *
879  * Returns: a #GstWFDResult.
880  */
881 GstWFDResult
882 gst_wfd_message_free (GstWFDMessage * msg)
883 {
884   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
885
886   gst_wfd_message_uninit (msg);
887   g_free (msg);
888
889   return GST_WFD_OK;
890 }
891
892 /**
893  * gst_wfd_message_as_text:
894  * @msg: a #GstWFDMessage
895  *
896  * Convert the contents of @msg to a text string.
897  *
898  * Returns: A dynamically allocated string representing the WFD description.
899  */
900 gchar *
901 gst_wfd_message_as_text (const GstWFDMessage * msg)
902 {
903   /* change all vars so they match rfc? */
904   GString *lines;
905   guint i;
906
907   g_return_val_if_fail (msg != NULL, NULL);
908
909   lines = g_string_new ("");
910
911   /* list of audio codecs */
912   if (msg->audio_codecs) {
913     g_string_append_printf (lines, "wfd_audio_codecs");
914     if (msg->audio_codecs->list) {
915       g_string_append_printf (lines, ":");
916       for (i = 0; i < msg->audio_codecs->count; i++) {
917         g_string_append_printf (lines, " %s",
918             msg->audio_codecs->list[i].audio_format);
919         g_string_append_printf (lines, " %08x",
920             msg->audio_codecs->list[i].modes);
921         g_string_append_printf (lines, " %02x",
922             msg->audio_codecs->list[i].latency);
923         if ((i + 1) < msg->audio_codecs->count)
924           g_string_append_printf (lines, ",");
925       }
926     }
927     g_string_append_printf (lines, "\r\n");
928   }
929
930   /* list of video codecs */
931   if (msg->video_formats) {
932     g_string_append_printf (lines, "wfd_video_formats");
933     if (msg->video_formats->list) {
934       g_string_append_printf (lines, ":");
935       g_string_append_printf (lines, " %02x", msg->video_formats->list->native);
936       g_string_append_printf (lines, " %02x",
937           msg->video_formats->list->preferred_display_mode_supported);
938       g_string_append_printf (lines, " %02x",
939           msg->video_formats->list->H264_codec.profile);
940       g_string_append_printf (lines, " %02x",
941           msg->video_formats->list->H264_codec.level);
942       g_string_append_printf (lines, " %08x",
943           msg->video_formats->list->H264_codec.misc_params.CEA_Support);
944       g_string_append_printf (lines, " %08x",
945           msg->video_formats->list->H264_codec.misc_params.VESA_Support);
946       g_string_append_printf (lines, " %08x",
947           msg->video_formats->list->H264_codec.misc_params.HH_Support);
948       g_string_append_printf (lines, " %02x",
949           msg->video_formats->list->H264_codec.misc_params.latency);
950       g_string_append_printf (lines, " %04x",
951           msg->video_formats->list->H264_codec.misc_params.min_slice_size);
952       g_string_append_printf (lines, " %04x",
953           msg->video_formats->list->H264_codec.misc_params.slice_enc_params);
954       g_string_append_printf (lines, " %02x",
955           msg->video_formats->list->H264_codec.
956           misc_params.frame_rate_control_support);
957
958       if (msg->video_formats->list->H264_codec.max_hres)
959         g_string_append_printf (lines, " %04x",
960             msg->video_formats->list->H264_codec.max_hres);
961       else
962         g_string_append_printf (lines, " none");
963
964       if (msg->video_formats->list->H264_codec.max_vres)
965         g_string_append_printf (lines, " %04x",
966             msg->video_formats->list->H264_codec.max_vres);
967       else
968         g_string_append_printf (lines, " none");
969     }
970     g_string_append_printf (lines, "\r\n");
971   }
972
973   /* list of video 3D codecs */
974   if (msg->video_3d_formats) {
975     g_string_append_printf (lines, "wfd_3d_video_formats");
976     g_string_append_printf (lines, ":");
977     if (msg->video_3d_formats->list) {
978       g_string_append_printf (lines, " %02x",
979           msg->video_3d_formats->list->native);
980       g_string_append_printf (lines, " %02x",
981           msg->video_3d_formats->list->preferred_display_mode_supported);
982       g_string_append_printf (lines, " %02x",
983           msg->video_3d_formats->list->H264_codec.profile);
984       g_string_append_printf (lines, " %02x",
985           msg->video_3d_formats->list->H264_codec.level);
986       g_string_append_printf (lines, " %16x",
987           msg->video_3d_formats->list->H264_codec.
988           misc_params.video_3d_capability);
989       g_string_append_printf (lines, " %02x",
990           msg->video_3d_formats->list->H264_codec.misc_params.latency);
991       g_string_append_printf (lines, " %04x",
992           msg->video_3d_formats->list->H264_codec.misc_params.min_slice_size);
993       g_string_append_printf (lines, " %04x",
994           msg->video_3d_formats->list->H264_codec.misc_params.slice_enc_params);
995       g_string_append_printf (lines, " %02x",
996           msg->video_3d_formats->list->H264_codec.
997           misc_params.frame_rate_control_support);
998       if (msg->video_3d_formats->list->H264_codec.max_hres)
999         g_string_append_printf (lines, " %04x",
1000             msg->video_formats->list->H264_codec.max_hres);
1001       else
1002         g_string_append_printf (lines, " none");
1003       if (msg->video_3d_formats->list->H264_codec.max_vres)
1004         g_string_append_printf (lines, " %04x",
1005             msg->video_formats->list->H264_codec.max_vres);
1006       else
1007         g_string_append_printf (lines, " none");
1008     } else {
1009       g_string_append_printf (lines, " none");
1010     }
1011     g_string_append_printf (lines, "\r\n");
1012   }
1013
1014   if (msg->content_protection) {
1015     g_string_append_printf (lines, "wfd_content_protection");
1016     g_string_append_printf (lines, ":");
1017     if (msg->content_protection->hdcp2_spec) {
1018       if (msg->content_protection->hdcp2_spec->hdcpversion) {
1019         g_string_append_printf (lines, " %s",
1020             msg->content_protection->hdcp2_spec->hdcpversion);
1021         g_string_append_printf (lines, " %s",
1022             msg->content_protection->hdcp2_spec->TCPPort);
1023       } else {
1024         g_string_append_printf (lines, " none");
1025       }
1026     } else {
1027       g_string_append_printf (lines, " none");
1028     }
1029     g_string_append_printf (lines, "\r\n");
1030   }
1031
1032   if (msg->display_edid) {
1033     g_string_append_printf (lines, "wfd_display_edid");
1034     g_string_append_printf (lines, ":");
1035     if (msg->display_edid->edid_supported) {
1036       g_string_append_printf (lines, " %d", msg->display_edid->edid_supported);
1037       if (msg->display_edid->edid_block_count)
1038         g_string_append_printf (lines, " %d",
1039             msg->display_edid->edid_block_count);
1040       else
1041         g_string_append_printf (lines, " none");
1042     } else {
1043       g_string_append_printf (lines, " none");
1044     }
1045     g_string_append_printf (lines, "\r\n");
1046   }
1047
1048   if (msg->coupled_sink) {
1049     g_string_append_printf (lines, "wfd_coupled_sink");
1050     g_string_append_printf (lines, ":");
1051     if (msg->coupled_sink->coupled_sink_cap) {
1052       g_string_append_printf (lines, " %02x",
1053           msg->coupled_sink->coupled_sink_cap->status);
1054       if (msg->coupled_sink->coupled_sink_cap->sink_address)
1055         g_string_append_printf (lines, " %s",
1056             msg->coupled_sink->coupled_sink_cap->sink_address);
1057       else
1058         g_string_append_printf (lines, " none");
1059     } else {
1060       g_string_append_printf (lines, " none");
1061     }
1062     g_string_append_printf (lines, "\r\n");
1063   }
1064
1065   if (msg->trigger_method) {
1066     g_string_append_printf (lines, "wfd_trigger_method");
1067     g_string_append_printf (lines, ":");
1068     g_string_append_printf (lines, " %s",
1069         msg->trigger_method->wfd_trigger_method);
1070     g_string_append_printf (lines, "\r\n");
1071   }
1072
1073   if (msg->presentation_url) {
1074     g_string_append_printf (lines, "wfd_presentation_URL");
1075     g_string_append_printf (lines, ":");
1076     if (msg->presentation_url->wfd_url0)
1077       g_string_append_printf (lines, " %s", msg->presentation_url->wfd_url0);
1078     else
1079       g_string_append_printf (lines, " none");
1080     if (msg->presentation_url->wfd_url1)
1081       g_string_append_printf (lines, " %s", msg->presentation_url->wfd_url1);
1082     else
1083       g_string_append_printf (lines, " none");
1084     g_string_append_printf (lines, "\r\n");
1085   }
1086
1087   if (msg->client_rtp_ports) {
1088     g_string_append_printf (lines, "wfd_client_rtp_ports");
1089     if (msg->client_rtp_ports->profile) {
1090       g_string_append_printf (lines, ":");
1091       g_string_append_printf (lines, " %s", msg->client_rtp_ports->profile);
1092       g_string_append_printf (lines, " %d", msg->client_rtp_ports->rtp_port0);
1093       g_string_append_printf (lines, " %d", msg->client_rtp_ports->rtp_port1);
1094       g_string_append_printf (lines, " %s", msg->client_rtp_ports->mode);
1095     }
1096     g_string_append_printf (lines, "\r\n");
1097   }
1098
1099   if (msg->route) {
1100     g_string_append_printf (lines, "wfd_route");
1101     g_string_append_printf (lines, ":");
1102     g_string_append_printf (lines, " %s", msg->route->destination);
1103     g_string_append_printf (lines, "\r\n");
1104   }
1105
1106   if (msg->I2C) {
1107     g_string_append_printf (lines, "wfd_I2C");
1108     g_string_append_printf (lines, ":");
1109     if (msg->I2C->I2CPresent)
1110       g_string_append_printf (lines, " %x", msg->I2C->I2C_port);
1111     else
1112       g_string_append_printf (lines, " none");
1113     g_string_append_printf (lines, "\r\n");
1114   }
1115
1116   if (msg->av_format_change_timing) {
1117     g_string_append_printf (lines, "wfd_av_format_change_timing");
1118     g_string_append_printf (lines, ":");
1119     g_string_append_printf (lines, " %10llu",
1120         msg->av_format_change_timing->PTS);
1121     g_string_append_printf (lines, " %10llu",
1122         msg->av_format_change_timing->DTS);
1123     g_string_append_printf (lines, "\r\n");
1124   }
1125
1126   if (msg->preferred_display_mode) {
1127     g_string_append_printf (lines, "wfd_preferred_display_mode");
1128     g_string_append_printf (lines, ":");
1129     if (msg->preferred_display_mode->displaymodesupported) {
1130       g_string_append_printf (lines, " %06llu",
1131           msg->preferred_display_mode->p_clock);
1132       g_string_append_printf (lines, " %04x", msg->preferred_display_mode->H);
1133       g_string_append_printf (lines, " %04x", msg->preferred_display_mode->HB);
1134       g_string_append_printf (lines, " %04x",
1135           msg->preferred_display_mode->HSPOL_HSOFF);
1136       g_string_append_printf (lines, " %04x", msg->preferred_display_mode->HSW);
1137       g_string_append_printf (lines, " %04x", msg->preferred_display_mode->V);
1138       g_string_append_printf (lines, " %04x", msg->preferred_display_mode->VB);
1139       g_string_append_printf (lines, " %04x",
1140           msg->preferred_display_mode->VSPOL_VSOFF);
1141       g_string_append_printf (lines, " %04x", msg->preferred_display_mode->VSW);
1142       g_string_append_printf (lines, " %02x",
1143           msg->preferred_display_mode->VBS3D);
1144       g_string_append_printf (lines, " %02x",
1145           msg->preferred_display_mode->V2d_s3d_modes);
1146       g_string_append_printf (lines, " %02x",
1147           msg->preferred_display_mode->P_depth);
1148     } else
1149       g_string_append_printf (lines, " none");
1150     g_string_append_printf (lines, "\r\n");
1151   }
1152
1153   if (msg->uibc_capability) {
1154     g_string_append_printf (lines, "wfd_uibc_capability");
1155     g_string_append_printf (lines, ":");
1156     if (msg->uibc_capability->uibcsupported) {
1157       g_string_append_printf (lines, " input_category_list=");
1158       if (msg->uibc_capability->input_category_list.input_cat) {
1159         guint32 tempcap = 0;
1160         if (msg->uibc_capability->
1161             input_category_list.input_cat & GST_WFD_UIBC_INPUT_CAT_GENERIC) {
1162           tempcap |= GST_WFD_UIBC_INPUT_CAT_GENERIC;
1163           g_string_append_printf (lines, "GENERIC");
1164           if (msg->uibc_capability->input_category_list.input_cat != tempcap)
1165             g_string_append_printf (lines, ", ");
1166         }
1167         if (msg->uibc_capability->
1168             input_category_list.input_cat & GST_WFD_UIBC_INPUT_CAT_HIDC) {
1169           tempcap |= GST_WFD_UIBC_INPUT_CAT_HIDC;
1170           g_string_append_printf (lines, "HIDC");
1171           if (msg->uibc_capability->input_category_list.input_cat != tempcap)
1172             g_string_append_printf (lines, ", ");
1173         }
1174       } else
1175         g_string_append_printf (lines, "none");
1176       g_string_append_printf (lines, ";");
1177       g_string_append_printf (lines, " generic_cap_list=");
1178       if (msg->uibc_capability->generic_cap_list.inp_type) {
1179         guint32 tempcap = 0;
1180         if (msg->uibc_capability->
1181             generic_cap_list.inp_type & GST_WFD_UIBC_INPUT_TYPE_KEYBOARD) {
1182           tempcap |= GST_WFD_UIBC_INPUT_TYPE_KEYBOARD;
1183           g_string_append_printf (lines, "Keyboard");
1184           if (msg->uibc_capability->generic_cap_list.inp_type != tempcap)
1185             g_string_append_printf (lines, ", ");
1186         }
1187         if (msg->uibc_capability->
1188             generic_cap_list.inp_type & GST_WFD_UIBC_INPUT_TYPE_MOUSE) {
1189           tempcap |= GST_WFD_UIBC_INPUT_TYPE_MOUSE;
1190           g_string_append_printf (lines, "Mouse");
1191           if (msg->uibc_capability->generic_cap_list.inp_type != tempcap)
1192             g_string_append_printf (lines, ", ");
1193         }
1194         if (msg->uibc_capability->
1195             generic_cap_list.inp_type & GST_WFD_UIBC_INPUT_TYPE_SINGLETOUCH) {
1196           tempcap |= GST_WFD_UIBC_INPUT_TYPE_SINGLETOUCH;
1197           g_string_append_printf (lines, "SingleTouch");
1198           if (msg->uibc_capability->generic_cap_list.inp_type != tempcap)
1199             g_string_append_printf (lines, ", ");
1200         }
1201         if (msg->uibc_capability->
1202             generic_cap_list.inp_type & GST_WFD_UIBC_INPUT_TYPE_MULTITOUCH) {
1203           tempcap |= GST_WFD_UIBC_INPUT_TYPE_MULTITOUCH;
1204           g_string_append_printf (lines, "MultiTouch");
1205           if (msg->uibc_capability->generic_cap_list.inp_type != tempcap)
1206             g_string_append_printf (lines, ", ");
1207         }
1208         if (msg->uibc_capability->
1209             generic_cap_list.inp_type & GST_WFD_UIBC_INPUT_TYPE_JOYSTICK) {
1210           tempcap |= GST_WFD_UIBC_INPUT_TYPE_JOYSTICK;
1211           g_string_append_printf (lines, "Joystick");
1212           if (msg->uibc_capability->generic_cap_list.inp_type != tempcap)
1213             g_string_append_printf (lines, ", ");
1214         }
1215         if (msg->uibc_capability->
1216             generic_cap_list.inp_type & GST_WFD_UIBC_INPUT_TYPE_CAMERA) {
1217           tempcap |= GST_WFD_UIBC_INPUT_TYPE_CAMERA;
1218           g_string_append_printf (lines, "Camera");
1219           if (msg->uibc_capability->generic_cap_list.inp_type != tempcap)
1220             g_string_append_printf (lines, ", ");
1221         }
1222         if (msg->uibc_capability->
1223             generic_cap_list.inp_type & GST_WFD_UIBC_INPUT_TYPE_GESTURE) {
1224           tempcap |= GST_WFD_UIBC_INPUT_TYPE_GESTURE;
1225           g_string_append_printf (lines, "Gesture");
1226           if (msg->uibc_capability->generic_cap_list.inp_type != tempcap)
1227             g_string_append_printf (lines, ", ");
1228         }
1229         if (msg->uibc_capability->
1230             generic_cap_list.inp_type & GST_WFD_UIBC_INPUT_TYPE_REMOTECONTROL) {
1231           tempcap |= GST_WFD_UIBC_INPUT_TYPE_REMOTECONTROL;
1232           g_string_append_printf (lines, "RemoteControl");
1233           if (msg->uibc_capability->generic_cap_list.inp_type != tempcap)
1234             g_string_append_printf (lines, ", ");
1235         }
1236       } else
1237         g_string_append_printf (lines, "none");
1238       g_string_append_printf (lines, ";");
1239       g_string_append_printf (lines, " hidc_cap_list=");
1240       if (msg->uibc_capability->hidc_cap_list.cap_count) {
1241         detailed_cap *temp_cap = msg->uibc_capability->hidc_cap_list.next;
1242         while (temp_cap) {
1243           if (temp_cap->p.inp_type == GST_WFD_UIBC_INPUT_TYPE_KEYBOARD)
1244             g_string_append_printf (lines, "Keyboard");
1245           else if (temp_cap->p.inp_type == GST_WFD_UIBC_INPUT_TYPE_MOUSE)
1246             g_string_append_printf (lines, "Mouse");
1247           else if (temp_cap->p.inp_type == GST_WFD_UIBC_INPUT_TYPE_SINGLETOUCH)
1248             g_string_append_printf (lines, "SingleTouch");
1249           else if (temp_cap->p.inp_type == GST_WFD_UIBC_INPUT_TYPE_MULTITOUCH)
1250             g_string_append_printf (lines, "MultiTouch");
1251           else if (temp_cap->p.inp_type == GST_WFD_UIBC_INPUT_TYPE_JOYSTICK)
1252             g_string_append_printf (lines, "Joystick");
1253           else if (temp_cap->p.inp_type == GST_WFD_UIBC_INPUT_TYPE_CAMERA)
1254             g_string_append_printf (lines, "Camera");
1255           else if (temp_cap->p.inp_type == GST_WFD_UIBC_INPUT_TYPE_GESTURE)
1256             g_string_append_printf (lines, "Gesture");
1257           else if (temp_cap->p.inp_type ==
1258               GST_WFD_UIBC_INPUT_TYPE_REMOTECONTROL)
1259             g_string_append_printf (lines, "RemoteControl");
1260           g_string_append_printf (lines, "/");
1261           if (temp_cap->p.inp_path == GST_WFD_UIBC_INPUT_PATH_INFRARED)
1262             g_string_append_printf (lines, "Infrared");
1263           else if (temp_cap->p.inp_path == GST_WFD_UIBC_INPUT_PATH_USB)
1264             g_string_append_printf (lines, "USB");
1265           else if (temp_cap->p.inp_path == GST_WFD_UIBC_INPUT_PATH_BT)
1266             g_string_append_printf (lines, "BT");
1267           else if (temp_cap->p.inp_path == GST_WFD_UIBC_INPUT_PATH_ZIGBEE)
1268             g_string_append_printf (lines, "Zigbee");
1269           else if (temp_cap->p.inp_path == GST_WFD_UIBC_INPUT_PATH_WIFI)
1270             g_string_append_printf (lines, "Wi-Fi");
1271           else if (temp_cap->p.inp_path == GST_WFD_UIBC_INPUT_PATH_NOSP)
1272             g_string_append_printf (lines, "No-SP");
1273           temp_cap = temp_cap->next;
1274           if (temp_cap)
1275             g_string_append_printf (lines, ", ");
1276         }
1277       } else
1278         g_string_append_printf (lines, "none");
1279       g_string_append_printf (lines, ";");
1280       if (msg->uibc_capability->tcp_port)
1281         g_string_append_printf (lines, "port=%u",
1282             msg->uibc_capability->tcp_port);
1283       else
1284         g_string_append_printf (lines, "port=none");
1285     } else
1286       g_string_append_printf (lines, " none");
1287     g_string_append_printf (lines, "\r\n");
1288   }
1289
1290   if (msg->uibc_setting) {
1291     g_string_append_printf (lines, "wfd_uibc_setting");
1292     g_string_append_printf (lines, ":");
1293     if (msg->uibc_setting->uibc_setting)
1294       g_string_append_printf (lines, " enable");
1295     else
1296       g_string_append_printf (lines, " disable");
1297     g_string_append_printf (lines, "\r\n");
1298   }
1299
1300   if (msg->standby_resume_capability) {
1301     g_string_append_printf (lines, "wfd_standby_resume_capability");
1302     g_string_append_printf (lines, ":");
1303     if (msg->standby_resume_capability->standby_resume_cap)
1304       g_string_append_printf (lines, " supported");
1305     else
1306       g_string_append_printf (lines, " none");
1307     g_string_append_printf (lines, "\r\n");
1308   }
1309
1310   if (msg->standby) {
1311     g_string_append_printf (lines, "wfd_standby");
1312     g_string_append_printf (lines, "\r\n");
1313   }
1314
1315   if (msg->connector_type) {
1316     g_string_append_printf (lines, "wfd_connector_type");
1317     g_string_append_printf (lines, ":");
1318     if (msg->connector_type->connector_type)
1319       g_string_append_printf (lines, " %02x",
1320           msg->connector_type->connector_type);
1321     else
1322       g_string_append_printf (lines, " none");
1323     g_string_append_printf (lines, "\r\n");
1324   }
1325
1326   if (msg->idr_request) {
1327     g_string_append_printf (lines, "wfd_idr_request");
1328     g_string_append_printf (lines, "\r\n");
1329   }
1330
1331   return g_string_free (lines, FALSE);
1332 }
1333
1334 gchar *
1335 gst_wfd_message_param_names_as_text (const GstWFDMessage * msg)
1336 {
1337   /* change all vars so they match rfc? */
1338   GString *lines;
1339   g_return_val_if_fail (msg != NULL, NULL);
1340
1341   lines = g_string_new ("");
1342
1343   /* list of audio codecs */
1344   if (msg->audio_codecs) {
1345     g_string_append_printf (lines, "wfd_audio_codecs");
1346     g_string_append_printf (lines, "\r\n");
1347   }
1348   /* list of video codecs */
1349   if (msg->video_formats) {
1350     g_string_append_printf (lines, "wfd_video_formats");
1351     g_string_append_printf (lines, "\r\n");
1352   }
1353   /* list of video 3D codecs */
1354   if (msg->video_3d_formats) {
1355     g_string_append_printf (lines, "wfd_3d_video_formats");
1356     g_string_append_printf (lines, "\r\n");
1357   }
1358   if (msg->content_protection) {
1359     g_string_append_printf (lines, "wfd_content_protection");
1360     g_string_append_printf (lines, "\r\n");
1361   }
1362   if (msg->display_edid) {
1363     g_string_append_printf (lines, "wfd_display_edid");
1364     g_string_append_printf (lines, "\r\n");
1365   }
1366   if (msg->coupled_sink) {
1367     g_string_append_printf (lines, "wfd_coupled_sink");
1368     g_string_append_printf (lines, "\r\n");
1369   }
1370   if (msg->trigger_method) {
1371     g_string_append_printf (lines, "wfd_trigger_method");
1372     g_string_append_printf (lines, "\r\n");
1373   }
1374   if (msg->presentation_url) {
1375     g_string_append_printf (lines, "wfd_presentation_URL");
1376     g_string_append_printf (lines, "\r\n");
1377   }
1378   if (msg->client_rtp_ports) {
1379     g_string_append_printf (lines, "wfd_client_rtp_ports");
1380     g_string_append_printf (lines, "\r\n");
1381   }
1382   if (msg->route) {
1383     g_string_append_printf (lines, "wfd_route");
1384     g_string_append_printf (lines, "\r\n");
1385   }
1386   if (msg->I2C) {
1387     g_string_append_printf (lines, "wfd_I2C");
1388     g_string_append_printf (lines, "\r\n");
1389   }
1390   if (msg->av_format_change_timing) {
1391     g_string_append_printf (lines, "wfd_av_format_change_timing");
1392     g_string_append_printf (lines, "\r\n");
1393   }
1394   if (msg->preferred_display_mode) {
1395     g_string_append_printf (lines, "wfd_preferred_display_mode");
1396     g_string_append_printf (lines, "\r\n");
1397   }
1398   if (msg->uibc_capability) {
1399     g_string_append_printf (lines, "wfd_uibc_capability");
1400     g_string_append_printf (lines, "\r\n");
1401   }
1402   if (msg->uibc_setting) {
1403     g_string_append_printf (lines, "wfd_uibc_setting");
1404     g_string_append_printf (lines, "\r\n");
1405   }
1406   if (msg->standby_resume_capability) {
1407     g_string_append_printf (lines, "wfd_standby_resume_capability");
1408     g_string_append_printf (lines, "\r\n");
1409   }
1410   if (msg->standby) {
1411     g_string_append_printf (lines, "wfd_standby");
1412     g_string_append_printf (lines, "\r\n");
1413   }
1414   if (msg->connector_type) {
1415     g_string_append_printf (lines, "wfd_connector_type");
1416     g_string_append_printf (lines, "\r\n");
1417   }
1418   if (msg->idr_request) {
1419     g_string_append_printf (lines, "wfd_idr_request");
1420     g_string_append_printf (lines, "\r\n");
1421   }
1422
1423   return g_string_free (lines, FALSE);
1424 }
1425
1426 /**
1427  * gst_wfd_message_dump:
1428  * @msg: a #GstWFDMessage
1429  *
1430  * Dump the parsed contents of @msg to stdout.
1431  *
1432  * Returns: a #GstWFDResult.
1433  */
1434 GstWFDResult
1435 gst_wfd_message_dump (const GstWFDMessage * msg)
1436 {
1437   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
1438
1439   if (msg->audio_codecs) {
1440     guint i = 0;
1441     g_print ("Audio supported formats : \n");
1442     for (; i < msg->audio_codecs->count; i++) {
1443       g_print ("Codec: %s\n", msg->audio_codecs->list[i].audio_format);
1444       if (!strcmp (msg->audio_codecs->list[i].audio_format, "LPCM")) {
1445         if (msg->audio_codecs->list[i].modes & GST_WFD_FREQ_44100)
1446           g_print ("    Freq: %d\n", 44100);
1447         if (msg->audio_codecs->list[i].modes & GST_WFD_FREQ_48000)
1448           g_print ("    Freq: %d\n", 48000);
1449         g_print ("      Channels: %d\n", 2);
1450       }
1451       if (!strcmp (msg->audio_codecs->list[i].audio_format, "AAC")) {
1452         g_print ("      Freq: %d\n", 48000);
1453         if (msg->audio_codecs->list[i].modes & GST_WFD_CHANNEL_2)
1454           g_print ("    Channels: %d\n", 2);
1455         if (msg->audio_codecs->list[i].modes & GST_WFD_CHANNEL_4)
1456           g_print ("    Channels: %d\n", 4);
1457         if (msg->audio_codecs->list[i].modes & GST_WFD_CHANNEL_6)
1458           g_print ("    Channels: %d\n", 6);
1459         if (msg->audio_codecs->list[i].modes & GST_WFD_CHANNEL_8)
1460           g_print ("    Channels: %d\n", 8);
1461       }
1462       if (!strcmp (msg->audio_codecs->list[i].audio_format, "AC3")) {
1463         g_print ("      Freq: %d\n", 48000);
1464         if (msg->audio_codecs->list[i].modes & GST_WFD_CHANNEL_2)
1465           g_print ("    Channels: %d\n", 2);
1466         if (msg->audio_codecs->list[i].modes & GST_WFD_CHANNEL_4)
1467           g_print ("    Channels: %d\n", 4);
1468         if (msg->audio_codecs->list[i].modes & GST_WFD_CHANNEL_6)
1469           g_print ("    Channels: %d\n", 6);
1470       }
1471       g_print ("        Bitwidth: %d\n", 16);
1472       g_print ("        Latency: %d\n", msg->audio_codecs->list[i].latency);
1473     }
1474   }
1475
1476
1477   if (msg->video_formats) {
1478     g_print ("Video supported formats : \n");
1479     if (msg->video_formats->list) {
1480       guint nativeindex = 0;
1481       g_print ("Codec: H264\n");
1482       if ((msg->video_formats->list->native & 0x7) ==
1483           GST_WFD_VIDEO_CEA_RESOLUTION) {
1484         g_print ("      Native type: CEA\n");
1485       } else if ((msg->video_formats->list->native & 0x7) ==
1486           GST_WFD_VIDEO_VESA_RESOLUTION) {
1487         g_print ("      Native type: VESA\n");
1488       } else if ((msg->video_formats->list->native & 0x7) ==
1489           GST_WFD_VIDEO_HH_RESOLUTION) {
1490         g_print ("      Native type: HH\n");
1491       }
1492       nativeindex = msg->video_formats->list->native >> 3;
1493       g_print ("        Resolution: %d\n", (1 << nativeindex));
1494
1495       if (msg->video_formats->list->
1496           H264_codec.profile & GST_WFD_H264_BASE_PROFILE) {
1497         g_print ("      Profile: BASE\n");
1498       } else if (msg->video_formats->list->
1499           H264_codec.profile & GST_WFD_H264_HIGH_PROFILE) {
1500         g_print ("      Profile: HIGH\n");
1501       }
1502       if (msg->video_formats->list->H264_codec.level & GST_WFD_H264_LEVEL_3_1) {
1503         g_print ("      Level: 3.1\n");
1504       } else if (msg->video_formats->list->
1505           H264_codec.level & GST_WFD_H264_LEVEL_3_2) {
1506         g_print ("      Level: 3.2\n");
1507       } else if (msg->video_formats->list->
1508           H264_codec.level & GST_WFD_H264_LEVEL_4) {
1509         g_print ("      Level: 4\n");
1510       } else if (msg->video_formats->list->
1511           H264_codec.level & GST_WFD_H264_LEVEL_4_1) {
1512         g_print ("      Level: 4.1\n");
1513       } else if (msg->video_formats->list->
1514           H264_codec.level & GST_WFD_H264_LEVEL_4_2) {
1515         g_print ("      Level: 4.2\n");
1516       }
1517       g_print ("        Latency: %d\n",
1518           msg->video_formats->list->H264_codec.misc_params.latency);
1519       g_print ("        min_slice_size: %x\n",
1520           msg->video_formats->list->H264_codec.misc_params.min_slice_size);
1521       g_print ("        slice_enc_params: %x\n",
1522           msg->video_formats->list->H264_codec.misc_params.slice_enc_params);
1523       g_print ("        frame_rate_control_support: %x\n",
1524           msg->video_formats->list->H264_codec.
1525           misc_params.frame_rate_control_support);
1526       if (msg->video_formats->list->H264_codec.max_hres) {
1527         g_print ("      Max Height: %04d\n",
1528             msg->video_formats->list->H264_codec.max_hres);
1529       }
1530       if (msg->video_formats->list->H264_codec.max_vres) {
1531         g_print ("      Max Width: %04d\n",
1532             msg->video_formats->list->H264_codec.max_vres);
1533       }
1534     }
1535   }
1536
1537   if (msg->video_3d_formats) {
1538     g_print ("wfd_3d_formats");
1539     g_print ("\r\n");
1540   }
1541
1542   if (msg->content_protection) {
1543     g_print ("wfd_content_protection");
1544     g_print ("\r\n");
1545   }
1546
1547   if (msg->display_edid) {
1548     g_print ("wfd_display_edid");
1549     g_print ("\r\n");
1550   }
1551
1552   if (msg->coupled_sink) {
1553     g_print ("wfd_coupled_sink");
1554     g_print ("\r\n");
1555   }
1556
1557   if (msg->trigger_method) {
1558     g_print ("  Trigger type: %s\n", msg->trigger_method->wfd_trigger_method);
1559   }
1560
1561   if (msg->presentation_url) {
1562     g_print ("wfd_presentation_URL");
1563     g_print ("\r\n");
1564   }
1565
1566   if (msg->client_rtp_ports) {
1567     g_print (" Client RTP Ports : \n");
1568     if (msg->client_rtp_ports->profile) {
1569       g_print ("%s\n", msg->client_rtp_ports->profile);
1570       g_print ("        %d\n", msg->client_rtp_ports->rtp_port0);
1571       g_print ("        %d\n", msg->client_rtp_ports->rtp_port1);
1572       g_print ("        %s\n", msg->client_rtp_ports->mode);
1573     }
1574     g_print ("\r\n");
1575   }
1576
1577   if (msg->route) {
1578     g_print ("wfd_route");
1579     g_print ("\r\n");
1580   }
1581
1582   if (msg->I2C) {
1583     g_print ("wfd_I2C");
1584     g_print ("\r\n");
1585   }
1586
1587   if (msg->av_format_change_timing) {
1588     g_print ("wfd_av_format_change_timing");
1589     g_print ("\r\n");
1590   }
1591
1592   if (msg->preferred_display_mode) {
1593     g_print ("wfd_preferred_display_mode");
1594     g_print ("\r\n");
1595   }
1596
1597   if (msg->uibc_capability) {
1598     g_print ("wfd_uibc_capability \r\n");
1599     g_print ("input category list:");
1600     if (msg->uibc_capability->
1601         input_category_list.input_cat & GST_WFD_UIBC_INPUT_CAT_GENERIC)
1602       g_print ("GENERIC");
1603     if (msg->uibc_capability->
1604         input_category_list.input_cat & GST_WFD_UIBC_INPUT_CAT_HIDC)
1605       g_print ("HIDC");
1606     if (!msg->uibc_capability->input_category_list.input_cat)
1607       g_print ("none");
1608     if (msg->uibc_capability->
1609         input_category_list.input_cat & GST_WFD_UIBC_INPUT_CAT_GENERIC) {
1610       g_print ("generic cap list: ");
1611       if (msg->uibc_capability->
1612           generic_cap_list.inp_type & GST_WFD_UIBC_INPUT_TYPE_KEYBOARD)
1613         g_print ("keyboard ");
1614       if (msg->uibc_capability->
1615           generic_cap_list.inp_type & GST_WFD_UIBC_INPUT_TYPE_MOUSE)
1616         g_print ("mouse ");
1617       if (msg->uibc_capability->
1618           generic_cap_list.inp_type & GST_WFD_UIBC_INPUT_TYPE_SINGLETOUCH)
1619         g_print ("single-touch ");
1620       if (msg->uibc_capability->
1621           generic_cap_list.inp_type & GST_WFD_UIBC_INPUT_TYPE_MULTITOUCH)
1622         g_print ("multi-touch ");
1623       if (msg->uibc_capability->
1624           generic_cap_list.inp_type & GST_WFD_UIBC_INPUT_TYPE_JOYSTICK)
1625         g_print ("joystick ");
1626       if (msg->uibc_capability->
1627           generic_cap_list.inp_type & GST_WFD_UIBC_INPUT_TYPE_CAMERA)
1628         g_print ("camera ");
1629       if (msg->uibc_capability->
1630           generic_cap_list.inp_type & GST_WFD_UIBC_INPUT_TYPE_GESTURE)
1631         g_print ("gesture ");
1632       if (msg->uibc_capability->
1633           generic_cap_list.inp_type & GST_WFD_UIBC_INPUT_TYPE_REMOTECONTROL)
1634         g_print ("remote control ");
1635       if (!msg->uibc_capability->generic_cap_list.inp_type)
1636         g_print ("none ");
1637     }
1638     if (msg->uibc_capability->
1639         input_category_list.input_cat & GST_WFD_UIBC_INPUT_CAT_HIDC) {
1640       g_print ("hidc cap list:");
1641       if (msg->uibc_capability->hidc_cap_list.cap_count) {
1642         detailed_cap *temp_cap = msg->uibc_capability->hidc_cap_list.next;
1643         while (temp_cap) {
1644           if (temp_cap->p.inp_type & GST_WFD_UIBC_INPUT_TYPE_KEYBOARD) {
1645             g_print ("keyboard ");
1646           } else if (temp_cap->p.inp_type & GST_WFD_UIBC_INPUT_TYPE_MOUSE) {
1647             g_print ("mouse ");
1648           } else if (temp_cap->p.inp_type & GST_WFD_UIBC_INPUT_TYPE_SINGLETOUCH) {
1649             g_print ("single-touch ");
1650           } else if (temp_cap->p.inp_type & GST_WFD_UIBC_INPUT_TYPE_MULTITOUCH) {
1651             g_print ("multi-touch ");
1652           } else if (temp_cap->p.inp_type & GST_WFD_UIBC_INPUT_TYPE_JOYSTICK) {
1653             g_print ("joystick ");
1654           } else if (temp_cap->p.inp_type & GST_WFD_UIBC_INPUT_TYPE_CAMERA) {
1655             g_print ("camera ");
1656           } else if (temp_cap->p.inp_type & GST_WFD_UIBC_INPUT_TYPE_GESTURE) {
1657             g_print ("gesture ");
1658           } else if (temp_cap->
1659               p.inp_type & GST_WFD_UIBC_INPUT_TYPE_REMOTECONTROL) {
1660             g_print ("remote control ");
1661           } else if (!temp_cap->p.inp_type) {
1662             g_print ("none ");
1663           }
1664           if (temp_cap->p.inp_path & GST_WFD_UIBC_INPUT_PATH_INFRARED) {
1665             g_print ("infrared");
1666           } else if (temp_cap->p.inp_path & GST_WFD_UIBC_INPUT_PATH_USB) {
1667             g_print ("usb");
1668           } else if (temp_cap->p.inp_path & GST_WFD_UIBC_INPUT_PATH_BT) {
1669             g_print ("bluetooth");
1670           } else if (temp_cap->p.inp_path & GST_WFD_UIBC_INPUT_PATH_WIFI) {
1671             g_print ("Wi-Fi");
1672           } else if (temp_cap->p.inp_path & GST_WFD_UIBC_INPUT_PATH_ZIGBEE) {
1673             g_print ("Zigbee");
1674           } else if (temp_cap->p.inp_path & GST_WFD_UIBC_INPUT_PATH_NOSP) {
1675             g_print ("No-SP");
1676           } else if (!temp_cap->p.inp_path) {
1677             g_print ("none");
1678           }
1679           temp_cap = temp_cap->next;
1680         }
1681       }
1682     }
1683     if (msg->uibc_capability->tcp_port)
1684       g_print ("tcp port:%u", msg->uibc_capability->tcp_port);
1685     if (!msg->uibc_capability->tcp_port)
1686       g_print ("tcp port: none");
1687     g_print ("\r\n");
1688   }
1689
1690   if (msg->uibc_setting) {
1691     g_print ("wfd_uibc_setting: ");
1692     if (msg->uibc_setting->uibc_setting) {
1693       g_print ("true");
1694     } else
1695       g_print ("false");
1696     g_print ("\r\n");
1697   }
1698
1699   if (msg->standby_resume_capability) {
1700     g_print ("wfd_standby_resume_capability");
1701     g_print ("\r\n");
1702   }
1703
1704   if (msg->standby) {
1705     g_print ("wfd_standby");
1706     g_print ("\r\n");
1707   }
1708
1709   if (msg->connector_type) {
1710     g_print ("wfd_connector_type");
1711     g_print ("\r\n");
1712   }
1713
1714   if (msg->idr_request) {
1715     g_print ("wfd_idr_request");
1716     g_print ("\r\n");
1717   }
1718
1719   return GST_WFD_OK;
1720 }
1721
1722 GstWFDResult
1723 gst_wfd_message_set_supported_audio_format (GstWFDMessage * msg,
1724     GstWFDAudioFormats a_codec,
1725     guint a_freq, guint a_channels, guint a_bitwidth, guint32 a_latency)
1726 {
1727   guint temp = a_codec;
1728   guint i = 0;
1729   guint pcm = 0, aac = 0, ac3 = 0;
1730
1731   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
1732
1733   if (!msg->audio_codecs)
1734     msg->audio_codecs = g_new0 (GstWFDAudioCodeclist, 1);
1735
1736   if (a_codec != GST_WFD_AUDIO_UNKNOWN) {
1737     while (temp) {
1738       msg->audio_codecs->count++;
1739       temp >>= 1;
1740     }
1741     msg->audio_codecs->list =
1742         g_new0 (GstWFDAudioCodec, msg->audio_codecs->count);
1743     for (; i < msg->audio_codecs->count; i++) {
1744       if ((a_codec & GST_WFD_AUDIO_LPCM) && (!pcm)) {
1745         msg->audio_codecs->list[i].audio_format = g_strdup ("LPCM");
1746         msg->audio_codecs->list[i].modes = a_freq;
1747         msg->audio_codecs->list[i].latency = a_latency;
1748         pcm = 1;
1749       } else if ((a_codec & GST_WFD_AUDIO_AAC) && (!aac)) {
1750         msg->audio_codecs->list[i].audio_format = g_strdup ("AAC");
1751         msg->audio_codecs->list[i].modes = a_channels;
1752         msg->audio_codecs->list[i].latency = a_latency;
1753         aac = 1;
1754       } else if ((a_codec & GST_WFD_AUDIO_AC3) && (!ac3)) {
1755         msg->audio_codecs->list[i].audio_format = g_strdup ("AC3");
1756         msg->audio_codecs->list[i].modes = a_channels;
1757         msg->audio_codecs->list[i].latency = a_latency;
1758         ac3 = 1;
1759       }
1760     }
1761   }
1762   return GST_WFD_OK;
1763 }
1764
1765 GstWFDResult
1766 gst_wfd_message_set_prefered_audio_format (GstWFDMessage * msg,
1767     GstWFDAudioFormats a_codec,
1768     GstWFDAudioFreq a_freq,
1769     GstWFDAudioChannels a_channels, guint a_bitwidth, guint32 a_latency)
1770 {
1771   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
1772
1773   if (!msg->audio_codecs)
1774     msg->audio_codecs = g_new0 (GstWFDAudioCodeclist, 1);
1775
1776   msg->audio_codecs->list = g_new0 (GstWFDAudioCodec, 1);
1777   msg->audio_codecs->count = 1;
1778   if (a_codec == GST_WFD_AUDIO_LPCM) {
1779     msg->audio_codecs->list->audio_format = g_strdup ("LPCM");
1780     msg->audio_codecs->list->modes = a_freq;
1781     msg->audio_codecs->list->latency = a_latency;
1782   } else if (a_codec == GST_WFD_AUDIO_AAC) {
1783     msg->audio_codecs->list->audio_format = g_strdup ("AAC");
1784     msg->audio_codecs->list->modes = a_channels;
1785     msg->audio_codecs->list->latency = a_latency;
1786   } else if (a_codec == GST_WFD_AUDIO_AC3) {
1787     msg->audio_codecs->list->audio_format = g_strdup ("AC3");
1788     msg->audio_codecs->list->modes = a_channels;
1789     msg->audio_codecs->list->latency = a_latency;
1790   }
1791   return GST_WFD_OK;
1792 }
1793
1794 GstWFDResult
1795 gst_wfd_message_get_supported_audio_format (GstWFDMessage * msg,
1796     guint * a_codec,
1797     guint * a_freq, guint * a_channels, guint * a_bitwidth, guint32 * a_latency)
1798 {
1799   guint i = 0;
1800   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
1801   g_return_val_if_fail (msg->audio_codecs != NULL, GST_WFD_EINVAL);
1802
1803   for (; i < msg->audio_codecs->count; i++) {
1804     if (!g_strcmp0 (msg->audio_codecs->list[i].audio_format, "LPCM")) {
1805       *a_codec |= GST_WFD_AUDIO_LPCM;
1806       *a_freq |= msg->audio_codecs->list[i].modes;
1807       *a_channels |= GST_WFD_CHANNEL_2;
1808       *a_bitwidth = 16;
1809       *a_latency = msg->audio_codecs->list[i].latency;
1810     } else if (!g_strcmp0 (msg->audio_codecs->list[i].audio_format, "AAC")) {
1811       *a_codec |= GST_WFD_AUDIO_AAC;
1812       *a_freq |= GST_WFD_FREQ_48000;
1813       *a_channels |= msg->audio_codecs->list[i].modes;
1814       *a_bitwidth = 16;
1815       *a_latency = msg->audio_codecs->list[i].latency;
1816     } else if (!g_strcmp0 (msg->audio_codecs->list[i].audio_format, "AC3")) {
1817       *a_codec |= GST_WFD_AUDIO_AC3;
1818       *a_freq |= GST_WFD_FREQ_48000;
1819       *a_channels |= msg->audio_codecs->list[i].modes;
1820       *a_bitwidth = 16;
1821       *a_latency = msg->audio_codecs->list[i].latency;
1822     }
1823   }
1824   return GST_WFD_OK;
1825 }
1826
1827 GstWFDResult
1828 gst_wfd_message_get_prefered_audio_format (GstWFDMessage * msg,
1829     GstWFDAudioFormats * a_codec,
1830     GstWFDAudioFreq * a_freq,
1831     GstWFDAudioChannels * a_channels, guint * a_bitwidth, guint32 * a_latency)
1832 {
1833   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
1834
1835   if (!g_strcmp0 (msg->audio_codecs->list->audio_format, "LPCM")) {
1836     *a_codec = GST_WFD_AUDIO_LPCM;
1837     *a_freq = msg->audio_codecs->list->modes;
1838     *a_channels = GST_WFD_CHANNEL_2;
1839     *a_bitwidth = 16;
1840     *a_latency = msg->audio_codecs->list->latency;
1841   } else if (!g_strcmp0 (msg->audio_codecs->list->audio_format, "AAC")) {
1842     *a_codec = GST_WFD_AUDIO_AAC;
1843     *a_freq = GST_WFD_FREQ_48000;
1844     *a_channels = msg->audio_codecs->list->modes;
1845     *a_bitwidth = 16;
1846     *a_latency = msg->audio_codecs->list->latency;
1847   } else if (!g_strcmp0 (msg->audio_codecs->list->audio_format, "AC3")) {
1848     *a_codec = GST_WFD_AUDIO_AC3;
1849     *a_freq = GST_WFD_FREQ_48000;
1850     *a_channels = msg->audio_codecs->list->modes;
1851     *a_bitwidth = 16;
1852     *a_latency = msg->audio_codecs->list->latency;
1853   }
1854   return GST_WFD_OK;
1855 }
1856
1857 GstWFDResult
1858 gst_wfd_message_set_supported_video_format (GstWFDMessage * msg,
1859     GstWFDVideoCodecs v_codec,
1860     GstWFDVideoNativeResolution v_native,
1861     guint64 v_native_resolution,
1862     guint64 v_cea_resolution,
1863     guint64 v_vesa_resolution,
1864     guint64 v_hh_resolution,
1865     guint v_profile,
1866     guint v_level,
1867     guint32 v_latency,
1868     guint32 v_max_height,
1869     guint32 v_max_width,
1870     guint32 min_slice_size, guint32 slice_enc_params, guint frame_rate_control)
1871 {
1872   guint nativeindex = 0;
1873   guint64 temp = v_native_resolution;
1874
1875   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
1876
1877   if (!msg->video_formats)
1878     msg->video_formats = g_new0 (GstWFDVideoCodeclist, 1);
1879
1880   if (v_codec != GST_WFD_VIDEO_UNKNOWN) {
1881     msg->video_formats->list = g_new0 (GstWFDVideoCodec, 1);
1882     while (temp) {
1883       nativeindex++;
1884       temp >>= 1;
1885     }
1886
1887     msg->video_formats->list->native = nativeindex - 1;
1888     msg->video_formats->list->native <<= 3;
1889
1890     if (v_native == GST_WFD_VIDEO_VESA_RESOLUTION)
1891       msg->video_formats->list->native |= 1;
1892     else if (v_native == GST_WFD_VIDEO_HH_RESOLUTION)
1893       msg->video_formats->list->native |= 2;
1894
1895     msg->video_formats->list->preferred_display_mode_supported = 1;
1896     msg->video_formats->list->H264_codec.profile = v_profile;
1897     msg->video_formats->list->H264_codec.level = v_level;
1898     msg->video_formats->list->H264_codec.max_hres = v_max_height;
1899     msg->video_formats->list->H264_codec.max_vres = v_max_width;
1900     msg->video_formats->list->H264_codec.misc_params.CEA_Support =
1901         v_cea_resolution;
1902     msg->video_formats->list->H264_codec.misc_params.VESA_Support =
1903         v_vesa_resolution;
1904     msg->video_formats->list->H264_codec.misc_params.HH_Support =
1905         v_hh_resolution;
1906     msg->video_formats->list->H264_codec.misc_params.latency = v_latency;
1907     msg->video_formats->list->H264_codec.misc_params.min_slice_size =
1908         min_slice_size;
1909     msg->video_formats->list->H264_codec.misc_params.slice_enc_params =
1910         slice_enc_params;
1911     msg->video_formats->list->H264_codec.
1912         misc_params.frame_rate_control_support = frame_rate_control;
1913   }
1914   return GST_WFD_OK;
1915 }
1916
1917 GstWFDResult
1918 gst_wfd_message_set_prefered_video_format (GstWFDMessage * msg,
1919     GstWFDVideoCodecs v_codec,
1920     GstWFDVideoNativeResolution v_native,
1921     guint64 v_native_resolution,
1922     GstWFDVideoCEAResolution v_cea_resolution,
1923     GstWFDVideoVESAResolution v_vesa_resolution,
1924     GstWFDVideoHHResolution v_hh_resolution,
1925     GstWFDVideoH264Profile v_profile,
1926     GstWFDVideoH264Level v_level,
1927     guint32 v_latency,
1928     guint32 v_max_height,
1929     guint32 v_max_width,
1930     guint32 min_slice_size, guint32 slice_enc_params, guint frame_rate_control)
1931 {
1932   guint nativeindex = 0;
1933   guint64 temp = v_native_resolution;
1934
1935   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
1936
1937   if (!msg->video_formats)
1938     msg->video_formats = g_new0 (GstWFDVideoCodeclist, 1);
1939   msg->video_formats->list = g_new0 (GstWFDVideoCodec, 1);
1940
1941   while (temp) {
1942     nativeindex++;
1943     temp >>= 1;
1944   }
1945
1946   if (nativeindex)
1947     msg->video_formats->list->native = nativeindex - 1;
1948   msg->video_formats->list->native <<= 3;
1949
1950   if (v_native == GST_WFD_VIDEO_VESA_RESOLUTION)
1951     msg->video_formats->list->native |= 1;
1952   else if (v_native == GST_WFD_VIDEO_HH_RESOLUTION)
1953     msg->video_formats->list->native |= 2;
1954
1955   msg->video_formats->list->preferred_display_mode_supported = 0;
1956   msg->video_formats->list->H264_codec.profile = v_profile;
1957   msg->video_formats->list->H264_codec.level = v_level;
1958   msg->video_formats->list->H264_codec.max_hres = v_max_height;
1959   msg->video_formats->list->H264_codec.max_vres = v_max_width;
1960   msg->video_formats->list->H264_codec.misc_params.CEA_Support =
1961       v_cea_resolution;
1962   msg->video_formats->list->H264_codec.misc_params.VESA_Support =
1963       v_vesa_resolution;
1964   msg->video_formats->list->H264_codec.misc_params.HH_Support = v_hh_resolution;
1965   msg->video_formats->list->H264_codec.misc_params.latency = v_latency;
1966   msg->video_formats->list->H264_codec.misc_params.min_slice_size =
1967       min_slice_size;
1968   msg->video_formats->list->H264_codec.misc_params.slice_enc_params =
1969       slice_enc_params;
1970   msg->video_formats->list->H264_codec.misc_params.frame_rate_control_support =
1971       frame_rate_control;
1972   return GST_WFD_OK;
1973 }
1974
1975 GstWFDResult
1976 gst_wfd_message_get_supported_video_format (GstWFDMessage * msg,
1977     GstWFDVideoCodecs * v_codec,
1978     GstWFDVideoNativeResolution * v_native,
1979     guint64 * v_native_resolution,
1980     guint64 * v_cea_resolution,
1981     guint64 * v_vesa_resolution,
1982     guint64 * v_hh_resolution,
1983     guint * v_profile,
1984     guint * v_level,
1985     guint32 * v_latency,
1986     guint32 * v_max_height,
1987     guint32 * v_max_width,
1988     guint32 * min_slice_size,
1989     guint32 * slice_enc_params, guint * frame_rate_control)
1990 {
1991   guint nativeindex = 0;
1992
1993   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
1994   *v_codec = GST_WFD_VIDEO_H264;
1995   *v_native = msg->video_formats->list->native & 0x7;
1996   nativeindex = msg->video_formats->list->native >> 3;
1997   *v_native_resolution = 1 << nativeindex;
1998   *v_profile = msg->video_formats->list->H264_codec.profile;
1999   *v_level = msg->video_formats->list->H264_codec.level;
2000   *v_max_height = msg->video_formats->list->H264_codec.max_hres;
2001   *v_max_width = msg->video_formats->list->H264_codec.max_vres;
2002   *v_cea_resolution =
2003       msg->video_formats->list->H264_codec.misc_params.CEA_Support;
2004   *v_vesa_resolution =
2005       msg->video_formats->list->H264_codec.misc_params.VESA_Support;
2006   *v_hh_resolution =
2007       msg->video_formats->list->H264_codec.misc_params.HH_Support;
2008   *v_latency = msg->video_formats->list->H264_codec.misc_params.latency;
2009   *min_slice_size =
2010       msg->video_formats->list->H264_codec.misc_params.min_slice_size;
2011   *slice_enc_params =
2012       msg->video_formats->list->H264_codec.misc_params.slice_enc_params;
2013   *frame_rate_control =
2014       msg->video_formats->list->H264_codec.
2015       misc_params.frame_rate_control_support;
2016   return GST_WFD_OK;
2017 }
2018
2019 GstWFDResult
2020 gst_wfd_message_get_prefered_video_format (GstWFDMessage * msg,
2021     GstWFDVideoCodecs * v_codec,
2022     GstWFDVideoNativeResolution * v_native,
2023     guint64 * v_native_resolution,
2024     GstWFDVideoCEAResolution * v_cea_resolution,
2025     GstWFDVideoVESAResolution * v_vesa_resolution,
2026     GstWFDVideoHHResolution * v_hh_resolution,
2027     GstWFDVideoH264Profile * v_profile,
2028     GstWFDVideoH264Level * v_level,
2029     guint32 * v_latency,
2030     guint32 * v_max_height,
2031     guint32 * v_max_width,
2032     guint32 * min_slice_size,
2033     guint32 * slice_enc_params, guint * frame_rate_control)
2034 {
2035   guint nativeindex = 0;
2036   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
2037
2038   *v_codec = GST_WFD_VIDEO_H264;
2039   *v_native = msg->video_formats->list->native & 0x7;
2040   nativeindex = msg->video_formats->list->native >> 3;
2041   *v_native_resolution = 1 << nativeindex;
2042   *v_profile = msg->video_formats->list->H264_codec.profile;
2043   *v_level = msg->video_formats->list->H264_codec.level;
2044   *v_max_height = msg->video_formats->list->H264_codec.max_hres;
2045   *v_max_width = msg->video_formats->list->H264_codec.max_vres;
2046   *v_cea_resolution =
2047       msg->video_formats->list->H264_codec.misc_params.CEA_Support;
2048   *v_vesa_resolution =
2049       msg->video_formats->list->H264_codec.misc_params.VESA_Support;
2050   *v_hh_resolution =
2051       msg->video_formats->list->H264_codec.misc_params.HH_Support;
2052   *v_latency = msg->video_formats->list->H264_codec.misc_params.latency;
2053   *min_slice_size =
2054       msg->video_formats->list->H264_codec.misc_params.min_slice_size;
2055   *slice_enc_params =
2056       msg->video_formats->list->H264_codec.misc_params.slice_enc_params;
2057   *frame_rate_control =
2058       msg->video_formats->list->H264_codec.
2059       misc_params.frame_rate_control_support;
2060   return GST_WFD_OK;
2061 }
2062
2063 GstWFDResult
2064 gst_wfd_message_set_display_edid (GstWFDMessage * msg,
2065     gboolean edid_supported, guint32 edid_blockcount, gchar * edid_playload)
2066 {
2067   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
2068   if (!msg->display_edid)
2069     msg->display_edid = g_new0 (GstWFDDisplayEdid, 1);
2070   msg->display_edid->edid_supported = edid_supported;
2071   if (!edid_supported)
2072     return GST_WFD_OK;
2073   msg->display_edid->edid_block_count = edid_blockcount;
2074   if (edid_blockcount) {
2075     msg->display_edid->edid_payload = g_malloc (128 * edid_blockcount);
2076     if (!msg->display_edid->edid_payload)
2077       memcpy (msg->display_edid->edid_payload, edid_playload,
2078           128 * edid_blockcount);
2079   } else
2080     msg->display_edid->edid_payload = g_strdup ("none");
2081   return GST_WFD_OK;
2082 }
2083
2084 GstWFDResult
2085 gst_wfd_message_get_display_edid (GstWFDMessage * msg,
2086     gboolean * edid_supported,
2087     guint32 * edid_blockcount, gchar ** edid_playload)
2088 {
2089   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
2090   if (msg->display_edid) {
2091     if (msg->display_edid->edid_supported) {
2092       *edid_blockcount = msg->display_edid->edid_block_count;
2093       if (msg->display_edid->edid_block_count) {
2094         char *temp;
2095         temp = g_malloc (EDID_BLOCK_SIZE * msg->display_edid->edid_block_count);
2096         if (temp) {
2097           memset (temp, 0,
2098               EDID_BLOCK_SIZE * msg->display_edid->edid_block_count);
2099           memcpy (temp, msg->display_edid->edid_payload,
2100               EDID_BLOCK_SIZE * msg->display_edid->edid_block_count);
2101           *edid_playload = temp;
2102           *edid_supported = TRUE;
2103         }
2104       } else
2105         *edid_playload = g_strdup ("none");
2106     }
2107   } else
2108     *edid_supported = FALSE;
2109   return GST_WFD_OK;
2110 }
2111
2112
2113 GstWFDResult
2114 gst_wfd_message_set_contentprotection_type (GstWFDMessage * msg,
2115     GstWFDHDCPProtection hdcpversion, guint32 TCPPort)
2116 {
2117   char str[11] = { 0, };
2118   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
2119
2120   if (!msg->content_protection)
2121     msg->content_protection = g_new0 (GstWFDContentProtection, 1);
2122   if (hdcpversion == GST_WFD_HDCP_NONE)
2123     return GST_WFD_OK;
2124   msg->content_protection->hdcp2_spec = g_new0 (GstWFDHdcp2Spec, 1);
2125   if (hdcpversion == GST_WFD_HDCP_2_0)
2126     msg->content_protection->hdcp2_spec->hdcpversion = g_strdup ("HDCP2.0");
2127   else if (hdcpversion == GST_WFD_HDCP_2_1)
2128     msg->content_protection->hdcp2_spec->hdcpversion = g_strdup ("HDCP2.1");
2129   snprintf (str, sizeof (str), "port=%d", TCPPort);
2130   msg->content_protection->hdcp2_spec->TCPPort = g_strdup (str);
2131   return GST_WFD_OK;
2132 }
2133
2134 GstWFDResult
2135 gst_wfd_message_get_contentprotection_type (GstWFDMessage * msg,
2136     GstWFDHDCPProtection * hdcpversion, guint32 * TCPPort)
2137 {
2138   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
2139   if (msg->content_protection && msg->content_protection->hdcp2_spec) {
2140     char *result = NULL;
2141     if (!g_strcmp0 (msg->content_protection->hdcp2_spec->hdcpversion, "none")) {
2142       *hdcpversion = GST_WFD_HDCP_NONE;
2143       *TCPPort = 0;
2144       return GST_WFD_OK;
2145     }
2146     if (!g_strcmp0 (msg->content_protection->hdcp2_spec->hdcpversion,
2147             "HDCP2.0"))
2148       *hdcpversion = GST_WFD_HDCP_2_0;
2149     else if (!g_strcmp0 (msg->content_protection->hdcp2_spec->hdcpversion,
2150             "HDCP2.1"))
2151       *hdcpversion = GST_WFD_HDCP_2_1;
2152     else {
2153       *hdcpversion = GST_WFD_HDCP_NONE;
2154       *TCPPort = 0;
2155       return GST_WFD_OK;
2156     }
2157
2158     result = strtok (msg->content_protection->hdcp2_spec->TCPPort, "=");
2159     while (result != NULL) {
2160       result = strtok (NULL, "=");
2161       *TCPPort = atoi (result);
2162       break;
2163     }
2164   } else
2165     *hdcpversion = GST_WFD_HDCP_NONE;
2166   return GST_WFD_OK;
2167 }
2168
2169
2170 GstWFDResult
2171 gst_wfd_messge_set_prefered_rtp_ports (GstWFDMessage * msg,
2172     GstWFDRTSPTransMode trans,
2173     GstWFDRTSPProfile profile,
2174     GstWFDRTSPLowerTrans lowertrans, guint32 rtp_port0, guint32 rtp_port1)
2175 {
2176   GString *lines;
2177   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
2178
2179   if (!msg->client_rtp_ports)
2180     msg->client_rtp_ports = g_new0 (GstWFDClientRtpPorts, 1);
2181
2182   if (trans != GST_WFD_RTSP_TRANS_UNKNOWN) {
2183     lines = g_string_new ("");
2184     if (trans == GST_WFD_RTSP_TRANS_RTP)
2185       g_string_append_printf (lines, "RTP");
2186     else if (trans == GST_WFD_RTSP_TRANS_RDT)
2187       g_string_append_printf (lines, "RDT");
2188
2189     if (profile == GST_WFD_RTSP_PROFILE_AVP)
2190       g_string_append_printf (lines, "/AVP");
2191     else if (profile == GST_WFD_RTSP_PROFILE_SAVP)
2192       g_string_append_printf (lines, "/SAVP");
2193
2194     if (lowertrans == GST_WFD_RTSP_LOWER_TRANS_UDP)
2195       g_string_append_printf (lines, "/UDP;unicast");
2196     else if (lowertrans == GST_WFD_RTSP_LOWER_TRANS_UDP_MCAST)
2197       g_string_append_printf (lines, "/UDP;multicast");
2198     else if (lowertrans == GST_WFD_RTSP_LOWER_TRANS_TCP)
2199       g_string_append_printf (lines, "/TCP;unicast");
2200     else if (lowertrans == GST_WFD_RTSP_LOWER_TRANS_HTTP)
2201       g_string_append_printf (lines, "/HTTP");
2202
2203     msg->client_rtp_ports->profile = g_string_free (lines, FALSE);
2204     msg->client_rtp_ports->rtp_port0 = rtp_port0;
2205     msg->client_rtp_ports->rtp_port1 = rtp_port1;
2206     msg->client_rtp_ports->mode = g_strdup ("mode=play");
2207   }
2208   return GST_WFD_OK;
2209 }
2210
2211 GstWFDResult
2212 gst_wfd_message_get_prefered_rtp_ports (GstWFDMessage * msg,
2213     GstWFDRTSPTransMode * trans,
2214     GstWFDRTSPProfile * profile,
2215     GstWFDRTSPLowerTrans * lowertrans, guint32 * rtp_port0, guint32 * rtp_port1)
2216 {
2217   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
2218   g_return_val_if_fail (msg->client_rtp_ports != NULL, GST_WFD_EINVAL);
2219
2220   if (g_strrstr (msg->client_rtp_ports->profile, "RTP"))
2221     *trans = GST_WFD_RTSP_TRANS_RTP;
2222   if (g_strrstr (msg->client_rtp_ports->profile, "RDT"))
2223     *trans = GST_WFD_RTSP_TRANS_RDT;
2224   if (g_strrstr (msg->client_rtp_ports->profile, "AVP"))
2225     *profile = GST_WFD_RTSP_PROFILE_AVP;
2226   if (g_strrstr (msg->client_rtp_ports->profile, "SAVP"))
2227     *profile = GST_WFD_RTSP_PROFILE_SAVP;
2228   if (g_strrstr (msg->client_rtp_ports->profile, "UDP;unicast"))
2229     *lowertrans = GST_WFD_RTSP_LOWER_TRANS_UDP;
2230   if (g_strrstr (msg->client_rtp_ports->profile, "UDP;multicast"))
2231     *lowertrans = GST_WFD_RTSP_LOWER_TRANS_UDP_MCAST;
2232   if (g_strrstr (msg->client_rtp_ports->profile, "TCP;unicast"))
2233     *lowertrans = GST_WFD_RTSP_LOWER_TRANS_TCP;
2234   if (g_strrstr (msg->client_rtp_ports->profile, "HTTP"))
2235     *lowertrans = GST_WFD_RTSP_LOWER_TRANS_HTTP;
2236
2237   *rtp_port0 = msg->client_rtp_ports->rtp_port0;
2238   *rtp_port1 = msg->client_rtp_ports->rtp_port1;
2239
2240   return GST_WFD_OK;
2241 }
2242
2243 GstWFDResult
2244 gst_wfd_message_set_presentation_url (GstWFDMessage * msg, gchar * wfd_url0,
2245     gchar * wfd_url1)
2246 {
2247   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
2248
2249   if (!msg->presentation_url)
2250     msg->presentation_url = g_new0 (GstWFDPresentationUrl, 1);
2251   if (wfd_url0)
2252     msg->presentation_url->wfd_url0 = g_strdup (wfd_url0);
2253   if (wfd_url1)
2254     msg->presentation_url->wfd_url1 = g_strdup (wfd_url1);
2255   return GST_WFD_OK;
2256 }
2257
2258 GstWFDResult
2259 gst_wfd_message_get_presentation_url (GstWFDMessage * msg, gchar ** wfd_url0,
2260     gchar ** wfd_url1)
2261 {
2262   g_return_val_if_fail (msg != NULL, GST_WFD_EINVAL);
2263
2264   if (msg->presentation_url) {
2265     *wfd_url0 = g_strdup (msg->presentation_url->wfd_url0);
2266     *wfd_url1 = g_strdup (msg->presentation_url->wfd_url1);
2267   }
2268   return GST_WFD_OK;
2269 }