Sending data to MyMqttHub through AT Commands - tcp

I've been coding a AT client using ESP32 S2 as a host and Nimbelink's Skywire Nano (nrf9160) as a LTE Modem controlled by Serial AT Commands, the LTE module is responsive and is working well. The LTE modem has an internal TCP Stack, which we have used to send data to dweet.io through a HTTP POST with success, but we haven't been successful in doing the same sending data to a private MQTT server.
The LTE module uses a method called Socket Dials, these are AT commands that facilitate sending data to the web, it basically consist in these three commands:
AT#SOCKET to activate the socket
AT#TCPCONN to connect to an URL
Example:
at#xtcpconn=3,"node02.myqtthub.com",1883
AT#TCPSEND which opens a > promt in which you enter whatever you are going to send
I'm not a communication protocols expert, so it has been a bit difficult finding the correct way to send the string since I haven't found similar examples using TCP sockets. I have tried sending mosquitto_pub strings withouy success and nimbelink only has an example using HTTP, I hope some one can help me with this or at least send me in the right direction.
at#xsocket=3,1,1
#XSOCKET: 3,6
OK
at#xtcpconn=3,"node02.myqtthub.com",1883
#XTCPCONN: 1
OK
at#xtcpsend=3
mosquitto_pub -h node02.myqtthub.com -i hub -u user -P 'password' -t topic -m "hello world"#XTCPSEND: 104
OK
SOCK: 3,HUP
Edit: added the LTE log of the attempt

Related

How to monitor simple bi-directional TCP socket traffic (Telnet) in the middle of two endpoints?

I'm debugging an IOT protocol between two essentially black boxes on my local network talking over a telnet connection. On either end, I can specify the IP address and port. I'd like to observe / record the data exchanged between the client and server.
I'm thinking a proxy running on my Mac laptop might work. I've done some research and experimentation with nc (BSD netcat). I can only figure out a working one-way pipe, and thus the protocol exchange does not happen between A and B.
Telnet TCP server (A) <===============> TCP Client (B)
Telnet TCP server (A) <===\ /==> TCP Client (B)
\ /
\ /
Proxy/Intercept (C) *
Using a feature in the server device (A), I can have two telnet connections active. Using this, I've been able to see the server's (A) responses to whatever Client (B) is commanding, but I cannot see the Client (B) commands. ~80% of the responses are a code meaning invalid command received, but a few are reasonable responses for what this thing should be doing. I can also note that that data rate is only about 4 Bytes / second, so I'd be happy to just watch this exchange live in a terminal.
To clarify: I can power-cycle the client (B), and it will re-establish a socket connection to the IP address and port of my choosing, so I'm not really thinking about a sniffing / Wireshark type solution.
I guess I'm hoping for a relatively straightforward solution run in the shell using existing standard tools. I suppose a small program could be written in Python or something to do this, but I hope that's overkill.

SIM5360A - HTTP bad request

I'm developing a device with an ESP32 connected through a level shifter to a SIM5360A.
The system is supposed to make a periodic HTTP post with it's sensor readings.
Even though I have a working setup with a SIM5360E breakout board, when I shifted to a custom PCB with a SIM5360A (because of carrier frequency), I'm not able of making an HTTP post/get.
Using a server hosted in AWS and doing a TCPDump, I detected that before the GET payload the SIM5360A inserts two spurious characters (0x01 0xF0).
The commands I'm sending to the modem are:
AT+CIPOPEN=0,"TCP","XX.XXX.XXX.XXX",80
AT+CIPSEND=0,39
GET /login HTTP/1.1<CR><LF>
Host: XX.XXX.XXX.XXX:80<CR><LF>
<CR><LF>
<CR><LF>
Using Wireshark to analyze the query on the server side, the data received is:
{0x01} {0xF0} GET ....
Those two characters confuse the apache server (and Wireshark) which doesn't interpret this as a HTTP message driving a 400: Bad Request.
I verified using PostMan that the query is correct. I also use the exact same firmware on my SIM5360E breakout successfully.
Using a scope I verified that the two characters are dumped into the UART channel by the SIM5360A and not by the level shifter or the ESP32.
I wanted to do a firmware upgrade on the SIM5360A but SIMCOM only has the 'E' firmware update available on it's website (just including this consideration for if someone has the firmware update for this version).
Any thoughts?
Thanks in advance
Bests

BlueZ BLE GATT write request (0x12) instead of (0x16)

