Not receiving data in LCP(PPPoS) phase over UART(ESP-32 -> Sim7600) - c++

On my ESP32 I am having trouble creating a working PPP interface to my ISP.
I am using an ESP-32 Ethernet kit and have it hooked up to a Simcom EVB Kit with a Sim7600G chip.
With this hardware I am using ESP-IDF in combination with LWIP to get the PPP connection going.
At first I have to send all the corresponding AT commands to make sure it is actually ready for a PPP connection.
These AT Commands are the following:
AT+CGDCONT=1,"IP","<APN>"
AT+CGACT=1,1
AT+CREG? <Must be 0,5 -> Registered and Roaming>
ATD*99***1# -> I receive "Connect 152000" and start the PPP phase.
After I received the Connect 152000 as a response, I start the PPP connection.
m_pPpp = pppapi_pppos_create(&netif, pppos_output_cb, ppp_link_status_cb, nullptr);
pppapi_set_default(m_pPpp);
pppapi_set_auth(m_pPpp, PPPAUTHTYPE_PAP, "", "");
err_t err = ppp_connect(m_pPpp, 0);
This is the output of the corresponding code:
ppp phase changed[2]: phase=0
ppp_connect[2]: holdoff=0
ppp phase changed[2]: phase=3
pppos_connect: unit 2: connecting
ppp_start[2]
ppp phase changed[2]: phase=6
pppos_send_config[2]: out_accm=FF FF FF FF
ppp_send_config[2]
pppos_recv_config[2]: in_accm=FF FF FF FF
ppp_recv_config[2]
ppp: auth protocols: PAP=1
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0xcd3e2cad> <pcomp> <accomp>]
I: pppos_output callback called
I: ppp_output_cb() len = 45
W: ip4addr: 0.0.0.0
W: his_ipaddr: 0.0.0.0
W: netmask: 255.255.255.255
pppos_write[2]: len=24
ppp_start[2]: finished
As far as I can see, it goes through a couple of phases regarding the PPP connection.
Phase 0(dead, obviously)
Phase 3(initialize)
Phase 6(Establish).
It will not continue after this. I see the pppos_output callback is being called, which is supposed to happen. As far as I understand this function is so you can write the PPP-data towards your UART device.
Seperately I have a task running in the background to poll my UART device for written data so I can write this to the pppos_input function. I never receive any data...
I honestly have no idea where if I am missing something or how to troubleshoot this.
Also the LWIP documentation is quite plain and is missing examples, which makes it even harder.
Additional things I have tried:
AT+CGDCONT=1,"PPP","APN". <- This will result in the Sim7600 never connecting and remains searching. Should I use these PDP settings or stay with IP?
Applied the above AT command and tried starting the PPP phase, hoping it would result in somehow connecting...

I have not found the solution to this problem with the mentioned frameworks. Instead I reverted to another dependency from the ESP-IDF: esp-modem. I managed to get a working solution by following the pppos-client and modem-console examples within my current software.

Related

Lag when sending an http request using POCO C++ libraries

I have written a program making an http POST request to google-analytics using the following code:
Poco::Net::HTTPClientSession session("www.google-analytics.com");
Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_POST, "/collect",Poco::Net::HTTPMessage::HTTP_1_1);
Poco::URI uri("");
uri.addQueryParameter("v", "1");
////// more parameters of the uri //////
req.setContentLength(uri.getRawQuery().length());
session.sendRequest(req) << uri.getRawQuery();
A user of the program has reported a 20 seconds freeze of the program every time a request is made. I have not been able to replicate the problem on any other computer, nor understand where it could come from.
He uses an ethernet connection to a modem TP-Link 300Mbps Wireless N Gigabit ADSL2+Modem Router TD-W8970. When the modem is turned off, the lag does not occur (my code throws an exception when sendRequest fails).
Any help/suggestion on the problem would be much appreciated!
Thanks.

GDB Server and GDB Client who sends the "+" first?

