Skip to main content
Associate II
July 10, 2026
Solved

ST87M01: Keeping transparent TCP pipe open during host-managed TLS

  • July 10, 2026
  • 5 replies
  • 89 views

Hello ,

I am planning a new NB-IoT design using the ST87M01 module. I am currently using a Nucleo-U545RE-Q host board paired with the EVKITST87M01-2 evaluation kit.

The application involves downloading weather observation files (TXT and XML formats, each under 100 KB) from a public server over HTTPS. Since the target server requires TLS 1.3, a large HARICA RSA ROOT CA 2021 (RSA-4096) certificate, and specific Cipher Suites not supported natively by the module, I have decided to run the TLS 1.3 stack directly on the STM32U545 host MCU. The ST87M01 will be used purely as a transparent TCP/IP pipe.

Specifically, the server enforces strict cryptographic handshakes with the following parameters, which I will process on the host MCU:

  • TLS 1.2: ECDHE_RSA with curve P-256 and AES_128_GCM
  • TLS 1.3: X25519 key exchange and AES_256_GCM

During early tests, I have noticed that the module frequently transitions from RRC Connected to RRC Idle mode, indicated by the unsolicited notification changing from +CSCON: 1 to +CSCON: 0. Given the high latency inherent to NB-IoT networks and the time required for the MCU to process the TLS handshake over the air, I have some concerns regarding socket stability.

I have a few questions about how to handle this with my current setup:

  1. TCP Socket Stability during +CSCON: 0 Transitions:
    When the ST87M01 transitions from +CSCON: 1 to +CSCON: 0 (RRC Idle), does the underlying raw TCP socket remain reliably open in the modem's internal stack? Is there a risk that this RRC connection drop triggers a premature closure of the transparent TCP pipe while the MCU is negotiating the TLS session? Are there specific socket timeout parameters I should tune to ensure the pipe stays alive during these state changes?
  2. Power Management (eDRX / PSM) Interaction:
    How does the transparent TCP data streaming interact with the module's power-saving states during a host-managed session? If the TLS handshake or the subsequent 100 KB data transfer experiences delays while the module is in RRC Idle (+CSCON: 0), is there a risk that the module attempts to enter a deep sleep mode (like eDRX or PSM) and drops the active network context? What is the recommended configuration to keep the network pipe stable during active host-managed data transfers?

Any application notes, AT command recommendations, or tips for ensuring a stable raw TCP pipe with host-based TLS on this setup would be highly appreciated.

 

Thank you in advance.

-Henry

Best answer by Didier HERROUIN

Dear HenryK,

Thanks a lot for your inputs : as you said, they can be very useful for people facing the same issue.
To close the chapter about RSA, it is not only a matter of AT command size but mostly of internal supported algorithms. Indeed, as mentioned in the Application Note, RSA certificates and keys are not supported by ST87M01 .

Only EC certificates and keys can be provisioned and used.

Regards.

5 replies

Didier HERROUIN
ST Technical Moderator
July 16, 2026

Dear HenryK,

The TCP socket will remain active and the PDP context will be saved inside the modem when CSCON = 0.
I assume that your plan is to send the data in binary mode ? You will have to chunk the file as the max data length is 1340 bytes per sending.

When you install the sST87M01 GUI (STSW-ST87MGUI | Product - STMicroelectronics), it will create a folder on your PC with multiple application notes or Design guide. You can directly access this folder through the GUI, just click on “Documentation and Applications Notes” in the left of the menu.

The AN “ST87MXX_TCP_UDP_IP_Application_Note”  should answer most of your questions, let me know if some points are still opened. 

Best regards,

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question.
HenryKAuthor
Associate II
August 4, 2026

Hi, thank you Didier HERROUIN for the reply. Sorry for the delayed response, I was on vacation.

Maybe a different product would make more sense for this use case. Unfortunately, I cannot even get a normal "GET..." request to work (without TLS encryption)(can’t get response from server). The documentation seems a bit lacking to me, and of course, the situation is also limited by my own lack of experience with this kind of architecture.

Thanks again for your time.

 

Below is one example of many different attempts to use AT commands (tested with \r\ŋ… and without and splitting send with “Connection Close” etc etc.):

