Revision c039490c

View differences:

Test/pschannel_bucket_test.c
29 29
	struct pschannel_bucket * pb = NULL;
30 30
	uint8_t res;
31 31

  
32
	res = pschannel_bucket_insert(NULL, NULL, NULL, NULL, NULL);
32
	res = pschannel_bucket_insert(NULL, NULL, NULL, NULL, NULL, NULL);
33 33
	assert(res);
34 34

  
35 35
	pb = pschannel_bucket_new();
36
	res = pschannel_bucket_insert(pb, NULL, NULL, NULL, NULL);
36
	res = pschannel_bucket_insert(pb, NULL, NULL, NULL, NULL, NULL);
37 37
	assert(res);
38
	res = pschannel_bucket_insert(pb, NULL, "10.0.0.1", "8000", NULL);
38
	res = pschannel_bucket_insert(pb, NULL, "10.0.0.1", "8000", NULL, NULL);
39 39
	assert(res);
40 40

  
41
	res = pschannel_bucket_insert(pb, "channel1", "10.0.0.1", "8000", "1Mbps");
41
	res = pschannel_bucket_insert(pb, "channel1", "10.0.0.1", "8000", "1Mbps", "localhost/channel.sdp");
42 42
	assert(res == 0);
43 43

  
44 44
	pschannel_bucket_destroy(&pb);
......
57 57
	iter = pschannel_bucket_iter(pb, iter);
58 58
	assert(iter == NULL);
59 59

  
60
	pschannel_bucket_insert(pb, "channel1", "10.0.0.1", "8000", "1Mbps");
60
	pschannel_bucket_insert(pb, "channel1", "10.0.0.1", "8000", "1Mbps", "localhost/channel.sdp");
61 61
	iter = pschannel_bucket_iter(pb, iter);
62 62
	assert(iter);
63 63
	iter = pschannel_bucket_iter(pb, iter);
......
81 81
	assert(strcmp(s, "[]") == 0);
82 82
	free(s);
83 83

  
84
	pschannel_bucket_insert(pb, "channel1", "10.0.0.1", "8000", "1Mbps");
84
	pschannel_bucket_insert(pb, "channel1", "10.0.0.1", "8000", "1Mbps", "localhost/channel.sdp");
85 85
	s = pschannel_bucket_to_json(pb);
86 86
	assert(strcmp(s, "[{\"name\":\"channel1\",\"ipaddr\":\"10.0.0.1\",\"port\":\"8000\",\"quality\":\"1Mbps\"}]") == 0);
87 87
	free(s);
88 88

  
89
	pschannel_bucket_insert(pb, "channel2", "10.0.0.1", "8001", "1Mbps");
89
	pschannel_bucket_insert(pb, "channel2", "10.0.0.1", "8001", "1Mbps", "localhost/channel.sdp");
90 90
	s = pschannel_bucket_to_json(pb);
91 91
	assert(strcmp(s, "[{\"name\":\"channel1\",\"ipaddr\":\"10.0.0.1\",\"port\":\"8000\",\"quality\":\"1Mbps\"},{\"name\":\"channel2\",\"ipaddr\":\"10.0.0.1\",\"port\":\"8001\",\"quality\":\"1Mbps\"}]") == 0);
92 92
	free(s);
Test/pstreamer_manager_test.c
19 19
	pstreamer_manager_destroy(NULL);
20 20
	pstreamer_manager_destroy(&psm);
21 21

  
22
	psm = pstreamer_manager_new();
22
	psm = pstreamer_manager_new(6000);
23 23

  
24 24
	pstreamer_manager_destroy(&psm);
25 25

  
......
34 34
	ps = pstreamer_manager_create_streamer(NULL, NULL, NULL, NULL);
35 35
	assert(ps == NULL);
36 36

  
37
	psm = pstreamer_manager_new();
37
	psm = pstreamer_manager_new(6000);
38 38

  
39 39
	ps = pstreamer_manager_create_streamer(psm, NULL, NULL, NULL);
40 40
	assert(ps == NULL);
......
62 62
	json = pstreamer_to_json(NULL);