GDB Client:
NetworkClientConnect 503: Attempting host: 10.23.37.155 (addr: 02CE4B50)
NetworkClientConnect 518: Connected to host: 10.23.37.155
NetworkClientRecv 576: Recv Packet: +
NetworkClientSend 550: Sent Packet: +
GDB Server:
Debug: 243 275 pld.c:207 handle_pld_init_command(): Initializing PLDs...
Info : 244 22937 server.c:83 add_connection(): accepting 'gdb' connection from 3333
Debug: 247 22954 gdb_server.c:260 gdb_get_char_inner(): received '+'
Debug: 248 22954 gdb_server.c:272 gdb_get_char_inner(): returned char '+' (0x2b)
Initially the connections are made then they acknowledge that they got the packet by sending "+". In my case the client says it is receiving a '+' and so does the server as the very first info exchange. That does not make sense. One has to send and the other receive what I see is both receiving and sending in parallel. But it is working. So where is my thinking wrong? Also if you can point me to a URL which shows exactly the GDB Server and Client protocol exchange that would be awesome.
In your GDB client printout, it looks to me, messages are not printed in order (see that Recv packet has number 576, and sent 550).
Use wireshark or similar tool to debug an issue like this.
I tried connecting to gdbserver via loopback and according to wireshark the dialogue looks like this:
client sends "+"
client sends "$qSupported:multiprocess+;xmlRegisters=i386;qRelocInsn+#b5"
server sends "+"
server sends "$PacketSize=3fff;QPassSignals+;..."
and so on.
Gdb does help an option selectable at runtime that can help debug such things. Start it, then issue "set debug remote 1". Same on remote side. Start gdbserver by "gdbserver --remote-debug ...". This will print remote gdb protocol dialogue on both sides.
Another, possibly best if most time consuming options is to check the gdb&gdbserver source.
I got into WireShark Help Forum (http://ask.wireshark.org/) and posed the question there. "How to capture packets between 2 IP's". There a person called Quadratic gave a brilliant answer. You can refer the WireShark site or here it is. It works like a charm!!
Do this:
• When you first start Wireshark, click on the button in the far upper-left that says "List the available capture interfaces" when you scroll over it.
• In the new "Capture Interfaces" window that opens, select the interface you want to capture packets (with the check box on the left-hand side) and click"Options".
• In the Capture Options window, on the lower-left corner there should be a "Stop Capture Automatically After..." seciton. Check the "packets" option and put in a value of 50
• In the same Capture Options window, in the text box to the right of "Capture Filter", type the statement (without quotes) "ip host 10.xx.xx.xx and ip host 10.yy.yy.yy".
• Hit the Start button :)
One small thing to note - if the interface you're capturing is doing vlan tagging, replace the capture filter statement to "vlan and ip host 10.xx.xx.xx and ip host 10.yy.yy.yy" without quotes.
Edit:
An even simpler solution is to just use one command line statement:
C:\Program Files\Wireshark\dumpcap.exe -c 50 -i {interface name or number} -w {wherever you want to save the packet capture file}

C++ - Testing serial ports without a physical device

I have a program that splits a serial device into multiple virtual serial ports and routes all the data to them.
---- /dev/ttyS1.a [data]->
|
[data]-> /dev/ttyS1 ---- /dev/ttyS1.b [data]->
|
---- /dev/ttyS1.c [data]->
My working program (pseudo code for sake of readability and simplicity):
poll(...) {
// Route data from master to vsp
master.read(buf)
for(virtual serial ports as vsp) {
vsp.write(buf)
}
// Route data from vsp to master (if need be)
for(virtual serial ports as vsp) {
if(vsp.needs_to_write()) {
vsp.read(buf)
master.write(buf)
}
}
}
I have one physical serial port device on my machine that continuously feeds data through, which is how I tested if my program initially works, but I would like to write a test to emulate/simulate writing and reading both directions and verifying the data on both ends. Since the data I am receiving from my physical serial port device writes seemingly random data it is hard to verify what is going in is exactly what is being written.
How would I be able to do this? (pseudo code)
1. fork process that feeds a known char sequence into /dev/ttyS2 in a loop
2. use my program to read from the COM `master.read(buf)` and then write to the vsp `vsp.write(buf)`
3. how can I verify that after writing to the buf that the vsp has the correct data?
Any help is appreciated I am confused on how to automate testing this.
Edit 1:
No one can help?
I think you can use com0com to test. You can connect virtual serial ports and then write to one and read from other what it received.
enter link description here

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.

Libnodave - daveStart() Error using TCP Connection

I have established connection to a Siemens S7-300 PLC (simulated via PlcSIM) using the libnodave library. There are no issues connecting and writing data to the PLC. However, I am unable to change the status of the PLC from Start/Stop. I am attempting to use the following libnodave methods for such actions:
int daveStatus = daveStart(dc);
int daveStatus = daveStop(dc);
Both function calls return the same Error: 33794
nodave.c Cites the error as the following:
case 0x8402: return "CPU already in RUN or already in STOP ?";
The use of the daveStart() and daveStop() functions can be viewed in the example testS7online.c:
if(doStop) {
daveStop(dc);
}
if(doRun) {
daveStart(dc);
}
In the examples the start/stop functions are only called when MPI connections to the PLC are made. Does anyone know if the start/stop functions are supported for use with TCP connections? If so, any suggestions as to what may be causing my error?
I have just tried dc.start() and dc.stop() using libnodave 8.4 and NetToPlcSim tool. It worked perfectly. Possibly you don't use NetToPlcSim tool that makes connection to PLCSim via TCP/IP (that is 127.0.0.1 port 102 obviously) hence dc can't even connect. So if your lines don't work, then u must be doing something wrong.