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.

94 lines
2.6KB

  1. /*
  2. C->S:
  3. DESCRIBE rtsp://server.example.com/fizzle/foo RTSP/1.0
  4. CSeq: 312
  5. Accept: application/sdp, application/rtsl, application/mheg
  6. S->C:
  7. RTSP/1.0 200 OK
  8. CSeq: 312
  9. Date: 23 Jan 1997 15:35:06 GMT
  10. Content-Type: application/sdp
  11. Content-Length: 376
  12. v=0
  13. o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4
  14. s=SDP Seminar
  15. i=A Seminar on the session description protocol
  16. u=http://www.cs.ucl.ac.uk/staff/M.Handley/sdp.03.ps
  17. e=mjh@isi.edu (Mark Handley)
  18. c=IN IP4 224.2.17.12/127
  19. t=2873397496 2873404696
  20. a=recvonly
  21. m=audio 3456 RTP/AVP 0
  22. m=video 2232 RTP/AVP 31
  23. m=whiteboard 32416 UDP WB
  24. a=orient:portrait
  25. */
  26. #include "rtsp-client-internal.h"
  27. static const char* sc_format =
  28. "DESCRIBE %s RTSP/1.0\r\n"
  29. "CSeq: %u\r\n"
  30. "%s" // Authorization: Digest xxx
  31. "Accept: application/sdp\r\n"
  32. "User-Agent: %s\r\n"
  33. "\r\n";
  34. int rtsp_client_describe(struct rtsp_client_t* rtsp)
  35. {
  36. int r;
  37. rtsp->progress = 0;
  38. rtsp->state = RTSP_DESCRIBE;
  39. r = rtsp_client_authenrization(rtsp, "DESCRIBE", rtsp->uri, NULL, 0, rtsp->authenrization, sizeof(rtsp->authenrization));
  40. r = snprintf(rtsp->req, sizeof(rtsp->req), sc_format, rtsp->uri, rtsp->cseq++, rtsp->authenrization, USER_AGENT);
  41. assert(r > 0 && r < sizeof(rtsp->req));
  42. return r == rtsp->handler.send(rtsp->param, rtsp->uri, rtsp->req, r) ? 0 : -1;
  43. }
  44. int rtsp_client_describe_onreply(struct rtsp_client_t* rtsp, void* parser)
  45. {
  46. int code, r;
  47. assert(0 == rtsp->progress);
  48. assert(RTSP_DESCRIBE == rtsp->state);
  49. r = -1;
  50. code = http_get_status_code(parser);
  51. if (200 == code)
  52. {
  53. const void* content;
  54. const char* contentType;
  55. const char* contentBase;
  56. const char* contentLocation;
  57. content = http_get_content(parser);
  58. contentType = http_get_header_by_name(parser, "Content-Type");
  59. contentBase = http_get_header_by_name(parser, "Content-Base");
  60. contentLocation = http_get_header_by_name(parser, "Content-Location");
  61. if ((contentBase && snprintf(rtsp->baseuri, sizeof(rtsp->baseuri), "%s", contentBase) >= sizeof(rtsp->baseuri))
  62. || (contentLocation && snprintf(rtsp->location, sizeof(rtsp->location), "%s", contentLocation) >= sizeof(rtsp->location)))
  63. return -1;
  64. rtsp->auth_failed = 0;
  65. if (!contentType || 0 == strcasecmp("application/sdp", contentType))
  66. {
  67. r = rtsp->handler.ondescribe(rtsp->param, (const char*)content, (int)http_get_content_length(parser));
  68. }
  69. }
  70. else if (401 == code)
  71. {
  72. // Unauthorized
  73. const char* authenticate;
  74. authenticate = http_get_header_by_name(parser, "WWW-Authenticate");
  75. if (authenticate && 0 == rtsp->auth_failed++)
  76. {
  77. rtsp_client_www_authenticate(rtsp, authenticate);
  78. r = rtsp_client_describe(rtsp);
  79. }
  80. }
  81. return r;
  82. }