63 63
	assert(json == NULL);
64 64

  
65
	psm = pstreamer_manager_new();
65
	psm = pstreamer_manager_new(6000);
66 66
	ps = pstreamer_manager_create_streamer(psm, "10.0.0.1", "6000", "42");
67 67

  
68 68
	json = pstreamer_to_json(ps);
......
82 82
	res = pstreamer_manager_destroy_streamer(NULL, NULL);
83 83
	assert(res);
84 84

  
85
	psm = pstreamer_manager_new();
85
	psm = pstreamer_manager_new(6000);
86 86
	res = pstreamer_manager_destroy_streamer(psm, NULL);
87 87
	assert(res);
88 88

  
peerstreamer-ng.c
85 85
	load_path_handlers(c->router);
86 86
	c->tm = task_manager_new();
87 87
	c->pb = pschannel_bucket_new();
88
	c->psm = pstreamer_manager_new();
89
	pschannel_bucket_insert(c->pb, "local_channel", "127.0.0.1", "6000", "300kbps");
88
	c->psm = pstreamer_manager_new(7000);
89
	pschannel_bucket_insert(c->pb, "local_channel", "127.0.0.1", "6000", "300kbps", "127.0.0.1:3000/lchannel.sdp");
90 90

  
91 91
	c->mongoose_srv = (struct mg_mgr*) malloc(sizeof(struct mg_mgr));
92 92
	mg_mgr_init(c->mongoose_srv, c);