I am trying to reverse engineer a BLE device for research. The BLE device does not require pairing.
One of the commands that are written that I can see in wireshark is write to a specific handle. When I try to do the same using the Gatttool write request:
sudo gatttool -i hci0 -b 54:6C:0E:21:F5:99 --char-write-req -a 0x0030
-n 110100701301000110010030721000d68c054688df413aa89fb3cfab3d6457172000053958839fa147ac53c129eafc524829bc9ed7655fe96c9f641745c4e07cf044
It uses a 0x16 prepare write request instead and there seems to be some error as well. Below is an image of both captures, the left side is the GAtttool request and the right side is the request done by the phone.
The communication to the right has earlier negotiated a larger MTU. That's why it can send the whole value in one request.

Multiple programs on a machine should receive the network traffic arriving on one port

I have UDP network traffic arriving on my machine (OSC traffic from an iPad, to be exact) and I want two programs to be able to receive that traffic. The problem is that I can't bind to the same network port with two programs at once and I can't send to multiple ports with the iOS app I'm using. How can I solve this problem?
You can use the power of the command line for this. The following snippet uses socat (probably needs to be installed beforehand) and tee (should be preinstalled on any OS X or Linux).
socat -u UDP4-RECVFROM:8123,fork - | tee >(socat -u - UDP4-SENDTO:localhost:8223) | socat -u - UDP4-SENDTO:localhost:8323
Explanation: socat listens for traffic on UDP port 8123, pipes it to tee, which pipes it to two other instances of socat forwarding it to ports 8223 and 8323 on localhost respectively. With your two programs you need to listen to those ports on localhost.
While the answer with using socat is elegant it is not clear for me, what you are trying to do:
both programs should receive all parts of the traffic and they will only receive and not reply. This can be done with the proposed socat way
both program should receive all parts of the traffic and there reply will be mixed together (how?)
each of the programs should only receive parts of the traffic, e.g. the one which the other did not get. This should be possible if both of your programs use SO_REUSEADDR, SO_REUSEPORT. Replies will then be mixed together.
or do you actually want to communicate with each of the programs seperatly - then you would have to use either multiple sockets in the iOS app (which you don't want to do) or built your own protocol which does multiplexing, e.g. each message is prefixed with there target app and on the target machine a demultiplexer application will receive all packets and forward them to the appropriate application and wrap the replies back in the multiplexing protocol.
In summary: please describe the problem your are trying to solve, not only one small technical detail of it.
The problem is that I can't bind to the same network port with two programs at once
Yes you can. Just set SO_REUSEADDR and maybe SO_REUSEPORT on both of them before you bind.

Wavecom GSM modem as a TCP client

I've been trying to do TCP communication using my Wavecom Fastrack modem. What I want to achieve is make the modem connect to a specified TCP server port to enable me to transfer data to and from the server. I found some information on than in the user's guide.
Basing on the information you can find on page 66 I created an application that opens the serial port to which the modem is connected and writes the following AT commands:
AT+WIPCFG=1 //start IP stack
AT+WIPBR=1,6 //open GPRS bearer
AT+WIPBR=2,6,11,"APN" //set APN of GPRS bearer
AT+WIPBR=2,6,0 //username
AT+WIPBR=2,6,1 //password
AT+WIPBR=4,6,0 //start GPRS bearer
AT+WIPCREATE=2,1,"server_ip_address",server_port //create a TCP client on port "server_port"
AT+WIPDATA=2,1,1 //switch do data exchange mode
This is exactly what the user's guide says. After the last command is sent to the modem, the device switches to data exchange mode and from then on everything what is written to the serial port opened by my application should be received by the server and everything the server sends should appear in the input buffer of that port.
The thing is that I did not manage to maintain stable bidirectional communication between the server and my modem. When I write some data to the serial port (only a few bytes), it takes a lot of time before the data appears on the server's side and in many cases the data does not reach the server at all.
I performed a few tests writing about 100 bytes to the serial port at once. Logging the data received by my server application I noticed that the first piece of data (8-35 bytes) is received after a second or two. The rest of the data appears in 2-5 seconds (either as a whole or in pieces of the said size) or does not appear at all.
I do not know where to look for the reason of that behaviour. Did I use wrong AT commands to switch the modem to TCP client mode? I can't believe the communication may be so slow and unstable.
Any advice will be appreciated. Thank you in advance.
what OS are you running? Windows does a pretty good job of hiding the messy details of communicating with the GPRS modem, all you have to do is create a new dial-up connection. To establish the connection you can make a call to the Win32 RasDial function. Once connected, you can use standard sockets to transfer data on a TCP port.
i have been using wavecomm modem for 2 years now.As far as i know from my experience is that if you are able to send some of the data then you can send all of the data.
the problem might be in the listening application which receives the data on the server side.
It could be that it is unable to deal with the amount of data that you are trying to send.
try sending the same data in smaller busts
with some delay in between them,then you might receive all data intact.

Resources