gwenhywfar 5.10.1
syncio_socket.c
Go to the documentation of this file.
1/***************************************************************************
2 begin : Tue Apr 27 2010
3 copyright : (C) 2010 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * *
8 * This library is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU Lesser General Public *
10 * License as published by the Free Software Foundation; either *
11 * version 2.1 of the License, or (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16 * Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this library; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21 * MA 02111-1307 USA *
22 * *
23 ***************************************************************************/
24
25#ifdef HAVE_CONFIG_H
26# include <config.h>
27#endif
28
29#define DISABLE_DEBUGLOG
30
31
32
33#include "syncio_socket_p.h"
34#include "i18n_l.h"
35
36#include <gwenhywfar/misc.h>
37#include <gwenhywfar/debug.h>
38#include <gwenhywfar/gui.h>
39#include <gwenhywfar/text.h>
40
41#include <assert.h>
42#include <errno.h>
43#include <string.h>
44
45
46#define GWEN_SYNCIO_SOCKET_READ_TIMEOUT 60000
47#define GWEN_SYNCIO_SOCKET_WRITE_TIMEOUT 60000
48
49
50GWEN_INHERIT(GWEN_SYNCIO, GWEN_SYNCIO_SOCKET)
51
52
53
55{
56 GWEN_SYNCIO *sio;
57 GWEN_SYNCIO_SOCKET *xio;
58
60 GWEN_NEW_OBJECT(GWEN_SYNCIO_SOCKET, xio);
61 GWEN_INHERIT_SETDATA(GWEN_SYNCIO, GWEN_SYNCIO_SOCKET, sio, xio, GWEN_SyncIo_Socket_FreeData);
62
67
68 xio->socketType=sockType;
69 xio->addressFamily=addressFamily;
70
71 return sio;
72}
73
74
75
77{
78 GWEN_SYNCIO *sio;
79 GWEN_SYNCIO_SOCKET *xio;
80
82 GWEN_NEW_OBJECT(GWEN_SYNCIO_SOCKET, xio);
83 GWEN_INHERIT_SETDATA(GWEN_SYNCIO, GWEN_SYNCIO_SOCKET, sio, xio, GWEN_SyncIo_Socket_FreeData);
84
89
90 xio->socketType=GWEN_Socket_GetSocketType(socket);
91 xio->socket=socket;
93
94 return sio;
95}
96
97
98
100{
101 GWEN_SYNCIO_SOCKET *xio;
102
103 xio=(GWEN_SYNCIO_SOCKET *) p;
104 free(xio->address);
105 GWEN_Socket_free(xio->socket);
106 GWEN_FREE_OBJECT(xio);
107}
108
109
110
112{
113 GWEN_SYNCIO_SOCKET *xio;
114
115 assert(sio);
116 xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_SOCKET, sio);
117 assert(xio);
118
119 return xio->address;
120}
121
122
123
125{
126 GWEN_SYNCIO_SOCKET *xio;
127
128 assert(sio);
129 xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_SOCKET, sio);
130 assert(xio);
131
132 free(xio->address);
133 if (s)
134 xio->address=strdup(s);
135 else
136 xio->address=NULL;
137}
138
139
140
142{
143 GWEN_SYNCIO_SOCKET *xio;
144
145 assert(sio);
146 xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_SOCKET, sio);
147 assert(xio);
148
149 return xio->port;
150}
151
152
153
155{
156 GWEN_SYNCIO_SOCKET *xio;
157
158 assert(sio);
159 xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_SOCKET, sio);
160 assert(xio);
161
162 xio->port=i;
163}
164
165
166
168{
169 GWEN_SYNCIO_SOCKET *xio;
170 GWEN_SOCKET *sk;
171 GWEN_INETADDRESS *addr;
172 int rv;
173
174 assert(sio);
175 xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_SOCKET, sio);
176 assert(xio);
177
179 /* already connected */
180 return 0;
181
183 /* passive, can't connect */
184 DBG_ERROR(GWEN_LOGDOMAIN, "Passive socket, can't connect");
185 return GWEN_ERROR_INVALID;
186 }
187
188 sk=GWEN_Socket_new(xio->socketType);
189 rv=GWEN_Socket_Open(sk);
190 if (rv<0) {
191 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
194 I18N("Error setting up socket: %d"),
195 rv);
197 return rv;
198 }
199 addr=GWEN_InetAddr_new(xio->addressFamily);
200
201 rv=GWEN_InetAddr_SetAddress(addr, xio->address);
202 if (rv<0) {
205 I18N("Resolving hostname \"%s\" ..."),
206 xio->address);
207 rv=GWEN_InetAddr_SetName(addr, xio->address);
208 if (rv<0) {
211 I18N("Unknown hostname \"%s\""),
212 xio->address);
213 GWEN_InetAddr_free(addr);
215 return rv;
216 }
217 else {
218 char addrBuf[256];
219
220 rv=GWEN_InetAddr_GetAddress(addr, addrBuf, sizeof(addrBuf)-1);
221 addrBuf[sizeof(addrBuf)-1]=0;
222 if (rv<0) {
223 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
224 }
225 else
228 I18N("IP address is \"%s\""),
229 addrBuf);
230 }
231 }
232 GWEN_InetAddr_SetPort(addr, xio->port);
233
234 /* connect */
237 I18N("Connecting to \"%s\""),
238 xio->address);
239 rv=GWEN_Socket_Connect(sk, addr);
240 GWEN_InetAddr_free(addr);
241 if (rv<0) {
244 I18N("Error connecting to \"%s\": %s"),
245 xio->address,
246 strerror(errno));
248 return rv;
249 }
250
251 /* done */
252 xio->socket=sk;
254 DBG_INFO(GWEN_LOGDOMAIN, "Connected to \"%s\"", xio->address);
257 I18N("Connected to \"%s\""),
258 xio->address);
259 return 0;
260}
261
262
263
265{
266 GWEN_SYNCIO_SOCKET *xio;
267
268 assert(sio);
269 xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_SOCKET, sio);
270 assert(xio);
271
272 if (xio->socket) {
273 GWEN_Socket_Close(xio->socket);
274 GWEN_Socket_free(xio->socket);
275 xio->socket=NULL;
277 DBG_INFO(GWEN_LOGDOMAIN, "Disconnected socket");
278 }
279
280 return 0;
281}
282
283
284
286 uint8_t *buffer,
287 uint32_t size)
288{
289 GWEN_SYNCIO_SOCKET *xio;
290 int rv;
291 int i;
292
293 assert(sio);
294 xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_SOCKET, sio);
295 assert(xio);
296
297 if (size==0) {
298 DBG_ERROR(GWEN_LOGDOMAIN, "Read size is zero");
299 return GWEN_ERROR_INVALID;
300 }
301
303 /* not connected */
304 DBG_ERROR(GWEN_LOGDOMAIN, "Socket not connected (%d)",
307 }
308
309 if (xio->socket==NULL) {
310 DBG_ERROR(GWEN_LOGDOMAIN, "No socket");
311 return GWEN_ERROR_INTERNAL;
312 }
313
314 /* check whether there is data available */
315 do {
316 rv=GWEN_Socket_WaitForRead(xio->socket, 0);
317 }
318 while (rv==GWEN_ERROR_INTERRUPTED);
319
320
321 /* nothing to read immediately, wait for data availability */
322 if (rv==GWEN_ERROR_TIMEOUT) {
324
326 GWEN_Socket_List2_PushBack(sl, xio->socket);
327
328 do {
330 }
331 while (rv==GWEN_ERROR_INTERRUPTED);
332
334 if (rv<0) {
335 if (rv==GWEN_ERROR_TIMEOUT) {
336 DBG_ERROR(GWEN_LOGDOMAIN, "timeout (%d)", rv);
337 return rv;
338 }
339 else {
340 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
341 return rv;
342 }
343 }
344 }
345
346 i=size;
347 rv=GWEN_Socket_Read(xio->socket, (char *) buffer, &i);
348 if (rv<0) {
349 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
350 return rv;
351 }
352
353#if 0
354 DBG_ERROR(0, "Received this:");
355 GWEN_Text_DumpString((const char *) buffer, i, stderr, 2);
356#endif
357
358 return i;
359}
360
361
362
364 const uint8_t *buffer,
365 uint32_t size)
366{
367 GWEN_SYNCIO_SOCKET *xio;
368 int rv;
369 int i;
370
371 assert(sio);
372 xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_SOCKET, sio);
373 assert(xio);
374
376 /* not connected */
377 DBG_ERROR(GWEN_LOGDOMAIN, "Socket not connected");
379 }
380
381 if (xio->socket==NULL) {
382 DBG_ERROR(GWEN_LOGDOMAIN, "No socket");
383 return GWEN_ERROR_INTERNAL;
384 }
385
386 /* check whether the socket is writeable */
387 do {
388 rv=GWEN_Socket_WaitForWrite(xio->socket, 0);
389 }
390 while (rv==GWEN_ERROR_INTERRUPTED);
391
392 if (rv==GWEN_ERROR_TIMEOUT) {
394
396 GWEN_Socket_List2_PushBack(sl, xio->socket);
397
398 do {
400 }
401 while (rv==GWEN_ERROR_INTERRUPTED);
402
403 if (rv<0) {
404 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
406 return rv;
407 }
409 }
410
411 i=size;
412 rv=GWEN_Socket_Write(xio->socket, (const char *) buffer, &i);
413 if (rv<0) {
414 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
415 return rv;
416 }
417
418#if 0
419 DBG_ERROR(0, "Written this:");
420 GWEN_Text_DumpString((const char *) buffer, i, stderr, 2);
421#endif
422
423 return i;
424}
425
426
427
428
429
#define NULL
Definition: binreloc.c:300
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
#define I18N(m)
Definition: error.c:42
#define GWEN_ERROR_INTERNAL
Definition: error.h:125
#define GWEN_ERROR_TIMEOUT
Definition: error.h:71
#define GWEN_ERROR_INVALID
Definition: error.h:67
#define GWEN_ERROR_NOT_CONNECTED
Definition: error.h:120
#define GWEN_ERROR_INTERRUPTED
Definition: error.h:74
GWEN_SOCKETTYPE
Definition: inetsocket.h:79
GWENHYWFAR_API void GWEN_Socket_free(GWEN_SOCKET *sp)
GWENHYWFAR_API int GWEN_Socket_Close(GWEN_SOCKET *sp)
GWENHYWFAR_API int GWEN_Socket_Open(GWEN_SOCKET *sp)
GWENHYWFAR_API GWEN_SOCKET * GWEN_Socket_new(GWEN_SOCKETTYPE socketType)
GWENHYWFAR_API int GWEN_Socket_Read(GWEN_SOCKET *sp, char *buffer, int *bsize)
GWENHYWFAR_API GWEN_SOCKETTYPE GWEN_Socket_GetSocketType(GWEN_SOCKET *sp)
GWENHYWFAR_API int GWEN_Socket_Connect(GWEN_SOCKET *sp, const GWEN_INETADDRESS *addr)
GWENHYWFAR_API int GWEN_Socket_WaitForRead(GWEN_SOCKET *sp, int timeout)
GWENHYWFAR_API int GWEN_Socket_WaitForWrite(GWEN_SOCKET *sp, int timeout)
GWENHYWFAR_API int GWEN_Socket_Write(GWEN_SOCKET *sp, const char *buffer, int *bsize)
GWENHYWFAR_API int GWEN_Gui_WaitForSockets(GWEN_SOCKET_LIST2 *readSockets, GWEN_SOCKET_LIST2 *writeSockets, uint32_t guiid, int msecs)
Definition: gui_virtual.c:667
GWENHYWFAR_API int GWEN_Gui_ProgressLog2(uint32_t id, GWEN_LOGGER_LEVEL level, const char *text,...)
Definition: gui_virtual.c:458
#define GWEN_UNUSED
#define GWENHYWFAR_CB
Definition: gwenhywfarapi.h:89
GWENHYWFAR_API void GWEN_InetAddr_free(GWEN_INETADDRESS *ia)
struct GWEN_INETADDRESSSTRUCT GWEN_INETADDRESS
Definition: inetaddr.h:95
GWENHYWFAR_API int GWEN_InetAddr_GetAddress(const GWEN_INETADDRESS *ia, char *buffer, unsigned int bsize)
GWENHYWFAR_API int GWEN_InetAddr_SetPort(GWEN_INETADDRESS *ia, int port)
GWENHYWFAR_API GWEN_INETADDRESS * GWEN_InetAddr_new(GWEN_AddressFamily af)
GWEN_AddressFamily
Definition: inetaddr.h:83
GWENHYWFAR_API int GWEN_InetAddr_SetAddress(GWEN_INETADDRESS *ia, const char *addr)
GWENHYWFAR_API int GWEN_InetAddr_SetName(GWEN_INETADDRESS *ia, const char *name)
struct GWEN_SOCKET GWEN_SOCKET
Definition: inetsocket.h:40
#define GWEN_INHERIT_SETDATA(bt, t, element, data, fn)
Definition: inherit.h:292
#define GWEN_INHERIT(bt, t)
Definition: inherit.h:264
#define GWEN_INHERIT_GETDATA(bt, t, element)
Definition: inherit.h:271
struct GWEN_SOCKET_LIST2 GWEN_SOCKET_LIST2
Definition: listdoc.h:4030
void GWEN_Socket_List2_free(GWEN_SOCKET_LIST2 *l)
GWEN_SOCKET_LIST2 * GWEN_Socket_List2_new()
void GWEN_Socket_List2_PushBack(GWEN_SOCKET_LIST2 *l, GWEN_SOCKET *p)
#define GWEN_LOGDOMAIN
Definition: logger.h:35
@ GWEN_LoggerLevel_Debug
Definition: logger.h:72
@ GWEN_LoggerLevel_Error
Definition: logger.h:68
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
uint32_t GWEN_SyncIo_GetFlags(const GWEN_SYNCIO *sio)
Definition: syncio.c:161
GWEN_SYNCIO * GWEN_SyncIo_new(const char *typeName, GWEN_SYNCIO *baseIo)
Definition: syncio.c:51
GWEN_SYNCIO_READ_FN GWEN_SyncIo_SetReadFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_READ_FN fn)
Definition: syncio.c:291
GWEN_SYNCIO_DISCONNECT_FN GWEN_SyncIo_SetDisconnectFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_DISCONNECT_FN fn)
Definition: syncio.c:265
GWEN_SYNCIO_WRITE_FN GWEN_SyncIo_SetWriteFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_WRITE_FN fn)
Definition: syncio.c:304
GWEN_SYNCIO_STATUS GWEN_SyncIo_GetStatus(const GWEN_SYNCIO *sio)
Definition: syncio.c:197
GWEN_SYNCIO_CONNECT_FN GWEN_SyncIo_SetConnectFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_CONNECT_FN fn)
Definition: syncio.c:252
void GWEN_SyncIo_SetStatus(GWEN_SYNCIO *sio, GWEN_SYNCIO_STATUS st)
Definition: syncio.c:206
#define GWEN_SYNCIO_FLAGS_PASSIVE
Definition: syncio.h:57
struct GWEN_SYNCIO GWEN_SYNCIO
Definition: syncio.h:40
@ GWEN_SyncIo_Status_Connected
Definition: syncio.h:49
@ GWEN_SyncIo_Status_Disconnected
Definition: syncio.h:48
GWEN_SYNCIO * GWEN_SyncIo_Socket_TakeOver(GWEN_SOCKET *socket)
Definition: syncio_socket.c:76
const char * GWEN_SyncIo_Socket_GetAddress(const GWEN_SYNCIO *sio)
void GWEN_SyncIo_Socket_SetPort(GWEN_SYNCIO *sio, int i)
void GWENHYWFAR_CB GWEN_SyncIo_Socket_FreeData(GWEN_UNUSED void *bp, void *p)
Definition: syncio_socket.c:99
GWEN_SYNCIO * GWEN_SyncIo_Socket_new(GWEN_SOCKETTYPE sockType, GWEN_AddressFamily addressFamily)
Definition: syncio_socket.c:54
int GWENHYWFAR_CB GWEN_SyncIo_Socket_Disconnect(GWEN_SYNCIO *sio)
int GWENHYWFAR_CB GWEN_SyncIo_Socket_Write(GWEN_SYNCIO *sio, const uint8_t *buffer, uint32_t size)
#define GWEN_SYNCIO_SOCKET_READ_TIMEOUT
Definition: syncio_socket.c:46
#define GWEN_SYNCIO_SOCKET_WRITE_TIMEOUT
Definition: syncio_socket.c:47
void GWEN_SyncIo_Socket_SetAddress(GWEN_SYNCIO *sio, const char *s)
int GWENHYWFAR_CB GWEN_SyncIo_Socket_Read(GWEN_SYNCIO *sio, uint8_t *buffer, uint32_t size)
int GWENHYWFAR_CB GWEN_SyncIo_Socket_Connect(GWEN_SYNCIO *sio)
int GWEN_SyncIo_Socket_GetPort(const GWEN_SYNCIO *sio)
#define GWEN_SYNCIO_SOCKET_TYPE
Definition: syncio_socket.h:33
void GWEN_Text_DumpString(const char *s, unsigned int l, unsigned int insert)
Definition: text.c:1283