mirror of https://github.com/ARMmbed/mbed-os.git
mbed-mesh-api: Add new Wi-SUN certificate API
Add new API for setting Wi-SUN: -Setting own/trusted certificates -Removing own/trusted certificatespull/11181/head
parent
c0f3cb7568
commit
774162dd83
|
|
@ -50,7 +50,7 @@ public:
|
|||
* \return MESH_ERROR_NONE on success.
|
||||
* \return MESH_ERROR_UNKNOWN in case of failure.
|
||||
* */
|
||||
mesh_error_t network_name_set(char *network_name);
|
||||
mesh_error_t set_network_name(char *network_name);
|
||||
|
||||
/**
|
||||
* \brief Set Wi-SUN network regulatory domain, operating class and operating mode.
|
||||
|
|
@ -61,13 +61,68 @@ public:
|
|||
*
|
||||
* Function overwrites parameters defined by Mbed OS configuration.
|
||||
*
|
||||
* \param regulatory_domain Values defined in Wi-SUN PHY-specification
|
||||
* \param operating_class Values defined in Wi-SUN PHY-specification
|
||||
* \param operating_mode Values defined in Wi-SUN PHY-specification
|
||||
* \param regulatory_domain Values defined in Wi-SUN PHY-specification. Use 0xff to use leave parameter unchanged.
|
||||
* \param operating_class Values defined in Wi-SUN PHY-specification. Use 0xff to use leave parameter unchanged.
|
||||
* \param operating_mode Values defined in Wi-SUN PHY-specification. Use 0xff to use leave parameter unchanged.
|
||||
* \return MESH_ERROR_NONE on success.
|
||||
* \return MESH_ERROR_UNKNOWN in case of failure.
|
||||
* */
|
||||
mesh_error_t network_regulatory_domain_set(uint8_t regulatory_domain = 0xff, uint8_t operating_class = 0xff, uint8_t operating_mode = 0xff);
|
||||
mesh_error_t set_network_regulatory_domain(uint8_t regulatory_domain = 0xff, uint8_t operating_class = 0xff, uint8_t operating_mode = 0xff);
|
||||
|
||||
/**
|
||||
* \brief Set own certificate and private key reference to the Wi-SUN network.
|
||||
*
|
||||
* Function can be called several times if intermediate certificates are used. Then each call to the function
|
||||
* adds a certificate reference to own certificate chain. Certificates are in bottom up order i.e. the top certificate is given last.
|
||||
*
|
||||
* Function must be called before connecting the device i.e before first call to connect() method.
|
||||
* Function will not copy certificate or key, therefore addresses must remain valid.
|
||||
*
|
||||
* \param cert Certificate address.
|
||||
* \param cert_len Certificate length in bytes.
|
||||
* \param cert_key Certificate key address.
|
||||
* \param cert_key_len Certificate key length in bytes.
|
||||
* \return MESH_ERROR_NONE on success.
|
||||
* \return MESH_ERROR_STATE if method is called after calling connect().
|
||||
* \return MESH_ERROR_MEMORY in case of memory allocation failure.
|
||||
* */
|
||||
mesh_error_t set_own_certificate(uint8_t *cert, uint16_t cert_len, uint8_t *cert_key = NULL, uint16_t cert_key_len = 0);
|
||||
|
||||
/**
|
||||
* \brief Remove own certificates from the Wi-SUN network.
|
||||
*
|
||||
* Function must be called before connecting the device i.e before first call to connect() method.
|
||||
*
|
||||
* \return MESH_ERROR_NONE on success.
|
||||
* \return MESH_ERROR_STATE if method is called after calling connect().
|
||||
* */
|
||||
mesh_error_t remove_own_certificates(void);
|
||||
|
||||
/**
|
||||
* \brief Set trusted certificate reference to the Wi-SUN network.
|
||||
*
|
||||
* Function can be called several times. Certificates are in bottom up order i.e. the top certificate is given last.
|
||||
*
|
||||
* Function must be called before connecting the device i.e before first call to connect() method.
|
||||
* Function will not copy certificate, therefore addresses must remain valid.
|
||||
*
|
||||
* \param cert Certificate address.
|
||||
* \param cert_len Certificate length in bytes.
|
||||
* \return MESH_ERROR_NONE on success.
|
||||
* \return MESH_ERROR_STATE if method is called after calling connect().
|
||||
* \return MESH_ERROR_MEMORY in case of memory allocation failure.
|
||||
* */
|
||||
mesh_error_t set_trusted_certificate(uint8_t *cert, uint16_t cert_len);
|
||||
|
||||
/**
|
||||
* \brief Remove trusted certificates from the Wi-SUN network.
|
||||
*
|
||||
* Function must be called before connecting the device i.e before first call to connect() method.
|
||||
*
|
||||
* \return MESH_ERROR_NONE on success.
|
||||
* \return MESH_ERROR_STATE if method is called after calling connect().
|
||||
* */
|
||||
mesh_error_t remove_trusted_certificates(void);
|
||||
|
||||
/**
|
||||
* \brief Get router IP address
|
||||
|
|
|
|||
|
|
@ -171,11 +171,11 @@ bool WisunInterface::getRouterIpAddress(char *address, int8_t len)
|
|||
return _interface->get_gateway(address, len);
|
||||
}
|
||||
|
||||
mesh_error_t WisunInterface::network_name_set(char *network_name)
|
||||
mesh_error_t WisunInterface::set_network_name(char *network_name)
|
||||
{
|
||||
mesh_error_t ret_val = MESH_ERROR_NONE;
|
||||
|
||||
int status = wisun_tasklet_network_name_set(get_interface_id(), network_name);
|
||||
int status = wisun_tasklet_set_network_name(get_interface_id(), network_name);
|
||||
if (status != 0) {
|
||||
ret_val = MESH_ERROR_UNKNOWN;
|
||||
}
|
||||
|
|
@ -183,11 +183,11 @@ mesh_error_t WisunInterface::network_name_set(char *network_name)
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
mesh_error_t WisunInterface::network_regulatory_domain_set(uint8_t regulatory_domain, uint8_t operating_class, uint8_t operating_mode)
|
||||
mesh_error_t WisunInterface::set_network_regulatory_domain(uint8_t regulatory_domain, uint8_t operating_class, uint8_t operating_mode)
|
||||
{
|
||||
mesh_error_t ret_val = MESH_ERROR_NONE;
|
||||
|
||||
int status = wisun_tasklet_regulatory_domain_set(get_interface_id(), regulatory_domain, operating_class, operating_mode);
|
||||
int status = wisun_tasklet_set_regulatory_domain(get_interface_id(), regulatory_domain, operating_class, operating_mode);
|
||||
if (status != 0) {
|
||||
ret_val = MESH_ERROR_UNKNOWN;
|
||||
}
|
||||
|
|
@ -195,6 +195,58 @@ mesh_error_t WisunInterface::network_regulatory_domain_set(uint8_t regulatory_do
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
mesh_error_t WisunInterface::set_own_certificate(uint8_t *cert, uint16_t cert_len, uint8_t *cert_key, uint16_t cert_key_len)
|
||||
{
|
||||
mesh_error_t ret_val = MESH_ERROR_NONE;
|
||||
int status = wisun_tasklet_set_own_certificate(cert, cert_len, cert_key, cert_key_len);
|
||||
if (status == -1) {
|
||||
ret_val = MESH_ERROR_MEMORY;
|
||||
} else if (status == -2) {
|
||||
ret_val = MESH_ERROR_STATE;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
mesh_error_t WisunInterface::remove_own_certificates(void)
|
||||
{
|
||||
mesh_error_t ret_val = MESH_ERROR_NONE;
|
||||
int status = wisun_tasklet_remove_own_certificates();
|
||||
if (status == -1) {
|
||||
ret_val = MESH_ERROR_MEMORY;
|
||||
} else if (status == -2) {
|
||||
ret_val = MESH_ERROR_STATE;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
mesh_error_t WisunInterface::set_trusted_certificate(uint8_t *cert, uint16_t cert_len)
|
||||
{
|
||||
mesh_error_t ret_val = MESH_ERROR_NONE;
|
||||
int status = wisun_tasklet_set_trusted_certificate(cert, cert_len);
|
||||
if (status == -1) {
|
||||
ret_val = MESH_ERROR_MEMORY;
|
||||
} else if (status == -2) {
|
||||
ret_val = MESH_ERROR_STATE;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
mesh_error_t WisunInterface::remove_trusted_certificates(void)
|
||||
{
|
||||
mesh_error_t ret_val = MESH_ERROR_NONE;
|
||||
int status = wisun_tasklet_remove_trusted_certificates();
|
||||
if (status == -1) {
|
||||
ret_val = MESH_ERROR_MEMORY;
|
||||
} else if (status == -2) {
|
||||
ret_val = MESH_ERROR_STATE;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
#define WISUN 0x2345
|
||||
#if MBED_CONF_NSAPI_DEFAULT_MESH_TYPE == WISUN && DEVICE_802_15_4_PHY
|
||||
MBED_WEAK MeshInterface *MeshInterface::get_target_default_instance()
|
||||
|
|
|
|||
|
|
@ -64,6 +64,9 @@ void wisun_tasklet_init(void);
|
|||
*
|
||||
* \param device_id registered physical device
|
||||
* \return interface ID that can be used to communication with this interface
|
||||
* \return -1 in case of MAC initialization fails
|
||||
* \return -2 in case of error in parameters
|
||||
* \return -3 in case of memory allocation error
|
||||
*/
|
||||
int8_t wisun_tasklet_network_init(int8_t device_id);
|
||||
|
||||
|
|
@ -84,7 +87,7 @@ int8_t wisun_tasklet_disconnect(bool send_cb);
|
|||
* \return 0 if network name stored successfully
|
||||
* \return < 0 in case of errors
|
||||
*/
|
||||
int wisun_tasklet_network_name_set(int8_t nwk_interface_id, char *network_name_ptr);
|
||||
int wisun_tasklet_set_network_name(int8_t nwk_interface_id, char *network_name_ptr);
|
||||
|
||||
/*
|
||||
* \brief Set Wi-SUN network regulatory domain
|
||||
|
|
@ -96,7 +99,45 @@ int wisun_tasklet_network_name_set(int8_t nwk_interface_id, char *network_name_p
|
|||
* \return 0 if regulatory domain is set successfully.
|
||||
* \return < 0 in case of errors
|
||||
*/
|
||||
int wisun_tasklet_regulatory_domain_set(int8_t nwk_interface_id, uint8_t regulatory_domain, uint8_t operating_class, uint8_t operating_mode);
|
||||
int wisun_tasklet_set_regulatory_domain(int8_t nwk_interface_id, uint8_t regulatory_domain, uint8_t operating_class, uint8_t operating_mode);
|
||||
|
||||
/*
|
||||
* \brief Set own certificate to Wi-SUN network
|
||||
*
|
||||
* \param cert to use for networking
|
||||
* \param cert_len
|
||||
* \param cert_key
|
||||
* \param cert_key_len
|
||||
* \return 0 if certificate stored successfully
|
||||
* \return < 0 in case of errors
|
||||
*/
|
||||
int wisun_tasklet_set_own_certificate(uint8_t *cert, uint16_t cert_len, uint8_t *cert_key, uint16_t cert_key_len);
|
||||
|
||||
/*
|
||||
* \brief Remove own certificate from Wi-SUN network
|
||||
*
|
||||
* \return 0 if certificates removed successfully
|
||||
* \return < 0 in case of errors
|
||||
*/
|
||||
int wisun_tasklet_remove_own_certificates(void);
|
||||
|
||||
/*
|
||||
* \brief Set trusted certificate to Wi-SUN network
|
||||
*
|
||||
* \param cert to use for networking
|
||||
* \param cert_len
|
||||
* \return 0 if certificate stored successfully
|
||||
* \return < 0 in case of errors
|
||||
*/
|
||||
int wisun_tasklet_set_trusted_certificate(uint8_t *cert, uint16_t cert_len);
|
||||
|
||||
/*
|
||||
* \brief Remove trusted certificate from Wi-SUN network
|
||||
*
|
||||
* \return 0 if certificates removed successfully
|
||||
* \return < 0 in case of errors
|
||||
*/
|
||||
int wisun_tasklet_remove_trusted_certificates(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#include "multicast_api.h"
|
||||
#include "mac_api.h"
|
||||
#include "sw_mac.h"
|
||||
#include "ns_list.h"
|
||||
#include "net_interface.h"
|
||||
#include "ws_management_api.h" //ws_management_node_init
|
||||
#ifdef MBED_CONF_MBED_MESH_API_CERTIFICATE_HEADER
|
||||
#if !defined(MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE) || !defined(MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE) || \
|
||||
|
|
@ -75,10 +77,24 @@ typedef struct {
|
|||
uint8_t rd_operating_mode;
|
||||
} wisun_network_settings_t;
|
||||
|
||||
typedef struct {
|
||||
arm_certificate_entry_s arm_cert_entry;
|
||||
ns_list_link_t link; /*!< List link entry */
|
||||
} wisun_certificate_entry_t;
|
||||
|
||||
typedef NS_LIST_HEAD(wisun_certificate_entry_t, link) cert_list_t;
|
||||
typedef struct {
|
||||
cert_list_t own_certificates_list;
|
||||
cert_list_t trusted_certificates_list;
|
||||
bool remove_own_certificates: 1;
|
||||
bool remove_trusted_certificates: 1;
|
||||
} wisun_certificates_t;
|
||||
|
||||
#define WS_NA 0xff // Not applicable value
|
||||
|
||||
/* Tasklet data */
|
||||
static wisun_tasklet_data_str_t *wisun_tasklet_data_ptr = NULL;
|
||||
static wisun_certificates_t *wisun_certificates_ptr = NULL;
|
||||
static wisun_network_settings_t wisun_settings_str = {NULL, WS_NA, WS_NA, WS_NA};
|
||||
static mac_api_t *mac_api = NULL;
|
||||
|
||||
|
|
@ -89,6 +105,9 @@ static void wisun_tasklet_main(arm_event_s *event);
|
|||
static void wisun_tasklet_network_state_changed(mesh_connection_status_t status);
|
||||
static void wisun_tasklet_parse_network_event(arm_event_s *event);
|
||||
static void wisun_tasklet_configure_and_connect_to_network(void);
|
||||
static void wisun_tasklet_clear_stored_certificates(void) ;
|
||||
static int wisun_tasklet_store_certificate_data(const uint8_t *cert, uint16_t cert_len, const uint8_t *cert_key, uint16_t cert_key_len, bool remove_own, bool remove_trusted, bool trusted_cert);
|
||||
static int wisun_tasklet_add_stored_certificates(void) ;
|
||||
|
||||
/*
|
||||
* \brief A function which will be eventually called by NanoStack OS when ever the OS has an event to deliver.
|
||||
|
|
@ -221,6 +240,11 @@ static void wisun_tasklet_configure_and_connect_to_network(void)
|
|||
wisun_tasklet_data_ptr->operating_mode,
|
||||
wisun_tasklet_data_ptr->operating_mode_extension);
|
||||
|
||||
if (wisun_tasklet_add_stored_certificates() != 0) {
|
||||
tr_error("Can't set Wi-SUN certificates");
|
||||
return;
|
||||
}
|
||||
|
||||
status = ws_management_node_init(wisun_tasklet_data_ptr->network_interface_id,
|
||||
MBED_CONF_MBED_MESH_API_WISUN_REGULATORY_DOMAIN,
|
||||
wisun_settings_str.network_name,
|
||||
|
|
@ -278,6 +302,118 @@ static void wisun_tasklet_network_state_changed(mesh_connection_status_t status)
|
|||
}
|
||||
}
|
||||
|
||||
static int wisun_tasklet_store_certificate_data(const uint8_t *cert, uint16_t cert_len, const uint8_t *cert_key, uint16_t cert_key_len, bool remove_own, bool remove_trusted, bool trusted_cert)
|
||||
{
|
||||
if (wisun_certificates_ptr == NULL) {
|
||||
wisun_certificates_ptr = (wisun_certificates_t *)ns_dyn_mem_alloc(sizeof(wisun_certificates_t));
|
||||
if (!wisun_certificates_ptr) {
|
||||
return -1;
|
||||
}
|
||||
ns_list_init(&wisun_certificates_ptr->own_certificates_list);
|
||||
ns_list_init(&wisun_certificates_ptr->trusted_certificates_list);
|
||||
wisun_certificates_ptr->remove_own_certificates = false;
|
||||
wisun_certificates_ptr->remove_trusted_certificates = false;
|
||||
}
|
||||
|
||||
if (remove_own) {
|
||||
wisun_certificates_ptr->remove_own_certificates = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (remove_trusted) {
|
||||
wisun_certificates_ptr->remove_trusted_certificates = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
wisun_certificate_entry_t *ws_cert_entry_store = (wisun_certificate_entry_t *)ns_dyn_mem_alloc(sizeof(wisun_certificate_entry_t));
|
||||
if (!ws_cert_entry_store) {
|
||||
wisun_tasklet_clear_stored_certificates();
|
||||
return -1;
|
||||
}
|
||||
|
||||
ws_cert_entry_store->arm_cert_entry.cert = cert;
|
||||
ws_cert_entry_store->arm_cert_entry.cert_len = cert_len;
|
||||
|
||||
if (cert_key) {
|
||||
ws_cert_entry_store->arm_cert_entry.key = cert_key;
|
||||
ws_cert_entry_store->arm_cert_entry.key_len = cert_key_len;
|
||||
} else {
|
||||
ws_cert_entry_store->arm_cert_entry.key = NULL;
|
||||
ws_cert_entry_store->arm_cert_entry.key_len = 0;
|
||||
}
|
||||
|
||||
if (trusted_cert) {
|
||||
ns_list_add_to_end(&wisun_certificates_ptr->trusted_certificates_list, ws_cert_entry_store);
|
||||
} else {
|
||||
ns_list_add_to_end(&wisun_certificates_ptr->own_certificates_list, ws_cert_entry_store);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wisun_tasklet_clear_stored_certificates(void)
|
||||
{
|
||||
if (!wisun_certificates_ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
ns_list_foreach_safe(wisun_certificate_entry_t, trusted_cert_entry, &wisun_certificates_ptr->trusted_certificates_list) {
|
||||
ns_list_remove(&wisun_certificates_ptr->trusted_certificates_list, trusted_cert_entry);
|
||||
ns_dyn_mem_free(trusted_cert_entry);
|
||||
}
|
||||
|
||||
ns_list_foreach_safe(wisun_certificate_entry_t, own_cert_entry, &wisun_certificates_ptr->own_certificates_list) {
|
||||
ns_list_remove(&wisun_certificates_ptr->own_certificates_list, own_cert_entry);
|
||||
ns_dyn_mem_free(own_cert_entry);
|
||||
}
|
||||
|
||||
ns_dyn_mem_free(wisun_certificates_ptr);
|
||||
wisun_certificates_ptr = NULL;
|
||||
}
|
||||
|
||||
static int wisun_tasklet_add_stored_certificates(void)
|
||||
{
|
||||
int8_t status = 0;
|
||||
|
||||
if (wisun_certificates_ptr == NULL) {
|
||||
// certificates not updated
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (wisun_certificates_ptr->remove_own_certificates) {
|
||||
status = arm_network_own_certificates_remove();
|
||||
if (status != 0) {
|
||||
goto CERTIFICATE_SET_END;
|
||||
}
|
||||
}
|
||||
|
||||
if (wisun_certificates_ptr->remove_trusted_certificates) {
|
||||
status = arm_network_trusted_certificates_remove();
|
||||
if (status != 0) {
|
||||
goto CERTIFICATE_SET_END;
|
||||
}
|
||||
}
|
||||
|
||||
ns_list_foreach(wisun_certificate_entry_t, cert_entry, &wisun_certificates_ptr->trusted_certificates_list) {
|
||||
status = arm_network_trusted_certificate_add(&cert_entry->arm_cert_entry);
|
||||
if (status != 0) {
|
||||
goto CERTIFICATE_SET_END;
|
||||
}
|
||||
}
|
||||
|
||||
ns_list_foreach(wisun_certificate_entry_t, cert_entry, &wisun_certificates_ptr->own_certificates_list) {
|
||||
status = arm_network_own_certificate_add(&cert_entry->arm_cert_entry);
|
||||
if (status != 0) {
|
||||
goto CERTIFICATE_SET_END;
|
||||
}
|
||||
}
|
||||
|
||||
CERTIFICATE_SET_END:
|
||||
wisun_tasklet_clear_stored_certificates();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Public functions */
|
||||
int8_t wisun_tasklet_get_router_ip_address(char *address, int8_t len)
|
||||
{
|
||||
|
|
@ -378,7 +514,7 @@ int8_t wisun_tasklet_network_init(int8_t device_id)
|
|||
return arm_nwk_interface_lowpan_init(mac_api, INTERFACE_NAME);
|
||||
}
|
||||
|
||||
int wisun_tasklet_network_name_set(int8_t nwk_interface_id, char *network_name_ptr)
|
||||
int wisun_tasklet_set_network_name(int8_t nwk_interface_id, char *network_name_ptr)
|
||||
{
|
||||
if (!network_name_ptr || strlen(network_name_ptr) > 32) {
|
||||
return -1;
|
||||
|
|
@ -401,7 +537,7 @@ int wisun_tasklet_network_name_set(int8_t nwk_interface_id, char *network_name_p
|
|||
return 0;
|
||||
}
|
||||
|
||||
int wisun_tasklet_regulatory_domain_set(int8_t nwk_interface_id, uint8_t regulatory_domain, uint8_t operating_class, uint8_t operating_mode)
|
||||
int wisun_tasklet_set_regulatory_domain(int8_t nwk_interface_id, uint8_t regulatory_domain, uint8_t operating_class, uint8_t operating_mode)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
|
|
@ -415,3 +551,46 @@ int wisun_tasklet_regulatory_domain_set(int8_t nwk_interface_id, uint8_t regulat
|
|||
|
||||
return status;
|
||||
}
|
||||
|
||||
int wisun_tasklet_set_own_certificate(uint8_t *cert, uint16_t cert_len, uint8_t *cert_key, uint16_t cert_key_len)
|
||||
{
|
||||
if (wisun_tasklet_data_ptr) {
|
||||
// this API can be only used before first connect()
|
||||
tr_err("Already connected");
|
||||
return -2;
|
||||
}
|
||||
|
||||
return wisun_tasklet_store_certificate_data(cert, cert_len, cert_key, cert_key_len, false, false, false);
|
||||
}
|
||||
|
||||
int wisun_tasklet_remove_own_certificates(void)
|
||||
{
|
||||
if (wisun_tasklet_data_ptr) {
|
||||
// this API can be only used before first connect()
|
||||
tr_err("Already connected");
|
||||
return -2;
|
||||
}
|
||||
|
||||
return wisun_tasklet_store_certificate_data(NULL, 0, NULL, 0, true, false, false);
|
||||
}
|
||||
|
||||
int wisun_tasklet_remove_trusted_certificates(void)
|
||||
{
|
||||
if (wisun_tasklet_data_ptr) {
|
||||
// this API can be only used before first connect()
|
||||
tr_err("Already connected");
|
||||
return -2;
|
||||
}
|
||||
|
||||
return wisun_tasklet_store_certificate_data(NULL, 0, NULL, 0, false, true, false);
|
||||
}
|
||||
|
||||
int wisun_tasklet_set_trusted_certificate(uint8_t *cert, uint16_t cert_len)
|
||||
{
|
||||
if (wisun_tasklet_data_ptr) {
|
||||
// this API can be only used before first connect()
|
||||
tr_err("Already connected");
|
||||
return -2;
|
||||
}
|
||||
return wisun_tasklet_store_certificate_data(cert, cert_len, NULL, 0, false, false, true);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue