Skip to content

Instantly share code, notes, and snippets.

@baconcheese113
Last active July 14, 2025 17:46
Show Gist options
  • Save baconcheese113/1f0264727fce3fa51a5bb06fa031aed2 to your computer and use it in GitHub Desktop.
Save baconcheese113/1f0264727fce3fa51a5bb06fa031aed2 to your computer and use it in GitHub Desktop.
HTTPS with SIMCOM modems has been a bit of a nightmare, this should help you avoid going through that yourself

"The fear of the AT Command is the beginning of wisdom

and the knowledge of the TLS handshake is understanding."

- Proverbs 9:10

This gist should help you troubleshoot your requests, leave a comment and star if it works (or doesn't) for you and see this thread for more background.

Uploading a certificate to the modem IS NOT REQUIRED TO USE HTTPS unless you're trying to host a domain from the modem

Here's the manual

Here's the release notes

And the FTP address for finding version B08 of the firmware that I received from SIMCOM support ftp://yuxj:[email protected]

Steps for an HTTPS request with SIM7000 modem

  1. If this step doesn't work either the modem isn't powered on or there's something wrong with the connection (like baud rate)
AT
OK
  1. I use the Hologram.io network so my apn name is hologram. Your provider should have this information
AT+CNACT=1, "your apn"
OK
+APP PDP:ACTIVE
  1. If the IP here is 000.00.00.000 then you're not connected to the network. Try setting AT+CREG=2 and then AT+CREG?
AT+CNACT?
+CNACT:1, "xxx.xx.xxx.116"
OK
  1. Now we get into SSL. You need to set your clock OR ignore the server certificate time validity
AT+CCLK="22/12/25,12:00:00-12"
OK

~~~OR~~~~

AT+CSSLCFG="ignorertctime",1,1
OK
  1. Then set which SSL/TLS version to use, 3 represents TLS 1.2 and is most likely what you want. You can check your domain here
AT+CSSLCFG="sslversion",1,3
OK
  1. If you're using a backend machine that is also hosting other domains (like domain mapping through AWS/GCP/Azure/etc) then you'll run into a problem requiring Server Name Indication. You need to declare which domain cert you're looking for in this case.
AT+CSSLCFG="sni",1,"domain.com"
OK
  1. If you need to manually verify the server cert from your own list of trusted CA's then I think you'd do that here. With an empty string you trust all server certs and skip the verification
AT+SHSSL=1,""
OK
  1. Now we just configure the properties of the request body and header, as well as the root URL
AT+SHCONF="BODYLEN",1024
OK
AT+SHCONF="HEADERLEN",350
OK
AT+SHCONF="URL", "https://httpbin.org"
OK
  1. This is where the first network interaction happens. With HTTPS the TLS handshake occurs during this step. If you've configured your SSL incorrectly it'll fail on this command. Calling AT+SHCONN again before AT+SHDISC will throw an error
AT+SHCONN
OK
  1. Now for all your headers. The names can be anything, these are just key/value pairs. If you're using a bearer token this is where you'd set it up. Leaving off the headers shouldn't impact your query unless you rely on them specificly...like content-type or authorization
AT+SHCHEAD
OK
AT+SHAHEAD="Content-type","application/json"
OK
AT+SHAHEAD="User-Agent","curl/7.47.0"
OK
AT+SHAHEAD="Cache-control","no-cache"
OK
AT+SHAHEAD="Connection","keep-alive"
OK
AT+SHAHEAD="Accept","*/*"
OK
AT+SHAHEAD="authorization","Bearer eyJhbGciOiJIUzI1NiJ9ao2918391938-19189283"
OK
  1. Here you can enter the body of your request (in my case a POST). The main gotcha is that this command will fail if the character count is not correct. \" is 1 character
AT+SHBOD="{\"query\":\"query getMySensors{hubViewer{sensors{serial}}}\",\"variables\":{}}",73
OK
  1. This step will send the request and set the request method (GET/POST/PUT/...). Here is where you'd also specify which page and other query params, i.e "/posts?data=today". When +SHREQ:... is received the request has completed.
AT+SHREQ="/",3
OK
+SHREQ: "POST",200,68
  1. Finally to read the response. Note that the size to read must be <= the response size from the previous step.
AT+SHREAD=0,68
OK
+SHREAD: 68
{"data":{"hubViewer":{"sensors":[{"serial":"12:23:34:40:7B:23"}]}}}
  1. Then clean up your connection if you're done making requests to that domain. Disconnect from the network if you're done making requests. You'll get errors if you weren't connected and try to disconnect
AT+SHDISC
OK

AT+CNACT=0
OK
+APP PDP: DEACT
@Mark-Wills
Copy link

Mark-Wills commented Mar 29, 2025 via email

@JohnDoes69
Copy link

I successfully created a connection to my server, but there is something I still don't understand... my goal was to periodically send data packets to the server each ~1 min. I have the code in a loop function, but after 5 or 6 hours of looping it randomly stops and gives +CME ERROR: operation not allowed or +CME ERROR: operation failed.

I don't know what is the exact difference between the two, but they keep occurring and the only way to reset them is to reset the modem (simcom 7070G).

Does anyone know anything about it or how can it be fixed? any kind of help would be appreciated 😊

@milanbx
Copy link

milanbx commented Apr 9, 2025

I'm sorry, but I have no idea either.
Nevertheless, if I may ask, would you be so kind as to let me know your list of commands for sending the data, assuming you're using a secure HTTPS connection? I'm really eager to find out what I'm doing wrong...
Thank you.

@milanbx
Copy link

milanbx commented Apr 9, 2025

After all, I could see one way in which these errors could be different. "Operation not allowed" can be caused by a temporary disconnection from the network. Whereas "Operation failed" can be caused by a timeout due to a temporary loss of signal.

@JohnDoes69
Copy link

JohnDoes69 commented Apr 9, 2025

Well, I'm using it like this:
This only happens once, in the setup:
AT+CPIN=9589
AT+CMEE=2
AT+GSN
AT+CGNSPWR=1
AT+CGNSINF
AT+CGNSPWR=0
AT+SHCONF="URL", "put-your-domain-here" //I'm not using https since I'm hosting a server at home
AT+SHCONF="BODYLEN",1024
AT+SHCONF="HEADERLEN",350
AT+CNACT=1,1

I then use these commands in the loop:
AT+CCLK?
AT+CGNSHOT
AT+CGNSINF
AT+CGNSPWR=0
AT+SHCONN
AT+SHSTATE?
AT+SHCHEAD
AT+SHAHEAD="Accept","/"
AT+SHAHEAD="Content-Type","application/json"
AT+SHAHEAD="Connection","keep-alive"
AT+SHBOD=100,4000
AT+SHREQ="your-domain-here",3 // here you want to use the same domain as before in shconf, you only add addition parameters for posting data like http://some-domain/add-data
AT+SHDISC

the loop is happening every appx. 50-60 seconds

@gusgonnet
Copy link

Hi, I am interested as to why this is true:

Uploading a certificate to the modem IS NOT REQUIRED TO USE HTTPS unless you're trying to host a domain from the modem

Is this statement present in any docs from SIMCOM? Thanks!

@baconcheese113
Copy link
Author

@gusgonnet the HTTPS protocol allows the client to check the validity of the server certificate, so if you're just using the modem to send requests then a certificate isn't required on your client.

@jamiedumont
Copy link

@baconcheese113 Just wanted to say thank you for this gist. It included the missing piece of the puzzle that I needed to get our LTE module working. We had been going back and forth with Core M5 who were suggesting that we needed a complex firmware upgrade to make HTTPS connections (currently on B05) but that contradicted the docs I was reading.

Once I understood that we didn't need a cert (FS commands were failing too) and I saw AT+CSSLCFG="ignorertctime",1,1 it all came together! Big thank you!

@Mark-Wills
Copy link

Mark-Wills commented Jun 17, 2025 via email

@jamiedumont
Copy link

Here's a modified/redacted version of what I got working today.

--- SETUP
AT                                      
AT+CNACT?
AT+SHDISC -- first one may return OK from previous attempts
AT+SHDISC -- when this returns ERROR you're good to proceed
AT+CSSLCFG="ignorertctime",1,1
AT+CSSLCFG="sslversion",1,3
AT+CSSLCFG="sni",1,"api.example.com"
AT+SHSSL=1,""
AT+SHCONF="BODYLEN",1024
AT+SHCONF="HEADERLEN",350
AT+SHCONF="URL","https://api.example.com"
AT+SHCONN

THEN...

--- FOR GET REQUEST TO /health
AT+SHCHEAD
AT+SHREQ="/health",1

OR...

--- FOR PUT to location update
AT+SHCHEAD
AT+SHAHEAD="Content-Type","application/json"
AT+SHBOD=39,10000 -- 39 is number of characters below, 10000 is number of ms to type/paste next line in
{"latitude":10.227,"longitude":-5.5363}
AT+SHREQ="/api/location",2   -- PUT request to set location (redacted original endpoint)

Hope that helps someone get started! πŸ‘πŸΌ

@Mark-Wills
Copy link

Mark-Wills commented Jun 17, 2025 via email

@JohnDoes69
Copy link

I'm about to try the SIM7070G (CAT-M/NB IoT) as the lower power requirements are attractive.

Please let us know how it goes.

@Kaktus994
Copy link

Hello there,
Also trying to make HTTPS request (HTTP is working) but either following your or the sequence from the instructions I always get error on AT+SHCONN (all other commands OK)

Also tried one with:
AT+HTTPINIT=1
AT+HTTPSSL=1 -> Also ERROR

I am currently running the SIM7000E and the firmware is B08, do I maybe need to update to B09?
Or if you have any other suggestions they are more than welcomed.

Already lot of helpful stuff on the thread. Cheers everyone!

@Mark-Wills
Copy link

Mark-Wills commented Jul 14, 2025 via email

@Kaktus994
Copy link

Thanks, I found it, will report when I manage it to work with the steps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment