Subversion Repositories Kolibri OS

Rev

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="Preved!!!Example."
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="Preved!!!Example."
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
}