14:07:39.639  >AT#RESET
14:07:39.639
14:07:39.639 OK
14:07:40.335
14:07:40.335 #REBOOT_HOST
14:07:40.600
14:07:40.600 #SIMST: 1
14:07:40.766
14:07:40.766 +CEREG: 2,"","",,,,"",""
14:07:42.024
14:07:42.024 +CEREG: 0,"","",,,,"",""
14:07:42.024
14:07:42.024 +CEREG: 2,"","",,,,"",""
14:07:42.786
14:07:42.786 +CSCON: 1
14:07:46.297
14:07:46.297 +CGEV: ME PDN ACT 5
14:07:46.297
14:07:46.297 #IPCFG: 5,0,1
14:07:46.727
14:07:46.727 +CEREG: 5,"B542","0005916A",9,,,"",""
14:07:57.259
14:07:57.259 +CSCON: 0
14:08:10.606 >AT+CEREG?
14:08:10.904
14:08:10.904 +CEREG: 5,5,"B542","0005916A",9,,,"",""
14:08:10.904
14:08:10.904 OK
14:08:15.544 >AT#SOCKETCREATE=5,0,TCP,80,60,60,1
14:08:15.644
14:08:15.644 #SOCKETCREATE: 0
14:08:15.644
14:08:15.644 OK
14:08:19.883 >AT#TCPCONNECT=5,0,193.166.221.39,80
14:08:21.208
14:08:21.208 +CSCON: 1
14:08:21.539
14:08:21.539 OK
14:08:27.502 >AT#IPSENDTCP=5,0,0,GET /wfs?service=WFS&version=2.0.0&request=getFeature&storedquery_id=fmi::observations::weather::simple&fmisid=129963&parameters=t2m,ws_10min,wd_10min&starttime=-10&endtime=now&timestep=10 HTTP/1.1\r\n\r\n
14:08:27.667
14:08:27.667 OK
14:08:38.431
14:08:38.431 +CSCON: 0
14:10:30.706 >AT+CEREG?
14:10:30.739
14:10:30.739 +CEREG: 5,5,"B542","0005916A",9,,,"",""
14:10:30.773
14:10:30.773 OK

and HTTPMETHOD works consistently every time:

