Skip to content

Commit cf557ba

Browse files
committed
Move connect to server from ctor to own function
1 parent e3b69f2 commit cf557ba

File tree

7 files changed

+136
-98
lines changed

7 files changed

+136
-98
lines changed

Modelica_DeviceDrivers/Blocks/Communication.mo

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -322,50 +322,47 @@ See <a href=\"modelica://Modelica_DeviceDrivers.Blocks.Examples.TestSerialPackag
322322
import Modelica_DeviceDrivers.Communication.TCPIPSocketClient;
323323

324324
parameter Modelica.SIunits.Period sampleTime=0.01 "Sample time for update";
325+
parameter String IPAddress="127.0.0.1" "IP address of remote TCP/IP server";
326+
parameter Integer port=10002 "Port of the TCP/IP server";
325327
parameter Integer outputBufferSize=16*1024
326328
"Buffer size of message data in bytes." annotation(Dialog(group="Outgoing data"));
327-
parameter String IPAddress="127.0.0.1" "IP address of remote TCP/IP server"
328-
annotation (Dialog(group="Outgoing data"));
329-
parameter Integer port_send=10002 "Port of the TCP/IP server"
330-
annotation (Dialog(group="Outgoing data"));
331329
parameter Integer inputBufferSize=16*1024
332330
"Buffer size of message data in bytes." annotation(Dialog(group="Incoming data"));
333331
Interfaces.PackageIn pkgIn annotation (Placement(transformation(
334332
extent={{-20,-20},{20,20}},
335333
rotation=270,
336334
origin={-108,0})));
337-
Interfaces.PackageOut pkgOut(pkg = SerialPackager(inputBufferSize))
335+
Interfaces.PackageOut pkgOut(pkg = SerialPackager(inputBufferSize), dummy(start=0, fixed=true))
338336
annotation (Placement(transformation(
339337
extent={{-20,-20},{20,20}},
340338
rotation=90,
341339
origin={108,0})));
342340
protected
343-
TCPIPSocketClient socket = TCPIPSocketClient(IPAddress, port_send);
344-
Real dummy;
341+
TCPIPSocketClient socket = TCPIPSocketClient();
342+
Boolean isConnected(start=false, fixed=true);
345343
equation
346344
when initial() then
347345
pkgIn.userPkgBitSize = outputBufferSize*8;
348346
pkgIn.autoPkgBitSize = 0;
347+
isConnected = Modelica_DeviceDrivers.Communication.TCPIPSocketClient_.connect_(socket, IPAddress, port);
349348
end when;
350349

