Line |
Branch |
Exec |
Source |
1 |
|
|
#include "socop.h" |
2 |
|
|
|
3 |
|
|
#include <stdlib.h> |
4 |
|
|
#include <string.h> |
5 |
|
|
|
6 |
|
✗ |
int socop_client_init(socop_client_t* session, |
7 |
|
|
socop_read_byte_t reader_func, void* reader_param, |
8 |
|
|
socop_write_byte_t writer_func, void* writer_param) |
9 |
|
|
{ |
10 |
|
✗ |
session->driver.read_byte = reader_func; |
11 |
|
✗ |
session->driver.read_param = reader_param; |
12 |
|
✗ |
session->driver.write_byte = writer_func; |
13 |
|
✗ |
session->driver.write_param = writer_param; |
14 |
|
✗ |
return SOCOP_ERROR_NOTIMPL; |
15 |
|
|
} |
16 |
|
|
|
17 |
|
✗ |
static void serialize_word(unsigned char target[2], socop_word_t src) |
18 |
|
|
{ |
19 |
|
✗ |
target[0] = (unsigned char)(src >> 8); |
20 |
|
✗ |
target[1] = (unsigned char)(src & 0xff); |
21 |
|
✗ |
} |
22 |
|
|
|
23 |
|
✗ |
static void deserialize_word(socop_word_t* target, unsigned char const* src) |
24 |
|
|
{ |
25 |
|
✗ |
*target = ((((socop_word_t)src[0]) << 8) | ((socop_word_t)(src[1] & 0xff))); |
26 |
|
✗ |
} |
27 |
|
|
|
28 |
|
|
|
29 |
|
✗ |
int socop_driver_send_msg(socop_driver_t* driver, socop_msg_base_t const* msg, void const* data) |
30 |
|
|
{ |
31 |
|
|
unsigned char msg_buffer[SOCOP_MSG_BASE_LENGTH]; |
32 |
|
|
unsigned ndx; |
33 |
|
✗ |
unsigned datalen = msg->msg_length - SOCOP_MSG_BASE_LENGTH; |
34 |
|
✗ |
unsigned char const* ptr_data = (unsigned char const*)data; |
35 |
|
|
unsigned more; /* true until no more bytes will follow */ |
36 |
|
|
int result; |
37 |
|
|
|
38 |
|
|
/* serialize header */ |
39 |
|
✗ |
serialize_word(&msg_buffer[0], msg->msg_type); |
40 |
|
✗ |
serialize_word(&msg_buffer[2], msg->msg_length); |
41 |
|
✗ |
serialize_word(&msg_buffer[4], msg->resource_id); |
42 |
|
✗ |
serialize_word(&msg_buffer[6], msg->resource_param); |
43 |
|
✗ |
serialize_word(&msg_buffer[8], msg->state); |
44 |
|
✗ |
serialize_word(&msg_buffer[10], msg->user_param); |
45 |
|
|
|
46 |
|
|
/* send header */ |
47 |
|
✗ |
more = 1; |
48 |
|
✗ |
for (ndx = 0; ndx != SOCOP_MSG_BASE_LENGTH; ++ndx) |
49 |
|
|
{ |
50 |
|
✗ |
if (ndx == SOCOP_MSG_BASE_LENGTH - 1) |
51 |
|
|
{ |
52 |
|
✗ |
more = (datalen == 0) ? 0 : 1; |
53 |
|
|
} |
54 |
|
✗ |
result = driver->write_byte(msg_buffer[ndx], more, driver->write_param); |
55 |
|
✗ |
if (result != SOCOP_OK) |
56 |
|
|
{ |
57 |
|
✗ |
return SOCOP_ERROR_IO; |
58 |
|
|
} |
59 |
|
|
} |
60 |
|
|
|
61 |
|
|
/* send content if available */ |
62 |
|
✗ |
for (ndx = 0; ndx != datalen; ++ndx) |
63 |
|
|
{ |
64 |
|
✗ |
more = (ndx == datalen - 1) ? 0 : 1; |
65 |
|
✗ |
result = driver->write_byte(ptr_data[ndx], more, driver->write_param); |
66 |
|
✗ |
if (result != SOCOP_OK) |
67 |
|
|
{ |
68 |
|
✗ |
return SOCOP_ERROR_IO; |
69 |
|
|
} |
70 |
|
|
} |
71 |
|
|
|
72 |
|
✗ |
return SOCOP_OK; |
73 |
|
|
} |
74 |
|
|
|
75 |
|
✗ |
static int receive_buffer(socop_driver_t* driver, unsigned char* target, unsigned length) |
76 |
|
|
{ |
77 |
|
|
unsigned ndx; |
78 |
|
|
unsigned more; |
79 |
|
|
int result; |
80 |
|
|
|
81 |
|
✗ |
for (ndx = 0; ndx != length; ++ndx) |
82 |
|
|
{ |
83 |
|
✗ |
more = (ndx == length - 1) ? 0 : 1; |
84 |
|
✗ |
result = driver->read_byte(&target[ndx], more, driver->read_param); |
85 |
|
✗ |
if (result == SOCOP_ERROR_TIMEOUT) |
86 |
|
|
{ |
87 |
|
✗ |
continue; |
88 |
|
|
} |
89 |
|
✗ |
if (result != SOCOP_OK) |
90 |
|
|
{ |
91 |
|
✗ |
return result; |
92 |
|
|
} |
93 |
|
|
} |
94 |
|
✗ |
return SOCOP_OK; |
95 |
|
|
} |
96 |
|
|
|
97 |
|
✗ |
int socop_driver_receive_msg(socop_driver_t* driver, socop_msg_buffer_t* buffer) |
98 |
|
|
{ |
99 |
|
|
unsigned char msg_buffer[SOCOP_MSG_BASE_LENGTH]; |
100 |
|
|
unsigned data_len; |
101 |
|
|
int result; |
102 |
|
|
|
103 |
|
✗ |
result = receive_buffer(driver, msg_buffer, SOCOP_MSG_BASE_LENGTH); |
104 |
|
✗ |
if (result != SOCOP_OK) |
105 |
|
|
{ |
106 |
|
✗ |
return result; |
107 |
|
|
} |
108 |
|
|
|
109 |
|
✗ |
deserialize_word(&buffer->base.msg_type, &msg_buffer[0]); |
110 |
|
✗ |
deserialize_word(&buffer->base.msg_length, &msg_buffer[2]); |
111 |
|
✗ |
deserialize_word(&buffer->base.resource_id, &msg_buffer[4]); |
112 |
|
✗ |
deserialize_word(&buffer->base.resource_param, &msg_buffer[6]); |
113 |
|
✗ |
deserialize_word(&buffer->base.state, &msg_buffer[8]); |
114 |
|
✗ |
deserialize_word(&buffer->base.user_param, &msg_buffer[10]); |
115 |
|
|
|
116 |
|
✗ |
if (buffer->base.msg_length < SOCOP_MSG_BASE_LENGTH) |
117 |
|
|
{ |
118 |
|
✗ |
return SOCOP_ERROR_INVALIDDATA; |
119 |
|
|
} |
120 |
|
✗ |
if ((buffer->base.msg_type & SOCOP_MSG_MASK) != SOCOP_MSG_MASK) |
121 |
|
|
{ |
122 |
|
✗ |
return SOCOP_ERROR_INVALIDDATA; |
123 |
|
|
} |
124 |
|
|
|
125 |
|
✗ |
if (buffer->base.msg_length == SOCOP_MSG_BASE_LENGTH) |
126 |
|
|
{ |
127 |
|
✗ |
return SOCOP_OK; |
128 |
|
|
} |
129 |
|
✗ |
data_len = buffer->base.msg_length - SOCOP_MSG_BASE_LENGTH; |
130 |
|
✗ |
if (data_len > sizeof(buffer->content)) |
131 |
|
|
{ |
132 |
|
✗ |
return SOCOP_ERROR_OUTOFBOUNDS; |
133 |
|
|
} |
134 |
|
✗ |
return receive_buffer(driver, (unsigned char*)&buffer->content[0], data_len); |
135 |
|
|
} |
136 |
|
|
|
137 |
|
|
|
138 |
|
|
|
139 |
|
✗ |
static void init_msg_base(socop_msg_base_t* msg, socop_word_t type, socop_word_t sock_id, socop_word_t sock_param, |
140 |
|
|
socop_word_t state, socop_word_t user, socop_word_t content_length) |
141 |
|
|
{ |
142 |
|
✗ |
msg->msg_type = type; |
143 |
|
✗ |
msg->msg_length = SOCOP_MSG_BASE_LENGTH + content_length; |
144 |
|
✗ |
msg->resource_id = sock_id; |
145 |
|
✗ |
msg->resource_param = sock_param; |
146 |
|
✗ |
msg->state = state; |
147 |
|
✗ |
msg->user_param = user; |
148 |
|
✗ |
} |
149 |
|
|
|
150 |
|
✗ |
static int receive_message_type(socop_driver_t* session, socop_msg_buffer_t* ptr_msg, socop_word_t desired_type, socop_word_t desired_resource_id) |
151 |
|
|
{ |
152 |
|
✗ |
int result = socop_driver_receive_msg(session, ptr_msg); |
153 |
|
✗ |
if (result != SOCOP_OK) |
154 |
|
|
{ |
155 |
|
✗ |
return result; |
156 |
|
|
} |
157 |
|
✗ |
if (ptr_msg->base.msg_type != desired_type) |
158 |
|
|
{ |
159 |
|
✗ |
return SOCOP_ERROR_WRONGMESSAGE; |
160 |
|
|
} |
161 |
|
✗ |
if (ptr_msg->base.state != SOCOP_OK) |
162 |
|
|
{ |
163 |
|
✗ |
return ptr_msg->base.state; |
164 |
|
|
} |
165 |
|
✗ |
if (desired_resource_id && (ptr_msg->base.resource_id != desired_resource_id)) |
166 |
|
|
{ |
167 |
|
✗ |
return SOCOP_ERROR_RESOURCEERROR; |
168 |
|
|
} |
169 |
|
✗ |
return SOCOP_OK; |
170 |
|
|
} |
171 |
|
|
|
172 |
|
✗ |
static socop_word_t serialize_addr(unsigned char target[6], socop_addr_t const* ptr_addr) |
173 |
|
|
{ |
174 |
|
✗ |
target[0] = ptr_addr->ip[0]; |
175 |
|
✗ |
target[1] = ptr_addr->ip[1]; |
176 |
|
✗ |
target[2] = ptr_addr->ip[2]; |
177 |
|
✗ |
target[3] = ptr_addr->ip[3]; |
178 |
|
✗ |
serialize_word(&target[4], ptr_addr->port); |
179 |
|
✗ |
return 6; |
180 |
|
|
} |
181 |
|
|
|
182 |
|
✗ |
static void deserialize_addr(socop_addr_t* target, unsigned char const src[6]) |
183 |
|
|
{ |
184 |
|
✗ |
target->ip[0] = src[0]; |
185 |
|
✗ |
target->ip[1] = src[1]; |
186 |
|
✗ |
target->ip[2] = src[2]; |
187 |
|
✗ |
target->ip[3] = src[3]; |
188 |
|
✗ |
deserialize_word(&target->port, &src[4]); |
189 |
|
✗ |
} |
190 |
|
|
|
191 |
|
|
|
192 |
|
✗ |
int socop_client_reset(socop_client_t* session) |
193 |
|
|
{ |
194 |
|
|
int result; |
195 |
|
|
socop_msg_buffer_t msg; |
196 |
|
|
|
197 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_RESET_REQUEST, 0, 0, 0, 0, 0); |
198 |
|
✗ |
result = socop_driver_send_msg(&session->driver, &msg.base, msg.content); |
199 |
|
✗ |
if (result != SOCOP_OK) |
200 |
|
|
{ |
201 |
|
✗ |
return result; |
202 |
|
|
} |
203 |
|
✗ |
result = receive_message_type(&session->driver, &msg, SOCOP_MSG_RESET_RESPONSE, 0); |
204 |
|
✗ |
if (result != SOCOP_OK) |
205 |
|
|
{ |
206 |
|
✗ |
return result; |
207 |
|
|
} |
208 |
|
✗ |
return SOCOP_OK; |
209 |
|
|
} |
210 |
|
|
|
211 |
|
✗ |
int socop_client_netstatus(socop_client_t* session, void* ptr_status) |
212 |
|
|
{ |
213 |
|
|
int result; |
214 |
|
|
socop_msg_buffer_t msg; |
215 |
|
|
|
216 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_NET_STATUS_REQUEST, 0, 0, 0, 0, 0); |
217 |
|
✗ |
result = socop_driver_send_msg(&session->driver, &msg.base, msg.content); |
218 |
|
✗ |
if (result != SOCOP_OK) |
219 |
|
|
{ |
220 |
|
✗ |
return result; |
221 |
|
|
} |
222 |
|
✗ |
result = receive_message_type(&session->driver, &msg, SOCOP_MSG_NET_STATUS_RESPONSE, 0); |
223 |
|
✗ |
if (result != SOCOP_OK) |
224 |
|
|
{ |
225 |
|
✗ |
return result; |
226 |
|
|
} |
227 |
|
✗ |
return SOCOP_OK; |
228 |
|
|
} |
229 |
|
|
|
230 |
|
✗ |
int socop_client_netstart(socop_client_t* session, char const* parameters, unsigned parameters_length) |
231 |
|
|
{ |
232 |
|
|
int result; |
233 |
|
|
socop_msg_buffer_t msg; |
234 |
|
✗ |
if (parameters_length > SOCOP_MAX_CONTENT_LENGTH) |
235 |
|
|
{ |
236 |
|
✗ |
parameters_length = SOCOP_MAX_CONTENT_LENGTH; |
237 |
|
|
} |
238 |
|
|
|
239 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_NET_START_REQUEST, 0, 0, 0, 0, (socop_word_t)parameters_length); |
240 |
|
✗ |
result = socop_driver_send_msg(&session->driver, &msg.base, parameters); |
241 |
|
✗ |
if (result != SOCOP_OK) |
242 |
|
|
{ |
243 |
|
✗ |
return result; |
244 |
|
|
} |
245 |
|
✗ |
result = receive_message_type(&session->driver, &msg, SOCOP_MSG_NET_START_RESPONSE, 0); |
246 |
|
✗ |
if (result != SOCOP_OK) |
247 |
|
|
{ |
248 |
|
✗ |
return result; |
249 |
|
|
} |
250 |
|
✗ |
return SOCOP_OK; |
251 |
|
|
} |
252 |
|
|
|
253 |
|
✗ |
int socop_client_netstop(socop_client_t* session) |
254 |
|
|
{ |
255 |
|
|
int result; |
256 |
|
|
socop_msg_buffer_t msg; |
257 |
|
|
|
258 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_NET_STOP_REQUEST, 0, 0, 0, 0, 0); |
259 |
|
✗ |
result = socop_driver_send_msg(&session->driver, &msg.base, NULL); |
260 |
|
✗ |
if (result != SOCOP_OK) |
261 |
|
|
{ |
262 |
|
✗ |
return result; |
263 |
|
|
} |
264 |
|
✗ |
result = receive_message_type(&session->driver, &msg, SOCOP_MSG_NET_STOP_RESPONSE, 0); |
265 |
|
✗ |
if (result != SOCOP_OK) |
266 |
|
|
{ |
267 |
|
✗ |
return result; |
268 |
|
|
} |
269 |
|
✗ |
return SOCOP_OK; |
270 |
|
|
} |
271 |
|
|
|
272 |
|
✗ |
int socop_client_connect(socop_client_t* session, socop_addr_t const* addr, socop_socket_t* ptr_sock) |
273 |
|
|
{ |
274 |
|
|
int result; |
275 |
|
|
socop_msg_buffer_t msg; |
276 |
|
✗ |
const socop_word_t content_len = serialize_addr((unsigned char*)&msg.content[0], addr); |
277 |
|
|
|
278 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_CONNECT_REQUEST, 0, 0, 0, 0, content_len); |
279 |
|
✗ |
result = socop_driver_send_msg(&session->driver, &msg.base, msg.content); |
280 |
|
✗ |
if (result != SOCOP_OK) |
281 |
|
|
{ |
282 |
|
✗ |
return result; |
283 |
|
|
} |
284 |
|
✗ |
result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_CONNECT_RESPONSE, 0); |
285 |
|
✗ |
if (result != SOCOP_OK) |
286 |
|
|
{ |
287 |
|
✗ |
return result; |
288 |
|
|
} |
289 |
|
✗ |
if (msg.base.resource_id) |
290 |
|
|
{ |
291 |
|
✗ |
*ptr_sock = msg.base.resource_id; |
292 |
|
✗ |
return SOCOP_OK; |
293 |
|
|
} |
294 |
|
|
else |
295 |
|
|
{ |
296 |
|
✗ |
return SOCOP_ERROR_RESOURCEERROR; |
297 |
|
|
} |
298 |
|
|
} |
299 |
|
|
|
300 |
|
✗ |
int socop_client_bind(socop_client_t* session, socop_addr_t const* addr, socop_socket_t* ptr_sock) |
301 |
|
|
{ |
302 |
|
|
int result; |
303 |
|
|
socop_msg_buffer_t msg; |
304 |
|
✗ |
const socop_word_t content_len = serialize_addr((unsigned char*)&msg.content[0], addr); |
305 |
|
|
|
306 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_BIND_REQUEST, 0, 0, 0, 0, content_len); |
307 |
|
✗ |
result = socop_driver_send_msg(&session->driver, &msg.base, msg.content); |
308 |
|
✗ |
if (result != SOCOP_OK) |
309 |
|
|
{ |
310 |
|
✗ |
return result; |
311 |
|
|
} |
312 |
|
✗ |
result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_BIND_RESPONSE, 0); |
313 |
|
✗ |
if (result != SOCOP_OK) |
314 |
|
|
{ |
315 |
|
✗ |
return result; |
316 |
|
|
} |
317 |
|
✗ |
if (msg.base.resource_id) |
318 |
|
|
{ |
319 |
|
✗ |
*ptr_sock = msg.base.resource_id; |
320 |
|
✗ |
return SOCOP_OK; |
321 |
|
|
} |
322 |
|
|
else |
323 |
|
|
{ |
324 |
|
✗ |
return SOCOP_ERROR_RESOURCEERROR; |
325 |
|
|
} |
326 |
|
|
} |
327 |
|
|
|
328 |
|
✗ |
int socop_client_listen(socop_client_t* session, socop_addr_t const* addr, socop_socket_t* ptr_sock) |
329 |
|
|
{ |
330 |
|
|
int result; |
331 |
|
|
socop_msg_buffer_t msg; |
332 |
|
✗ |
const socop_word_t content_len = serialize_addr((unsigned char*)&msg.content[0], addr); |
333 |
|
|
|
334 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_LISTEN_REQUEST, 0, 0, 0, 0, content_len); |
335 |
|
✗ |
result = socop_driver_send_msg(&session->driver, &msg.base, msg.content); |
336 |
|
✗ |
if (result != SOCOP_OK) |
337 |
|
|
{ |
338 |
|
✗ |
return result; |
339 |
|
|
} |
340 |
|
✗ |
result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_LISTEN_RESPONSE, 0); |
341 |
|
✗ |
if (result != SOCOP_OK) |
342 |
|
|
{ |
343 |
|
✗ |
return result; |
344 |
|
|
} |
345 |
|
✗ |
if (msg.base.resource_id) |
346 |
|
|
{ |
347 |
|
✗ |
*ptr_sock = msg.base.resource_id; |
348 |
|
✗ |
return SOCOP_OK; |
349 |
|
|
} |
350 |
|
|
else |
351 |
|
|
{ |
352 |
|
✗ |
return SOCOP_ERROR_RESOURCEERROR; |
353 |
|
|
} |
354 |
|
|
} |
355 |
|
|
|
356 |
|
✗ |
int socop_client_accept(socop_client_t* session, socop_socket_t sock, socop_socket_t* ptr_sock) |
357 |
|
|
{ |
358 |
|
|
int result; |
359 |
|
|
socop_msg_buffer_t msg; |
360 |
|
|
|
361 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_ACCEPT_REQUEST, sock, 0, 0, 0, 0); |
362 |
|
✗ |
result = socop_driver_send_msg(&session->driver, &msg.base, NULL); |
363 |
|
✗ |
if (result != SOCOP_OK) |
364 |
|
|
{ |
365 |
|
✗ |
return result; |
366 |
|
|
} |
367 |
|
✗ |
result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_ACCEPT_RESPONSE, 0); |
368 |
|
✗ |
if (result != SOCOP_OK) |
369 |
|
|
{ |
370 |
|
✗ |
return result; |
371 |
|
|
} |
372 |
|
|
/* original server socket is returned as resource_param */ |
373 |
|
✗ |
if (msg.base.resource_param == sock) |
374 |
|
|
{ |
375 |
|
✗ |
*ptr_sock = msg.base.resource_id; |
376 |
|
✗ |
return SOCOP_OK; |
377 |
|
|
} |
378 |
|
|
else |
379 |
|
|
{ |
380 |
|
✗ |
return SOCOP_ERROR_RESOURCEERROR; |
381 |
|
|
} |
382 |
|
|
} |
383 |
|
|
|
384 |
|
|
|
385 |
|
✗ |
int socop_client_close(socop_client_t* session, socop_socket_t sock) |
386 |
|
|
{ |
387 |
|
|
int result; |
388 |
|
|
socop_msg_buffer_t msg; |
389 |
|
|
|
390 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_CLOSE_REQUEST, sock, 0, 0, 0, 0); |
391 |
|
✗ |
result = socop_driver_send_msg(&session->driver, &msg.base, NULL); |
392 |
|
✗ |
if (result != SOCOP_OK) |
393 |
|
|
{ |
394 |
|
✗ |
return result; |
395 |
|
|
} |
396 |
|
✗ |
return receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_CLOSE_RESPONSE, 0); |
397 |
|
|
} |
398 |
|
|
|
399 |
|
✗ |
int socop_client_receive(socop_client_t* session, socop_socket_t sock, |
400 |
|
|
void* buffer, unsigned bufferlen, unsigned* bufferused) |
401 |
|
|
{ |
402 |
|
|
int result; |
403 |
|
|
socop_msg_buffer_t msg; |
404 |
|
|
unsigned received_content; |
405 |
|
|
|
406 |
|
✗ |
if (bufferlen > SOCOP_MAX_CONTENT_LENGTH) |
407 |
|
|
{ |
408 |
|
✗ |
bufferlen = SOCOP_MAX_CONTENT_LENGTH; |
409 |
|
|
} |
410 |
|
|
|
411 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_RECV_REQUEST, sock, (socop_word_t)bufferlen, 0, 0, 0); |
412 |
|
✗ |
result = socop_driver_send_msg(&session->driver, &msg.base, NULL); |
413 |
|
✗ |
if (result != SOCOP_OK) |
414 |
|
|
{ |
415 |
|
✗ |
return result; |
416 |
|
|
} |
417 |
|
✗ |
result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_RECV_RESPONSE, sock); |
418 |
|
✗ |
if (result != SOCOP_OK) |
419 |
|
|
{ |
420 |
|
✗ |
return result; |
421 |
|
|
} |
422 |
|
✗ |
received_content = msg.base.msg_length - SOCOP_MSG_BASE_LENGTH; |
423 |
|
✗ |
if (received_content) |
424 |
|
|
{ |
425 |
|
✗ |
memcpy(buffer, msg.content, received_content); |
426 |
|
|
} |
427 |
|
✗ |
if (bufferused) |
428 |
|
|
{ |
429 |
|
✗ |
*bufferused = received_content; |
430 |
|
|
} |
431 |
|
✗ |
return SOCOP_OK; |
432 |
|
|
} |
433 |
|
|
|
434 |
|
✗ |
int socop_client_recv_from(socop_client_t* session, socop_socket_t sock, |
435 |
|
|
void* buffer, unsigned bufferlen, unsigned* bufferused, |
436 |
|
|
socop_addr_t* ptr_addr) |
437 |
|
|
{ |
438 |
|
|
int result; |
439 |
|
|
socop_msg_buffer_t msg; |
440 |
|
|
unsigned address_length; |
441 |
|
|
unsigned received_content; |
442 |
|
|
|
443 |
|
✗ |
if (bufferlen > (SOCOP_MAX_CONTENT_LENGTH - 8)) |
444 |
|
|
{ |
445 |
|
✗ |
bufferlen = SOCOP_MAX_CONTENT_LENGTH - 8; |
446 |
|
|
} |
447 |
|
|
|
448 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_RECVFROM_REQUEST, sock, (socop_word_t)bufferlen, 0, 0, 0); |
449 |
|
✗ |
result = socop_driver_send_msg(&session->driver, &msg.base, NULL); |
450 |
|
✗ |
if (result != SOCOP_OK) |
451 |
|
|
{ |
452 |
|
✗ |
return result; |
453 |
|
|
} |
454 |
|
✗ |
result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_RECVFROM_RESPONSE, sock); |
455 |
|
✗ |
if (result != SOCOP_OK) |
456 |
|
|
{ |
457 |
|
✗ |
return result; |
458 |
|
|
} |
459 |
|
|
|
460 |
|
✗ |
address_length = msg.base.resource_param; |
461 |
|
✗ |
if (address_length > (unsigned)(msg.base.msg_length - SOCOP_MSG_BASE_LENGTH)) |
462 |
|
|
{ |
463 |
|
✗ |
return SOCOP_ERROR_CORRUPTION; |
464 |
|
|
} |
465 |
|
|
|
466 |
|
✗ |
if (ptr_addr) |
467 |
|
|
{ |
468 |
|
✗ |
deserialize_addr(ptr_addr, (unsigned char const*)&msg.content[0]); |
469 |
|
|
} |
470 |
|
|
|
471 |
|
✗ |
received_content = msg.base.msg_length - address_length - SOCOP_MSG_BASE_LENGTH; |
472 |
|
✗ |
if (received_content) |
473 |
|
|
{ |
474 |
|
✗ |
memcpy(buffer, &msg.content[address_length], received_content); |
475 |
|
|
} |
476 |
|
✗ |
if (bufferused) |
477 |
|
|
{ |
478 |
|
✗ |
*bufferused = received_content; |
479 |
|
|
} |
480 |
|
✗ |
return SOCOP_OK; |
481 |
|
|
} |
482 |
|
|
|
483 |
|
✗ |
int socop_client_send(socop_client_t* session, socop_socket_t sock, |
484 |
|
|
void const* buffer, unsigned bufferlen, unsigned* bufferused) |
485 |
|
|
{ |
486 |
|
|
int result; |
487 |
|
|
socop_msg_buffer_t msg; |
488 |
|
|
|
489 |
|
✗ |
if (bufferlen > (SOCOP_MAX_CONTENT_LENGTH)) |
490 |
|
|
{ |
491 |
|
✗ |
bufferlen = SOCOP_MAX_CONTENT_LENGTH; |
492 |
|
|
} |
493 |
|
|
|
494 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_SEND_REQUEST, sock, 0, 0, 0, (socop_word_t)bufferlen); |
495 |
|
✗ |
result = socop_driver_send_msg(&session->driver, &msg.base, buffer); |
496 |
|
✗ |
if (result != SOCOP_OK) |
497 |
|
|
{ |
498 |
|
✗ |
return result; |
499 |
|
|
} |
500 |
|
✗ |
result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_SEND_RESPONSE, sock); |
501 |
|
✗ |
if (result != SOCOP_OK) |
502 |
|
|
{ |
503 |
|
✗ |
return result; |
504 |
|
|
} |
505 |
|
✗ |
if (bufferused) |
506 |
|
|
{ |
507 |
|
✗ |
*bufferused = msg.base.resource_param; |
508 |
|
|
} |
509 |
|
✗ |
return SOCOP_OK; |
510 |
|
|
} |
511 |
|
|
|
512 |
|
✗ |
int socop_client_sendto(socop_client_t* session, socop_socket_t sock, |
513 |
|
|
void const* buffer, unsigned bufferlen, unsigned* bufferused, |
514 |
|
|
socop_addr_t const* ptr_addr) |
515 |
|
|
{ |
516 |
|
|
int result; |
517 |
|
|
socop_msg_buffer_t msg; |
518 |
|
✗ |
const socop_word_t addr_length = serialize_addr((unsigned char*)&msg.content[0], ptr_addr); |
519 |
|
|
|
520 |
|
✗ |
if (bufferlen > (unsigned)(SOCOP_MAX_CONTENT_LENGTH - addr_length)) |
521 |
|
|
{ |
522 |
|
✗ |
bufferlen = SOCOP_MAX_CONTENT_LENGTH - addr_length; |
523 |
|
|
} |
524 |
|
✗ |
memcpy(&msg.content[addr_length], buffer, bufferlen); |
525 |
|
|
|
526 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_SENDTO_REQUEST, sock, addr_length, 0, 0, (socop_word_t)(bufferlen + addr_length)); |
527 |
|
✗ |
result = socop_driver_send_msg(&session->driver, &msg.base, msg.content); |
528 |
|
✗ |
if (result != SOCOP_OK) |
529 |
|
|
{ |
530 |
|
✗ |
return result; |
531 |
|
|
} |
532 |
|
✗ |
result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_SENDTO_RESPONSE, sock); |
533 |
|
✗ |
if (result != SOCOP_OK) |
534 |
|
|
{ |
535 |
|
✗ |
return result; |
536 |
|
|
} |
537 |
|
✗ |
if (bufferused) |
538 |
|
|
{ |
539 |
|
✗ |
*bufferused = msg.base.resource_param; |
540 |
|
|
} |
541 |
|
✗ |
return SOCOP_OK; |
542 |
|
|
} |
543 |
|
|
|
544 |
|
✗ |
int socop_client_shutdown(socop_client_t* session, socop_socket_t sock, unsigned target) |
545 |
|
|
{ |
546 |
|
|
int result; |
547 |
|
|
socop_msg_buffer_t msg; |
548 |
|
|
|
549 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_SHUTDOWN_REQUEST, sock, (socop_word_t)target, 0, 0, 0); |
550 |
|
✗ |
result = socop_driver_send_msg(&session->driver, &msg.base, msg.content); |
551 |
|
✗ |
if (result != SOCOP_OK) |
552 |
|
|
{ |
553 |
|
✗ |
return result; |
554 |
|
|
} |
555 |
|
✗ |
return receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_SHUTDOWN_RESPONSE, sock); |
556 |
|
|
} |
557 |
|
|
|
558 |
|
✗ |
int socop_client_select(socop_client_t* session, socop_socket_t sock, unsigned* flags, unsigned timeout_ms) |
559 |
|
|
{ |
560 |
|
|
int result; |
561 |
|
|
socop_msg_buffer_t msg; |
562 |
|
✗ |
const socop_word_t sel_flags = flags ? ((socop_word_t)*flags) : (SOCOP_MSG_FLAG_RECV | SOCOP_MSG_FLAG_SEND | SOCOP_MSG_FLAG_ERROR); |
563 |
|
|
socop_word_t timeout; |
564 |
|
|
|
565 |
|
✗ |
if (timeout_ms > (unsigned int)0xffff) |
566 |
|
|
{ |
567 |
|
✗ |
timeout = 0xffff; |
568 |
|
|
} |
569 |
|
|
else |
570 |
|
|
{ |
571 |
|
✗ |
timeout = (socop_word_t)timeout_ms; |
572 |
|
|
} |
573 |
|
|
|
574 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_SELECT_REQUEST, sock, sel_flags, timeout, 0, 0); |
575 |
|
✗ |
result = socop_driver_send_msg(&session->driver, &msg.base, msg.content); |
576 |
|
✗ |
if (result != SOCOP_OK) |
577 |
|
|
{ |
578 |
|
✗ |
return result; |
579 |
|
|
} |
580 |
|
✗ |
result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_SELECT_RESPONSE, sock); |
581 |
|
✗ |
if (result != SOCOP_OK) |
582 |
|
|
{ |
583 |
|
✗ |
return result; |
584 |
|
|
} |
585 |
|
✗ |
if (flags) |
586 |
|
|
{ |
587 |
|
✗ |
*flags = msg.base.resource_param; |
588 |
|
|
} |
589 |
|
✗ |
return SOCOP_OK; |
590 |
|
|
} |
591 |
|
|
|
592 |
|
✗ |
int socop_client_peer(socop_client_t* session, socop_socket_t sock, socop_addr_t* ptr_addr) |
593 |
|
|
{ |
594 |
|
|
int result; |
595 |
|
|
socop_msg_buffer_t msg; |
596 |
|
|
|
597 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_PEER_REQUEST, sock, 0, 0, 0, 0); |
598 |
|
✗ |
result = socop_driver_send_msg(&session->driver, &msg.base, 0); |
599 |
|
✗ |
if (result != SOCOP_OK) |
600 |
|
|
{ |
601 |
|
✗ |
return result; |
602 |
|
|
} |
603 |
|
✗ |
result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_PEER_RESPONSE, sock); |
604 |
|
✗ |
if (result != SOCOP_OK) |
605 |
|
|
{ |
606 |
|
✗ |
return result; |
607 |
|
|
} |
608 |
|
✗ |
deserialize_addr(ptr_addr, (unsigned char const*)&msg.content[0]); |
609 |
|
✗ |
return SOCOP_OK; |
610 |
|
|
} |
611 |
|
|
|
612 |
|
✗ |
int socop_client_ioctl(socop_client_t* session, socop_socket_t sock, unsigned option, void* data, unsigned datalen) |
613 |
|
|
{ |
614 |
|
|
int result; |
615 |
|
|
socop_msg_buffer_t msg; |
616 |
|
|
unsigned content_length; |
617 |
|
|
|
618 |
|
✗ |
if (datalen > SOCOP_MAX_CONTENT_LENGTH) |
619 |
|
|
{ |
620 |
|
✗ |
datalen = SOCOP_MAX_CONTENT_LENGTH; |
621 |
|
|
} |
622 |
|
✗ |
if ((datalen > 0) && !data) |
623 |
|
|
{ |
624 |
|
✗ |
return SOCOP_ERROR_INVALIDARG; |
625 |
|
|
} |
626 |
|
|
|
627 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_IOCTL_REQUEST, sock, (socop_word_t)option, 0, 0, (socop_word_t)datalen); |
628 |
|
✗ |
result = socop_driver_send_msg(&session->driver, &msg.base, data); |
629 |
|
✗ |
if (result != SOCOP_OK) |
630 |
|
|
{ |
631 |
|
✗ |
return result; |
632 |
|
|
} |
633 |
|
✗ |
result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_IOCTL_RESPONSE, sock); |
634 |
|
✗ |
if (result != SOCOP_OK) |
635 |
|
|
{ |
636 |
|
✗ |
return result; |
637 |
|
|
} |
638 |
|
✗ |
content_length = msg.base.msg_length - SOCOP_MSG_BASE_LENGTH; |
639 |
|
✗ |
if (content_length > datalen) |
640 |
|
|
{ |
641 |
|
✗ |
content_length = datalen; |
642 |
|
|
} |
643 |
|
✗ |
if (content_length > 0) |
644 |
|
|
{ |
645 |
|
✗ |
memcpy(data, msg.content, content_length); |
646 |
|
|
} |
647 |
|
✗ |
return SOCOP_OK; |
648 |
|
|
} |
649 |
|
|
|
650 |
|
|
|
651 |
|
|
|
652 |
|
|
|
653 |
|
✗ |
int socop_server_init(socop_server_t* server, void* server_param, |
654 |
|
|
socop_read_byte_t reader_func, void* reader_param, socop_write_byte_t writer_func, void* writer_param) |
655 |
|
|
{ |
656 |
|
✗ |
memset(server, 0, sizeof(socop_server_t)); |
657 |
|
✗ |
server->server_param = server_param; |
658 |
|
✗ |
server->driver.read_byte = reader_func; |
659 |
|
✗ |
server->driver.read_param = reader_param; |
660 |
|
✗ |
server->driver.write_byte = writer_func; |
661 |
|
✗ |
server->driver.write_param = writer_param; |
662 |
|
✗ |
return SOCOP_OK; |
663 |
|
|
} |
664 |
|
|
|
665 |
|
|
|
666 |
|
|
|
667 |
|
✗ |
int socop_server_chat_once(socop_server_t* server) |
668 |
|
|
{ |
669 |
|
|
int result; |
670 |
|
✗ |
socop_msg_buffer_t msg = { 0 }; |
671 |
|
✗ |
unsigned content_length = 0; |
672 |
|
✗ |
socop_addr_t addr = { 0 }; |
673 |
|
✗ |
socop_socket_t sock = 0; |
674 |
|
✗ |
unsigned flags = 0; |
675 |
|
|
|
676 |
|
✗ |
result = socop_driver_receive_msg(&server->driver, &msg); |
677 |
|
✗ |
if (SOCOP_OK != result) |
678 |
|
|
{ |
679 |
|
✗ |
return result; |
680 |
|
|
} |
681 |
|
|
|
682 |
|
✗ |
content_length = msg.base.msg_length - SOCOP_MSG_BASE_LENGTH; |
683 |
|
|
|
684 |
|
✗ |
switch (msg.base.msg_type) |
685 |
|
|
{ |
686 |
|
✗ |
case SOCOP_MSG_RESET_REQUEST: |
687 |
|
|
{ |
688 |
|
✗ |
if (!server->on_reset) |
689 |
|
|
{ |
690 |
|
✗ |
result = SOCOP_ERROR_NOTIMPL; |
691 |
|
|
} |
692 |
|
|
else |
693 |
|
|
{ |
694 |
|
✗ |
result = server->on_reset(server, msg.content, content_length); |
695 |
|
|
} |
696 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_RESET_RESPONSE, 0, 0, (socop_word_t)result, msg.base.user_param, 0); |
697 |
|
✗ |
result = SOCOP_OK; |
698 |
|
✗ |
break; |
699 |
|
|
} |
700 |
|
|
|
701 |
|
✗ |
case SOCOP_MSG_NET_STATUS_REQUEST: |
702 |
|
|
{ |
703 |
|
✗ |
if (!server->on_netstatus) |
704 |
|
|
{ |
705 |
|
✗ |
result = SOCOP_ERROR_NOTIMPL; |
706 |
|
|
} |
707 |
|
|
else |
708 |
|
|
{ |
709 |
|
✗ |
result = server->on_netstatus(server, NULL, 0); |
710 |
|
|
} |
711 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_NET_STATUS_RESPONSE, 0, 0, (socop_word_t)result, msg.base.user_param, 0); |
712 |
|
✗ |
result = SOCOP_OK; |
713 |
|
✗ |
break; |
714 |
|
|
} |
715 |
|
|
|
716 |
|
✗ |
case SOCOP_MSG_NET_START_REQUEST: |
717 |
|
|
{ |
718 |
|
✗ |
if (!server->on_netstart) |
719 |
|
|
{ |
720 |
|
✗ |
result = SOCOP_ERROR_NOTIMPL; |
721 |
|
|
} |
722 |
|
|
else |
723 |
|
|
{ |
724 |
|
✗ |
result = server->on_netstart(server, msg.content, content_length); |
725 |
|
|
} |
726 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_NET_STATUS_RESPONSE, 0, 0, (socop_word_t)result, msg.base.user_param, 0); |
727 |
|
✗ |
result = SOCOP_OK; |
728 |
|
✗ |
break; |
729 |
|
|
} |
730 |
|
✗ |
case SOCOP_MSG_NET_STOP_REQUEST: |
731 |
|
|
{ |
732 |
|
✗ |
if (!server->on_netstop) |
733 |
|
|
{ |
734 |
|
✗ |
result = SOCOP_ERROR_NOTIMPL; |
735 |
|
|
} |
736 |
|
|
else |
737 |
|
|
{ |
738 |
|
✗ |
result = server->on_netstop(server, NULL, 0); |
739 |
|
|
} |
740 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_NET_STATUS_RESPONSE, 0, 0, (socop_word_t)result, msg.base.user_param, 0); |
741 |
|
✗ |
result = SOCOP_OK; |
742 |
|
✗ |
break; |
743 |
|
|
} |
744 |
|
|
|
745 |
|
✗ |
case SOCOP_MSG_SOCK_CONNECT_REQUEST: |
746 |
|
|
{ |
747 |
|
✗ |
if (!server->on_connect) |
748 |
|
|
{ |
749 |
|
✗ |
result = SOCOP_ERROR_NOTIMPL; |
750 |
|
|
} |
751 |
|
|
else |
752 |
|
|
{ |
753 |
|
✗ |
deserialize_addr(&addr, (unsigned char const*)&msg.content[0]); |
754 |
|
✗ |
result = server->on_connect(server, &addr, &sock); |
755 |
|
|
} |
756 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_CONNECT_RESPONSE, sock, 0, (socop_word_t)result, msg.base.user_param, 0); |
757 |
|
✗ |
result = SOCOP_OK; |
758 |
|
✗ |
break; |
759 |
|
|
} |
760 |
|
|
|
761 |
|
✗ |
case SOCOP_MSG_SOCK_BIND_REQUEST: |
762 |
|
|
{ |
763 |
|
✗ |
if (!server->on_bind) |
764 |
|
|
{ |
765 |
|
✗ |
result = SOCOP_ERROR_NOTIMPL; |
766 |
|
|
} |
767 |
|
|
else |
768 |
|
|
{ |
769 |
|
✗ |
deserialize_addr(&addr, (unsigned char const*)&msg.content[0]); |
770 |
|
✗ |
result = server->on_bind(server, &addr, &sock); |
771 |
|
|
} |
772 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_BIND_RESPONSE, sock, 0, (socop_word_t)result, msg.base.user_param, 0); |
773 |
|
✗ |
result = SOCOP_OK; |
774 |
|
✗ |
break; |
775 |
|
|
} |
776 |
|
|
|
777 |
|
✗ |
case SOCOP_MSG_SOCK_LISTEN_REQUEST: |
778 |
|
|
{ |
779 |
|
✗ |
if (!server->on_bind) |
780 |
|
|
{ |
781 |
|
✗ |
result = SOCOP_ERROR_NOTIMPL; |
782 |
|
|
} |
783 |
|
|
else |
784 |
|
|
{ |
785 |
|
✗ |
deserialize_addr(&addr, (unsigned char const*)&msg.content[0]); |
786 |
|
✗ |
result = server->on_listen(server, &addr, &sock); |
787 |
|
|
} |
788 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_LISTEN_RESPONSE, sock, 0, (socop_word_t)result, msg.base.user_param, 0); |
789 |
|
✗ |
result = SOCOP_OK; |
790 |
|
✗ |
break; |
791 |
|
|
} |
792 |
|
|
|
793 |
|
✗ |
case SOCOP_MSG_SOCK_ACCEPT_REQUEST: |
794 |
|
|
{ |
795 |
|
✗ |
if (!server->on_accept) |
796 |
|
|
{ |
797 |
|
✗ |
result = SOCOP_ERROR_NOTIMPL; |
798 |
|
|
} |
799 |
|
|
else |
800 |
|
|
{ |
801 |
|
✗ |
result = server->on_accept(server, msg.base.resource_id, &sock); |
802 |
|
|
} |
803 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_ACCEPT_RESPONSE, sock, msg.base.resource_id, (socop_word_t)result, msg.base.user_param, 0); |
804 |
|
✗ |
result = SOCOP_OK; |
805 |
|
✗ |
break; |
806 |
|
|
} |
807 |
|
|
|
808 |
|
✗ |
case SOCOP_MSG_SOCK_CLOSE_REQUEST: |
809 |
|
|
{ |
810 |
|
✗ |
if (!server->on_close) |
811 |
|
|
{ |
812 |
|
✗ |
result = SOCOP_ERROR_NOTIMPL; |
813 |
|
|
} |
814 |
|
|
else |
815 |
|
|
{ |
816 |
|
✗ |
result = server->on_close(server, msg.base.resource_id, 0); |
817 |
|
|
} |
818 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_CLOSE_RESPONSE, msg.base.resource_id, 0, |
819 |
|
✗ |
(socop_word_t)result, msg.base.user_param, 0); |
820 |
|
✗ |
result = SOCOP_OK; |
821 |
|
✗ |
break; |
822 |
|
|
} |
823 |
|
|
|
824 |
|
✗ |
case SOCOP_MSG_SOCK_RECV_REQUEST: |
825 |
|
|
{ |
826 |
|
✗ |
if (!server->on_recv) |
827 |
|
|
{ |
828 |
|
✗ |
result = SOCOP_ERROR_NOTIMPL; |
829 |
|
|
} |
830 |
|
|
else |
831 |
|
|
{ |
832 |
|
✗ |
content_length = msg.base.resource_param; |
833 |
|
✗ |
if (content_length > SOCOP_MAX_CONTENT_LENGTH) |
834 |
|
|
{ |
835 |
|
✗ |
content_length = SOCOP_MAX_CONTENT_LENGTH; |
836 |
|
|
} |
837 |
|
✗ |
result = server->on_recv(server, msg.base.resource_id, msg.content, content_length, &content_length); |
838 |
|
✗ |
if (SOCOP_OK != result) |
839 |
|
|
{ |
840 |
|
✗ |
content_length = 0; |
841 |
|
|
} |
842 |
|
|
} |
843 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_RECV_RESPONSE, msg.base.resource_id, 0, |
844 |
|
✗ |
(socop_word_t)result, msg.base.user_param, (socop_word_t)content_length); |
845 |
|
✗ |
result = SOCOP_OK; |
846 |
|
✗ |
break; |
847 |
|
|
} |
848 |
|
|
|
849 |
|
✗ |
case SOCOP_MSG_SOCK_RECVFROM_REQUEST: |
850 |
|
|
{ |
851 |
|
✗ |
if (!server->on_recvfrom) |
852 |
|
|
{ |
853 |
|
✗ |
result = SOCOP_ERROR_NOTIMPL; |
854 |
|
|
} |
855 |
|
|
else |
856 |
|
|
{ |
857 |
|
✗ |
content_length = msg.base.resource_param; |
858 |
|
✗ |
if (content_length > SOCOP_MAX_CONTENT_LENGTH) |
859 |
|
|
{ |
860 |
|
✗ |
content_length = SOCOP_MAX_CONTENT_LENGTH; |
861 |
|
|
} |
862 |
|
✗ |
result = server->on_recvfrom(server, msg.base.resource_id, &msg.content[6], content_length, &content_length, &addr); |
863 |
|
✗ |
if (SOCOP_OK != result) |
864 |
|
|
{ |
865 |
|
✗ |
content_length = 0; |
866 |
|
✗ |
msg.base.resource_param = 0; |
867 |
|
|
} |
868 |
|
|
else |
869 |
|
|
{ |
870 |
|
✗ |
msg.base.resource_param = serialize_addr((unsigned char*)&msg.content[0], &addr); |
871 |
|
|
} |
872 |
|
|
} |
873 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_RECVFROM_RESPONSE, msg.base.resource_id, msg.base.resource_param, |
874 |
|
✗ |
(socop_word_t)result, msg.base.user_param, (socop_word_t)content_length); |
875 |
|
✗ |
result = SOCOP_OK; |
876 |
|
✗ |
break; |
877 |
|
|
} |
878 |
|
✗ |
case SOCOP_MSG_SOCK_SEND_REQUEST: |
879 |
|
|
{ |
880 |
|
✗ |
if (!server->on_send) |
881 |
|
|
{ |
882 |
|
✗ |
result = SOCOP_ERROR_NOTIMPL; |
883 |
|
|
} |
884 |
|
|
else |
885 |
|
|
{ |
886 |
|
✗ |
result = server->on_send(server, msg.base.resource_id, msg.content, content_length, &content_length); |
887 |
|
✗ |
if (SOCOP_OK != result) |
888 |
|
|
{ |
889 |
|
✗ |
content_length = 0; |
890 |
|
|
} |
891 |
|
|
} |
892 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_SEND_RESPONSE, msg.base.resource_id, (socop_word_t)content_length, |
893 |
|
✗ |
(socop_word_t)result, msg.base.user_param, 0); |
894 |
|
✗ |
result = SOCOP_OK; |
895 |
|
✗ |
break; |
896 |
|
|
} |
897 |
|
|
|
898 |
|
✗ |
case SOCOP_MSG_SOCK_SENDTO_REQUEST: |
899 |
|
|
{ |
900 |
|
✗ |
if (!server->on_sendto) |
901 |
|
|
{ |
902 |
|
✗ |
result = SOCOP_ERROR_NOTIMPL; |
903 |
|
|
} |
904 |
|
|
else |
905 |
|
|
{ |
906 |
|
✗ |
deserialize_addr(&addr, (unsigned char const*)&msg.content[0]); |
907 |
|
✗ |
result = server->on_sendto(server, msg.base.resource_id, &msg.content[6], content_length - 6, &content_length, &addr); |
908 |
|
✗ |
if (SOCOP_OK != result) |
909 |
|
|
{ |
910 |
|
✗ |
content_length = 0; |
911 |
|
|
} |
912 |
|
|
} |
913 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_SENDTO_RESPONSE, msg.base.resource_id, (socop_word_t)content_length, |
914 |
|
✗ |
(socop_word_t)result, msg.base.user_param, 0); |
915 |
|
✗ |
result = SOCOP_OK; |
916 |
|
✗ |
break; |
917 |
|
|
} |
918 |
|
|
|
919 |
|
✗ |
case SOCOP_MSG_SOCK_SHUTDOWN_REQUEST: |
920 |
|
|
{ |
921 |
|
✗ |
if (!server->on_shutdown) |
922 |
|
|
{ |
923 |
|
✗ |
result = SOCOP_ERROR_NOTIMPL; |
924 |
|
|
} |
925 |
|
|
else |
926 |
|
|
{ |
927 |
|
✗ |
result = server->on_shutdown(server, msg.base.resource_id, msg.base.resource_param); |
928 |
|
|
} |
929 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_SHUTDOWN_RESPONSE, msg.base.resource_id, 0, |
930 |
|
✗ |
(socop_word_t)result, msg.base.user_param, 0); |
931 |
|
✗ |
result = SOCOP_OK; |
932 |
|
✗ |
break; |
933 |
|
|
} |
934 |
|
|
|
935 |
|
✗ |
case SOCOP_MSG_SOCK_SELECT_REQUEST: |
936 |
|
|
{ |
937 |
|
✗ |
if (!server->on_select) |
938 |
|
|
{ |
939 |
|
✗ |
result = SOCOP_ERROR_NOTIMPL; |
940 |
|
|
} |
941 |
|
|
else |
942 |
|
|
{ |
943 |
|
✗ |
flags = msg.base.resource_param; |
944 |
|
✗ |
result = server->on_select(server, msg.base.resource_id, &flags); |
945 |
|
|
} |
946 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_SELECT_RESPONSE, msg.base.resource_id, (socop_word_t)flags, |
947 |
|
✗ |
(socop_word_t)result, msg.base.user_param, 0); |
948 |
|
✗ |
result = SOCOP_OK; |
949 |
|
✗ |
break; |
950 |
|
|
} |
951 |
|
|
|
952 |
|
✗ |
case SOCOP_MSG_SOCK_PEER_REQUEST: |
953 |
|
|
case SOCOP_MSG_SOCK_IOCTL_REQUEST: |
954 |
|
|
{ |
955 |
|
✗ |
result = SOCOP_ERROR_WRONGMESSAGE; |
956 |
|
✗ |
break; |
957 |
|
|
} |
958 |
|
|
|
959 |
|
✗ |
default: |
960 |
|
|
{ |
961 |
|
✗ |
result = SOCOP_ERROR_WRONGMESSAGE; |
962 |
|
✗ |
break; |
963 |
|
|
} |
964 |
|
|
} |
965 |
|
|
|
966 |
|
✗ |
if (SOCOP_OK != result) |
967 |
|
|
{ |
968 |
|
✗ |
init_msg_base(&msg.base, SOCOP_MSG_SOCK_UNKNOWN, msg.base.resource_id, msg.base.resource_param, |
969 |
|
✗ |
(socop_word_t)result, msg.base.user_param, 0); |
970 |
|
|
} |
971 |
|
|
|
972 |
|
✗ |
return socop_driver_send_msg(&server->driver, &msg.base, msg.content); |
973 |
|
|
} |
974 |
|
|
|
975 |
|
|
|