4 * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
7 * Manoj Kumar K <manojkumar.k@samsung.com>, Abhishek Bajaj <abhi.bajaj@samsung.com>, Nikhilesh Mittal <nikhilesh.m@samsung.com>
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
30 #ifdef HAVE_SYS_TYPES_H
31 #include <sys/types.h>
34 #include <glib.h> /* for G_OS_WIN32 */
35 #include "wfdconfigmessage.h"
36 #include "mm_wfd_common_private.h"
38 /* FIXME, is currently allocated on the stack */
39 #define MAX_LINE_LEN (1024 * 16)
41 #define FREE_STRING(field) if (field != NULL) g_free(field); (field) = NULL;
42 #define REPLACE_STRING(field, val) FREE_STRING(field); (field) = g_strdup(val);
43 #define EDID_BLOCK_SIZE 128
55 * wfdconfig_message_new:
56 * @msg: pointer to new #WFDMessage
58 * Allocate a new WFDMessage and store the result in @msg.
60 * Returns: a #WFDResult.
63 wfdconfig_message_new(WFDMessage **msg)
67 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
69 newmsg = g_new0(WFDMessage, 1);
73 return wfdconfig_message_init(newmsg);
77 * wfdconfig_message_init:
80 * Initialize @msg so that its contents are as if it was freshly allocated
81 * with wfdconfig_message_new(). This function is mostly used to initialize a message
82 * allocated on the stack. wfdconfig_message_uninit() undoes this operation.
84 * When this function is invoked on newly allocated data(with malloc or on the
85 * stack), its contents should be set to 0 before calling this function.
87 * Returns: a #WFDResult.
90 wfdconfig_message_init(WFDMessage *msg)
92 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
98 * wfdconfig_message_uninit:
101 * Free all resources allocated in @msg. @msg should not be used anymore after
102 * this function. This function should be used when @msg was allocated on the
103 * stack and initialized with wfdconfig_message_init().
105 * Returns: a #WFDResult.
108 wfdconfig_message_uninit(WFDMessage *msg)
110 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
112 if (msg->audio_codecs) {
114 if (msg->audio_codecs->list) {
115 for (; i < msg->audio_codecs->count; i++) {
116 FREE_STRING(msg->audio_codecs->list[i].audio_format);
117 msg->audio_codecs->list[i].modes = 0;
118 msg->audio_codecs->list[i].latency = 0;
120 FREE_STRING(msg->audio_codecs->list);
122 FREE_STRING(msg->audio_codecs);
125 if (msg->video_formats) {
126 FREE_STRING(msg->video_formats->list);
127 FREE_STRING(msg->video_formats);
130 if (msg->video_3d_formats) {
131 FREE_STRING(msg->video_3d_formats);
134 if (msg->content_protection) {
135 FREE_STRING(msg->content_protection);
138 if (msg->display_edid) {
139 if (msg->display_edid->edid_payload)
140 FREE_STRING(msg->display_edid->edid_payload);
141 FREE_STRING(msg->display_edid);
144 if (msg->coupled_sink) {
145 FREE_STRING(msg->coupled_sink);
148 if (msg->trigger_method) {
149 FREE_STRING(msg->trigger_method->wfd_trigger_method);
150 FREE_STRING(msg->trigger_method);
153 if (msg->presentation_url) {
154 FREE_STRING(msg->trigger_method);
157 if (msg->client_rtp_ports) {
158 FREE_STRING(msg->client_rtp_ports->profile);
159 FREE_STRING(msg->client_rtp_ports->mode);
160 FREE_STRING(msg->client_rtp_ports);
164 FREE_STRING(msg->route);
168 FREE_STRING(msg->I2C);
171 if (msg->av_format_change_timing) {
172 FREE_STRING(msg->av_format_change_timing);
175 if (msg->preferred_display_mode) {
176 FREE_STRING(msg->preferred_display_mode);
179 if (msg->uibc_capability) {
180 FREE_STRING(msg->uibc_capability);
183 if (msg->uibc_setting) {
184 FREE_STRING(msg->uibc_setting);
187 if (msg->standby_resume_capability) {
188 FREE_STRING(msg->standby_resume_capability);
192 FREE_STRING(msg->standby);
195 if (msg->connector_type) {
196 FREE_STRING(msg->connector_type);
199 if (msg->idr_request) {
200 FREE_STRING(msg->idr_request);
207 * wfdconfig_message_free:
208 * @msg: a #WFDMessage
210 * Free all resources allocated by @msg. @msg should not be used anymore after
211 * this function. This function should be used when @msg was dynamically
212 * allocated with wfdconfig_message_new().
214 * Returns: a #WFDResult.
217 wfdconfig_message_free(WFDMessage *msg)
219 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
221 wfdconfig_message_uninit(msg);
228 * wfdconfig_message_as_text:
229 * @msg: a #WFDMessage
231 * Convert the contents of @msg to a text string.
233 * Returns: A dynamically allocated string representing the WFD description.
236 wfdconfig_message_as_text(const WFDMessage *msg)
238 /* change all vars so they match rfc? */
240 g_return_val_if_fail(msg != NULL, NULL);
242 lines = g_string_new("");
244 /* list of audio codecs */
245 if (msg->audio_codecs) {
247 g_string_append_printf(lines, "wfd_audio_codecs");
248 if (msg->audio_codecs->list) {
249 g_string_append_printf(lines, ":");
250 for (; i < msg->audio_codecs->count; i++) {
251 g_string_append_printf(lines, " %s", msg->audio_codecs->list[i].audio_format);
252 g_string_append_printf(lines, " %08x", msg->audio_codecs->list[i].modes);
253 g_string_append_printf(lines, " %02x", msg->audio_codecs->list[i].latency);
254 if ((i + 1) < msg->audio_codecs->count)
255 g_string_append_printf(lines, ",");
258 g_string_append_printf(lines, "\r\n");
261 /* list of video codecs */
262 if (msg->video_formats) {
263 g_string_append_printf(lines, "wfd_video_formats");
264 if (msg->video_formats->list) {
265 g_string_append_printf(lines, ":");
266 g_string_append_printf(lines, " %02x", msg->video_formats->list->native);
267 g_string_append_printf(lines, " %02x", msg->video_formats->list->preferred_display_mode_supported);
268 g_string_append_printf(lines, " %02x", msg->video_formats->list->H264_codec.profile);
269 g_string_append_printf(lines, " %02x", msg->video_formats->list->H264_codec.level);
270 g_string_append_printf(lines, " %08x", msg->video_formats->list->H264_codec.misc_params.CEA_Support);
271 g_string_append_printf(lines, " %08x", msg->video_formats->list->H264_codec.misc_params.VESA_Support);
272 g_string_append_printf(lines, " %08x", msg->video_formats->list->H264_codec.misc_params.HH_Support);
273 g_string_append_printf(lines, " %02x", msg->video_formats->list->H264_codec.misc_params.latency);
274 g_string_append_printf(lines, " %04x", msg->video_formats->list->H264_codec.misc_params.min_slice_size);
275 g_string_append_printf(lines, " %04x", msg->video_formats->list->H264_codec.misc_params.slice_enc_params);
276 g_string_append_printf(lines, " %02x", msg->video_formats->list->H264_codec.misc_params.frame_rate_control_support);
278 if (msg->video_formats->list->H264_codec.max_hres)
279 g_string_append_printf(lines, " %04x", msg->video_formats->list->H264_codec.max_hres);
281 g_string_append_printf(lines, " none");
283 if (msg->video_formats->list->H264_codec.max_vres)
284 g_string_append_printf(lines, " %04x", msg->video_formats->list->H264_codec.max_vres);
286 g_string_append_printf(lines, " none");
288 g_string_append_printf(lines, "\r\n");
291 /* list of video 3D codecs */
292 if (msg->video_3d_formats) {
293 g_string_append_printf(lines, "wfd_3d_video_formats");
294 g_string_append_printf(lines, ":");
295 if (msg->video_3d_formats->list) {
296 g_string_append_printf(lines, " %02x", msg->video_3d_formats->list->native);
297 g_string_append_printf(lines, " %02x", msg->video_3d_formats->list->preferred_display_mode_supported);
298 g_string_append_printf(lines, " %02x", msg->video_3d_formats->list->H264_codec.profile);
299 g_string_append_printf(lines, " %02x", msg->video_3d_formats->list->H264_codec.level);
300 g_string_append_printf(lines, " %16x", msg->video_3d_formats->list->H264_codec.misc_params.video_3d_capability);
301 g_string_append_printf(lines, " %02x", msg->video_3d_formats->list->H264_codec.misc_params.latency);
302 g_string_append_printf(lines, " %04x", msg->video_3d_formats->list->H264_codec.misc_params.min_slice_size);
303 g_string_append_printf(lines, " %04x", msg->video_3d_formats->list->H264_codec.misc_params.slice_enc_params);
304 g_string_append_printf(lines, " %02x", msg->video_3d_formats->list->H264_codec.misc_params.frame_rate_control_support);
305 if (msg->video_3d_formats->list->H264_codec.max_hres)
306 g_string_append_printf(lines, " %04x", msg->video_formats->list->H264_codec.max_hres);
308 g_string_append_printf(lines, " none");
309 if (msg->video_3d_formats->list->H264_codec.max_vres)
310 g_string_append_printf(lines, " %04x", msg->video_formats->list->H264_codec.max_vres);
312 g_string_append_printf(lines, " none");
314 g_string_append_printf(lines, " none");
316 g_string_append_printf(lines, "\r\n");
319 if (msg->content_protection) {
320 g_string_append_printf(lines, "wfd_content_protection");
321 g_string_append_printf(lines, ":");
322 if (msg->content_protection->hdcp2_spec) {
323 if (msg->content_protection->hdcp2_spec->hdcpversion) {
324 g_string_append_printf(lines, " %s", msg->content_protection->hdcp2_spec->hdcpversion);
325 g_string_append_printf(lines, " %s", msg->content_protection->hdcp2_spec->TCPPort);
327 g_string_append_printf(lines, " none");
330 g_string_append_printf(lines, " none");
332 g_string_append_printf(lines, "\r\n");
335 if (msg->display_edid) {
336 g_string_append_printf(lines, "wfd_display_edid");
337 g_string_append_printf(lines, ":");
338 if (msg->display_edid->edid_supported) {
339 g_string_append_printf(lines, " %d", msg->display_edid->edid_supported);
340 if (msg->display_edid->edid_block_count)
341 g_string_append_printf(lines, " %d", msg->display_edid->edid_block_count);
343 g_string_append_printf(lines, " none");
345 g_string_append_printf(lines, " none");
347 g_string_append_printf(lines, "\r\n");
350 if (msg->coupled_sink) {
351 g_string_append_printf(lines, "wfd_coupled_sink");
352 g_string_append_printf(lines, ":");
353 if (msg->coupled_sink->coupled_sink_cap) {
354 g_string_append_printf(lines, " %02x", msg->coupled_sink->coupled_sink_cap->status);
355 if (msg->coupled_sink->coupled_sink_cap->sink_address)
356 g_string_append_printf(lines, " %s", msg->coupled_sink->coupled_sink_cap->sink_address);
358 g_string_append_printf(lines, " none");
360 g_string_append_printf(lines, " none");
362 g_string_append_printf(lines, "\r\n");
365 if (msg->trigger_method) {
366 g_string_append_printf(lines, "wfd_trigger_method");
367 g_string_append_printf(lines, ":");
368 g_string_append_printf(lines, " %s", msg->trigger_method->wfd_trigger_method);
369 g_string_append_printf(lines, "\r\n");
372 if (msg->presentation_url) {
373 g_string_append_printf(lines, "wfd_presentation_URL");
374 g_string_append_printf(lines, ":");
375 if (msg->presentation_url->wfd_url0)
376 g_string_append_printf(lines, " %s", msg->presentation_url->wfd_url0);
378 g_string_append_printf(lines, " none");
379 if (msg->presentation_url->wfd_url1)
380 g_string_append_printf(lines, " %s", msg->presentation_url->wfd_url1);
382 g_string_append_printf(lines, " none");
383 g_string_append_printf(lines, "\r\n");
386 if (msg->client_rtp_ports) {
387 g_string_append_printf(lines, "wfd_client_rtp_ports");
388 if (msg->client_rtp_ports->profile) {
389 g_string_append_printf(lines, ":");
390 g_string_append_printf(lines, " %s", msg->client_rtp_ports->profile);
391 g_string_append_printf(lines, " %d", msg->client_rtp_ports->rtp_port0);
392 g_string_append_printf(lines, " %d", msg->client_rtp_ports->rtp_port1);
393 g_string_append_printf(lines, " %s", msg->client_rtp_ports->mode);
395 g_string_append_printf(lines, "\r\n");
399 g_string_append_printf(lines, "wfd_route");
400 g_string_append_printf(lines, ":");
401 g_string_append_printf(lines, " %s", msg->route->destination);
402 g_string_append_printf(lines, "\r\n");
406 g_string_append_printf(lines, "wfd_I2C");
407 g_string_append_printf(lines, ":");
408 if (msg->I2C->I2CPresent)
409 g_string_append_printf(lines, " %x", msg->I2C->I2C_port);
411 g_string_append_printf(lines, " none");
412 g_string_append_printf(lines, "\r\n");
415 if (msg->av_format_change_timing) {
416 g_string_append_printf(lines, "wfd_av_format_change_timing");
417 g_string_append_printf(lines, ":");
418 g_string_append_printf(lines, " %10"G_GUINT64_FORMAT, msg->av_format_change_timing->PTS);
419 g_string_append_printf(lines, " %10"G_GUINT64_FORMAT, msg->av_format_change_timing->DTS);
420 g_string_append_printf(lines, "\r\n");
423 if (msg->preferred_display_mode) {
424 g_string_append_printf(lines, "wfd_preferred_display_mode");
425 g_string_append_printf(lines, ":");
426 if (msg->preferred_display_mode->displaymodesupported) {
427 g_string_append_printf(lines, " %06"G_GUINT64_FORMAT, msg->preferred_display_mode->p_clock);
428 g_string_append_printf(lines, " %04x", msg->preferred_display_mode->H);
429 g_string_append_printf(lines, " %04x", msg->preferred_display_mode->HB);
430 g_string_append_printf(lines, " %04x", msg->preferred_display_mode->HSPOL_HSOFF);
431 g_string_append_printf(lines, " %04x", msg->preferred_display_mode->HSW);
432 g_string_append_printf(lines, " %04x", msg->preferred_display_mode->V);
433 g_string_append_printf(lines, " %04x", msg->preferred_display_mode->VB);
434 g_string_append_printf(lines, " %04x", msg->preferred_display_mode->VSPOL_VSOFF);
435 g_string_append_printf(lines, " %04x", msg->preferred_display_mode->VSW);
436 g_string_append_printf(lines, " %02x", msg->preferred_display_mode->VBS3D);
437 g_string_append_printf(lines, " %02x", msg->preferred_display_mode->V2d_s3d_modes);
438 g_string_append_printf(lines, " %02x", msg->preferred_display_mode->P_depth);
439 } else g_string_append_printf(lines, " none");
440 g_string_append_printf(lines, "\r\n");
443 if (msg->uibc_capability) {
444 g_string_append_printf(lines, "wfd_uibc_capability");
445 g_string_append_printf(lines, ":");
446 if (msg->uibc_capability->uibcsupported) {
447 g_string_append_printf(lines, " input_category_list=");
448 if (msg->uibc_capability->input_category_list.input_cat) {
450 if (msg->uibc_capability->input_category_list.input_cat & WFD_UIBC_INPUT_CAT_GENERIC) {
451 tempcap |= WFD_UIBC_INPUT_CAT_GENERIC;
452 g_string_append_printf(lines, "GENERIC");
453 if (msg->uibc_capability->input_category_list.input_cat != tempcap) g_string_append_printf(lines, ", ");
455 if (msg->uibc_capability->input_category_list.input_cat & WFD_UIBC_INPUT_CAT_HIDC) {
456 tempcap |= WFD_UIBC_INPUT_CAT_HIDC;
457 g_string_append_printf(lines, "HIDC");
458 if (msg->uibc_capability->input_category_list.input_cat != tempcap) g_string_append_printf(lines, ", ");
460 } else g_string_append_printf(lines, "none");
461 g_string_append_printf(lines, ";");
462 g_string_append_printf(lines, " generic_cap_list=");
463 if (msg->uibc_capability->generic_cap_list.inp_type) {
465 if (msg->uibc_capability->generic_cap_list.inp_type & WFD_UIBC_INPUT_TYPE_KEYBOARD) {
466 tempcap |= WFD_UIBC_INPUT_TYPE_KEYBOARD;
467 g_string_append_printf(lines, "Keyboard");
468 if (msg->uibc_capability->generic_cap_list.inp_type != tempcap) g_string_append_printf(lines, ", ");
470 if (msg->uibc_capability->generic_cap_list.inp_type & WFD_UIBC_INPUT_TYPE_MOUSE) {
471 tempcap |= WFD_UIBC_INPUT_TYPE_MOUSE;
472 g_string_append_printf(lines, "Mouse");
473 if (msg->uibc_capability->generic_cap_list.inp_type != tempcap) g_string_append_printf(lines, ", ");
475 if (msg->uibc_capability->generic_cap_list.inp_type & WFD_UIBC_INPUT_TYPE_SINGLETOUCH) {
476 tempcap |= WFD_UIBC_INPUT_TYPE_SINGLETOUCH;
477 g_string_append_printf(lines, "SingleTouch");
478 if (msg->uibc_capability->generic_cap_list.inp_type != tempcap) g_string_append_printf(lines, ", ");
480 if (msg->uibc_capability->generic_cap_list.inp_type & WFD_UIBC_INPUT_TYPE_MULTITOUCH) {
481 tempcap |= WFD_UIBC_INPUT_TYPE_MULTITOUCH;
482 g_string_append_printf(lines, "MultiTouch");
483 if (msg->uibc_capability->generic_cap_list.inp_type != tempcap) g_string_append_printf(lines, ", ");
485 if (msg->uibc_capability->generic_cap_list.inp_type & WFD_UIBC_INPUT_TYPE_JOYSTICK) {
486 tempcap |= WFD_UIBC_INPUT_TYPE_JOYSTICK;
487 g_string_append_printf(lines, "Joystick");
488 if (msg->uibc_capability->generic_cap_list.inp_type != tempcap) g_string_append_printf(lines, ", ");
490 if (msg->uibc_capability->generic_cap_list.inp_type & WFD_UIBC_INPUT_TYPE_CAMERA) {
491 tempcap |= WFD_UIBC_INPUT_TYPE_CAMERA;
492 g_string_append_printf(lines, "Camera");
493 if (msg->uibc_capability->generic_cap_list.inp_type != tempcap) g_string_append_printf(lines, ", ");
495 if (msg->uibc_capability->generic_cap_list.inp_type & WFD_UIBC_INPUT_TYPE_GESTURE) {
496 tempcap |= WFD_UIBC_INPUT_TYPE_GESTURE;
497 g_string_append_printf(lines, "Gesture");
498 if (msg->uibc_capability->generic_cap_list.inp_type != tempcap) g_string_append_printf(lines, ", ");
500 if (msg->uibc_capability->generic_cap_list.inp_type & WFD_UIBC_INPUT_TYPE_REMOTECONTROL) {
501 tempcap |= WFD_UIBC_INPUT_TYPE_REMOTECONTROL;
502 g_string_append_printf(lines, "RemoteControl");
503 if (msg->uibc_capability->generic_cap_list.inp_type != tempcap) g_string_append_printf(lines, ", ");
505 } else g_string_append_printf(lines, "none");
506 g_string_append_printf(lines, ";");
507 g_string_append_printf(lines, " hidc_cap_list=");
508 if (msg->uibc_capability->hidc_cap_list.cap_count) {
509 detailed_cap *temp_cap = msg->uibc_capability->hidc_cap_list.next;
511 if (temp_cap->p.inp_type == WFD_UIBC_INPUT_TYPE_KEYBOARD) g_string_append_printf(lines, "Keyboard");
512 else if (temp_cap->p.inp_type == WFD_UIBC_INPUT_TYPE_MOUSE) g_string_append_printf(lines, "Mouse");
513 else if (temp_cap->p.inp_type == WFD_UIBC_INPUT_TYPE_SINGLETOUCH) g_string_append_printf(lines, "SingleTouch");
514 else if (temp_cap->p.inp_type == WFD_UIBC_INPUT_TYPE_MULTITOUCH) g_string_append_printf(lines, "MultiTouch");
515 else if (temp_cap->p.inp_type == WFD_UIBC_INPUT_TYPE_JOYSTICK) g_string_append_printf(lines, "Joystick");
516 else if (temp_cap->p.inp_type == WFD_UIBC_INPUT_TYPE_CAMERA) g_string_append_printf(lines, "Camera");
517 else if (temp_cap->p.inp_type == WFD_UIBC_INPUT_TYPE_GESTURE) g_string_append_printf(lines, "Gesture");
518 else if (temp_cap->p.inp_type == WFD_UIBC_INPUT_TYPE_REMOTECONTROL) g_string_append_printf(lines, "RemoteControl");
519 g_string_append_printf(lines, "/");
520 if (temp_cap->p.inp_path == WFD_UIBC_INPUT_PATH_INFRARED) g_string_append_printf(lines, "Infrared");
521 else if (temp_cap->p.inp_path == WFD_UIBC_INPUT_PATH_USB) g_string_append_printf(lines, "USB");
522 else if (temp_cap->p.inp_path == WFD_UIBC_INPUT_PATH_BT) g_string_append_printf(lines, "BT");
523 else if (temp_cap->p.inp_path == WFD_UIBC_INPUT_PATH_ZIGBEE) g_string_append_printf(lines, "Zigbee");
524 else if (temp_cap->p.inp_path == WFD_UIBC_INPUT_PATH_WIFI) g_string_append_printf(lines, "Wi-Fi");
525 else if (temp_cap->p.inp_path == WFD_UIBC_INPUT_PATH_NOSP) g_string_append_printf(lines, "No-SP");
526 temp_cap = temp_cap->next;
527 if (temp_cap) g_string_append_printf(lines, ", ");
529 } else g_string_append_printf(lines, "none");
530 g_string_append_printf(lines, ";");
531 if (msg->uibc_capability->tcp_port) g_string_append_printf(lines, "port=%u", msg->uibc_capability->tcp_port);
532 else g_string_append_printf(lines, "port=none");
533 } else g_string_append_printf(lines, " none");
534 g_string_append_printf(lines, "\r\n");
537 if (msg->uibc_setting) {
538 g_string_append_printf(lines, "wfd_uibc_setting");
539 g_string_append_printf(lines, ":");
540 if (msg->uibc_setting->uibc_setting)
541 g_string_append_printf(lines, " enable");
543 g_string_append_printf(lines, " disable");
544 g_string_append_printf(lines, "\r\n");
547 if (msg->standby_resume_capability) {
548 g_string_append_printf(lines, "wfd_standby_resume_capability");
549 g_string_append_printf(lines, ":");
550 if (msg->standby_resume_capability->standby_resume_cap)
551 g_string_append_printf(lines, " supported");
553 g_string_append_printf(lines, " none");
554 g_string_append_printf(lines, "\r\n");
558 g_string_append_printf(lines, "wfd_standby");
559 g_string_append_printf(lines, "\r\n");
562 if (msg->connector_type) {
563 g_string_append_printf(lines, "wfd_connector_type");
564 g_string_append_printf(lines, ":");
565 g_string_append_printf(lines, "\r\n");
568 if (msg->idr_request) {
569 g_string_append_printf(lines, "wfd_idr_request");
570 g_string_append_printf(lines, "\r\n");
573 /*g_string_append_printf (lines, "\0"); */
574 /*if(g_str_has_suffix (lines, "\r\n\0"))
576 guint32 length = g_strlen(lines);
577 lines[length-2] = '\0';
579 return g_string_free(lines, FALSE);
582 gchar *wfdconfig_parameter_names_as_text(const WFDMessage *msg)
584 /* change all vars so they match rfc? */
586 g_return_val_if_fail(msg != NULL, NULL);
588 lines = g_string_new("");
590 /* list of audio codecs */
591 if (msg->audio_codecs) {
592 g_string_append_printf(lines, "wfd_audio_codecs");
593 g_string_append_printf(lines, "\r\n");
595 /* list of video codecs */
596 if (msg->video_formats) {
597 g_string_append_printf(lines, "wfd_video_formats");
598 g_string_append_printf(lines, "\r\n");
600 /* list of video 3D codecs */
601 if (msg->video_3d_formats) {
602 g_string_append_printf(lines, "wfd_3d_video_formats");
603 g_string_append_printf(lines, "\r\n");
605 if (msg->content_protection) {
606 g_string_append_printf(lines, "wfd_content_protection");
607 g_string_append_printf(lines, "\r\n");
609 if (msg->display_edid) {
610 g_string_append_printf(lines, "wfd_display_edid");
611 g_string_append_printf(lines, "\r\n");
613 if (msg->coupled_sink) {
614 g_string_append_printf(lines, "wfd_coupled_sink");
615 g_string_append_printf(lines, "\r\n");
617 if (msg->trigger_method) {
618 g_string_append_printf(lines, "wfd_trigger_method");
619 g_string_append_printf(lines, "\r\n");
621 if (msg->presentation_url) {
622 g_string_append_printf(lines, "wfd_presentation_URL");
623 g_string_append_printf(lines, "\r\n");
625 if (msg->client_rtp_ports) {
626 g_string_append_printf(lines, "wfd_client_rtp_ports");
627 g_string_append_printf(lines, "\r\n");
630 g_string_append_printf(lines, "wfd_route");
631 g_string_append_printf(lines, "\r\n");
634 g_string_append_printf(lines, "wfd_I2C");
635 g_string_append_printf(lines, "\r\n");
637 if (msg->av_format_change_timing) {
638 g_string_append_printf(lines, "wfd_av_format_change_timing");
639 g_string_append_printf(lines, "\r\n");
641 if (msg->preferred_display_mode) {
642 g_string_append_printf(lines, "wfd_preferred_display_mode");
643 g_string_append_printf(lines, "\r\n");
645 if (msg->uibc_capability) {
646 g_string_append_printf(lines, "wfd_uibc_capability");
647 g_string_append_printf(lines, "\r\n");
649 if (msg->uibc_setting) {
650 g_string_append_printf(lines, "wfd_uibc_setting");
651 g_string_append_printf(lines, "\r\n");
653 if (msg->standby_resume_capability) {
654 g_string_append_printf(lines, "wfd_standby_resume_capability");
655 g_string_append_printf(lines, "\r\n");
658 g_string_append_printf(lines, "wfd_standby");
659 g_string_append_printf(lines, "\r\n");
661 if (msg->connector_type) {
662 g_string_append_printf(lines, "wfd_connector_type");
663 g_string_append_printf(lines, "\r\n");
665 if (msg->idr_request) {
666 g_string_append_printf(lines, "wfd_idr_request");
667 g_string_append_printf(lines, "\r\n");
669 return g_string_free(lines, FALSE);
673 read_string_space_ended(gchar *dest, guint size, gchar *src)
677 while (!g_ascii_isspace(*src) && *src != '\0') {
688 read_string_char_ended(gchar *dest, guint size, gchar del, gchar *src)
692 while (*src != del && *src != '\0') {
703 read_string_type_and_value(gchar *type, gchar *value, guint tsize, guint vsize, gchar del, gchar *src)
708 while (*src != del && *src != '\0') {
719 while (*src != '\0') {
729 wfdconfig_parse_line(WFDMessage *msg, gchar *buffer)
731 gchar type[8192] = {0};
732 gchar value[8192] = {0};
733 gchar temp[8192] = {0};
736 gchar *result = NULL;
738 #define WFD_SKIP_SPACE(q) if (*q && g_ascii_isspace(*q)) q++;
739 #define WFD_SKIP_EQUAL(q) if (*q && *q == '=') q++;
740 #define WFD_SKIP_COMMA(q) if (*q && g_ascii_ispunct(*q)) q++;
741 #define WFD_READ_STRING(field) read_string_space_ended(temp, sizeof(temp), v); v += strlen(temp); REPLACE_STRING(field, temp);
742 #define WFD_READ_CHAR_END_STRING(field, del) read_string_char_ended(temp, sizeof(temp), del, v); v += strlen(temp); REPLACE_STRING(field, temp);
743 #define WFD_READ_UINT32(field) read_string_space_ended(temp, sizeof(temp), v); v += strlen(temp); field = strtoul(temp, NULL, 16);
744 #define WFD_READ_UINT32_DIGIT(field) read_string_space_ended(temp, sizeof(temp), v); v += strlen(temp); field = strtoul(temp, NULL, 10);
746 /*g_print("wfdconfig_parse_line input: %s\n", buffer); */
747 read_string_type_and_value(type, value, sizeof(type), sizeof(value), ':', p);
748 /*g_print("wfdconfig_parse_line type:%s value:%s\n", type, value); */
749 if (!g_strcmp0(type, "wfd_audio_codecs")) {
750 msg->audio_codecs = g_new0(WFDAudioCodeclist, 1);
753 msg->audio_codecs->count = strlen(v) / 16;
754 msg->audio_codecs->list = g_new0(WFDAudioCodec, msg->audio_codecs->count);
755 for (; i < msg->audio_codecs->count; i++) {
757 WFD_READ_STRING(msg->audio_codecs->list[i].audio_format);
759 WFD_READ_UINT32(msg->audio_codecs->list[i].modes);
761 WFD_READ_UINT32(msg->audio_codecs->list[i].latency);
765 } else if (!g_strcmp0(type, "wfd_video_formats")) {
766 msg->video_formats = g_new0(WFDVideoCodeclist, 1);
768 msg->video_formats->count = 1;
769 msg->video_formats->list = g_new0(WFDVideoCodec, 1);
771 WFD_READ_UINT32(msg->video_formats->list->native);
773 WFD_READ_UINT32(msg->video_formats->list->preferred_display_mode_supported);
775 WFD_READ_UINT32(msg->video_formats->list->H264_codec.profile);
777 WFD_READ_UINT32(msg->video_formats->list->H264_codec.level);
779 WFD_READ_UINT32(msg->video_formats->list->H264_codec.misc_params.CEA_Support);
781 WFD_READ_UINT32(msg->video_formats->list->H264_codec.misc_params.VESA_Support);
783 WFD_READ_UINT32(msg->video_formats->list->H264_codec.misc_params.HH_Support);
785 WFD_READ_UINT32(msg->video_formats->list->H264_codec.misc_params.latency);
787 WFD_READ_UINT32(msg->video_formats->list->H264_codec.misc_params.min_slice_size);
789 WFD_READ_UINT32(msg->video_formats->list->H264_codec.misc_params.slice_enc_params);
791 WFD_READ_UINT32(msg->video_formats->list->H264_codec.misc_params.frame_rate_control_support);
793 if (msg->video_formats->list->preferred_display_mode_supported == 1) {
794 WFD_READ_UINT32(msg->video_formats->list->H264_codec.max_hres);
796 WFD_READ_UINT32(msg->video_formats->list->H264_codec.max_vres);
800 } else if (!g_strcmp0(type, "wfd_3d_video_formats")) {
801 msg->video_3d_formats = g_new0(WFD3DFormats, 1);
803 msg->video_3d_formats->count = 1;
804 msg->video_3d_formats->list = g_new0(WFD3dCapList, 1);
806 WFD_READ_UINT32(msg->video_3d_formats->list->native);
808 WFD_READ_UINT32(msg->video_3d_formats->list->preferred_display_mode_supported);
810 WFD_READ_UINT32(msg->video_3d_formats->list->H264_codec.profile);
812 WFD_READ_UINT32(msg->video_3d_formats->list->H264_codec.level);
814 WFD_READ_UINT32(msg->video_3d_formats->list->H264_codec.misc_params.video_3d_capability);
816 WFD_READ_UINT32(msg->video_3d_formats->list->H264_codec.misc_params.latency);
818 WFD_READ_UINT32(msg->video_3d_formats->list->H264_codec.misc_params.min_slice_size);
820 WFD_READ_UINT32(msg->video_3d_formats->list->H264_codec.misc_params.slice_enc_params);
822 WFD_READ_UINT32(msg->video_3d_formats->list->H264_codec.misc_params.frame_rate_control_support);
824 if (msg->video_3d_formats->list->preferred_display_mode_supported == 1) {
825 WFD_READ_UINT32(msg->video_3d_formats->list->H264_codec.max_hres);
827 WFD_READ_UINT32(msg->video_3d_formats->list->H264_codec.max_vres);
831 } else if (!g_strcmp0(type, "wfd_content_protection")) {
832 msg->content_protection = g_new0(WFDContentProtection, 1);
835 msg->content_protection->hdcp2_spec = g_new0(WFDHdcp2Spec, 1);
836 if (strstr(v, "none")) {
837 msg->content_protection->hdcp2_spec->hdcpversion = g_strdup("none");
839 WFD_READ_STRING(msg->content_protection->hdcp2_spec->hdcpversion);
841 WFD_READ_STRING(msg->content_protection->hdcp2_spec->TCPPort);
844 } else if (!g_strcmp0(type, "wfd_display_edid")) {
845 msg->display_edid = g_new0(WFDDisplayEdid, 1);
848 if (strstr(v, "none")) {
849 msg->display_edid->edid_supported = 0;
851 msg->display_edid->edid_supported = 1;
852 WFD_READ_UINT32(msg->display_edid->edid_block_count);
854 if (msg->display_edid->edid_block_count) {
855 gchar *edid_string = v;
856 int i = 0, j = 0, size = 0;
857 guint32 payload_size = EDID_BLOCK_SIZE * msg->display_edid->edid_block_count;
858 msg->display_edid->edid_payload = g_malloc(payload_size);
859 size = EDID_BLOCK_SIZE * msg->display_edid->edid_block_count * 2;
860 for (; i < size; j++) {
862 if (edid_string[i] > 0x29 && edid_string[i] < 0x40) k = edid_string[i] - 48;
863 else if (edid_string[i] > 0x60 && edid_string[i] < 0x67) k = edid_string[i] - 87;
864 else if (edid_string[i] > 0x40 && edid_string[i] < 0x47) k = edid_string[i] - 55;
866 if (edid_string[i + 1] > 0x29 && edid_string[i + 1] < 0x40) kk = edid_string[i + 1] - 48;
867 else if (edid_string[i + 1] > 0x60 && edid_string[i + 1] < 0x67) kk = edid_string[i + 1] - 87;
868 else if (edid_string[i + 1] > 0x40 && edid_string[i + 1] < 0x47) kk = edid_string[i + 1] - 55;
870 msg->display_edid->edid_payload[j] = (k << 4) | kk;
873 /*memcpy(msg->display_edid->edid_payload, v, payload_size); */
874 v += (payload_size * 2);
875 } else v += strlen(v);
878 } else if (!g_strcmp0(type, "wfd_coupled_sink")) {
879 msg->coupled_sink = g_new0(WFDCoupledSink, 1);
881 msg->coupled_sink->coupled_sink_cap = g_new0(WFDCoupled_sink_cap, 1);
883 WFD_READ_UINT32(msg->coupled_sink->coupled_sink_cap->status);
885 WFD_READ_STRING(msg->coupled_sink->coupled_sink_cap->sink_address);
887 } else if (!g_strcmp0(type, "wfd_trigger_method")) {
888 msg->trigger_method = g_new0(WFDTriggerMethod, 1);
891 WFD_READ_STRING(msg->trigger_method->wfd_trigger_method);
893 } else if (!g_strcmp0(type, "wfd_presentation_URL")) {
894 msg->presentation_url = g_new0(WFDPresentationUrl, 1);
897 WFD_READ_STRING(msg->presentation_url->wfd_url0);
899 WFD_READ_STRING(msg->presentation_url->wfd_url1);
901 } else if (!g_strcmp0(type, "wfd_client_rtp_ports")) {
902 msg->client_rtp_ports = g_new0(WFDClientRtpPorts, 1);
905 WFD_READ_STRING(msg->client_rtp_ports->profile);
907 WFD_READ_UINT32_DIGIT(msg->client_rtp_ports->rtp_port0);
909 WFD_READ_UINT32_DIGIT(msg->client_rtp_ports->rtp_port1);
911 WFD_READ_STRING(msg->client_rtp_ports->mode);
913 } else if (!g_strcmp0(type, "wfd_route")) {
914 msg->route = g_new0(WFDRoute, 1);
917 WFD_READ_STRING(msg->route->destination);
919 } else if (!g_strcmp0(type, "wfd_I2C")) {
920 msg->I2C = g_new0(WFDI2C, 1);
922 msg->I2C->I2CPresent = TRUE;
924 WFD_READ_UINT32_DIGIT(msg->I2C->I2C_port);
925 if (msg->I2C->I2C_port) msg->I2C->I2CPresent = TRUE;
927 } else if (!g_strcmp0(type, "wfd_av_format_change_timing")) {
928 msg->av_format_change_timing = g_new0(WFDAVFormatChangeTiming, 1);
931 WFD_READ_UINT32(msg->av_format_change_timing->PTS);
933 WFD_READ_UINT32(msg->av_format_change_timing->DTS);
935 } else if (!g_strcmp0(type, "wfd_preferred_display_mode")) {
936 msg->preferred_display_mode = g_new0(WFDPreferredDisplayMode, 1);
939 if (!strstr(v, "none")) {
940 msg->preferred_display_mode->displaymodesupported = FALSE;
942 WFD_READ_UINT32(msg->preferred_display_mode->p_clock);
944 WFD_READ_UINT32(msg->preferred_display_mode->H);
946 WFD_READ_UINT32(msg->preferred_display_mode->HB);
948 WFD_READ_UINT32(msg->preferred_display_mode->HSPOL_HSOFF);
950 WFD_READ_UINT32(msg->preferred_display_mode->HSW);
952 WFD_READ_UINT32(msg->preferred_display_mode->V);
954 WFD_READ_UINT32(msg->preferred_display_mode->VB);
956 WFD_READ_UINT32(msg->preferred_display_mode->VSPOL_VSOFF);
958 WFD_READ_UINT32(msg->preferred_display_mode->VSW);
960 WFD_READ_UINT32(msg->preferred_display_mode->VBS3D);
962 WFD_READ_UINT32(msg->preferred_display_mode->V2d_s3d_modes);
964 WFD_READ_UINT32(msg->preferred_display_mode->P_depth);
966 WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.profile);
968 WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.level);
970 WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.misc_params.CEA_Support);
972 WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.misc_params.VESA_Support);
974 WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.misc_params.HH_Support);
976 WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.misc_params.latency);
978 WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.misc_params.min_slice_size);
980 WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.misc_params.slice_enc_params);
982 WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.misc_params.frame_rate_control_support);
984 WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.max_hres);
986 WFD_READ_UINT32(msg->preferred_display_mode->H264_codec.max_vres);
990 } else if (!g_strcmp0(type, "wfd_uibc_capability")) {
991 msg->uibc_capability = g_new0(WFDUibcCapability, 1);
992 if (strstr(v, "input_category_list")) {
993 gchar *tstring = NULL;
994 msg->uibc_capability->uibcsupported = TRUE;
996 WFD_READ_CHAR_END_STRING(tstring, '=');
997 if (!g_strcmp0(tstring, "input_category_list")) {
998 gchar temp2[8192] = {0};
999 guint rem_len = 0, read_len = 0;
1000 WFD_READ_CHAR_END_STRING(tstring, ';');
1001 rem_len = strlen(tstring);
1004 read_string_char_ended(temp2, 8192, ',', tstring + read_len);
1005 read_len += (strlen(temp2) + 1);
1006 if (strstr(temp2, "GENERIC")) msg->uibc_capability->input_category_list.input_cat |= WFD_UIBC_INPUT_CAT_GENERIC;
1007 else if (strstr(temp2, "HIDC")) msg->uibc_capability->input_category_list.input_cat |= WFD_UIBC_INPUT_CAT_HIDC;
1008 else msg->uibc_capability->input_category_list.input_cat |= WFD_UIBC_INPUT_CAT_UNKNOWN;
1009 } while (read_len < rem_len);
1011 result = strstr(v, "generic_cap_list");
1012 if (result != NULL) {
1013 memset(temp2, 0, 8192);
1017 WFD_READ_CHAR_END_STRING(tstring, '=');
1018 if (!g_strcmp0(tstring, "generic_cap_list")) {
1020 WFD_READ_CHAR_END_STRING(tstring, ';');
1021 rem_len = strlen(tstring);
1023 read_string_char_ended(temp2, 8192, ',', tstring + read_len);
1024 read_len += (strlen(temp2) + 1);
1025 if (strstr(temp2, "Keyboard")) msg->uibc_capability->generic_cap_list.inp_type |= WFD_UIBC_INPUT_TYPE_KEYBOARD;
1026 else if (strstr(temp2, "Mouse")) msg->uibc_capability->generic_cap_list.inp_type |= WFD_UIBC_INPUT_TYPE_MOUSE;
1027 else if (strstr(temp2, "SingleTouch")) msg->uibc_capability->generic_cap_list.inp_type |= WFD_UIBC_INPUT_TYPE_SINGLETOUCH;
1028 else if (strstr(temp2, "MultiTouch")) msg->uibc_capability->generic_cap_list.inp_type |= WFD_UIBC_INPUT_TYPE_MULTITOUCH;
1029 else if (strstr(temp2, "Joystick")) msg->uibc_capability->generic_cap_list.inp_type |= WFD_UIBC_INPUT_TYPE_JOYSTICK;
1030 else if (strstr(temp2, "Camera")) msg->uibc_capability->generic_cap_list.inp_type |= WFD_UIBC_INPUT_TYPE_CAMERA;
1031 else if (strstr(temp2, "Gesture")) msg->uibc_capability->generic_cap_list.inp_type |= WFD_UIBC_INPUT_TYPE_GESTURE;
1032 else if (strstr(temp2, "RemoteControl")) msg->uibc_capability->generic_cap_list.inp_type |= WFD_UIBC_INPUT_TYPE_REMOTECONTROL;
1033 else msg->uibc_capability->generic_cap_list.inp_type |= WFD_UIBC_INPUT_TYPE_UNKNOWN;
1034 } while (read_len < rem_len);
1037 result = strstr(v, "hidc_cap_list");
1038 if (result != NULL) {
1041 WFD_READ_CHAR_END_STRING(tstring, '=');
1042 if (!g_strcmp0(tstring, "hidc_cap_list")) {
1043 gchar inp_type[8192];
1044 gchar inp_path[8192];
1045 memset(temp2, 0, 8192);
1048 detailed_cap *temp_cap;
1049 WFD_READ_CHAR_END_STRING(tstring, ';');
1050 rem_len = strlen(tstring);
1051 msg->uibc_capability->hidc_cap_list.next = g_new0(detailed_cap, 1);
1052 temp_cap = msg->uibc_capability->hidc_cap_list.next;
1054 msg->uibc_capability->hidc_cap_list.cap_count++;
1055 read_string_char_ended(temp2, 8192, ',', tstring + read_len);
1056 read_len += (strlen(temp2) + 1);
1057 read_string_type_and_value(inp_type, inp_path, sizeof(inp_type), sizeof(inp_path), '/', temp2);
1058 if (strstr(inp_type, "Keyboard")) temp_cap->p.inp_type = WFD_UIBC_INPUT_TYPE_KEYBOARD;
1059 else if (strstr(inp_type, "Mouse")) temp_cap->p.inp_type = WFD_UIBC_INPUT_TYPE_MOUSE;
1060 else if (strstr(inp_type, "SingleTouch")) temp_cap->p.inp_type = WFD_UIBC_INPUT_TYPE_SINGLETOUCH;
1061 else if (strstr(inp_type, "MultiTouch")) temp_cap->p.inp_type = WFD_UIBC_INPUT_TYPE_MULTITOUCH;
1062 else if (strstr(inp_type, "Joystick")) temp_cap->p.inp_type = WFD_UIBC_INPUT_TYPE_JOYSTICK;
1063 else if (strstr(inp_type, "Camera")) temp_cap->p.inp_type = WFD_UIBC_INPUT_TYPE_CAMERA;
1064 else if (strstr(inp_type, "Gesture")) temp_cap->p.inp_type = WFD_UIBC_INPUT_TYPE_GESTURE;
1065 else if (strstr(inp_type, "RemoteControl")) temp_cap->p.inp_type = WFD_UIBC_INPUT_TYPE_REMOTECONTROL;
1066 else temp_cap->p.inp_type = WFD_UIBC_INPUT_TYPE_UNKNOWN;
1068 if (strstr(inp_path, "Infrared")) temp_cap->p.inp_path = WFD_UIBC_INPUT_PATH_INFRARED;
1069 else if (strstr(inp_path, "USB")) temp_cap->p.inp_path = WFD_UIBC_INPUT_PATH_USB;
1070 else if (strstr(inp_path, "BT")) temp_cap->p.inp_path = WFD_UIBC_INPUT_PATH_BT;
1071 else if (strstr(inp_path, "Zigbee")) temp_cap->p.inp_path = WFD_UIBC_INPUT_PATH_ZIGBEE;
1072 else if (strstr(inp_path, "Wi-Fi")) temp_cap->p.inp_path = WFD_UIBC_INPUT_PATH_WIFI;
1073 else if (strstr(inp_path, "No-SP")) temp_cap->p.inp_path = WFD_UIBC_INPUT_PATH_NOSP;
1074 else temp_cap->p.inp_path = WFD_UIBC_INPUT_PATH_UNKNOWN;
1075 if (read_len < rem_len) {
1076 temp_cap->next = g_new0(detailed_cap, 1);
1077 temp_cap = temp_cap->next;
1079 } while (read_len < rem_len);
1082 result = strstr(v, "port");
1083 if (result != NULL) {
1085 WFD_READ_CHAR_END_STRING(tstring, '=');
1086 if (!g_strcmp0(tstring, "port")) {
1088 WFD_READ_CHAR_END_STRING(tstring, ';');
1089 if (!strstr(tstring, "none")) {
1090 msg->uibc_capability->tcp_port = strtoul(tstring, NULL, 10);
1095 } else if (strstr(v, "none")) {
1096 msg->uibc_capability->uibcsupported = FALSE;
1098 } else if (!g_strcmp0(type, "wfd_uibc_setting")) {
1099 msg->uibc_setting = g_new0(WFDUibcSetting, 1);
1102 if (!g_strcmp0(v, "enable"))
1103 msg->uibc_setting->uibc_setting = TRUE;
1105 msg->uibc_setting->uibc_setting = FALSE;
1107 } else if (!g_strcmp0(type, "wfd_standby_resume_capability")) {
1108 msg->standby_resume_capability = g_new0(WFDStandbyResumeCapability, 1);
1111 if (!g_strcmp0(v, "supported"))
1112 msg->standby_resume_capability->standby_resume_cap = TRUE;
1114 msg->standby_resume_capability->standby_resume_cap = FALSE;
1116 } else if (!g_strcmp0(type, "wfd_standby")) {
1117 msg->standby = g_new0(WFDStandby, 1);
1118 msg->standby->wfd_standby = TRUE;
1119 } else if (!g_strcmp0(type, "wfd_connector_type")) {
1120 msg->connector_type = g_new0(WFDConnectorType, 1);
1122 msg->connector_type->supported = TRUE;
1124 WFD_READ_UINT32(msg->connector_type->connector_type);
1126 } else if (!g_strcmp0(type, "wfd_idr_request")) {
1127 msg->idr_request = g_new0(WFDIdrRequest, 1);
1128 msg->idr_request->idr_request = TRUE;
1135 * wfdconfig_message_parse_buffer:
1136 * @data: the start of the buffer
1137 * @size: the size of the buffer
1138 * @msg: the result #WFDMessage
1140 * Parse the contents of @size bytes pointed to by @data and store the result in
1143 * Returns: #WFD_OK on success.
1146 wfdconfig_message_parse_buffer(const guint8 *data, guint size, WFDMessage *msg)
1149 gchar buffer[MAX_LINE_LEN] = {0};
1152 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1153 g_return_val_if_fail(data != NULL, WFD_EINVAL);
1154 g_return_val_if_fail(size != 0, WFD_EINVAL);
1156 p = (const gchar *) data;
1163 while (*p != '\n' && *p != '\r' && *p != '\0') {
1164 if (idx < sizeof(buffer) - 1)
1169 wfdconfig_parse_line(msg, buffer);
1180 * wfdconfig_message_dump:
1181 * @msg: a #WFDMessage
1183 * Dump the parsed contents of @msg to stdout.
1185 * Returns: a #WFDResult.
1188 wfdconfig_message_dump(const WFDMessage *msg)
1190 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1191 wfd_debug("===========WFD Message dump=========");
1193 if (msg->audio_codecs) {
1195 wfd_debug("Audio supported formats : \n");
1196 for (; i < msg->audio_codecs->count; i++) {
1197 wfd_debug("Codec: %s\n", msg->audio_codecs->list[i].audio_format);
1198 if (!strcmp(msg->audio_codecs->list[i].audio_format, "LPCM")) {
1199 if (msg->audio_codecs->list[i].modes & WFD_FREQ_44100)
1200 wfd_debug(" Freq: %d\n", 44100);
1201 if (msg->audio_codecs->list[i].modes & WFD_FREQ_48000)
1202 wfd_debug(" Freq: %d\n", 48000);
1203 wfd_debug(" Channels: %d\n", 2);
1205 if (!strcmp(msg->audio_codecs->list[i].audio_format, "AAC")) {
1206 wfd_debug(" Freq: %d\n", 48000);
1207 if (msg->audio_codecs->list[i].modes & WFD_CHANNEL_2)
1208 wfd_debug(" Channels: %d\n", 2);
1209 if (msg->audio_codecs->list[i].modes & WFD_CHANNEL_4)
1210 wfd_debug(" Channels: %d\n", 4);
1211 if (msg->audio_codecs->list[i].modes & WFD_CHANNEL_6)
1212 wfd_debug(" Channels: %d\n", 6);
1213 if (msg->audio_codecs->list[i].modes & WFD_CHANNEL_8)
1214 wfd_debug(" Channels: %d\n", 8);
1216 if (!strcmp(msg->audio_codecs->list[i].audio_format, "AC3")) {
1217 wfd_debug(" Freq: %d\n", 48000);
1218 if (msg->audio_codecs->list[i].modes & WFD_CHANNEL_2)
1219 wfd_debug(" Channels: %d\n", 2);
1220 if (msg->audio_codecs->list[i].modes & WFD_CHANNEL_4)
1221 wfd_debug(" Channels: %d\n", 4);
1222 if (msg->audio_codecs->list[i].modes & WFD_CHANNEL_6)
1223 wfd_debug(" Channels: %d\n", 6);
1225 wfd_debug(" Bitwidth: %d\n", 16);
1226 wfd_debug(" Latency: %d\n", msg->audio_codecs->list[i].latency);
1231 if (msg->video_formats) {
1232 wfd_debug("Video supported formats : \n");
1233 if (msg->video_formats->list) {
1234 wfd_debug("Codec: H264\n");
1235 guint nativeindex = 0;
1236 if ((msg->video_formats->list->native & 0x7) == WFD_VIDEO_CEA_RESOLUTION) {
1237 wfd_debug(" Native type: CEA\n");
1238 } else if ((msg->video_formats->list->native & 0x7) == WFD_VIDEO_VESA_RESOLUTION) {
1239 wfd_debug(" Native type: VESA\n");
1240 } else if ((msg->video_formats->list->native & 0x7) == WFD_VIDEO_HH_RESOLUTION) {
1241 wfd_debug(" Native type: HH\n");
1243 nativeindex = msg->video_formats->list->native >> 3;
1244 wfd_debug(" Resolution: %d\n", (1 << nativeindex));
1246 if (msg->video_formats->list->H264_codec.profile & WFD_H264_BASE_PROFILE) {
1247 wfd_debug(" Profile: BASE\n");
1248 } else if (msg->video_formats->list->H264_codec.profile & WFD_H264_HIGH_PROFILE) {
1249 wfd_debug(" Profile: HIGH\n");
1251 if (msg->video_formats->list->H264_codec.level & WFD_H264_LEVEL_3_1) {
1252 wfd_debug(" Level: 3.1\n");
1253 } else if (msg->video_formats->list->H264_codec.level & WFD_H264_LEVEL_3_2) {
1254 wfd_debug(" Level: 3.2\n");
1255 } else if (msg->video_formats->list->H264_codec.level & WFD_H264_LEVEL_4) {
1256 wfd_debug(" Level: 4\n");
1257 } else if (msg->video_formats->list->H264_codec.level & WFD_H264_LEVEL_4_1) {
1258 wfd_debug(" Level: 4.1\n");
1259 } else if (msg->video_formats->list->H264_codec.level & WFD_H264_LEVEL_4_2) {
1260 wfd_debug(" Level: 4.2\n");
1262 wfd_debug(" Latency: %d\n", msg->video_formats->list->H264_codec.misc_params.latency);
1263 wfd_debug(" min_slice_size: %x\n", msg->video_formats->list->H264_codec.misc_params.min_slice_size);
1264 wfd_debug(" slice_enc_params: %x\n", msg->video_formats->list->H264_codec.misc_params.slice_enc_params);
1265 wfd_debug(" frame_rate_control_support: %x\n", msg->video_formats->list->H264_codec.misc_params.frame_rate_control_support);
1266 if (msg->video_formats->list->H264_codec.max_hres) {
1267 wfd_debug(" Max Width: %04d\n", msg->video_formats->list->H264_codec.max_hres);
1269 if (msg->video_formats->list->H264_codec.max_vres) {
1270 wfd_debug(" Max Height: %04d\n", msg->video_formats->list->H264_codec.max_vres);
1275 if (msg->video_3d_formats) {
1276 wfd_debug("wfd_3d_formats");
1280 if (msg->content_protection) {
1281 wfd_debug("wfd_content_protection");
1285 if (msg->display_edid) {
1286 wfd_debug("wfd_display_edid");
1290 if (msg->coupled_sink) {
1291 wfd_debug("wfd_coupled_sink");
1295 if (msg->trigger_method) {
1296 wfd_debug(" Trigger type: %s\n", msg->trigger_method->wfd_trigger_method);
1299 if (msg->presentation_url) {
1300 wfd_debug("wfd_presentation_URL");
1304 if (msg->client_rtp_ports) {
1305 wfd_debug(" Client RTP Ports : \n");
1306 if (msg->client_rtp_ports->profile) {
1307 wfd_debug("%s\n", msg->client_rtp_ports->profile);
1308 wfd_debug(" %d\n", msg->client_rtp_ports->rtp_port0);
1309 wfd_debug(" %d\n", msg->client_rtp_ports->rtp_port1);
1310 wfd_debug(" %s\n", msg->client_rtp_ports->mode);
1316 wfd_debug("wfd_route");
1321 wfd_debug("wfd_I2C");
1325 if (msg->av_format_change_timing) {
1326 wfd_debug("wfd_av_format_change_timing");
1330 if (msg->preferred_display_mode) {
1331 wfd_debug("wfd_preferred_display_mode");
1335 if (msg->uibc_capability) {
1336 wfd_debug("wfd_uibc_capability \r\n");
1337 wfd_debug("input category list:");
1338 if (msg->uibc_capability->input_category_list.input_cat & WFD_UIBC_INPUT_CAT_GENERIC)
1339 wfd_debug("GENERIC");
1340 if (msg->uibc_capability->input_category_list.input_cat & WFD_UIBC_INPUT_CAT_HIDC)
1342 if (!msg->uibc_capability->input_category_list.input_cat)
1344 if (msg->uibc_capability->input_category_list.input_cat & WFD_UIBC_INPUT_CAT_GENERIC) {
1345 wfd_debug("generic cap list: ");
1346 if (msg->uibc_capability->generic_cap_list.inp_type & WFD_UIBC_INPUT_TYPE_KEYBOARD)
1347 wfd_debug("keyboard ");
1348 if (msg->uibc_capability->generic_cap_list.inp_type & WFD_UIBC_INPUT_TYPE_MOUSE)
1349 wfd_debug("mouse ");
1350 if (msg->uibc_capability->generic_cap_list.inp_type & WFD_UIBC_INPUT_TYPE_SINGLETOUCH)
1351 wfd_debug("single-touch ");
1352 if (msg->uibc_capability->generic_cap_list.inp_type & WFD_UIBC_INPUT_TYPE_MULTITOUCH)
1353 wfd_debug("multi-touch ");
1354 if (msg->uibc_capability->generic_cap_list.inp_type & WFD_UIBC_INPUT_TYPE_JOYSTICK)
1355 wfd_debug("joystick ");
1356 if (msg->uibc_capability->generic_cap_list.inp_type & WFD_UIBC_INPUT_TYPE_CAMERA)
1357 wfd_debug("camera ");
1358 if (msg->uibc_capability->generic_cap_list.inp_type & WFD_UIBC_INPUT_TYPE_GESTURE)
1359 wfd_debug("gesture ");
1360 if (msg->uibc_capability->generic_cap_list.inp_type & WFD_UIBC_INPUT_TYPE_REMOTECONTROL)
1361 wfd_debug("remote control ");
1362 if (!msg->uibc_capability->generic_cap_list.inp_type)
1365 if (msg->uibc_capability->input_category_list.input_cat & WFD_UIBC_INPUT_CAT_HIDC) {
1366 wfd_debug("hidc cap list:");
1367 if (msg->uibc_capability->hidc_cap_list.cap_count) {
1368 detailed_cap *temp_cap = msg->uibc_capability->hidc_cap_list.next;
1370 if (temp_cap->p.inp_type & WFD_UIBC_INPUT_TYPE_KEYBOARD) {
1371 wfd_debug("keyboard ");
1372 } else if (temp_cap->p.inp_type & WFD_UIBC_INPUT_TYPE_MOUSE) {
1373 wfd_debug("mouse ");
1374 } else if (temp_cap->p.inp_type & WFD_UIBC_INPUT_TYPE_SINGLETOUCH) {
1375 wfd_debug("single-touch ");
1376 } else if (temp_cap->p.inp_type & WFD_UIBC_INPUT_TYPE_MULTITOUCH) {
1377 wfd_debug("multi-touch ");
1378 } else if (temp_cap->p.inp_type & WFD_UIBC_INPUT_TYPE_JOYSTICK) {
1379 wfd_debug("joystick ");
1380 } else if (temp_cap->p.inp_type & WFD_UIBC_INPUT_TYPE_CAMERA) {
1381 wfd_debug("camera ");
1382 } else if (temp_cap->p.inp_type & WFD_UIBC_INPUT_TYPE_GESTURE) {
1383 wfd_debug("gesture ");
1384 } else if (temp_cap->p.inp_type & WFD_UIBC_INPUT_TYPE_REMOTECONTROL) {
1385 wfd_debug("remote control ");
1386 } else if (!temp_cap->p.inp_type) {
1389 if (temp_cap->p.inp_path & WFD_UIBC_INPUT_PATH_INFRARED) {
1390 wfd_debug("infrared");
1391 } else if (temp_cap->p.inp_path & WFD_UIBC_INPUT_PATH_USB) {
1393 } else if (temp_cap->p.inp_path & WFD_UIBC_INPUT_PATH_BT) {
1394 wfd_debug("bluetooth");
1395 } else if (temp_cap->p.inp_path & WFD_UIBC_INPUT_PATH_WIFI) {
1397 } else if (temp_cap->p.inp_path & WFD_UIBC_INPUT_PATH_ZIGBEE) {
1398 wfd_debug("Zigbee");
1399 } else if (temp_cap->p.inp_path & WFD_UIBC_INPUT_PATH_NOSP) {
1401 } else if (!temp_cap->p.inp_path) {
1404 temp_cap = temp_cap->next;
1408 if (msg->uibc_capability->tcp_port)
1409 wfd_debug("tcp port:%u", msg->uibc_capability->tcp_port);
1410 if (!msg->uibc_capability->tcp_port)
1411 wfd_debug("tcp port: none");
1415 if (msg->uibc_setting) {
1416 wfd_debug("wfd_uibc_setting: ");
1417 if (msg->uibc_setting->uibc_setting) {
1419 } else wfd_debug("false");
1423 if (msg->standby_resume_capability) {
1424 wfd_debug("wfd_standby_resume_capability");
1429 wfd_debug("wfd_standby");
1433 if (msg->connector_type) {
1434 wfd_debug("wfd_connector_type");
1438 if (msg->idr_request) {
1439 wfd_debug("wfd_idr_request");
1443 wfd_debug("===============================================\n");
1447 WFDResult wfdconfig_set_supported_audio_format(WFDMessage *msg, WFDAudioFormats aCodec, guint aFreq, guint aChanels,
1448 guint aBitwidth, guint32 aLatency)
1450 guint temp = aCodec;
1452 guint pcm = 0, aac = 0, ac3 = 0;
1454 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1456 if (!msg->audio_codecs)
1457 msg->audio_codecs = g_new0(WFDAudioCodeclist, 1);
1459 if (aCodec != WFD_AUDIO_UNKNOWN) {
1461 msg->audio_codecs->count++;
1464 msg->audio_codecs->list = g_new0(WFDAudioCodec, msg->audio_codecs->count);
1465 for (; i < msg->audio_codecs->count; i++) {
1466 if ((aCodec & WFD_AUDIO_LPCM) && (!pcm)) {
1467 msg->audio_codecs->list[i].audio_format = g_strdup("LPCM");
1468 msg->audio_codecs->list[i].modes = aFreq;
1469 msg->audio_codecs->list[i].latency = aLatency;
1471 } else if ((aCodec & WFD_AUDIO_AAC) && (!aac)) {
1472 msg->audio_codecs->list[i].audio_format = g_strdup("AAC");
1473 msg->audio_codecs->list[i].modes = aChanels;
1474 msg->audio_codecs->list[i].latency = aLatency;
1476 } else if ((aCodec & WFD_AUDIO_AC3) && (!ac3)) {
1477 msg->audio_codecs->list[i].audio_format = g_strdup("AC3");
1478 msg->audio_codecs->list[i].modes = aChanels;
1479 msg->audio_codecs->list[i].latency = aLatency;
1487 WFDResult wfdconfig_set_prefered_audio_format(WFDMessage *msg, WFDAudioFormats aCodec, WFDAudioFreq aFreq, WFDAudioChannels aChanels,
1488 guint aBitwidth, guint32 aLatency)
1491 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1493 if (!msg->audio_codecs)
1494 msg->audio_codecs = g_new0(WFDAudioCodeclist, 1);
1496 msg->audio_codecs->list = g_new0(WFDAudioCodec, 1);
1497 msg->audio_codecs->count = 1;
1498 if (aCodec == WFD_AUDIO_LPCM) {
1499 msg->audio_codecs->list->audio_format = g_strdup("LPCM");
1500 msg->audio_codecs->list->modes = aFreq;
1501 msg->audio_codecs->list->latency = aLatency;
1502 } else if (aCodec == WFD_AUDIO_AAC) {
1503 msg->audio_codecs->list->audio_format = g_strdup("AAC");
1504 msg->audio_codecs->list->modes = aChanels;
1505 msg->audio_codecs->list->latency = aLatency;
1506 } else if (aCodec == WFD_AUDIO_AC3) {
1507 msg->audio_codecs->list->audio_format = g_strdup("AC3");
1508 msg->audio_codecs->list->modes = aChanels;
1509 msg->audio_codecs->list->latency = aLatency;
1514 WFDResult wfdconfig_get_supported_audio_format(WFDMessage *msg, guint *aCodec, guint *aFreq, guint *aChanels,
1515 guint *aBitwidth, guint32 *aLatency)
1518 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1519 g_return_val_if_fail(msg->audio_codecs != NULL, WFD_EINVAL);
1521 for (; i < msg->audio_codecs->count; i++) {
1522 if (!g_strcmp0(msg->audio_codecs->list[i].audio_format, "LPCM")) {
1523 *aCodec |= WFD_AUDIO_LPCM;
1524 *aFreq |= msg->audio_codecs->list[i].modes;
1525 *aChanels |= WFD_CHANNEL_2;
1527 *aLatency = msg->audio_codecs->list[i].latency;
1528 } else if (!g_strcmp0(msg->audio_codecs->list[i].audio_format, "AAC")) {
1529 *aCodec |= WFD_AUDIO_AAC;
1530 *aFreq |= WFD_FREQ_48000;
1531 *aChanels |= msg->audio_codecs->list[i].modes;
1533 *aLatency = msg->audio_codecs->list[i].latency;
1534 } else if (!g_strcmp0(msg->audio_codecs->list[i].audio_format, "AC3")) {
1535 *aCodec |= WFD_AUDIO_AC3;
1536 *aFreq |= WFD_FREQ_48000;
1537 *aChanels |= msg->audio_codecs->list[i].modes;
1539 *aLatency = msg->audio_codecs->list[i].latency;
1545 WFDResult wfdconfig_get_prefered_audio_format(WFDMessage *msg, WFDAudioFormats *aCodec, WFDAudioFreq *aFreq, WFDAudioChannels *aChanels,
1546 guint *aBitwidth, guint32 *aLatency)
1548 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1550 if (!g_strcmp0(msg->audio_codecs->list->audio_format, "LPCM")) {
1551 *aCodec = WFD_AUDIO_LPCM;
1552 *aFreq = msg->audio_codecs->list->modes;
1553 *aChanels = WFD_CHANNEL_2;
1555 *aLatency = msg->audio_codecs->list->latency;
1556 } else if (!g_strcmp0(msg->audio_codecs->list->audio_format, "AAC")) {
1557 *aCodec = WFD_AUDIO_AAC;
1558 *aFreq = WFD_FREQ_48000;
1559 *aChanels = msg->audio_codecs->list->modes;
1561 *aLatency = msg->audio_codecs->list->latency;
1562 } else if (!g_strcmp0(msg->audio_codecs->list->audio_format, "AC3")) {
1563 *aCodec = WFD_AUDIO_AC3;
1564 *aFreq = WFD_FREQ_48000;
1565 *aChanels = msg->audio_codecs->list->modes;
1567 *aLatency = msg->audio_codecs->list->latency;
1572 WFDResult wfdconfig_set_supported_video_format(WFDMessage *msg, WFDVideoCodecs vCodec,
1573 WFDVideoNativeResolution vNative, guint64 vNativeResolution,
1574 guint64 vCEAResolution, guint64 vVESAResolution, guint64 vHHResolution,
1575 guint vProfile, guint vLevel, guint32 vLatency, guint32 vMaxHeight,
1576 guint32 vMaxWidth, guint32 min_slice_size, guint32 slice_enc_params, guint frame_rate_control)
1578 guint nativeindex = 0;
1579 guint64 temp = vNativeResolution;
1581 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1583 if (!msg->video_formats)
1584 msg->video_formats = g_new0(WFDVideoCodeclist, 1);
1586 if (vCodec != WFD_VIDEO_UNKNOWN) {
1587 msg->video_formats->list = g_new0(WFDVideoCodec, 1);
1593 msg->video_formats->list->native = nativeindex - 1;
1594 msg->video_formats->list->native <<= 3;
1596 if (vNative == WFD_VIDEO_VESA_RESOLUTION)
1597 msg->video_formats->list->native |= 1;
1598 else if (vNative == WFD_VIDEO_HH_RESOLUTION)
1599 msg->video_formats->list->native |= 2;
1601 msg->video_formats->list->preferred_display_mode_supported = 1;
1602 msg->video_formats->list->H264_codec.profile = vProfile;
1603 msg->video_formats->list->H264_codec.level = vLevel;
1604 msg->video_formats->list->H264_codec.max_hres = vMaxWidth;
1605 msg->video_formats->list->H264_codec.max_vres = vMaxHeight;
1606 msg->video_formats->list->H264_codec.misc_params.CEA_Support = vCEAResolution;
1607 msg->video_formats->list->H264_codec.misc_params.VESA_Support = vVESAResolution;
1608 msg->video_formats->list->H264_codec.misc_params.HH_Support = vHHResolution;
1609 msg->video_formats->list->H264_codec.misc_params.latency = vLatency;
1610 msg->video_formats->list->H264_codec.misc_params.min_slice_size = min_slice_size;
1611 msg->video_formats->list->H264_codec.misc_params.slice_enc_params = slice_enc_params;
1612 msg->video_formats->list->H264_codec.misc_params.frame_rate_control_support = frame_rate_control;
1617 WFDResult wfdconfig_set_prefered_video_format(WFDMessage *msg, WFDVideoCodecs vCodec,
1618 WFDVideoNativeResolution vNative, guint64 vNativeResolution,
1619 WFDVideoCEAResolution vCEAResolution, WFDVideoVESAResolution vVESAResolution,
1620 WFDVideoHHResolution vHHResolution, WFDVideoH264Profile vProfile,
1621 WFDVideoH264Level vLevel, guint32 vLatency, guint32 vMaxHeight,
1622 guint32 vMaxWidth, guint32 min_slice_size, guint32 slice_enc_params, guint frame_rate_control)
1624 guint nativeindex = 0;
1625 guint64 temp = vNativeResolution;
1627 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1629 if (!msg->video_formats)
1630 msg->video_formats = g_new0(WFDVideoCodeclist, 1);
1631 msg->video_formats->list = g_new0(WFDVideoCodec, 1);
1638 if (nativeindex) msg->video_formats->list->native = nativeindex - 1;
1639 msg->video_formats->list->native <<= 3;
1641 if (vNative == WFD_VIDEO_VESA_RESOLUTION)
1642 msg->video_formats->list->native |= 1;
1643 else if (vNative == WFD_VIDEO_HH_RESOLUTION)
1644 msg->video_formats->list->native |= 2;
1646 msg->video_formats->list->preferred_display_mode_supported = 0;
1647 msg->video_formats->list->H264_codec.profile = vProfile;
1648 msg->video_formats->list->H264_codec.level = vLevel;
1649 msg->video_formats->list->H264_codec.max_hres = vMaxWidth;
1650 msg->video_formats->list->H264_codec.max_vres = vMaxHeight;
1651 msg->video_formats->list->H264_codec.misc_params.CEA_Support = vCEAResolution;
1652 msg->video_formats->list->H264_codec.misc_params.VESA_Support = vVESAResolution;
1653 msg->video_formats->list->H264_codec.misc_params.HH_Support = vHHResolution;
1654 msg->video_formats->list->H264_codec.misc_params.latency = vLatency;
1655 msg->video_formats->list->H264_codec.misc_params.min_slice_size = min_slice_size;
1656 msg->video_formats->list->H264_codec.misc_params.slice_enc_params = slice_enc_params;
1657 msg->video_formats->list->H264_codec.misc_params.frame_rate_control_support = frame_rate_control;
1661 WFDResult wfdconfig_get_supported_video_format(WFDMessage *msg, WFDVideoCodecs *vCodec,
1662 WFDVideoNativeResolution *vNative, guint64 *vNativeResolution,
1663 guint64 *vCEAResolution, guint64 *vVESAResolution, guint64 *vHHResolution,
1664 guint *vProfile, guint *vLevel, guint32 *vLatency, guint32 *vMaxHeight,
1665 guint32 *vMaxWidth, guint32 *min_slice_size, guint32 *slice_enc_params, guint *frame_rate_control)
1667 guint nativeindex = 0;
1669 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1670 g_return_val_if_fail(msg->video_formats != NULL, WFD_EINVAL);
1671 g_return_val_if_fail(msg->video_formats->list != NULL, WFD_EINVAL);
1673 *vCodec = WFD_VIDEO_H264;
1674 *vNative = msg->video_formats->list->native & 0x7;
1675 nativeindex = msg->video_formats->list->native >> 3;
1676 *vNativeResolution = (guint64)1 << nativeindex;
1677 *vProfile = msg->video_formats->list->H264_codec.profile;
1678 *vLevel = msg->video_formats->list->H264_codec.level;
1679 *vMaxWidth = msg->video_formats->list->H264_codec.max_hres;
1680 *vMaxHeight = msg->video_formats->list->H264_codec.max_vres;
1681 *vCEAResolution = msg->video_formats->list->H264_codec.misc_params.CEA_Support;
1682 *vVESAResolution = msg->video_formats->list->H264_codec.misc_params.VESA_Support;
1683 *vHHResolution = msg->video_formats->list->H264_codec.misc_params.HH_Support;
1684 *vLatency = msg->video_formats->list->H264_codec.misc_params.latency;
1685 *min_slice_size = msg->video_formats->list->H264_codec.misc_params.min_slice_size;
1686 *slice_enc_params = msg->video_formats->list->H264_codec.misc_params.slice_enc_params;
1687 *frame_rate_control = msg->video_formats->list->H264_codec.misc_params.frame_rate_control_support;
1691 WFDResult wfdconfig_get_prefered_video_format(WFDMessage *msg, WFDVideoCodecs *vCodec,
1692 WFDVideoNativeResolution *vNative, guint64 *vNativeResolution,
1693 WFDVideoCEAResolution *vCEAResolution, WFDVideoVESAResolution *vVESAResolution,
1694 WFDVideoHHResolution *vHHResolution, WFDVideoH264Profile *vProfile,
1695 WFDVideoH264Level *vLevel, guint32 *vLatency, guint32 *vMaxHeight,
1696 guint32 *vMaxWidth, guint32 *min_slice_size, guint32 *slice_enc_params, guint *frame_rate_control)
1698 guint nativeindex = 0;
1699 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1700 g_return_val_if_fail(msg->video_formats != NULL, WFD_EINVAL);
1701 g_return_val_if_fail(msg->video_formats->list != NULL, WFD_EINVAL);
1703 *vCodec = WFD_VIDEO_H264;
1704 *vNative = msg->video_formats->list->native & 0x7;
1705 nativeindex = msg->video_formats->list->native >> 3;
1706 *vNativeResolution = (guint64)1 << nativeindex;
1707 *vProfile = msg->video_formats->list->H264_codec.profile;
1708 *vLevel = msg->video_formats->list->H264_codec.level;
1709 *vMaxWidth = msg->video_formats->list->H264_codec.max_hres;
1710 *vMaxHeight = msg->video_formats->list->H264_codec.max_vres;
1711 *vCEAResolution = msg->video_formats->list->H264_codec.misc_params.CEA_Support;
1712 *vVESAResolution = msg->video_formats->list->H264_codec.misc_params.VESA_Support;
1713 *vHHResolution = msg->video_formats->list->H264_codec.misc_params.HH_Support;
1714 *vLatency = msg->video_formats->list->H264_codec.misc_params.latency;
1715 *min_slice_size = msg->video_formats->list->H264_codec.misc_params.min_slice_size;
1716 *slice_enc_params = msg->video_formats->list->H264_codec.misc_params.slice_enc_params;
1717 *frame_rate_control = msg->video_formats->list->H264_codec.misc_params.frame_rate_control_support;
1721 WFDResult wfdconfig_set_contentprotection_type(WFDMessage *msg, WFDHDCPProtection hdcpversion, guint32 TCPPort)
1723 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1725 if (!msg->content_protection) msg->content_protection = g_new0(WFDContentProtection, 1);
1726 if (hdcpversion == WFD_HDCP_NONE) return WFD_OK;
1727 msg->content_protection->hdcp2_spec = g_new0(WFDHdcp2Spec, 1);
1728 if (hdcpversion == WFD_HDCP_2_0) msg->content_protection->hdcp2_spec->hdcpversion = g_strdup("HDCP2.0");
1729 else if (hdcpversion == WFD_HDCP_2_1) msg->content_protection->hdcp2_spec->hdcpversion = g_strdup("HDCP2.1");
1730 char str[11] = {0, };
1731 snprintf(str, 11, "port=%d", TCPPort);
1732 msg->content_protection->hdcp2_spec->TCPPort = g_strdup(str);
1736 WFDResult wfdconfig_get_contentprotection_type(WFDMessage *msg, WFDHDCPProtection *hdcpversion, guint32 *TCPPort)
1738 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1739 if (msg->content_protection && msg->content_protection->hdcp2_spec) {
1740 char *result = NULL;
1742 if (!g_strcmp0(msg->content_protection->hdcp2_spec->hdcpversion, "none")) {
1743 wfd_warning("HDCP none");
1744 *hdcpversion = WFD_HDCP_NONE;
1748 if (!g_strcmp0(msg->content_protection->hdcp2_spec->hdcpversion, "HDCP2.0")) *hdcpversion = WFD_HDCP_2_0;
1749 else if (!g_strcmp0(msg->content_protection->hdcp2_spec->hdcpversion, "HDCP2.1")) *hdcpversion = WFD_HDCP_2_1;
1751 wfd_warning("Unknown protection type");
1752 *hdcpversion = WFD_HDCP_NONE;
1757 result = strtok_r(msg->content_protection->hdcp2_spec->TCPPort, "=", &ptr);
1758 while (result != NULL) {
1759 result = strtok_r(NULL, "=", &ptr);
1760 *TCPPort = atoi(result);
1763 } else *hdcpversion = WFD_HDCP_NONE;
1767 WFDResult wfdconfig_set_display_EDID(WFDMessage *msg, gboolean edid_supported, guint32 edid_blockcount, gchar *edid_playload)
1769 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1770 if (!msg->display_edid) msg->display_edid = g_new0(WFDDisplayEdid, 1);
1771 msg->display_edid->edid_supported = edid_supported;
1772 if (!edid_supported) return WFD_OK;
1773 msg->display_edid->edid_block_count = edid_blockcount;
1774 if (edid_blockcount) {
1775 msg->display_edid->edid_payload = g_malloc(128 * edid_blockcount);
1776 if (!msg->display_edid->edid_payload)
1777 memcpy(msg->display_edid->edid_payload, edid_playload, 128 * edid_blockcount);
1778 } else msg->display_edid->edid_payload = g_strdup("none");
1782 WFDResult wfdconfig_get_display_EDID(WFDMessage *msg, gboolean *edid_supported, guint32 *edid_blockcount, gchar **edid_playload)
1784 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1785 if (msg->display_edid) {
1786 if (msg->display_edid->edid_supported) {
1787 *edid_blockcount = msg->display_edid->edid_block_count;
1788 if (msg->display_edid->edid_block_count) {
1790 temp = g_malloc(EDID_BLOCK_SIZE * msg->display_edid->edid_block_count);
1792 memset(temp, 0, EDID_BLOCK_SIZE * msg->display_edid->edid_block_count);
1793 memcpy(temp, msg->display_edid->edid_payload, EDID_BLOCK_SIZE * msg->display_edid->edid_block_count);
1794 *edid_playload = temp;
1795 *edid_supported = TRUE;
1797 } else *edid_playload = g_strdup("none");
1799 } else *edid_supported = FALSE;
1803 WFDResult wfdconfig_set_coupled_sink(WFDMessage *msg, WFDCoupledSinkStatus status, gchar *sink_address)
1805 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1806 if (!msg->coupled_sink) msg->coupled_sink = g_new0(WFDCoupledSink, 1);
1807 if (status == WFD_SINK_UNKNOWN) return WFD_OK;
1808 msg->coupled_sink->coupled_sink_cap = g_new0(WFDCoupled_sink_cap, 1);
1809 msg->coupled_sink->coupled_sink_cap->status = status;
1810 msg->coupled_sink->coupled_sink_cap->sink_address = g_strdup(sink_address);
1814 WFDResult wfdconfig_get_coupled_sink(WFDMessage *msg, WFDCoupledSinkStatus *status, gchar **sink_address)
1816 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1817 if (msg->coupled_sink && msg->coupled_sink->coupled_sink_cap) {
1818 *status = msg->coupled_sink->coupled_sink_cap->status;
1819 *sink_address = g_strdup(msg->coupled_sink->coupled_sink_cap->sink_address);
1820 } else *status = WFD_SINK_UNKNOWN;
1824 WFDResult wfdconfig_set_trigger_type(WFDMessage *msg, WFDTrigger trigger)
1826 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1828 if (!msg->trigger_method)
1829 msg->trigger_method = g_new0(WFDTriggerMethod, 1);
1830 if (trigger == WFD_TRIGGER_SETUP)
1831 msg->trigger_method->wfd_trigger_method = g_strdup("SETUP");
1832 else if (trigger == WFD_TRIGGER_PAUSE)
1833 msg->trigger_method->wfd_trigger_method = g_strdup("PAUSE");
1834 else if (trigger == WFD_TRIGGER_TEARDOWN)
1835 msg->trigger_method->wfd_trigger_method = g_strdup("TEARDOWN");
1836 else if (trigger == WFD_TRIGGER_PLAY)
1837 msg->trigger_method->wfd_trigger_method = g_strdup("PLAY");
1843 WFDResult wfdconfig_get_trigger_type(WFDMessage *msg, WFDTrigger *trigger)
1845 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1846 if (!g_strcmp0(msg->trigger_method->wfd_trigger_method, "SETUP"))
1847 *trigger = WFD_TRIGGER_SETUP;
1848 else if (!g_strcmp0(msg->trigger_method->wfd_trigger_method, "PAUSE"))
1849 *trigger = WFD_TRIGGER_PAUSE;
1850 else if (!g_strcmp0(msg->trigger_method->wfd_trigger_method, "TEARDOWN"))
1851 *trigger = WFD_TRIGGER_TEARDOWN;
1852 else if (!g_strcmp0(msg->trigger_method->wfd_trigger_method, "PLAY"))
1853 *trigger = WFD_TRIGGER_PLAY;
1855 *trigger = WFD_TRIGGER_UNKNOWN;
1861 WFDResult wfdconfig_set_presentation_url(WFDMessage *msg, gchar *wfd_url0, gchar *wfd_url1)
1863 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1864 if (!msg->presentation_url) msg->presentation_url = g_new0(WFDPresentationUrl, 1);
1865 if (wfd_url0) msg->presentation_url->wfd_url0 = g_strdup(wfd_url0);
1866 if (wfd_url1) msg->presentation_url->wfd_url1 = g_strdup(wfd_url1);
1870 WFDResult wfdconfig_get_presentation_url(WFDMessage *msg, gchar **wfd_url0, gchar **wfd_url1)
1872 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1873 if (msg->presentation_url) {
1874 *wfd_url0 = g_strdup(msg->presentation_url->wfd_url0);
1875 *wfd_url1 = g_strdup(msg->presentation_url->wfd_url1);
1880 WFDResult wfdconfig_set_prefered_RTP_ports(WFDMessage *msg, WFDRTSPTransMode trans, WFDRTSPProfile profile,
1881 WFDRTSPLowerTrans lowertrans, guint32 rtp_port0, guint32 rtp_port1)
1884 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1886 if (!msg->client_rtp_ports)
1887 msg->client_rtp_ports = g_new0(WFDClientRtpPorts, 1);
1889 if (trans != WFD_RTSP_TRANS_UNKNOWN) {
1890 lines = g_string_new("");
1891 if (trans == WFD_RTSP_TRANS_RTP) g_string_append_printf(lines, "RTP");
1892 else if (trans == WFD_RTSP_TRANS_RDT) g_string_append_printf(lines, "RDT");
1894 if (profile == WFD_RTSP_PROFILE_AVP) g_string_append_printf(lines, "/AVP");
1895 else if (profile == WFD_RTSP_PROFILE_SAVP) g_string_append_printf(lines, "/SAVP");
1897 if (lowertrans == WFD_RTSP_LOWER_TRANS_UDP) g_string_append_printf(lines, "/UDP;unicast");
1898 else if (lowertrans == WFD_RTSP_LOWER_TRANS_UDP_MCAST) g_string_append_printf(lines, "/UDP;multicast");
1899 else if (lowertrans == WFD_RTSP_LOWER_TRANS_TCP) g_string_append_printf(lines, "/TCP;unicast");
1900 else if (lowertrans == WFD_RTSP_LOWER_TRANS_HTTP) g_string_append_printf(lines, "/HTTP");
1902 msg->client_rtp_ports->profile = g_string_free(lines, FALSE);
1903 msg->client_rtp_ports->rtp_port0 = rtp_port0;
1904 msg->client_rtp_ports->rtp_port1 = rtp_port1;
1905 msg->client_rtp_ports->mode = g_strdup("mode=play");
1910 WFDResult wfdconfig_get_prefered_RTP_ports(WFDMessage *msg, WFDRTSPTransMode *trans, WFDRTSPProfile *profile,
1911 WFDRTSPLowerTrans *lowertrans, guint32 *rtp_port0, guint32 *rtp_port1)
1913 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1914 g_return_val_if_fail(msg->client_rtp_ports != NULL, WFD_EINVAL);
1916 if (g_strrstr(msg->client_rtp_ports->profile, "RTP")) *trans = WFD_RTSP_TRANS_RTP;
1917 if (g_strrstr(msg->client_rtp_ports->profile, "RDT")) *trans = WFD_RTSP_TRANS_RDT;
1918 if (g_strrstr(msg->client_rtp_ports->profile, "AVP")) *profile = WFD_RTSP_PROFILE_AVP;
1919 if (g_strrstr(msg->client_rtp_ports->profile, "SAVP")) *profile = WFD_RTSP_PROFILE_SAVP;
1920 if (g_strrstr(msg->client_rtp_ports->profile, "UDP;unicast")) *lowertrans = WFD_RTSP_LOWER_TRANS_UDP;
1921 if (g_strrstr(msg->client_rtp_ports->profile, "UDP;multicast")) *lowertrans = WFD_RTSP_LOWER_TRANS_UDP_MCAST;
1922 if (g_strrstr(msg->client_rtp_ports->profile, "TCP;unicast")) *lowertrans = WFD_RTSP_LOWER_TRANS_TCP;
1923 if (g_strrstr(msg->client_rtp_ports->profile, "HTTP")) *lowertrans = WFD_RTSP_LOWER_TRANS_HTTP;
1925 *rtp_port0 = msg->client_rtp_ports->rtp_port0;
1926 *rtp_port1 = msg->client_rtp_ports->rtp_port1;
1931 WFDResult wfdconfig_set_audio_sink_type(WFDMessage *msg, WFDSinkType sinktype)
1933 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1934 if (!msg->route) msg->route = g_new0(WFDRoute, 1);
1935 if (sinktype == WFD_PRIMARY_SINK) msg->route->destination = g_strdup("primary");
1936 else if (sinktype == WFD_SECONDARY_SINK) msg->route->destination = g_strdup("secondary");
1940 WFDResult wfdconfig_get_audio_sink_type(WFDMessage *msg, WFDSinkType *sinktype)
1942 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1944 if (!g_strcmp0(msg->route->destination, "primary")) *sinktype = WFD_PRIMARY_SINK;
1945 else if (!g_strcmp0(msg->route->destination, "secondary")) *sinktype = WFD_SECONDARY_SINK;
1950 WFDResult wfdconfig_set_I2C_port(WFDMessage *msg, gboolean i2csupport, guint32 i2cport)
1952 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1953 if (!msg->I2C) msg->I2C = g_new0(WFDI2C, 1);
1954 msg->I2C->I2CPresent = i2csupport;
1955 msg->I2C->I2C_port = i2cport;
1959 WFDResult wfdconfig_get_I2C_port(WFDMessage *msg, gboolean *i2csupport, guint32 *i2cport)
1961 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1962 if (msg->I2C && msg->I2C->I2CPresent) {
1963 *i2csupport = msg->I2C->I2CPresent;
1964 *i2cport = msg->I2C->I2C_port;
1965 } else *i2csupport = FALSE;
1969 WFDResult wfdconfig_set_av_format_change_timing(WFDMessage *msg, guint64 PTS, guint64 DTS)
1971 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1972 if (!msg->av_format_change_timing) msg->av_format_change_timing = g_new0(WFDAVFormatChangeTiming, 1);
1973 msg->av_format_change_timing->PTS = PTS;
1974 msg->av_format_change_timing->DTS = DTS;
1978 WFDResult wfdconfig_get_av_format_change_timing(WFDMessage *msg, guint64 *PTS, guint64 *DTS)
1980 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1981 if (msg->av_format_change_timing) {
1982 *PTS = msg->av_format_change_timing->PTS;
1983 *DTS = msg->av_format_change_timing->DTS;
1988 WFDResult wfdconfig_set_uibc_capability(WFDMessage *msg, guint32 input_category, guint32 inp_type, WFDHIDCTypePathPair *inp_pair,
1989 guint32 inp_type_path_count, guint32 tcp_port)
1991 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
1992 if (!msg->uibc_capability) msg->uibc_capability = g_new0(WFDUibcCapability, 1);
1993 msg->uibc_capability->uibcsupported = TRUE;
1994 msg->uibc_capability->input_category_list.input_cat = input_category;
1995 msg->uibc_capability->generic_cap_list.inp_type = inp_type;
1996 msg->uibc_capability->hidc_cap_list.cap_count = inp_type_path_count;
1997 if (msg->uibc_capability->hidc_cap_list.cap_count) {
1998 detailed_cap *temp_cap;
2000 msg->uibc_capability->hidc_cap_list.next = g_new0(detailed_cap, 1);
2001 temp_cap = msg->uibc_capability->hidc_cap_list.next;
2002 for (; i < inp_type_path_count;) {
2003 temp_cap->p.inp_type = inp_pair[i].inp_type;
2004 temp_cap->p.inp_path = inp_pair[i].inp_path;
2006 if (i < inp_type_path_count) {
2007 temp_cap->next = g_new0(detailed_cap, 1);
2008 temp_cap = temp_cap->next;
2012 msg->uibc_capability->tcp_port = tcp_port;
2016 WFDResult wfdconfig_get_uibc_capability(WFDMessage *msg, guint32 *input_category, guint32 *inp_type, WFDHIDCTypePathPair **inp_pair,
2017 guint32 *inp_type_path_count, guint32 *tcp_port)
2019 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
2020 if (msg->uibc_capability && msg->uibc_capability->uibcsupported) {
2021 *input_category = msg->uibc_capability->input_category_list.input_cat;
2022 *inp_type = msg->uibc_capability->generic_cap_list.inp_type;
2023 *inp_type_path_count = msg->uibc_capability->hidc_cap_list.cap_count;
2024 if (msg->uibc_capability->hidc_cap_list.cap_count) {
2025 detailed_cap *temp_cap;
2027 *inp_pair = g_new0(WFDHIDCTypePathPair, msg->uibc_capability->hidc_cap_list.cap_count);
2028 temp_cap = msg->uibc_capability->hidc_cap_list.next;
2030 (*(inp_pair))[i].inp_type = temp_cap->p.inp_type;
2031 (*(inp_pair))[i].inp_path = temp_cap->p.inp_path;
2032 temp_cap = temp_cap->next;
2036 *tcp_port = msg->uibc_capability->tcp_port;
2041 WFDResult wfdconfig_set_uibc_status(WFDMessage *msg, gboolean uibc_enable)
2043 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
2044 if (!msg->uibc_setting) msg->uibc_setting = g_new0(WFDUibcSetting, 1);
2045 msg->uibc_setting->uibc_setting = uibc_enable;
2049 WFDResult wfdconfig_get_uibc_status(WFDMessage *msg, gboolean *uibc_enable)
2051 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
2052 if (msg->uibc_setting) *uibc_enable = msg->uibc_setting->uibc_setting;
2055 #ifdef STANDBY_RESUME_CAPABILITY
2056 WFDResult wfdconfig_set_standby_resume_capability(WFDMessage *msg, gboolean supported)
2058 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
2059 if (!msg->standby_resume_capability) msg->standby_resume_capability = g_new0(WFDStandbyResumeCapability, 1);
2060 msg->standby_resume_capability->standby_resume_cap = supported;
2064 WFDResult wfdconfig_get_standby_resume_capability(WFDMessage *msg, gboolean *supported)
2066 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
2067 if (msg->standby_resume_capability) *supported = msg->standby_resume_capability->standby_resume_cap;
2071 WFDResult wfdconfig_set_standby(WFDMessage *msg, gboolean standby_enable)
2073 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
2074 if (!msg->standby) msg->standby = g_new0(WFDStandby, 1);
2075 msg->standby->wfd_standby = standby_enable;
2079 WFDResult wfdconfig_get_standby(WFDMessage *msg, gboolean *standby_enable)
2081 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
2082 if (msg->standby) *standby_enable = msg->standby->wfd_standby;
2086 WFDResult wfdconfig_set_connector_type(WFDMessage *msg, WFDConnector connector)
2088 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
2089 if (!msg->connector_type) msg->connector_type = g_new0(WFDConnectorType, 1);
2090 msg->connector_type->connector_type = connector;
2094 WFDResult wfdconfig_get_connector_type(WFDMessage *msg, WFDConnector *connector)
2096 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
2097 if (msg->connector_type) *connector = msg->connector_type->connector_type;
2101 WFDResult wfdconfig_set_idr_request(WFDMessage *msg)
2103 g_return_val_if_fail(msg != NULL, WFD_EINVAL);
2104 if (!msg->idr_request) msg->idr_request = g_new0(WFDIdrRequest, 1);
2105 msg->idr_request->idr_request = TRUE;