126 const int size = 1024;
127 const int nNewCha = strlen(toAdd);
128 const int nBufCha = strlen(*buffer);
130 if ( *bufLen < nNewCha + nBufCha + 1){
131 *bufLen = *bufLen + size * (((nNewCha + nBufCha) / size)+1);
132 *buffer = realloc(*buffer, *bufLen);
133 if (*buffer == NULL) {
134 perror(
"Realloc failed in save_append.");
136 fprintf(
f1,
"Realloc failed in save_append.\n");
142 strcpy(*buffer + strlen(*buffer), toAdd);
160 int nDbl,
int nInt,
int nBoo,
162 double dblVal[],
int intVal[],
int booVal[],
163 char* *buffer,
int *bufLen)
168 memset((
char*) *buffer,
'\0', *bufLen);
174 if ( retVal != 0 )
return retVal;
175 sprintf(temCha,
"%d ", flag);
177 if ( retVal != 0 )
return retVal;
180 sprintf(temCha,
"%d ", nDbl);
182 if ( retVal != 0 )
return retVal;
183 sprintf(temCha,
"%d ", nInt);
185 if ( retVal != 0 )
return retVal;
186 sprintf(temCha,
"%d ", nBoo);
188 if ( retVal != 0 )
return retVal;
189 sprintf(temCha,
"%20.15e ", curSimTim);
191 if ( retVal != 0 )
return retVal;
193 for(i = 0; i < nDbl; i++){
194 sprintf(temCha,
"%20.15e ", dblVal[i]);
196 if ( retVal != 0 )
return retVal;
198 for(i = 0; i < nInt; i++){
199 sprintf(temCha,
"%d ", intVal[i]);
201 if ( retVal != 0 )
return retVal;
203 for(i = 0; i < nBoo; i++){
204 sprintf(temCha,
"%d ", booVal[i]);
206 if ( retVal != 0 )
return retVal;
211 sprintf(temCha,
"\n");
213 if ( retVal != 0 )
return retVal;
231 *val = strtol(nptr, endptr, base);
234 if ((errno == ERANGE)
235 || (errno != 0 && *val == 0)) {
236 perror(
"strtol caused error.");
237 if (strlen(nptr) < 1) {
238 fprintf(stderr,
"strtol() was called with a string of length less than 1. This can occur when no data is read.\n");
240 fprintf(stderr,
"strtol was called with strtol(%s, %s, %d)\n", nptr, *endptr, base);
244 if (*endptr == nptr) {
247 fprintf(stderr,
"Error: No digits were found in getIntCheckError.\n");
248 fprintf(stderr,
"Further characters after number: %s\n", *endptr);
249 fprintf(stderr,
"Sending EXIT_FAILURE = : %d\n", EXIT_FAILURE);
267 *val = strtod(nptr, endptr);
270 if ((errno == ERANGE && (*val == HUGE_VAL || *val == -HUGE_VAL))
271 || (errno != 0 && *val == 0)) {
272 perror(
"strtod caused error.");
275 if (*endptr == nptr) {
276 fprintf(stderr,
"Error: No digits were found in getDoubleCheckError.\n");
277 fprintf(stderr,
"Further characters after number: %s\n", *endptr);
278 fprintf(stderr,
"Sending EXIT_FAILURE = : %d\n", EXIT_FAILURE);
298 char **endptr,
const int base,
300 int *nDbl,
int *nInt,
int *nBoo)
345 int *nDbl,
int *nInt,
int *nBoo,
347 double dblVal[],
int intVal[],
int booVal[])
354 fla, nDbl, nInt, nBoo);
357 fprintf(
f1,
"Error while disassembling the header of the buffer.\n");
367 fprintf(
f1,
"Error while getting the current simulation time.\n");
373 for(i=0; i < *nDbl; i++){
377 fprintf(
f1,
"Error while getting double %d of %d.\n", i, *nDbl);
384 for(i=0; i < *nInt; i++){
388 fprintf(
f1,
"Error while getting integer %d of %d.\n", i, *nInt);
395 for(i=0; i < *nBoo; i++){
399 fprintf(
f1,
"Error while getting boolean %d of %d.\n", i, *nBoo);
415 char *xPat =
"//ipc/socket[@port]";
420 perror(
"malloc failed in getsocketportnumber.");
422 fprintf(
f1,
"malloc failed in getsocketportnumber.\n");
427 retVal = atoi((
char*)res);
455 char *xPat =
"//ipc/socket[@hostname]";
473 struct hostent* FAR server;
475 WORD wVersionRequested;
477 struct hostent *server;
479 struct sockaddr_in serAdd;
483 f1 = fopen (
"utilSocket.log",
"w");
485 fprintf(stderr,
"Could not open file '%s'\n",
"utilSocket.log");
489 fprintf(
f1,
"utilSocket: Establishing socket based on file %s.\n", docname);
493 if (hostname == NULL) {
494 perror(
"malloc failed in establishclientsocket.");
496 fprintf(
f1,
"malloc failed in establishclientsocket.\n");
504 fprintf(
f1,
"Getting socket port number.\n");
508 fprintf(
f1,
"Received socket port number %d.\n", portNo);
511 fprintf(stderr,
"Error: Could not obtain socket port number. Return value = %d.\n", portNo);
513 fprintf(
f1,
"Error: Could not obtain socket port number. Return value = %d.\n", portNo);
518 fprintf(
f1,
"Socket port number = %d.\n", portNo);
525 fprintf(
f1,
"Error: Could not obtain socket hostname. Return value = %d.\n", retVal);
531 wVersionRequested = MAKEWORD( 2, 2 );
532 retVal = WSAStartup( wVersionRequested, &wsaData );
537 fprintf(
f1,
"Error: Could not find a usable WinSock DLL.\n");
538 fprintf(
f1,
"WSAGetLastError = %d\n", WSAGetLastError());
547 if ( LOBYTE( wsaData.wVersion ) != 2 ||
548 HIBYTE( wsaData.wVersion ) != 2 ) {
552 fprintf(
f1,
"Error: Could not find a usable WinSock DLL for requested version.\n");
558 fprintf(
f1,
"WinSock DLL is acceptable.\n");
562 sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
565 fprintf(
f1,
"Error opening socket. sockfd = %d.\n", sockfd);
570 fprintf(
f1,
"Socket opened, sockfd = %d.\n", sockfd);
578 if( setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (
char *)&arg,
sizeof(arg)) != 0){
580 fprintf(
f1,
"Error setting socket option keep alive.\n");
581 fprintf(
f1,
"Error flag errno = %d.\n", errno);
594 server = gethostbyname(hostname);
595 if (server == NULL) {
597 fprintf(
f1,
"Error, no such host: %s\n", hostname);
599 fprintf(
f1,
"gethostbyname(%s) returned %d, which means '%s'\n", hostname, h_errno, hstrerror(h_errno));
603 server = gethostbyname(
"localhost");
604 if (server == NULL) {
606 fprintf(
f1,
"Error, no such host: %s\n",
"localhost");
608 fprintf(
f1,
"gethostbyname(%s) returned %d, which means '%s'\n",
"localhost", h_errno, hstrerror(h_errno));
615 fprintf(
f1,
"Warning: gethostbyname(\"%s\") returned null, but gethostbyname(\"localhost\") returned non-null.\n", hostname);
616 fprintf(
f1,
"This sometimes happens on a Mac.\n");
618 fprintf(stderr,
"Warning: gethostbyname(\"%s\") returned null, but gethostbyname(\"localhost\") returned non-null.\n", hostname);
619 fprintf(stderr,
"This sometimes happens on a Mac.\n");
624 serverIP = inet_ntoa(*(
struct in_addr *)*server->h_addr_list);
625 memset((
char *) &serAdd,
'\0',
sizeof(serAdd));
626 serAdd.sin_family = AF_INET;
627 serAdd.sin_addr.s_addr = inet_addr(serverIP);
628 serAdd.sin_port = htons(portNo);
632 retVal = connect(sockfd, (
const struct sockaddr*)&serAdd,
sizeof(serAdd));
635 fprintf(stderr,
"Error when connecting to socket %d on %s: WSAGetLastError = %d\n", portNo, serverIP, WSAGetLastError());
637 fprintf(stderr,
"Error when connecting to socket %d on %s: %s\n", portNo, serverIP, strerror(errno));
641 fprintf(
f1,
"Error when connecting to socket %d on %s: WSAGetLastError = %d\n", portNo, serverIP, WSAGetLastError());
643 fprintf(
f1,
"Error when connecting to socket %d on %s: %s\n", portNo, serverIP, strerror(errno));
672 const int *
nDblWri,
const int *nIntWri,
const int *nBooWri,
674 double dblValWri[],
int intValWri[],
int booValWri[])
683 f1 = fopen (
"utilSocket.log",
"w");
685 fprintf(stderr,
"Cannot open file %s\n",
"utilSocket.log");
693 fprintf(stderr,
"Error: Called write to socket with negative socket number.\n");
694 fprintf(stderr,
" sockfd : %d\n", *sockfd);
696 fprintf(
f1,
"Error: Called write to socket with negative socket number.\n");
706 fprintf(
f1,
"Assembling buffer.\n", *sockfd);
708 buffer = malloc(bufLen);
709 if (buffer == NULL) {
710 perror(
"malloc failed in writetosocket.");
712 fprintf(
f1,
"malloc failed in writetosocket.\n");
720 dblValWri, intValWri, booValWri,
724 fprintf(stderr,
"Error: Failed to allocate memory for buffer before writing to socket.\n");
725 fprintf(stderr,
" retVal : %d\n", retVal);
726 fprintf(stderr,
" Message: %s\n", strerror(errno));
728 fprintf(
f1,
"Error: Failed to allocate memory for buffer before writing to socket.\n");
730 fprintf(
f1,
" Message: %s\n", strerror(errno));
739 fprintf(
f1,
"Write to socket with fd = %d\n", *sockfd);
744 retVal = send(*sockfd,buffer,strlen(buffer), 0);
746 retVal = write(*sockfd,buffer,strlen(buffer));
751 fprintf(
f1,
"Wrote %d characters to socket.\n", retVal);
753 fprintf(
f1,
"Error writing to socket: Return value = %d.\n", retVal);
758 fprintf(
f1,
"Error writing to socket: WSAGetLastError = %d\n", WSAGetLastError());
760 fprintf(
f1,
"Error writing to socket: %s\n", strerror(errno));
795 fprintf(
f1,
"sendclientmessage wrote flag %d, return value = %d.\n",
804 if (inpBuf == NULL) {
805 perror(
"malloc failed in sendclientmessage.");
807 fprintf(
f1,
"malloc failed in sendclientmessage.\n");
843 #define MSG_WAITALL 0x8 // do not complete until packet is completely filled
849 perror(
"Failed to peek at socket.");
853 &fla, &nDbl, &nInt, &nBoo);
855 perror(
"Failed to disassemble header buffer.");
869 if ( ( nInt > 0 ) || ( nBoo > 0) ){
870 fprintf(stderr,
"Error: Integers and booleans are currently not\n");
871 fprintf(stderr,
" implemented in utilSocket:getrequiredbufferlength.\n");
872 fprintf(stderr,
" Received %d integers and %d boolean.\n", nInt, nBoo);
900 int *nDblRea,
int *nIntRea,
int *nBooRea,
902 double dblValRea[],
int intValRea[],
int booValRea[])
909 fprintf(stderr,
"Error: Called read from socket with negative socket number.\n");
910 fprintf(stderr,
" sockfd : %d\n", *sockfd);
912 fprintf(
f1,
"Error: Called read from socket with negative socket number.\n");
931 if (inpBuf == NULL) {
932 perror(
"malloc failed in readfromsocket.");
934 fprintf(
f1,
"malloc failed in readfromsocket.\n");
945 fprintf(
f1,
"Error reading: WSAGetLastError = %d\n", WSAGetLastError());
947 fprintf(
f1,
"Error reading: %s\n", strerror(errno));
958 nDblRea, nIntRea, nBooRea,
960 dblValRea, intValRea, booValRea);
978 char *buffer,
int *bufLen){
982 int maxChaRea = 8192;
988 #define MSG_WAITALL 0x8
989 retVal = recv(*sockfd, buffer, *bufLen, 0);
991 retVal = read(*sockfd, &buffer[chaSta], maxChaRea);
998 fprintf(stderr,
"Error: The server closed the socket while the client was reading.\n");
1002 fprintf(stderr,
"Error: Unspecified error when reading from socket.\n");
1007 if ( NULL == memchr(&buffer[chaSta],
'\n', retVal) ){
1010 fprintf(stderr,
"Error: This version of the socket interface cannot process such large data.\n");
1011 fprintf(stderr,
" You will need to update to BCVTB 0.8.0 or higher.\n");
1013 fprintf(
f1,
"Error: This version of the socket interface cannot process such large data.\n");
1014 fprintf(
f1,
" You will need to update to BCVTB 0.8.0 or higher.\n");
1022 }
while(reachedEnd == 0);
1050 const int *flaWri,
int *
flaRea,
1051 const int *
nDblWri,
const int *nIntWri,
const int *nBooWri,
1052 int *nDblRea,
int *nIntRea,
int *nBooRea,
1054 double dblValWri[],
int intValWri[],
int booValWri[],
1056 double dblValRea[],
int intValRea[],
int booValRea[]){
1060 f1 = fopen (
"utilSocket.log",
"w");
1062 fprintf(stderr,
"Cannot open file %s\n",
"utilSocket.log");
1066 fprintf(
f1,
"*** BCVTB client log file.\n", *simTimWri);
1067 fprintf(
f1,
"*************************.\n", *simTimWri);
1068 fprintf(
f1,
"Writing to socket at time = %e\n", *simTimWri);
1084 nDblWri, nIntWri, nBooWri,
1086 dblValWri, intValWri, booValWri);
1093 nDblRea, nIntRea, nBooRea,
1095 dblValRea, intValRea, booValRea);
1098 fprintf(
f1,
"Finished exchanging data with socket: simTimRea=%e, flag=%d.\n", *simTimRea, retVal);
1120 const int *flaWri,
int *
flaRea,
1134 nDblWri, &zer, &zer,
1135 nDblRea, &nIntRea, &nBooRea,
1137 dblValWri, NULL, NULL,
1139 dblValRea, intValRea, booValRea);
1161 const int *flaWri,
int *
flaRea,
1168 const int* flaExport){
1174 if (*flaExport == 1){
1179 nDblWri, &zer, &zer,
1180 nDblRea, &nIntRea, &nBooRea,
1182 dblValWri, NULL, NULL,
1184 dblValRea, intValRea,
1195 return closesocket(*sockfd);
1197 return close(*sockfd);
1202 int main(
int argc,
const char* argv[] )
1204 fprintf(stderr,
"Calling establ...'\n");
int exchangedoubleswithsocketFMU(const int *sockfd, const int *flaWri, int *flaRea, const int *nDblWri, int *nDblRea, double *simTimWri, double dblValWri[], double *simTimRea, double dblValRea[], const int *flaExport)
Exchanges data with the socket.
int getIntCheckError(const char *nptr, char **endptr, const int base, int *val)
Gets an integer and does the required error checking.
int exchangedoubleswithsocket(const int *sockfd, const int *flaWri, int *flaRea, const int *nDblWri, int *nDblRea, double *simTimWri, double dblValWri[], double *simTimRea, double dblValRea[])
Exchanges data with the socket.
int main(int argc, const char *argv[])
int REQUIRED_WRITE_LENGTH
int getsocketportnumber(const char *const docname)
Gets the port number for the BSD socket communication.
int getDoubleCheckError(const char *nptr, char **endptr, double *val)
Gets a double and does the required error checking.
int getRequiredReadBufferLength(const int *sockfd)
Returns the required socket buffer length by reading from the socket how many data it contains...
#define MAINVERSION
The main version of the socket interface.
int disassembleHeaderBuffer(const char *buffer, char **endptr, const int base, int *fla, int *nDbl, int *nInt, int *nBoo)
Disassembles the header of the buffer that has been received through the IPC.
int establishclientsocket(const char *const docname)
Establishes a connection to the socket.
int getrequiredbufferlength(const int nDbl, const int nInt, const int nBoo)
Returns the required socket buffer length.
fprintf([' ', 'Trying to send client error from MATLAB to the BCVTB.'])
int getmainversionnumber()
Returns the version number of the client.
int SERVER_VERSION
This will be overwritten to contain the version number of the server.
int sendclientmessage(const int *sockfd, const int *flaWri)
Writes a message flag to the socket stream.
end Get return values from pointers flaRea
int closeipc(int *sockfd)
Closes the inter process communication socket.
int getsockethost(const char *const docname, char *const hostname)
Gets the hostname for the BSD socket communication.
int writetosocket(const int *sockfd, const int *flaWri, const int *nDblWri, const int *nIntWri, const int *nBooWri, double *curSimTim, double dblValWri[], int intValWri[], int booValWri[])
Writes data to the socket.
int readbufferfromsocket(const int *sockfd, char *buffer, int *bufLen)
Reads a character buffer from the socket.
int save_append(char **buffer, const char *toAdd, int *bufLen)
Appends a character array to another character array.
int exchangewithsocket(const int *sockfd, const int *flaWri, int *flaRea, const int *nDblWri, const int *nIntWri, const int *nBooWri, int *nDblRea, int *nIntRea, int *nBooRea, double *simTimWri, double dblValWri[], int intValWri[], int booValWri[], double *simTimRea, double dblValRea[], int intValRea[], int booValRea[])
Exchanges data with the socket.
int readfromsocket(const int *sockfd, int *flaRea, int *nDblRea, int *nIntRea, int *nBooRea, double *curSimTim, double dblValRea[], int intValRea[], int booValRea[])
Reads data from the socket.
#define BUFFER_LENGTH
Debug flag, uncomment to enable debug messages
int assembleBuffer(int flag, int nDbl, int nInt, int nBoo, double curSimTim, double dblVal[], int intVal[], int booVal[], char **buffer, int *bufLen)
Assembles the buffer that will be exchanged through the IPC.
int getxmlvalue(char *const fileName, char *const exp, char *const str, int *const nVals, int const strLen)
int disassembleBuffer(const char *buffer, int *fla, int *nDbl, int *nInt, int *nBoo, double *curSimTim, double dblVal[], int intVal[], int booVal[])
Disassembles the buffer that has been received through the IPC.