コード例 #1
0
ファイル: ctl-sink.c プロジェクト: Happy-Ferret/miraclecast
static void sink_handle_options(struct ctl_sink *s,
				struct rtsp_message *m)
{
	_rtsp_message_unref_ struct rtsp_message *rep = NULL;
	int r;

	r = rtsp_message_new_reply_for(m, &rep, RTSP_CODE_OK, NULL);
	if (r < 0)
		return cli_vERR(r);

	r = rtsp_message_append(rep, "<s>",
				"Public",
				"org.wfa.wfd1.0, GET_PARAMETER, SET_PARAMETER");
	if (r < 0)
		return cli_vERR(r);

	rtsp_message_seal(rep);
	cli_debug("OUTGOING: %s\n", rtsp_message_get_raw(rep));

	r = rtsp_send(s->rtsp, rep);
	if (r < 0)
		return cli_vERR(r);

	rtsp_message_unref(rep);
	rep = NULL;

	r = rtsp_message_new_request(s->rtsp,
				     &rep,
				     "OPTIONS",
				     "*");
	if (r < 0)
		return cli_vERR(r);

	r = rtsp_message_append(rep, "<s>",
				"Require",
				"org.wfa.wfd1.0");
	if (r < 0)
		return cli_vERR(r);

	rtsp_message_seal(rep);
	cli_debug("OUTGOING: %s\n", rtsp_message_get_raw(rep));

	r = rtsp_call_async(s->rtsp, rep, sink_req_fn, NULL, 0, NULL);
	if (r < 0)
		return cli_vERR(r);
}
コード例 #2
0
ファイル: ctl-sink.c プロジェクト: Happy-Ferret/miraclecast
static int sink_setup_fn(struct rtsp *bus, struct rtsp_message *m, void *data)
{
	_rtsp_message_unref_ struct rtsp_message *rep = NULL;
	struct ctl_sink *s = data;
	const char *session;
	char *ns, *next;
	int r;

	cli_debug("INCOMING: %s\n", rtsp_message_get_raw(m));

	r = rtsp_message_read(m, "<s>", "Session", &session);
	if (r < 0)
		return cli_ERR(r);

	ns = strdup(session);
	if (!ns)
		return cli_ENOMEM();

	next = strchr(ns, ';');
	if (next)
		*next = '\0';

	free(s->session);
	s->session = ns;

	r = rtsp_message_new_request(s->rtsp,
				     &rep,
				     "PLAY",
				     s->url);
	if (r < 0)
		return cli_ERR(r);

	r = rtsp_message_append(rep, "<s>", "Session", s->session);
	if (r < 0)
		return cli_ERR(r);

	rtsp_message_seal(rep);
	cli_debug("OUTGOING: %s\n", rtsp_message_get_raw(rep));

	r = rtsp_call_async(s->rtsp, rep, sink_req_fn, NULL, 0, NULL);
	if (r < 0)
		return cli_ERR(r);

	return 0;
}
コード例 #3
0
ファイル: test_rtsp.c プロジェクト: Al3n/miraclecast
static struct rtsp_message *create_from_recipe(struct rtsp *bus,
					       struct recipe *rec)
{
	struct rtsp_message *m;
	void *raw;
	size_t i, rawlen;
	char t;
	int r;

	ck_assert(!!rec);

	switch (rec->type) {
	case RTSP_MESSAGE_REQUEST:
		r = rtsp_message_new_request(bus,
					     &m,
					     rec->request.method,
					     rec->request.uri);
		ck_assert_int_ge(r, 0);
		break;
	case RTSP_MESSAGE_REPLY:
		r = rtsp_message_new_reply(bus,
					   &m,
					   rec->reply.cookie ? : 1,
					   rec->reply.code,
					   rec->reply.phrase);
		ck_assert_int_ge(r, 0);
		break;
	case RTSP_MESSAGE_DATA:
		r = rtsp_message_new_data(bus,
					  &m,
					  rec->data.channel,
					  rec->data.payload,
					  rec->data.size);
		ck_assert_int_ge(r, 0);
		break;
	default:
		ck_assert(false);
		abort();
	}

	for (i = 0; rec->types && rec->types[i]; ++i) {
		t = rec->types[i];
		switch (t) {
		case RTSP_TYPE_INT32:
			r = rtsp_message_append_basic(m,
						      t,
						      rec->args[i].i32);
			break;
		case RTSP_TYPE_UINT32:
			r = rtsp_message_append_basic(m,
						      t,
						      rec->args[i].u32);
			break;
		default:
			r = rtsp_message_append_basic(m,
						      t,
						      rec->args[i].ptr);
			break;
		}

		ck_assert_int_ge(r, 0);
	}

	r = rtsp_message_set_cookie(m, 1);
	ck_assert_int_ge(r, 0);
	r = rtsp_message_seal(m);
	ck_assert_int_ge(r, 0);

	/* compare to @raw */