351-
algorithm
352-
pkgIn.backwardTrigger := sample(0, sampleTime);
353-
when pkgIn.trigger then
354-
dummy :=
355-
Modelica_DeviceDrivers.Blocks.Communication.Internal.DummyFunctions.sendToTCPIPServer(
356-
socket,
357-
Modelica_DeviceDrivers.Packaging.SerialPackager_.getPackage(pkgIn.pkg),
358-
outputBufferSize,
359-
pkgIn.dummy);
360-
end when;
361-
362-
pkgOut.trigger := sample(0,sampleTime);
363-
when pkgOut.trigger then
364-
pkgOut.dummy := Modelica_DeviceDrivers.Blocks.Packaging.SerialPackager.Internal.DummyFunctions.setPackage(
365-
pkgOut.pkg,
366-
Modelica_DeviceDrivers.Communication.TCPIPSocketClient_.read(socket, inputBufferSize),
367-
inputBufferSize,
368-
time);
350+
pkgIn.backwardTrigger = sample(0, sampleTime);
351+
pkgOut.trigger = pkgIn.backwardTrigger;
352+
when pkgIn.backwardTrigger then
353+
if isConnected then
354+
pkgOut.dummy = Modelica_DeviceDrivers.Blocks.Packaging.SerialPackager.Internal.DummyFunctions.setPackage(
355+
pkgOut.pkg,
356+
Modelica_DeviceDrivers.Communication.TCPIPSocketClient_.read(socket, inputBufferSize),
357+
inputBufferSize,
358+
Modelica_DeviceDrivers.Blocks.Communication.Internal.DummyFunctions.sendToTCPIPServer(
359+
socket,
360+
Modelica_DeviceDrivers.Packaging.SerialPackager_.getPackage(pkgIn.pkg),
361+
outputBufferSize,
362+
pkgIn.dummy));
363+
else
364+
pkgOut.dummy = pre(pkgOut.dummy);
365+
end if;
369366
end when;
370367
annotation (preferredView="info",
371368
Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,

Modelica_DeviceDrivers/Communication/TCPIPSocketClient.mo

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@ within Modelica_DeviceDrivers.Communication;
22
class TCPIPSocketClient "A client for TCP/IP packet network communication."
33
extends ExternalObject;
44
encapsulated function constructor
5-
"Creates a TCP/IP socket client."
5+
"Creates a TCP/IP socket client instance."
66
import Modelica_DeviceDrivers.Communication.TCPIPSocketClient;
7-
input String ip "IP address";
8-
input Integer port "listening port";
97
output TCPIPSocketClient socketClient;
10-
external "C" socketClient = MDD_TCPIPClient_Constructor(ip, port)
8+
external "C" socketClient = MDD_TCPIPClient_Constructor()
119
annotation(IncludeDirectory="modelica://Modelica_DeviceDrivers/Resources/Include",
1210
Include = "#include \"MDDTCPIPSocket.h\" ",
1311
Library = {"pthread", "Ws2_32"},

Modelica_DeviceDrivers/Communication/TCPIPSocketClient_.mo

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
within Modelica_DeviceDrivers.Communication;
22
package TCPIPSocketClient_ "Accompanying functions for the TCP/IP socket client object"
33
extends Modelica_DeviceDrivers.Utilities.Icons.DriverIcon;
4+
5+
encapsulated function connect_
6+
"Connects to a TCP/IP socket server."
7+
import Modelica_DeviceDrivers.Communication.TCPIPSocketClient;
8+
input TCPIPSocketClient socketClient;
9+
input String ip "IP address";
10+
input Integer port "Port";
11+
output Boolean isConnected;
12+
external "C" isConnected = MDD_TCPIPClient_Connect(socketClient, ip, port)
13+
annotation(IncludeDirectory="modelica://Modelica_DeviceDrivers/Resources/Include",
14+
Include = "#include \"MDDTCPIPSocket.h\" ",
15+
Library = {"pthread", "Ws2_32"},
16+
__iti_dll = "ITI_MDD.dll");
17+
end connect_;
18+
419
encapsulated function read
520
import Modelica_DeviceDrivers.Communication.TCPIPSocketClient;
621
input TCPIPSocketClient socketClient;

Modelica_DeviceDrivers/Resources/Include/MDDTCPIPSocket.h

Lines changed: 96 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -28,86 +28,114 @@ struct MDDTCPIPSocket_s {
2828
SOCKET SocketID;
2929
};
3030

31-
DllExport void * MDD_TCPIPClient_Constructor(const char* ipaddress, int port) {
32-
33-
int rc; /* Error variable */
34-
WSADATA wsa;
35-
struct addrinfo *result = NULL;
36-
struct addrinfo *ptr = NULL;
37-
struct addrinfo hints;
38-
MDDTCPIPSocket * tcpip;
39-
char port_str[20];
40-
41-
/* Initialize Winsock */
42-
rc = WSAStartup(MAKEWORD(2,2), &wsa);
43-
if (rc != NO_ERROR) {
44-
ModelicaFormatError("MDDTCPIPSocket.h: WSAStartup failed with error: %d\n", rc);
31+
DllExport void * MDD_TCPIPClient_Constructor(void) {
32+
MDDTCPIPSocket** tcpip = (MDDTCPIPSocket **)calloc(sizeof(MDDTCPIPSocket*), 1);
33+
if (tcpip) {
34+
*tcpip = (MDDTCPIPSocket *)calloc(sizeof(MDDTCPIPSocket), 1);
35+
if (*tcpip) {
36+
int rc; /* Error variable */
37+
WSADATA wsa;
38+
39+
(*tcpip)->SocketID = INVALID_SOCKET;
40+
41+
/* Initialize Winsock */
42+
rc = WSAStartup(MAKEWORD(2,2), &wsa);
43+
if (rc != NO_ERROR) {
44+
ModelicaFormatError("MDDTCPIPSocket.h: WSAStartup failed with error: %d\n", rc);
45+
}
46+
}
4547
}
4648

47-
memset(&hints, 0, sizeof(hints));
48-
hints.ai_family = AF_UNSPEC;
49-
hints.ai_socktype = SOCK_STREAM;
50-
hints.ai_protocol = IPPROTO_TCP;
51-
52-
/* Resolve the server address and port */
53-
_snprintf(port_str, 20, "%d", port);
54-
rc = getaddrinfo(ipaddress, port_str, &hints, &result);
55-
if (rc != NO_ERROR) {
56-
WSACleanup();
57-
ModelicaFormatError("MDDTCPIPSocket.h: getaddrinfo failed with error: %d\n", rc);
58-
}
59-
60-
tcpip = (MDDTCPIPSocket *)calloc(sizeof(MDDTCPIPSocket), 1);
61-
/* Attempt to connect to an address until one succeeds */
62-
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
63-
64-
/* Create a SOCKET for connecting to server */
65-
tcpip->SocketID = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
66-
if (tcpip->SocketID == INVALID_SOCKET) {
67-
free(tcpip);
68-
tcpip = NULL;
69-
rc = WSAGetLastError();
70-
WSACleanup();
71-
ModelicaFormatError("MDDTCPIPSocket.h: socket failed with error: %ld\n", WSAGetLastError());
72-
}
49+
return (void *) tcpip;
50+
}
7351

74-
/* Connect to server */
75-
rc = connect(tcpip->SocketID, ptr->ai_addr, (int)ptr->ai_addrlen);
76-
if (rc == SOCKET_ERROR) {
77-
closesocket(tcpip->SocketID);
78-
tcpip->SocketID = INVALID_SOCKET;
79-
continue;
52+
DllExport int MDD_TCPIPClient_Connect(void * p_tcpip, const char* ipaddress, int port) {
53+
MDDTCPIPSocket ** tcpip = (MDDTCPIPSocket **) p_tcpip;
54+
int ret = 0;
55+
if (tcpip && *tcpip) {
56+
if ((*tcpip)->SocketID == INVALID_SOCKET) {
57+
int rc; /* Error variable */
58+
struct addrinfo *result = NULL;
59+
struct addrinfo *ptr = NULL;
60+
struct addrinfo hints;
61+
char port_str[20];
62+
63+
memset(&hints, 0, sizeof(hints));
64+
hints.ai_family = AF_UNSPEC;
65+
hints.ai_socktype = SOCK_STREAM;
66+
hints.ai_protocol = IPPROTO_TCP;
67+
68+
/* Resolve the server address and port */
69+
_snprintf(port_str, 20, "%d", port);
70+
rc = getaddrinfo(ipaddress, port_str, &hints, &result);
71+
if (rc != NO_ERROR) {
72+
free(*tcpip);
73+
*tcpip = NULL;
74+
WSACleanup();
75+
ModelicaFormatError("MDDTCPIPSocket.h: getaddrinfo failed with error: %d\n", rc);
76+
}
77+
78+
/* Attempt to connect to an address until one succeeds */
79+
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
80+
81+
/* Create a SOCKET for connecting to server */
82+
(*tcpip)->SocketID = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
83+
if ((*tcpip)->SocketID == INVALID_SOCKET) {
84+
free(*tcpip);
85+
*tcpip = NULL;
86+
rc = WSAGetLastError();
87+
WSACleanup();
88+
ModelicaFormatError("MDDTCPIPSocket.h: socket failed with error: %ld\n", WSAGetLastError());
89+
}
90+
91+
/* Connect to server */
92+
rc = connect((*tcpip)->SocketID, ptr->ai_addr, (int)ptr->ai_addrlen);
93+
if (rc == SOCKET_ERROR) {
94+
closesocket((*tcpip)->SocketID);
95+
(*tcpip)->SocketID = INVALID_SOCKET;
96+
continue;
97+
}
98+
break;
99+
}
100+
101+
freeaddrinfo(result);
102+
103+
if ((*tcpip)->SocketID == INVALID_SOCKET) {
104+
free(*tcpip);
105+
*tcpip = NULL;
106+
WSACleanup();
107+
ModelicaFormatError("MDDTCPIPSocket.h: Unable to connect to server!\n");
108+
}
109+
110+
ret = 1;
111+
}
112+
else {
113+
ret = 1;
80114
}
81-
break;
82-
}
83-
84-
freeaddrinfo(result);
85-
86-
if (tcpip->SocketID == INVALID_SOCKET) {
87-
free(tcpip);
88-
tcpip = NULL;
89-
WSACleanup();
90-
ModelicaFormatError("MDDTCPIPSocket.h: Unable to connect to server!\n");
91115
}
92-
93-
return (void *) tcpip;
116+
return ret;
94117
}
95118

96119
DllExport void MDD_TCPIPClient_Destructor(void * p_tcpip) {
97-
MDDTCPIPSocket * tcpip = (MDDTCPIPSocket *) p_tcpip;
120+
MDDTCPIPSocket ** tcpip = (MDDTCPIPSocket **) p_tcpip;
98121
if (tcpip) {
99-
shutdown(tcpip->SocketID, SD_BOTH);
100-
closesocket(tcpip->SocketID);
122+
if (*tcpip) {
123+
if ((*tcpip)->SocketID != INVALID_SOCKET) {
124+
shutdown((*tcpip)->SocketID, SD_BOTH);
125+
closesocket((*tcpip)->SocketID);
126+
}
127+
free(*tcpip);
128+
WSACleanup();
129+
}
101130
free(tcpip);
102131
}
103-
WSACleanup();
104132
}
105133

106134
DllExport int MDD_TCPIPClient_Send(void * p_tcpip, const char * data, int dataSize) {
107-
MDDTCPIPSocket * tcpip = (MDDTCPIPSocket *) p_tcpip;
135+
MDDTCPIPSocket ** tcpip = (MDDTCPIPSocket **) p_tcpip;
108136
int rc = EXIT_SUCCESS;
109-
if (tcpip) {
110-
rc = send(tcpip->SocketID, data, dataSize, 0);
137+
if (tcpip && *tcpip) {
138+
rc = send((*tcpip)->SocketID, data, dataSize, 0);
111139
if (rc == SOCKET_ERROR) {
112140
ModelicaFormatMessage("MDDTCPIPSocket.h: send failed with error: %d\n", WSAGetLastError());
113141
rc = EXIT_FAILURE;
@@ -117,10 +145,10 @@ DllExport int MDD_TCPIPClient_Send(void * p_tcpip, const char * data, int dataSi
117145
}
118146

119147
DllExport const char * MDD_TCPIPClient_Read(void * p_tcpip, int recvbuflen) {
120-
MDDTCPIPSocket * tcpip = (MDDTCPIPSocket *) p_tcpip;
121-
if (tcpip) {
148+
MDDTCPIPSocket ** tcpip = (MDDTCPIPSocket **) p_tcpip;
149+
if (tcpip && *tcpip) {
122150
char* recvbuf = ModelicaAllocateString(recvbuflen);
123-
int rc = recv(tcpip->SocketID, recvbuf, recvbuflen, 0);
151+
int rc = recv((*tcpip)->SocketID, recvbuf, recvbuflen, 0);
124152
return recvbuf;
125153
}
126154
return "";
Binary file not shown.
Binary file not shown.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Modelica_DeviceDrivers
22
Free library for interfacing hardware drivers to Modelica models.
3-
There is support for joysticks, keyboards, UDP, shared memory, AD/DA converters, serial port and other devices.
3+
There is support for joysticks, keyboards, UDP, TCP/IP, shared memory, AD/DA converters, serial port and other devices.
44

55
## Library description
66
The `Modelica_DeviceDrivers` library is an open source Modelica package under [Modelica License 2](https://modelica.org/licenses/ModelicaLicense2) that interfaces hardware drivers to Modelica models.

0 commit comments

Comments
 (0)