Statistics
| Branch: | Revision:

peerstreamer-src / src / pschannel.c @ c039490c

History | View | Annotate | Download (3.92 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<pschannel.h>
21
#include<ord_set.h>
22
#include<stdint.h>
23
#include<string.h>
24
#include<stdlib.h>
25
#include<stdio.h>
26

    
27
int8_t pschannel_cmp(const void *ch1,const  void *ch2)
28
{
29
        const struct pschannel *psc1, *psc2;
30
        int res;
31

    
32
        psc1 = (const struct pschannel *) ch1;
33
        psc2 = (const struct pschannel *) ch2;
34
        res = strcmp(psc1->ipaddr, psc2->ipaddr);
35
        if (res == 0)
36
                res = strcmp(psc1->port, psc2->port);
37
        return res;
38
}
39

    
40
struct pschannel_bucket {
41
        struct ord_set * channels;
42
};
43

    
44
struct pschannel_bucket * pschannel_bucket_new()
45
{
46
        struct pschannel_bucket * pb;
47
        pb = (struct pschannel_bucket*) malloc(sizeof(struct pschannel_bucket));
48
        pb->channels = ord_set_new(10, pschannel_cmp);
49
        return pb;
50
}
51

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

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

    
67
                res = ord_set_insert(pb->channels, ch, 0);
68
                if (res != ch)  // there is a conflict
69
                        ord_set_insert(pb->channels, ch, 1);  // we just override the current value
70
                return 0;
71
        }
72
        else
73
                return 1;
74
}
75

    
76
const struct pschannel * pschannel_bucket_iter(const struct pschannel_bucket * pb, const struct pschannel * iter)
77
{
78
        const struct pschannel * res = NULL;
79

    
80
        if (pb)
81
                res = (const struct pschannel *) ord_set_iter(pb->channels, (const void *) iter);
82
        return res;
83
}
84

    
85
void pschannel_bucket_destroy(struct pschannel_bucket ** pb)
86
{
87
        if(pb && *pb)
88
        {
89
                ord_set_destroy(&((*pb)->channels), 1);
90
                free(*pb);
91
                *pb = NULL;
92
        }
93
}
94

    
95
char * pschannel_bucket_to_json(const struct pschannel_bucket * pb)
96
{
97
        char objstr[] = "{\"name\":\"\",\"ipaddr\":\"\",\"port\":\"\",\"quality\":\"\"},";
98
        size_t reslength, i;
99
        char * res = NULL;
100
        const struct pschannel * iter;
101

    
102
        if (pb)
103
        {
104
                reslength = strlen("[]") + (strlen(objstr) + MAX_NAME_LENGTH + 
105
                        MAX_IPADDR_LENGTH + MAX_PORT_LENGTH + MAX_QUALITY_LENGTH) * 
106
                           ord_set_length(pb->channels) + 1;
107

    
108
                res = (char *) malloc (sizeof(char) * reslength);
109

    
110
                res[0] = '[';
111
                i = 1;
112
                for(iter = NULL; (iter = pschannel_bucket_iter(pb, iter));)
113
                {
114
                        if (i > 1)
115
                                res[i++] = ',';
116
                        i += sprintf(res+i, "{\"name\":\"%s\",\"ipaddr\":\"%s\",\"port\":\"%s\",\"quality\":\"%s\"}", 
117
                                        iter->name, iter->ipaddr, iter->port, iter->quality);
118
                }
119
                res[i] = ']'; i++;
120
                res[i] = '\0'; i++;
121
        }
122

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