80 |
79 |
81 /** |
80 /** |
82 * gst_rtsp_message_new: |
81 * gst_rtsp_message_new: |
83 * @msg: a location for the new #GstRTSPMessage |
82 * @msg: a location for the new #GstRTSPMessage |
84 * |
83 * |
85 * Create a new initialized #GstRTSPMessage. Free with gst_rtsp_message_free(). |
84 * Create a new initialized #GstRTSPMessage. |
86 * |
85 * |
87 * Returns: a #GstRTSPResult. |
86 * Returns: a #GstRTSPResult. Free with gst_rtsp_message_free(). |
88 */ |
87 */ |
89 GstRTSPResult |
88 GstRTSPResult |
90 gst_rtsp_message_new (GstRTSPMessage ** msg) |
89 gst_rtsp_message_new (GstRTSPMessage ** msg) |
91 { |
90 { |
92 GstRTSPMessage *newmsg; |
91 GstRTSPMessage *newmsg; |
143 * @msg: a location for the new #GstRTSPMessage |
142 * @msg: a location for the new #GstRTSPMessage |
144 * @method: the request method to use |
143 * @method: the request method to use |
145 * @uri: the uri of the request |
144 * @uri: the uri of the request |
146 * |
145 * |
147 * Create a new #GstRTSPMessage with @method and @uri and store the result |
146 * Create a new #GstRTSPMessage with @method and @uri and store the result |
148 * request message in @msg. Free with gst_rtsp_message_free(). |
147 * request message in @msg. |
149 * |
148 * |
150 * Returns: a #GstRTSPResult. |
149 * Returns: a #GstRTSPResult. Free with gst_rtsp_message_free(). |
151 */ |
150 */ |
152 GstRTSPResult |
151 GstRTSPResult |
153 gst_rtsp_message_new_request (GstRTSPMessage ** msg, GstRTSPMethod method, |
152 gst_rtsp_message_new_request (GstRTSPMessage ** msg, GstRTSPMethod method, |
154 const gchar * uri) |
153 const gchar * uri) |
155 { |
154 { |
212 GstRTSPResult |
211 GstRTSPResult |
213 gst_rtsp_message_parse_request (GstRTSPMessage * msg, |
212 gst_rtsp_message_parse_request (GstRTSPMessage * msg, |
214 GstRTSPMethod * method, const gchar ** uri, GstRTSPVersion * version) |
213 GstRTSPMethod * method, const gchar ** uri, GstRTSPVersion * version) |
215 { |
214 { |
216 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
215 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
217 g_return_val_if_fail (msg->type == GST_RTSP_MESSAGE_REQUEST, GST_RTSP_EINVAL); |
216 g_return_val_if_fail (msg->type != GST_RTSP_MESSAGE_REQUEST, GST_RTSP_EINVAL); |
218 |
217 |
219 if (method) |
218 if (method) |
220 *method = msg->type_data.request.method; |
219 *method = msg->type_data.request.method; |
221 if (uri) |
220 if (uri) |
222 *uri = msg->type_data.request.uri; |
221 *uri = msg->type_data.request.uri; |
232 * @code: the status code |
231 * @code: the status code |
233 * @reason: the status reason or #NULL |
232 * @reason: the status reason or #NULL |
234 * @request: the request that triggered the response or #NULL |
233 * @request: the request that triggered the response or #NULL |
235 * |
234 * |
236 * Create a new response #GstRTSPMessage with @code and @reason and store the |
235 * Create a new response #GstRTSPMessage with @code and @reason and store the |
237 * result message in @msg. Free with gst_rtsp_message_free(). |
236 * result message in @msg. |
238 * |
237 * |
239 * When @reason is #NULL, the default reason for @code will be used. |
238 * When @reason is #NULL, the default reason for @code will be used. |
240 * |
239 * |
241 * When @request is not #NULL, the relevant headers will be copied to the new |
240 * When @request is not #NULL, the relevant headers will be copied to the new |
242 * response message. |
241 * response message. |
243 * |
242 * |
244 * Returns: a #GstRTSPResult. |
243 * Returns: a #GstRTSPResult. Free with gst_rtsp_message_free(). |
245 */ |
244 */ |
246 GstRTSPResult |
245 GstRTSPResult |
247 gst_rtsp_message_new_response (GstRTSPMessage ** msg, GstRTSPStatusCode code, |
246 gst_rtsp_message_new_response (GstRTSPMessage ** msg, GstRTSPStatusCode code, |
248 const gchar * reason, const GstRTSPMessage * request) |
247 const gchar * reason, const GstRTSPMessage * request) |
249 { |
248 { |
308 header = g_strdup (header); |
307 header = g_strdup (header); |
309 if ((pos = strchr (header, ';'))) { |
308 if ((pos = strchr (header, ';'))) { |
310 *pos = '\0'; |
309 *pos = '\0'; |
311 } |
310 } |
312 g_strchomp (header); |
311 g_strchomp (header); |
313 gst_rtsp_message_take_header (msg, GST_RTSP_HDR_SESSION, header); |
312 gst_rtsp_message_add_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. Free with gst_rtsp_message_free(). |
362 * result message in @msg. |
363 * |
363 * |
364 * Returns: a #GstRTSPResult. |
364 * Returns: a #GstRTSPResult. Free with gst_rtsp_message_free(). |
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 contents of @msg so that it becomes an uninitialized |
427 * Unset the concents 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_take_header: |
494 * gst_rtsp_message_add_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. This function takes |
499 * Add a header with key @field and @value to @msg. |
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. |
|
531 * |
500 * |
532 * Returns: a #GstRTSPResult. |
501 * Returns: a #GstRTSPResult. |
533 */ |
502 */ |
534 GstRTSPResult |
503 GstRTSPResult |
535 gst_rtsp_message_add_header (GstRTSPMessage * msg, GstRTSPHeaderField field, |
504 gst_rtsp_message_add_header (GstRTSPMessage * msg, GstRTSPHeaderField field, |
536 const gchar * value) |
505 const gchar * value) |
537 { |
506 { |
538 return gst_rtsp_message_take_header (msg, field, g_strdup (value)); |
507 RTSPKeyValue key_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; |
539 } |
518 } |
540 |
519 |
541 /** |
520 /** |
542 * gst_rtsp_message_remove_header: |
521 * gst_rtsp_message_remove_header: |
543 * @msg: a #GstRTSPMessage |
522 * @msg: a #GstRTSPMessage |
558 gint cnt = 0; |
537 gint cnt = 0; |
559 |
538 |
560 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
539 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
561 |
540 |
562 while (i < msg->hdr_fields->len) { |
541 while (i < msg->hdr_fields->len) { |
563 RTSPKeyValue *key_value = &g_array_index (msg->hdr_fields, RTSPKeyValue, i); |
542 RTSPKeyValue key_value = g_array_index (msg->hdr_fields, RTSPKeyValue, i); |
564 |
543 |
565 if (key_value->field == field && (indx == -1 || cnt++ == indx)) { |
544 if (key_value.field == field && (indx == -1 || cnt++ == indx)) { |
566 g_free (key_value->value); |
|
567 g_array_remove_index (msg->hdr_fields, i); |
545 g_array_remove_index (msg->hdr_fields, i); |
568 res = GST_RTSP_OK; |
546 res = GST_RTSP_OK; |
569 if (indx != -1) |
547 if (indx != -1) |
570 break; |
548 break; |
571 } else { |
549 } else { |
580 * @msg: a #GstRTSPMessage |
558 * @msg: a #GstRTSPMessage |
581 * @field: a #GstRTSPHeaderField |
559 * @field: a #GstRTSPHeaderField |
582 * @value: pointer to hold the result |
560 * @value: pointer to hold the result |
583 * @indx: the index of the header |
561 * @indx: the index of the header |
584 * |
562 * |
585 * Get the @indx header value with key @field from @msg. The result in @value |
563 * Get the @indx header value with key @field from @msg. |
586 * stays valid as long as it remains present in @msg. |
|
587 * |
564 * |
588 * Returns: #GST_RTSP_OK when @field was found, #GST_RTSP_ENOTIMPL if the key |
565 * Returns: #GST_RTSP_OK when @field was found, #GST_RTSP_ENOTIMPL if the key |
589 * was not found. |
566 * was not found. |
590 */ |
567 */ |
591 GstRTSPResult |
568 GstRTSPResult |
595 guint i; |
572 guint i; |
596 gint cnt = 0; |
573 gint cnt = 0; |
597 |
574 |
598 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
575 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
599 |
576 |
600 /* no header initialized, there are no headers */ |
|
601 if (msg->hdr_fields == NULL) |
|
602 return GST_RTSP_ENOTIMPL; |
|
603 |
|
604 for (i = 0; i < msg->hdr_fields->len; i++) { |
577 for (i = 0; i < msg->hdr_fields->len; i++) { |
605 RTSPKeyValue *key_value = &g_array_index (msg->hdr_fields, RTSPKeyValue, i); |
578 RTSPKeyValue key_value = g_array_index (msg->hdr_fields, RTSPKeyValue, i); |
606 |
579 |
607 if (key_value->field == field && cnt++ == indx) { |
580 if (key_value.field == field && cnt++ == indx) { |
608 if (value) |
581 if (value) |
609 *value = key_value->value; |
582 *value = key_value.value; |
610 return GST_RTSP_OK; |
583 return GST_RTSP_OK; |
611 } |
584 } |
612 } |
585 } |
613 |
586 |
614 return GST_RTSP_ENOTIMPL; |
587 return GST_RTSP_ENOTIMPL; |
631 |
604 |
632 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
605 g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); |
633 g_return_val_if_fail (str != NULL, GST_RTSP_EINVAL); |
606 g_return_val_if_fail (str != NULL, GST_RTSP_EINVAL); |
634 |
607 |
635 for (i = 0; i < msg->hdr_fields->len; i++) { |
608 for (i = 0; i < msg->hdr_fields->len; i++) { |
636 RTSPKeyValue *key_value; |
609 RTSPKeyValue key_value = g_array_index (msg->hdr_fields, RTSPKeyValue, i); |
637 const gchar *keystr; |
610 const gchar *keystr = gst_rtsp_header_as_text (key_value.field); |
638 |
611 |
639 key_value = &g_array_index (msg->hdr_fields, RTSPKeyValue, i); |
612 g_string_append_printf (str, "%s: %s\r\n", keystr, key_value.value); |
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); |
|
643 } |
613 } |
644 return GST_RTSP_OK; |
614 return GST_RTSP_OK; |
645 } |
615 } |
646 |
616 |
647 /** |
617 /** |
740 |
710 |
741 return GST_RTSP_OK; |
711 return GST_RTSP_OK; |
742 } |
712 } |
743 |
713 |
744 static void |
714 static void |
745 dump_key_value (gpointer data, gpointer user_data G_GNUC_UNUSED) |
715 dump_mem (guint8 * mem, guint size) |
|
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) |
746 { |
747 { |
747 RTSPKeyValue *key_value = (RTSPKeyValue *) data; |
748 RTSPKeyValue *key_value = (RTSPKeyValue *) data; |
748 |
749 |
749 g_print (" key: '%s', value: '%s'\n", |
750 g_print (" key: '%s', value: '%s'\n", |
750 gst_rtsp_header_as_text (key_value->field), key_value->value); |
751 gst_rtsp_header_as_text (key_value->field), key_value->value); |
777 gst_rtsp_version_as_text (msg->type_data.request.version)); |
778 gst_rtsp_version_as_text (msg->type_data.request.version)); |
778 g_print (" headers:\n"); |
779 g_print (" headers:\n"); |
779 key_value_foreach (msg->hdr_fields, dump_key_value, NULL); |
780 key_value_foreach (msg->hdr_fields, dump_key_value, NULL); |
780 g_print (" body:\n"); |
781 g_print (" body:\n"); |
781 gst_rtsp_message_get_body (msg, &data, &size); |
782 gst_rtsp_message_get_body (msg, &data, &size); |
782 gst_util_dump_mem (data, size); |
783 dump_mem (data, size); |
783 break; |
784 break; |
784 case GST_RTSP_MESSAGE_RESPONSE: |
785 case GST_RTSP_MESSAGE_RESPONSE: |
785 g_print ("RTSP response message %p\n", msg); |
786 g_print ("RTSP response message %p\n", msg); |
786 g_print (" status line:\n"); |
787 g_print (" status line:\n"); |
787 g_print (" code: '%d'\n", msg->type_data.response.code); |
788 g_print (" code: '%d'\n", msg->type_data.response.code); |
790 gst_rtsp_version_as_text (msg->type_data.response.version)); |
791 gst_rtsp_version_as_text (msg->type_data.response.version)); |
791 g_print (" headers:\n"); |
792 g_print (" headers:\n"); |
792 key_value_foreach (msg->hdr_fields, dump_key_value, NULL); |
793 key_value_foreach (msg->hdr_fields, dump_key_value, NULL); |
793 gst_rtsp_message_get_body (msg, &data, &size); |
794 gst_rtsp_message_get_body (msg, &data, &size); |
794 g_print (" body: length %d\n", size); |
795 g_print (" body: length %d\n", size); |
795 gst_util_dump_mem (data, size); |
796 dump_mem (data, size); |
796 break; |
797 break; |
797 case GST_RTSP_MESSAGE_DATA: |
798 case GST_RTSP_MESSAGE_DATA: |
798 g_print ("RTSP data message %p\n", msg); |
799 g_print ("RTSP data message %p\n", msg); |
799 g_print (" channel: '%d'\n", msg->type_data.data.channel); |
800 g_print (" channel: '%d'\n", msg->type_data.data.channel); |
800 g_print (" size: '%d'\n", msg->body_size); |
801 g_print (" size: '%d'\n", msg->body_size); |
801 gst_rtsp_message_get_body (msg, &data, &size); |
802 gst_rtsp_message_get_body (msg, &data, &size); |
802 gst_util_dump_mem (data, size); |
803 dump_mem (data, size); |
803 break; |
804 break; |
804 default: |
805 default: |
805 g_print ("unsupported message type %d\n", msg->type); |
806 g_print ("unsupported message type %d\n", msg->type); |
806 return GST_RTSP_EINVAL; |
807 return GST_RTSP_EINVAL; |
807 } |
808 } |