Macro qtTrIdx() replaced by tr() and QT_TRANSLATE_NOOP()
[mafwsubrenderer] / gst-plugins-base-subtitles0.10 / gst-libs / gst / rtsp / gstrtspdefs.c
1 /* GStreamer
2  * Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 /*
20  * Unless otherwise indicated, Source Code is licensed under MIT license.
21  * See further explanation attached in License Statement (distributed in the file
22  * LICENSE).
23  *
24  * Permission is hereby granted, free of charge, to any person obtaining a copy of
25  * this software and associated documentation files (the "Software"), to deal in
26  * the Software without restriction, including without limitation the rights to
27  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
28  * of the Software, and to permit persons to whom the Software is furnished to do
29  * so, subject to the following conditions:
30  *
31  * The above copyright notice and this permission notice shall be included in all
32  * copies or substantial portions of the Software.
33  *
34  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
37  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
39  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
40  * SOFTWARE.
41  */
42
43 /**
44  * SECTION:gstrtspdefs
45  * @short_description: common RTSP defines
46  * @see_also: gstrtspurl, gstrtspconnection
47  *  
48  * Provides common defines for the RTSP library. 
49  *  
50  * Last reviewed on 2007-07-24 (0.10.14)
51  */
52
53 #include <errno.h>
54
55 #include "gstrtspdefs.h"
56
57 #ifdef G_OS_WIN32
58 #include <winsock2.h>
59 #else
60 #include <netdb.h>
61 #endif
62
63 struct rtsp_header
64 {
65   const gchar *name;
66   gboolean multiple;
67 };
68
69 static const gchar *rtsp_methods[] = {
70   "DESCRIBE",
71   "ANNOUNCE",
72   "GET_PARAMETER",
73   "OPTIONS",
74   "PAUSE",
75   "PLAY",
76   "RECORD",
77   "REDIRECT",
78   "SETUP",
79   "SET_PARAMETER",
80   "TEARDOWN",
81   "GET",
82   "POST",
83   NULL
84 };
85
86 static struct rtsp_header rtsp_headers[] = {
87   {"Accept", TRUE},
88   {"Accept-Encoding", TRUE},
89   {"Accept-Language", TRUE},
90   {"Allow", TRUE},
91   {"Authorization", FALSE},
92   {"Bandwidth", FALSE},
93   {"Blocksize", FALSE},
94   {"Cache-Control", TRUE},
95   {"Conference", FALSE},
96   {"Connection", TRUE},
97   {"Content-Base", FALSE},
98   {"Content-Encoding", TRUE},
99   {"Content-Language", TRUE},
100   {"Content-Length", FALSE},
101   {"Content-Location", FALSE},
102   {"Content-Type", FALSE},
103   {"CSeq", FALSE},
104   {"Date", FALSE},
105   {"Expires", FALSE},
106   {"From", FALSE},
107   {"If-Modified-Since", FALSE},
108   {"Last-Modified", FALSE},
109   {"Proxy-Authenticate", TRUE},
110   {"Proxy-Require", TRUE},
111   {"Public", TRUE},
112   {"Range", FALSE},
113   {"Referer", FALSE},
114   {"Require", TRUE},
115   {"Retry-After", FALSE},
116   {"RTP-Info", TRUE},
117   {"Scale", FALSE},
118   {"Session", FALSE},
119   {"Server", FALSE},
120   {"Speed", FALSE},
121   {"Transport", TRUE},
122   {"Unsupported", FALSE},
123   {"User-Agent", FALSE},
124   {"Via", TRUE},
125   {"WWW-Authenticate", TRUE},
126
127   /* Real extensions */
128   {"ClientChallenge", FALSE},
129   {"RealChallenge1", FALSE},
130   {"RealChallenge2", FALSE},
131   {"RealChallenge3", FALSE},
132   {"Subscribe", FALSE},
133   {"Alert", FALSE},
134   {"ClientID", FALSE},
135   {"CompanyID", FALSE},
136   {"GUID", FALSE},
137   {"RegionData", FALSE},
138   {"SupportsMaximumASMBandwidth", FALSE},
139   {"Language", FALSE},
140   {"PlayerStarttime", FALSE},
141
142   /* Since 0.10.16 */
143   {"Location", FALSE},
144
145   /* Since 0.10.23 */
146   {"ETag", FALSE},
147   {"If-Match", TRUE},
148
149   /* WM extensions [MS-RTSP] Since 0.10.23 */
150   {"Accept-Charset", TRUE},
151   {"Supported", TRUE},
152   {"Vary", TRUE},
153   {"X-Accelerate-Streaming", FALSE},
154   {"X-Accept-Authentication", FALSE},
155   {"X-Accept-Proxy-Authentication", FALSE},
156   {"X-Broadcast-Id", FALSE},
157   {"X-Burst-Streaming", FALSE},
158   {"X-Notice", FALSE},
159   {"X-Player-Lag-Time", FALSE},
160   {"X-Playlist", FALSE},
161   {"X-Playlist-Change-Notice", FALSE},
162   {"X-Playlist-Gen-Id", FALSE},
163   {"X-Playlist-Seek-Id", FALSE},
164   {"X-Proxy-Client-Agent", FALSE},
165   {"X-Proxy-Client-Verb", FALSE},
166   {"X-Receding-PlaylistChange", FALSE},
167   {"X-RTP-Info", FALSE},
168   {"X-StartupProfile", FALSE},
169
170   /* Since 0.10.24 */
171   {"Timestamp", FALSE},
172
173   /* Since 0.10.25 */
174   {"Authentication-Info", FALSE},
175   {"Host", FALSE},
176   {"Pragma", TRUE},
177   {"X-Server-IP-Address", FALSE},
178   {"X-Sessioncookie", FALSE},
179
180   {NULL, FALSE}
181 };
182
183 #define DEF_STATUS(c, t) \
184   g_hash_table_insert (statuses, GUINT_TO_POINTER(c), (gpointer) t)
185
186 static GHashTable *
187 rtsp_init_status (void)
188 {
189   GHashTable *statuses = g_hash_table_new (NULL, NULL);
190
191   DEF_STATUS (GST_RTSP_STS_CONTINUE, "Continue");
192   DEF_STATUS (GST_RTSP_STS_OK, "OK");
193   DEF_STATUS (GST_RTSP_STS_CREATED, "Created");
194   DEF_STATUS (GST_RTSP_STS_LOW_ON_STORAGE, "Low on Storage Space");
195   DEF_STATUS (GST_RTSP_STS_MULTIPLE_CHOICES, "Multiple Choices");
196   DEF_STATUS (GST_RTSP_STS_MOVED_PERMANENTLY, "Moved Permanently");
197   DEF_STATUS (GST_RTSP_STS_MOVE_TEMPORARILY, "Move Temporarily");
198   DEF_STATUS (GST_RTSP_STS_SEE_OTHER, "See Other");
199   DEF_STATUS (GST_RTSP_STS_NOT_MODIFIED, "Not Modified");
200   DEF_STATUS (GST_RTSP_STS_USE_PROXY, "Use Proxy");
201   DEF_STATUS (GST_RTSP_STS_BAD_REQUEST, "Bad Request");
202   DEF_STATUS (GST_RTSP_STS_UNAUTHORIZED, "Unauthorized");
203   DEF_STATUS (GST_RTSP_STS_PAYMENT_REQUIRED, "Payment Required");
204   DEF_STATUS (GST_RTSP_STS_FORBIDDEN, "Forbidden");
205   DEF_STATUS (GST_RTSP_STS_NOT_FOUND, "Not Found");
206   DEF_STATUS (GST_RTSP_STS_METHOD_NOT_ALLOWED, "Method Not Allowed");
207   DEF_STATUS (GST_RTSP_STS_NOT_ACCEPTABLE, "Not Acceptable");
208   DEF_STATUS (GST_RTSP_STS_PROXY_AUTH_REQUIRED,
209       "Proxy Authentication Required");
210   DEF_STATUS (GST_RTSP_STS_REQUEST_TIMEOUT, "Request Time-out");
211   DEF_STATUS (GST_RTSP_STS_GONE, "Gone");
212   DEF_STATUS (GST_RTSP_STS_LENGTH_REQUIRED, "Length Required");
213   DEF_STATUS (GST_RTSP_STS_PRECONDITION_FAILED, "Precondition Failed");
214   DEF_STATUS (GST_RTSP_STS_REQUEST_ENTITY_TOO_LARGE,
215       "Request Entity Too Large");
216   DEF_STATUS (GST_RTSP_STS_REQUEST_URI_TOO_LARGE, "Request-URI Too Large");
217   DEF_STATUS (GST_RTSP_STS_UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type");
218   DEF_STATUS (GST_RTSP_STS_PARAMETER_NOT_UNDERSTOOD,
219       "Parameter Not Understood");
220   DEF_STATUS (GST_RTSP_STS_CONFERENCE_NOT_FOUND, "Conference Not Found");
221   DEF_STATUS (GST_RTSP_STS_NOT_ENOUGH_BANDWIDTH, "Not Enough Bandwidth");
222   DEF_STATUS (GST_RTSP_STS_SESSION_NOT_FOUND, "Session Not Found");
223   DEF_STATUS (GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE,
224       "Method Not Valid in This State");
225   DEF_STATUS (GST_RTSP_STS_HEADER_FIELD_NOT_VALID_FOR_RESOURCE,
226       "Header Field Not Valid for Resource");
227   DEF_STATUS (GST_RTSP_STS_INVALID_RANGE, "Invalid Range");
228   DEF_STATUS (GST_RTSP_STS_PARAMETER_IS_READONLY, "Parameter Is Read-Only");
229   DEF_STATUS (GST_RTSP_STS_AGGREGATE_OPERATION_NOT_ALLOWED,
230       "Aggregate operation not allowed");
231   DEF_STATUS (GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED,
232       "Only aggregate operation allowed");
233   DEF_STATUS (GST_RTSP_STS_UNSUPPORTED_TRANSPORT, "Unsupported transport");
234   DEF_STATUS (GST_RTSP_STS_DESTINATION_UNREACHABLE, "Destination unreachable");
235   DEF_STATUS (GST_RTSP_STS_INTERNAL_SERVER_ERROR, "Internal Server Error");
236   DEF_STATUS (GST_RTSP_STS_NOT_IMPLEMENTED, "Not Implemented");
237   DEF_STATUS (GST_RTSP_STS_BAD_GATEWAY, "Bad Gateway");
238   DEF_STATUS (GST_RTSP_STS_SERVICE_UNAVAILABLE, "Service Unavailable");
239   DEF_STATUS (GST_RTSP_STS_GATEWAY_TIMEOUT, "Gateway Time-out");
240   DEF_STATUS (GST_RTSP_STS_RTSP_VERSION_NOT_SUPPORTED,
241       "RTSP Version not supported");
242   DEF_STATUS (GST_RTSP_STS_OPTION_NOT_SUPPORTED, "Option not supported");
243
244   return statuses;
245 }
246
247 /**
248  * gst_rtsp_strresult:
249  * @result: a #GstRTSPResult
250  *
251  * Convert @result in a human readable string.
252  *
253  * Returns: a newly allocated string. g_free() after usage.
254  */
255 gchar *
256 gst_rtsp_strresult (GstRTSPResult result)
257 {
258   switch (result) {
259     case GST_RTSP_OK:
260       return g_strdup ("OK");
261 #ifdef G_OS_WIN32
262     case GST_RTSP_ESYS:
263     case GST_RTSP_ENET:
264     {
265       gchar *res, *msg;
266       msg = g_win32_error_message (WSAGetLastError ());
267       if (result == GST_RTSP_ESYS)
268         res = g_strdup_printf ("System error: %s", msg);
269       else
270         res = g_strdup_printf ("Network error: %s", msg);
271       g_free (msg);
272       return res;
273     }
274 #else
275     case GST_RTSP_ESYS:
276       return g_strdup_printf ("System error: %s", g_strerror (errno));
277     case GST_RTSP_ENET:
278       return g_strdup_printf ("Network error: %s", hstrerror (h_errno));
279 #endif
280     case GST_RTSP_ERROR:
281       return g_strdup ("Generic error");
282     case GST_RTSP_EINVAL:
283       return g_strdup ("Invalid parameter specified");
284     case GST_RTSP_EINTR:
285       return g_strdup ("Operation interrupted");
286     case GST_RTSP_ENOMEM:
287       return g_strdup ("Out of memory");
288     case GST_RTSP_ERESOLV:
289       return g_strdup ("Cannot resolve host");
290     case GST_RTSP_ENOTIMPL:
291       return g_strdup ("Function not implemented");
292     case GST_RTSP_EPARSE:
293       return g_strdup ("Parse error");
294     case GST_RTSP_EWSASTART:
295       return g_strdup ("Error on WSAStartup");
296     case GST_RTSP_EWSAVERSION:
297       return g_strdup ("Windows sockets are not version 0x202");
298     case GST_RTSP_EEOF:
299       return g_strdup ("Received end-of-file");
300     case GST_RTSP_ENOTIP:
301       return g_strdup ("Host is not a valid IP address");
302     case GST_RTSP_ETIMEOUT:
303       return g_strdup ("Timeout while waiting for server response");
304     case GST_RTSP_ETGET:
305       return g_strdup ("Tunnel GET request received");
306     case GST_RTSP_ETPOST:
307       return g_strdup ("Tunnel POST request received");
308     case GST_RTSP_ELAST:
309     default:
310       return g_strdup_printf ("Unknown error (%d)", result);
311   }
312 }
313
314 /**
315  * gst_rtsp_method_as_text:
316  * @method: a #GstRTSPMethod
317  *
318  * Convert @method to a string.
319  *
320  * Returns: a string representation of @method.
321  */
322 const gchar *
323 gst_rtsp_method_as_text (GstRTSPMethod method)
324 {
325   gint i;
326
327   if (method == GST_RTSP_INVALID)
328     return NULL;
329
330   i = 0;
331   while ((method & 1) == 0) {
332     i++;
333     method >>= 1;
334   }
335   return rtsp_methods[i];
336 }
337
338 /**
339  * gst_rtsp_version_as_text:
340  * @version: a #GstRTSPVersion
341  *
342  * Convert @version to a string.
343  *
344  * Returns: a string representation of @version.
345  */
346 const gchar *
347 gst_rtsp_version_as_text (GstRTSPVersion version)
348 {
349   switch (version) {
350     case GST_RTSP_VERSION_1_0:
351       return "1.0";
352
353     case GST_RTSP_VERSION_1_1:
354       return "1.1";
355
356     default:
357       return "0.0";
358   }
359 }
360
361 /**
362  * gst_rtsp_header_as_text:
363  * @field: a #GstRTSPHeaderField
364  *
365  * Convert @field to a string.
366  *
367  * Returns: a string representation of @field.
368  */
369 const gchar *
370 gst_rtsp_header_as_text (GstRTSPHeaderField field)
371 {
372   if (field == GST_RTSP_HDR_INVALID)
373     return NULL;
374   else
375     return rtsp_headers[field - 1].name;
376 }
377
378 /**
379  * gst_rtsp_status_as_text:
380  * @code: a #GstRTSPStatusCode
381  *
382  * Convert @code to a string.
383  *
384  * Returns: a string representation of @code.
385  */
386 const gchar *
387 gst_rtsp_status_as_text (GstRTSPStatusCode code)
388 {
389   static GHashTable *statuses;
390
391   if (G_UNLIKELY (statuses == NULL))
392     statuses = rtsp_init_status ();
393
394   return g_hash_table_lookup (statuses, GUINT_TO_POINTER (code));
395 }
396
397 /**
398  * gst_rtsp_find_header_field:
399  * @header: a header string
400  *
401  * Convert @header to a #GstRTSPHeaderField.
402  *
403  * Returns: a #GstRTSPHeaderField for @header or #GST_RTSP_HDR_INVALID if the
404  * header field is unknown.
405  */
406 GstRTSPHeaderField
407 gst_rtsp_find_header_field (const gchar * header)
408 {
409   gint idx;
410
411   for (idx = 0; rtsp_headers[idx].name; idx++) {
412     if (g_ascii_strcasecmp (rtsp_headers[idx].name, header) == 0) {
413       return idx + 1;
414     }
415   }
416   return GST_RTSP_HDR_INVALID;
417 }
418
419 /**
420  * gst_rtsp_find_method:
421  * @method: a method
422  *
423  * Convert @method to a #GstRTSPMethod.
424  *
425  * Returns: a #GstRTSPMethod for @method or #GST_RTSP_INVALID if the
426  * method is unknown.
427  */
428 GstRTSPMethod
429 gst_rtsp_find_method (const gchar * method)
430 {
431   gint idx;
432
433   for (idx = 0; rtsp_methods[idx]; idx++) {
434     if (g_ascii_strcasecmp (rtsp_methods[idx], method) == 0) {
435       return (1 << idx);
436     }
437   }
438   return GST_RTSP_INVALID;
439 }
440
441 /**
442  * gst_rtsp_options_as_text:
443  * @options: one or more #GstRTSPMethod
444  *
445  * Convert @options to a string.
446  *
447  * Returns: a new string of @options. g_free() after usage.
448  *
449  * Since: 0.10.23
450  */
451 gchar *
452 gst_rtsp_options_as_text (GstRTSPMethod options)
453 {
454   GString *str;
455
456   str = g_string_new ("");
457
458   if (options & GST_RTSP_OPTIONS)
459     g_string_append (str, "OPTIONS, ");
460   if (options & GST_RTSP_DESCRIBE)
461     g_string_append (str, "DESCRIBE, ");
462   if (options & GST_RTSP_ANNOUNCE)
463     g_string_append (str, "ANNOUNCE, ");
464   if (options & GST_RTSP_GET_PARAMETER)
465     g_string_append (str, "GET_PARAMETER, ");
466   if (options & GST_RTSP_PAUSE)
467     g_string_append (str, "PAUSE, ");
468   if (options & GST_RTSP_PLAY)
469     g_string_append (str, "PLAY, ");
470   if (options & GST_RTSP_RECORD)
471     g_string_append (str, "RECORD, ");
472   if (options & GST_RTSP_REDIRECT)
473     g_string_append (str, "REDIRECT, ");
474   if (options & GST_RTSP_SETUP)
475     g_string_append (str, "SETUP, ");
476   if (options & GST_RTSP_SET_PARAMETER)
477     g_string_append (str, "SET_PARAMETER, ");
478   if (options & GST_RTSP_TEARDOWN)
479     g_string_append (str, "TEARDOWN, ");
480
481   /* remove trailing ", " if there is one */
482   if (str->len > 2)
483     str = g_string_truncate (str, str->len - 2);
484
485   return g_string_free (str, FALSE);
486 }
487
488 /**
489  * gst_rtsp_header_allow_multiple:
490  * @field: a #GstRTSPHeaderField
491  *
492  * Check whether @field may appear multiple times in a message.
493  *
494  * Returns: %TRUE if multiple headers are allowed.
495  *
496  * Since: 0.10.25
497  */
498 gboolean
499 gst_rtsp_header_allow_multiple (GstRTSPHeaderField field)
500 {
501   if (field == GST_RTSP_HDR_INVALID)
502     return FALSE;
503   else
504     return rtsp_headers[field - 1].multiple;
505 }