Statistics
| Branch: | Revision:

peerstreamer-src / src / pstreamer.c @ c039490c

History | View | Annotate | Download (3.64 KB)

1
/*******************************************************************
2
* PeerStreamer-ng is a P2P video streaming application exposing a ReST
3
* interface.
4
* Copyright (C) 2017 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<pstreamer.h>
21
#include<time.h>
22
#include<stdlib.h>
23
#include<string.h>
24
#include<stdio.h>
25
#include<ord_set.h>
26

    
27
struct pstreamer {
28
        char source_ip[MAX_IPADDR_LENGTH];
29
        char source_port[MAX_PORT_LENGTH];
30
        char id[PSID_LENGTH];  // identifier for the streamer instance
31
        struct pscontext * psc;
32
        time_t last_beat;
33
        uint16_t base_port;
34
};
35

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

    
41
int8_t pstreamer_cmp(const void * v1, const void * v2)
42
{
43
        const struct pstreamer *ps1, *ps2;
44

    
45
        ps1 = (struct pstreamer *) v1;
46
        ps2 = (struct pstreamer *) v2;
47

    
48
        if (ps1 && ps2)
49
        {
50
                return strcmp(ps1->id, ps2->id);
51
        }
52
        return 0;
53
}
54

    
55
char * pstreamer_to_json(const struct pstreamer * ps)
56
{
57
        char fmt[] = "{\"id\":\"%s\",\"source_ip\":\"%s\",\"source_port\":\"%s\"}";
58
        size_t reslength;
59
        char * res = NULL;
60

    
61
        if (ps)
62
        {
63
                reslength = strlen(fmt) - 2*3 + PSID_LENGTH + MAX_IPADDR_LENGTH + MAX_PORT_LENGTH + 1;
64
                res = malloc(reslength * sizeof(char));
65
                sprintf(res, fmt, ps->id, ps->source_ip, ps->source_port);
66
        }
67
        return res;
68
}
69

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

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

    
78
        return psm;
79
}
80

    
81
void pstreamer_manager_destroy(struct pstreamer_manager ** psm)
82
{
83
        if (psm && *psm)
84
        {
85
                ord_set_destroy(&((*psm)->streamers), 1);
86
                free(*psm);
87
                *psm = NULL;
88
        }
89
}
90

    
91
void pstreamer_touch(struct pstreamer *ps)
92
{
93
        ps->last_beat = time(NULL);
94
}
95

    
96
const struct pstreamer * pstreamer_manager_create_streamer(struct pstreamer_manager * psm, const char * source_ip, const char * source_port, const char * id)
97
{
98
        struct pstreamer * ps = NULL;
99
        const void * ptr = NULL;
100

    
101
        if (psm && source_ip && source_port && id)
102
        {
103
                ps = malloc(sizeof(struct pstreamer));
104
                strncpy(ps->source_ip, source_ip, MAX_IPADDR_LENGTH);
105
                strncpy(ps->source_port, source_port, MAX_PORT_LENGTH);
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
109
                ptr = ord_set_find(psm->streamers, (const void *) ps);
110
                if (ptr == NULL)
111
                {
112
                        pstreamer_touch(ps);
113
                        // initialize context
114
                        ord_set_insert(psm->streamers, ps, 0);
115
                } else
116
                {
117
                        free(ps);
118
                        ps = NULL;
119
                }
120
        }
121

    
122
        return ps;
123
}
124

    
125
uint8_t pstreamer_manager_destroy_streamer(struct pstreamer_manager *psm, const struct pstreamer *ps)
126
{
127
        uint8_t res = 1;
128

    
129
        if (psm && ps)
130
                res = ord_set_remove(psm->streamers, ps, 1);
131

    
132
        return res;
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
}