Revision 3af4c8d7 src/janus_instance.c

View differences:

src/janus_instance.c
24 24
#include<unistd.h>
25 25
#include<tokens.h>
26 26
#include<grapes_config.h>
27
#include <sys/prctl.h>  // for process sync
27 28

  
28 29
#define INVALID_PID -1
29 30

  
30 31
#define JANUS_MSG_SESSION_CREATE "{\"transaction\": \"random\", \"janus\": \"create\"}"
31 32
#define JANUS_MSG_SESSION_KEEPALIVE "{\"transaction\": \"ciao\", \"janus\": \"keepalive\"}"
32
#define JANUS_MSG_PLUGIN_CREATE "{\"transaction\": \"ciao\", \"janus\": \"attach\", \"plugin\":\"janus.plugin.streaming\"}"
33
#define JANUS_MSG_STREAMING_PLUGIN_CREATE "{\"transaction\": \"ciao\", \"janus\": \"attach\", \"plugin\":\"janus.plugin.streaming\"}"
34
#define JANUS_MSG_VIDEOROOM_PLUGIN_CREATE "{\"transaction\": \"ciao\", \"janus\": \"attach\", \"plugin\":\"janus.plugin.videoroom\"}"
33 35

  
34 36

  
35 37
struct janus_instance {
......
41 43
	struct mg_mgr *mongoose_srv;
42 44
	struct periodic_task * heartbeat;
43 45
	uint64_t management_session;
44
	uint64_t plugin_handle;
46
	uint64_t streaming_plugin_handle;
47
	uint64_t videoroom_plugin_handle;
45 48
	struct task_manager * tm;
46 49
};
47 50

  
......
63 66
	return res;
64 67
}
65 68

  
66
char * janus_instance_handle_path(const struct janus_instance * janus)
69
char * janus_instance_streaming_handle_path(const struct janus_instance * janus)
67 70
{
68 71
	char * res = NULL;
69
	if (janus && janus->management_session && janus->plugin_handle && janus->endpoint)
72
	if (janus && janus->management_session && janus->streaming_plugin_handle && janus->endpoint)
70 73
	{
71 74
		res = malloc(sizeof(char) * (strlen(janus->endpoint) + 43));  // each identifier comprises of 20 characters at most
72
		sprintf(res, "%s/%"PRId64"/%"PRId64"", janus->endpoint, janus->management_session, janus->plugin_handle);
75
		sprintf(res, "%s/%"PRId64"/%"PRId64"", janus->endpoint, janus->management_session, janus->streaming_plugin_handle);
76
	}
77
	return res;
78
}
79

  
80
char * janus_instance_videoroom_handle_path(const struct janus_instance * janus)
81
{
82
	char * res = NULL;
83
	if (janus && janus->management_session && janus->videoroom_plugin_handle && janus->endpoint)
84
	{
85
		res = malloc(sizeof(char) * (strlen(janus->endpoint) + 43));  // each identifier comprises of 20 characters at most
86
		sprintf(res, "%s/%"PRId64"/%"PRId64"", janus->endpoint, janus->management_session, janus->videoroom_plugin_handle);
73 87
	}
74 88
	return res;
75 89
}
......
101 115
		ji->logfile = strdup(grapes_config_value_str_default(tags, "janus_logfile", "janus.log"));
102 116
		ji->janus_pid = INVALID_PID;
103 117
		ji->management_session = 0;
104
		ji->plugin_handle = 0;
118
		ji->streaming_plugin_handle = 0;
119
		ji->videoroom_plugin_handle = 0;
105 120
		ji->tm = tm;
106 121
		ji->heartbeat = NULL;
107 122
		ji->mongoose_srv = mongoose_srv;
......
155 170
	}
156 171
}
157 172

  
158
void janus_instance_plugin_handler(struct mg_connection *nc, int ev, void *ev_data)
173
void janus_instance_streaming_plugin_handler(struct mg_connection *nc, int ev, void *ev_data)
159 174
{
160 175
	struct janus_instance * janus;
161 176
	struct http_message *hm = (struct http_message *) ev_data;
......
173 188
					buff = malloc(sizeof(char) * (hm->body.len + 1));
174 189
					strncpy(buff, hm->body.p, hm->body.len);
175 190
					buff[hm->body.len] = '\0';  // make sure string terminates
176
					janus->plugin_handle = janus_instance_msg_get_id(buff);
191
					janus->streaming_plugin_handle = janus_instance_msg_get_id(buff);
177 192
					free(buff);
178
					debug("Got plugin handle!\n");
193
					debug("Got plugin streaming_handle!\n");
194
				default:
195
					debug("Janus answers: %d\n", hm->resp_code);
196
			}
