I am currently developing an IoT device which must connect to an API-server.
Since this is my first project with mbedtls on freertos I am a bit lost and I hope I can learn fast.
System summary:
Controller: STM32F746IGT
OS: Freertos
TCP/IP-Stack: LWIP
And of course mbedTLS
So bascially what the programm needs to do:
Start a TLS connection
Get an OAuth2 token from the server
Do something with it (not yet clear because I am missing a LOT of information)
TBD
So I managed with the help of others to start up the TLS connection. This works so far. It correctly encrypts and decrypts messages with the server. I checked that with Wireshark and I extracted the Master Secret from it. (I have made an HTML/JS application to extract the āclient hello randomā and āmaster secretā key from the debug output of mbedtls if anyone wants it)
The problem
So after analyzing the whole datastream which is sent to the serve I noticed that the POST header is sent twice for no apparant reason.
I only send it once in the code. It looks like this:
apperantly the server also receives two POST requests.
I also have the entire debuglog of this session stored so if more informations are needed I can provide.
All login data and server addresses have been changed.
Hi Adrian,
Iām not very good at this, however Iām using Mbed TLS connection for use on Firebase. Below is my POST function that works, or at least it appears to be working, I cantā see any double posting issues and runs for days. Iām using the Socket reuse method but have found that after precisely 8 minutes I get
HttpRequest failed (error code -3012)
where I detect this and close the socket and open a new one, other than that no issues. The single non reuse function works with no issues.
I see you have a āwhileā in your write line, perhaps try a different way?? but I know noting about this its only a tool for me to send stuff to Firebase.
bool postFirebase(char* FirebaseUrl, char *stringToProcess)
{
// HttpsRequest* post_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, FirebaseUrl); // non socket reuse function
HttpsRequest* post_req = new HttpsRequest(socket, HTTP_POST, FirebaseUrl); // socket reuse function
post_req->set_header("Content-Type", "application/json");
HttpResponse* post_res = post_req->send(stringToProcess, strlen(stringToProcess));
if (!post_res) {
time_t seconds = time(NULL);
printf("Https POST failed (error code %d), %s", post_req->get_error(), ctime(&seconds));
socket->close();
delete socket;
delete post_req;
TLSSocket* socket = new TLSSocket();
startTLSreusesocket((char*)FirebaseID); // restart TLS reuse socket if failure
return 0;
}
else{
//dump_response(post_res);
delete post_req;
return post_res;
}
}
My library is here, you could pick the bones out it and if you find out why it trips out after 8 minutes, let me know.
The POST-Request is only sent once with the data directly attached to it. After a while the server closes the connection since the request has the wrong format and it doesnāt know how to handle it.
The POST-Request will look something like this:
POST /uaa/oauth/token HTTP/1.1
Host: my.server.com
Content-type: application/x-www-form-urlencoded
grant_type=password&username=some.email@address.org&password=password1234&client_id=iiot-gateway&client_secret=xxxxxxxxx
The server gives a correct reply but of course terminates the connection.
As mentioned by @star297, you are sending your POST message in a while loop.
I am guessing that the first āwriteā returned some error or 0 ( please check the error code), and the second write returned a positive number. Sinceyou are not modifying the positionin thebufbetween everty iteration, according to how many bytes were written, you are trying to write samebuf, with same original len. I would first check what the return code from mbedtls_ssl_write()` is and change the code to the following:
sprintf((char *) buf, POST_REQUEST);
len = strlen((char *) buf);
ret = 0;
while((ret = mbedtls_ssl_write(&ssl, buf + ret, len - ret)) <= 0) { ...
Hey @roneld01
Thanks for the tip but I donāt think this is the problem but I will try tomorrow. Hopefully Iāll be at least one step further. I keep you posted on what the result will be. I will have the tools then again to analyze the network traffic.
All the best
Adrian
Hi Adrian,
Are you sure that your data is correct? Your server response looks just like I had before I got the authorization and .json data format correct.
Perhaps to save you pulling the rest of your hair out, could I suggest to try my example.
It may give you a starting point. Then you can work back on your C version.
My server response, although a PUT in this case, not POST, looks like this:
{āHumidityā:ā96.00ā,āPressureā:ā1081.00ā,āTempInā:ā73.85ā,āTempOutā:ā108.48ā,āTimeā:"18:44:10 02/03/2020 "}
PUT Current okay, time: 18:44:10 02/03/2020
Hey Paul
I would not know where to start to be frankā¦ I am currently answering you outside of my working hours trying to find a solution for this problem. (Frankly, I pulled to many hairs out already and I am wondering if I am even smart enough to solve this.)
First of all it is a custom board with a PHY and certain pinout I donāt know how easy this would be to port. I donāt know if that porting work is worth the time.
Second, I donāt have the tools yet to make this work and I would need to study those too which will take up another day or so.
I am honestly lost. I can try and make it work here at home but then I would need to port it at work.
Adrian, your custom board is basically this with a different pin count ?
You could use Mbedās RTOS and this board to develop your application. once you get it working all you would need to do is change the pin defines for the PHY in the ātarget_overridesā in the mbed_app.json file to suit your custom board. It may save you a lot of time?
Hey Paul
If I would have the board and if we didnāt already had a bigger application running on it, I would change the OS but for now I will not do that. Since I have no idea on how I can explain this to my boss. I already stepped outside my boundaries as I ordered the managed switch. I was barely able to start this programm up let alone now starting up a whole new OS.
At least it would be the same PHY.
@roneld01 I tried what you told me but it still seems to send out the POST twice. I am lost on what to do next.
If the last newline/cariage return is left out, only the POST seems to be sent by wireshark.
But on closer inspection the whole package is sent out correctly.
I am starting to think this is an problem because of the formating and the interpretation of the server.