src/name_lengths.h
7 7
#define MAX_QUALITY_LENGTH 10  // for future use
8 8
#define PSID_LENGTH 16
9 9
#define MAX_URI_LENGTH 80
10
#define MAX_SDPFILENAME_LENGTH 255
11
#define MAX_PATH_LENGTH 255
10 12

  
11 13
#endif
src/path_handlers.c
1
/*******************************************************************
2
* PeerStreamer-ng is a P2P video streaming application exposing a ReST
3
* interface.
4
* Copyright (C) 2015 Luca Baldesi <luca.baldesi@unitn.it>
5
*
6
* This program is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU Affero General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU Affero General Public License for more details.
15
*
16
* You should have received a copy of the GNU Affero General Public License
17
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
*******************************************************************/
19

  
20
#include<stdint.h>
21
#include<pschannel.h>
22
#include<router.h>
23
#include<tokens.h>
24
#include<name_lengths.h>
25
#include<debug.h>
26
#include<pschannel.h>
27
#include<context.h>
28
#include<mongoose.h>
29
#include<sdpfile.h>
30

  
31

  
32
char * mg_uri_field(struct http_message *hm, uint8_t pos)
33
{
34
	char * uri;
35
	char ** tokens;
36
	uint32_t ntok;
37

  
38
	uri = malloc((hm->uri.len + 1) * sizeof(char));
39
	strncpy(uri, hm->uri.p, hm->uri.len);
40
	uri[hm->uri.len] = '\0';
41

  
42
	tokens = tokens_create(uri, '/', &ntok);
43
	
44
	strcpy(uri, tokens[pos]);
45
	tokens_destroy(&tokens, ntok);
46

  
47
	return uri;
48
}
49

  
50
void channel_index(struct mg_connection *nc, struct http_message *hm)
51
{
52
	char * channels;
53
	const struct context * c;
54

  
55
	c = (const struct context *) nc->user_data;
56

  
57
	debug("GET request for channels\n");
58
	channels = pschannel_bucket_to_json(c->pb);
59
	debug("\t%s\n", channels);
60

  
61
	mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
62
	mg_printf_http_chunk(nc, "%s", channels);
63
	mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
64

  
65
	free(channels);
66
}
67

  
68
void streamer_create(struct mg_connection *nc, struct http_message *hm)
69
{
70
	const struct context * c;
71
	char ipaddr[MAX_IPADDR_LENGTH];
72
	char port[MAX_PORT_LENGTH];
73
	char * id, *sdpuri;
74
	const struct pstreamer * ps;
75
	const struct pschannel * ch;
76

  
77
	c = (const struct context *) nc->user_data;
78
	mg_get_http_var(&hm->body, "ipaddr", ipaddr, MAX_IPADDR_LENGTH);
79
	mg_get_http_var(&hm->body, "port", port, MAX_PORT_LENGTH);
80

  
81
	id = mg_uri_field(hm, 1);
82

  
83
	debug("POST request for resource %s\n", id);
84
	ch = pschannel_bucket_find(c->pb, ipaddr, port);
85

  
86
	if (ch)
87
	{
88
		debug("Channel: %s\n", ch->name);
89
		ps = pstreamer_manager_create_streamer(c->psm, ipaddr, port, id); 
90
		if(ps)
91
		{
92
			debug("Streamer instance created\n");
93
			sdpuri = sdpfile_create(c, ch, ps);
94
			mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
95
			mg_printf_http_chunk(nc, "{id=%s,sdpfile=%s}", id, sdpuri);
96
			mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
97
			free(sdpuri);
98
		} else {
99
			debug("Streamer could not be launched\n");
100
			mg_printf(nc, "%s", "HTTP/1.1 409 Conflict\r\nTransfer-Encoding: chunked\r\n\r\n");
101
			mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
102
		}
103
	} else {
104
		debug("No channel found for socket <%s:%s>\n", ipaddr, port);
105
		mg_printf(nc, "%s", "HTTP/1.1 404 Not Found\r\nTransfer-Encoding: chunked\r\n\r\n");
106
		mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
107
	}
108

  
109
	free(id);
110
}
src/path_handlers.h
17 17
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 18
*******************************************************************/
19 19

  
20
#ifndef __PATH_HANDLERS__ 
21
#define __PATH_HANDLERS__ 
22

  
20 23
#include <stdint.h>
21 24

  
22 25
#include<router.h>
23
#include<tokens.h>
24
#include<name_lengths.h>
25
#include<debug.h>
26 26
#include<pschannel.h>
27
#include<context.h>
28
#include<mongoose.h>
29

  
30
char * mg_uri_field(struct http_message *hm, uint8_t pos)
31
{
32
	char * uri;
33
	char ** tokens;
34
	uint32_t ntok;
35

  
36
	uri = malloc((hm->uri.len + 1) * sizeof(char));
37
	strncpy(uri, hm->uri.p, hm->uri.len);
38
	uri[hm->uri.len] = '\0';
39

  
40
	tokens = tokens_create(uri, '/', &ntok);
41
	
42
	strcpy(uri, tokens[pos]);
43
	tokens_destroy(&tokens, ntok);
44

  
45
	return uri;
46
}
47

  
48
void channel_index(struct mg_connection *nc, struct http_message *hm)
49
{
50
	char * channels;
51
	const struct context * c;
52

  
53
	c = (const struct context *) nc->user_data;
54 27

  
55
	debug("GET request for channels\n");
56
	channels = pschannel_bucket_to_json(c->pb);
57
	debug("\t%s\n", channels);
58 28

  
59
	mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
60
	mg_printf_http_chunk(nc, "%s", channels);
61
	mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
29
char * mg_uri_field(struct http_message *hm, uint8_t pos);
62 30

  
63
	free(channels);
64
}
65

  
66
void streamer_create(struct mg_connection *nc, struct http_message *hm)
67
{
68
	const struct context * c;
69
	char ipaddr[MAX_IPADDR_LENGTH];
70
	char port[MAX_PORT_LENGTH];
71
	char * id, *json;
72
	const struct pstreamer * ps;
73

  
74
	c = (const struct context *) nc->user_data;
75
	mg_get_http_var(&hm->body, "ipaddr", ipaddr, MAX_IPADDR_LENGTH);
76
	mg_get_http_var(&hm->body, "port", port, MAX_PORT_LENGTH);
77

  
78
	id = mg_uri_field(hm, 2);
31
void channel_index(struct mg_connection *nc, struct http_message *hm);
79 32

  
80
	debug("POST request for resource %s\n", id);
81

  
82
	ps = pstreamer_manager_create_streamer(c->psm, ipaddr, port, id); 
83

  
84
	if(ps)
85
	{
86
		json = pstreamer_to_json(ps);
87
		mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
88
		mg_printf_http_chunk(nc, "%s", json);
89
		mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
90
		free(json);
91
	} else {
92
		mg_printf(nc, "%s", "HTTP/1.1 409 Conflict\r\nTransfer-Encoding: chunked\r\n\r\n");
93
		mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
94
	}
95

  
96
	free(id);
97
}
33
void streamer_create(struct mg_connection *nc, struct http_message *hm);
98 34

  
99 35
uint8_t load_path_handlers(struct router *r)
100 36
{
......
105 41

  
106 42
	return res;
107 43
}
44

  
45
#endif
src/pschannel.c
49 49
	return pb;