197
			nc->flags |= MG_F_SEND_AND_CLOSE;
198
			break;
199
		case MG_EV_CLOSE:
200
			debug("Janus server closed connection\n");
201
			break;
202
		default:
203
			break;
204
	}
205
}
206

  
207
void janus_instance_videoroom_plugin_handler(struct mg_connection *nc, int ev, void *ev_data)
208
{
209
	struct janus_instance * janus;
210
	struct http_message *hm = (struct http_message *) ev_data;
211
	char *buff;
212

  
213
	janus = nc->user_data;
214
	switch (ev) {
215
		case MG_EV_CONNECT:
216
			if (*(int *) ev_data != 0)
217
				debug("Janus communication failure\n");
218
			break;
219
		case MG_EV_HTTP_REPLY:
220
			switch (hm->resp_code) {
221
				case 200:
222
					buff = malloc(sizeof(char) * (hm->body.len + 1));
223
					strncpy(buff, hm->body.p, hm->body.len);
224
					buff[hm->body.len] = '\0';  // make sure string terminates
225
					janus->videoroom_plugin_handle = janus_instance_msg_get_id(buff);
226
					free(buff);
227
					debug("Got plugin videoroom_handle!\n");
179 228
				default:
180 229
					debug("Janus answers: %d\n", hm->resp_code);
181 230
			}
......
210 259
					buff[hm->body.len] = '\0';  // make sure string terminates
211 260
					janus->management_session = janus_instance_msg_get_id(buff);
212 261
					free(buff);
262
					
263
					// Requesting handle for the streaming plugin
264
					buff = malloc(sizeof(char) * (strlen(janus->endpoint) + 22));
265
					sprintf(buff, "%s/%"PRId64"", janus->endpoint, janus->management_session);
266
					conn = mg_connect_http(janus->mongoose_srv, janus_instance_streaming_plugin_handler, buff, NULL, JANUS_MSG_STREAMING_PLUGIN_CREATE);
267
					free(buff);
268
					if (conn)
269
						conn->user_data = (void *) janus;
270

  
271
					// Requesting handle for the videoroom plugin
213 272
					buff = malloc(sizeof(char) * (strlen(janus->endpoint) + 22));
214 273
					sprintf(buff, "%s/%"PRId64"", janus->endpoint, janus->management_session);
215
					conn = mg_connect_http(janus->mongoose_srv, janus_instance_plugin_handler, buff, NULL, JANUS_MSG_PLUGIN_CREATE);
274
					conn = mg_connect_http(janus->mongoose_srv, janus_instance_videoroom_plugin_handler, buff, NULL, JANUS_MSG_VIDEOROOM_PLUGIN_CREATE);
216 275
					free(buff);
217 276
					if (conn)
218 277
						conn->user_data = (void *) janus;
......
273 332

  
274 333
	if (ji && ji->janus_pid == INVALID_PID)
275 334
	{
335
		info("%s - %s\n", ji->executable, ji->conf_param);
276 336
		res = stat(ji->executable, &s);
277 337
		// check exe existence
278 338
		if (res == 0 && S_ISREG(s.st_mode))
......
294 354
					dup2(fd, 2);   // make stderr go to file - you may choose to not do this
295 355
					close(fd);
296 356

  
357
					prctl(PR_SET_PDEATHSIG, SIGHUP); // makes kernel dispatch me a SIGHUP if parent dies
358

  
297 359
					argv[0] = ji->executable;
298 360
					argv[1] = ji->conf_param;
299 361
					argv[2] = NULL;
......
359 421
	}
360 422
}
361 423

  
424
void janus_instance_videoroom_creation_handler(struct mg_connection *nc, int ev, void *ev_data)
425
{
426
	struct http_message *hm = (struct http_message *) ev_data;
427
	void ** data;
428
	struct streamer_creation_callback * scc;
429

  
430
	data = nc->user_data;
431
	scc = data[0];
432
	switch (ev) {
433
		case MG_EV_CONNECT:
434
			if (*(int *) ev_data != 0)
435
				debug("Janus communication failure\n");
436
			break;
437
		case MG_EV_HTTP_REPLY:
438
			switch (hm->resp_code) {
439
				case 200:
440
					info("Room created\n");
441
				default:
442
					debug("Janus answers: %d\n", hm->resp_code);
443
			}
444
			nc->flags |= MG_F_SEND_AND_CLOSE;
445
			break;
446
		case MG_EV_CLOSE:
447
			debug("Janus server closed connection\n");
448
			if (scc)
449
			{
450
				debug("Janus instance calls creation trigger\n");
451
				streamer_creation_callback_trigger(scc, 0);
452
				streamer_creation_callback_destroy(&scc);
453
				free(data);
454
			}
455
			break;
456
		default:
457
			break;
458
	}
459
}
460

  
362 461
int8_t janus_instance_create_streaming_point(struct janus_instance const * janus, uint64_t *mp_id, uint16_t audio_port, uint16_t video_port, struct streamer_creation_callback *scc)
363 462
{
364 463
	struct mg_connection * conn;
......
372 471

  
373 472
	if (janus && mp_id && audio_port && video_port)
374 473
	{
375
		uri = janus_instance_handle_path(janus);
474
		uri = janus_instance_streaming_handle_path(janus);
376 475
		if (uri)
377 476
		{
378 477
			sprintf(buff, fmt, audio_port, video_port);
......
403 502

  
404 503
	if (janus && mp_id)
405 504
	{
406
		uri = janus_instance_handle_path(janus);
505
		uri = janus_instance_streaming_handle_path(janus);
407 506
		if (uri)
408 507
		{
409 508
			sprintf(buff, fmt, mp_id);
......
418 517
	}
419 518
	return res;
420 519
}
520

  
521
int8_t janus_instance_create_videoroom(struct janus_instance const * janus, const char * room_id, struct streamer_creation_callback *scc)
522
{
523
	struct mg_connection * conn;
524
	int8_t res = -1;
525
	char * uri;
526
	char * fmt = "{\"transaction\":\"random_str\",\"janus\":\"message\",\"body\":{\"request\":\"create\",\"room\":%s}}";
527

  
528
	char buff[280];
529
	void ** data;
530

  
531
	if (janus && room_id)
532
	{
533
		uri = janus_instance_videoroom_handle_path(janus);
534
		if (uri)
535
		{
536
			sprintf(buff, fmt, room_id);
537
		   debug("Conctating Janus to create a new video room\n");	
538
			conn = mg_connect_http(janus->mongoose_srv, janus_instance_videoroom_creation_handler, uri, NULL, buff);
539
			if (conn)
540
			{
541
				data = malloc(sizeof(void *));
542
				data[0] = scc;
543
				conn->user_data = data;
544
				res = 0;
545
			} else
546
			   debug("Aaargh, no connection!\n");	
547
			free(uri);
548
		}
549
	}
550
	return res;
551
}
552

  
553
int8_t janus_instance_destroy_videoroom(struct janus_instance const * janus, const char * room_id)
554
{
555
	struct mg_connection * conn;
556
	int8_t res = -1;
557
	char * uri;
558
	char * fmt = "{\"transaction\":\"random_str\",\"janus\":\"message\",\"body\":{\"request\":\"destroy\",\"room\": %s}}";
559
	char buff[120];
560

  
561
	if (janus && room_id)
562
	{
563
		uri = janus_instance_videoroom_handle_path(janus);
564
		if (uri)
565
		{
566
			sprintf(buff, fmt, room_id);
567
			conn = mg_connect_http(janus->mongoose_srv, janus_instance_generic_handler, uri, NULL, buff);
568
			if (conn)
569
			{
570
				conn->user_data = (void *) room_id;
571
				res = 0;
572
			} 
573
			free(uri);
574
		}
575
	}
576
	return res;
577
}
578

  
579
int8_t janus_instance_forward_rtp(struct janus_instance const * janus, const char * room_id, uint64_t participant_id, const char * rtp_dest, uint16_t audio_port, uint16_t video_port)
580
{
581
	struct mg_connection * conn;
582
	int8_t res = -1;
583
	char * uri;
584
	char * fmt = "{\"transaction\":\"random_str\",\"janus\":\"message\",\"body\":{\"request\":\"rtp_forward\",\"room\":%s,\"publisher_id\":%"PRId64", \"host\": %s,\"audio_port\":%"PRId16",\"video_port\":%"PRId16",\"audio_pt\":111,\"video_pt\":98}}";
585

  
586
	char buff[280];
587

  
588
	if (janus && room_id && rtp_dest && audio_port > 0 && video_port > 0)
589
	{
590
		uri = janus_instance_videoroom_handle_path(janus);
591
		if (uri)
592
		{
593
			sprintf(buff, fmt, room_id, participant_id, rtp_dest, audio_port, video_port);
594
		   debug("Conctating Janus to create a new video room\n");	
595
			conn = mg_connect_http(janus->mongoose_srv, janus_instance_generic_handler, uri, NULL, buff);
596
			if (conn)
597
				res = 0;
598
			else
599
			   debug("Aaargh, no connection!\n");	
600
			free(uri);
601
		}
602
	}
603
	return res;
604
}

Also available in: Unified diff