![]() |
![]() |
![]() |
![]() |
mti_AddSocketInputReadyCB()
Adds or removes a socket input ready callback.
Syntax
mti_AddSocketInputReadyCB( socket_desc, func, param )Returns
Arguments
Description
mti_AddSocketInputReadyCB() puts a watch on the specified socket descriptor. Whenever the socket descriptor has data available for reading, the specified function is called along with its parameter.
To remove a previously added callback, call mti_AddSocketInputReadyCB() with the same socket descriptor but with a NULL function pointer.
mti_AddSocketInputReadyCB() and mti_AddSocketOutputReadyCB() are useful in setting up cosimulation environments where FLI code uses sockets to communicate with other processes. In the course of initialization, a cosimulation application typically would use standard system library routines to create or open a socket and obtain a socket descriptor and then call mti_AddSocketInputReadyCB() and mti_AddSocketOutputReadyCB() to set up the callback functions. During simulation, FLI code may initiate a non-blocking I/O operation on the socket (again using standard system library routines) and immediately return control to the simulator. When the I/O is completed, the simulator invokes the callback function which could check for errors, handle received data, or initiate another non-blocking I/O operation before returning to the simulator.
Related functions
Example
FLI code
#include <mti.h> #include <stdio.h> #include <fcntl.h> #include <sys/types.h> #include <stdlib.h> #ifdef WIN32 #include <winsock.h> #else #include <unistd.h> #include <sys/time.h> #include <sys/param.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> /* gethostbyname() */ #endif #ifdef HP700 #include <resolv.h> #endif #ifdef WIN32 #define MAXHOSTNAMELEN MAXGETHOSTSTRUCT #else #define SOCKET_ERROR -1 #define INVALID_SOCKET -1 typedef int SOCKET; #endif void sockCB( void * sock ) { int i; char buf[1]; #ifdef WIN32 i = recv( (SOCKET)sock, buf, sizeof(buf), 0 ); #else i = read( (SOCKET)sock, buf, sizeof(buf) ); #endif mti_PrintFormatted( "Read returned %d - Read %c\n", i, buf[0] ); if ( (i == 0) || (buf[0] == 'C') ) { /* Remove the callback. */ mti_AddSocketInputReadyCB( (SOCKET)sock, (mtiVoidFuncPtrT)0, 0 ); mti_PrintMessage("Closing socket\n"); close( (SOCKET)sock ); } } void loadDoneCB( void * sock ) { mti_PrintMessage( "Load Done: Adding socket callback.\n" ); mti_AddSocketInputReadyCB( (SOCKET)sock, (mtiVoidFuncPtrT)sockCB, sock ); } void initForeign( mtiRegionIdT region, /* The ID of the region in which this */ /* foreign architecture is instantiated. */ char *param, /* The last part of the string in the */ /* foreign attribute. */ mtiInterfaceListT *generics, /* A list of generics for the foreign model.*/ mtiInterfaceListT *ports /* A list of ports for the foreign model. */ ) { char hostname[MAXHOSTNAMELEN] = "localhost"; int statusFlags; int server_length; int status; int retry_cnt = 0; short portNum = 0; struct sockaddr_in server; struct hostent *hp; SOCKET sock = INVALID_SOCKET; #ifdef WIN32 WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 1, 1 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { mti_PrintMessage( "Cannot find a useable winsock.dll.\n" ); return; } /* Confirm that the Windows Sockets DLL supports 1.1. Note that if * the DLL supports versions greater than 1.1 in addition to 1.1, * it will still return 1.1 in wVersion since that is the version * we requested. */ if ( (LOBYTE( wsaData.wVersion ) != 1) || (HIBYTE( wsaData.wVersion ) != 1) ) { mti_PrintMessage( "Cannot find a useable winsock.dll.\n" ); WSACleanup(); return; } /* The Windows Sockets DLL is acceptable. Proceed. */ #endif sock = socket( AF_INET, SOCK_STREAM, 0 ); if ( sock == INVALID_SOCKET ) { #ifdef WIN32 DWORD le = GetLastError(); mti_PrintFormatted( "Error opening socket. Error=%d\n", le ); #else mti_PrintMessage( "Error opening socket.\n" ); #endif return; } while ( retry_cnt < 2 ) { memset( (char *)&server, 0, sizeof(server) ); server.sin_family = AF_INET; if ( (hp = gethostbyname(hostname)) == 0 ) { mti_PrintFormatted( "%s: Unknown host.\n", hostname ); close( sock ); return; } memcpy( (char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length ); portNum = 19; /* 'chargen' */ server.sin_port = htons(portNum); server_length = sizeof(server); status = connect( sock, (struct sockaddr *)&server, server_length ); if ( status < 0 ) { if ( retry_cnt++ > 1 ) { mti_PrintFormatted( "Error connecting to server %s:%d\n", hostname, portNum ); close( sock ); } else { strcpy( hostname, "map" ); /* Put your hostname here. */ } } } #ifdef WIN32 { unsigned long non_blocking = 1; status = ioctlsocket( sock, FIONBIO, &non_blocking ); if ( status == SOCKET_ERROR ) { perror( "Setting socket status" ); } } #else statusFlags = fcntl( sock, F_GETFL ); if ( statusFlags == SOCKET_ERROR ) { perror( "Getting socket status" ); } else { int ctlValue; statusFlags |= O_NONBLOCK; ctlValue = fcntl( sock, F_SETFL, statusFlags ); if ( ctlValue == SOCKET_ERROR ) { perror( "Setting socket status" ); } } #endif mti_AddLoadDoneCB( (mtiVoidFuncPtrT)loadDoneCB, (void *)sock ); }HDL code
entity top is end top; architecture a of top is signal s1 : bit := '0'; begin s1 <= not s1 after 5 ns; end a;Simulation output
% vsim -c -foreign "initForeign ./for_model.sl" top Reading .../modeltech/sunos5/../tcl/vsim/pref.tcl # 5.4b # vsim -foreign {initForeign ./for_model.sl} -c top # Loading .../modeltech/sunos5/../std.standard # Loading work.top(a) # Loading ./for_model.sl # Load Done: Adding socket callback. # Read returned 1 - Read # Read returned 1 - Read ! # Read returned 1 - Read " # Read returned 1 - Read # # Read returned 1 - Read $ # Read returned 1 - Read % # Read returned 1 - Read & # Read returned 1 - Read ' # Read returned 1 - Read ( # Read returned 1 - Read ) # Read returned 1 - Read * # Read returned 1 - Read + # Read returned 1 - Read , # Read returned 1 - Read - # Read returned 1 - Read . # Read returned 1 - Read / # Read returned 1 - Read 0 # Read returned 1 - Read 1 # Read returned 1 - Read 2 # Read returned 1 - Read 3 # Read returned 1 - Read 4 # Read returned 1 - Read 5 # Read returned 1 - Read 6 # Read returned 1 - Read 7 # Read returned 1 - Read 8 # Read returned 1 - Read 9 # Read returned 1 - Read : # Read returned 1 - Read ; # Read returned 1 - Read < # Read returned 1 - Read = # Read returned 1 - Read > # Read returned 1 - Read ? # Read returned 1 - Read @ # Read returned 1 - Read A # Read returned 1 - Read B # Read returned 1 - Read C # Closing socket VSIM 1> quit
![]() Model Technology Inc. Voice: (503) 641-1340 Fax: (503)526-5410 http://www.model.com sales@model.com |
![]() |
![]() |
![]() |
![]() |