d26a2085bdb49879ed0ce612791ee63629ecb42f
[swifty.git] / src / lib_swift.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include <arpa/inet.h>
6 #include <netinet/in.h>
7 #include <sys/types.h>
8 #include <sys/socket.h>
9 #include <unistd.h>
10
11 #define DEBUG
12 #include "lib_swift.h"
13
14 struct sockSwiftaddr transformFromAddrToSwift(struct listsockaddr lsa)
15 {
16         struct sockSwiftaddr ssa;
17         int i;
18         
19         for (i = 0; i < lsa.N; i++)
20         {
21                 ssa.sin_addr.s_addr[i] = lsa.sa[i].sin_addr.s_addr;
22         }
23         
24         return ssa;
25 }
26
27 struct listsockaddr transformFromSwiftToAddr(struct sockSwiftaddr ssa)
28 {
29         struct listsockaddr lsa;
30         int i;
31         
32         lsa.N = ssa.sin_addr.N;
33         
34         for ( i = 0; i < lsa.N; i++) {
35                 lsa.sa[i].sin_family = ssa.sin_family;
36                 lsa.sa[i].sin_port = ssa.sin_port;
37                 lsa.sa[i].sin_addr.s_addr = ssa.sin_addr.s_addr[i];
38         }
39         
40         return lsa;
41 }
42
43 // Function to receive a message
44 ssize_t recvfromSwift(Swift s, void *buf, size_t len, int flags,
45                                           struct sockSwiftaddr *from, socklen_t fromlen)
46 {
47         struct sockaddr s_other;
48         socklen_t slen=sizeof(s_other); 
49         ssize_t rec = -1, send;
50         char *command = "test";
51         struct listsockaddr lsa =  transformFromSwiftToAddr(*from);
52         int i, channel;
53         
54         Dprintf("create recv channel\n");       
55         // TODO make pool
56         if (s->usedChannels < s->maxChannels) 
57         {
58                 channel = s->usedChannels++;
59                 CHECK(s->recvChannel[channel] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP));
60
61                 for ( i = 0 ; i < lsa.N ; i++) 
62                 {
63                         Dprintf("send information to %s\n", inet_ntoa(lsa.sa[0].sin_addr));                     
64                         send = sendto(s->recvChannel[channel], command, strlen(command), 0, (const struct sockaddr *)&lsa.sa[i], sizeof(lsa.sa[i]));
65                 }
66                 
67                 Dprintf("receive data\n");
68                 // I'm waiting for response
69                 rec = recvfrom(s->recvChannel[channel], buf, len, flags,  (struct sockaddr * __restrict__)&s_other, &slen);             
70         
71                 close(s->recvChannel[channel]);
72                 s->usedChannels--;
73         }
74         return rec;
75 }
76
77 // Function to send a message
78 ssize_t sendToSwift(Swift s, const void *buf, size_t len, int flags, 
79                                         const struct sockSwiftaddr *to, socklen_t tolen) 
80 {
81         struct listsockaddr lsa =  transformFromSwiftToAddr(*to);
82         int i;
83         ssize_t send = -1;
84         
85         Dprintf("send data\n");
86         for ( i = 0 ; i < lsa.N ; i++) 
87         {
88                 send = sendto(s->sendChannel, buf, len, flags, (const struct sockaddr *)&lsa.sa[i], sizeof(lsa.sa[i]));
89         }
90         
91         return send;
92 }
93 // Function to listen to a port
94 int listenfromSwift (Swift s, void *buf, size_t len, int flags,
95                                          struct sockSwiftaddr * __restrict__ from, socklen_t *fromlen) 
96 {
97         struct sockaddr s_other;
98         struct listsockaddr lsa;
99         socklen_t slen=sizeof(s_other); 
100         ssize_t rec;
101         
102         Dprintf("wait to receive messages\n");
103         
104         rec = recvfrom(s->socketListener, buf, len, flags,  (struct sockaddr * __restrict__)&s_other, &slen);
105         
106         // fill listsockaddr
107         memcpy(&lsa.sa[0], &s_other, sizeof(s_other));
108         lsa.N = 1;
109         
110         *from = transformFromAddrToSwift(lsa);
111         
112         return rec;
113 }
114
115 // Function to bind a port for swift socket
116 int bindSwift(Swift s, const struct sockSwiftaddr *my_addr, socklen_t addrlen)
117 {
118         Dprintf("bind swift socket\n");
119         struct listsockaddr lsa = transformFromSwiftToAddr(*my_addr);
120                 
121         return bind(s->socketListener, (const struct sockaddr *)&lsa.sa[0], sizeof(lsa.sa[0]));
122 }
123
124 // Function to create a Swift socket
125 Swift socketSwift(int maxChannels)
126 {
127         Dprintf("create struct swift\n");       
128         Swift s = calloc(1,sizeof(*s));
129
130         Dprintf("create swift socket listener\n");      
131         CHECK(s->socketListener = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP));
132
133         Dprintf("create swift send channel\n"); 
134         CHECK(s->sendChannel = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP));
135
136         return s;
137 }
138
139
140 void closeSwift(Swift s)
141 {
142         Dprintf("close swift socket\n");
143         close(s->socketListener);
144         close(s->sendChannel);
145         
146         
147         free(s);
148 }
149
150