Rev 2110 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2099 | jaeger | 1 | #include |
8473 | maxcodehac | 2 | // #include |
2099 | jaeger | 3 | |
4 | #include "tp.h" |
||
5 | |||
6 | extern tp_obj tp_dict(TP); |
||
7 | extern tp_obj tp_method(TP,tp_obj self,tp_obj v(TP)); |
||
8 | extern tp_obj tp_fnc(TP,tp_obj v(TP)); |
||
2110 | jaeger | 9 | extern tp_obj tp_get(TP,tp_obj self, tp_obj k); |
10 | tp_obj tp_has(TP,tp_obj self, tp_obj k); |
||
11 | #define _cdecl __attribute__((cdecl)) |
||
12 | extern int (* _cdecl con_printf)(const char* format,...); |
||
2099 | jaeger | 13 | |
2110 | jaeger | 14 | #define PRECISION 0.000001 |
15 | |||
2099 | jaeger | 16 | #define GET_SOCKET_DESCRIPTOR(_obj, _sock) do{ \ |
2110 | jaeger | 17 | if (fabs(tp_has(tp, _obj, tp_string("socket")).number.val) < PRECISION)\ |
2099 | jaeger | 18 | tp_raise(tp_None, "Socket not open", tp_None); \ |
2110 | jaeger | 19 | _sock = (__u32)(tp_get(tp, _obj, tp_string("socket")).number.val + PRECISION);\ |
2099 | jaeger | 20 | } while(0) |
21 | |||
22 | /* Socket close method. |
||
23 | * |
||
24 | * Example: |
||
25 | * s.close() # s must be a socket object created by socket. |
||
26 | * |
||
27 | * Raises exception if socket was not opened. Otherwise returns True. |
||
28 | */ |
||
2110 | jaeger | 29 | static tp_obj kolibri_close_socket(TP) |
2099 | jaeger | 30 | { |
8473 | maxcodehac | 31 | // tp_obj self = TP_TYPE(TP_DICT); |
32 | // __u32 socktype; |
||
33 | // __u32 s; |
||
2099 | jaeger | 34 | |
8473 | maxcodehac | 35 | // GET_SOCKET_DESCRIPTOR(self, s); |
2099 | jaeger | 36 | |
8473 | maxcodehac | 37 | // socktype = (__u32)tp_get(tp, self, tp_string("type")).number.val; |
38 | // GET_SOCKET_DESCRIPTOR(self, s); |
||
39 | // if (socktype == SOCK_STREAM) |
||
40 | // __menuet__close_TCP_socket(s); |
||
41 | // else if (socktype == SOCK_DGRAM) |
||
42 | // __menuet__close_UDP_socket(s); |
||
2099 | jaeger | 43 | return tp_True; |
44 | } |
||
45 | |||
46 | /* Socket send method. |
||
47 | * |
||
48 | * Example: |
||
49 | * data=" |
||
50 | * s.send(data) |
||
51 | * or: |
||
52 | * s.send(data, 20) # Send just 20 bytes |
||
53 | */ |
||
2110 | jaeger | 54 | static tp_obj kolibri_send(TP) |
2099 | jaeger | 55 | { |
8473 | maxcodehac | 56 | // tp_obj self = TP_TYPE(TP_DICT); |
57 | // tp_obj data_obj = TP_TYPE(TP_STRING); |
||
58 | // __u32 datalen = TP_DEFAULT(tp_False).number.val; |
||
59 | // __u32 socktype = (__u32)tp_get(tp, self, tp_string("type")).number.val; |
||
60 | // __u32 s; |
||
61 | // int result; |
||
2099 | jaeger | 62 | |
8473 | maxcodehac | 63 | // GET_SOCKET_DESCRIPTOR(self, s); |
2099 | jaeger | 64 | |
8473 | maxcodehac | 65 | // if (datalen < 0 || datalen > data_obj.string.len) |
66 | // datalen = data_obj.string.len; |
||
67 | // if (socktype == SOCK_STREAM) |
||
68 | // result = __menuet__write_TCP_socket(s, datalen, (void *)data_obj.string.val); |
||
69 | // else if (socktype == SOCK_DGRAM) |
||
70 | // result = __menuet__write_UDP_socket(s, datalen, (void *)data_obj.string.val); |
||
71 | // return tp_number(!(result != 0)); |
||
72 | return tp_number(0); |
||
2099 | jaeger | 73 | } |
74 | |||
8473 | maxcodehac | 75 | #define __u32 unsigned int |
76 | #define __u8 unsigned char |
||
77 | |||
2099 | jaeger | 78 | /* Socket recv method. |
79 | * |
||
80 | * data=" |
||
81 | * s.recv(data) |
||
82 | * or: |
||
83 | * s.recv(data, 20) # Send just 20 bytes |
||
84 | */ |
||
2110 | jaeger | 85 | static tp_obj kolibri_recv(TP) |
2099 | jaeger | 86 | { |
87 | tp_obj self = TP_TYPE(TP_DICT); |
||
88 | __u32 datalen = TP_DEFAULT(tp_False).number.val; |
||
89 | __u32 s; |
||
90 | __u8 c; |
||
91 | __u8 *buf, *p; |
||
92 | __u32 buf_size; |
||
93 | __u32 bytes_read = 0; |
||
94 | int i; |
||
95 | |||
8473 | maxcodehac | 96 | // GET_SOCKET_DESCRIPTOR(self, s); |
2099 | jaeger | 97 | |
8473 | maxcodehac | 98 | // if (datalen) |
99 | // buf_size = datalen; |
||
100 | // else |
||
101 | // buf_size = 2048; |
||
102 | // if (!(buf = malloc(datalen))) |
||
103 | // tp_raise(tp_None, "Cannot allocate buffer for received data", tp_None); |
||
104 | // p = buf; |
||
105 | // while (__menuet__read_socket(s, &c) && bytes_read < buf_size) |
||
106 | // { |
||
107 | // *p++ = c; |
||
108 | // bytes_read++; |
||
109 | // if (bytes_read >= buf_size && !datalen) |
||
110 | // { |
||
111 | // buf_size += 1024; |
||
112 | // buf = realloc(buf, buf_size); |
||
113 | // } |
||
114 | // } |
||
2099 | jaeger | 115 | return tp_string_n(buf, bytes_read); |
116 | } |
||
117 | |||
2110 | jaeger | 118 | static void inet_pton(TP, const char *buf, int len, __u32 *addr) |
2099 | jaeger | 119 | { |
120 | char *p = (char *)buf; |
||
121 | int i = 0; |
||
122 | __u32 val = 0; |
||
123 | *addr = 0; |
||
124 | while (*p && p < buf + len && i < 4) |
||
125 | { |
||
2110 | jaeger | 126 | if (*p == '.' || !*p) |
2099 | jaeger | 127 | { |
128 | if (val > 255) |
||
2110 | jaeger | 129 | tp_raise(tp_None, "ValueError: number > 255 in IP address", tp_None); |
2099 | jaeger | 130 | *addr += (val << ((i++) << 3)); |
131 | val = 0; |
||
132 | } |
||
133 | else |
||
134 | { |
||
135 | if (*p < '0' || *p > '9') |
||
2110 | jaeger | 136 | tp_raise(tp_None, "ValueError: bad char in IP address, digit expected", tp_None); |
2099 | jaeger | 137 | val = val * 10 + *p - '0'; |
138 | } |
||
139 | p++; |
||
140 | } |
||
2110 | jaeger | 141 | if (!*p) |
142 | { |
||
143 | if (i == 3) |
||
144 | *addr += (val << ((i++) << 3)); |
||
145 | else |
||
146 | tp_raise(tp_None, "ValueError: bad IP address", tp_None); |
||
147 | } |
||
148 | |||
2099 | jaeger | 149 | } |
150 | |||
151 | /* Converter from string presentation to binary address. */ |
||
2110 | jaeger | 152 | static tp_obj kolibri_inet_pton(TP) |
2099 | jaeger | 153 | { |
154 | tp_obj obj; |
||
155 | __u32 addr; |
||
156 | obj = TP_TYPE(TP_STRING); |
||
8473 | maxcodehac | 157 | // inet_pton(tp, (char *)obj.string.val, (int)obj.string.len, &addr); |
2099 | jaeger | 158 | return tp_number(addr); |
159 | } |
||
160 | |||
161 | /* Socket bind method. |
||
162 | * |
||
163 | * In KolibriOS it just sets local address and port. |
||
164 | * |
||
165 | * Example: |
||
166 | * s.bind('10.10.1.2', 6000) #Connects to 10.10.1.2:6000 |
||
167 | */ |
||
168 | tp_obj kolibri_bind(TP) |
||
169 | { |
||
8473 | maxcodehac | 170 | // tp_obj self = TP_TYPE(TP_DICT); |
171 | // tp_obj local_addr_obj = TP_OBJ(); |
||
172 | // __u32 local_port = (__u32)TP_TYPE(TP_NUMBER).number.val; |
||
173 | // __u32 local_addr; |
||
2099 | jaeger | 174 | |
8473 | maxcodehac | 175 | // if (local_addr_obj.type == TP_NUMBER) |
176 | // local_addr = local_addr_obj.number.val; |
||
177 | // else if (local_addr_obj.type == TP_STRING) |
||
178 | // inet_pton(tp, (const char *)local_addr_obj.string.val, local_addr_obj.string.len, &local_addr); |
||
2099 | jaeger | 179 | |
8473 | maxcodehac | 180 | // tp_set(tp, self, tp_string("local_addr"), tp_number(local_addr)); |
181 | // tp_set(tp, self, tp_string("local_port"), tp_number(local_port)); |
||
2099 | jaeger | 182 | return tp_None; |
183 | } |
||
184 | |||
185 | /* Socket connect method. |
||
186 | * |
||
187 | * Example: |
||
188 | * s.connect('10.10.1.1', 7000) #Connects to 10.10.1.1:7000 |
||
189 | */ |
||
190 | tp_obj kolibri_connect(TP) |
||
191 | { |
||
8473 | maxcodehac | 192 | // tp_obj self = TP_TYPE(TP_DICT); |
193 | // tp_obj remote_addr_obj = TP_OBJ(); |
||
194 | // __u32 remote_addr; |
||
195 | // __u32 remote_port = (__u32)TP_TYPE(TP_NUMBER).number.val; |
||
196 | // __u32 local_port = tp_get(tp, self, tp_string("local_port")).number.val; |
||
197 | // __u32 socktype = (__u32)tp_get(tp, self, tp_string("type")).number.val; |
||
198 | // int s = -1; /* Socket descriptor */ |
||
2099 | jaeger | 199 | |
200 | |||
8473 | maxcodehac | 201 | // if (remote_addr_obj.type == TP_NUMBER) |
202 | // remote_addr = remote_addr_obj.number.val; |
||
203 | // else if (remote_addr_obj.type == TP_STRING) |
||
204 | // inet_pton(tp, (const char *)remote_addr_obj.string.val, remote_addr_obj.string.len, &remote_addr); |
||
2099 | jaeger | 205 | |
8473 | maxcodehac | 206 | // if (socktype == SOCK_STREAM) |
207 | // s = __menuet__open_TCP_socket(local_port, remote_port, remote_addr, 1); |
||
208 | // else if (socktype == SOCK_DGRAM) |
||
209 | // s = __menuet__open_UDP_socket(local_port, remote_port, remote_addr); |
||
210 | // if (s >= 0) |
||
211 | // { |
||
212 | // tp_set(tp, self, tp_string("socket"), tp_number(s)); |
||
213 | // return tp_True; |
||
214 | // } |
||
215 | // else |
||
2099 | jaeger | 216 | return tp_False; |
217 | } |
||
218 | |||
219 | /* Socket listen method. |
||
220 | * |
||
221 | * Example: |
||
222 | * s.listen('10.10.1.1', 5000) |
||
223 | */ |
||
224 | tp_obj kolibri_listen(TP) |
||
225 | { |
||
8473 | maxcodehac | 226 | // tp_obj self = TP_TYPE(TP_DICT); |
227 | // tp_obj remote_addr_obj = TP_OBJ(); |
||
228 | // __u32 remote_addr; |
||
229 | // __u32 remote_port = (__u32)TP_TYPE(TP_NUMBER).number.val; |
||
230 | // __u32 local_port = tp_get(tp, self, tp_string("local_port")).number.val; |
||
231 | // __u32 socktype = (__u32)tp_get(tp, self, tp_string("type")).number.val; |
||
232 | // int s = -1; /* Socket descriptor */ |
||
2099 | jaeger | 233 | |
8473 | maxcodehac | 234 | // if (socktype != SOCK_STREAM) |
235 | // tp_raise(tp_None, "IOError: attempt to listen on non-TCP socket", tp_None); |
||
2099 | jaeger | 236 | |
8473 | maxcodehac | 237 | // if (remote_addr_obj.type == TP_NUMBER) |
238 | // remote_addr = remote_addr_obj.number.val; |
||
239 | // else if (remote_addr_obj.type == TP_STRING) |
||
240 | // inet_pton(tp, (const char *)remote_addr_obj.string.val, remote_addr_obj.string.len, &remote_addr); |
||
2099 | jaeger | 241 | |
8473 | maxcodehac | 242 | // if ((s = __menuet__open_TCP_socket(local_port, remote_port, remote_addr, 0)) >= 0) |
243 | // { |
||
244 | // tp_set(tp, self, tp_string("socket"), tp_number(s)); |
||
245 | // return tp_True; |
||
246 | // } |
||
247 | // else |
||
2099 | jaeger | 248 | return tp_False; |
249 | } |
||
250 | |||
251 | |||
252 | /* Exported function. |
||
253 | * |
||
254 | * Example: |
||
255 | * |
||
256 | * s = socket(socket.AF_INET, socket.SOCK_DGRAM) |
||
257 | * |
||
258 | * Returns socket object. |
||
259 | */ |
||
260 | tp_obj kolibri_socket(TP) |
||
261 | { |
||
262 | tp_obj s; |
||
263 | tp_obj sockfamily = TP_TYPE(TP_NUMBER); |
||
264 | tp_obj socktype = TP_TYPE(TP_NUMBER); |
||
265 | |||
8473 | maxcodehac | 266 | // if (fabs(sockfamily.number.val - AF_INET) > PRECISION || |
267 | // (fabs(socktype.number.val - SOCK_STREAM) > PRECISION && |
||
268 | // fabs(socktype.number.val - SOCK_DGRAM) > PRECISION)) |
||
269 | // return tp_None; |
||
2099 | jaeger | 270 | s = tp_dict(tp); |
8473 | maxcodehac | 271 | // tp_set(tp, s, tp_string("family"), sockfamily); |
272 | // tp_set(tp, s, tp_string("type"), socktype); |
||
273 | // tp_set(tp, s, tp_string("bind"), tp_method(tp, s, kolibri_bind)); |
||
274 | // tp_set(tp, s, tp_string("connect"), tp_method(tp, s, kolibri_connect)); |
||
275 | // tp_set(tp, s, tp_string("send"), tp_method(tp, s, kolibri_send)); |
||
276 | // tp_set(tp, s, tp_string("recv"), tp_method(tp, s, kolibri_recv)); |
||
277 | // tp_set(tp, s, tp_string("close"), tp_method(tp, s, kolibri_close_socket)); |
||
278 | // if (fabs(socktype.number.val - SOCK_STREAM) < PRECISION) |
||
279 | // tp_set(tp, s, tp_string("listen"), tp_method(tp, s, kolibri_listen)); |
||
2099 | jaeger | 280 | return s; |
281 | } |
||
282 | |||
283 | tp_obj kolibri_socket_module(TP) |
||
284 | { |
||
285 | tp_obj socket_mod = tp_dict(tp); |
||
286 | |||
8473 | maxcodehac | 287 | // tp_set(tp, socket_mod, tp_string("AF_INET"), tp_number(AF_INET)); |
288 | // tp_set(tp, socket_mod, tp_string("SOCK_STREAM"), tp_number(SOCK_STREAM)); |
||
289 | // tp_set(tp, socket_mod, tp_string("SOCK_DGRAM"), tp_number(SOCK_DGRAM)); |
||
290 | tp_set(tp, socket_mod, tp_string("AF_INET"), tp_number(0)); |
||
291 | tp_set(tp, socket_mod, tp_string("SOCK_STREAM"), tp_number(0)); |
||
292 | tp_set(tp, socket_mod, tp_string("SOCK_DGRAM"), tp_number(0)); |
||
2110 | jaeger | 293 | tp_set(tp, socket_mod, tp_string("inet_pton"), tp_fnc(tp, kolibri_inet_pton)); |
2099 | jaeger | 294 | tp_set(tp, socket_mod, tp_string("socket"), tp_fnc(tp, kolibri_socket)); |
295 | return socket_mod; |
||
296 | }>><>><>>><>><>>>>>> |