|
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 * <refsect2> |
|
49 * <para> |
|
50 * Provides common defines for the RTSP library. |
|
51 * </para> |
|
52 * </refsect2> |
|
53 * |
|
54 * Last reviewed on 2007-07-24 (0.10.14) |
|
55 */ |
|
56 |
|
57 #include <errno.h> |
|
58 |
|
59 extern int h_errno; |
|
60 |
|
61 #include "gstrtspdefs.h" |
|
62 |
|
63 #ifndef G_OS_WIN32 |
|
64 #include <netdb.h> |
|
65 #endif |
|
66 |
|
67 static const gchar *rtsp_results[] = { |
|
68 "OK", |
|
69 /* errors */ |
|
70 "Generic error", |
|
71 "Invalid parameter specified", |
|
72 "Operation interrupted", |
|
73 "Out of memory", |
|
74 "Cannot resolve host", |
|
75 "Function not implemented", |
|
76 "System error: %s", |
|
77 "Parse error", |
|
78 "Error on WSAStartup", |
|
79 "Windows sockets are not version 0x202", |
|
80 "Received end-of-file", |
|
81 "Network error: %s", |
|
82 "Host is not a valid IP address", |
|
83 "Timeout while waiting for server response", |
|
84 "Unknown error (%d)", |
|
85 NULL |
|
86 }; |
|
87 |
|
88 static const gchar *rtsp_methods[] = { |
|
89 "DESCRIBE", |
|
90 "ANNOUNCE", |
|
91 "GET_PARAMETER", |
|
92 "OPTIONS", |
|
93 "PAUSE", |
|
94 "PLAY", |
|
95 "RECORD", |
|
96 "REDIRECT", |
|
97 "SETUP", |
|
98 "SET_PARAMETER", |
|
99 "TEARDOWN", |
|
100 NULL |
|
101 }; |
|
102 |
|
103 static const gchar *rtsp_headers[] = { |
|
104 "Accept", /* Accept R opt. entity */ |
|
105 "Accept-Encoding", /* Accept-Encoding R opt. entity */ |
|
106 "Accept-Language", /* Accept-Language R opt. all */ |
|
107 "Allow", /* Allow r opt. all */ |
|
108 "Authorization", /* Authorization R opt. all */ |
|
109 "Bandwidth", /* Bandwidth R opt. all */ |
|
110 "Blocksize", /* Blocksize R opt. all but OPTIONS, TEARDOWN */ |
|
111 "Cache-Control", /* Cache-Control g opt. SETUP */ |
|
112 "Conference", /* Conference R opt. SETUP */ |
|
113 "Connection", /* Connection g req. all */ |
|
114 "Content-Base", /* Content-Base e opt. entity */ |
|
115 "Content-Encoding", /* Content-Encoding e req. SET_PARAMETER, DESCRIBE, ANNOUNCE */ |
|
116 "Content-Language", /* Content-Language e req. DESCRIBE, ANNOUNCE */ |
|
117 "Content-Length", /* Content-Length e req. SET_PARAMETER, ANNOUNCE, entity */ |
|
118 "Content-Location", /* Content-Location e opt. entity */ |
|
119 "Content-Type", /* Content-Type e req. SET_PARAMETER, ANNOUNCE, entity */ |
|
120 "CSeq", /* CSeq g req. all */ |
|
121 "Date", /* Date g opt. all */ |
|
122 "Expires", /* Expires e opt. DESCRIBE, ANNOUNCE */ |
|
123 "From", /* From R opt. all */ |
|
124 "If-Modified-Since", /* If-Modified-Since R opt. DESCRIBE, SETUP */ |
|
125 "Last-Modified", /* Last-Modified e opt. entity */ |
|
126 "Proxy-Authenticate", /* Proxy-Authenticate */ |
|
127 "Proxy-Require", /* Proxy-Require R req. all */ |
|
128 "Public", /* Public r opt. all */ |
|
129 "Range", /* Range Rr opt. PLAY, PAUSE, RECORD */ |
|
130 "Referer", /* Referer R opt. all */ |
|
131 "Require", /* Require R req. all */ |
|
132 "Retry-After", /* Retry-After r opt. all */ |
|
133 "RTP-Info", /* RTP-Info r req. PLAY */ |
|
134 "Scale", /* Scale Rr opt. PLAY, RECORD */ |
|
135 "Session", /* Session Rr req. all but SETUP, OPTIONS */ |
|
136 "Server", /* Server r opt. all */ |
|
137 "Speed", /* Speed Rr opt. PLAY */ |
|
138 "Transport", /* Transport Rr req. SETUP */ |
|
139 "Unsupported", /* Unsupported r req. all */ |
|
140 "User-Agent", /* User-Agent R opt. all */ |
|
141 "Via", /* Via g opt. all */ |
|
142 "WWW-Authenticate", /* WWW-Authenticate r opt. all */ |
|
143 |
|
144 /* Real extensions */ |
|
145 "ClientChallenge", /* ClientChallenge */ |
|
146 "RealChallenge1", /* RealChallenge1 */ |
|
147 "RealChallenge2", /* RealChallenge2 */ |
|
148 "RealChallenge3", /* RealChallenge3 */ |
|
149 "Subscribe", /* Subscribe */ |
|
150 "Alert", /* Alert */ |
|
151 "ClientID", /* ClientID */ |
|
152 "CompanyID", /* CompanyID */ |
|
153 "GUID", /* GUID */ |
|
154 "RegionData", /* RegionData */ |
|
155 "SupportsMaximumASMBandwidth", /* SupportsMaximumASMBandwidth */ |
|
156 "Language", /* Language */ |
|
157 "PlayerStarttime", /* PlayerStarttime */ |
|
158 |
|
159 "Location", /* Location */ |
|
160 |
|
161 NULL |
|
162 }; |
|
163 |
|
164 #define DEF_STATUS(c, t) \ |
|
165 g_hash_table_insert (statuses, GUINT_TO_POINTER(c), t) |
|
166 |
|
167 static GHashTable * |
|
168 rtsp_init_status (void) |
|
169 { |
|
170 GHashTable *statuses = g_hash_table_new (NULL, NULL); |
|
171 |
|
172 DEF_STATUS (GST_RTSP_STS_CONTINUE, "Continue"); |
|
173 DEF_STATUS (GST_RTSP_STS_OK, "OK"); |
|
174 DEF_STATUS (GST_RTSP_STS_CREATED, "Created"); |
|
175 DEF_STATUS (GST_RTSP_STS_LOW_ON_STORAGE, "Low on Storage Space"); |
|
176 DEF_STATUS (GST_RTSP_STS_MULTIPLE_CHOICES, "Multiple Choices"); |
|
177 DEF_STATUS (GST_RTSP_STS_MOVED_PERMANENTLY, "Moved Permanently"); |
|
178 DEF_STATUS (GST_RTSP_STS_MOVE_TEMPORARILY, "Move Temporarily"); |
|
179 DEF_STATUS (GST_RTSP_STS_SEE_OTHER, "See Other"); |
|
180 DEF_STATUS (GST_RTSP_STS_NOT_MODIFIED, "Not Modified"); |
|
181 DEF_STATUS (GST_RTSP_STS_USE_PROXY, "Use Proxy"); |
|
182 DEF_STATUS (GST_RTSP_STS_BAD_REQUEST, "Bad Request"); |
|
183 DEF_STATUS (GST_RTSP_STS_UNAUTHORIZED, "Unauthorized"); |
|
184 DEF_STATUS (GST_RTSP_STS_PAYMENT_REQUIRED, "Payment Required"); |
|
185 DEF_STATUS (GST_RTSP_STS_FORBIDDEN, "Forbidden"); |
|
186 DEF_STATUS (GST_RTSP_STS_NOT_FOUND, "Not Found"); |
|
187 DEF_STATUS (GST_RTSP_STS_METHOD_NOT_ALLOWED, "Method Not Allowed"); |
|
188 DEF_STATUS (GST_RTSP_STS_NOT_ACCEPTABLE, "Not Acceptable"); |
|
189 DEF_STATUS (GST_RTSP_STS_PROXY_AUTH_REQUIRED, |
|
190 "Proxy Authentication Required"); |
|
191 DEF_STATUS (GST_RTSP_STS_REQUEST_TIMEOUT, "Request Time-out"); |
|
192 DEF_STATUS (GST_RTSP_STS_GONE, "Gone"); |
|
193 DEF_STATUS (GST_RTSP_STS_LENGTH_REQUIRED, "Length Required"); |
|
194 DEF_STATUS (GST_RTSP_STS_PRECONDITION_FAILED, "Precondition Failed"); |
|
195 DEF_STATUS (GST_RTSP_STS_REQUEST_ENTITY_TOO_LARGE, |
|
196 "Request Entity Too Large"); |
|
197 DEF_STATUS (GST_RTSP_STS_REQUEST_URI_TOO_LARGE, "Request-URI Too Large"); |
|
198 DEF_STATUS (GST_RTSP_STS_UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type"); |
|
199 DEF_STATUS (GST_RTSP_STS_PARAMETER_NOT_UNDERSTOOD, |
|
200 "Parameter Not Understood"); |
|
201 DEF_STATUS (GST_RTSP_STS_CONFERENCE_NOT_FOUND, "Conference Not Found"); |
|
202 DEF_STATUS (GST_RTSP_STS_NOT_ENOUGH_BANDWIDTH, "Not Enough Bandwidth"); |
|
203 DEF_STATUS (GST_RTSP_STS_SESSION_NOT_FOUND, "Session Not Found"); |
|
204 DEF_STATUS (GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE, |
|
205 "Method Not Valid in This State"); |
|
206 DEF_STATUS (GST_RTSP_STS_HEADER_FIELD_NOT_VALID_FOR_RESOURCE, |
|
207 "Header Field Not Valid for Resource"); |
|
208 DEF_STATUS (GST_RTSP_STS_INVALID_RANGE, "Invalid Range"); |
|
209 DEF_STATUS (GST_RTSP_STS_PARAMETER_IS_READONLY, "Parameter Is Read-Only"); |
|
210 DEF_STATUS (GST_RTSP_STS_AGGREGATE_OPERATION_NOT_ALLOWED, |
|
211 "Aggregate operation not allowed"); |
|
212 DEF_STATUS (GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, |
|
213 "Only aggregate operation allowed"); |
|
214 DEF_STATUS (GST_RTSP_STS_UNSUPPORTED_TRANSPORT, "Unsupported transport"); |
|
215 DEF_STATUS (GST_RTSP_STS_DESTINATION_UNREACHABLE, "Destination unreachable"); |
|
216 DEF_STATUS (GST_RTSP_STS_INTERNAL_SERVER_ERROR, "Internal Server Error"); |
|
217 DEF_STATUS (GST_RTSP_STS_NOT_IMPLEMENTED, "Not Implemented"); |
|
218 DEF_STATUS (GST_RTSP_STS_BAD_GATEWAY, "Bad Gateway"); |
|
219 DEF_STATUS (GST_RTSP_STS_SERVICE_UNAVAILABLE, "Service Unavailable"); |
|
220 DEF_STATUS (GST_RTSP_STS_GATEWAY_TIMEOUT, "Gateway Time-out"); |
|
221 DEF_STATUS (GST_RTSP_STS_RTSP_VERSION_NOT_SUPPORTED, |
|
222 "RTSP Version not supported"); |
|
223 DEF_STATUS (GST_RTSP_STS_OPTION_NOT_SUPPORTED, "Option not supported"); |
|
224 |
|
225 return statuses; |
|
226 } |
|
227 |
|
228 /** |
|
229 * gst_rtsp_strresult: |
|
230 * @result: a #GstRTSPResult |
|
231 * |
|
232 * Convert @result in a human readable string. |
|
233 * |
|
234 * Returns: a newly allocated string. g_free() after usage. |
|
235 */ |
|
236 gchar * |
|
237 gst_rtsp_strresult (GstRTSPResult result) |
|
238 { |
|
239 gint idx; |
|
240 gchar *res; |
|
241 |
|
242 idx = ABS (result); |
|
243 idx = CLAMP (idx, 0, -GST_RTSP_ELAST); |
|
244 |
|
245 switch (idx) { |
|
246 case -GST_RTSP_ESYS: |
|
247 res = g_strdup_printf (rtsp_results[idx], g_strerror (errno)); |
|
248 break; |
|
249 case -GST_RTSP_ENET: |
|
250 #ifndef G_OS_WIN32 |
|
251 res = g_strdup_printf (rtsp_results[idx], hstrerror (h_errno)); |
|
252 #else |
|
253 res = |
|
254 g_strdup |
|
255 ("not supported on win32, implement me in a different way ??"); |
|
256 #endif |
|
257 break; |
|
258 case -GST_RTSP_ELAST: |
|
259 res = g_strdup_printf (rtsp_results[idx], result); |
|
260 break; |
|
261 default: |
|
262 res = g_strdup (rtsp_results[idx]); |
|
263 break; |
|
264 } |
|
265 return res; |
|
266 } |
|
267 |
|
268 /** |
|
269 * gst_rtsp_method_as_text: |
|
270 * @method: a #GstRTSPMethod |
|
271 * |
|
272 * Convert @method to a string. |
|
273 * |
|
274 * Returns: a string representation of @method. |
|
275 */ |
|
276 const gchar * |
|
277 gst_rtsp_method_as_text (GstRTSPMethod method) |
|
278 { |
|
279 gint i; |
|
280 |
|
281 if (method == GST_RTSP_INVALID) |
|
282 return NULL; |
|
283 |
|
284 i = 0; |
|
285 while ((method & 1) == 0) { |
|
286 i++; |
|
287 method >>= 1; |
|
288 } |
|
289 return rtsp_methods[i]; |
|
290 } |
|
291 |
|
292 /** |
|
293 * gst_rtsp_version_as_text: |
|
294 * @version: a #GstRTSPVersion |
|
295 * |
|
296 * Convert @version to a string. |
|
297 * |
|
298 * Returns: a string representation of @version. |
|
299 */ |
|
300 const gchar * |
|
301 gst_rtsp_version_as_text (GstRTSPVersion version) |
|
302 { |
|
303 switch (version) { |
|
304 case GST_RTSP_VERSION_1_0: |
|
305 return "1.0"; |
|
306 |
|
307 default: |
|
308 return "0.0"; |
|
309 } |
|
310 } |
|
311 |
|
312 /** |
|
313 * gst_rtsp_header_as_text: |
|
314 * @field: a #GstRTSPHeaderField |
|
315 * |
|
316 * Convert @field to a string. |
|
317 * |
|
318 * Returns: a string representation of @field. |
|
319 */ |
|
320 const gchar * |
|
321 gst_rtsp_header_as_text (GstRTSPHeaderField field) |
|
322 { |
|
323 if (field == GST_RTSP_HDR_INVALID) |
|
324 return NULL; |
|
325 else |
|
326 return rtsp_headers[field - 1]; |
|
327 } |
|
328 |
|
329 /** |
|
330 * gst_rtsp_status_as_text: |
|
331 * @code: a #GstRTSPStatusCode |
|
332 * |
|
333 * Convert @code to a string. |
|
334 * |
|
335 * Returns: a string representation of @code. |
|
336 */ |
|
337 const gchar * |
|
338 gst_rtsp_status_as_text (GstRTSPStatusCode code) |
|
339 { |
|
340 static GHashTable *statuses; |
|
341 |
|
342 if (G_UNLIKELY (statuses == NULL)) |
|
343 statuses = rtsp_init_status (); |
|
344 |
|
345 return g_hash_table_lookup (statuses, GUINT_TO_POINTER (code)); |
|
346 } |
|
347 |
|
348 /** |
|
349 * gst_rtsp_find_header_field: |
|
350 * @header: a header string |
|
351 * |
|
352 * Convert @header to a #GstRTSPHeaderField. |
|
353 * |
|
354 * Returns: a #GstRTSPHeaderField for @header or #GST_RTSP_HDR_INVALID if the |
|
355 * header field is unknown. |
|
356 */ |
|
357 GstRTSPHeaderField |
|
358 gst_rtsp_find_header_field (const gchar * header) |
|
359 { |
|
360 gint idx; |
|
361 |
|
362 for (idx = 0; rtsp_headers[idx]; idx++) { |
|
363 if (g_ascii_strcasecmp (rtsp_headers[idx], header) == 0) { |
|
364 return idx + 1; |
|
365 } |
|
366 } |
|
367 return GST_RTSP_HDR_INVALID; |
|
368 } |
|
369 |
|
370 /** |
|
371 * gst_rtsp_find_method: |
|
372 * @method: a method |
|
373 * |
|
374 * Convert @method to a #GstRTSPMethod. |
|
375 * |
|
376 * Returns: a #GstRTSPMethod for @method or #GST_RTSP_INVALID if the |
|
377 * method is unknown. |
|
378 */ |
|
379 GstRTSPMethod |
|
380 gst_rtsp_find_method (const gchar * method) |
|
381 { |
|
382 gint idx; |
|
383 |
|
384 for (idx = 0; rtsp_methods[idx]; idx++) { |
|
385 if (g_ascii_strcasecmp (rtsp_methods[idx], method) == 0) { |
|
386 return (1 << idx); |
|
387 } |
|
388 } |
|
389 return GST_RTSP_INVALID; |
|
390 } |