/** * gst_rtsp_message_init_response: * @msg: a #GstRTSPMessage * @code: the status code * @reason: (transfer none) (allow-none): the status reason or %NULL * @request: (transfer none) (allow-none): the request that triggered the response or %NULL * * Initialize @msg with @code and @reason. * * When @reason is #NULL, the default reason for @code will be used. * * When @request is not #NULL, the relevant headers will be copied to the new * response message. * * Returns: a #GstRTSPResult. */ GstRTSPResult gst_rtsp_message_init_response (GstRTSPMessage * msg, GstRTSPStatusCode code, const gchar * reason, const GstRTSPMessage * request) { g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL); gst_rtsp_message_unset (msg); if (reason == NULL) reason = gst_rtsp_status_as_text (code); msg->type = GST_RTSP_MESSAGE_RESPONSE; msg->type_data.response.code = code; msg->type_data.response.reason = g_strdup (reason); msg->type_data.response.version = GST_RTSP_VERSION_1_0; msg->hdr_fields = g_array_new (FALSE, FALSE, sizeof (RTSPKeyValue)); if (request) { if (request->type == GST_RTSP_MESSAGE_HTTP_REQUEST) { msg->type = GST_RTSP_MESSAGE_HTTP_RESPONSE; if (request->type_data.request.version != GST_RTSP_VERSION_INVALID) msg->type_data.response.version = request->type_data.request.version; else msg->type_data.response.version = GST_RTSP_VERSION_1_1; } else { gchar *header; /* copy CSEQ */ if (gst_rtsp_message_get_header (request, GST_RTSP_HDR_CSEQ, &header, 0) == GST_RTSP_OK) { gst_rtsp_message_add_header (msg, GST_RTSP_HDR_CSEQ, header); } /* copy session id */ if (gst_rtsp_message_get_header (request, GST_RTSP_HDR_SESSION, &header, 0) == GST_RTSP_OK) { char *pos; header = g_strdup (header); if ((pos = strchr (header, ';'))) { *pos = '\0'; } g_strchomp (header); gst_rtsp_message_take_header (msg, GST_RTSP_HDR_SESSION, header); } /* FIXME copy more headers? */ } } return GST_RTSP_OK; }
static gboolean test_setup_response_461 (GstRTSPClient * client, GstRTSPMessage * response, gboolean close, gpointer user_data) { GstRTSPStatusCode code; const gchar *reason; GstRTSPVersion version; gchar *str; fail_unless (expected_transport == NULL); fail_unless (gst_rtsp_message_get_type (response) == GST_RTSP_MESSAGE_RESPONSE); fail_unless (gst_rtsp_message_parse_response (response, &code, &reason, &version) == GST_RTSP_OK); fail_unless (code == GST_RTSP_STS_UNSUPPORTED_TRANSPORT); fail_unless (g_str_equal (reason, "Unsupported transport")); fail_unless (version == GST_RTSP_VERSION_1_0); fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str, 0) == GST_RTSP_OK); fail_unless (atoi (str) == cseq++); return TRUE; }
static GstRTSPResult gst_rtsp_wms_after_send (GstRTSPExtension * ext, GstRTSPMessage * req, GstRTSPMessage * resp) { GstRTSPWMS *ctx = (GstRTSPWMS *) ext; GST_DEBUG_OBJECT (ext, "after send"); switch (req->type_data.request.method) { case GST_RTSP_OPTIONS: { gchar *server = NULL; gst_rtsp_message_get_header (resp, GST_RTSP_HDR_SERVER, &server, 0); if (server && g_str_has_prefix (server, SERVER_PREFIX)) ctx->active = TRUE; else ctx->active = FALSE; break; } default: break; } return GST_RTSP_OK; }
static gint create_and_send_ANNOUNCE_message(GstRTSPsink* sink, GTimeVal *timeout, char **szSessionNumber) { GstRTSPResult res; gchar *hdr; res = create_and_send_ANNOUNCE_message2(sink, timeout, szSessionNumber); // If authentication error occured its okay, just send with authentication parameters. if (res == -ERR_UNAUTHORIZED) { // parse authentication parameters such as nonce etc. if (gst_rtsp_message_get_header(sink->responce, GST_RTSP_HDR_WWW_AUTHENTICATE, &hdr, 0) == GST_RTSP_OK) { gchar *start; if (sink->debug) g_print("HEADER: %s", hdr); /* Skip whitespace at the start of the string */ for (start = hdr; start[0] != '\0' && g_ascii_isspace(start[0]); start++); // check if we should authenticate... if (g_ascii_strncasecmp(start, "digest ", 7) == 0) g_print("Authentication required.\n"); if (sink->authentication_name == NULL) { goto beach; } gst_rtsp_connection_clear_auth_params(sink->conn); gst_rtspsrc_parse_digest_challenge(sink->conn, start + g_utf8_strlen("Digest ", 7), FALSE); /* Pass the credentials to the connection to try on the next request */ res = gst_rtsp_connection_set_auth(sink->conn, GST_RTSP_AUTH_DIGEST, sink->authentication_name, sink->authentication_pass); /* INVAL indicates an invalid username/passwd were supplied, so we'll just * ignore it and end up retrying later */ /*if (res == GST_RTSP_OK || res == GST_RTSP_EINVAL) { g_print("Attempting %s authentication", gst_rtsp_auth_method_to_string(method)); }*/ res = create_and_send_ANNOUNCE_message2(sink, &timeout, szSessionNumber); if (res == -ERR_UNAUTHORIZED) { g_print("Authentication failed, wrong user/password.\n"); } //gst_rtsp_connection_clear_auth_params(sink->conn); } } return res; beach: return ERR_UNAUTHORIZED; }
static gboolean test_option_response_200 (GstRTSPClient * client, GstRTSPMessage * response, gboolean close, gpointer user_data) { GstRTSPStatusCode code; const gchar *reason; GstRTSPVersion version; gchar *str; GstRTSPMethod methods; fail_unless (gst_rtsp_message_get_type (response) == GST_RTSP_MESSAGE_RESPONSE); fail_unless (gst_rtsp_message_parse_response (response, &code, &reason, &version) == GST_RTSP_OK); fail_unless (code == GST_RTSP_STS_OK); fail_unless (g_str_equal (reason, "OK")); fail_unless (version == GST_RTSP_VERSION_1_0); fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str, 0) == GST_RTSP_OK); fail_unless (atoi (str) == cseq++); fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_PUBLIC, &str, 0) == GST_RTSP_OK); methods = gst_rtsp_options_from_text (str); fail_if (methods == 0); fail_unless (methods == (GST_RTSP_DESCRIBE | GST_RTSP_OPTIONS | GST_RTSP_PAUSE | GST_RTSP_PLAY | GST_RTSP_SETUP | GST_RTSP_GET_PARAMETER | GST_RTSP_SET_PARAMETER | GST_RTSP_TEARDOWN)); return TRUE; }
static GstRTSPResult gst_rtsp_wms_receive_request (GstRTSPExtension * ext, GstRTSPMessage * request) { GstRTSPWMS *ctx; GstRTSPResult res = GST_RTSP_ENOTIMPL; GstRTSPMessage response = { 0 }; ctx = (GstRTSPWMS *) ext; GST_DEBUG_OBJECT (ext, "before send"); switch (request->type_data.request.method) { case GST_RTSP_SET_PARAMETER: { gchar *content_type = NULL; gst_rtsp_message_get_header (request, GST_RTSP_HDR_CONTENT_TYPE, &content_type, 0); if (content_type && !g_ascii_strcasecmp (content_type, EXTENSION_CMD)) { /* parse the command */ /* default implementation, send OK */ res = gst_rtsp_message_init_response (&response, GST_RTSP_STS_OK, "OK", request); if (res < 0) goto send_error; GST_DEBUG_OBJECT (ctx, "replying with OK"); /* send reply */ if ((res = gst_rtsp_extension_send (ext, request, &response)) < 0) goto send_error; res = GST_RTSP_EEOF; } break; } default: break; } return res; send_error: { return res; } }
char * extractSessionNumberFromMessage(GstRTSPMessage * msg){ GstRTSPResult res = GST_RTSP_OK; GstRTSPHeaderField field = GST_RTSP_HDR_SESSION; gchar *value; gint indx = 0; gboolean bAnnounceFlag = FALSE, bRecordFlag = FALSE; while (res == GST_RTSP_OK) { res = gst_rtsp_message_get_header(msg, field, &value, indx); // if its only numbers if (isDigitsOnly(value) ) return (g_strdup(value)); indx++; } return NULL; }
int extractTransportFromMessage(GstRTSPMessage * msg, GstRTSPTransport *transport){ GstRTSPResult res = GST_RTSP_OK; GstRTSPHeaderField field = GST_RTSP_HDR_TRANSPORT; gchar *value; gint indx = 0; while (res == GST_RTSP_OK) { res = gst_rtsp_message_get_header(msg, field, &value, indx); if (res == GST_RTSP_OK) { res = gst_rtsp_transport_parse(value, transport); return GST_RTSP_OK; } indx++; } return GST_RTSP_EINVAL; }
static int isServerSupportStreamPush(GstRTSPMessage * msg){ GstRTSPResult res = GST_RTSP_OK; GstRTSPHeaderField field = GST_RTSP_HDR_PUBLIC; gchar *value; gint indx = 0; gboolean bAnnounceFlag = FALSE, bRecordFlag = FALSE; while (res == GST_RTSP_OK) { res = gst_rtsp_message_get_header(msg, field, &value, indx); if (0 == g_strcmp0(value, "RECORD")) bRecordFlag = TRUE; if (0 == g_strcmp0(value, "ANNOUNCE")) bAnnounceFlag = TRUE; indx++; } if (bAnnounceFlag != TRUE || bRecordFlag != TRUE) { return -ERR_CANNOT_PUSH_STREAM; } return GST_RTSP_OK; }
static gboolean test_setup_response_200_multicast (GstRTSPClient * client, GstRTSPMessage * response, gboolean close, gpointer user_data) { GstRTSPStatusCode code; const gchar *reason; GstRTSPVersion version; gchar *str; GstRTSPSessionPool *session_pool; GstRTSPSession *session; gchar **session_hdr_params; fail_unless (expected_transport != NULL); fail_unless (gst_rtsp_message_get_type (response) == GST_RTSP_MESSAGE_RESPONSE); fail_unless (gst_rtsp_message_parse_response (response, &code, &reason, &version) == GST_RTSP_OK); fail_unless (code == GST_RTSP_STS_OK); fail_unless (g_str_equal (reason, "OK")); fail_unless (version == GST_RTSP_VERSION_1_0); fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str, 0) == GST_RTSP_OK); fail_unless (atoi (str) == cseq++); fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_TRANSPORT, &str, 0) == GST_RTSP_OK); fail_unless (!strcmp (str, expected_transport)); fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_SESSION, &str, 0) == GST_RTSP_OK); session_hdr_params = g_strsplit (str, ";", -1); /* session-id value */ fail_unless (session_hdr_params[0] != NULL); if (expected_session_timeout != 60) { /* session timeout param */ gchar *timeout_str = g_strdup_printf ("timeout=%u", expected_session_timeout); fail_unless (session_hdr_params[1] != NULL); g_strstrip (session_hdr_params[1]); fail_unless (g_strcmp0 (session_hdr_params[1], timeout_str) == 0); g_free (timeout_str); } session_pool = gst_rtsp_client_get_session_pool (client); fail_unless (session_pool != NULL); fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 1); session = gst_rtsp_session_pool_find (session_pool, session_hdr_params[0]); g_strfreev (session_hdr_params); fail_unless (session != NULL); g_object_unref (session); g_object_unref (session_pool); return TRUE; }
static GstRTSPStatusCode nmp_rtsp_handle_response(NmpMediaDevice *device, GstRTSPMessage *response) { GstRTSPStatusCode res_code; GstRTSPVersion version; const gchar *reason = NULL; gchar *sessid = NULL, *cseq = NULL, *content_base = NULL; GstRTSPResult ret; NmpRtspMedia *media = NULL; NmpSessionState s_state; GstSDPMessage *sdp = NULL; guint8 *sdp_body = NULL; guint sdp_size, seq; gst_rtsp_message_parse_response(response, &res_code, &reason, &version); if (version != GST_RTSP_VERSION_1_0) { nmp_warning("Device RTSP response version mismatch"); return GST_RTSP_STS_RTSP_VERSION_NOT_SUPPORTED; } ret = gst_rtsp_message_get_header(response, GST_RTSP_HDR_CSEQ, &cseq, 0); if (ret != GST_RTSP_OK) { nmp_warning("Device RTSP response, No 'CSeq:' field"); return GST_RTSP_STS_INVALID; } seq = atoi(cseq); if (!seq) return GST_RTSP_OK; media = nmp_rtsp_device_get_media(device, seq); if (!media) { //TEARDOWN或者SET_PARAMETER响应 nmp_print( "Drop device response(TEARDOWN|SET_PARAMETER), seq:'%s'.", cseq ); return GST_RTSP_OK; } s_state = nmp_rtsp_media_get_session_state(media); if (s_state == NMP_SESSION_TEARDOWN) { nmp_print( "Response _After_ TEARDOWN ?? seq:'%s'", cseq ); goto handle_teardown_ok; } if (res_code != GST_RTSP_STS_OK) { nmp_warning("Device RTSP res-code: %d", res_code); goto handle_response_failed; } ret = gst_rtsp_message_get_header(response, GST_RTSP_HDR_SESSION, &sessid, 0); if (ret != GST_RTSP_OK) { //只有DESCRIBE消息没有SESSION域 if (s_state != NMP_SESSION_DESCRIBE) { nmp_warning("Device RTSP response, No 'Session:' field"); goto handle_response_failed; } ret = gst_rtsp_message_get_header(response, GST_RTSP_HDR_CONTENT_BASE, &content_base, 0); if (ret != GST_RTSP_OK) { nmp_warning("Device RTSP response, No 'Content-Base:' field"); goto handle_response_failed; } //处理DESCRIBE消息 if (gst_sdp_message_new(&sdp) != GST_SDP_OK) { nmp_warning("Create SDP message failed"); goto handle_response_failed; } gst_rtsp_message_get_body(response, &sdp_body, &sdp_size); if (gst_sdp_message_parse_buffer(sdp_body, sdp_size, sdp) != GST_SDP_OK) { nmp_warning("Device DESCRIBE response, invalid SDP info"); gst_sdp_message_free(sdp); goto handle_response_failed; } nmp_rtsp_media_set_sdp_info(media, sdp); } else { if (s_state == NMP_SESSION_SETUP) nmp_rtsp_media_set_session_id(media, sessid); } if (nmp_rtsp_media_session_state_next(media) == NMP_SESSION_PLAY) nmp_rtsp_media_deal_pending_request(media); if (nmp_rtsp_device_request(device, media)) { nmp_warning("Device RTSP Request failed"); goto handle_response_failed; } handle_teardown_ok: nmp_rtsp_media_unref(media); return GST_RTSP_OK; handle_response_failed: nmp_rtsp_media_die_announce(media, device); // nmp_rtsp_media_deal_pending_request(media); /* nmp_rtsp_media_kill_unref() can do this */ nmp_rtsp_device_remove_media(device, media); nmp_rtsp_media_kill_unref(media); return GST_RTSP_OK; }