Lwip on mbed-os 5 doesn't make a proper ethernet connection - c++

My goal is to send UDP packets from the microcontroller (nucleo board) to the PC - as simple as that. Update: I reached the goal successfully. I'll explain here how I did it, and the problems I stumbled upon initially. Many thanks to the StackOverflow community and people on LinkedIn ARM group to help me out!
1. SYSTEM OVERVIEW
My system is as follows:
1.1 Microcontroller side
Nucleo_F767ZI board with STM32F767ZI microcontroller. This board has an ethernet connector.
Mbed-OS 5 operating system.
lwip library (wich is part from the Mbed-OS 5 operating system).
1.2 PC side 🖳
Windows 10, 64-bit.
Free ethernet port (internet is through WiFi, that's why this ethernet port is unused).
Wireshark to see if the microcontroller actually sends out UDP packets. Interpretation of them will be done later on in Python. First I want to see packets in Wireshark.
1.3 Connections
Initially I connected the nucleo board directly to my computer, without a router or switch involved. Such a setup requires "static IP configuration". I would configure the PC to have IP address "192.168.1.10" and the microcontroller to have "192.168.1.20". I know this can work, because I've done it before with a PIC microcontroller.
But this situation is a little different. I got a little operating system running on the microcontroller: mbed-os v5. This operating system makes use of Lwip (Light-weight ip stack). Although it should be possible to configure a "static IP address", the software currently doesn't support it. More information can be found here: https://developer.mbed.org/questions/74145/EthernetInterfaceinit-mbed-os-5x-not-wor/. Because there is no way to configure a static IP address on the microcontroller, you need a DHCP server. The microcontroller connects to the network without an IP address, and broadcasts a packet with the question: "What IP address should I use on this network?". If the microcontroller doesn't get an answer, it will broadcast the question a few times, and eventually give up.
If there is a DHCP server connected to the network, it will receive the question and hand over a free IP address. So that is what you need. There are several ways to provide such a DHCP server:
Install a DHCP server on your Windows PC. This is the only way to keep switches and routers out of the picture. The nucleo board is connected directly to the PC. When the microcontroller broadcasts the question, the Windows PC hands over an IP address. After that, communication can start.
Throw a Raspberry PI into the game. The Raspberry PI should run a DHCP server. Connect the three devices (Windows PC, Raspberry PI and Nucleo board) to a switch.
Buy a simple router. Home routers have a DHCP server built-in. Connect the Windows PC and the Nucleo board to the LAN ports of this router.
I decided to go for the third option. The following figure shows the connections to my Netgear R7000 router:
2. ROUTER SETUP
The DHCP server inside the router will hand out IP addresses to all devices that connect to it. My router will hand out the IP address "192.168.1.2" to the first device, "192.168.1.3" to the second, and so forth all the way up to "192.168.1.254". But that's a bit problematic. How can the PC and the microcontroller know each others IP addresses? Perhaps there are more clever solutions, but I've figured out the following approach.
Each DHCP server has a table with "reserved IP addresses". In this table, you can add devices and assign a static IP address to them. So whenever that device asks for an IP address, the DHCP server takes a look in the table and hands over the one you've configured. But how does the DHCP server recognizes a device? It can recognize a device by its MAC-address. Every device has a globally unique MAC-address of 6 bytes.
This is how I've added my Windows PC and my microcontroller to the table:
STEP 1: Connect the computer to one of the LAN ports of the router. Switch the router on.
STEP 2: Make sure that all WiFi on your computer is disconnected. I've experienced lots of issues with this. (*)
STEP 3: Open a browser, and surf to "192.168.1.1". This is my routers home page. It could be different for your router.
STEP 4: Login (my routers default login is "admin" for the username and "password" for the password)
STEP 5: Add the Windows PC and the microcontroller board to the table. You have to look up their MAC-addresses first (**):
2.1 Disconnect all WiFi (*)
This should be a simple step, but Windows makes it hard. Windows can be quite stubborn and reconnect automatically to WiFi networks around, even if you've unchecked the connect automatically box! To force Windows to listen to you, you can use the cmd terminal. Open a cmd terminal with admin privileges. Next, type the following command to see all your WiFi profiles:
> netsh wlan show profiles
Apply the following command to those WiFi profiles that your PC is stubbornly connecting to:
> netsh wlan set profileparameter name="someWifiName" connectionmode=manual
Now you can disconnect from that WiFi network, and Windows won't reconnect automatically anymore.
2.2 Find the MAC address of your PC (**)
This is how I found the MAC-address of my computer. Keep in mind that a computer can have several MAC-addresses. The one for your ethernet port will be different to the one for your wireless connection! Type ipconfig /all in the Windows cmd terminal. I got the following output:
# Note: this is the correct item!
# --------------------------------
Ethernet adapter Local Area Connection:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Intel(R) Ethernet Connection (2) I219-LM
Physical Address. . . . . . . . . : C8-xx-xx-xx-xx-01 # Replaced some numbers by x for security :-)
DHCP Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : Yes
Make sure you're looking at the correct item in the list of connections. Ethernet adapter Local Area Connection is the correct one for my computer, because the network card description fits what is expected: Intel(R) Ethernet Connection (2) I219-LM. Before, I was looking at another item in the list, labelled Ethernet adapter Ethernet:
# Note: this is the wrong item!
# ------------------------------
Ethernet adapter Ethernet:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : TAP-Windows Adapter V9
Physical Address. . . . . . . . . : 00-xx-xx-xx-xx-F7
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
Mr. Joel C (see his answer below) notified me that the network card from that item is TAP-Windows Adapter V9. Apparently that is a virtual network card. That made me lose a lot of time. Thank you Mr. Joel C for helping me out!
Please make also sure that DHCP Enabled and Autoconfiguration Enabled are turned on!
2.3 Find the MAC address of your Nucleo board (**)
I found the MAC-address of my Nucleo board with the following code:
#include "lwip-interface/EthernetInterface.h"
//1. Make an ethernet object
EthernetInterface eth;
//2. Try to connect
eth.connect(); // <- This line will not work now,
// but at least it will help you to find out your
// own MAC-address.
//3. Print the MAC-address
logger.printf("Controller MAC Address is: %s\r\n", eth.get_mac_address());
The print output I got over my serial port is (some numbers I replaced by x for security):
Controller MAC Address is: 00:xx:xx:xx:xx:40
3. MICROCONTROLLER CODE
This is the code that runs on the microcontroller. My main.cpp file is inspired on the code found on the Mbed-os forum at https://forums.mbed.com/t/udp-receive-with-nucleo-f767zi/1806.
#include <string>
using std::string;
#include "mbed.h"
#include "lwip-interface/EthernetInterface.h"
static Serial logger(USBTX, USBRX);
static DigitalOut led1(LED1);
// IP addresses
#define IP_COMPUTER "192.168.1.10" // Make sure these IP addresses correspond to the
#define IP_NUCLEO "192.168.1.20" // table of 'reserved IP addresses' you have setup in
// your routers DHCP server!
// Ethernet settings
const int PORT_T = 50000;
const int PORT_R = 50001;
EthernetInterface eth;
static void udp_tx_thread_func();
static void udp_rx_thread_func();
static Thread udp_tx_thread;
static Thread udp_rx_thread;
int main()
{
// 1. Initialize the serial logger
logger.baud(115200);
logger.printf("\r\n\r\nApplication started\r\n");
// 2. Initialize and start the UDP connection
eth.connect();
logger.printf("Controller MAC Address is: %s\r\n", eth.get_mac_address());
logger.printf("Controller IP Address is: %s\r\n", eth.get_ip_address());
Thread::wait(200);
udp_tx_thread.start(udp_tx_thread_func);
udp_rx_thread.start(udp_rx_thread_func);
while (true)
{
led1 = !led1;
Thread::wait(500);
}
}
//------------------ Ethernet --------------------------------------------------
static void udp_tx_thread_func()
{
UDPSocket socket(&eth);
SocketAddress sock_addr(IP_COMPUTER, PORT_T);
static uint32_t out_buffer[3];
while(true)
{
Thread::wait(100);
// Send 3 values of 32-bit each
out_buffer[0] = 150500;
out_buffer[1] = 255300;
out_buffer[2] = 54;
int ret = socket.sendto(sock_addr, &out_buffer[0], 12); // 3 values of 32-bit equals 12 bytes
//logger.printf("sendto return: %d\r\n", ret);
}
}
static void udp_rx_thread_func()
{
UDPSocket socket(&eth);
SocketAddress sock_addr;
int bind = socket.bind(PORT_R);
logger.printf("bind return: %d\n", bind);
char buffer[256];
while(true)
{
//logger.printf("\nWait for packet...\n");
int n = socket.recvfrom(&sock_addr, buffer, sizeof(buffer));
buffer[n] = '\0';
//logger.printf("Packet from \"%s\": %s\n", sock_addr.get_ip_address(), buffer);
Thread::wait(500);
}
}
4. RESULTS
4.1 Wireshark results
In Wireshark I can see the UDP packets flowing in on the Local Area Connection! Huray!
4.2 Python code
The python code to catch the UDP packets looks like this:
import sys
import os
import socket
import dataprocessing.datastruct as datastruct
def main():
# 1. Configure the IP address
# -----------------------------
myAddr = ('192.168.1.10', 50000)
# 2. Create a UDP socket
# -----------------------
sock = None
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(1.5)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(myAddr)
print('UDPsock #: ' + str(sock.getsockname()))
sys.stdout.flush()
except Exception as e:
print('Could not bind to the UDP socket.')
print(e)
sys.stdout.flush()
while (true):
try:
data, address = sock.recvfrom(256) # buffer size is 256 bytes
bytedata = bytearray(data)
# Each 32-bit number is cut in 8-bit pieces. Bring them back together.
value_01 = bytedata[0] + 256*bytedata[1] + 65536*bytedata[2] + 16777216*bytedata[3]
value_02 = bytedata[4] + 256*bytedata[5] + 65536*bytedata[6] + 16777216*bytedata[7]
value_03 = bytedata[8] + 256*bytedata[9] + 65536*bytedata[10] + 16777216*bytedata[11]
print("Value 01: %d", value_01)
print("Value 02: %d", value_02)
print("Value 03: %d", value_03)
except socket.error as err:
print(err)
if __name__== '__main__':
print("")
print("Start UDP catcher")
print("-----------------")
main()
5. LET WIFI AND ETHERNET COEXIST
The UDP packets from the microcontroller flow in on your ethernet port (passing along the router). Meanwhile you might want to connect to some WiFi network for internet access. The problem is that any browser will try to get access through your ethernet port - ignoring the WiFi.
The solution is to make your browsers FIRST attempt to use the WiFi to reach an IP address, next attempt through the Ethernet port. This is done with the "Interface metric" in the Control Panel. Increase this number slightly:

The connection you have labelled Ethernet is actually a TAP connection (eg. a virtual ethernet card). Your actual ethernet connection is labelled Local Area Connection; that is the connection you will need to be configuring and watching with Wireshark, etc.
As to everything else Mbed-OS related, I personally have not dealt with it.

Related

ESP8266 Access Point Mode - Intermittent when connecting

I'm using an ESP8266 in access point mode to send it some data (wifi credentials) from a mobile app via HTTP. The access point init code is very simple:
IPAddress apIP(10, 10, 10, 1);
IPAddress subnet(255,255,255,0);
WiFi.softAPConfig(apIP, apIP, subnet);
WiFi.softAP(ACCESS_POINT_NAME); // No password requird
What I find is that sometimes the mobile phone connects to the ESP's network seamlessly, and other times seriously struggles (rejects the connection, or takes > 3 mins to connect).
Questions are:
Are there issues with this code that could make a connection to the ESP by a client temperamental (sometimes fine, other times not)? Like should I change the WiFi channel from 1? Are the static IP/Subnet mask creating issues?
Is the issue likely hardware related - i.e. sometimes the client gets a good wifi signal from the ESP, sometimes not?
If anyone else faces this, I found a large performance improvement from doing the following:
Removing DNS
Reseting the WiFi config
Explicitly setting the module to AP mode - this is referenced by this Github issue comment. This seems to be the primary driver of improvement.
So the code is now:
// Set up WiFi mode [Improve AP stability - no dual STA mode]
ESP.eraseConfig();
WiFi.mode(WIFI_AP);
IPAddress apIP(10, 10, 10, 1);
IPAddress subnet(255,255,255,0);
WiFi.softAPConfig(apIP, apIP, subnet);
WiFi.softAP(ACCESS_POINT_NAME); // No password
WiFi.printDiag(Serial);
The reasoning is that while in STA mode, the ESP may channel hop (depending on the environment), and the AP gets pulled with it. So any client connected before the channel hop will have to reconnect.

How do I programatically remove a flash drive based on its device node name?

I have a Linux system with multiple USB flash drives plugged in, as /dev/sda1, /dev/sdb1, etc. I need to eject one of these from within my program -- something like EjectDrive("/dev/sdb1"); I then may need to programmatically re-insert the drive.
I know I can do this from the command line if I know the USB bus, port and device number. e.g. echo '2-1.3' > /sys/bus/usb/drivers/usb/unbind and then echo '2-1.3' > /sys/bus/usb/drivers/usb/bind
I'm not sure how to do this from C++, and be 100% sure I am using the correct bus, port and device for the specified drive.
This is an embedded platform with BusyBox v1.22.1, so udev is not available to me, and lsusb returns minimal information.
Yes it can be done using libusb (follow this link for libusb usage with C++). Now a few things to keep in mind -
1 - What is the device address? (You can get this using libusb API)
libusb_get_device_list (libusb_context *ctx, libusb_device ***list)
libusb_get_device_address (libusb_device *dev)
libusb_get_port_number (libusb_device *dev)
2 - Is the device connected to the root hub port or to a hub port? (This can be done by reading the parent device of the /dev/sdb1 or sda1)
libusb_get_parent (libusb_device *dev)
3 - If its connected to a hub, then do a control transfer to "clear" PORT_POWER feature of that port. That will turn off the port and the device will be disconnected. You can "set" PORT_POWER feature to turn on the port and the device will be connected again. Remember that you will not get any disconnect event which is as per the spec. (EHCI or XHCI)
int libusb_control_transfer ( libusb_device_handle * dev_handle,
uint8_t bmRequestType,
uint8_t bRequest,
uint16_t wValue,
uint16_t wIndex,
unsigned char * data,
uint16_t wLength,
unsigned int timeout
)
4 - If the device is connected to the root hub port directly, then please check if libusb supports clearing root hub port power. I am not sure about this. This also depends on the Host controller driver stack.
Please follow the link I mentioned at the top for example usage of these API's.

Can I use the USB port of the raspberry pi (model B+) for serial communication (RS232)

I need to interface an old machine (thermostream) to interface with the raspberry pi (model B+)
The thermostream device has a RS232 serial port and I want to connect it to the USB port of the raspberry pi using the RS232 serial to usb cable (where the usb end of the cable is inserted in the pi and the serial end is connected to the device). And I need to write the code in python.
IS this possible? If yes, how should I proceed? Any help is greatly appreciated.
Yes. First you need to install pyserial
Then, in Python, you can use the following function to create a serial object that connects to a port. The usb ports on the pi are dynamically assigned a name and those names can change. This function will enable you to loop through each port for the name. (might not work well with multiple devices attached). Check your connection settings on the device you wish to communicate with (baudrate, parity, stopbits etc) and modify the code to use those settings.
import serial
def serialConnect():
serlocations=['/dev/ttyACM', '/dev/ttyACM0', '/dev/ttyACM1','/dev/ttyACM2', '/dev/ttyACM3','/dev/ttyACM4', '/dev/ttyACM5','/dev/ttyUSB0','/dev/ttyUSB1','/dev/ttyUSB2','/dev/ttyUSB3', '/dev/ttyUSB4', '/dev/ttyUSB5', '/dev/ttyUSB6', '/dev/ttyUSB7', '/dev/ttyUSB8', '/dev/ttyUSB9', '/dev/ttyUSB10','/dev/ttyS0', '/dev/ttyS1', '/dev/ttyS2', 'com2', 'com3', 'com4', 'com5', 'com6', 'com7', 'com8', 'com9', 'com10', 'com11', 'com12', 'com13', 'com14', 'com15', 'com16', 'com17', 'com18', 'com19', 'com20', 'com21', 'com1', 'end']
for device in serlocations:
try:
ser = serial.Serial(
port=device,
baudrate=9600,
parity=serial.PARITY_ODD,
stopbits=serial.STOPBITS_TWO,
bytesize=serial.SEVENBITS
)
print device
return ser
except:
x=0
if device == 'end':
print "No Device Found"
ser = serialConnect()
if ser:
ser.write("TEST")
ser.timeout=5
for i in ser.readlines():
print i

Telnet client console: SEND invalid command - Only for Spanish version

I’ve developed an application in QT C++ (server with listening sockets) waiting for clients to connect and send commands.
It was developed and tested in Windows XP Professional Version 2002 SP3 English version and tested in Windows seven 64 bits using telnet client sending strings to server from command prompt using reserved word SEND without problems.
Actually I am testing this app from another Windows XP Professional Version 2002 SP3 Spanish version machine and I’m having problems with sending strings.
Telnet client connects correctly, receives data from server, but when I move to command prompt and try to send strings I receive and error.
Microsoft Telnet> send MYSTRING
Invalid command. type ?/help for help
Microsoft Telnet> ?
Commands may be abbreviated. Supported commands are:
c – close close current connection
d – display display operating parameters
o – open hostname [port] connect to hostname (default port 23).
q – quit exit telnet
set – set set options (type ‘set ?’ for a list)
sen – send send strings to server
st – status print status information
u – unset unset options (type ‘unset ?’ for a list)
?/h – help print help information
Microsoft Telnet> d
Escape Character is ‘CTRL+}’
Will auth(NTLM Authentication)
Local echo off
New line mode – Causes return key to send CR & LF
Current mode: Console
Will term type
Preferred term type is ANSI
Note: Above transcription is translated, I get this message in Spanish
I need to know if this problem, telnet not recognizing a reserved word is a configuration or security problem.
Windows Firewall is deactivated.
EDIT1:
To clear situation on problem with Telnet Client:
I develop an App in Windows XP 2002 SP3 English version. This app is a server in a network listening in port 6000. Waits for clients to connect (through Telnet client for example) over lan.
The pc running my app has IP1 and its working.
From PC2 with same os I connect using >telnet IP1 6000 and after I connect and receive data from my app (server). Then I press 'ctrl+}' and get to Telnet prompt Microsoft Telnet> send AnyString AnyString has been sent to server. My app receives data correctly, process it and works fine.
From PC3 using W7 and Ubuntu virtual machines, same procedure than PC2 and it works fine.
From PC4 os Windows XP SP3 2002 Spanish i connect using >telnet IP1 6000 and after I connect and receive data from my app (server). Then I press 'ctrl+}' and get to Telnet prompt Microsoft Telnet> send AnyString Invalid command. type ?/help for help
That's why I suppose Telnet client on XP can be "configured?"
To send a text message over TCP/IP using telnet client you need just to call telnet with address (and port if not default 23 should be used), i.e:
> telnet 192.168.1.1 13 // tell me your time
> string to be sent // type windows's enter
> // should be sent as a text to 192.168.1.1 on port 13
when i move to command prompt and try to send strings i receive and
error.
Microsoft Telnet> send MYSTRING
Invalid command. type ?/help for help
The command is named sen, not send. Maybe a send is also sen but in help only sen is showed so better stick with it.
You can move to telnet mode by typing escape character that might be i.e. '^]' then type sen:
> telnet 192.168.1.1 13
> ctrl+]
Microsoft Telnet> sen my string here
> // should be sent as a text to 192.168.1.1 on port 13
Microsoft telnet client sen command terminates strings with null: when you type 5 characters p i o t r it terminates these 5 bytes with 00 byte ( '\0') so there are 6 bytes sent:
p i o t r .
70 69 6f 74 72 00
In case of problems with Microsoft Telnet you can always install a putty or write a simple telnet client:
void
str_cli(FILE *fp, int sockfd) {
char buf[MAXLINE];
int n;
for ( ;;) {
if ((n = Read(fileno(fp), buf, MAXLINE)) < 0) {
err_quit("str_cli:");
}
Writen( sockfd, buf, n);
}
}
int main( int argc, char** argv) {
int sockfd;
struct sockaddr_in servaddr;
if (argc != 2)
err_quit("usage: tcpcli <IPaddress>");
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons( SERV_PORT);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
str_cli( stdin, sockfd); /* do it all */
close( sockfd);
exit(0);
}