50 50
}
51 51

  
52
uint8_t pschannel_bucket_insert(struct pschannel_bucket * pb, char * name, char * ip, char * port, char * quality)
52
uint8_t pschannel_bucket_insert(struct pschannel_bucket * pb, char * name, char * ip, char * port, char * quality, char * sdpfile)
53 53
{
54 54
	struct pschannel * ch;
55 55
	void * res;
56 56

  
57
	if (pb && name && ip && port && quality)
57
	if (pb && name && ip && port && quality && sdpfile)
58 58
	{
59 59
		ch = (struct pschannel *) malloc(sizeof(struct pschannel));
60 60
		memset(ch, 0, sizeof(struct pschannel));
......
62 62
		strncpy(ch->ipaddr, ip, MAX_IPADDR_LENGTH-1);
63 63
		strncpy(ch->port, port, MAX_PORT_LENGTH-1);
64 64
		strncpy(ch->quality, quality, MAX_QUALITY_LENGTH-1);
65
		strncpy(ch->sdpfile, sdpfile, MAX_SDPFILENAME_LENGTH-1);
65 66

  
66 67
		res = ord_set_insert(pb->channels, ch, 0);
67 68
		if (res != ch)  // there is a conflict
......
121 122

  
122 123
	return res;
123 124
}
125

  
126
const struct pschannel * pschannel_bucket_find(const struct pschannel_bucket * psb, const char * ipaddr, const char * port)
127
{
128
	struct pschannel ch;
129
	
130
	if (ipaddr && port)
131
	{
132
		strncpy(ch.ipaddr, ipaddr, MAX_IPADDR_LENGTH);
133
		strncpy(ch.port, port, MAX_PORT_LENGTH);
134
		return (const struct pschannel *) ord_set_find(psb->channels, &ch);
135

  
136
	} else
137
		return NULL;
138
}
src/pschannel.h
28 28
	char ipaddr[MAX_IPADDR_LENGTH];
29 29
	char port[MAX_PORT_LENGTH];
30 30
	char quality[MAX_QUALITY_LENGTH];
31
	char sdpfile[MAX_SDPFILENAME_LENGTH];
31 32
};
32 33

  
33 34
struct pschannel_bucket;
34 35

  
35 36
struct pschannel_bucket * pschannel_bucket_new();
36 37

  
37
uint8_t pschannel_bucket_insert(struct pschannel_bucket * pb, char * name, char * ip, char * port, char * quality);
38
uint8_t pschannel_bucket_insert(struct pschannel_bucket * pb, char * name, char * ip, char * port, char * quality, char * sdpfile);
38 39

  
39 40
const struct pschannel * pschannel_bucket_iter(const struct pschannel_bucket * pb, const struct pschannel * iter);
40 41

  
......
42 43

  
43 44
char * pschannel_bucket_to_json(const struct pschannel_bucket * pb);
44 45

  
46
const struct pschannel * pschannel_bucket_find(const struct pschannel_bucket * psb, const char * ipaddr, const char * port);
47

  
45 48
#endif
src/pstreamer.c
30 30
	char id[PSID_LENGTH];  // identifier for the streamer instance
31 31
	struct pscontext * psc;
32 32
	time_t last_beat;
33
	uint16_t base_port;
