Skip to content

Commit 3398b30

Browse files
committed
Refinements to support multiple network interfaces
1 parent 5387184 commit 3398b30

File tree

11 files changed

+432
-188
lines changed

11 files changed

+432
-188
lines changed

ArrowPoint-CANbus-Test/Canbus/CanLoopbackTest.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ public class CanLoopbackTest
1212
[Test]
1313
public void TestConnect()
1414
{
15-
ICanTrafficInterface canLoopback = new CanLoopback(ReceivedCanPacketCallBack);
15+
ICanTrafficInterface canLoopback = new CanLoopback()
16+
{
17+
ReceivedCanPacketCallBack = ReceivedCanPacketCallBack
18+
};
1619

1720
canLoopback.Connect();
1821
Assert.IsTrue(canLoopback.IsConnected());
@@ -24,7 +27,10 @@ public void TestConnect()
2427
[Test]
2528
public void TestReceived()
2629
{
27-
ICanTrafficInterface canLoopback = new CanLoopback(ReceivedCanPacketCallBack);
30+
ICanTrafficInterface canLoopback = new CanLoopback()
31+
{
32+
ReceivedCanPacketCallBack = ReceivedCanPacketCallBack
33+
};
2834

2935
canLoopback.Connect();
3036
Assert.IsTrue(canLoopback.IsConnected());

ArrowPoint-CANbus-Test/Canbus/CanOverEthernetTest.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ public class CanOverEthernetTest
1313
[Test]
1414
public void TestConnect()
1515
{
16-
ICanTrafficInterface canLoopback = new CanOverEthernet(ReceivedCanPacketCallBack);
16+
ICanTrafficInterface canLoopback = new CanLoopback()
17+
{
18+
ReceivedCanPacketCallBack = ReceivedCanPacketCallBack
19+
};
1720

1821
canLoopback.Connect();
1922
Assert.IsTrue(canLoopback.IsConnected());
@@ -25,7 +28,10 @@ public void TestConnect()
2528
[Test]
2629
public void TestReceived()
2730
{
28-
ICanTrafficInterface canLoopback = new CanOverEthernet(ReceivedCanPacketCallBack);
31+
ICanTrafficInterface canLoopback = new CanLoopback()
32+
{
33+
ReceivedCanPacketCallBack = ReceivedCanPacketCallBack
34+
};
2935

3036
canLoopback.Connect();
3137
Assert.IsTrue(canLoopback.IsConnected());

ArrowPoint-CANbus-Tools/Canbus/CanLoopback.cs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,35 @@ public class CanLoopback : ICanTrafficInterface
1111
{
1212
public ReceivedCanPacketHandler ReceivedCanPacketCallBack { get; set; }
1313

14-
private bool isConnected = false;
15-
16-
public CanLoopback(ReceivedCanPacketHandler receivedCanPacketCallBack)
14+
public Dictionary<string, string> AvailableInterfaces
1715
{
18-
this.ReceivedCanPacketCallBack = receivedCanPacketCallBack;
19-
this.isConnected = false;
16+
get
17+
{
18+
Dictionary<string, string> interfaces = new Dictionary<string, string>
19+
{
20+
{ "localhost", "localhost" }
21+
};
22+
return interfaces;
23+
}
2024
}
2125

26+
public List<string> SelectedInterfaces {
27+
get
28+
{
29+
List<string> selectedInterfaces = new List<string>()
30+
{
31+
{ "localhost" }
32+
};
33+
return selectedInterfaces;
34+
}
35+
set
36+
{
37+
38+
}
39+
}
40+
41+
private bool isConnected = false;
42+
2243
public bool Connect()
2344
{
2445
isConnected = true;

ArrowPoint-CANbus-Tools/Canbus/CanOverEthernet.cs

Lines changed: 124 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Collections.Generic;
55
using System.Linq;
66
using System.Net;
7+
using System.Net.NetworkInformation;
78
using System.Net.Sockets;
89
using System.Threading;
910

@@ -26,40 +27,70 @@ public class CanOverEthernet : ICanTrafficInterface
2627

2728
private Thread UdpReceiverThread;
2829
private UdpClient udpReceiverConnection;
29-
private UdpClient udpSenderConnection;
30-
private Boolean isConnected;
30+
private List<UdpClient> udpSenderConnections;
31+
private Boolean isConnected = false;
3132
private IPAddress ipAddressMulticast;
3233
private IPEndPoint ipEndPointMulticast;
3334
private IPEndPoint localEndPoint;
3435

35-
public string Ip;
36-
public int Port;
36+
public string Ip { get; set; } = DEFAULT_IPADDRESS;
37+
public int Port { get; set; } = DEFAULT_PORT;
3738
public ReceivedCanPacketHandler ReceivedCanPacketCallBack { get; set; }
39+
public List<string> SelectedInterfaces { get; set; }
3840

39-
public CanOverEthernet(string Ip, int Port, ReceivedCanPacketHandler receivedCanPacketCallBack)
41+
internal void Close()
4042
{
41-
this.Ip = Ip;
42-
this.Port = Port;
43-
this.ReceivedCanPacketCallBack = receivedCanPacketCallBack;
44-
45-
if (Ip == null || Ip.Length == 0 || Port == 0) return;
46-
47-
this.isConnected = false;
43+
Disconnect();
4844
}
4945

50-
public CanOverEthernet(ReceivedCanPacketHandler receivedCanPacketHandler)
46+
public Dictionary<string, string> AvailableInterfaces
5147
{
52-
this.Ip = DEFAULT_IPADDRESS;
53-
this.Port = DEFAULT_PORT;
54-
this.ReceivedCanPacketCallBack = receivedCanPacketHandler;
55-
this.isConnected = false;
56-
}
48+
get
49+
{
50+
Dictionary<string, string> availableInterfaces = null;
5751

58-
internal void Close()
59-
{
60-
Disconnect();
52+
// Find all available network interfaces
53+
NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
54+
55+
foreach (NetworkInterface networkInterface in networkInterfaces)
56+
{
57+
if ((!networkInterface.Supports(NetworkInterfaceComponent.IPv4)) ||
58+
(networkInterface.OperationalStatus != OperationalStatus.Up))
59+
{
60+
continue;
61+
}
62+
63+
IPInterfaceProperties adapterProperties = networkInterface.GetIPProperties();
64+
UnicastIPAddressInformationCollection unicastIPAddresses = adapterProperties.UnicastAddresses;
65+
IPAddress ipAddress = null;
66+
67+
foreach (UnicastIPAddressInformation unicastIPAddress in unicastIPAddresses)
68+
{
69+
if (unicastIPAddress.Address.AddressFamily != AddressFamily.InterNetwork)
70+
{
71+
continue;
72+
}
73+
74+
ipAddress = unicastIPAddress.Address;
75+
break;
76+
}
77+
78+
if (ipAddress == null)
79+
{
80+
continue;
81+
}
82+
83+
if (availableInterfaces == null)
84+
availableInterfaces = new Dictionary<string, string>();
85+
86+
availableInterfaces.Add(ipAddress.ToString(), ipAddress.ToString() + " - " + networkInterface.Name);
87+
88+
}
89+
return availableInterfaces;
90+
}
6191
}
6292

93+
6394
public Boolean Connect()
6495
{
6596

@@ -68,25 +99,66 @@ public Boolean Connect()
6899
ipEndPointMulticast = new IPEndPoint(this.ipAddressMulticast, this.Port);
69100
localEndPoint = new IPEndPoint(IPAddress.Any, this.Port);
70101

71-
// Setup sender and receiver
72102
try
73103
{
74-
udpSenderConnection = new UdpClient()
75-
{
76-
ExclusiveAddressUse = false
77-
};
78-
udpSenderConnection.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
79-
udpSenderConnection.Client.Bind(localEndPoint);
80-
udpSenderConnection.JoinMulticastGroup(ipAddressMulticast);
81-
udpSenderConnection.Client.MulticastLoopback = true;
82-
83104
this.udpReceiverConnection = new UdpClient()
84105
{
85106
ExclusiveAddressUse = false
86107
};
87108
udpReceiverConnection.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
88109
udpReceiverConnection.Client.Bind(localEndPoint);
89-
udpReceiverConnection.JoinMulticastGroup(ipAddressMulticast, 50);
110+
111+
// join multicast group on all available network interfaces
112+
NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
113+
114+
foreach (NetworkInterface networkInterface in networkInterfaces)
115+
{
116+
if ((!networkInterface.Supports(NetworkInterfaceComponent.IPv4)) ||
117+
(networkInterface.OperationalStatus != OperationalStatus.Up))
118+
{
119+
continue;
120+
}
121+
122+
IPInterfaceProperties adapterProperties = networkInterface.GetIPProperties();
123+
UnicastIPAddressInformationCollection unicastIPAddresses = adapterProperties.UnicastAddresses;
124+
IPAddress ipAddress = null;
125+
126+
foreach (UnicastIPAddressInformation unicastIPAddress in unicastIPAddresses)
127+
{
128+
if (unicastIPAddress.Address.AddressFamily != AddressFamily.InterNetwork)
129+
{
130+
continue;
131+
}
132+
133+
ipAddress = unicastIPAddress.Address;
134+
break;
135+
}
136+
137+
if (ipAddress == null)
138+
{
139+
continue;
140+
}
141+
142+
if (SelectedInterfaces != null && !SelectedInterfaces.Contains(ipAddress.ToString()))
143+
{
144+
continue;
145+
}
146+
147+
udpReceiverConnection.JoinMulticastGroup(ipAddressMulticast, ipAddress);
148+
149+
// Also create a client for this interface and add it to the list of interfaces
150+
IPEndPoint interfaceEndPoint = new IPEndPoint(ipAddress, this.Port);
151+
152+
UdpClient sendClient = new UdpClient();
153+
sendClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
154+
sendClient.Client.MulticastLoopback = true;
155+
sendClient.Client.Bind(interfaceEndPoint);
156+
sendClient.JoinMulticastGroup(ipAddressMulticast);
157+
158+
if (udpSenderConnections == null) udpSenderConnections = new List<UdpClient>();
159+
udpSenderConnections.Add(sendClient);
160+
}
161+
90162
}
91163
catch
92164
{
@@ -104,8 +176,14 @@ public Boolean Disconnect()
104176
{
105177
if (!isConnected) return false;
106178

107-
udpReceiverConnection.Close();
108-
udpSenderConnection.Close();
179+
try
180+
{
181+
udpReceiverConnection.Close();
182+
foreach (UdpClient client in udpSenderConnections)
183+
client.Close();
184+
}
185+
catch { }
186+
109187
StopReceiver();
110188

111189
isConnected = false;
@@ -118,7 +196,17 @@ public int SendMessage(CanPacket canPacket)
118196
if (!isConnected) return -1;
119197

120198
var data = canPacket.RawBytes;
121-
return udpSenderConnection.Send(data, data.Length, ipEndPointMulticast);
199+
200+
int resultToReturn = 0;
201+
202+
foreach (UdpClient client in udpSenderConnections)
203+
{
204+
int result = client.Send(data, data.Length, ipEndPointMulticast);
205+
if (result > resultToReturn)
206+
resultToReturn = result;
207+
}
208+
209+
return resultToReturn;
122210
}
123211

124212
public Boolean IsConnected()
@@ -162,7 +250,7 @@ private void UdpReceiverLoop()
162250
SplitCanPackets(data, sourceAddress, port);
163251
}
164252
}
165-
catch (Exception ex) {
253+
catch {
166254
Disconnect();
167255
}
168256
}

ArrowPoint-CANbus-Tools/Canbus/ICanTrafficInterface.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ namespace ArrowPointCANBusTool.Canbus
1111
public delegate void ReceivedCanPacketHandler(CanPacket canPacket);
1212

1313
public interface ICanTrafficInterface
14-
{
14+
{
15+
Dictionary<string, string> AvailableInterfaces { get; }
16+
17+
List<string> SelectedInterfaces { get; set; }
18+
1519
ReceivedCanPacketHandler ReceivedCanPacketCallBack { get; set; }
1620

1721
Boolean Connect();

0 commit comments

Comments
 (0)