	raw = rtsp_message_get_raw(m);
	ck_assert(!!raw);
	rawlen = rtsp_message_get_raw_size(m);

	if (debug)
		fprintf(stderr, "---------EXPECT---------\n%s\n----------GOT-----------\n%s\n-----------END----------\n", (char*)rec->raw, (char*)raw);

	ck_assert_int_eq(rawlen, rec->rawlen ? : strlen(rec->raw));
	ck_assert(!memcmp(raw, rec->raw, rawlen));

	return m;
}
コード例 #4
0
ファイル: test_rtsp.c プロジェクト: Al3n/miraclecast
TEST_END_CASE

START_TEST(msg_new_invalid)
{
	char data[128] = { };
	struct rtsp *bus;
	struct rtsp_message *m;
	int r, fd;

	fd = dup(0);
	ck_assert_int_ge(fd, 0);
	r = rtsp_open(&bus, fd);
	ck_assert_int_ge(r, 0);

	/* request messages */

	m = TEST_INVALID_PTR;
	r = rtsp_message_new_request(NULL, &m, "method", "uri");
	ck_assert_int_lt(r, 0);
	ck_assert(m == TEST_INVALID_PTR);
	r = rtsp_message_new_request(bus, NULL, "method", "uri");
	ck_assert_int_lt(r, 0);
	ck_assert(m == TEST_INVALID_PTR);
	r = rtsp_message_new_request(bus, &m, "", "uri");
	ck_assert_int_lt(r, 0);
	ck_assert(m == TEST_INVALID_PTR);
	r = rtsp_message_new_request(bus, &m, NULL, "uri");
	ck_assert_int_lt(r, 0);
	ck_assert(m == TEST_INVALID_PTR);
	r = rtsp_message_new_request(bus, &m, "method", "");
	ck_assert_int_lt(r, 0);
	ck_assert(m == TEST_INVALID_PTR);
	r = rtsp_message_new_request(bus, &m, "method", NULL);
	ck_assert_int_lt(r, 0);
	ck_assert(m == TEST_INVALID_PTR);

	r = rtsp_message_new_request(bus, &m, "method", "uri");
	ck_assert_int_ge(r, 0);
	ck_assert(m != TEST_INVALID_PTR);
	rtsp_message_unref(m);

	/* reply-for messages */

	m = TEST_INVALID_PTR;
	r = rtsp_message_new_reply(NULL, &m, 1, 200, "OK");
	ck_assert_int_lt(r, 0);
	ck_assert(m == TEST_INVALID_PTR);
	r = rtsp_message_new_reply(bus, NULL, 1, 200, "OK");
	ck_assert_int_lt(r, 0);
	ck_assert(m == TEST_INVALID_PTR);
	r = rtsp_message_new_reply(bus, &m, 0, 200, "OK");
	ck_assert_int_lt(r, 0);
	ck_assert(m == TEST_INVALID_PTR);
	r = rtsp_message_new_reply(bus, &m, 1, RTSP_ANY_CODE, "OK");
	ck_assert_int_lt(r, 0);
	ck_assert(m == TEST_INVALID_PTR);

	r = rtsp_message_new_reply(bus, &m, 1, 200, "OK");
	ck_assert_int_ge(r, 0);
	ck_assert(m != TEST_INVALID_PTR);
	rtsp_message_unref(m);

	/* data messages */

	m = TEST_INVALID_PTR;
	r = rtsp_message_new_data(NULL, &m, 0, data, sizeof(data));
	ck_assert_int_lt(r, 0);
	ck_assert(m == TEST_INVALID_PTR);
	r = rtsp_message_new_data(bus, NULL, 0, data, sizeof(data));
	ck_assert_int_lt(r, 0);
	ck_assert(m == TEST_INVALID_PTR);
	r = rtsp_message_new_data(bus, &m, RTSP_ANY_CHANNEL, data, sizeof(data));
	ck_assert_int_lt(r, 0);
	ck_assert(m == TEST_INVALID_PTR);
	r = rtsp_message_new_data(bus, &m, 0, NULL, sizeof(data));
	ck_assert_int_lt(r, 0);
	ck_assert(m == TEST_INVALID_PTR);

	r = rtsp_message_new_data(bus, &m, 0, data, sizeof(data));
	ck_assert_int_ge(r, 0);
	ck_assert(m != TEST_INVALID_PTR);
	rtsp_message_unref(m);

	/* invalid ops */

	rtsp_message_ref(NULL);
	rtsp_message_unref(NULL);

	ck_assert_int_eq(rtsp_message_get_type(NULL), 0);
	ck_assert(!rtsp_message_get_method(NULL));
	ck_assert(!rtsp_message_get_uri(NULL));
	ck_assert_int_eq(rtsp_message_get_code(NULL), RTSP_ANY_CODE);
	ck_assert(!rtsp_message_get_phrase(NULL));
	ck_assert_int_eq(rtsp_message_get_channel(NULL), RTSP_ANY_CHANNEL);
	ck_assert(!rtsp_message_get_payload(NULL));
	ck_assert_int_eq(rtsp_message_get_payload_size(NULL), 0);

	ck_assert(!rtsp_message_is_request(NULL, NULL, NULL));
	ck_assert(!rtsp_message_is_reply(NULL, RTSP_ANY_CODE, NULL));
	ck_assert(!rtsp_message_is_data(NULL, RTSP_ANY_CHANNEL));

	ck_assert(!rtsp_message_get_bus(NULL));
	ck_assert(!rtsp_message_get_cookie(NULL));
	ck_assert(!rtsp_message_is_sealed(NULL));

	rtsp_unref(bus);
}
コード例 #5
0
ファイル: ctl-sink.c プロジェクト: Happy-Ferret/miraclecast
static void sink_handle_set_parameter(struct ctl_sink *s,
				      struct rtsp_message *m)
{
	_rtsp_message_unref_ struct rtsp_message *rep = NULL;
	const char *trigger;
	const char *url;
	char *nu;
	unsigned int cea_res, vesa_res, hh_res;
	int r;