33 34
};
34 35

  
35 36
struct pstreamer_manager {
36 37
	struct ord_set * streamers;
38
	uint16_t next_streaming_port;
37 39
};
38 40

  
39 41
int8_t pstreamer_cmp(const void * v1, const void * v2)
......
65 67
	return res;
66 68
}
67 69

  
68
struct pstreamer_manager * pstreamer_manager_new()
70
struct pstreamer_manager * pstreamer_manager_new(uint16_t starting_port)
69 71
{
70 72
	struct pstreamer_manager * psm = NULL;
71 73

  
72 74
	psm = malloc(sizeof(struct pstreamer_manager));
73 75
	psm->streamers = ord_set_new(1, pstreamer_cmp);
76
	psm->next_streaming_port = starting_port;
74 77

  
75 78
	return psm;
76 79
}
......
101 104
		strncpy(ps->source_ip, source_ip, MAX_IPADDR_LENGTH);
102 105
		strncpy(ps->source_port, source_port, MAX_PORT_LENGTH);
103 106
		strncpy(ps->id, id, PSID_LENGTH);
107
		ps->base_port = psm->next_streaming_port;
108
		psm->next_streaming_port += 4;  // we consider RTP streamers uses 4 ports
104 109
		ptr = ord_set_find(psm->streamers, (const void *) ps);
105 110
		if (ptr == NULL)
