Initial submission of GUPnP-AV to Tizen IVI
[profile/ivi/GUPnP-AV.git] / libgupnp-av / gupnp-protocol-info.c
1 /*
2  * Copyright (C) 2009 Nokia Corporation.
3  * Copyright (C) 2007, 2008 OpenedHand Ltd.
4  *
5  * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
6  *                                <zeeshanak@gnome.org>
7  *          Jorn Baayen <jorn@openedhand.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24
25 /**
26  * SECTION:gupnp-protocol-info
27  * @short_description: UPnP AV ProtocolInfo
28  *
29  * #GUPnPProtocolInfo provides a convenient API to deal with ProtocolInfo
30  * strings used in UPnP AV specifications.
31  */
32
33 #include <string.h>
34 #include <stdlib.h>
35 #include <libgupnp/gupnp.h>
36 #include "gupnp-protocol-info.h"
37 #include "gupnp-av-error.h"
38
39 G_DEFINE_TYPE (GUPnPProtocolInfo,
40                gupnp_protocol_info,
41                G_TYPE_OBJECT);
42
43 struct _GUPnPProtocolInfoPrivate {
44         char  *protocol;
45         char  *network;
46         char  *mime_type;
47         char  *dlna_profile;
48         char **play_speeds;
49
50         GUPnPDLNAConversion dlna_conversion;
51         GUPnPDLNAOperation  dlna_operation;
52         GUPnPDLNAFlags      dlna_flags;
53 };
54
55 enum {
56         PROP_0,
57         PROP_PROTOCOL,
58         PROP_NETWORK,
59         PROP_MIME_TYPE,
60         PROP_DLNA_PROFILE,
61         PROP_PLAY_SPEEDS,
62
63         PROP_DLNA_CONVERSION,
64         PROP_DLNA_OPERATION,
65         PROP_DLNA_FLAGS
66 };
67
68 static void
69 parse_additional_info (const char        *additional_info,
70                        GUPnPProtocolInfo *info)
71 {
72         GUPnPProtocolInfoPrivate *priv;
73         char **tokens = NULL;
74         short i;
75
76         priv = info->priv;
77
78         if (strcmp (additional_info, "*") == 0)
79                 return;
80
81         tokens = g_strsplit (additional_info, ";", -1);
82         if (tokens == NULL) {
83                 g_warning ("Invalid additional info in DIDL-Lite info: %s",
84                            additional_info);
85
86                 return;
87         }
88
89         for (i = 0; tokens[i]; i++) {
90                 char *p;
91
92                 p = g_strstr_len (tokens[i],
93                                   strlen (tokens[i]),
94                                   "DLNA.ORG_PN=");
95                 if (p != NULL) {
96                         p += 12; /* end of "DLNA.ORG_PN=" */
97                         gupnp_protocol_info_set_dlna_profile (info, p);
98
99                         continue;
100                 }
101
102                 p = g_strstr_len (tokens[i],
103                                   strlen (tokens[i]),
104                                   "DLNA.ORG_PS=");
105                 if (p != NULL) {
106                         char **play_speeds;
107
108                         p += 12; /* end of "DLNA.ORG_PS=" */
109
110                         play_speeds = g_strsplit (p, ",", -1);
111                         gupnp_protocol_info_set_play_speeds
112                                                 (info,
113                                                  (const char **) play_speeds);
114                         g_strfreev (play_speeds);
115
116                         continue;
117                 }
118
119                 p = g_strstr_len (tokens[i],
120                                   strlen (tokens[i]),
121                                   "DLNA.ORG_CI=");
122                 if (p != NULL) {
123                         p += 12; /* end of "DLNA.ORG_CI=" */
124
125                         gupnp_protocol_info_set_dlna_conversion (info,
126                                                                  atoi (p));
127
128                         continue;
129                 }
130
131                 p = g_strstr_len (tokens[i],
132                                   strlen (tokens[i]),
133                                   "DLNA.ORG_OP=");
134                 if (p != NULL) {
135                         p += 12; /* end of "DLNA.ORG_OP=" */
136
137                         gupnp_protocol_info_set_dlna_operation
138                                                         (info,
139                                                          strtoul (p, NULL, 16));
140
141                         continue;
142                 }
143
144                 p = g_strstr_len (tokens[i],
145                                   strlen (tokens[i]),
146                                   "DLNA.ORG_FLAGS=");
147                 if (p != NULL) {
148                         p += 15; /* end of "DLNA.ORG_FLAGS=" */
149                         if (strlen (p) > 8)
150                                 p[8] = '\0';
151                         gupnp_protocol_info_set_dlna_flags
152                                                         (info,
153                                                          strtoul (p, NULL, 16));
154
155                         continue;
156                 }
157         }
158
159         g_strfreev (tokens);
160 }
161
162 static gboolean
163 is_transport_compat (GUPnPProtocolInfo *info1,
164                      GUPnPProtocolInfo *info2)
165 {
166         const char *protocol1;
167         const char *protocol2;
168
169         protocol1 = gupnp_protocol_info_get_protocol (info1);
170         protocol2 = gupnp_protocol_info_get_protocol (info2);
171
172         if (protocol1[0] != '*' &&
173             protocol2[0] != '*' &&
174             g_ascii_strcasecmp (protocol1, protocol2) != 0)
175                 return FALSE;
176         else if (g_ascii_strcasecmp ("internal", protocol1) == 0 &&
177                  strcmp (gupnp_protocol_info_get_network (info1),
178                          gupnp_protocol_info_get_network (info2)) != 0)
179                 /* Host must be the same in case of INTERNAL protocol */
180                 return FALSE;
181         else
182                 return TRUE;
183 }
184
185 static gboolean
186 is_content_format_compat (GUPnPProtocolInfo *info1,
187                           GUPnPProtocolInfo *info2)
188 {
189         const char *mime_type1;
190         const char *mime_type2;
191
192         mime_type1 = gupnp_protocol_info_get_mime_type (info1);
193         mime_type2 = gupnp_protocol_info_get_mime_type (info2);
194
195         if (mime_type1 [0] != '*' &&
196             mime_type2 [0] != '*' &&
197             g_ascii_strcasecmp (mime_type1, mime_type2) != 0 &&
198             /* Handle special case for LPCM: It is the only content type that
199              * make use of mime-type parameters that we know of.
200              *
201              * Example: audio/L16;rate=44100;channels=2
202              */
203             !((g_ascii_strcasecmp (mime_type1, "audio/L16") == 0 &&
204                g_ascii_strncasecmp (mime_type2, "audio/L16", 9) == 0) ||
205               (g_ascii_strcasecmp (mime_type2, "audio/L16") == 0 &&
206                g_ascii_strncasecmp (mime_type1, "audio/L16", 9) == 0)))
207                 return FALSE;
208         else
209                 return TRUE;
210 }
211
212 static gboolean
213 is_additional_info_compat (GUPnPProtocolInfo *info1,
214                            GUPnPProtocolInfo *info2)
215 {
216         const char *profile1;
217         const char *profile2;
218
219         profile1 = gupnp_protocol_info_get_dlna_profile (info1);
220         profile2 = gupnp_protocol_info_get_dlna_profile (info2);
221
222         if (profile1 == NULL ||
223             profile2 == NULL ||
224             profile1 [0] == '*' ||
225             profile2 [0] == '*' ||
226             g_ascii_strcasecmp (profile1, profile2) == 0)
227                 return TRUE;
228         else
229                 return FALSE;
230 }
231
232 static void
233 add_dlna_info (GString           *str,
234                GUPnPProtocolInfo *info)
235 {
236         const char *dlna_profile;
237         const char **speeds;
238         GUPnPDLNAConversion conversion;
239         GUPnPDLNAOperation operation;
240         GUPnPDLNAFlags flags;
241
242         dlna_profile = gupnp_protocol_info_get_dlna_profile (info);
243         if (dlna_profile == NULL) {
244                 g_string_append_printf (str, ":");
245         } else {
246                 g_string_append_printf (str, ":DLNA.ORG_PN=%s;", dlna_profile);
247         }
248
249         operation = gupnp_protocol_info_get_dlna_operation (info);
250         if (operation != GUPNP_DLNA_OPERATION_NONE &&
251             /* the OP parameter is only allowed for the "http-get"
252              * and "rtsp-rtp-udp" protocols
253              */
254             (strcmp (gupnp_protocol_info_get_protocol (info),
255                      "http-get") == 0 ||
256              strcmp (gupnp_protocol_info_get_protocol (info),
257                      "rtsp-rtp-udp") == 0))
258                 g_string_append_printf (str, "DLNA.ORG_OP=%.2x;", operation);
259
260         /* Specify PS parameter if list of play speeds is provided */
261         speeds = gupnp_protocol_info_get_play_speeds (info);
262         if (speeds != NULL) {
263                 int i;
264
265                 g_string_append_printf (str, "DLNA.ORG_PS=;");
266
267                 for (i = 0; speeds[i]; i++) {
268                         g_string_append (str, speeds[i]);
269
270                         if (speeds[i + 1])
271                                 g_string_append_c (str, ',');
272                 }
273         }
274
275         conversion = gupnp_protocol_info_get_dlna_conversion (info);
276         /* omit the CI parameter for non-converted content */
277         if (conversion != GUPNP_DLNA_CONVERSION_NONE)
278                 g_string_append_printf (str, "DLNA.ORG_CI=%d;", conversion);
279
280         flags = gupnp_protocol_info_get_dlna_flags (info);
281         /* Omit the FLAGS parameter if no or DLNA profile are set */
282         if (flags != GUPNP_DLNA_FLAGS_NONE && dlna_profile != NULL) {
283                 g_string_append_printf (str, "DLNA.ORG_FLAGS=%.8x", flags);
284                 /*  append 24 reserved hex-digits */
285                 g_string_append_printf (str,
286                                         "0000" "0000" "0000"
287                                         "0000" "0000" "0000");
288         }
289
290         /* if nothing of the above was set, use the "match all" rule */
291         switch (str->str[str->len - 1]) {
292                 case ':':
293                         g_string_append_c (str, '*');
294                         break;
295                 case ';':
296                         g_string_erase (str, str->len - 1, 1);
297                         break;
298                 default:
299                         break;
300         }
301 }
302
303 static void
304 gupnp_protocol_info_init (GUPnPProtocolInfo *info)
305 {
306         info->priv = G_TYPE_INSTANCE_GET_PRIVATE
307                                         (info,
308                                          GUPNP_TYPE_PROTOCOL_INFO,
309                                          GUPnPProtocolInfoPrivate);
310
311         info->priv->dlna_conversion = GUPNP_DLNA_CONVERSION_NONE;
312         info->priv->dlna_operation  = GUPNP_DLNA_OPERATION_NONE;
313         info->priv->dlna_flags      = GUPNP_DLNA_FLAGS_NONE;
314 }
315
316 static void
317 gupnp_protocol_info_set_property (GObject      *object,
318                                   guint         property_id,
319                                   const GValue *value,
320                                   GParamSpec   *pspec)
321 {
322         GUPnPProtocolInfo *info;
323
324         info = GUPNP_PROTOCOL_INFO (object);
325
326         switch (property_id) {
327         case PROP_PROTOCOL:
328                 gupnp_protocol_info_set_protocol (info,
329                                                   g_value_get_string (value));
330                 break;
331         case PROP_NETWORK:
332                 gupnp_protocol_info_set_network (info,
333                                                  g_value_get_string (value));
334                 break;
335         case PROP_MIME_TYPE:
336                 gupnp_protocol_info_set_mime_type (info,
337                                                    g_value_get_string (value));
338                 break;
339         case PROP_DLNA_PROFILE:
340                 gupnp_protocol_info_set_dlna_profile
341                                         (info,
342                                          g_value_get_string (value));
343                 break;
344         case PROP_PLAY_SPEEDS:
345                 gupnp_protocol_info_set_play_speeds (info,
346                                                      g_value_get_boxed (value));
347                 break;
348         case PROP_DLNA_CONVERSION:
349                 gupnp_protocol_info_set_dlna_conversion
350                                         (info,
351                                          g_value_get_flags (value));
352                 break;
353         case PROP_DLNA_OPERATION:
354                 gupnp_protocol_info_set_dlna_operation
355                                         (info,
356                                          g_value_get_flags (value));
357                 break;
358         case PROP_DLNA_FLAGS:
359                 gupnp_protocol_info_set_dlna_flags
360                                         (info,
361                                          g_value_get_flags (value));
362                 break;
363         default:
364                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
365                 break;
366         }
367 }
368
369 static void
370 gupnp_protocol_info_get_property (GObject    *object,
371                                   guint       property_id,
372                                   GValue     *value,
373                                   GParamSpec *pspec)
374 {
375         GUPnPProtocolInfo *info;
376
377         info = GUPNP_PROTOCOL_INFO (object);
378
379         switch (property_id) {
380         case PROP_PROTOCOL:
381                 g_value_set_string (value,
382                                     gupnp_protocol_info_get_protocol (info));
383                 break;
384         case PROP_NETWORK:
385                 g_value_set_string (value,
386                                     gupnp_protocol_info_get_network (info));
387                 break;
388         case PROP_MIME_TYPE:
389                 g_value_set_string (value,
390                                     gupnp_protocol_info_get_mime_type (info));
391                 break;
392         case PROP_DLNA_PROFILE:
393                 g_value_set_string
394                               (value,
395                                gupnp_protocol_info_get_dlna_profile (info));
396                 break;
397         case PROP_PLAY_SPEEDS:
398                 g_value_set_boxed (value,
399                                    gupnp_protocol_info_get_play_speeds (info));
400                 break;
401         case PROP_DLNA_CONVERSION:
402                 g_value_set_flags
403                                 (value,
404                                  gupnp_protocol_info_get_dlna_conversion
405                                                                 (info));
406                 break;
407         case PROP_DLNA_OPERATION:
408                 g_value_set_flags
409                                 (value,
410                                  gupnp_protocol_info_get_dlna_operation (info));
411                 break;
412         case PROP_DLNA_FLAGS:
413                 g_value_set_flags (value,
414                                    gupnp_protocol_info_get_dlna_flags (info));
415                 break;
416         default:
417                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
418                 break;
419         }
420 }
421
422 static void
423 gupnp_protocol_info_finalize (GObject *object)
424 {
425         GObjectClass                 *object_class;
426         GUPnPProtocolInfoPrivate *priv;
427
428         priv = GUPNP_PROTOCOL_INFO (object)->priv;
429
430         if (priv->protocol)
431                 g_free (priv->protocol);
432         if (priv->network)
433                 g_free (priv->network);
434         if (priv->mime_type)
435                 g_free (priv->mime_type);
436         if (priv->dlna_profile)
437                 g_free (priv->dlna_profile);
438         if (priv->play_speeds)
439                 g_strfreev (priv->play_speeds);
440
441         object_class = G_OBJECT_CLASS (gupnp_protocol_info_parent_class);
442         object_class->finalize (object);
443 }
444
445 static void
446 gupnp_protocol_info_class_init (GUPnPProtocolInfoClass *klass)
447 {
448         GObjectClass *object_class;
449
450         object_class = G_OBJECT_CLASS (klass);
451
452         object_class->set_property = gupnp_protocol_info_set_property;
453         object_class->get_property = gupnp_protocol_info_get_property;
454         object_class->finalize = gupnp_protocol_info_finalize;
455
456         g_type_class_add_private (klass, sizeof (GUPnPProtocolInfoPrivate));
457
458         /**
459          * GUPnPProtocolInfo:protocol:
460          *
461          * The protocol of this info.
462          **/
463         g_object_class_install_property
464                 (object_class,
465                  PROP_PROTOCOL,
466                  g_param_spec_string ("protocol",
467                                       "Protocol",
468                                       "The protocol of this info.",
469                                       NULL,
470                                       G_PARAM_READWRITE |
471                                       G_PARAM_STATIC_NAME |
472                                       G_PARAM_STATIC_NICK |
473                                       G_PARAM_STATIC_BLURB));
474
475         /**
476          * GUPnPProtocolInfo:network:
477          *
478          * The network this info is associated with.
479          **/
480         g_object_class_install_property
481                 (object_class,
482                  PROP_NETWORK,
483                  g_param_spec_string ("network",
484                                       "Network",
485                                       "The network this info is associated"
486                                       " with.",
487                                       NULL,
488                                       G_PARAM_READWRITE |
489                                       G_PARAM_STATIC_NAME |
490                                       G_PARAM_STATIC_NICK |
491                                       G_PARAM_STATIC_BLURB));
492
493         /**
494          * GUPnPProtocolInfo:mime-type:
495          *
496          * The MIME-type of this info.
497          **/
498         g_object_class_install_property
499                 (object_class,
500                  PROP_MIME_TYPE,
501                  g_param_spec_string ("mime-type",
502                                       "MIMEType",
503                                       "The MIME-type of this info.",
504                                       NULL,
505                                       G_PARAM_READWRITE |
506                                       G_PARAM_STATIC_NAME |
507                                       G_PARAM_STATIC_NICK |
508                                       G_PARAM_STATIC_BLURB));
509
510         /**
511          * GUPnPProtocolInfo:dlna-profile:
512          *
513          * The DLNA profile of this info.
514          **/
515         g_object_class_install_property
516                 (object_class,
517                  PROP_DLNA_PROFILE,
518                  g_param_spec_string ("dlna-profile",
519                                       "DLNAProfile",
520                                       "The DLNA profile of this info.",
521                                       NULL,
522                                       G_PARAM_READWRITE |
523                                       G_PARAM_STATIC_NAME |
524                                       G_PARAM_STATIC_NICK |
525                                       G_PARAM_STATIC_BLURB));
526
527         /**
528          * GUPnPProtocolInfo:play-speeds:
529          *
530          * The allowed play speeds on this info in the form of array of
531          * strings.
532          **/
533         g_object_class_install_property
534                 (object_class,
535                  PROP_PLAY_SPEEDS,
536                  g_param_spec_boxed ("play-speeds",
537                                      "PlaySpeeds",
538                                      "The allowed play speeds on this"
539                                      " info in the form of array of"
540                                      " strings.",
541                                      G_TYPE_STRV,
542                                      G_PARAM_READWRITE |
543                                      G_PARAM_STATIC_NAME |
544                                      G_PARAM_STATIC_NICK |
545                                      G_PARAM_STATIC_BLURB));
546
547         /**
548          * GUPnPProtocolInfo:dlna-conversion:
549          *
550          * The DLNA conversion flags.
551          **/
552         g_object_class_install_property
553                 (object_class,
554                  PROP_DLNA_CONVERSION,
555                  g_param_spec_flags ("dlna-conversion",
556                                      "DLNAConversion",
557                                      "The DLNA conversion flags.",
558                                      GUPNP_TYPE_DLNA_CONVERSION,
559                                      GUPNP_DLNA_CONVERSION_NONE,
560                                      G_PARAM_READWRITE |
561                                      G_PARAM_STATIC_NAME |
562                                      G_PARAM_STATIC_NICK |
563                                      G_PARAM_STATIC_BLURB));
564
565         /**
566          * GUPnPProtocolInfo:dlna-operation:
567          *
568          * The DLNA operation flags.
569          **/
570         g_object_class_install_property
571                 (object_class,
572                  PROP_DLNA_OPERATION,
573                  g_param_spec_flags ("dlna-operation",
574                                      "DLNAOperation",
575                                      "The DLNA operation flags.",
576                                      GUPNP_TYPE_DLNA_OPERATION,
577                                      GUPNP_DLNA_OPERATION_NONE,
578                                      G_PARAM_READWRITE |
579                                      G_PARAM_STATIC_NAME |
580                                      G_PARAM_STATIC_NICK |
581                                      G_PARAM_STATIC_BLURB));
582
583         /**
584          * GUPnPProtocolInfo:dlna-flags:
585          *
586          * Various generic DLNA flags.
587          **/
588         g_object_class_install_property
589                 (object_class,
590                  PROP_DLNA_FLAGS,
591                  g_param_spec_flags ("dlna-flags",
592                                      "DLNAFlags",
593                                      "Various generic DLNA flags.",
594                                      GUPNP_TYPE_DLNA_FLAGS,
595                                      GUPNP_DLNA_FLAGS_NONE,
596                                      G_PARAM_READWRITE |
597                                      G_PARAM_STATIC_NAME |
598                                      G_PARAM_STATIC_NICK |
599                                      G_PARAM_STATIC_BLURB));
600 }
601
602 /**
603  * gupnp_protocol_info_new:
604  *
605  * Return value: A new #GUPnPProtocolInfo object. Unref after usage.
606  **/
607 GUPnPProtocolInfo *
608 gupnp_protocol_info_new ()
609 {
610         return g_object_new (GUPNP_TYPE_PROTOCOL_INFO,
611                              NULL);
612 }
613
614 /**
615  * gupnp_protocol_info_new_from_string:
616  * @protocol_info: The protocol info string
617  * @error: The location where to store any error, or NULL
618  *
619  * Parses the @protocol_info string and creates a new #GUPnPProtocolInfo object
620  * as a result.
621  *
622  * Return value: A new #GUPnPProtocolInfo object. Unref after usage.
623  **/
624 GUPnPProtocolInfo *
625 gupnp_protocol_info_new_from_string (const char *protocol_info,
626                                      GError    **error)
627 {
628         GUPnPProtocolInfo *info;
629         char **tokens;
630
631         g_return_val_if_fail (protocol_info != NULL, NULL);
632
633         tokens = g_strsplit (protocol_info, ":", 4);
634         if (tokens[0] == NULL ||
635             tokens[1] == NULL ||
636             tokens[2] == NULL ||
637             tokens[3] == NULL) {
638                 g_set_error (error,
639                              GUPNP_PROTOCOL_ERROR,
640                              GUPNP_PROTOCOL_ERROR_INVALID_SYNTAX,
641                              "Failed to parse protocolInfo string: \n%s",
642                              protocol_info);
643
644                 g_strfreev (tokens);
645
646                 return NULL;
647         }
648
649         info = gupnp_protocol_info_new ();
650
651         gupnp_protocol_info_set_protocol (info, tokens[0]);
652         gupnp_protocol_info_set_network (info, tokens[1]);
653         gupnp_protocol_info_set_mime_type (info, tokens[2]);
654
655         parse_additional_info (tokens[3], info);
656
657         g_strfreev (tokens);
658
659         return info;
660 }
661
662 /**
663  * gupnp_protocol_info_to_string:
664  * @info: The #GUPnPProtocolInfo
665  *
666  * Provides the string representation of @info.
667  *
668  * Return value: String representation of @info. #g_free after usage.
669  **/
670 char *
671 gupnp_protocol_info_to_string (GUPnPProtocolInfo *info)
672 {
673         GString *str;
674         const char *protocol;
675         const char *mime_type;
676         const char *network;
677
678         g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL);
679
680         protocol = gupnp_protocol_info_get_protocol (info);
681         mime_type = gupnp_protocol_info_get_mime_type (info);
682         network = gupnp_protocol_info_get_network (info);
683
684         g_return_val_if_fail (protocol != NULL, NULL);
685         g_return_val_if_fail (mime_type != NULL, NULL);
686
687         str = g_string_new ("");
688
689         g_string_append (str, protocol);
690         g_string_append_c (str, ':');
691         if (network != NULL)
692                 g_string_append (str, network);
693         else
694                 g_string_append_c (str, '*');
695         g_string_append_c (str, ':');
696         g_string_append (str, mime_type);
697
698         add_dlna_info (str, info);
699
700         return g_string_free (str, FALSE);
701 }
702
703 /**
704  * gupnp_protocol_info_get_protocol:
705  * @info: A #GUPnPProtocolInfo
706  *
707  * Get the protocol of this info.
708  *
709  * Return value: The protocol of this info or %NULL. This string should not
710  * be freed.
711  **/
712 const char *
713 gupnp_protocol_info_get_protocol (GUPnPProtocolInfo *info)
714 {
715         g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL);
716
717         return info->priv->protocol;
718 }
719
720 /**
721  * gupnp_protocol_info_get_network:
722  * @info: A #GUPnPProtocolInfo
723  *
724  * Get the network this info is associated with.
725  *
726  * Return value: The network string or %NULL. This string should not be freed.
727  **/
728 const char *
729 gupnp_protocol_info_get_network (GUPnPProtocolInfo *info)
730 {
731         g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL);
732
733         return info->priv->network;
734 }
735
736 /**
737  * gupnp_protocol_info_get_mime_type:
738  * @info: A #GUPnPProtocolInfo
739  *
740  * Get the MIME-type of this info.
741  *
742  * Return value: The MIME-type of this info or %NULL. This string should not
743  * be freed.
744  **/
745 const char *
746 gupnp_protocol_info_get_mime_type (GUPnPProtocolInfo *info)
747 {
748         g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL);
749
750         return info->priv->mime_type;
751 }
752
753 /**
754  * gupnp_protocol_info_get_dlna_profile:
755  * @info: A #GUPnPProtocolInfo
756  *
757  * Get the DLNA profile of this info.
758  *
759  * Return value: The DLNA profile of this info or %NULL. This string should
760  * not be freed.
761  **/
762 const char *
763 gupnp_protocol_info_get_dlna_profile (GUPnPProtocolInfo *info)
764 {
765         g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL);
766
767         return info->priv->dlna_profile;
768 }
769
770 /**
771  * gupnp_protocol_info_get_play_speeds:
772  * @info: A #GUPnPProtocolInfo
773  *
774  * Get the allowed play speeds on this info in the form of array of strings.
775  *
776  * Returns: (transfer none): The allowed play speeds as array of strings or %NULL. This
777  * return array and it's content must not be modified or freed.
778  **/
779 const char **
780 gupnp_protocol_info_get_play_speeds (GUPnPProtocolInfo *info)
781 {
782         g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL);
783
784         return (const char **) info->priv->play_speeds;
785 }
786
787 /**
788  * gupnp_protocol_info_get_dlna_conversion:
789  * @info: A #GUPnPProtocolInfo
790  *
791  * Get the DLNA conversion flags.
792  *
793  * Return value: The DLNA conversion flags.
794  **/
795 GUPnPDLNAConversion
796 gupnp_protocol_info_get_dlna_conversion (GUPnPProtocolInfo *info)
797 {
798         g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info),
799                               GUPNP_DLNA_CONVERSION_NONE);
800
801         return info->priv->dlna_conversion;
802 }
803
804 /**
805  * gupnp_protocol_info_get_dlna_operation:
806  * @info: A #GUPnPProtocolInfo
807  *
808  * Get the DLNA operation flags.
809  *
810  * Return value: The DLNA operation flags.
811  **/
812 GUPnPDLNAOperation
813 gupnp_protocol_info_get_dlna_operation (GUPnPProtocolInfo *info)
814 {
815         g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info),
816                               GUPNP_DLNA_OPERATION_NONE);
817
818         return info->priv->dlna_operation;
819 }
820
821 /**
822  * gupnp_protocol_info_get_dlna_flags:
823  * @info: A #GUPnPProtocolInfo
824  *
825  * Get the gereric DLNA flags.
826  *
827  * Return value: The generic DLNA flags.
828  **/
829 GUPnPDLNAFlags
830 gupnp_protocol_info_get_dlna_flags (GUPnPProtocolInfo *info)
831 {
832         g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info),
833                               GUPNP_DLNA_FLAGS_NONE);
834
835         return info->priv->dlna_flags;
836 }
837
838 /**
839  * gupnp_protocol_info_set_protocol:
840  * @info: A #GUPnPProtocolInfo
841  * @protocol: The protocol string
842  *
843  * Set the protocol of this info.
844  *
845  * Return value: None.
846  **/
847 void
848 gupnp_protocol_info_set_protocol (GUPnPProtocolInfo *info,
849                                   const char        *protocol)
850 {
851         g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info));
852
853         if (info->priv->protocol)
854                 g_free (info->priv->protocol);
855         info->priv->protocol = g_strdup (protocol);
856
857         g_object_notify (G_OBJECT (info), "protocol");
858 }
859
860 /**
861  * gupnp_protocol_info_set_network:
862  * @info: A #GUPnPProtocolInfo
863  * @network: The network string
864  *
865  * Set the network this info is associated with.
866  *
867  * Return value: None.
868  **/
869 void
870 gupnp_protocol_info_set_network (GUPnPProtocolInfo *info,
871                                  const char        *network)
872 {
873         g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info));
874
875         if (info->priv->network)
876                 g_free (info->priv->network);
877         info->priv->network = g_strdup (network);
878
879         g_object_notify (G_OBJECT (info), "network");
880 }
881
882 /**
883  * gupnp_protocol_info_set_mime_type:
884  * @info: A #GUPnPProtocolInfo
885  * @mime_type: The MIME-type string
886  *
887  * Set the MIME-type of this info.
888  *
889  * Return value: None.
890  **/
891 void
892 gupnp_protocol_info_set_mime_type (GUPnPProtocolInfo *info,
893                                    const char        *mime_type)
894 {
895         g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info));
896
897         if (info->priv->mime_type)
898                 g_free (info->priv->mime_type);
899         info->priv->mime_type = g_strdup (mime_type);
900
901         g_object_notify (G_OBJECT (info), "mime-type");
902 }
903
904 /**
905  * gupnp_protocol_info_set_dlna_profile:
906  * @info: A #GUPnPProtocolInfo
907  * @profile: The DLNA profile string
908  *
909  * Set the DLNA profile of this info.
910  *
911  * Return value: None.
912  **/
913 void
914 gupnp_protocol_info_set_dlna_profile (GUPnPProtocolInfo *info,
915                                       const char        *profile)
916 {
917         g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info));
918
919         if (info->priv->dlna_profile)
920                 g_free (info->priv->dlna_profile);
921         info->priv->dlna_profile = g_strdup (profile);
922
923         g_object_notify (G_OBJECT (info), "dlna-profile");
924 }
925
926 /**
927  * gupnp_protocol_info_set_play_speeds:
928  * @info: A #GUPnPProtocolInfo
929  * @speeds: The allowed play speeds
930  *
931  * Set the allowed play speeds on this info in the form of array of strings.
932  *
933  * Return value: None.
934  **/
935 void
936 gupnp_protocol_info_set_play_speeds (GUPnPProtocolInfo *info,
937                                      const char       **speeds)
938 {
939         g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info));
940
941         if (info->priv->play_speeds)
942                 g_strfreev (info->priv->play_speeds);
943         info->priv->play_speeds = (char **) g_boxed_copy (G_TYPE_STRV, speeds);
944
945         g_object_notify (G_OBJECT (info), "play-speeds");
946 }
947
948 /**
949  * gupnp_protocol_info_set_dlna_conversion:
950  * @info: A #GUPnPProtocolInfo
951  * @conversion: The bitwise OR of one or more DLNA conversion flags
952  *
953  * Set the DLNA conversion flags.
954  *
955  * Return value: None.
956  **/
957 void
958 gupnp_protocol_info_set_dlna_conversion (GUPnPProtocolInfo  *info,
959                                          GUPnPDLNAConversion conversion)
960 {
961         g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info));
962
963         info->priv->dlna_conversion = conversion;
964
965         g_object_notify (G_OBJECT (info), "dlna-conversion");
966 }
967
968 /**
969  * gupnp_protocol_info_set_dlna_operation:
970  * @info: A #GUPnPProtocolInfo
971  * @operation: The bitwise OR of one or more DLNA operation flags
972  *
973  * Set the DLNA operation flags.
974  *
975  * Return value: None.
976  **/
977 void
978 gupnp_protocol_info_set_dlna_operation (GUPnPProtocolInfo *info,
979                                         GUPnPDLNAOperation operation)
980 {
981         g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info));
982
983         info->priv->dlna_operation = operation;
984
985         g_object_notify (G_OBJECT (info), "dlna-operation");
986 }
987
988 /**
989  * gupnp_protocol_info_set_dlna_flags:
990  * @info: A #GUPnPProtocolInfo
991  * @flags: The bitwise OR of one or more generic DLNA flags
992  *
993  * Set the gereric DLNA flags.
994  *
995  * Return value: None.
996  **/
997 void
998 gupnp_protocol_info_set_dlna_flags (GUPnPProtocolInfo  *info,
999                                     GUPnPDLNAFlags      flags)
1000 {
1001         g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info));
1002
1003         info->priv->dlna_flags = flags;
1004
1005         g_object_notify (G_OBJECT (info), "dlna-flags");
1006 }
1007
1008 /**
1009  * gupnp_protocol_info_is_compatible:
1010  * @info1: The first #GUPnPProtocolInfo
1011  * @info2: The second #GUPnPProtocolInfo
1012  *
1013  * Checks if the given protocolInfo string is compatible with @info.
1014  *
1015  * Return value: #TRUE if @protocol_info is compatible with @info, otherwise
1016  * #FALSE.
1017  **/
1018 gboolean
1019 gupnp_protocol_info_is_compatible (GUPnPProtocolInfo *info1,
1020                                    GUPnPProtocolInfo *info2)
1021 {
1022         g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info1), FALSE);
1023         g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info2), FALSE);
1024
1025         return is_transport_compat (info1, info2) &&
1026                is_content_format_compat (info1, info2) &&
1027                is_additional_info_compat (info1, info2);
1028 }
1029