	r = rtsp_message_new_reply_for(m, &rep, RTSP_CODE_OK, NULL);
	if (r < 0)
		return cli_vERR(r);

	rtsp_message_seal(rep);
	cli_debug("OUTGOING: %s\n", rtsp_message_get_raw(rep));

	r = rtsp_send(s->rtsp, rep);
	if (r < 0)
		return cli_vERR(r);

	rtsp_message_unref(rep);
	rep = NULL;

	/* M4 (or any other) can pass presentation URLs */
	r = rtsp_message_read(m, "{<s>}", "wfd_presentation_URL", &url);
	if (r >= 0) {
		if (!s->url || strcmp(s->url, url)) {
			nu = strdup(url);
			if (!nu)
				return cli_vENOMEM();

			free(s->url);
			s->url = nu;
			cli_debug("Got URL: %s\n", s->url);
		}
	}

	/* M4 again */
	r = rtsp_message_read(m, "{<****hhh>}", "wfd_video_formats",
							&cea_res, &vesa_res, &hh_res);
	if (r == 0) {
		r = sink_set_format(s, cea_res, vesa_res, hh_res);
		if (r)
			return cli_vERR(r);
	}

	/* M5 */
	r = rtsp_message_read(m, "{<s>}", "wfd_trigger_method", &trigger);
	if (r < 0)
		return;

	if (!strcmp(trigger, "SETUP")) {
		if (!s->url) {
			cli_error("No valid wfd_presentation_URL\n");
			return;
		}

		r = rtsp_message_new_request(s->rtsp,
					     &rep,
					     "SETUP",
					     s->url);
		if (r < 0)
			return cli_vERR(r);

		r = rtsp_message_append(rep, "<s>",
					"Transport",
					"RTP/AVP/UDP;unicast;client_port=1991");
		if (r < 0)
			return cli_vERR(r);

		rtsp_message_seal(rep);
		cli_debug("OUTGOING: %s\n", rtsp_message_get_raw(rep));

		r = rtsp_call_async(s->rtsp, rep, sink_setup_fn, s, 0, NULL);
		if (r < 0)
			return cli_vERR(r);
	}
}
コード例 #6
0
ファイル: jpf_service.c プロジェクト: dulton/nampu
static void
jpf_service_op_timer(jpf_service *ps, tp_block *tb)
{
	rtsp_message *rm = NULL;
	char url[MAX_URL_LEN];
	char ip[MAX_IP_LEN];
	RTSP_RESULT res;

	if (!ps->running)
		return;

	if (!ps->jpf_client)
	{
		if (--ps->ttl > 0)
			return;

		ps->ttl = CONNECT_INTERVAL;
		jpf_service_connect(ps);
	}

	if (!ps->jpf_client)
	{
		return;
	}

	if (rtsp_impl_ts_client_killed(ps->jpf_client))
	{
		LOG_I(
			"Mds reset connection."
		);
		client_kill_unref((client*)ps->jpf_client);
		ps->jpf_client = NULL;
		return;
	}

	if (--ps->ttl > 0)
		return;

	ps->ttl = ps->psp.ka;
	jpf_service_resolve_ip(ps->psp.ip, ip);

	snprintf(url,
		MAX_URL_LEN,
		"rtsp://%s:%d/PUID=%s/keepalive=%d/l4proto=%d",
		ip,
		ps->psp.port,
		ps->psp.puid,
		ps->psp.ka,
		ps->psp.l4_proto
	);

	res = rtsp_message_new_request(&rm, RTSP_OPTIONS, url);
	if (res != RTSP_OK || !rm)
	{
		LOG_W(
			"jpf_service_op_timer()->rtsp_message_new_request() failed."
		);
		return;
	}

	rtsp_impl_send_message((rtsp_client*)ps->jpf_client, rm);
}