/**
 * 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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;

}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
  }
}
Ejemplo n.º 7
0
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;


}
Ejemplo n.º 8
0
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;


}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
0
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;
}