14:14:09.867  >AT#RESET
14:14:09.867
14:14:09.867 OK
14:14:10.563
14:14:10.563 #REBOOT_HOST
14:14:10.794
14:14:10.794 #SIMST: 1
14:14:10.960
14:14:10.960 +CEREG: 2,"","",,,,"",""
14:14:21.394
14:14:21.394 +CEREG: 0,"","",,,,"",""
14:14:21.394
14:14:21.394 +CEREG: 2,"","",,,,"",""
14:14:22.157
14:14:22.157 +CSCON: 1
14:14:24.972
14:14:24.972 +CGEV: ME PDN ACT 5
14:14:25.005
14:14:25.005 #IPCFG: 5,0,1
14:14:25.469
14:14:25.469 +CEREG: 5,"B542","0005916A",9,,,"",""
14:14:36.001
14:14:36.001 +CSCON: 0
14:14:38.782 >AT+CEREG?
14:14:39.047
14:14:39.047 +CEREG: 5,5,"B542","0005916A",9,,,"",""
14:14:39.047
14:14:39.047 OK
14:14:46.929 >AT#SOCKETCREATE=5,0,TCP,80,60,60,1
14:14:47.028
14:14:47.028 #SOCKETCREATE: 0
14:14:47.028
14:14:47.028 OK
14:14:53.983 >AT#TCPCONNECT=5,0,193.166.221.39,80
14:14:55.142
14:14:55.142 +CSCON: 1
14:14:55.440
14:14:55.440 OK
14:15:02.130 >AT#HTTPSTART
14:15:02.263
14:15:02.263 OK
14:15:06.403
14:15:06.403 +CSCON: 0
14:15:07.893 >AT#HTTPMETHOD=GET,opendata.fmi.fi,"/wfs?service=WFS&version=2.0.0&request=getFeature&storedquery_id=fmi::observations::weather::simple&fmisid=129963&parameters=t2m,ws_10min,wd_10min&starttime=-10&endtime=now&timestep=10",1
14:15:08.059
14:15:08.059 OK
14:15:14.617 >AT#HTTPSEND=5,0
14:15:14.882
14:15:14.882 OK
14:15:15.710
14:15:15.710 +CSCON: 1
14:15:17.068
14:15:17.068 #HTTPRECV: 0,415,200,2431
14:15:17.068
14:15:17.068 #HTTPRECV: 1,903
14:15:22.433
14:15:22.433 #HTTPRECV: 1,1528
14:15:26.010 >AT#HTTPREAD
14:15:26.142
14:15:26.142 #HTTPREAD: 415
14:15:26.142 HTTP/1.0 200 OK
14:15:26.142 Access-Control-Allow-Origin: *
14:15:26.142 Cache-Control: public, max-age=600, stale-while-revalidate=60, stale-if-error=86400
14:15:26.142 Content-Length: 2431
14:15:26.142 Content-Type: text/xml; charset=UTF-8
14:15:26.142 Date: Tue, 04 Aug 2026 11:15:15 GMT
14:15:26.176 Expires: Tue, 04 Aug 2026 11:25:15 GMT
14:15:26.176 Last-Modified: Tue, 04 Aug 2026 11:15:15 GMT
14:15:26.176 Server: SmartMet Server (22:40:49 Jul 14 2026)
14:15:26.176 Vary: Accept-Encoding
14:15:26.176 Connection: Keep-Alive
14:15:26.176
14:15:26.176
14:15:26.176
14:15:26.176 OK
14:15:27.699 >AT#HTTPREAD
14:15:27.898
14:15:27.898 #HTTPREAD: 903
14:15:27.898 <?xml version="1.0" encoding="UTF-8"?>
14:15:27.898 <wfs:FeatureCollection
14:15:27.898 timeStamp="2026-08-04T11:15:15Z"
14:15:27.898 numberReturned="3"
14:15:27.898 numberMatched="3"
14:15:27.898 xmlns:wfs="http://www.opengis.net/wfs/2.0"
14:15:27.898 xmlns:gml="http://www.opengis.net/gml/3.2"
14:15:27.931 xmlns:BsWfs="http://xml.fmi.fi/schema/wfs/2.0"
14:15:27.931 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
14:15:27.931 xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd
14:15:27.931 http://xml.fmi.fi/schema/wfs/2.0 https://xml.fmi.fi/schema/wfs/2.0/fmi_wfs_simplefeature.xsd"
14:15:27.931 >
14:15:27.931
14:15:27.964 <wfs:member>
14:15:27.964 <BsWfs:BsWfsElement gml:id="BsWfsElement.1.1.1">
14:15:27.964 <BsWfs:Location>
14:15:27.964 <gml:Point gml:id="BsWfsElementP.1.1.1" srsDimension="2" srsName="http://www.opengis.net/def/crs/EPSG/0/4258">
14:15:27.964 <gml:pos>69.04853 27.75700 </gml:pos>
14:15:27.964 </gml:Point>
14:15:27.964
14:15:27.964
14:15:27.964 OK
14:15:29.355 >AT#HTTPREAD
14:15:29.587 <gml:Point gml:id="BsWfsElementP.1.1.3" srsDimension="2" srsName="http://www.opengis.net/def/crs/EPSG/0/4258">
14:15:29.620 <gml:pos>69.04853 27.75700 </gml:pos>
14:15:29.620 </gml:Point>
14:15:29.620 </BsWfs:Location>
14:15:29.620 <BsWfs:Time>2026-08-04T11:10:00Z</BsWfs:Time>
14:15:29.620 <BsWfs:ParameterName>wd_10min</BsWfs:ParameterName>
14:15:29.620 <BsWfs:ParameterValue>298.0</BsWfs:ParameterValue>
14:15:29.653 </BsWfs:BsWfsElement>
14:15:29.653 </wfs:member>
14:15:29.653
14:15:29.653
14:15:29.653 </wfs:FeatureCollection>
14:15:29.653
14:15:29.653
14:15:29.653 OK
14:15:31.044 >AT#HTTPREAD
14:15:31.143
14:15:31.143 #HTTPREAD: 0
14:15:31.143
14:15:31.143 OK
14:15:33.263
14:15:33.263 +CSCON: 0
14:15:39.058 >AT#HTTPSTOP
14:15:39.158
14:15:39.158 OK
14:15:46.940 >AT#SOCKETCLOSE=5,0
14:15:47.934
14:15:47.934 +CSCON: 1
14:15:48.298
14:15:48.298 OK
14:15:58.829 >AT+CEREG?
14:15:58.962
14:15:58.962 +CEREG: 5,5,"B542","0005916A",9,,,"",""
14:15:58.962
14:15:58.962 OK
14:15:59.194
14:15:59.194 +CSCON: 0

Have a great rest of the summer!

Best regards,

Henry

HenryKAuthor
Associate II
August 11, 2026

Hi,

I couldn't just leave it at that. While the final result is probably obvious to many, I hope this helps other beginners. A successful GET request works at least when the <data> of the IPSENDTCP command is in hex format.

Here is the <data> string:

GET /wfs?service=WFS&version=2.0.0&request=getFeature&storedquery_id=fmi::observations::weather::simple&fmisid=129963&parameters=t2m,ws_10min,wd_10min&starttime=-10&endtime=now&timestep=10 HTTP/1.1
Host: opendata.fmi.fi
Connection: close