106 111
		{
......
126 131

  
127 132
	return res;
128 133
}
134

  
135
const char * pstreamer_id(const struct pstreamer * ps)
136
{
137
	if (ps)
138
		return ps->id;
139
	return NULL;
140
}
141

  
142
uint16_t pstreamer_base_port(const struct pstreamer * ps)
143
{
144
	if (ps)
145
		return ps->base_port;
146
	return 0;
147
}
src/pstreamer.h
27 27
struct pstreamer;
28 28
struct pstreamer_manager;
29 29

  
30
struct pstreamer_manager * pstreamer_manager_new();
30
struct pstreamer_manager * pstreamer_manager_new(uint16_t starting_port);
31 31

  
32 32
void pstreamer_manager_destroy(struct pstreamer_manager ** psm);
33 33

  
......
37 37

  
38 38
uint8_t pstreamer_manager_destroy_streamer(struct pstreamer_manager *psm, const struct pstreamer *ps);
39 39

  
40
const char * pstreamer_id(const struct pstreamer * ps);
41

  
42
uint16_t pstreamer_base_port(const struct pstreamer * ps);
43

  
40 44
#endif
src/sdpfile.c
1
/*******************************************************************
2
* PeerStreamer-ng is a P2P video streaming application exposing a ReST
3
* interface.
4
* Copyright (C) 2015 Luca Baldesi <luca.baldesi@unitn.it>
5
*
6
* This program is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU Affero General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU Affero General Public License for more details.
15
*
16
* You should have received a copy of the GNU Affero General Public License
17
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
*******************************************************************/
19

  
20
#include<stdint.h>
21
#include<stdio.h>
22
#include<sdpfile.h>
23
#include<debug.h>
24
#include<tokens.h>
25

  
26

  
27
#ifndef MAX
28
#define MAX(a, b) ((a) > (b) ? (a) : (b))
29
#endif
30

  
31
struct pssdpfile {
32
	const struct pstreamer * ps;
33
	char path[MAX_PATH_LENGTH];
34
};
35

  
36
void sdpfile_dump(const char * filename, const char * sdpdesc, const struct pstreamer * ps)
37
{
38
	FILE * fp;
39
	char ** lines;
40
	char ** records;
41
	uint32_t n_lines, n_records, l, r, i;
42
	uint16_t audio_port, video_port;
43

  
44
	audio_port = pstreamer_base_port(ps);
45
	video_port = audio_port + 2;
46

  
47
	debug("Saving sdpfile to %s\n", filename);
48
	lines = tokens_create((char *) sdpdesc, '\n', &n_lines);
49

  
50
	fp = fopen(filename, "w");
51
	for(l = 0; l < n_lines; l++)
52
	{
53
		records = tokens_create(lines[l], ' ', &n_records);
54
		if ((r = tokens_check(records, n_records, "m=audio")) + 1 > 0)
55
		{
56
			for(i = 0; i < r+1; i++)
57
				fprintf(fp, "%s ", records[i]);
58
			fprintf(fp, "%d ", audio_port);
59
			for(i = r+2; i < n_records-1; i++)
60
				fprintf(fp, "%s ", records[i]);
61
			fprintf(fp, "%s\n", records[i]);
62
		}
63
		else if ((r = tokens_check(records, n_records, "m=video")) + 1 > 0)
64
		{
65
			for(i = 0; i < r+1; i++)
66
				fprintf(fp, "%s ", records[i]);
67
			fprintf(fp, "%d ", video_port);
68
			for(i = r+2; i < n_records-1; i++)
69
				fprintf(fp, "%s ", records[i]);
70
			fprintf(fp, "%s\n", records[i]);
71
		}
72
		else
73
			if (lines[l])
74
				fprintf(fp, "%s\n", lines[l]);
75
		tokens_destroy(&records, n_records);
76
	}
77
	fclose(fp);
78

  
79
	tokens_destroy(&lines, n_lines);
80
}
81

  
82
void sdpfile_handler(struct mg_connection *nc, int ev, void *ev_data)
83
{
84
	struct http_message *hm = (struct http_message *) ev_data;
85
	struct pssdpfile * psdp;
86
	char * sdpdesc;
87

  
88
	psdp = nc->user_data;
89

  
90
	switch (ev) {
91
		case MG_EV_CONNECT:
92
			if (*(int *) ev_data != 0)
93
				debug("SDPFILE retrieval failure\n");
94
			break;
95
		case MG_EV_HTTP_REPLY:
96
			switch (hm->resp_code) {
97
				case 200:
98
					sdpdesc = malloc(sizeof(char) * (hm->body.len + 1));
99
					strncpy(sdpdesc, hm->body.p, hm->body.len);
100
					sdpdesc[hm->body.len] = '\0';  // make sure string terminates
101
					sdpfile_dump(psdp->path, sdpdesc, psdp->ps);
102
					free(sdpdesc);
103
				default:
104
					debug("SDPFILE server answers: %d\n", hm->resp_code);
105
			}
106
			free(psdp);
107
			break;
108
		case MG_EV_CLOSE:
109
			debug("SDPFILE server closed connection\n");
110
			break;
111
		default:
112
			break;
113
	}
114
}
115

  
116

  
117
char * sdpfile_create(const struct context * c, const struct pschannel * ch, const struct pstreamer * ps)
118
{
119
	struct mg_connection * conn;
120
	struct pssdpfile * psdp;
121

  
122
	psdp = malloc(sizeof(struct pssdpfile));
123
	psdp->ps = ps;
124
	snprintf(psdp->path, MAX_PATH_LENGTH, "%s/%s.sdp", c->http_opts.document_root, pstreamer_id(ps));
125

  
126
	conn = mg_connect_http(c->mongoose_srv, sdpfile_handler, ch->sdpfile, NULL, NULL);
127
	conn->user_data = (void *) psdp;
128

  
129
	return strdup(psdp->path);
130
}
src/sdpfile.h
1
/*******************************************************************
2
* PeerStreamer-ng is a P2P video streaming application exposing a ReST
3
* interface.
4
* Copyright (C) 2015 Luca Baldesi <luca.baldesi@unitn.it>
5
*
6
* This program is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU Affero General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU Affero General Public License for more details.
15
*
16
* You should have received a copy of the GNU Affero General Public License
17
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
*******************************************************************/
19

  
20
#ifndef __SDPFILE_H__
21
#define __SDPFILE_H__
22

  
23
#include<pschannel.h>
24
#include<mongoose.h>
25
#include<context.h>
26

  
27

  
28
void sdpfile_handler(struct mg_connection *nc, int ev, void *ev_data);
29

  
30
char * sdpfile_create(const struct context * c, const struct pschannel * ch, const struct pstreamer * ps);
31

  
32
#endif

Also available in: Unified diff