FreeCalypso > hg > leo2moko-debug
comparison gpf/tst/DRV/socket.c @ 0:509db1a7b7b8
initial import: leo2moko-r1
| author | Space Falcon <falcon@ivan.Harhan.ORG> |
|---|---|
| date | Mon, 01 Jun 2015 03:24:05 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:509db1a7b7b8 |
|---|---|
| 1 /* | |
| 2 +------------------------------------------------------------------------------ | |
| 3 | File: socket.c | |
| 4 +------------------------------------------------------------------------------ | |
| 5 | Copyright 2002 Texas Instruments Berlin, AG | |
| 6 | All rights reserved. | |
| 7 | | |
| 8 | This file is confidential and a trade secret of Texas | |
| 9 | Instruments Berlin, AG | |
| 10 | The receipt of or possession of this file does not convey | |
| 11 | any rights to reproduce or disclose its contents or to | |
| 12 | manufacture, use, or sell anything it may describe, in | |
| 13 | whole, or in part, without the specific written consent of | |
| 14 | Texas Instruments Berlin, AG. | |
| 15 +----------------------------------------------------------------------------- | |
| 16 | Purpose : This Modul contains the socket driver adaptation | |
| 17 +----------------------------------------------------------------------------- | |
| 18 */ | |
| 19 | |
| 20 #ifdef _VXWORKS_ | |
| 21 #define GNU_COMPILER | |
| 22 #endif | |
| 23 | |
| 24 #undef SOCK_TRACE | |
| 25 | |
| 26 #undef SOCKET_DEBUG | |
| 27 | |
| 28 /*==== INCLUDES =============================================================*/ | |
| 29 | |
| 30 #if defined _NUCLEUS_ || defined _TOOLS_ /* socket-driver running on windows OS */ | |
| 31 /*lint -e717 suppress info do...while(0); */ | |
| 32 /*lint -esym(550,rc) suppress info not accessed */ | |
| 33 /*lint -e813, suppress Info 813: auto variable has size > 100 -> uncritical in this context */ | |
| 34 /*lint -e801, suppress Info 801: Use of goto is deprecated */ | |
| 35 #include <windows.h> | |
| 36 #include <winsock.h> | |
| 37 #include <stdio.h> | |
| 38 #ifdef SOCK_TRACE | |
| 39 #include <stdio.h> | |
| 40 #include <fcntl.h> | |
| 41 #include <io.h> | |
| 42 #endif /* SOCK_TRACE */ | |
| 43 #endif /* #ifdef _NUCLEUS_ */ | |
| 44 | |
| 45 #ifdef _PSOS_ /* socket-driver running on pSOS */ | |
| 46 #define _PNA_30_BACK | |
| 47 #include <psos.h> | |
| 48 #include "bsp.h" | |
| 49 #include <pna.h> | |
| 50 #include <prepc.h> | |
| 51 #include <rescfg.h> | |
| 52 #endif /* #ifdef _PSOS_ */ | |
| 53 | |
| 54 #ifdef _VXWORKS_ | |
| 55 #include "vxWorks.h" | |
| 56 #include "sockLib.h" | |
| 57 #include "inetLib.h" | |
| 58 #include "ioLib.h" | |
| 59 #include "selectLib.h" | |
| 60 #include "errnoLib.h" | |
| 61 #include "logLib.h" | |
| 62 /* undefine the MALLOC and FREE of VxWorks to avoid warnings */ | |
| 63 #undef MALLOC | |
| 64 #undef FREE | |
| 65 #endif /* _VXWORKS_ */ | |
| 66 | |
| 67 /* More operating systems go here */ | |
| 68 | |
| 69 #ifdef _LINUX_ | |
| 70 #include <sys/types.h> | |
| 71 #include <sys/socket.h> | |
| 72 #include <netinet/in.h> | |
| 73 #include <netinet/tcp.h> | |
| 74 #include <sys/ioctl.h> | |
| 75 #include <errno.h> | |
| 76 #include <netdb.h> | |
| 77 #endif | |
| 78 | |
| 79 #ifdef _SOLARIS_ | |
| 80 #include <sys/types.h> | |
| 81 #include <sys/socket.h> | |
| 82 #include <netinet/in.h> | |
| 83 #include <netinet/tcp.h> | |
| 84 #include <sys/ioctl.h> | |
| 85 #include <errno.h> | |
| 86 #include <netdb.h> | |
| 87 #include <sys/filio.h> | |
| 88 #endif | |
| 89 | |
| 90 #ifndef OLD_FRAME | |
| 91 #include "typedefs.h" | |
| 92 #include "os.h" | |
| 93 #endif | |
| 94 | |
| 95 #include "socket.h" | |
| 96 #include "tools.h" | |
| 97 #include "vsi.h" | |
| 98 #include "drvconf.h" | |
| 99 #include "tstheader.h" | |
| 100 | |
| 101 /*==== DEFINITIONS ==========================================================*/ | |
| 102 | |
| 103 #define MAX_PENDING_CONNECTS 5 /* The backlog allowed for listen() */ | |
| 104 #define SEND_TIMEOUTUSEC 500 /* minimal timeout value for sending*/ | |
| 105 #define INVALID_HANDLE NULL | |
| 106 #define INVALID_SIGNALTYPE 0 | |
| 107 #define NO_FLAGS_SET 0 /* Used with recv()/send() */ | |
| 108 #define MAX_ETH_LEN (1500-40) /* Maximum size of a Ethernet packet without IP headers */ | |
| 109 #define WRBUF_LEN 2048 | |
| 110 | |
| 111 #define ALLOWED_SOCKET_SIGNALS (DRV_SIGTYPE_READ|DRV_SIGTYPE_CONNECT|DRV_SIGTYPE_DISCONNECT) | |
| 112 | |
| 113 #if defined _NUCLEUS_ || defined _TOOLS_ | |
| 114 typedef ULONG SIZETYPE; | |
| 115 #define GETTIME(t) (t = GetTickCount()) | |
| 116 #define GETREADSIZE(sok,psiz) ioctlsocket(sok, FIONREAD,(ULONG*)psiz) | |
| 117 #define READ_SOCKET(s,b,l) recv((s),(b),(int)(l),NO_FLAGS_SET) | |
| 118 #define WRITE_SOCKET(s,b,l) send((s),(const char*)(b),(l),NO_FLAGS_SET) | |
| 119 #define CLOSE_SOCKET(s) closesocket(s) | |
| 120 #endif /* #ifdef _NUCLEUS_ */ | |
| 121 | |
| 122 #ifdef _PSOS_ | |
| 123 typedef int SOCKET; | |
| 124 typedef int SIZETYPE; | |
| 125 typedef struct hostent HOSTENT; | |
| 126 #define h_addr h_addr_list[0] | |
| 127 typedef HOSTENT * PHOSTENT; | |
| 128 #define FAR /**/ | |
| 129 #define SOCKADDR_IN struct sockaddr_in | |
| 130 #define SOCKET_ERROR (-1) | |
| 131 #define INVALID_SOCKET (-1) | |
| 132 #define GETTIME(t) os_GetTime (0, &(t)) | |
| 133 #define GETREADSIZE(sok,psiz) ioctl(sok, FIOREAD,(char*)psiz) | |
| 134 #define READ_SOCKET(s,b,l) recv((s),(b),(int)(l),NO_FLAGS_SET) | |
| 135 #define WRITE_SOCKET(s,b,l) send((s),(char *)(b),(int)(l),NO_FLAGS_SET) | |
| 136 #define CLOSE_SOCKET(s) close(s) | |
| 137 #endif /* #ifdef _PSOS_ */ | |
| 138 | |
| 139 #ifdef _VXWORKS_ | |
| 140 #define SOCKADDR_IN struct sockaddr_in | |
| 141 #define FAR /* nil */ | |
| 142 #define SOCKET_ERROR ERROR | |
| 143 #define INVALID_SOCKET ERROR | |
| 144 typedef int SOCKET; | |
| 145 typedef int SIZETYPE; | |
| 146 #define GETTIME(t) os_GetTime (0, &(t)) | |
| 147 #define GETREADSIZE(sok,psiz) ioctl(sok, FIONREAD, (int)psiz) | |
| 148 #define READ_SOCKET(s,b,l) recv((s), (b), (int)(l), NO_FLAGS_SET) | |
| 149 #define WRITE_SOCKET(s,b,l) send((s), (char *)(b), (int)(l), NO_FLAGS_SET) | |
| 150 #define CLOSE_SOCKET(s) close(s) | |
| 151 #endif /* _VXWORKS_ */ | |
| 152 | |
| 153 #if defined (_LINUX_) || defined (_SOLARIS_) | |
| 154 #define SOCKADDR_IN struct sockaddr_in | |
| 155 #define FAR /* nil */ | |
| 156 #define SOCKET_ERROR (-1) | |
| 157 #define INVALID_SOCKET (-1) | |
| 158 typedef int SIZETYPE; | |
| 159 #define GETTIME(t) os_GetTime (0, &(t)) | |
| 160 #define GETREADSIZE(sok,psiz) ioctl(sok, FIONREAD, (int)psiz) | |
| 161 #define READ_SOCKET(s,b,l) recv((s), (b), (int)(l), NO_FLAGS_SET) | |
| 162 #define WRITE_SOCKET(s,b,l) send((s), (char *)(b), (int)(l), NO_FLAGS_SET) | |
| 163 #define CLOSE_SOCKET(s) close(s) | |
| 164 #endif /* _VXWORKS_ */ | |
| 165 | |
| 166 #define PORT_NO 6392 | |
| 167 #define TX_BUFFER_SIZE 8192 | |
| 168 #define RX_BUFFER_SIZE 8192 | |
| 169 #define TX_TIMEOUT_MSEC 10000 | |
| 170 #define RX_TIMEOUT_MSEC 10000 | |
| 171 | |
| 172 #ifdef _VXWORKS_ | |
| 173 #define SOCKET_PRIO 115 | |
| 174 #define SOCKET_STACK 8192 | |
| 175 #elif defined _PSOS_ | |
| 176 #define SOCKET_PRIO 110 | |
| 177 #define SOCKET_STACK 1024 | |
| 178 #elif defined _TOOLS_ | |
| 179 #define SOCKET_PRIO 1 | |
| 180 #define SOCKET_STACK 1024 | |
| 181 #else | |
| 182 #define SOCKET_PRIO 1 | |
| 183 #define SOCKET_STACK 1024 | |
| 184 #endif | |
| 185 | |
| 186 #define TI_MODE 0x0001 | |
| 187 | |
| 188 /*==== TYPES ================================================================*/ | |
| 189 typedef enum | |
| 190 { | |
| 191 SST_PL0, /* 0 bytes of packet length read*/ | |
| 192 SST_PL1, /* 1 bytes of packet length read*/ | |
| 193 SST_DATA0, /* 0 bytes of data read*/ | |
| 194 SST_DATAx /* not all data read */ | |
| 195 } T_SOCK_STATE; | |
| 196 | |
| 197 typedef struct | |
| 198 { | |
| 199 USHORT Connect; | |
| 200 SOCKET Listener; | |
| 201 SOCKET Socket; | |
| 202 USHORT EnabledSignals; | |
| 203 OS_HANDLE ThreadID ; | |
| 204 USHORT SocketHandle; | |
| 205 T_DRV_CB_FUNC Callback; | |
| 206 } Client_Type; | |
| 207 | |
| 208 /*==== EXTERNALS ============================================================*/ | |
| 209 EXTERN BOOL socket_flush; | |
| 210 | |
| 211 /*==== LOCAL VARS ===========================================================*/ | |
| 212 | |
| 213 LOCAL socket_DCB_Type L_DCB ; | |
| 214 LOCAL Client_Type L_ClientData ; | |
| 215 LOCAL BOOL L_ThreadActive ; | |
| 216 LOCAL T_DRV_SIGNAL SocketSignal; | |
| 217 LOCAL UBYTE wrbuf[WRBUF_LEN+2]; | |
| 218 LOCAL UBYTE *wrbuf_pos = wrbuf; | |
| 219 T_SOCK_STATE sock_state = SST_PL0; | |
| 220 | |
| 221 #ifdef SOCK_TRACE | |
| 222 ULONG fh_sock = -1; | |
| 223 LOCAL char stbuf[80]; | |
| 224 #endif | |
| 225 | |
| 226 LOCAL BOOL isLittleEndian = TRUE; | |
| 227 int tst_socket; /* for psos */ | |
| 228 int tst_socket_initialized; /* flag for pSOS */ | |
| 229 int tst_socket_in_TxLen; /* for pSOS */ | |
| 230 | |
| 231 | |
| 232 /*==== DIAGNOSTICS ==========================================================*/ | |
| 233 | |
| 234 #ifdef SOCKET_DEBUG | |
| 235 #include <STDIO.H> | |
| 236 static char *logfile = "socket.log"; | |
| 237 static char *bufferfullfile = "bufferfull.log"; | |
| 238 static char *inprocessfile = "inprogress.log"; | |
| 239 static char *noconnectfile1 = "noconnect1.log"; | |
| 240 static char *noconnectfile2 = "noconnect2.log"; | |
| 241 static char *noconnectfile3 = "noconnect3.log"; | |
| 242 static char *readerrorfile = "readerror.log"; | |
| 243 static FILE *fp = NULL; | |
| 244 #endif /* SOCKET_DEBUG */ | |
| 245 | |
| 246 /*==== END DIAGNOSTICS ======================================================*/ | |
| 247 | |
| 248 extern USHORT ext_data_pool_handle; | |
| 249 | |
| 250 GLOBAL ULONG drv_socket_task_stack_size = SOCKET_STACK; | |
| 251 GLOBAL USHORT drv_socket_task_prio = SOCKET_PRIO; | |
| 252 | |
| 253 /*==== PRIVATE FUNCTIONS ====================================================*/ | |
| 254 /* | |
| 255 +------------------------------------------------------------------------------ | |
| 256 | Function : L_CreateThread | |
| 257 +------------------------------------------------------------------------------ | |
| 258 | Description : This function creates a thread. | |
| 259 | | |
| 260 | Parameters : ThreadFunc - pointer to the function beeing a thread | |
| 261 | | |
| 262 | Return : FALSE - Thread not created | |
| 263 | TRUE - Thread create (Thread ID stored in | |
| 264 | L_ClientData.ThreadID | |
| 265 | | |
| 266 +------------------------------------------------------------------------------ | |
| 267 */ | |
| 268 #ifdef OLD_FRAME | |
| 269 BOOL L_CreateThread (USHORT (*ThreadFunc)(USHORT,ULONG)) | |
| 270 { | |
| 271 return (CreateThread ((LPSECURITY_ATTRIBUTES) NULL, | |
| 272 0, | |
| 273 (LPTHREAD_START_ROUTINE)ThreadFunc, | |
| 274 (LPVOID) NULL, | |
| 275 0, | |
| 276 &L_ClientData.ThreadID) != NULL); | |
| 277 } | |
| 278 #else | |
| 279 BOOL L_CreateThread (void (*ThreadFunc)(T_HANDLE,ULONG)) | |
| 280 { | |
| 281 if ( os_CreateTask (0, (char*)"SOCKET", ThreadFunc, drv_socket_task_stack_size, drv_socket_task_prio, &L_ClientData.ThreadID, ext_data_pool_handle) < 0L ) | |
| 282 return FALSE; | |
| 283 if ( os_StartTask (0, L_ClientData.ThreadID, 0) < 0 ) | |
| 284 return FALSE ; | |
| 285 | |
| 286 return TRUE; | |
| 287 } | |
| 288 #endif | |
| 289 | |
| 290 /* | |
| 291 +------------------------------------------------------------------------------ | |
| 292 | Function : L_SetSocketBuffer | |
| 293 +------------------------------------------------------------------------------ | |
| 294 | Description : This function sets the IP read and write buffer | |
| 295 | | |
| 296 | Parameters : in_TxLen - size of transmission buffer | |
| 297 | in_RxLen - size of receiver buffer | |
| 298 | | |
| 299 | Return : FALSE - either the read or write buffer could not | |
| 300 | be set. | |
| 301 | TRUE - OK | |
| 302 | | |
| 303 +------------------------------------------------------------------------------ | |
| 304 */ | |
| 305 LOCAL BOOL L_SetSocketBuffer (USHORT in_TxLen, USHORT in_RxLen) | |
| 306 { | |
| 307 int in_TxLen1 = (int) in_TxLen; | |
| 308 int in_RxLen1 = (int) in_RxLen; | |
| 309 #ifndef _PSOS_ | |
| 310 int nodelay = TRUE; | |
| 311 #if defined (_VXWORKS_) || defined (_LINUX_) || defined (_SOLARIS_) | |
| 312 struct linger nolinger = {0, 0}; | |
| 313 #else | |
| 314 int linger = TRUE; | |
| 315 #endif | |
| 316 int rc=0; | |
| 317 | |
| 318 if (in_TxLen > 0) | |
| 319 { | |
| 320 if ( (rc=setsockopt(L_ClientData.Socket, SOL_SOCKET, SO_SNDBUF, | |
| 321 (char*)&in_TxLen1, sizeof(in_TxLen1))) != 0) | |
| 322 { | |
| 323 #ifdef _VXWORKS_ | |
| 324 rc = errnoGet (); | |
| 325 #else | |
| 326 #if defined (_LINUX_) || defined (_SOLARIS_) | |
| 327 rc = errno; | |
| 328 #else | |
| 329 rc = WSAGetLastError(); | |
| 330 #endif | |
| 331 #endif | |
| 332 #if defined _NUCLEUS_ || defined _TOOLS_ | |
| 333 printf("SOCKET: setsockopt() returned error code %d\n", rc); | |
| 334 #endif | |
| 335 return FALSE ; | |
| 336 } | |
| 337 } | |
| 338 #if defined (_VXWORKS_) || defined (_LINUX_) || defined (_SOLARIS_) | |
| 339 if (setsockopt(L_ClientData.Socket, SOL_SOCKET, SO_LINGER, | |
| 340 (char*)&nolinger, sizeof(nolinger))) | |
| 341 #else | |
| 342 if (setsockopt(L_ClientData.Socket, SOL_SOCKET, (int)SO_DONTLINGER, | |
| 343 (char*)&linger, sizeof(linger))) | |
| 344 #endif | |
| 345 return FALSE ; | |
| 346 if (setsockopt(L_ClientData.Socket, IPPROTO_TCP, TCP_NODELAY, | |
| 347 (char*)&nodelay, sizeof(nodelay))) | |
| 348 return FALSE ; | |
| 349 | |
| 350 #else /* PSOS */ | |
| 351 tst_socket_in_TxLen = in_TxLen; | |
| 352 #endif /* PSOS */ | |
| 353 if (in_RxLen > 0) | |
| 354 { | |
| 355 if (setsockopt(L_ClientData.Socket, SOL_SOCKET, SO_RCVBUF, | |
| 356 (char *) &in_RxLen1, sizeof(in_RxLen1))) | |
| 357 return FALSE ; | |
| 358 } | |
| 359 | |
| 360 return TRUE ; | |
| 361 } | |
| 362 | |
| 363 /* | |
| 364 +------------------------------------------------------------------------------ | |
| 365 | Function : L_Disconnect | |
| 366 +------------------------------------------------------------------------------ | |
| 367 | Description : This function is called when the connection to the peer entity | |
| 368 | is lost. If the release signal is set a signal is generated. | |
| 369 | | |
| 370 | Parameters : - | |
| 371 | | |
| 372 | Return : - | |
| 373 | | |
| 374 +------------------------------------------------------------------------------ | |
| 375 */ | |
| 376 LOCAL void L_Disconnect (void) | |
| 377 { | |
| 378 | |
| 379 L_ClientData.Connect = FALSE; | |
| 380 if (L_ClientData.EnabledSignals != INVALID_SIGNALTYPE) | |
| 381 { | |
| 382 SocketSignal.SignalType = DRV_SIGTYPE_DISCONNECT; | |
| 383 SocketSignal.DrvHandle = L_ClientData.SocketHandle; | |
| 384 (*L_ClientData.Callback)(&SocketSignal) ; | |
| 385 } | |
| 386 } | |
| 387 | |
| 388 /* | |
| 389 +------------------------------------------------------------------------------ | |
| 390 | Function : L_AsyncSelect | |
| 391 +------------------------------------------------------------------------------ | |
| 392 | Description : This function waits (blocking) for either something to read | |
| 393 | or an execption on the socket. | |
| 394 | | |
| 395 | Parameters : - | |
| 396 | | |
| 397 | Return : FALSE - failure on the socket | |
| 398 | TRUE - a read event was signalled | |
| 399 | | |
| 400 +------------------------------------------------------------------------------ | |
| 401 */ | |
| 402 LOCAL BOOL L_AsyncSelect (void) | |
| 403 { | |
| 404 fd_set fd_r ; | |
| 405 fd_set fd_e ; | |
| 406 int status, rc; | |
| 407 | |
| 408 /* wait for possibility to read */ | |
| 409 FD_ZERO(&fd_r); | |
| 410 FD_SET(L_ClientData.Socket, &fd_r); | |
| 411 FD_ZERO(&fd_e); | |
| 412 FD_SET(L_ClientData.Socket, &fd_e); | |
| 413 | |
| 414 status = select(FD_SETSIZE, &fd_r, NULL, &fd_e, (struct timeval *) 0); | |
| 415 | |
| 416 if (status > 0) | |
| 417 { | |
| 418 if (!FD_ISSET (L_ClientData.Socket, &fd_e)) | |
| 419 { | |
| 420 if (L_ClientData.Callback != NULL) | |
| 421 { | |
| 422 if (FD_ISSET (L_ClientData.Socket, &fd_r)) | |
| 423 { | |
| 424 SIZETYPE size ; | |
| 425 | |
| 426 if ((rc = GETREADSIZE( L_ClientData.Socket, &size)) != 0 || !size) | |
| 427 { | |
| 428 #ifdef SOCK_TRACE | |
| 429 if (fh_sock != -1) | |
| 430 { | |
| 431 char sstop[10]; | |
| 432 ULONG stop = GetTickCount(); | |
| 433 | |
| 434 sprintf(sstop, "%03d:%03d", (stop/1000) % 1000, stop % 1000); | |
| 435 sprintf(stbuf, "reset at %s rc=%d size=%d left %d \n", | |
| 436 sstop, rc, size, | |
| 437 wrbuf_pos-wrbuf); | |
| 438 write (fh_sock, stbuf, strlen(stbuf)); | |
| 439 /* close(fh_sock); | |
| 440 fh_sock = -1; */ | |
| 441 } | |
| 442 #endif | |
| 443 os_SuspendTask ( 0, 2 ); | |
| 444 CLOSE_SOCKET (L_ClientData.Socket); | |
| 445 L_ClientData.Socket = INVALID_SOCKET; | |
| 446 wrbuf_pos = wrbuf; | |
| 447 sock_state = SST_PL0; | |
| 448 return FALSE ; | |
| 449 } | |
| 450 | |
| 451 /* Indicate that it is possible to read something */ | |
| 452 if (L_ClientData.EnabledSignals & DRV_SIGTYPE_READ) | |
| 453 { | |
| 454 SocketSignal.SignalType = DRV_SIGTYPE_READ; | |
| 455 SocketSignal.DrvHandle = L_ClientData.SocketHandle; | |
| 456 (*L_ClientData.Callback)(&SocketSignal) ; | |
| 457 } | |
| 458 } | |
| 459 } | |
| 460 return TRUE ; | |
| 461 } | |
| 462 } | |
| 463 return FALSE; | |
| 464 } | |
| 465 | |
| 466 /* | |
| 467 +------------------------------------------------------------------------------ | |
| 468 | Function : L_ClientThread | |
| 469 +------------------------------------------------------------------------------ | |
| 470 | Description : This function is a thread used if the driver is configured to | |
| 471 | be a client. | |
| 472 | | |
| 473 | Parameters : - | |
| 474 | | |
| 475 | Return : - | |
| 476 | | |
| 477 +------------------------------------------------------------------------------ | |
| 478 */ | |
| 479 void L_ClientThread (T_HANDLE Handle, ULONG Value ) | |
| 480 { | |
| 481 L_ThreadActive = TRUE ; | |
| 482 | |
| 483 L_SetSocketBuffer (L_DCB.tx_buffer_size, L_DCB.rx_buffer_size) ; | |
| 484 | |
| 485 /*------------------------------------- | |
| 486 Listen what's goning on on the socket | |
| 487 -------------------------------------*/ | |
| 488 while (L_ThreadActive) | |
| 489 if (!L_AsyncSelect()) | |
| 490 { | |
| 491 L_ThreadActive = FALSE ; | |
| 492 L_Disconnect() ; | |
| 493 } | |
| 494 } | |
| 495 | |
| 496 | |
| 497 /* | |
| 498 +------------------------------------------------------------------------------ | |
| 499 | Function : L_ServerThread | |
| 500 +------------------------------------------------------------------------------ | |
| 501 | Description : This function is a thread used if the driver is configured to | |
| 502 | be a server. It serves only one client. It cycles between | |
| 503 | two modes, wait for a client to connect and listening on the | |
| 504 | connection for any further action. | |
| 505 | The thread exits when the flag L_ThreadActive is set to false. | |
| 506 | | |
| 507 | Parameters : - | |
| 508 | | |
| 509 | Return : - | |
| 510 | | |
| 511 +------------------------------------------------------------------------------ | |
| 512 */ | |
| 513 void L_ServerThread (T_HANDLE TaskHandle, ULONG Value) | |
| 514 { | |
| 515 BOOL BufferSizeSet; | |
| 516 SOCKADDR_IN local_sin; /* Local socket - internet style */ | |
| 517 #ifdef _VXWORKS_ | |
| 518 SOCKADDR_IN clientAddr; /* client */ | |
| 519 int sockAddrSize = sizeof (struct sockaddr_in); | |
| 520 | |
| 521 memset ((char *) &local_sin, 0, sockAddrSize); | |
| 522 local_sin.sin_len = (u_char) sockAddrSize; | |
| 523 #endif/* _VXWORKS_ */ | |
| 524 L_ClientData.Listener = socket (AF_INET, SOCK_STREAM, 0); | |
| 525 if (L_ClientData.Listener == INVALID_SOCKET) | |
| 526 goto error; | |
| 527 | |
| 528 if (L_DCB.port == SOCKET_INVALID_PORT) | |
| 529 goto error; | |
| 530 | |
| 531 local_sin.sin_addr.s_addr = htonl(INADDR_ANY); | |
| 532 local_sin.sin_family = AF_INET; | |
| 533 local_sin.sin_port = htons(L_DCB.port); /* Convert to network ordering */ | |
| 534 | |
| 535 /*------------------------------------------- | |
| 536 Associate an address with a socket. (bind) | |
| 537 -------------------------------------------*/ | |
| 538 #ifdef _PSOS_ | |
| 539 if (bind (L_ClientData.Listener, (struct sockaddr_in*) &local_sin, sizeof(local_sin)) != 0) | |
| 540 #else | |
| 541 #ifdef _VXWORKS_ | |
| 542 /* Look at the following cast of local_sin. | |
| 543 * This is from VxWorks Network 5.4 Programmer’s Guide, example 7-1, page 131 | |
| 544 */ | |
| 545 if (bind (L_ClientData.Listener, (struct sockaddr*) &local_sin, sockAddrSize) == ERROR) | |
| 546 #else /* _VXWORKS_ */ | |
| 547 if (bind (L_ClientData.Listener, (const struct sockaddr FAR *) &local_sin, sizeof(local_sin)) != 0) | |
| 548 #endif /* _VXWORKS_ */ | |
| 549 #endif | |
| 550 { | |
| 551 CLOSE_SOCKET (L_ClientData.Listener); | |
| 552 goto error; | |
| 553 } | |
| 554 #ifdef _VXWORKS_ | |
| 555 if (listen (L_ClientData.Listener, MAX_PENDING_CONNECTS) == ERROR) | |
| 556 #else /* _VXWORKS_ */ | |
| 557 if (listen (L_ClientData.Listener, MAX_PENDING_CONNECTS) != 0) | |
| 558 #endif /* _VXWORKS_ */ | |
| 559 { | |
| 560 CLOSE_SOCKET (L_ClientData.Listener); | |
| 561 goto error; | |
| 562 } | |
| 563 | |
| 564 BufferSizeSet = FALSE ; | |
| 565 L_ThreadActive = TRUE ; | |
| 566 | |
| 567 while (L_ThreadActive) | |
| 568 { | |
| 569 /*------------------------------------- | |
| 570 Wait for somebody to connect | |
| 571 -------------------------------------*/ | |
| 572 if (L_ClientData.Socket != INVALID_SOCKET) | |
| 573 { | |
| 574 #ifdef SOCK_TRACE | |
| 575 if (fh_sock != -1) | |
| 576 { | |
| 577 char sstop[10]; | |
| 578 ULONG stop = GetTickCount(); | |
| 579 | |
| 580 sprintf(sstop, "%03d:%03d", (stop/1000) % 1000, stop % 1000); | |
| 581 sprintf(stbuf, "close at %s socket=%d\n", | |
| 582 sstop, L_ClientData.Socket); | |
| 583 write (fh_sock, stbuf, strlen(stbuf)); | |
| 584 /* close(fh_sock); | |
| 585 fh_sock = -1; */ | |
| 586 } | |
| 587 #endif | |
| 588 CLOSE_SOCKET (L_ClientData.Socket); | |
| 589 L_ClientData.Socket = INVALID_SOCKET; | |
| 590 wrbuf_pos = wrbuf; | |
| 591 sock_state = SST_PL0; | |
| 592 } | |
| 593 #ifdef _VXWORKS_ | |
| 594 if ((L_ClientData.Socket = accept (L_ClientData.Listener, | |
| 595 (struct sockaddr *) &clientAddr, | |
| 596 &sockAddrSize)) != ERROR) | |
| 597 #else /* _VXWORKS_ */ | |
| 598 L_ClientData.Socket = accept(L_ClientData.Listener, NULL, NULL) ; | |
| 599 if (L_ClientData.Socket != INVALID_SOCKET) | |
| 600 #endif /* _VXWORKS_ */ | |
| 601 { | |
| 602 #ifdef SOCK_TRACE | |
| 603 if (fh_sock == -1) | |
| 604 fh_sock = open("SOCK_S.dbg", O_WRONLY| O_TEXT| O_TRUNC| O_CREAT, 0666); | |
| 605 if (fh_sock != -1) | |
| 606 { | |
| 607 char sstop[10]; | |
| 608 ULONG stop = GetTickCount(); | |
| 609 | |
| 610 sprintf(sstop, "%03d:%03d", (stop/1000) % 1000, stop % 1000); | |
| 611 sprintf(stbuf, "accept at %s socket=%d listener=%d\n", | |
| 612 sstop, L_ClientData.Socket, L_ClientData.Listener); | |
| 613 write (fh_sock, stbuf, strlen(stbuf)); | |
| 614 } | |
| 615 #endif | |
| 616 | |
| 617 #ifdef _PSOS_ | |
| 618 { | |
| 619 ULONG tid; | |
| 620 int err; | |
| 621 /* for pSOS */ | |
| 622 /* wait for TST task */ | |
| 623 while( t_ident( FRM_TST_NAME, 0, &tid ) != 0 ) | |
| 624 tm_wkafter( 10 ); | |
| 625 | |
| 626 tst_socket = shr_socket( L_ClientData.Socket, (int)tid ); | |
| 627 if( tst_socket < 0 ) | |
| 628 { | |
| 629 err = errno; | |
| 630 goto error; | |
| 631 } | |
| 632 } | |
| 633 #endif | |
| 634 | |
| 635 if (!BufferSizeSet) | |
| 636 L_SetSocketBuffer (L_DCB.tx_buffer_size, L_DCB.rx_buffer_size) ; | |
| 637 | |
| 638 /* Signalisiere Connect */ | |
| 639 L_ClientData.Connect = TRUE; | |
| 640 if (L_ClientData.EnabledSignals & DRV_SIGTYPE_CONNECT) | |
| 641 { | |
| 642 SocketSignal.SignalType = DRV_SIGTYPE_CONNECT; | |
| 643 SocketSignal.DrvHandle = L_ClientData.SocketHandle; | |
| 644 (*L_ClientData.Callback)(&SocketSignal) ; | |
| 645 } | |
| 646 | |
| 647 /*------------------------------------- | |
| 648 Listen what's goning on on the socket | |
| 649 -------------------------------------*/ | |
| 650 while (L_ThreadActive) | |
| 651 if (!L_AsyncSelect()) | |
| 652 { | |
| 653 L_Disconnect() ; | |
| 654 break ; | |
| 655 } | |
| 656 } | |
| 657 } | |
| 658 | |
| 659 error: | |
| 660 #ifndef OLD_FRAME | |
| 661 for(;;) | |
| 662 os_SuspendTask( 0, 1000 ); | |
| 663 #endif | |
| 664 } | |
| 665 | |
| 666 /* | |
| 667 +------------------------------------------------------------------------------ | |
| 668 | Function : socket_Create | |
| 669 +------------------------------------------------------------------------------ | |
| 670 | Description : This function is used to set up the driver to act as a | |
| 671 | server. The function tries to initialize the socket, creates | |
| 672 | a thread in which it awaits first awaits the establishement | |
| 673 | of a connection by a client. As soon as a client has | |
| 674 | connected a signal (SOCKET_CONNECTED) is generated (call | |
| 675 | socket_SetSignal() to activate a signal). From this time the | |
| 676 | driver is able to send data (socket_write()) to the client and | |
| 677 | to read received data (socket_read()). To get notified about | |
| 678 | the reception of data the apropriate signal has to be set. | |
| 679 | In the case of a successful completion the driver returns | |
| 680 | DRV_OK. | |
| 681 | If the driver is already busy DRV_INPROCESS is returned. | |
| 682 | If the driver is not configured, the function returns | |
| 683 | DRV_ NOTCONFIGURED. | |
| 684 | | |
| 685 | Parameters : - | |
| 686 | | |
| 687 | Return : DRV_OK - Function successful | |
| 688 | DRV_INPROCESS - The driver is currently reading data. | |
| 689 | The data is incomplete. | |
| 690 | DRV_NOTCONFIGURED - The driver is not yet configured | |
| 691 | SOCKET_ERRORUNSPEC - Error occured during initialization | |
| 692 | | |
| 693 +------------------------------------------------------------------------------ | |
| 694 */ | |
| 695 LOCAL UBYTE L_CreateServer (void) | |
| 696 { | |
| 697 if (!L_CreateThread (L_ServerThread)) | |
| 698 { | |
| 699 CLOSE_SOCKET (L_ClientData.Listener); | |
| 700 return SOCKET_ERRUNSPEC; | |
| 701 } | |
| 702 #ifdef _TOOLS_ | |
| 703 printf("SOCKET: now listening on port %i ...\n",L_DCB.port); | |
| 704 #endif | |
| 705 | |
| 706 return DRV_OK ; | |
| 707 } | |
| 708 /* | |
| 709 +------------------------------------------------------------------------------ | |
| 710 | Function : socket_WriteToOS | |
| 711 +------------------------------------------------------------------------------ | |
| 712 | Description : This function is used to write data to the driver of operating | |
| 713 | system. | |
| 714 | The parameter thr_BufferSize contains the number of | |
| 715 | characters to write. In the case of a successful completion, | |
| 716 | the function returns DRV_OK. | |
| 717 | | |
| 718 | Parameters : in_BufferPtr - This parameter points to the buffer | |
| 719 | that is passed to the driver for | |
| 720 | further processing | |
| 721 | thr_BufferSize - number of characters to write. | |
| 722 | | |
| 723 | Return : DRV_OK - Function successful | |
| 724 | DRV_INPROCESS - Driver is busy writing data | |
| 725 | SOCKET_NOCONNECT - Connection not available | |
| 726 | | |
| 727 +------------------------------------------------------------------------------ | |
| 728 */ | |
| 729 LOCAL UBYTE socket_WriteToOS (void* in_BufferPtr, USHORT thr_BufferSize) | |
| 730 { | |
| 731 int err; | |
| 732 USHORT c_written; | |
| 733 #ifndef _PSOS_ | |
| 734 fd_set fd_w; | |
| 735 fd_set fd_e; | |
| 736 struct timeval tv; | |
| 737 | |
| 738 if (L_ClientData.Socket == INVALID_SOCKET) | |
| 739 return SOCKET_NOCONNECT; | |
| 740 | |
| 741 if ( L_ClientData.Connect == FALSE ) | |
| 742 return SOCKET_NOCONNECT ; | |
| 743 | |
| 744 tv.tv_sec = (int)(L_DCB.tx_timeout_msec / 1000) ; | |
| 745 tv.tv_usec = SEND_TIMEOUTUSEC ; | |
| 746 | |
| 747 FD_ZERO(&fd_w); | |
| 748 FD_SET(L_ClientData.Socket, &fd_w); | |
| 749 FD_ZERO(&fd_e); | |
| 750 FD_SET(L_ClientData.Socket, &fd_e); | |
| 751 | |
| 752 if (select(FD_SETSIZE, NULL, &fd_w, &fd_e, &tv) <= 0) | |
| 753 { | |
| 754 #ifdef SOCKET_DEBUG | |
| 755 char buffer[200]; | |
| 756 char *ptr = in_BufferPtr; | |
| 757 char c = ptr[21]; | |
| 758 fp = fopen(inprocessfile, "at"); | |
| 759 if ( *ptr == 'P' ) | |
| 760 ptr[21] = 0; | |
| 761 else | |
| 762 ptr[thr_BufferSize] = 0; | |
| 763 strcpy (buffer, "errno:" ); | |
| 764 sprintf (&buffer[6], "%8d", WSAGetLastError() ); | |
| 765 buffer[14] = ' '; | |
| 766 memcpy (&buffer[15], ptr, (thr_BufferSize)+1); | |
| 767 fprintf (fp, "%s\n", buffer ); | |
| 768 ptr[21] = c; | |
| 769 fclose(fp); | |
| 770 #endif /* SOCKET_DEBUG */ | |
| 771 #ifdef _VXWORKS_ | |
| 772 err = errnoGet (); | |
| 773 #else /* _VXWORKS_ */ | |
| 774 err = errno; | |
| 775 printf("SOCKET: socket write failed with error code: %d\n",err ); | |
| 776 #endif /* _VXWORKS_ */ | |
| 777 | |
| 778 return DRV_INPROCESS ; | |
| 779 } | |
| 780 | |
| 781 if (FD_ISSET (L_ClientData.Socket, &fd_e)) | |
| 782 { | |
| 783 #ifdef SOCKET_DEBUG | |
| 784 char buffer[200]; | |
| 785 char *ptr = in_BufferPtr; | |
| 786 char c = ptr[21]; | |
| 787 fp = fopen(noconnectfile1, "at"); | |
| 788 if ( *ptr == 'P' ) | |
| 789 ptr[21] = 0; | |
| 790 else | |
| 791 ptr[thr_BufferSize] = 0; | |
| 792 strcpy (buffer, "errno:" ); | |
| 793 sprintf (&buffer[6], "%8d", WSAGetLastError() ); | |
| 794 buffer[14] = ' '; | |
| 795 memcpy (&buffer[15], ptr, (thr_BufferSize)+1); | |
| 796 fprintf (fp, "%s\n", buffer ); | |
| 797 ptr[21] = c; | |
| 798 fclose(fp); | |
| 799 #endif /* SOCKET_DEBUG */ | |
| 800 return SOCKET_NOCONNECT ; | |
| 801 } | |
| 802 | |
| 803 /*--------------------------------- | |
| 804 Send the data | |
| 805 ---------------------------------*/ | |
| 806 c_written = (USHORT) WRITE_SOCKET(L_ClientData.Socket, in_BufferPtr, (USHORT)thr_BufferSize); | |
| 807 | |
| 808 if (c_written == (USHORT)SOCKET_ERROR || c_written != thr_BufferSize) | |
| 809 { | |
| 810 #ifdef SOCKET_DEBUG | |
| 811 char buffer[200]; | |
| 812 char *ptr = in_BufferPtr; | |
| 813 char c = ptr[21]; | |
| 814 fp = fopen(noconnectfile2, "at"); | |
| 815 if ( *ptr == 'P' ) | |
| 816 ptr[21] = 0; | |
| 817 else | |
| 818 ptr[thr_BufferSize] = 0; | |
| 819 strcpy (buffer, "errno:" ); | |
| 820 sprintf (&buffer[6], "%8d", WSAGetLastError() ); | |
| 821 buffer[14] = ' '; | |
| 822 memcpy (&buffer[15], ptr, (thr_BufferSize)+1); | |
| 823 fprintf (fp, "%s\n", buffer ); | |
| 824 ptr[21] = c; | |
| 825 fclose(fp); | |
| 826 #endif /* SOCKET_DEBUG */ | |
| 827 return SOCKET_NOCONNECT ; | |
| 828 } | |
| 829 | |
| 830 #ifdef SOCK_TRACE | |
| 831 if (fh_sock != -1) | |
| 832 { | |
| 833 char sstop[10]; | |
| 834 ULONG stop = GetTickCount(); | |
| 835 | |
| 836 sprintf(sstop, "%03d:%03d", (stop/1000) % 1000, stop % 1000); | |
| 837 sprintf(stbuf, "sent %d at %s\n", | |
| 838 thr_BufferSize, | |
| 839 sstop); | |
| 840 write (fh_sock, stbuf, strlen(stbuf)); | |
| 841 } | |
| 842 #endif | |
| 843 return DRV_OK ; | |
| 844 | |
| 845 #else | |
| 846 | |
| 847 /* pSOS */ | |
| 848 | |
| 849 /*--------------------------------- | |
| 850 Send the data | |
| 851 ---------------------------------*/ | |
| 852 c_written = (USHORT) WRITE_SOCKET(tst_socket, in_BufferPtr, (USHORT)thr_BufferSize); | |
| 853 | |
| 854 if (c_written == (USHORT)SOCKET_ERROR || c_written != thr_BufferSize) | |
| 855 { | |
| 856 err = errno; | |
| 857 return SOCKET_NOCONNECT ; | |
| 858 } | |
| 859 | |
| 860 return DRV_OK ; | |
| 861 #endif /* _PSOS_ */ | |
| 862 } | |
| 863 | |
| 864 /*==== PUBLIC FUNCTIONS =====================================================*/ | |
| 865 | |
| 866 /* | |
| 867 +------------------------------------------------------------------------------ | |
| 868 | Function : socket_Exit | |
| 869 +------------------------------------------------------------------------------ | |
| 870 | Description : The function is called when the driver functionality is no | |
| 871 | longer required. The function "de-allocates" the resources | |
| 872 | and releases active connections. The driver terminates | |
| 873 | regardless of any outstanding data to be sent. | |
| 874 | | |
| 875 | Parameters : - | |
| 876 | | |
| 877 | Return : - | |
| 878 | | |
| 879 +------------------------------------------------------------------------------ | |
| 880 */ | |
| 881 void socket_Exit (void) | |
| 882 { | |
| 883 os_DestroyTask ( 0, L_ClientData.ThreadID ); | |
| 884 socket_Close() ; | |
| 885 } | |
| 886 | |
| 887 | |
| 888 /* | |
| 889 +------------------------------------------------------------------------------ | |
| 890 | Function : socket_Open | |
| 891 +------------------------------------------------------------------------------ | |
| 892 | Description : This function is used to establish a connection to server or | |
| 893 | activate the driver to act as a server, using the settings of | |
| 894 | the socket_DCB. A hostname must be specified to open a | |
| 895 | connection to a server, in this case the driver runs in the | |
| 896 | client mode. If no hostname is specified the driver will run in | |
| 897 | server mode. In the server mode it serves a single client. As | |
| 898 | soon as a client is connected the CONNECT signal is generated. | |
| 899 | In case of a successful completion the driver is no able to send | |
| 900 | data (socket_write()) to the peer entity and to read data | |
| 901 | received from the peer entity (socket_read()). To get notified | |
| 902 | about the reception of data the appropriate signal has to be set | |
| 903 | (socket_SetSignal()). | |
| 904 | In the case of a successful completion the driver returns DRV_OK. | |
| 905 | If the driver is already busy DRV_INPROCESS is returned. | |
| 906 | If the driver is not configured, the function returns | |
| 907 | DRV_NOTCONFIGURED. | |
| 908 | If an error occurs while establishing the requested mode, the | |
| 909 | function returns SOCKET_ERRUNSPEC. | |
| 910 | | |
| 911 | Parameters : - | |
| 912 | | |
| 913 | Return : DRV_OK - Function successful | |
| 914 | DRV_INPROCESS - The driver is currently reading data. | |
| 915 | The data is incomplete. | |
| 916 | DRV_NOTCONFIGURED - The driver is not yet configured | |
| 917 | SOCKET_ERRUNSPEC - Error occured during initialization | |
| 918 | | |
| 919 +------------------------------------------------------------------------------ | |
| 920 */ | |
| 921 USHORT socket_Open (void) | |
| 922 { | |
| 923 SOCKADDR_IN dest_sin; /* DESTination Socket INternet */ | |
| 924 SOCKET connectsocket; | |
| 925 #ifdef _VXWORKS_ | |
| 926 int sockAddrSize; | |
| 927 #else /* _VXWORKS_ */ | |
| 928 #if defined (_LINUX_) || defined (_SOLARIS_) | |
| 929 struct hostent* phe; | |
| 930 #else | |
| 931 PHOSTENT phe; | |
| 932 #endif | |
| 933 #endif /* _VXWORKS_ */ | |
| 934 if (L_ThreadActive) | |
| 935 { | |
| 936 return DRV_INPROCESS ; | |
| 937 } | |
| 938 | |
| 939 /*--------------------------------- | |
| 940 if no hostname is specified we | |
| 941 open as a server | |
| 942 ---------------------------------*/ | |
| 943 if (!*L_DCB.hostname) | |
| 944 { | |
| 945 return L_CreateServer() ; | |
| 946 } | |
| 947 | |
| 948 connectsocket = socket (AF_INET, SOCK_STREAM, 0); | |
| 949 if (connectsocket == INVALID_SOCKET) | |
| 950 { | |
| 951 return SOCKET_ERRUNSPEC; | |
| 952 } | |
| 953 | |
| 954 #ifdef _PSOS_ | |
| 955 | |
| 956 if ( !gethostbyname(L_DCB.hostname, phe)) | |
| 957 { | |
| 958 CLOSE_SOCKET(connectsocket); | |
| 959 return SOCKET_ERRUNSPEC; | |
| 960 } | |
| 961 | |
| 962 #else /* _PSOS_ */ | |
| 963 #ifdef _VXWORKS_ | |
| 964 sockAddrSize = sizeof (struct sockaddr_in); | |
| 965 memset((char *) &dest_sin, 0, sockAddrSize); | |
| 966 dest_sin.sin_len = (u_char) sockAddrSize; | |
| 967 dest_sin.sin_family = AF_INET; | |
| 968 dest_sin.sin_port = htons(L_DCB.port); | |
| 969 if (((dest_sin.sin_addr.s_addr = inet_addr (L_DCB.hostname)) == ERROR) && | |
| 970 ((dest_sin.sin_addr.s_addr = hostGetByName (L_DCB.hostname)) == ERROR)) | |
| 971 { | |
| 972 CLOSE_SOCKET(connectsocket); | |
| 973 return SOCKET_ERRUNSPEC; | |
| 974 } | |
| 975 #else /* _VXWORKS_ */ | |
| 976 phe = gethostbyname(L_DCB.hostname); | |
| 977 if (!phe) | |
| 978 { | |
| 979 #ifdef _TOOLS_ | |
| 980 printf("SOCKET: host %s not found ;-(\n",L_DCB.hostname); | |
| 981 #endif | |
| 982 CLOSE_SOCKET(connectsocket); | |
| 983 return SOCKET_ERRUNSPEC; | |
| 984 } | |
| 985 #endif /* _VXWORKS_ */ | |
| 986 #endif /* _PSOS_ */ | |
| 987 | |
| 988 #ifndef _VXWORKS_ | |
| 989 memset(&dest_sin, 0, sizeof(struct sockaddr_in)); | |
| 990 memcpy((char*)&(dest_sin.sin_addr), phe->h_addr, (unsigned int)((int)(phe->h_length))); | |
| 991 dest_sin.sin_family = AF_INET; | |
| 992 if ( L_DCB.config & TI_MODE ) | |
| 993 dest_sin.sin_port = L_DCB.port; | |
| 994 else | |
| 995 dest_sin.sin_port = htons(L_DCB.port); | |
| 996 #endif /* _VXWORKS_ */ | |
| 997 | |
| 998 #ifdef _PSOS_ | |
| 999 if (connect (connectsocket, (struct sockaddr_in*) &dest_sin, sizeof(dest_sin))) | |
| 1000 #else /* _PSOS_ */ | |
| 1001 #ifdef _VXWORKS_ | |
| 1002 if (connect (connectsocket, (struct sockaddr*) &dest_sin, sockAddrSize) == ERROR) | |
| 1003 #else /* _VXWORKS_ */ | |
| 1004 #if defined (_LINUX_) || defined (_SOLARIS_) | |
| 1005 if (connect (connectsocket, (struct sockaddr*) &dest_sin, | |
| 1006 sizeof(dest_sin))) | |
| 1007 #else | |
| 1008 if (connect (connectsocket, (const PSOCKADDR) &dest_sin, | |
| 1009 sizeof(dest_sin))) | |
| 1010 #endif | |
| 1011 #endif /* _VXWORKS_ */ | |
| 1012 #endif /* defined(_PSOS_) || defined(_VXWORKS_) */ | |
| 1013 { | |
| 1014 #ifdef _TOOLS_ | |
| 1015 printf("SOCKET: connection to %s on port %i failed ;-(\n",L_DCB.hostname,L_DCB.port); | |
| 1016 #endif | |
| 1017 CLOSE_SOCKET(connectsocket); | |
| 1018 return SOCKET_ERRUNSPEC; | |
| 1019 } | |
| 1020 #ifdef _TOOLS_ | |
| 1021 printf("SOCKET: successfully connected to %s on port %i\n",L_DCB.hostname,L_DCB.port); | |
| 1022 #endif | |
| 1023 | |
| 1024 if (!L_CreateThread (L_ClientThread)) | |
| 1025 { | |
| 1026 CLOSE_SOCKET (L_ClientData.Listener); | |
| 1027 return SOCKET_ERRUNSPEC; | |
| 1028 } | |
| 1029 | |
| 1030 L_ClientData.Socket = connectsocket ; | |
| 1031 L_ClientData.Connect = TRUE; | |
| 1032 if (L_ClientData.EnabledSignals & DRV_SIGTYPE_CONNECT) | |
| 1033 { | |
| 1034 SocketSignal.SignalType = DRV_SIGTYPE_CONNECT; | |
| 1035 SocketSignal.DrvHandle = L_ClientData.SocketHandle; | |
| 1036 (*L_ClientData.Callback)(&SocketSignal) ; | |
| 1037 } | |
| 1038 return DRV_OK ; | |
| 1039 } | |
| 1040 | |
| 1041 /* | |
| 1042 +------------------------------------------------------------------------------ | |
| 1043 | Function : socket_Close | |
| 1044 +------------------------------------------------------------------------------ | |
| 1045 | Description : This function is used by a client to close the connection or | |
| 1046 | by server to shut down the server functionality. | |
| 1047 | In case of a successful completion the connection is shutdown | |
| 1048 | and neither socket_Read nor socket_Write will be successful. | |
| 1049 | To get notified about the termination of a connection the | |
| 1050 | appropriate signal has to be set (socket_SetSignal()). | |
| 1051 | | |
| 1052 | Parameters : - | |
| 1053 | | |
| 1054 | Return : - | |
| 1055 | | |
| 1056 +------------------------------------------------------------------------------ | |
| 1057 */ | |
| 1058 USHORT socket_Close (void) | |
| 1059 { | |
| 1060 L_ThreadActive = FALSE ; | |
| 1061 | |
| 1062 #ifdef SOCK_TRACE | |
| 1063 if (fh_sock != -1) | |
| 1064 { | |
| 1065 char sstop[10]; | |
| 1066 ULONG stop = GetTickCount(); | |
| 1067 | |
| 1068 sprintf(sstop, "%03d:%03d", (stop/1000) % 1000, stop % 1000); | |
| 1069 sprintf(stbuf, "socket_Close at %s socket=%d listener=%d\n", | |
| 1070 sstop, L_ClientData.Socket, L_ClientData.Listener); | |
| 1071 write (fh_sock, stbuf, strlen(stbuf)); | |
| 1072 } | |
| 1073 #endif | |
| 1074 if (L_ClientData.Socket != INVALID_SOCKET) | |
| 1075 { | |
| 1076 CLOSE_SOCKET (L_ClientData.Socket); | |
| 1077 L_ClientData.Socket = INVALID_SOCKET; | |
| 1078 } | |
| 1079 | |
| 1080 if (L_ClientData.Listener != INVALID_SOCKET) | |
| 1081 CLOSE_SOCKET (L_ClientData.Listener); | |
| 1082 | |
| 1083 L_ClientData.ThreadID = 0 ; | |
| 1084 return DRV_OK; | |
| 1085 } | |
| 1086 | |
| 1087 /* | |
| 1088 +------------------------------------------------------------------------------ | |
| 1089 | Function : socket_Read_with_Timeout | |
| 1090 +------------------------------------------------------------------------------ | |
| 1091 | Description : This function is used to read data from the USART driver. | |
| 1092 | For more details see socket_Read() | |
| 1093 | | |
| 1094 | Return: >= 0 - Number of bytes read | |
| 1095 | SOCKET_ERROR - error occurred | |
| 1096 +------------------------------------------------------------------------------ | |
| 1097 */ | |
| 1098 LOCAL ULONG socket_Read_with_Timeout( void* destBuf, ULONG reqLen ) | |
| 1099 { | |
| 1100 ULONG timeout, | |
| 1101 totalBytes = 0, | |
| 1102 stop_timeout ; | |
| 1103 int readBytes, | |
| 1104 attempts = 0; | |
| 1105 | |
| 1106 /* calculate timeout time */ | |
| 1107 GETTIME( stop_timeout ); | |
| 1108 stop_timeout = stop_timeout + L_DCB.rx_timeout_msec ; | |
| 1109 | |
| 1110 /* read nonblocking until requested data is read or timeout */ | |
| 1111 do | |
| 1112 { | |
| 1113 readBytes = (SHORT)READ_SOCKET( L_ClientData.Socket, | |
| 1114 ((char *)destBuf) + totalBytes, | |
| 1115 reqLen - totalBytes ); | |
| 1116 | |
| 1117 if( readBytes < 0 || readBytes == SOCKET_ERROR ) | |
| 1118 { | |
| 1119 #ifdef SOCKET_DEBUG | |
| 1120 #ifndef _PSOS_ | |
| 1121 fp = fopen(readerrorfile, "at"); | |
| 1122 fprintf (fp, "WSAGetLastError returned: %8d", WSAGetLastError() ); | |
| 1123 fclose(fp); | |
| 1124 #endif | |
| 1125 #endif /* SOCKET_DEBUG */ | |
| 1126 return 0; | |
| 1127 } | |
| 1128 else | |
| 1129 { | |
| 1130 totalBytes += (unsigned int)readBytes; | |
| 1131 | |
| 1132 GETTIME (timeout) ; | |
| 1133 | |
| 1134 if( totalBytes < reqLen ) | |
| 1135 { | |
| 1136 if (attempts++) /* try to get data by two consecutive accesses | |
| 1137 then sleep (but this should not be necessary) */ | |
| 1138 { | |
| 1139 #ifdef OLD_FRAME | |
| 1140 Sleep (1) ; | |
| 1141 #else | |
| 1142 os_SuspendTask ( 0, 1 ); | |
| 1143 #endif | |
| 1144 } | |
| 1145 } | |
| 1146 else | |
| 1147 { | |
| 1148 return totalBytes; | |
| 1149 } | |
| 1150 } | |
| 1151 } while (timeout < stop_timeout); | |
| 1152 | |
| 1153 return 0; | |
| 1154 } | |
| 1155 | |
| 1156 /* | |
| 1157 +------------------------------------------------------------------------------ | |
| 1158 | Function : socket_Read | |
| 1159 +------------------------------------------------------------------------------ | |
| 1160 | Description : This function is used to read data from the USART driver. The | |
| 1161 | data is copied into the buffer to which out_BufferPtr points. | |
| 1162 | The parameter *thr_BufferSizePtr contains the size of the | |
| 1163 | buffer in characters. | |
| 1164 | In the case of a successful completion, the driver's buffer | |
| 1165 | is cleared. The driver keeps the data available when calling | |
| 1166 | the function drv_Look(). | |
| 1167 | If the driver is not configured, the function returns | |
| 1168 | DRV_NOTCONFIGURED. | |
| 1169 | | |
| 1170 | NOTE: When calling the function with a buffer size of 0, the | |
| 1171 | function will return DRV_OK. The size of the buffer | |
| 1172 | needed to store the available data is stored in the | |
| 1173 | parameter *thr_BufferSizePtr. In this case, the | |
| 1174 | out_BufferPtr can be set to NULL. | |
| 1175 | | |
| 1176 | | |
| 1177 | Parameters : out_BufferPtr - This parameter points to the buffer | |
| 1178 | wherein the data is to be copied | |
| 1179 | thr_BufferSizePtr - On call: number of characters to | |
| 1180 | read. If the function returns DRV_OK, | |
| 1181 | it contains the number of characters | |
| 1182 | read. If the function returns | |
| 1183 | DRV_INPROCESS, it contains 0. | |
| 1184 | | |
| 1185 | Return : DRV_OK - Function successful | |
| 1186 | DRV_INPROCESS - The driver is currently reading data. | |
| 1187 | The data is incomplete. | |
| 1188 | DRV_NOTCONFIGURED - The driver is not yet configured | |
| 1189 | SOCKET_NOCONNECT - Connection not available | |
| 1190 | | |
| 1191 +------------------------------------------------------------------------------ | |
| 1192 */ | |
| 1193 USHORT socket_Read (void* out_BufferPtr, ULONG* thr_BufferSizePtr) | |
| 1194 { | |
| 1195 #ifdef _VXWORKS_ | |
| 1196 SIZETYPE pending_data_size = 0; | |
| 1197 #else | |
| 1198 ULONG pending_data_size = 0; | |
| 1199 #endif | |
| 1200 ULONG bytesToRead, bytesReq; | |
| 1201 int rc; | |
| 1202 static USHORT packet_size; | |
| 1203 union | |
| 1204 { | |
| 1205 USHORT s; | |
| 1206 UBYTE b[2]; | |
| 1207 } conv; | |
| 1208 #ifdef SOCKET_DEBUG | |
| 1209 static ULONG BytesRead = 0; | |
| 1210 #endif | |
| 1211 #ifdef SOCK_TRACE | |
| 1212 static ULONG start; | |
| 1213 static ULONG lasttime = 0; | |
| 1214 #endif | |
| 1215 | |
| 1216 bytesReq = *thr_BufferSizePtr; | |
| 1217 *thr_BufferSizePtr = 0; /* no bytes returned yet */ | |
| 1218 while ( (rc = (GETREADSIZE( L_ClientData.Socket, &pending_data_size ))) == 0 && | |
| 1219 pending_data_size > 0 ) | |
| 1220 { | |
| 1221 switch (sock_state) | |
| 1222 { | |
| 1223 case SST_PL0: | |
| 1224 #ifdef SOCK_TRACE | |
| 1225 GETTIME (start) ; | |
| 1226 #endif | |
| 1227 packet_size = 0; | |
| 1228 if (pending_data_size >= 2) | |
| 1229 { | |
| 1230 bytesToRead = 2; | |
| 1231 sock_state = SST_DATA0; | |
| 1232 } | |
| 1233 else | |
| 1234 { | |
| 1235 bytesToRead = 1; | |
| 1236 sock_state = SST_PL1; | |
| 1237 } | |
| 1238 if ( !(L_DCB.config & TI_MODE) ) | |
| 1239 { | |
| 1240 if (socket_Read_with_Timeout(&packet_size, bytesToRead) != bytesToRead) | |
| 1241 { | |
| 1242 sock_state = SST_PL0; | |
| 1243 return SOCKET_NOCONNECT; | |
| 1244 } | |
| 1245 } | |
| 1246 break; | |
| 1247 case SST_PL1: | |
| 1248 if (socket_Read_with_Timeout(((char*)&packet_size)+1, 1) != 1) | |
| 1249 { | |
| 1250 sock_state = SST_PL0; | |
| 1251 return SOCKET_NOCONNECT; | |
| 1252 } | |
| 1253 sock_state = SST_DATA0; | |
| 1254 break; | |
| 1255 case SST_DATA0: | |
| 1256 if ( !(L_DCB.config & TI_MODE) && isLittleEndian ) | |
| 1257 { | |
| 1258 conv.b[0] = *(((UBYTE*)&packet_size)+1); /* LSB */ | |
| 1259 conv.b[1] = * (UBYTE*)&packet_size; /* MSB */ | |
| 1260 packet_size = conv.s; | |
| 1261 } | |
| 1262 /*lint -fallthrough*/ | |
| 1263 case SST_DATAx: | |
| 1264 /* now read the packet payload or a part of it */ | |
| 1265 if ( L_DCB.config & TI_MODE ) | |
| 1266 { | |
| 1267 bytesToRead = (pending_data_size < bytesReq) ? pending_data_size : bytesReq; | |
| 1268 } | |
| 1269 else | |
| 1270 { | |
| 1271 bytesToRead = (packet_size < bytesReq) ? packet_size : bytesReq; | |
| 1272 if (pending_data_size < bytesToRead) | |
| 1273 bytesToRead = pending_data_size; | |
| 1274 } | |
| 1275 if( (*thr_BufferSizePtr = | |
| 1276 socket_Read_with_Timeout( ((char *)out_BufferPtr), bytesToRead )) != | |
| 1277 bytesToRead ) | |
| 1278 { | |
| 1279 *thr_BufferSizePtr = 0; | |
| 1280 if ( !(L_DCB.config & TI_MODE) ) | |
| 1281 sock_state = SST_PL0; | |
| 1282 return SOCKET_NOCONNECT; | |
| 1283 } | |
| 1284 #ifdef SOCK_TRACE | |
| 1285 if (fh_sock != -1 && sock_state == SST_DATA0 && bytesToRead >= 13) | |
| 1286 { | |
| 1287 char split[10+1]; | |
| 1288 char sstart[20], sstop[20]; | |
| 1289 static ULONG c_received = 0; | |
| 1290 ULONG len = packet_size; | |
| 1291 ULONG stop = GetTickCount(); | |
| 1292 | |
| 1293 if (((char*)out_BufferPtr)[13] == 'T') | |
| 1294 { | |
| 1295 memcpy(split, ((char*)out_BufferPtr)+9, 7); | |
| 1296 split[7] = '\0'; | |
| 1297 } | |
| 1298 else | |
| 1299 { | |
| 1300 memcpy(split, ((char*)out_BufferPtr)+9, 4); | |
| 1301 split[4] = '\0'; | |
| 1302 } | |
| 1303 if (start != lasttime) | |
| 1304 { | |
| 1305 if (lasttime - start > 11) | |
| 1306 sprintf(sstart, "->%d %03d:%03d\n", c_received, (start/1000) % 1000, start % 1000); | |
| 1307 else | |
| 1308 sprintf(sstart, "%03d:%03d\n", (start/1000) % 1000, start % 1000); | |
| 1309 c_received = 0; | |
| 1310 } | |
| 1311 c_received += packet_size + 2; | |
| 1312 if (start != stop) | |
| 1313 { | |
| 1314 sprintf(sstop, "->%d %03d:%03d\n", c_received, (stop/1000) % 1000, stop % 1000); | |
| 1315 c_received = 0; | |
| 1316 } | |
| 1317 sprintf(stbuf, "%s%d %s\n%s", | |
| 1318 (start != lasttime) ? sstart : "", | |
| 1319 packet_size + 2, split, | |
| 1320 (start != stop) ? sstop : ""); | |
| 1321 write (fh_sock, stbuf, strlen(stbuf)); | |
| 1322 lasttime = stop; | |
| 1323 } | |
| 1324 #endif | |
| 1325 if ( !(L_DCB.config & TI_MODE) ) | |
| 1326 { | |
| 1327 if (*thr_BufferSizePtr == packet_size) | |
| 1328 sock_state = SST_PL0; | |
| 1329 else | |
| 1330 { | |
| 1331 packet_size -= (USHORT)*thr_BufferSizePtr; | |
| 1332 sock_state = SST_DATAx; | |
| 1333 } | |
| 1334 } | |
| 1335 return DRV_OK; | |
| 1336 /*lint -e527 suppress Warning -- Unreachable */ | |
| 1337 break; | |
| 1338 /*lint +e527 */ | |
| 1339 } /* switch */ | |
| 1340 } /* while */ | |
| 1341 if (rc) | |
| 1342 { | |
| 1343 sock_state = SST_PL0; | |
| 1344 return SOCKET_NOCONNECT; | |
| 1345 } | |
| 1346 #ifdef SOCKET_DEBUG | |
| 1347 { | |
| 1348 static char Buffer[2000]; | |
| 1349 memcpy (Buffer+BytesRead,out_BufferPtr,*thr_BufferSizePtr); | |
| 1350 BytesRead += *thr_BufferSizePtr; | |
| 1351 if ( (Buffer[0] == 'P') ) | |
| 1352 { | |
| 1353 OS_TIME time; | |
| 1354 char c = Buffer[21]; | |
| 1355 fp = fopen(logfile, "at"); | |
| 1356 Buffer[21] = 0; | |
| 1357 os_GetTime ( 0, &time ); | |
| 1358 fprintf (fp, "P%ld IN: %s\n", time/10, &Buffer[9] ); | |
| 1359 Buffer[21] = c; | |
| 1360 fclose(fp); | |
| 1361 } | |
| 1362 } | |
| 1363 | |
| 1364 #endif | |
| 1365 return DRV_OK ; | |
| 1366 } | |
| 1367 | |
| 1368 /* | |
| 1369 +------------------------------------------------------------------------------ | |
| 1370 | Function : socket_Write | |
| 1371 +------------------------------------------------------------------------------ | |
| 1372 | Description : This function is used to write data to the driver. The | |
| 1373 | parameter *thr_BufferSizePtr contains the number of | |
| 1374 | characters to write. In the case of a successful completion, | |
| 1375 | the function returns DRV_OK. | |
| 1376 | If the data cannot be written because the storage capacity of | |
| 1377 | the driver has been exhausted, the function returns | |
| 1378 | DRV_BUFFER_FULL and the maximum number of characters that can | |
| 1379 | be written in *thr_BufferSizePtr. | |
| 1380 | If the driver is currently busy writing data and therefore | |
| 1381 | cannot accept further data to be written, it returns | |
| 1382 | DRV_INPROCESS and sets the parameter *thr_BufferSizePtr to 0. | |
| 1383 | If the driver is not configured, the function returns | |
| 1384 | DRV_ NOTCONFIGURED. | |
| 1385 | | |
| 1386 | NOTE: When calling the function with a buffer size of 0, the | |
| 1387 | function will return the number of characters that can be | |
| 1388 | written in the parameter *thr_BufferSizePtr. In this | |
| 1389 | case, the in_BufferPtr can be set to NULL. | |
| 1390 | | |
| 1391 | Parameters : in_BufferPtr - This parameter points to the buffer | |
| 1392 | that is passed to the driver for | |
| 1393 | further processing | |
| 1394 | thr_BufferSizePtr - On call: number of characters to | |
| 1395 | write. If the function returns | |
| 1396 | DRV_BUFFER_FULL, it contains the | |
| 1397 | maximum number of characters that can | |
| 1398 | be written. If the function returns | |
| 1399 | DRV_OK, it contains the number of | |
| 1400 | characters written. If the function | |
| 1401 | returns DRV_INPROCESS, it contains 0. | |
| 1402 | | |
| 1403 | | |
| 1404 | Return : DRV_OK - Function successful | |
| 1405 | DRV_BUFFER_FULL - Not enough space | |
| 1406 | DRV_INPROCESS - Driver is busy writing data | |
| 1407 | DRV_NOTCONFIGURED - The driver is not yet configured | |
| 1408 | SOCKET_NOCONNECT - Connection not available | |
| 1409 | | |
| 1410 +------------------------------------------------------------------------------ | |
| 1411 */ | |
| 1412 /*lint -esym(613,auxb) suppress warning possibly use off NULL pointer auxb */ | |
| 1413 /*lint -esym(644,auxb) suppress warning possibly not initialized */ | |
| 1414 /*lint -e668 suppress warning possibly passing NULL pointer to memcpy */ | |
| 1415 USHORT socket_Write (void* in_BufferPtr, ULONG* thr_BufferSizePtr) | |
| 1416 { | |
| 1417 UBYTE rc = DRV_OK; | |
| 1418 int max_len, rest; | |
| 1419 char * auxb; | |
| 1420 ULONG buffer_size; | |
| 1421 | |
| 1422 buffer_size = *thr_BufferSizePtr & ~PRIM_FLAG_MASK; | |
| 1423 | |
| 1424 #ifndef _PSOS_ | |
| 1425 #ifdef SOCKET_DEBUG | |
| 1426 UBYTE Prim = 0; | |
| 1427 { | |
| 1428 char *ptr = in_BufferPtr; | |
| 1429 if ( *ptr == 'P' ) | |
| 1430 { | |
| 1431 OS_TIME time; | |
| 1432 char c = ptr[21]; | |
| 1433 fp = fopen(logfile, "at"); | |
| 1434 ptr[21] = 0; | |
| 1435 os_GetTime ( 0, &time ); | |
| 1436 fprintf (fp, "P%ld OUT: %s\n", time/10, &ptr[9] ); | |
| 1437 ptr[21] = c; | |
| 1438 fclose(fp); | |
| 1439 Prim = 1; | |
| 1440 } | |
| 1441 } | |
| 1442 #endif /* SOCKET_DEBUG */ | |
| 1443 #else /* _PSOS */ | |
| 1444 if( !tst_socket_initialized ) | |
| 1445 { | |
| 1446 if (tst_socket_in_TxLen > 0) | |
| 1447 { | |
| 1448 int nodelay = TRUE; | |
| 1449 if (setsockopt(tst_socket, SOL_SOCKET, SO_SNDBUF, | |
| 1450 (char*)&tst_socket_in_TxLen, sizeof(tst_socket_in_TxLen))) | |
| 1451 return DRV_INITFAILURE; | |
| 1452 if (setsockopt(tst_socket, IPPROTO_TCP, TCP_NODELAY, | |
| 1453 (char*)&nodelay, sizeof(nodelay))) | |
| 1454 return DRV_INITFAILURE; | |
| 1455 } | |
| 1456 tst_socket_initialized = 1; | |
| 1457 } | |
| 1458 #endif /* _PSOS_ */ | |
| 1459 | |
| 1460 if ( L_DCB.config & TI_MODE ) | |
| 1461 { | |
| 1462 /* add TI-MUX header */ | |
| 1463 auxb=(char*)malloc(buffer_size+2); | |
| 1464 memcpy((void*)(auxb+2),in_BufferPtr,buffer_size); | |
| 1465 auxb[0]=19; /* assigned to L23 */ | |
| 1466 auxb[1]=(char)buffer_size; | |
| 1467 in_BufferPtr=auxb; | |
| 1468 buffer_size+=2; | |
| 1469 } | |
| 1470 | |
| 1471 max_len = (L_DCB.tx_buffer_size < WRBUF_LEN) ? L_DCB.tx_buffer_size : WRBUF_LEN; | |
| 1472 if (max_len < (int)buffer_size) | |
| 1473 { | |
| 1474 #ifndef _PSOS_ | |
| 1475 #ifdef SOCKET_DEBUG | |
| 1476 char buffer[200]; | |
| 1477 char *ptr = in_BufferPtr; | |
| 1478 char c = ptr[21]; | |
| 1479 fp = fopen(bufferfullfile, "at"); | |
| 1480 if ( *ptr == 'P' ) | |
| 1481 ptr[21] = 0; | |
| 1482 else | |
| 1483 ptr[buffer_size] = 0; | |
| 1484 strcpy (buffer, "errno:" ); | |
| 1485 sprintf (&buffer[6], "%8d", WSAGetLastError() ); | |
| 1486 buffer[14] = ' '; | |
| 1487 memcpy (&buffer[15], ptr, (buffer_size)+1); | |
| 1488 fprintf (fp, "%s\n", buffer ); | |
| 1489 ptr[21] = c; | |
| 1490 fclose(fp); | |
| 1491 #endif /* SOCKET_DEBUG */ | |
| 1492 #endif /* _PSOS_ */ | |
| 1493 if ( L_DCB.config & TI_MODE ) | |
| 1494 free(auxb); | |
| 1495 *thr_BufferSizePtr = (unsigned int)max_len | | |
| 1496 (*thr_BufferSizePtr & PRIM_FLAG_MASK) ; | |
| 1497 return DRV_BUFFER_FULL ; | |
| 1498 } | |
| 1499 | |
| 1500 rest = MAX_ETH_LEN - (wrbuf_pos - wrbuf); | |
| 1501 if (buffer_size + 2 >= (unsigned int)rest) /* more than maximum ethernet packet size needed ?*/ | |
| 1502 { | |
| 1503 /*--------------------------------- | |
| 1504 send the buffer | |
| 1505 ---------------------------------*/ | |
| 1506 rc = socket_WriteToOS(wrbuf, (USHORT)(wrbuf_pos - wrbuf)); | |
| 1507 wrbuf_pos = wrbuf; | |
| 1508 | |
| 1509 if (rc != DRV_OK) | |
| 1510 { | |
| 1511 if ( L_DCB.config & TI_MODE ) | |
| 1512 free(auxb); | |
| 1513 *thr_BufferSizePtr = (*thr_BufferSizePtr & PRIM_FLAG_MASK) ; | |
| 1514 return rc; | |
| 1515 } | |
| 1516 } | |
| 1517 | |
| 1518 if ( !(L_DCB.config & TI_MODE) ) | |
| 1519 { | |
| 1520 /*------------------------------------------------ | |
| 1521 put the size of the data into buffer (MSB first) | |
| 1522 ------------------------------------------------*/ | |
| 1523 if (isLittleEndian) | |
| 1524 { | |
| 1525 *wrbuf_pos = *(((UBYTE*)&buffer_size)+1); /* MSB */ | |
| 1526 *(wrbuf_pos+1) = * (UBYTE*)&buffer_size; /* LSB */ | |
| 1527 } | |
| 1528 else | |
| 1529 *((USHORT*)wrbuf_pos) = (USHORT)buffer_size; | |
| 1530 wrbuf_pos += 2; | |
| 1531 } | |
| 1532 /*--------------------------------- | |
| 1533 put the data itself into buffer | |
| 1534 ---------------------------------*/ | |
| 1535 memcpy(wrbuf_pos, in_BufferPtr, (size_t)buffer_size); | |
| 1536 wrbuf_pos += buffer_size; | |
| 1537 | |
| 1538 if (socket_flush) | |
| 1539 { | |
| 1540 /*--------------------------------- | |
| 1541 send the buffer | |
| 1542 ---------------------------------*/ | |
| 1543 rc = socket_WriteToOS(wrbuf, (USHORT)(wrbuf_pos - wrbuf)); | |
| 1544 wrbuf_pos = wrbuf; | |
| 1545 socket_flush = 0; | |
| 1546 | |
| 1547 if (rc != DRV_OK) | |
| 1548 { | |
| 1549 *thr_BufferSizePtr = (*thr_BufferSizePtr & PRIM_FLAG_MASK) ; | |
| 1550 } | |
| 1551 } | |
| 1552 | |
| 1553 if ( L_DCB.config & TI_MODE ) | |
| 1554 { | |
| 1555 free(auxb); | |
| 1556 } | |
| 1557 return rc ; | |
| 1558 } | |
| 1559 | |
| 1560 /* | |
| 1561 +------------------------------------------------------------------------------ | |
| 1562 | Function : socket_Flush | |
| 1563 +------------------------------------------------------------------------------ | |
| 1564 | Description : This function flushes the socket write buffer where data | |
| 1565 | is stored until a complete packet can be sent or the | |
| 1566 | transmission is forced by an external setting of the | |
| 1567 | socket_flush flag. | |
| 1568 | | |
| 1569 | Parameters : --- | |
| 1570 | | |
| 1571 | Return : DRV_OK - Function completed successfully | |
| 1572 | | |
| 1573 +------------------------------------------------------------------------------ | |
| 1574 */ | |
| 1575 USHORT socket_Flush ( void ) | |
| 1576 { | |
| 1577 ULONG len = 0; | |
| 1578 | |
| 1579 socket_flush = 1; | |
| 1580 return ( socket_Write(NULL, &len) ); | |
| 1581 } | |
| 1582 | |
| 1583 /* | |
| 1584 +------------------------------------------------------------------------------ | |
| 1585 | Function : socket_SetSignal | |
| 1586 +------------------------------------------------------------------------------ | |
| 1587 | Description : This function is used to define a single or multiple signals | |
| 1588 | that is/are indicated to the process when the event identified | |
| 1589 | in the signal information data type as SignalType occurs. The | |
| 1590 | USART uses only the standard signals defined in [C_8415.0026]. | |
| 1591 | To remove a signal, call the function socket_ResetSignal(). | |
| 1592 | If one of the parameters of the signal information data is | |
| 1593 | invalid, the function returns DRV_INVALID_PARAMS. | |
| 1594 | If no signal call-back function has been defined at the time | |
| 1595 | of initialization, the driver returns DRV_SIGFCT_NOTAVAILABLE. | |
| 1596 | | |
| 1597 | Parameters : in_SignalIDPtr - Pointer to the signal information | |
| 1598 | data | |
| 1599 | | |
| 1600 | Return : DRV_OK - Function completed successfully | |
| 1601 | DRV_INVALID_PARAMS - One or more parameters are out of | |
| 1602 | range or invalid | |
| 1603 | DRV_SIGFCT_NOTAVAILABLE - Event signaling functionality is | |
| 1604 | not available | |
| 1605 | | |
| 1606 +------------------------------------------------------------------------------ | |
| 1607 */ | |
| 1608 USHORT socket_SetSignal (USHORT SignalType) | |
| 1609 { | |
| 1610 if (L_ClientData.Callback == NULL) | |
| 1611 return DRV_SIGFCT_NOTAVAILABLE ; | |
| 1612 | |
| 1613 if (SignalType & ALLOWED_SOCKET_SIGNALS) | |
| 1614 L_ClientData.EnabledSignals |= SignalType; | |
| 1615 else | |
| 1616 return DRV_INVALID_PARAMS ; | |
| 1617 return DRV_OK ; | |
| 1618 } | |
| 1619 | |
| 1620 /* | |
| 1621 +------------------------------------------------------------------------------ | |
| 1622 | Function : socket_ResetSignal | |
| 1623 +------------------------------------------------------------------------------ | |
| 1624 | Description : This function is used to remove previously set single or | |
| 1625 | multiple signals. The signals that are removed are identified | |
| 1626 | by the Signal Information Data element called SignalType. All | |
| 1627 | other elements of the Signal Information Data must be | |
| 1628 | identical to the signal(s) that are to be removed (process | |
| 1629 | handle and signal value). If the SignalID provided cannot be | |
| 1630 | located, the function returns DRV_INVALID_PARAMS. | |
| 1631 | If no signal call-back function has been defined at the time | |
| 1632 | of initialization, the driver returns DRV_SIGFCT_NOTAVAILABLE. | |
| 1633 | | |
| 1634 | Parameters : in_SignalIDPtr - Pointer to the signal information | |
| 1635 | data | |
| 1636 | | |
| 1637 | Return : DRV_OK - Function completed successfully | |
| 1638 | DRV_INVALID_PARAMS - One or more parameters are out of | |
| 1639 | range or invalid | |
| 1640 | DRV_SIGFCT_NOTAVAILABLE - Event signaling functionality is | |
| 1641 | not available | |
| 1642 | | |
| 1643 +------------------------------------------------------------------------------ | |
| 1644 */ | |
| 1645 USHORT socket_ResetSignal (USHORT SignalType) | |
| 1646 { | |
| 1647 if (L_ClientData.Callback == NULL) | |
| 1648 return DRV_SIGFCT_NOTAVAILABLE ; | |
| 1649 | |
| 1650 if (SignalType & ALLOWED_SOCKET_SIGNALS) | |
| 1651 L_ClientData.EnabledSignals &= ~SignalType; | |
| 1652 else | |
| 1653 return DRV_INVALID_PARAMS ; | |
| 1654 | |
| 1655 return DRV_OK ; | |
| 1656 } | |
| 1657 | |
| 1658 /* | |
| 1659 +------------------------------------------------------------------------------ | |
| 1660 | Function : socket_SetConfig | |
| 1661 +------------------------------------------------------------------------------ | |
| 1662 | Description : This function is used to configure the driver (port, | |
| 1663 | transmission rate, flow control, etc). The driver can be | |
| 1664 | configured at any one time before a connection is opened. The | |
| 1665 | parameters that can be configured are included in the USART's | |
| 1666 | device control block socket_DCB_Type. For detailed information | |
| 1667 | about the contents of the device control block, refer to | |
| 1668 | Chapter 2.1.1. If any value of the configuration is out of | |
| 1669 | range or invalid in combination with any other value of the | |
| 1670 | configuration, the function returns DRV_INVALID_PARAMS. | |
| 1671 | Call the socket_GetConfig() function to retrieve the driver's | |
| 1672 | configuration. | |
| 1673 | The driver needs to be configured after initialization. Only | |
| 1674 | the following functions can be called while the driver is not | |
| 1675 | configured: socket_Clear, socket_SetSignal and socket_GetSignal. | |
| 1676 | All other functions return DRV_NOTCONFIGURED. | |
| 1677 | | |
| 1678 | Parameters : in_DCBPtr - Pointer to the driver control block | |
| 1679 | | |
| 1680 | Return : DRV_OK - Function completed successfully | |
| 1681 | DRV_INVALID_PARAMS - One or more parameters are out of | |
| 1682 | range or invalid | |
| 1683 | | |
| 1684 +------------------------------------------------------------------------------ | |
| 1685 */ | |
| 1686 USHORT socket_SetConfig (char* in_DCBPtr) | |
| 1687 { | |
| 1688 char token [SOCKET_MAX_LEN_HOSTNAME+1]; | |
| 1689 USHORT port; | |
| 1690 unsigned int len; | |
| 1691 | |
| 1692 if ( (len = GetNextToken (in_DCBPtr, token, " #")) == 0) | |
| 1693 { | |
| 1694 return DRV_INVALID_PARAMS; | |
| 1695 } | |
| 1696 else | |
| 1697 { | |
| 1698 in_DCBPtr += (len+1); | |
| 1699 } | |
| 1700 | |
| 1701 port = (USHORT)atoi(token); | |
| 1702 | |
| 1703 if ( (len = GetNextToken (in_DCBPtr, token, " #")) == 0) | |
| 1704 { | |
| 1705 return DRV_INVALID_PARAMS; | |
| 1706 } | |
| 1707 else | |
| 1708 { | |
| 1709 in_DCBPtr += (len+1); | |
| 1710 } | |
| 1711 | |
| 1712 if ( !strcmp ( DRV_TI_MODE, token ) ) | |
| 1713 { | |
| 1714 L_DCB.config = TI_MODE; | |
| 1715 sock_state = SST_DATAx; | |
| 1716 } | |
| 1717 else if ( !strcmp ( DRV_DEFAULT, token ) ) | |
| 1718 { | |
| 1719 L_DCB.config = 0; | |
| 1720 sock_state = SST_PL0; | |
| 1721 } | |
| 1722 else | |
| 1723 return DRV_INVALID_PARAMS; | |
| 1724 | |
| 1725 if ( (len = GetNextToken (in_DCBPtr, token, " #")) == 0 ) | |
| 1726 { | |
| 1727 #ifdef _TOOLS_ | |
| 1728 gethostname (token,SOCKET_MAX_LEN_HOSTNAME); | |
| 1729 #endif /* _TOOLS_ */ | |
| 1730 } | |
| 1731 | |
| 1732 if (L_ThreadActive) | |
| 1733 { | |
| 1734 /* check if host is already used */ | |
| 1735 if (strcmp(L_DCB.hostname, token)==0 && L_DCB.port==port) | |
| 1736 { | |
| 1737 #ifdef _TOOLS_ | |
| 1738 printf("SOCKET: keeping connection to host %s on port %u\n",L_DCB.hostname,L_DCB.port); | |
| 1739 #endif | |
| 1740 return DRV_OK; | |
| 1741 } | |
| 1742 | |
| 1743 socket_Close(); | |
| 1744 } | |
| 1745 | |
| 1746 L_DCB.port=port; | |
| 1747 strcpy ( L_DCB.hostname, token); | |
| 1748 | |
| 1749 if (socket_Open () != DRV_OK) | |
| 1750 { | |
| 1751 return DRV_INVALID_PARAMS ; | |
| 1752 } | |
| 1753 | |
| 1754 return DRV_OK ; | |
| 1755 } | |
| 1756 | |
| 1757 /* | |
| 1758 +------------------------------------------------------------------------------ | |
| 1759 | Function : socket_GetConfig | |
| 1760 +------------------------------------------------------------------------------ | |
| 1761 | Description : This function is used to retrieve the configuration of the | |
| 1762 | driver. The configuration is returned in the driver control | |
| 1763 | block to which the pointer provided out_DCBPtr points. For | |
| 1764 | detailed information about the contents of the device control | |
| 1765 | block, refer to Chapter 2.1.1. The configuration can be | |
| 1766 | requested at any one time. | |
| 1767 | If the driver is not configured, the function returns | |
| 1768 | DRV_ NOTCONFIGURED. | |
| 1769 | | |
| 1770 | Parameters : out_DCBPtr - Pointer to the driver control block | |
| 1771 | | |
| 1772 | Return : DRV_OK - Function completed successfully | |
| 1773 | DRV_INVALID_PARAMS - One or more parameters are out of | |
| 1774 | range or invalid | |
| 1775 | | |
| 1776 +------------------------------------------------------------------------------ | |
| 1777 */ | |
| 1778 USHORT socket_GetConfig (socket_DCB_Type* out_DCBPtr) | |
| 1779 { | |
| 1780 if (out_DCBPtr == NULL) | |
| 1781 return DRV_INVALID_PARAMS ; | |
| 1782 | |
| 1783 memcpy (out_DCBPtr, &L_DCB, sizeof (L_DCB)) ; | |
| 1784 return DRV_OK ; | |
| 1785 } | |
| 1786 | |
| 1787 /* | |
| 1788 +------------------------------------------------------------------------------ | |
| 1789 | Function : socket_Init | |
| 1790 +------------------------------------------------------------------------------ | |
| 1791 | Description : The function initializes the internal data of the driver. | |
| 1792 | The function returns DRV_INITIALIZED if the driver has | |
| 1793 | already been initialized and is ready to be used or is | |
| 1794 | already in use. In the case of an initialization failure, | |
| 1795 | i.e. the driver cannot be used, the function returns | |
| 1796 | DRV_INITFAILURE. | |
| 1797 | | |
| 1798 | Parameters : in_SignalCBPtr - This parameter points to the function that | |
| 1799 | is called at the time an event that is to | |
| 1800 | be signaled occurs. This value can be set | |
| 1801 | to NULL if event signaling should not be | |
| 1802 | possible. | |
| 1803 | | |
| 1804 | Return : DRV_OK - Initialization successful | |
| 1805 | DRV_INITIALIZED - Driver already initialized | |
| 1806 | DRV_INITFAILURE - Initialization failed | |
| 1807 | | |
| 1808 +------------------------------------------------------------------------------ | |
| 1809 */ | |
| 1810 GLOBAL USHORT socket_Init ( USHORT DrvHandle, T_DRV_CB_FUNC CallbackFunc, T_DRV_EXPORT const **DrvInfo ) | |
| 1811 { | |
| 1812 static const T_DRV_EXPORT Socket_Info = | |
| 1813 { | |
| 1814 "SOCKET", | |
| 1815 0, | |
| 1816 { | |
| 1817 #ifdef _TOOLS_ | |
| 1818 socket_Init, | |
| 1819 #endif | |
| 1820 socket_Exit, | |
| 1821 socket_Read, | |
| 1822 socket_Write, | |
| 1823 NULL, | |
| 1824 NULL, | |
| 1825 socket_Flush, | |
| 1826 socket_SetSignal, | |
| 1827 socket_ResetSignal, | |
| 1828 socket_SetConfig, | |
| 1829 NULL, | |
| 1830 NULL, | |
| 1831 } | |
| 1832 }; | |
| 1833 union | |
| 1834 { | |
| 1835 USHORT s; | |
| 1836 UBYTE b[2]; | |
| 1837 } test; | |
| 1838 | |
| 1839 #ifndef _PSOS_ | |
| 1840 #if defined (_VXWORKS_) || defined (_LINUX_) || defined (_SOLARIS_) | |
| 1841 /* ToDo: vxWorks-libs initiieren | |
| 1842 sockLib | |
| 1843 inetLib | |
| 1844 */ | |
| 1845 #else /* _VXWORKS_ */ | |
| 1846 WSADATA WSAData; | |
| 1847 if (WSAStartup(MAKEWORD(1,1), &WSAData)) | |
| 1848 return DRV_INITFAILURE; | |
| 1849 #endif /* _VXWORKS_ */ | |
| 1850 #endif | |
| 1851 | |
| 1852 test.s = 1; | |
| 1853 isLittleEndian = (test.b[0] == 1); | |
| 1854 | |
| 1855 L_ThreadActive = FALSE ; | |
| 1856 L_DCB.config = 0; | |
| 1857 L_DCB.port = 6392; | |
| 1858 L_DCB.tx_buffer_size = TX_BUFFER_SIZE; | |
| 1859 L_DCB.rx_buffer_size = RX_BUFFER_SIZE ; | |
| 1860 L_DCB.tx_timeout_msec = TX_TIMEOUT_MSEC; | |
| 1861 L_DCB.rx_timeout_msec = RX_TIMEOUT_MSEC; | |
| 1862 *L_DCB.hostname = 0 ; | |
| 1863 L_ClientData.Connect = FALSE; | |
| 1864 L_ClientData.SocketHandle = DrvHandle; | |
| 1865 L_ClientData.Socket = INVALID_SOCKET ; | |
| 1866 L_ClientData.Listener = INVALID_SOCKET ; | |
| 1867 #ifdef _PSOS_ | |
| 1868 tst_socket = INVALID_SOCKET ; | |
| 1869 tst_socket_initialized = 0; | |
| 1870 tst_socket_in_TxLen = 0; | |
| 1871 #endif | |
| 1872 | |
| 1873 L_ClientData.Callback = CallbackFunc ; | |
| 1874 L_ClientData.EnabledSignals = ALLOWED_SOCKET_SIGNALS ; | |
| 1875 *DrvInfo = &Socket_Info; | |
| 1876 #ifdef SOCKET_DEBUG | |
| 1877 fp = fopen(logfile,"wt"); | |
| 1878 fclose(fp); | |
| 1879 fp = fopen(inprocessfile,"wt"); | |
| 1880 fclose(fp); | |
| 1881 fp = fopen(bufferfullfile,"wt"); | |
| 1882 fclose(fp); | |
| 1883 fp = fopen(noconnectfile1,"wt"); | |
| 1884 fclose(fp); | |
| 1885 fp = fopen(noconnectfile2,"wt"); | |
| 1886 fclose(fp); | |
| 1887 fp = fopen(noconnectfile3,"wt"); | |
| 1888 fclose(fp); | |
| 1889 fp = fopen(readerrorfile,"wt"); | |
| 1890 fclose(fp); | |
| 1891 #endif /* SOCKET_DEBUG */ | |
| 1892 return DRV_OK ; | |
| 1893 } | |
| 1894 | |
| 1895 /*==== END OF FILE ==========================================================*/ | |
| 1896 |