Create and test virtual serial ports with com0com and hub4com

I'm working on sending datas via COM in C++ for ESPA 4.4.4. A program B connected on a COM port normally detects if the program A sends datas. To test this I have created two virtual ports pair with com0com, COM1/CNCB1, COM2/CNCB2. With hub4com I connected like explained here
But when I try to connect to COM1 or COM2 with A or B, it cannot be done because the port is already in use.
SO my problem is that I want the two ports to communicate.
-> First question: is the architecture in the tutorial good to deal with. I mean is it ok to deal with COM1/CNCB1 and COM2/CNCB2?
-> Second question: the command to connect the two ports is "hub4com options \.\input_COM \.\output_COM1" \.\output_COM2"...
SO I tried to do: "hub4com -baud=9600 \.\COM1 \.\COM2". The command is valid and I get the following return:
Open("\\.\COM1", baud=9600, data=8, parity=no, stop=1, octs=off, odsr=off, ox=off, ix=off, idsr=off, ito=0) - OK
Open("\\.\COM2", baud=9600, data=8, parity=no, stop=1, octs=off, odsr=off, ox=off, ix=off, idsr=off, ito=0) - OK
Route data COM1(0) --> COM2(1)
Route data COM2(1) --> COM1(0)
Route flow control COM1(0) --> COM2(1)
Route flow control COM2(1) --> COM1(0)
Started COM1(0)
Started COM2(1)
So the road is established and the datas should communicate. But I can't connect on the COM ports with my programs. So I tried to connect on CNCB1 and CNCB2 instead. I can connect on the COM ports. But I don't know if the data have arrived.
-> So third question: is there a reliable way to know if COM1 sends datas to COM2? Just a little software would be great, to test the architecture
It should be fine, they're just names. If you're going to have a man in the middle type of application, you'd want the data to flow like... (ProgramA -> COM1 -> CNCB1 -> ProgramB -> COM2 -> CNCB2 -> Destination.) So ProgramB should have ports open for both CNCB1 and COM2.
I'm not too familiar with hub4com to give you an answer for that. It sounds like hub4com is opening the ports up and your application is also trying to open the port up. Only one application can have access to a port.
Sounds like you need a port monitor. http://technet.microsoft.com/en-us/sysinternals/bb896644.aspx
You don’t need hub4com if you just have 2 programs communicating with each- other. Just use com0com to set up a port pair like : COM1<>COM2.
Now select Com1 in Program A and Com2 in Program B, and that should work. (This is "One-To-One-Comms")
For "One-To-Many-Comms", you need hub4com:
Example 1:
Program A is your data- source, and both Program B and Program C needs to receive the data from A. Then you go like this :
com0com : COM1<>CNCB0 ; COM2<>CNCB1 ; COM3<>CNCB2
hub4com --route=0:All \\.\CNCB0 \\.\CNCB1 \\.\CNCB2
Now Use: Com1, 2 and 3 in Program A, B and C.
Example 2:
COM7 is a real comport with an external data- source like a GPS receiver connected to it. Program A , B and C needs to receive the data from COM7. Then you go like this :
com0com : COM1<>CNCB0 ; COM2<>CNCB1 ; COM3<>CNCB2
hub4com --octs=off --route=0:All \\.\COM7 \\.\CNCB0 \\.\CNCB1 \\.\CNCB2
Note: The “--octs=off” command is needed when working with real com ports. Also, if the real com port needs to work at say 4800 baud, you need to add the command: “--baud=4800”.
Example 3:
You need bidirectional comms between 3 programs: Program A sends to B and C; B sends to A and C; and C sends to A and B. Then you go like this :
com0com : COM1<>CNCB0 ; COM2<>CNCB1 ; COM3<>CNCB2
hub4com --route=All:All \\.\CNCB0 \\.\CNCB1 \\.\CNCB2
Note: “Realterm” is a good free program to use to test your comms. (open it 3 times for this test)
Example 4:
Hub4com is also good for a "Com<>TCP<-->TCP<>Com"- network connection. Like this:
Server side:
com0com : COM1<>CNCB0
hub4com \\.\CNCB0 --use-driver=tcp 7000
Client side:
com0com : COM1<>CNCB0
hub4com \\.\CNCB0 --use-driver=tcp 192.168.20.3:7000
Note: Change the IP address to the address of your Server computer on your Ethernet or WiFi network. On both computers you can now use COM1 to send data to the other over your network.
Portmon is discontinued and doesn't work in recent (x64) Windows versions...
So now, in Windows, you can use this nice program: Serial-Lab
I had a similar problem and also used com0com in combination with above mentioned SerialLab.
When com0com got installed it created COM3 and COM4 ports and I used those two for testing. In your case it seems you have COM1 and COM2 created by com0com?
In my (Java) application I was then sending data to COM4 while in SerialLab I connected to COM5 and I was able to read the data sent from my Java application. You can also send data from SerialLab, so you can test an simulate communication in all directions.
Another similar program is also MyTerm.