From ae470a5d61a27ec11fea588fa53a1f4f1ddac1cb Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 7 Nov 2023 10:38:21 +0100 Subject: [PATCH 1/7] Gemalto Cinterion Cellular: Disable urcs while reading --- .../GEMALTO_CINTERION_CellularStack.cpp | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp index 33a73bf9a35..fc2e8985d74 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp @@ -524,6 +524,9 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_sendto_impl(Cellul return (_at.get_last_error() == NSAPI_ERROR_OK) ? accept_len : NSAPI_ERROR_DEVICE_ERROR; } +#define DISABLE_URCs _at.at_cmd_discard("^SCFG", "=", "%s%s","Tcp/WithURCs","off") +#define RESTORE_URCs_AND_RETURN(ret) do { _at.at_cmd_discard("^SCFG", "=", "%s%s","Tcp/WithURCs","on"); return ret; } while(0) + nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address, void *buffer, nsapi_size_t size) { @@ -531,13 +534,15 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(Cell // open on the modem, assert here to catch a programming error MBED_ASSERT(socket->id != -1); + DISABLE_URCs; + // we must use this flag, otherwise ^SISR URC can come while we are reading response and there is // no way to detect if that is really an URC or response if (!socket->pending_bytes) { _at.process_oob(); // check for ^SISR URC if (!socket->pending_bytes) { tr_debug("Socket %d recv would block", socket->id); - return NSAPI_ERROR_WOULD_BLOCK; + RESTORE_URCs_AND_RETURN(NSAPI_ERROR_WOULD_BLOCK); } } @@ -552,7 +557,7 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(Cell _at.resp_start("^SISR:"); if (!_at.info_resp()) { tr_error("Socket %d not responding", socket->id); - return NSAPI_ERROR_DEVICE_ERROR; + RESTORE_URCs_AND_RETURN(NSAPI_ERROR_DEVICE_ERROR); } int socket_id = _at.read_int(); @@ -564,24 +569,24 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(Cell goto sisr_retry; } tr_error("Socket recvfrom id %d != %d", socket_id, socket->id); - return NSAPI_ERROR_DEVICE_ERROR; + RESTORE_URCs_AND_RETURN(NSAPI_ERROR_DEVICE_ERROR); } nsapi_size_or_error_t len = _at.read_int(); if (len == 0) { tr_warn("Socket %d no data", socket->id); _at.resp_stop(); - return NSAPI_ERROR_WOULD_BLOCK; + RESTORE_URCs_AND_RETURN(NSAPI_ERROR_WOULD_BLOCK); } if (len == -1) { if (GEMALTO_CINTERION::get_module() == GEMALTO_CINTERION::ModuleTX62 && _at.get_last_read_error() == -2) { _at.process_oob(); tr_error("Socket %d recvfrom finished!", socket->id); socket->pending_bytes = 0; - return NSAPI_ERROR_OK; + RESTORE_URCs_AND_RETURN(NSAPI_ERROR_OK); } tr_error("Socket %d recvfrom failed!", socket->id); - return NSAPI_ERROR_DEVICE_ERROR; + RESTORE_URCs_AND_RETURN(NSAPI_ERROR_DEVICE_ERROR); } if (len >= (nsapi_size_or_error_t)size) { len = (nsapi_size_or_error_t)size; @@ -606,7 +611,7 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(Cell int len = _at.read_bytes(at_buf + ip_len, 1); if (len <= 0) { tr_error("Socket %d recvfrom addr (len %d)", socket->id, ip_len); - return NSAPI_ERROR_DEVICE_ERROR; + RESTORE_URCs_AND_RETURN(NSAPI_ERROR_DEVICE_ERROR); } ip_len += len; } while (ip_len < ip_address_len && at_buf[ip_len - 2] != '\r' && at_buf[ip_len - 1] != '\n'); @@ -629,7 +634,7 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(Cell int ip_len = _at.read_string(ip_address, sizeof(ip_address)); if (ip_len <= 0) { tr_error("Socket %d recvfrom addr (len %d)", socket->id, ip_len); - return NSAPI_ERROR_DEVICE_ERROR; + RESTORE_URCs_AND_RETURN(NSAPI_ERROR_DEVICE_ERROR); } } @@ -671,7 +676,7 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(Cell _at.resp_stop(); - return (_at.get_last_error() == NSAPI_ERROR_OK) ? (recv_len ? recv_len : NSAPI_ERROR_WOULD_BLOCK) : NSAPI_ERROR_DEVICE_ERROR; + RESTORE_URCs_AND_RETURN((_at.get_last_error() == NSAPI_ERROR_OK) ? (recv_len ? recv_len : NSAPI_ERROR_WOULD_BLOCK) : NSAPI_ERROR_DEVICE_ERROR); } // setup internet connection profile for sockets From 8dd642cb19e16ae9169fa52f26f4b1a6abc489d8 Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 7 Nov 2023 14:10:31 +0100 Subject: [PATCH 2/7] AT_CellularContext: Fix ^SCFG commands to configure bands and URCs --- .../source/framework/AT/AT_CellularContext.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/connectivity/cellular/source/framework/AT/AT_CellularContext.cpp b/connectivity/cellular/source/framework/AT/AT_CellularContext.cpp index 087846e9b5d..e876e384c9d 100644 --- a/connectivity/cellular/source/framework/AT/AT_CellularContext.cpp +++ b/connectivity/cellular/source/framework/AT/AT_CellularContext.cpp @@ -452,26 +452,21 @@ void AT_CellularContext::enable_access_technology() { case CATM1: _at.at_cmd_discard("^SXRAT", "=","%d", _rat); - _at.cmd_start_stop("^SCFG", "=","%s%s", "Radio/Band/CatM",buffer); - _at.resp_start("^SCFG"); - _at.cmd_start_stop("^SCFG", "=","%s%d%d", "Radio/Band/CatNB",0,0); - _at.resp_start("^SCFG"); + _at.at_cmd_discard("^SCFG", "=","%s%s", "Radio/Band/CatM",buffer); + _at.at_cmd_discard("^SCFG", "=","%s%d%d", "Radio/Band/CatNB",0,0); break; case CATNB: _at.at_cmd_discard("^SXRAT", "=","%d", _rat); - _at.cmd_start_stop("^SCFG", "=","%s%s", "Radio/Band/CatNB",buffer); - _at.resp_start("^SCFG"); - _at.cmd_start_stop("^SCFG", "=","%s%d%d", "Radio/Band/CatM",0,0); - _at.resp_start("^SCFG"); + _at.at_cmd_discard("^SCFG", "=","%s%s", "Radio/Band/CatNB",buffer); + _at.at_cmd_discard("^SCFG", "=","%s%d%d", "Radio/Band/CatM",0,0); break; default: break; } - _at.cmd_start_stop("^SCFG", "=", "%s%s", "Tcp/withURCs", "on"); - _at.resp_start("^SCFG"); + _at.at_cmd_discard("^SCFG", "=", "%s%s", "Tcp/withURCs", "on"); free(buffer); } From 822f1b2b855afd1f332dc3c8e490c1f7b08923b5 Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 10 Nov 2023 10:30:12 +0100 Subject: [PATCH 3/7] AT_CellularContext: move enable_access_technology() at commands into GEMALTO_CINTERION_CellularContext --- .../framework/AT/AT_CellularContext.h | 4 +-- .../framework/AT/AT_CellularContext.cpp | 25 +---------------- .../GEMALTO_CINTERION_CellularContext.cpp | 28 +++++++++++++++++++ .../GEMALTO_CINTERION_CellularContext.h | 1 + 4 files changed, 32 insertions(+), 26 deletions(-) diff --git a/connectivity/cellular/include/cellular/framework/AT/AT_CellularContext.h b/connectivity/cellular/include/cellular/framework/AT/AT_CellularContext.h index eb3bf5afdd1..2f68f1f97bc 100644 --- a/connectivity/cellular/include/cellular/framework/AT/AT_CellularContext.h +++ b/connectivity/cellular/include/cellular/framework/AT/AT_CellularContext.h @@ -135,8 +135,6 @@ class AT_CellularContext : public CellularContext { PinName _dcd_pin; bool _active_high; - RadioAccessTechnologyType _rat; - FrequencyBand _band; protected: char _found_apn[MAX_APN_LENGTH]; @@ -144,6 +142,8 @@ class AT_CellularContext : public CellularContext { bool _cp_req; bool _is_connected; ATHandler &_at; + RadioAccessTechnologyType _rat; + FrequencyBand _band; }; } // namespace mbed diff --git a/connectivity/cellular/source/framework/AT/AT_CellularContext.cpp b/connectivity/cellular/source/framework/AT/AT_CellularContext.cpp index e876e384c9d..c05fc386e05 100644 --- a/connectivity/cellular/source/framework/AT/AT_CellularContext.cpp +++ b/connectivity/cellular/source/framework/AT/AT_CellularContext.cpp @@ -445,30 +445,7 @@ bool AT_CellularContext::set_new_context(int cid) void AT_CellularContext::enable_access_technology() { - char *buffer = new char [8]; - memset(buffer, 0, 8); - sprintf(buffer,"%08X", _band); - switch (_rat) - { - case CATM1: - _at.at_cmd_discard("^SXRAT", "=","%d", _rat); - _at.at_cmd_discard("^SCFG", "=","%s%s", "Radio/Band/CatM",buffer); - _at.at_cmd_discard("^SCFG", "=","%s%d%d", "Radio/Band/CatNB",0,0); - break; - - case CATNB: - _at.at_cmd_discard("^SXRAT", "=","%d", _rat); - _at.at_cmd_discard("^SCFG", "=","%s%s", "Radio/Band/CatNB",buffer); - _at.at_cmd_discard("^SCFG", "=","%s%d%d", "Radio/Band/CatM",0,0); - break; - - default: - break; - } - - _at.at_cmd_discard("^SCFG", "=", "%s%s", "Tcp/withURCs", "on"); - free(buffer); - + enable_access_technology(); } nsapi_error_t AT_CellularContext::do_activate_context() diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp index 7ee2c8e53c7..bc2b1d514c7 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp @@ -148,4 +148,32 @@ NetworkStack *GEMALTO_CINTERION_CellularContext::get_stack() } #endif // NSAPI_PPP_AVAILABLE +void GEMALTO_CINTERION_CellularContext::enable_access_technology() +{ + char *buffer = new char [8]; + memset(buffer, 0, 8); + sprintf(buffer,"%08X", _band); + switch (_rat) + { + case CATM1: + _at.at_cmd_discard("^SXRAT", "=","%d", _rat); + _at.at_cmd_discard("^SCFG", "=","%s%s", "Radio/Band/CatM",buffer); + _at.at_cmd_discard("^SCFG", "=","%s%d%d", "Radio/Band/CatNB",0,0); + break; + + case CATNB: + _at.at_cmd_discard("^SXRAT", "=","%d", _rat); + _at.at_cmd_discard("^SCFG", "=","%s%s", "Radio/Band/CatNB",buffer); + _at.at_cmd_discard("^SCFG", "=","%s%d%d", "Radio/Band/CatM",0,0); + break; + + default: + break; + } + + _at.at_cmd_discard("^SCFG", "=", "%s%s", "Tcp/withURCs", "on"); + free(buffer); + +} + } /* namespace mbed */ diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.h b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.h index 0645b2b87ce..cd9aef02221 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.h +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.h @@ -34,6 +34,7 @@ class GEMALTO_CINTERION_CellularContext: public AT_CellularContext { virtual NetworkStack *get_stack(); #endif // NSAPI_PPP_AVAILABLE virtual nsapi_error_t do_user_authentication(); + virtual void enable_access_technology(); }; } /* namespace mbed */ From 915ad28bd3e9d369128691e8558c4626bc65fb82 Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 10 Nov 2023 10:30:54 +0100 Subject: [PATCH 4/7] GEMALTO_CINTERION_CellularContext: do not disable all bands * Switching rat AT command fails and should not be necessary to disable bands since we do not use a fallback rat --- .../GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp index bc2b1d514c7..bf7522621b8 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp @@ -158,13 +158,11 @@ void GEMALTO_CINTERION_CellularContext::enable_access_technology() case CATM1: _at.at_cmd_discard("^SXRAT", "=","%d", _rat); _at.at_cmd_discard("^SCFG", "=","%s%s", "Radio/Band/CatM",buffer); - _at.at_cmd_discard("^SCFG", "=","%s%d%d", "Radio/Band/CatNB",0,0); break; case CATNB: _at.at_cmd_discard("^SXRAT", "=","%d", _rat); _at.at_cmd_discard("^SCFG", "=","%s%s", "Radio/Band/CatNB",buffer); - _at.at_cmd_discard("^SCFG", "=","%s%d%d", "Radio/Band/CatM",0,0); break; default: From 64e0c1f45702e5e2d11a667176c12582c3a36bdf Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 10 Nov 2023 10:58:37 +0100 Subject: [PATCH 5/7] GEMALTO_CINTERION_CellularContext: add return value to enable_access_technology() --- .../framework/AT/AT_CellularContext.h | 2 +- .../framework/AT/AT_CellularContext.cpp | 4 +-- .../GEMALTO_CINTERION_CellularContext.cpp | 25 +++++++++++-------- .../GEMALTO_CINTERION_CellularContext.h | 2 +- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/connectivity/cellular/include/cellular/framework/AT/AT_CellularContext.h b/connectivity/cellular/include/cellular/framework/AT/AT_CellularContext.h index 2f68f1f97bc..6291bb11d70 100644 --- a/connectivity/cellular/include/cellular/framework/AT/AT_CellularContext.h +++ b/connectivity/cellular/include/cellular/framework/AT/AT_CellularContext.h @@ -109,7 +109,7 @@ class AT_CellularContext : public CellularContext { * @return NIDD context text, e.g. Non-IP or NONIP */ virtual const char *get_nonip_context_type_str(); - virtual void enable_access_technology(); + virtual nsapi_error_t enable_access_technology(); virtual void set_cid(int cid); private: diff --git a/connectivity/cellular/source/framework/AT/AT_CellularContext.cpp b/connectivity/cellular/source/framework/AT/AT_CellularContext.cpp index c05fc386e05..f5e69aac80b 100644 --- a/connectivity/cellular/source/framework/AT/AT_CellularContext.cpp +++ b/connectivity/cellular/source/framework/AT/AT_CellularContext.cpp @@ -443,9 +443,9 @@ bool AT_CellularContext::set_new_context(int cid) return success; } -void AT_CellularContext::enable_access_technology() +nsapi_error_t AT_CellularContext::enable_access_technology() { - enable_access_technology(); + return enable_access_technology(); } nsapi_error_t AT_CellularContext::do_activate_context() diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp index bf7522621b8..bbd5c4c4b5e 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp @@ -148,30 +148,35 @@ NetworkStack *GEMALTO_CINTERION_CellularContext::get_stack() } #endif // NSAPI_PPP_AVAILABLE -void GEMALTO_CINTERION_CellularContext::enable_access_technology() +nsapi_error_t GEMALTO_CINTERION_CellularContext::enable_access_technology() { - char *buffer = new char [8]; - memset(buffer, 0, 8); - sprintf(buffer,"%08X", _band); + nsapi_error_t error = NSAPI_ERROR_OK; + char buffer[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; + + snprintf(buffer, 9, "%08X", _band); switch (_rat) { case CATM1: - _at.at_cmd_discard("^SXRAT", "=","%d", _rat); - _at.at_cmd_discard("^SCFG", "=","%s%s", "Radio/Band/CatM",buffer); + error = _at.at_cmd_discard("^SCFG", "=","%s%s", "Radio/Band/CatM", buffer); break; case CATNB: - _at.at_cmd_discard("^SXRAT", "=","%d", _rat); - _at.at_cmd_discard("^SCFG", "=","%s%s", "Radio/Band/CatNB",buffer); + error = _at.at_cmd_discard("^SCFG", "=","%s%s", "Radio/Band/CatNB", buffer); break; default: break; } + if (error != NSAPI_ERROR_OK) { + return error; + } - _at.at_cmd_discard("^SCFG", "=", "%s%s", "Tcp/withURCs", "on"); - free(buffer); + error = _at.at_cmd_discard("^SXRAT", "=","%d", _rat); + if (error != NSAPI_ERROR_OK) { + return error; + } + return _at.at_cmd_discard("^SCFG", "=", "%s%s", "Tcp/withURCs", "on"); } } /* namespace mbed */ diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.h b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.h index cd9aef02221..24ff87bc084 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.h +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.h @@ -34,7 +34,7 @@ class GEMALTO_CINTERION_CellularContext: public AT_CellularContext { virtual NetworkStack *get_stack(); #endif // NSAPI_PPP_AVAILABLE virtual nsapi_error_t do_user_authentication(); - virtual void enable_access_technology(); + virtual nsapi_error_t enable_access_technology(); }; } /* namespace mbed */ From b5d44a4f3be3938045c185d5f1753cbade22a6f9 Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 10 Nov 2023 17:06:53 +0100 Subject: [PATCH 6/7] GEMALTO_CINTERION_CellularContext::connect check return codes and print errors --- .../GEMALTO_CINTERION_CellularContext.cpp | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp index bbd5c4c4b5e..0af08a786d7 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp @@ -33,22 +33,41 @@ GEMALTO_CINTERION_CellularContext::~GEMALTO_CINTERION_CellularContext() nsapi_error_t GEMALTO_CINTERION_CellularContext::connect(const char *sim_pin, const char *apn, const char *uname, const char *pwd) { + nsapi_error_t error = NSAPI_ERROR_OK; + set_sim_pin(sim_pin); set_credentials(apn, uname, pwd); - set_device_ready(); + error = set_device_ready(); + if ((error != NSAPI_ERROR_OK) && (error != NSAPI_ERROR_ALREADY)) { + tr_error("Failure connecting to GEMALTO CINTERION modem"); + return error; + } _at.lock(); bool valid_context = get_context(); _at.unlock(); - if(!valid_context) { - set_new_context(_cid); + if (!valid_context) { + valid_context = set_new_context(_cid); + } + + if (!valid_context) { + tr_error("Invalid AT cellular context %d", _cid); + return NSAPI_ERROR_DEVICE_ERROR; } - do_user_authentication(); + error = do_user_authentication(); + if (error != NSAPI_ERROR_OK) { + tr_error("Failure during user authentication"); + return error; + } - enable_access_technology(); + error = enable_access_technology(); + if (error != NSAPI_ERROR_OK) { + tr_error("Failure enabling access technology"); + return error; + } return AT_CellularContext::connect(); } From e69150d098a78a9f4d10f5f993dee29602cd076a Mon Sep 17 00:00:00 2001 From: pennam Date: Mon, 13 Nov 2023 16:22:14 +0100 Subject: [PATCH 7/7] TLSSocketWrapper: allow appending ca_cert to an empty chain --- connectivity/netsocket/source/TLSSocketWrapper.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/connectivity/netsocket/source/TLSSocketWrapper.cpp b/connectivity/netsocket/source/TLSSocketWrapper.cpp index 6665f64cc0b..1fb9c217694 100644 --- a/connectivity/netsocket/source/TLSSocketWrapper.cpp +++ b/connectivity/netsocket/source/TLSSocketWrapper.cpp @@ -145,10 +145,11 @@ nsapi_error_t TLSSocketWrapper::append_root_ca_cert(const void *root_ca, size_t crt = get_ca_chain(); if (!crt) { - return NSAPI_ERROR_NO_MEMORY; + /* In no chain is configured create a new one */ + return set_root_ca_cert(root_ca, len); } - /* Parse CA certification */ + /* Append root_ca to the crt chain */ int ret; if ((ret = mbedtls_x509_crt_parse(crt, static_cast(root_ca), len)) != 0) {