79 |
80 |
80 /** |
81 /** |
81 * gst_rtsp_message_new: |
82 * gst_rtsp_message_new: |
82 * @msg: a location for the new #GstRTSPMessage |
83 * @msg: a location for the new #GstRTSPMessage |
83 * |
84 * |
84 * Create a new initialized #GstRTSPMessage. |
85 * Create a new initialized #GstRTSPMessage. Free with gst_rtsp_message_free(). |
85 * |
86 * |
86 * Returns: a #GstRTSPResult. Free with gst_rtsp_message_free(). |
87 * Returns: a #GstRTSPResult. |
87 */ |
88 */ |
88 GstRTSPResult |
89 GstRTSPResult |
89 gst_rtsp_message_new (GstRTSPMessage ** msg) |
90 gst_rtsp_message_new (GstRTSPMessage ** msg) |
90 { |
91 { |
91 GstRTSPMessage *newmsg; |
92 GstRTSPMessage *newmsg; |
142 * @msg: a location for the new #GstRTSPMessage |
143 * @msg: a location for the new #GstRTSPMessage |
143 * @method: the request method to use |
144 * @method: the request method to use |
144 * @uri: the uri of the request |
145 * @uri: the uri of the request |
145 * |
146 * |
146 * Create a new #GstRTSPMessage with @method and @uri and store the result |
147 * Create a new #GstRTSPMessage with @method and @uri and store the result |
147 * request message in @msg. |
148 * request message in @msg. Free with gst_rtsp_message_free(). |
148 * |
149 * |
149 * Returns: a #GstRTSPResult. Free with gst_rtsp_message_free(). |
150 * Returns: a #GstRTSPResult. |
150 */ |
151 */ |
151 GstRTSPResult |
152 GstRTSPResult |
152 gst_rtsp_message_new_request (GstRTSPMessage ** msg, GstRTSPMethod method, |
153 gst_rtsp_message_new_request (GstRTSPMessage ** msg, GstRTSPMethod method, |
153 const gchar * uri) |
154 const gchar * uri) |
154 { |
155 { |
211 GstRTSPResult |
212 GstRTSPResult |
212 gst_rtsp_message_parse_request (GstRTSPMessage * msg, |
213 gst_rtsp_message_parse_request (GstRTSPMessage * msg, |
213 GstRTSPMethod * method, const gchar ** uri, GstRTSPVersion * version) |
214 GstRTSPMethod * method, const gchar ** uri, GstRTSPVersion * version) |
214 { |
215 { |
215 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
216 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
216 g_return_val_if_fail (msg->type != GST_RTSP_MESSAGE_REQUEST, GST_RTSP_EINVAL); |
217 g_return_val_if_fail (msg->type == GST_RTSP_MESSAGE_REQUEST, GST_RTSP_EINVAL); |
217 |
218 |
218 if (method) |
219 if (method) |
219 *method = msg->type_data.request.method; |
220 *method = msg->type_data.request.method; |
220 if (uri) |
221 if (uri) |
221 *uri = msg->type_data.request.uri; |
222 *uri = msg->type_data.request.uri; |
231 * @code: the status code |
232 * @code: the status code |
232 * @reason: the status reason or #NULL |
233 * @reason: the status reason or #NULL |
233 * @request: the request that triggered the response or #NULL |
234 * @request: the request that triggered the response or #NULL |
234 * |
235 * |
235 * Create a new response #GstRTSPMessage with @code and @reason and store the |
236 * Create a new response #GstRTSPMessage with @code and @reason and store the |
236 * result message in @msg. |
237 * result message in @msg. Free with gst_rtsp_message_free(). |
237 * |
238 * |
238 * When @reason is #NULL, the default reason for @code will be used. |
239 * When @reason is #NULL, the default reason for @code will be used. |
239 * |
240 * |
240 * When @request is not #NULL, the relevant headers will be copied to the new |
241 * When @request is not #NULL, the relevant headers will be copied to the new |
241 * response message. |
242 * response message. |
242 * |
243 * |
243 * Returns: a #GstRTSPResult. Free with gst_rtsp_message_free(). |
244 * Returns: a #GstRTSPResult. |
244 */ |
245 */ |
245 GstRTSPResult |
246 GstRTSPResult |
246 gst_rtsp_message_new_response (GstRTSPMessage ** msg, GstRTSPStatusCode code, |
247 gst_rtsp_message_new_response (GstRTSPMessage ** msg, GstRTSPStatusCode code, |
247 const gchar * reason, const GstRTSPMessage * request) |
248 const gchar * reason, const GstRTSPMessage * request) |
248 { |
249 { |
307 header = g_strdup (header); |
308 header = g_strdup (header); |
308 if ((pos = strchr (header, ';'))) { |
309 if ((pos = strchr (header, ';'))) { |
309 *pos = '\0'; |
310 *pos = '\0'; |
310 } |
311 } |
311 g_strchomp (header); |
312 g_strchomp (header); |
312 gst_rtsp_message_add_header (msg, GST_RTSP_HDR_SESSION, header); |
313 gst_rtsp_message_take_header (msg, GST_RTSP_HDR_SESSION, header); |
313 g_free (header); |
|
314 } |
314 } |
315 |
315 |
316 /* FIXME copy more headers? */ |
316 /* FIXME copy more headers? */ |
317 } |
317 } |
318 |
318 |
338 GstRTSPResult |
338 GstRTSPResult |
339 gst_rtsp_message_parse_response (GstRTSPMessage * msg, |
339 gst_rtsp_message_parse_response (GstRTSPMessage * msg, |
340 GstRTSPStatusCode * code, const gchar ** reason, GstRTSPVersion * version) |
340 GstRTSPStatusCode * code, const gchar ** reason, GstRTSPVersion * version) |
341 { |
341 { |
342 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
342 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
343 g_return_val_if_fail (msg->type != GST_RTSP_MESSAGE_RESPONSE, |
343 g_return_val_if_fail (msg->type == GST_RTSP_MESSAGE_RESPONSE, |
344 GST_RTSP_EINVAL); |
344 GST_RTSP_EINVAL); |
345 |
345 |
346 if (code) |
346 if (code) |
347 *code = msg->type_data.response.code; |
347 *code = msg->type_data.response.code; |
348 if (reason) |
348 if (reason) |
357 * gst_rtsp_message_new_data: |
357 * gst_rtsp_message_new_data: |
358 * @msg: a location for the new #GstRTSPMessage |
358 * @msg: a location for the new #GstRTSPMessage |
359 * @channel: the channel |
359 * @channel: the channel |
360 * |
360 * |
361 * Create a new data #GstRTSPMessage with @channel and store the |
361 * Create a new data #GstRTSPMessage with @channel and store the |
362 * result message in @msg. |
362 * result message in @msg. Free with gst_rtsp_message_free(). |
363 * |
363 * |
364 * Returns: a #GstRTSPResult. Free with gst_rtsp_message_free(). |
364 * Returns: a #GstRTSPResult. |
365 */ |
365 */ |
366 GstRTSPResult |
366 GstRTSPResult |
367 gst_rtsp_message_new_data (GstRTSPMessage ** msg, guint8 channel) |
367 gst_rtsp_message_new_data (GstRTSPMessage ** msg, guint8 channel) |
368 { |
368 { |
369 GstRTSPMessage *newmsg; |
369 GstRTSPMessage *newmsg; |
410 */ |
410 */ |
411 GstRTSPResult |
411 GstRTSPResult |
412 gst_rtsp_message_parse_data (GstRTSPMessage * msg, guint8 * channel) |
412 gst_rtsp_message_parse_data (GstRTSPMessage * msg, guint8 * channel) |
413 { |
413 { |
414 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
414 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
415 g_return_val_if_fail (msg->type != GST_RTSP_MESSAGE_DATA, GST_RTSP_EINVAL); |
415 g_return_val_if_fail (msg->type == GST_RTSP_MESSAGE_DATA, GST_RTSP_EINVAL); |
416 |
416 |
417 if (channel) |
417 if (channel) |
418 *channel = msg->type_data.data.channel; |
418 *channel = msg->type_data.data.channel; |
419 |
419 |
420 return GST_RTSP_OK; |
420 return GST_RTSP_OK; |
422 |
422 |
423 /** |
423 /** |
424 * gst_rtsp_message_unset: |
424 * gst_rtsp_message_unset: |
425 * @msg: a #GstRTSPMessage |
425 * @msg: a #GstRTSPMessage |
426 * |
426 * |
427 * Unset the concents of @msg so that it becomes an uninitialized |
427 * Unset the contents of @msg so that it becomes an uninitialized |
428 * #GstRTSPMessage again. This function is mostly used in combination with |
428 * #GstRTSPMessage again. This function is mostly used in combination with |
429 * gst_rtsp_message_init_request(), gst_rtsp_message_init_response() and |
429 * gst_rtsp_message_init_request(), gst_rtsp_message_init_response() and |
430 * gst_rtsp_message_init_data() on stack allocated #GstRTSPMessage structures. |
430 * gst_rtsp_message_init_data() on stack allocated #GstRTSPMessage structures. |
431 * |
431 * |
432 * Returns: #GST_RTSP_OK. |
432 * Returns: #GST_RTSP_OK. |
489 |
489 |
490 return res; |
490 return res; |
491 } |
491 } |
492 |
492 |
493 /** |
493 /** |
494 * gst_rtsp_message_add_header: |
494 * gst_rtsp_message_take_header: |
495 * @msg: a #GstRTSPMessage |
495 * @msg: a #GstRTSPMessage |
496 * @field: a #GstRTSPHeaderField |
496 * @field: a #GstRTSPHeaderField |
497 * @value: the value of the header |
497 * @value: the value of the header |
498 * |
498 * |
499 * Add a header with key @field and @value to @msg. |
499 * Add a header with key @field and @value to @msg. This function takes |
|
500 * ownership of @value. |
|
501 * |
|
502 * Returns: a #GstRTSPResult. |
|
503 * |
|
504 * Since: 0.10.23 |
|
505 */ |
|
506 GstRTSPResult |
|
507 gst_rtsp_message_take_header (GstRTSPMessage * msg, GstRTSPHeaderField field, |
|
508 gchar * value) |
|
509 { |
|
510 RTSPKeyValue key_value; |
|
511 |
|
512 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
|
513 g_return_val_if_fail (value != NULL, GST_RTSP_EINVAL); |
|
514 |
|
515 key_value.field = field; |
|
516 key_value.value = value; |
|
517 |
|
518 g_array_append_val (msg->hdr_fields, key_value); |
|
519 |
|
520 return GST_RTSP_OK; |
|
521 } |
|
522 |
|
523 /** |
|
524 * gst_rtsp_message_add_header: |
|
525 * @msg: a #GstRTSPMessage |
|
526 * @field: a #GstRTSPHeaderField |
|
527 * @value: the value of the header |
|
528 * |
|
529 * Add a header with key @field and @value to @msg. This function takes a copy |
|
530 * of @value. |
500 * |
531 * |
501 * Returns: a #GstRTSPResult. |
532 * Returns: a #GstRTSPResult. |
502 */ |
533 */ |
503 GstRTSPResult |
534 GstRTSPResult |
504 gst_rtsp_message_add_header (GstRTSPMessage * msg, GstRTSPHeaderField field, |
535 gst_rtsp_message_add_header (GstRTSPMessage * msg, GstRTSPHeaderField field, |
505 const gchar * value) |
536 const gchar * value) |
506 { |
537 { |
507 RTSPKeyValue key_value; |
538 return gst_rtsp_message_take_header (msg, field, g_strdup (value)); |
508 |
|
509 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
|
510 g_return_val_if_fail (value != NULL, GST_RTSP_EINVAL); |
|
511 |
|
512 key_value.field = field; |
|
513 key_value.value = g_strdup (value); |
|
514 |
|
515 g_array_append_val (msg->hdr_fields, key_value); |
|
516 |
|
517 return GST_RTSP_OK; |
|
518 } |
539 } |
519 |
540 |
520 /** |
541 /** |
521 * gst_rtsp_message_remove_header: |
542 * gst_rtsp_message_remove_header: |
522 * @msg: a #GstRTSPMessage |
543 * @msg: a #GstRTSPMessage |
537 gint cnt = 0; |
558 gint cnt = 0; |
538 |
559 |
539 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
560 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
540 |
561 |
541 while (i < msg->hdr_fields->len) { |
562 while (i < msg->hdr_fields->len) { |
542 RTSPKeyValue key_value = g_array_index (msg->hdr_fields, RTSPKeyValue, i); |
563 RTSPKeyValue *key_value = &g_array_index (msg->hdr_fields, RTSPKeyValue, i); |
543 |
564 |
544 if (key_value.field == field && (indx == -1 || cnt++ == indx)) { |
565 if (key_value->field == field && (indx == -1 || cnt++ == indx)) { |
|
566 g_free (key_value->value); |
545 g_array_remove_index (msg->hdr_fields, i); |
567 g_array_remove_index (msg->hdr_fields, i); |
546 res = GST_RTSP_OK; |
568 res = GST_RTSP_OK; |
547 if (indx != -1) |
569 if (indx != -1) |
548 break; |
570 break; |
549 } else { |
571 } else { |
558 * @msg: a #GstRTSPMessage |
580 * @msg: a #GstRTSPMessage |
559 * @field: a #GstRTSPHeaderField |
581 * @field: a #GstRTSPHeaderField |
560 * @value: pointer to hold the result |
582 * @value: pointer to hold the result |
561 * @indx: the index of the header |
583 * @indx: the index of the header |
562 * |
584 * |
563 * Get the @indx header value with key @field from @msg. |
585 * Get the @indx header value with key @field from @msg. The result in @value |
|
586 * stays valid as long as it remains present in @msg. |
564 * |
587 * |
565 * Returns: #GST_RTSP_OK when @field was found, #GST_RTSP_ENOTIMPL if the key |
588 * Returns: #GST_RTSP_OK when @field was found, #GST_RTSP_ENOTIMPL if the key |
566 * was not found. |
589 * was not found. |
567 */ |
590 */ |
568 GstRTSPResult |
591 GstRTSPResult |
572 guint i; |
595 guint i; |
573 gint cnt = 0; |
596 gint cnt = 0; |
574 |
597 |
575 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
598 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
576 |
599 |
|
600 /* no header initialized, there are no headers */ |
|
601 if (msg->hdr_fields == NULL) |
|
602 return GST_RTSP_ENOTIMPL; |
|
603 |
577 for (i = 0; i < msg->hdr_fields->len; i++) { |
604 for (i = 0; i < msg->hdr_fields->len; i++) { |
578 RTSPKeyValue key_value = g_array_index (msg->hdr_fields, RTSPKeyValue, i); |
605 RTSPKeyValue *key_value = &g_array_index (msg->hdr_fields, RTSPKeyValue, i); |
579 |
606 |
580 if (key_value.field == field && cnt++ == indx) { |
607 if (key_value->field == field && cnt++ == indx) { |
581 if (value) |
608 if (value) |
582 *value = key_value.value; |
609 *value = key_value->value; |
583 return GST_RTSP_OK; |
610 return GST_RTSP_OK; |
584 } |
611 } |
585 } |
612 } |
586 |
613 |
587 return GST_RTSP_ENOTIMPL; |
614 return GST_RTSP_ENOTIMPL; |
604 |
631 |
605 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
632 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
606 g_return_val_if_fail (str != NULL, GST_RTSP_EINVAL); |
633 g_return_val_if_fail (str != NULL, GST_RTSP_EINVAL); |
607 |
634 |
608 for (i = 0; i < msg->hdr_fields->len; i++) { |
635 for (i = 0; i < msg->hdr_fields->len; i++) { |
609 RTSPKeyValue key_value = g_array_index (msg->hdr_fields, RTSPKeyValue, i); |
636 RTSPKeyValue *key_value; |
610 const gchar *keystr = gst_rtsp_header_as_text (key_value.field); |
637 const gchar *keystr; |
611 |
638 |
612 g_string_append_printf (str, "%s: %s\r\n", keystr, key_value.value); |
639 key_value = &g_array_index (msg->hdr_fields, RTSPKeyValue, i); |
|
640 keystr = gst_rtsp_header_as_text (key_value->field); |
|
641 |
|
642 g_string_append_printf (str, "%s: %s\r\n", keystr, key_value->value); |
613 } |
643 } |
614 return GST_RTSP_OK; |
644 return GST_RTSP_OK; |
615 } |
645 } |
616 |
646 |
617 /** |
647 /** |
710 |
740 |
711 return GST_RTSP_OK; |
741 return GST_RTSP_OK; |
712 } |
742 } |
713 |
743 |
714 static void |
744 static void |
715 dump_mem (guint8 * mem, guint size) |
745 dump_key_value (gpointer data, gpointer user_data G_GNUC_UNUSED) |
716 { |
|
717 guint i, j; |
|
718 GString *string = g_string_sized_new (50); |
|
719 GString *chars = g_string_sized_new (18); |
|
720 |
|
721 i = j = 0; |
|
722 while (i < size) { |
|
723 if (g_ascii_isprint (mem[i])) |
|
724 g_string_append_printf (chars, "%c", mem[i]); |
|
725 else |
|
726 g_string_append_printf (chars, "."); |
|
727 |
|
728 g_string_append_printf (string, "%02x ", mem[i]); |
|
729 |
|
730 j++; |
|
731 i++; |
|
732 |
|
733 if (j == 16 || i == size) { |
|
734 g_print ("%08x (%p): %-48.48s %-16.16s\n", i - j, mem + i - j, |
|
735 string->str, chars->str); |
|
736 g_string_set_size (string, 0); |
|
737 g_string_set_size (chars, 0); |
|
738 j = 0; |
|
739 } |
|
740 } |
|
741 g_string_free (string, TRUE); |
|
742 g_string_free (chars, TRUE); |
|
743 } |
|
744 |
|
745 static void |
|
746 dump_key_value (gpointer data, gpointer user_data) |
|
747 { |
746 { |
748 RTSPKeyValue *key_value = (RTSPKeyValue *) data; |
747 RTSPKeyValue *key_value = (RTSPKeyValue *) data; |
749 |
748 |
750 g_print (" key: '%s', value: '%s'\n", |
749 g_print (" key: '%s', value: '%s'\n", |
751 gst_rtsp_header_as_text (key_value->field), key_value->value); |
750 gst_rtsp_header_as_text (key_value->field), key_value->value); |
778 gst_rtsp_version_as_text (msg->type_data.request.version)); |
777 gst_rtsp_version_as_text (msg->type_data.request.version)); |
779 g_print (" headers:\n"); |
778 g_print (" headers:\n"); |
780 key_value_foreach (msg->hdr_fields, dump_key_value, NULL); |
779 key_value_foreach (msg->hdr_fields, dump_key_value, NULL); |
781 g_print (" body:\n"); |
780 g_print (" body:\n"); |
782 gst_rtsp_message_get_body (msg, &data, &size); |
781 gst_rtsp_message_get_body (msg, &data, &size); |
783 dump_mem (data, size); |
782 gst_util_dump_mem (data, size); |
784 break; |
783 break; |
785 case GST_RTSP_MESSAGE_RESPONSE: |
784 case GST_RTSP_MESSAGE_RESPONSE: |
786 g_print ("RTSP response message %p\n", msg); |
785 g_print ("RTSP response message %p\n", msg); |
787 g_print (" status line:\n"); |
786 g_print (" status line:\n"); |
788 g_print (" code: '%d'\n", msg->type_data.response.code); |
787 g_print (" code: '%d'\n", msg->type_data.response.code); |
791 gst_rtsp_version_as_text (msg->type_data.response.version)); |
790 gst_rtsp_version_as_text (msg->type_data.response.version)); |
792 g_print (" headers:\n"); |
791 g_print (" headers:\n"); |
793 key_value_foreach (msg->hdr_fields, dump_key_value, NULL); |
792 key_value_foreach (msg->hdr_fields, dump_key_value, NULL); |
794 gst_rtsp_message_get_body (msg, &data, &size); |
793 gst_rtsp_message_get_body (msg, &data, &size); |
795 g_print (" body: length %d\n", size); |
794 g_print (" body: length %d\n", size); |
796 dump_mem (data, size); |
795 gst_util_dump_mem (data, size); |
797 break; |
796 break; |
798 case GST_RTSP_MESSAGE_DATA: |
797 case GST_RTSP_MESSAGE_DATA: |
799 g_print ("RTSP data message %p\n", msg); |
798 g_print ("RTSP data message %p\n", msg); |
800 g_print (" channel: '%d'\n", msg->type_data.data.channel); |
799 g_print (" channel: '%d'\n", msg->type_data.data.channel); |
801 g_print (" size: '%d'\n", msg->body_size); |
800 g_print (" size: '%d'\n", msg->body_size); |
802 gst_rtsp_message_get_body (msg, &data, &size); |
801 gst_rtsp_message_get_body (msg, &data, &size); |
803 dump_mem (data, size); |
802 gst_util_dump_mem (data, size); |
804 break; |
803 break; |
805 default: |
804 default: |
806 g_print ("unsupported message type %d\n", msg->type); |
805 g_print ("unsupported message type %d\n", msg->type); |
807 return GST_RTSP_EINVAL; |
806 return GST_RTSP_EINVAL; |
808 } |
807 } |