And working….:

11:44:09.932 >AT#RESET
11:44:09.932
11:44:09.932 OK
11:44:10.628
11:44:10.628 #REBOOT_HOST
11:44:10.893
11:44:10.893 #SIMST: 1
11:44:11.059
11:44:11.059 +CEREG: 2,"","",,,,"",""
11:44:15.331
11:44:15.331 +CEREG: 0,"","",,,,"",""
11:44:15.331
11:44:15.331 +CEREG: 2,"","",,,,"",""
11:44:16.093
11:44:16.093 +CSCON: 1
11:44:18.942
11:44:18.942 +CGEV: ME PDN ACT 5
11:44:18.942
11:44:18.942 #IPCFG: 5,0,1
11:44:19.406
11:44:19.406 +CEREG: 5,"B542","0005916A",9,,,"",""
11:44:29.906
11:44:29.906 +CSCON: 0
11:44:33.284 >AT#SOCKETCREATE=5,0,TCP,443,120,120,2
11:44:33.417
11:44:33.417 #SOCKETCREATE: 0
11:44:33.417
11:44:33.417 OK
11:44:39.081 >AT#TCPCONNECT=5,0,opendata.fmi.fi,80
11:44:40.075
11:44:40.075 +CSCON: 1
11:44:40.836
11:44:40.836 OK
11:44:45.871 >AT#IPSENDTCP=5,0,2,474554202F7766733F736572766963653D5746532676657273696F6E3D322E302E3026726571756573743D676574466561747572652673746F72656471756572795F69643D666D693A3A6F62736572766174696F6E733A3A776561746865723A3A73696D706C6526666D697369643D31323939363326706172616D65746572733D74326D2C77735F31306D696E2C77645F31306D696E26737461727474696D653D2D313026656E6474696D653D6E6F772674696D65737465703D313020485454502F312E310D0A486F73743A206F70656E646174612E666D692E66690D0A436F6E6E656374696F6E3A20636C6F73650D0A0D0A
11:44:46.070
11:44:46.070 OK
11:44:47.229
11:44:47.229 #IPRECV: 5,0,1318
11:44:47.858
11:44:47.858 #IPRECV: 5,0,1318
11:44:48.090 >AT#IPREAD=5,0
11:44:48.322
11:44:48.322 #IPREAD: 5,0,1318
11:44:48.322 HTTP/1.1 200 OK
11:44:48.322 Access-Control-Allow-Origin: *
11:44:48.322 Cache-Control: public, max-age=600, stale-while-revalidate=60, stale-if-error=86400
11:44:48.322 Content-Type: text/xml; charset=UTF-8
11:44:48.322 Last-Modified: Tue, 11 Aug 2026 08:37:18 GMT
11:44:48.355 Server: SmartMet Server (22:40:49 Jul 14 2026)
11:44:48.355 Vary: Accept-Encoding
11:44:48.355 Accept-Ranges: bytes
11:44:48.355 Connection: close
11:44:48.355 Date: Tue, 11 Aug 2026 08:44:46 GMT
11:44:48.355 Expires: Tue, 11 Aug 2026 08:47:19 GMT
11:44:48.355 Age: 448
11:44:48.355 Content-Length: 2430
11:44:48.355
11:44:48.355 <?xml version="1.0" encoding="UTF-8"?>
11:44:48.355 <wfs:FeatureCollection
11:44:48.355 timeStamp="2026-08-11T08:37:18Z"
11:44:48.355 numberReturned="3"
11:44:48.388 numberMatched="3"
11:44:48.388 xmlns:wfs="http://www.opengis.net/wfs/2.0"
11:44:48.388 xmlns:gml="http://www.opengis.net/gml/3.2"
11:44:48.388 xmlns:BsWfs="http://xml.fmi.fi/schema/wfs/2.0"
11:44:48.388 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
11:44:48.388 xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd
11:44:48.388 http://xml.fmi.fi/schema/wfs/2.0 https://xml.fmi.fi/schema/wfs/2.0/fmi_wfs_simplefeature.xsd"
11:44:48.421 >
11:44:48.421
11:44:48.421 <wfs:member>
11:44:48.421 <BsWfs:BsWfsElement gml:id="BsWfsElement.1.1.1">
11:44:48.421 <BsWfs:Location>
11:44:48.421 <gml:Point gml:id="BsWfsElementP.1.1.1" srsDimension="2" srsName="http://www.opengis.net/def/crs/EPSG/0/4258">
11:44:48.421 <gml:pos>69.04853 27.75700 </gml:
11:44:48.454
11:44:48.454 OK
11:44:48.554
11:44:48.554 #IPRECV: 5,0,251
11:44:49.150 >AT#IPREAD=5,0
11:44:49.382
11:44:49.382 #IPREAD: 5,0,1318
11:44:49.382 pos>
11:44:49.382 </gml:Point>
11:44:49.382 </BsWfs:Location>
11:44:49.382 <BsWfs:Time>2026-08-11T08:30:00Z</BsWfs:Time>
11:44:49.382 <BsWfs:ParameterName>t2m</BsWfs:ParameterName>
11:44:49.382 <BsWfs:ParameterValue>10.8</BsWfs:ParameterValue>
11:44:49.382 </BsWfs:BsWfsElement>
11:44:49.382 </wfs:member>
11:44:49.415
11:44:49.415 <wfs:member>
11:44:49.415 <BsWfs:BsWfsElement gml:id="BsWfsElement.1.1.2">
11:44:49.415 <BsWfs:Location>
11:44:49.415 <gml:Point gml:id="BsWfsElementP.1.1.2" srsDimension="2" srsName="http://www.opengis.net/def/crs/EPSG/0/4258">
11:44:49.415 <gml:pos>69.04853 27.75700 </gml:pos>
11:44:49.415 </gml:Point>
11:44:49.415 </BsWfs:Location>
11:44:49.448 <BsWfs:Time>2026-08-11T08:30:00Z</BsWfs:Time>
11:44:49.448 <BsWfs:ParameterName>ws_10min</BsWfs:ParameterName>
11:44:49.448 <BsWfs:ParameterValue>3.0</BsWfs:ParameterValue>
11:44:49.448 </BsWfs:BsWfsElement>
11:44:49.448 </wfs:member>
11:44:49.448
11:44:49.448 <wfs:member>
11:44:49.448 <BsWfs:BsWfsElement gml:id="BsWfsElement.1.1.3">
11:44:49.448 <BsWfs:Location>
11:44:49.448 <gml:Point gml:id="BsWfsElementP.1.1.3" srsDimension="2" srsName="http://www.opengis.net/def/crs/EPSG/0/4258">
11:44:49.481 <gml:pos>69.04853 27.75700 </gml:pos>
11:44:49.481 </gml:Point>
11:44:49.481 </BsWfs:Location>
11:44:49.481 <BsWfs
11:44:49.481
11:44:49.481 OK
11:44:50.342 >AT#IPREAD=5,0
11:44:50.475
11:44:50.475 #IPREAD: 5,0,251
11:44:50.475 :Time>2026-08-11T08:30:00Z</BsWfs:Time>
11:44:50.475 <BsWfs:ParameterName>wd_10min</BsWfs:ParameterName>
11:44:50.475 <BsWfs:ParameterValue>27.0</BsWfs:ParameterValue>
11:44:50.475 </BsWfs:BsWfsElement>
11:44:50.508 </wfs:member>
11:44:50.508
11:44:50.508
11:44:50.508 </wfs:FeatureCollection>
11:44:50.508
11:44:50.508
11:44:50.508 OK
11:44:51.800
11:44:51.800 #SOCKETCLOSED: 5,0

 

