You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
2.9KB

  1. /*
  2. C->S:
  3. TEARDOWN rtsp://example.com/fizzle/foo RTSP/1.0
  4. CSeq: 892
  5. Session: 12345678
  6. S->C:
  7. RTSP/1.0 200 OK
  8. CSeq: 892
  9. */
  10. #include "rtsp-client-internal.h"
  11. static const char* sc_format =
  12. "TEARDOWN %s RTSP/1.0\r\n"
  13. "CSeq: %u\r\n"
  14. "Session: %s\r\n"
  15. "%s" // Authorization: Digest xxx
  16. "User-Agent: %s\r\n"
  17. "\r\n";
  18. static int rtsp_client_media_teardown(struct rtsp_client_t* rtsp, int i)
  19. {
  20. int r;
  21. assert(i < rtsp->media_count);
  22. assert(RTSP_TEARDWON == rtsp->state);
  23. if (i >= rtsp->media_count) return -1;
  24. assert(rtsp->media[i].uri[0] && rtsp->session[i].session[0]);
  25. r = rtsp_client_authenrization(rtsp, "TEARDOWN", rtsp->media[i].uri, NULL, 0, rtsp->authenrization, sizeof(rtsp->authenrization));
  26. r = snprintf(rtsp->req, sizeof(rtsp->req), sc_format, rtsp->media[i].uri, rtsp->cseq++, rtsp->session[i].session, rtsp->authenrization, USER_AGENT);
  27. return (r > 0 && r < sizeof(rtsp->req) && r == rtsp->handler.send(rtsp->param, rtsp->media[i].uri, rtsp->req, r)) ? 0 : -1;
  28. }
  29. int rtsp_client_teardown(struct rtsp_client_t* rtsp)
  30. {
  31. int r;
  32. rtsp->state = RTSP_TEARDWON;
  33. rtsp->progress = 0;
  34. if (rtsp->aggregate)
  35. {
  36. assert(rtsp->media_count > 0);
  37. assert(rtsp->aggregate_uri[0]);
  38. r = rtsp_client_authenrization(rtsp, "TEARDOWN", rtsp->aggregate_uri, NULL, 0, rtsp->authenrization, sizeof(rtsp->authenrization));
  39. r = snprintf(rtsp->req, sizeof(rtsp->req), sc_format, rtsp->aggregate_uri, rtsp->cseq++, rtsp->session[0].session, rtsp->authenrization, USER_AGENT);
  40. return (r > 0 && r < sizeof(rtsp->req) && r == rtsp->handler.send(rtsp->param, rtsp->aggregate_uri, rtsp->req, r)) ? 0 : -1;
  41. }
  42. else
  43. {
  44. return rtsp_client_media_teardown(rtsp, rtsp->progress);
  45. }
  46. }
  47. static int rtsp_client_media_teardown_onreply(struct rtsp_client_t* rtsp, void* parser)
  48. {
  49. int code;
  50. assert(RTSP_TEARDWON == rtsp->state);
  51. assert(rtsp->progress <= rtsp->media_count);
  52. code = http_get_status_code(parser);
  53. if (200 != code)
  54. return -1;
  55. if (rtsp->media_count == ++rtsp->progress)
  56. {
  57. return rtsp->handler.onteardown(rtsp->param);
  58. }
  59. else
  60. {
  61. // teardown next media
  62. return rtsp_client_media_teardown(rtsp, rtsp->progress);
  63. }
  64. }
  65. // aggregate control reply
  66. static int rtsp_client_aggregate_teardown_onreply(struct rtsp_client_t* rtsp, void* parser)
  67. {
  68. int code;
  69. assert(RTSP_TEARDWON == rtsp->state);
  70. assert(0 == rtsp->progress);
  71. assert(rtsp->aggregate);
  72. code = http_get_status_code(parser);
  73. if (459 == code) // 459 Aggregate operation not allowed (p26)
  74. {
  75. rtsp->aggregate = 0;
  76. return rtsp_client_media_teardown(rtsp, rtsp->progress);
  77. }
  78. else if (200 == code)
  79. {
  80. return rtsp->handler.onteardown(rtsp->param);
  81. }
  82. else
  83. {
  84. return -1;
  85. }
  86. }
  87. int rtsp_client_teardown_onreply(struct rtsp_client_t* rtsp, void* parser)
  88. {
  89. assert(RTSP_TEARDWON == rtsp->state);
  90. assert(rtsp->progress < rtsp->media_count);
  91. if (rtsp->aggregate)
  92. return rtsp_client_aggregate_teardown_onreply(rtsp, parser);
  93. else
  94. return rtsp_client_media_teardown_onreply(rtsp, parser);
  95. }