HenryKAuthor
Associate II
August 19, 2026

Hello,

I wanted to update this thread in case other rookies run into similar issues. My original post contained a misconception about the network: the transition from RRC Connected to RRC Idle (+CSCON: 1 to +CSCON: 0) is actually not a problem, and the modem's internal TCP socket remains reliably open. Running the mbedTLS library directly on the host STM32U5 MCU handles the large TLS 1.2 handshakes perfectly in both directions without any socket timeout issues.

The ST87M01's native hardware TLS cannot be used here at least in HEX format, because the long HARICA RSA ROOT CA 2021 certificate generates a 2,932-byte AT command. This exceeds the input buffer and triggers serial error 1001. I didn't even bother trying to transfer it in binary format, so processing TLS on the host MCU and using the module purely as a transparent TCP pipe is the way to go, even though it is a very laborious solution.

– Henry

Didier HERROUIN
Didier HERROUINBest answer
ST Technical Moderator
August 25, 2026

Dear HenryK,

Thanks a lot for your inputs : as you said, they can be very useful for people facing the same issue.
To close the chapter about RSA, it is not only a matter of AT command size but mostly of internal supported algorithms. Indeed, as mentioned in the Application Note, RSA certificates and keys are not supported by ST87M01 .

Only EC certificates and keys can be provisioned and used.

Regards.

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question.