Merge branch 'feature/provisioning_backport_api_changes' into 'release/v3.2'
(backport v3.2) Provisioning Framework API changes See merge request idf/esp-idf!4249
This commit is contained in:
commit
332ccd0925
30 changed files with 589 additions and 263 deletions
|
@ -17,6 +17,10 @@
|
|||
#include <protocomm_security.h>
|
||||
#include <esp_err.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Function prototype for protocomm endpoint handler
|
||||
*/
|
||||
|
@ -42,7 +46,7 @@ typedef struct protocomm protocomm_t;
|
|||
* @brief Create a new protocomm instance
|
||||
*
|
||||
* This API will return a new dynamically allocated protocomm instance
|
||||
* with all elements of the protocomm_t structure initialised to NULL.
|
||||
* with all elements of the protocomm_t structure initialized to NULL.
|
||||
*
|
||||
* @return
|
||||
* - protocomm_t* : On success
|
||||
|
@ -71,7 +75,8 @@ void protocomm_delete(protocomm_t *pc);
|
|||
* - An endpoint must be bound to a valid protocomm instance,
|
||||
* created using `protocomm_new()`.
|
||||
* - This function internally calls the registered `add_endpoint()`
|
||||
* function which is a member of the protocomm_t instance structure.
|
||||
* function of the selected transport which is a member of the
|
||||
* protocomm_t instance structure.
|
||||
*
|
||||
* @param[in] pc Pointer to the protocomm instance
|
||||
* @param[in] ep_name Endpoint identifier(name) string
|
||||
|
@ -81,7 +86,7 @@ void protocomm_delete(protocomm_t *pc);
|
|||
* Pass NULL if not needed.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Added new endpoint succesfully
|
||||
* - ESP_OK : Success
|
||||
* - ESP_FAIL : Error adding endpoint / Endpoint with this name already exists
|
||||
* - ESP_ERR_NO_MEM : Error allocating endpoint resource
|
||||
* - ESP_ERR_INVALID_ARG : Null instance/name/handler arguments
|
||||
|
@ -103,7 +108,7 @@ esp_err_t protocomm_add_endpoint(protocomm_t *pc, const char *ep_name,
|
|||
* @param[in] ep_name Endpoint identifier(name) string
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Added new endpoint succesfully
|
||||
* - ESP_OK : Success
|
||||
* - ESP_ERR_NOT_FOUND : Endpoint with specified name doesn't exist
|
||||
* - ESP_ERR_INVALID_ARG : Null instance/name arguments
|
||||
*/
|
||||
|
@ -111,12 +116,12 @@ esp_err_t protocomm_remove_endpoint(protocomm_t *pc, const char *ep_name);
|
|||
|
||||
/**
|
||||
* @brief Calls the registered handler of an endpoint session
|
||||
* for processing incoming data and giving the output
|
||||
* for processing incoming data and generating the response
|
||||
*
|
||||
* @note
|
||||
* - An endpoint must be bound to a valid protocomm instance,
|
||||
* created using `protocomm_new()`.
|
||||
* - Resulting output buffer must be deallocated by the user.
|
||||
* - Resulting output buffer must be deallocated by the caller.
|
||||
*
|
||||
* @param[in] pc Pointer to the protocomm instance
|
||||
* @param[in] ep_name Endpoint identifier(name) string
|
||||
|
@ -130,7 +135,7 @@ esp_err_t protocomm_remove_endpoint(protocomm_t *pc, const char *ep_name);
|
|||
* @param[out] outlen Buffer length of the allocated output buffer
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Request handled succesfully
|
||||
* - ESP_OK : Request handled successfully
|
||||
* - ESP_FAIL : Internal error in execution of registered handler
|
||||
* - ESP_ERR_NO_MEM : Error allocating internal resource
|
||||
* - ESP_ERR_NOT_FOUND : Endpoint with specified name doesn't exist
|
||||
|
@ -159,7 +164,7 @@ esp_err_t protocomm_req_handle(protocomm_t *pc, const char *ep_name, uint32_t se
|
|||
* @param[in] pop Pointer to proof of possession for authenticating a client
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Added new security endpoint succesfully
|
||||
* - ESP_OK : Success
|
||||
* - ESP_FAIL : Error adding endpoint / Endpoint with this name already exists
|
||||
* - ESP_ERR_INVALID_STATE : Security endpoint already set
|
||||
* - ESP_ERR_NO_MEM : Error allocating endpoint resource
|
||||
|
@ -179,7 +184,7 @@ esp_err_t protocomm_set_security(protocomm_t *pc, const char *ep_name,
|
|||
* @param[in] ep_name Endpoint identifier(name) string
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Added new endpoint succesfully
|
||||
* - ESP_OK : Success
|
||||
* - ESP_ERR_NOT_FOUND : Endpoint with specified name doesn't exist
|
||||
* - ESP_ERR_INVALID_ARG : Null instance/name arguments
|
||||
*/
|
||||
|
@ -189,7 +194,7 @@ esp_err_t protocomm_unset_security(protocomm_t *pc, const char *ep_name);
|
|||
* @brief Set endpoint for version verification
|
||||
*
|
||||
* This API can be used for setting an application specific protocol
|
||||
* version which can be verfied by clients through the endpoint.
|
||||
* version which can be verified by clients through the endpoint.
|
||||
*
|
||||
* @note
|
||||
* - An endpoint must be bound to a valid protocomm instance,
|
||||
|
@ -200,7 +205,7 @@ esp_err_t protocomm_unset_security(protocomm_t *pc, const char *ep_name);
|
|||
* @param[in] version Version identifier(name) string
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Added new security endpoint succesfully
|
||||
* - ESP_OK : Success
|
||||
* - ESP_FAIL : Error adding endpoint / Endpoint with this name already exists
|
||||
* - ESP_ERR_INVALID_STATE : Version endpoint already set
|
||||
* - ESP_ERR_NO_MEM : Error allocating endpoint resource
|
||||
|
@ -219,8 +224,12 @@ esp_err_t protocomm_set_version(protocomm_t *pc, const char *ep_name,
|
|||
* @param[in] ep_name Endpoint identifier(name) string
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Added new endpoint succesfully
|
||||
* - ESP_OK : Success
|
||||
* - ESP_ERR_NOT_FOUND : Endpoint with specified name doesn't exist
|
||||
* - ESP_ERR_INVALID_ARG : Null instance/name arguments
|
||||
*/
|
||||
esp_err_t protocomm_unset_version(protocomm_t *pc, const char *ep_name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
|
||||
#include <esp_err.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Proof Of Possession for authenticating a secure session
|
||||
*/
|
||||
|
@ -42,12 +46,12 @@ typedef struct protocomm_security_pop {
|
|||
*/
|
||||
typedef struct protocomm_security {
|
||||
/**
|
||||
* Unique version number of security implmentation
|
||||
* Unique version number of security implementation
|
||||
*/
|
||||
int ver;
|
||||
|
||||
/**
|
||||
* Function for initialising/allocating security
|
||||
* Function for initializing/allocating security
|
||||
* infrastructure
|
||||
*/
|
||||
esp_err_t (*init)();
|
||||
|
@ -91,3 +95,7 @@ typedef struct protocomm_security {
|
|||
const uint8_t *inbuf, ssize_t inlen,
|
||||
uint8_t *outbuf, ssize_t *outlen);
|
||||
} protocomm_security_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
|
||||
#include <protocomm_security.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Protocomm security version 0 implementation
|
||||
*
|
||||
|
@ -23,3 +27,7 @@
|
|||
* security is required for the protocomm instance
|
||||
*/
|
||||
extern const protocomm_security_t protocomm_security0;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -16,10 +16,18 @@
|
|||
|
||||
#include <protocomm_security.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Protocomm security version 1 implementation
|
||||
*
|
||||
* This is a full fledged security implmentation using
|
||||
* This is a full fledged security implementation using
|
||||
* Curve25519 key exchange and AES-256-CTR encryption
|
||||
*/
|
||||
extern const protocomm_security_t protocomm_security1;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
|
||||
#include <protocomm.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* BLE device name cannot be larger than this value
|
||||
*/
|
||||
|
@ -30,7 +34,7 @@ typedef struct name_uuid {
|
|||
/**
|
||||
* Name of the handler, which is passed to protocomm layer
|
||||
*/
|
||||
char *name;
|
||||
const char *name;
|
||||
|
||||
/**
|
||||
* UUID to be assigned to the BLE characteristic which is
|
||||
|
@ -63,10 +67,10 @@ typedef struct {
|
|||
* the initialization for characteristics/service for BLE.
|
||||
*
|
||||
* @param[in] pc Protocomm instance pointer obtained from protocomm_new()
|
||||
* @param[in] config Pointer to config structure for initialising BLE
|
||||
* @param[in] config Pointer to config structure for initializing BLE
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : if successful
|
||||
* - ESP_OK : Success
|
||||
* - ESP_FAIL : Simple BLE start error
|
||||
* - ESP_ERR_NO_MEM : Error allocating memory for internal resources
|
||||
* - ESP_ERR_INVALID_STATE : Error in ble config
|
||||
|
@ -85,8 +89,12 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con
|
|||
* @param[in] pc Same protocomm instance that was passed to protocomm_ble_start()
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : For success or appropriate error code
|
||||
* - ESP_OK : Success
|
||||
* - ESP_FAIL : Simple BLE stop error
|
||||
* - ESP_ERR_INVALID_ARG : Null / incorrect protocomm instance
|
||||
*/
|
||||
esp_err_t protocomm_ble_stop(protocomm_t *pc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
|
||||
#include <protocomm.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PROTOCOMM_CONSOLE_DEFAULT_CONFIG() { \
|
||||
.stack_size = 4096, \
|
||||
.task_priority = tskIDLE_PRIORITY + 3, \
|
||||
|
@ -25,7 +29,7 @@
|
|||
* @brief Config parameters for protocomm console
|
||||
*/
|
||||
typedef struct {
|
||||
size_t stack_size; /*!< Stack size of console taks */
|
||||
size_t stack_size; /*!< Stack size of console task */
|
||||
unsigned task_priority; /*!< Priority of console task */
|
||||
} protocomm_console_config_t;
|
||||
|
||||
|
@ -39,7 +43,7 @@ typedef struct {
|
|||
* @param[in] config Config param structure for protocomm console
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Server started succefully
|
||||
* - ESP_OK : Success
|
||||
* - ESP_ERR_INVALID_ARG : Null arguments
|
||||
* - ESP_ERR_NOT_SUPPORTED : Transport layer bound to another protocomm instance
|
||||
* - ESP_ERR_INVALID_STATE : Transport layer already bound to this protocomm instance
|
||||
|
@ -53,7 +57,11 @@ esp_err_t protocomm_console_start(protocomm_t *pc, const protocomm_console_confi
|
|||
* @param[in] pc Same protocomm instance that was passed to protocomm_console_start()
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Server stopped succefully
|
||||
* - ESP_OK : Success
|
||||
* - ESP_ERR_INVALID_ARG : Null / incorrect protocomm instance pointer
|
||||
*/
|
||||
esp_err_t protocomm_console_stop(protocomm_t *pc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -22,11 +22,16 @@
|
|||
.task_priority = tskIDLE_PRIORITY + 5, \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Config parameters for protocomm HTTP server
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t port; /*!< Port on which the http server will listen */
|
||||
|
||||
uint16_t port; /*!< Port on which the HTTP server will listen */
|
||||
|
||||
/**
|
||||
* Stack size of server task, adjusted depending
|
||||
|
@ -34,6 +39,31 @@ typedef struct {
|
|||
*/
|
||||
size_t stack_size;
|
||||
unsigned task_priority; /*!< Priority of server task */
|
||||
} protocomm_http_server_config_t; /*!< HTTP Server Configuration, if HTTP Server has not been started already */
|
||||
|
||||
/** Protocomm HTTPD Configuration Data
|
||||
*/
|
||||
typedef union {
|
||||
/** HTTP Server Handle, if ext_handle_provided is set to true
|
||||
*/
|
||||
void *handle;
|
||||
|
||||
/** HTTP Server Configuration, if a server is not already active
|
||||
*/
|
||||
protocomm_http_server_config_t config;
|
||||
} protocomm_httpd_config_data_t;
|
||||
|
||||
/**
|
||||
* @brief Config parameters for protocomm HTTP server
|
||||
*/
|
||||
typedef struct {
|
||||
/** Flag to indicate of an external HTTP Server Handle has been provided.
|
||||
* In such as case, protocomm will use the same HTTP Server and not start
|
||||
* a new one internally.
|
||||
*/
|
||||
bool ext_handle_provided;
|
||||
/** Protocomm HTTPD Configuration Data */
|
||||
protocomm_httpd_config_data_t data;
|
||||
} protocomm_httpd_config_t;
|
||||
|
||||
/**
|
||||
|
@ -46,10 +76,10 @@ typedef struct {
|
|||
* one instance can be bound to an HTTP transport layer.
|
||||
*
|
||||
* @param[in] pc Protocomm instance pointer obtained from protocomm_new()
|
||||
* @param[in] config Pointer to config structure for initialising HTTP server
|
||||
* @param[in] config Pointer to config structure for initializing HTTP server
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Server started succefully
|
||||
* - ESP_OK : Success
|
||||
* - ESP_ERR_INVALID_ARG : Null arguments
|
||||
* - ESP_ERR_NOT_SUPPORTED : Transport layer bound to another protocomm instance
|
||||
* - ESP_ERR_INVALID_STATE : Transport layer already bound to this protocomm instance
|
||||
|
@ -67,7 +97,11 @@ esp_err_t protocomm_httpd_start(protocomm_t *pc, const protocomm_httpd_config_t
|
|||
* @param[in] pc Same protocomm instance that was passed to protocomm_httpd_start()
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Server stopped succefully
|
||||
* - ESP_OK : Success
|
||||
* - ESP_ERR_INVALID_ARG : Null / incorrect protocomm instance pointer
|
||||
*/
|
||||
esp_err_t protocomm_httpd_stop(protocomm_t *pc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -52,6 +52,19 @@ void protocomm_delete(protocomm_t *pc)
|
|||
free(it);
|
||||
}
|
||||
|
||||
/* Free memory allocated to version string */
|
||||
if (pc->ver) {
|
||||
free((void *)pc->ver);
|
||||
}
|
||||
|
||||
/* Free memory allocated to security */
|
||||
if (pc->sec && pc->sec->cleanup) {
|
||||
pc->sec->cleanup();
|
||||
}
|
||||
if (pc->pop) {
|
||||
free(pc->pop);
|
||||
}
|
||||
|
||||
free(pc);
|
||||
}
|
||||
|
||||
|
@ -140,11 +153,14 @@ esp_err_t protocomm_req_handle(protocomm_t *pc, const char *ep_name, uint32_t se
|
|||
const uint8_t *inbuf, ssize_t inlen,
|
||||
uint8_t **outbuf, ssize_t *outlen)
|
||||
{
|
||||
if ((pc == NULL) || (ep_name == NULL)) {
|
||||
if (!pc || !ep_name || !outbuf || !outlen) {
|
||||
ESP_LOGE(TAG, "Invalid params %p %p", pc, ep_name);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*outbuf = NULL;
|
||||
*outlen = 0;
|
||||
|
||||
protocomm_ep_t *ep = search_endpoint(pc, ep_name);
|
||||
if (!ep) {
|
||||
ESP_LOGE(TAG, "No registered endpoint for %s", ep_name);
|
||||
|
@ -166,19 +182,23 @@ esp_err_t protocomm_req_handle(protocomm_t *pc, const char *ep_name, uint32_t se
|
|||
}
|
||||
|
||||
ssize_t dec_inbuf_len = inlen;
|
||||
pc->sec->decrypt(session_id, inbuf, inlen, dec_inbuf, &dec_inbuf_len);
|
||||
ret = pc->sec->decrypt(session_id, inbuf, inlen, dec_inbuf, &dec_inbuf_len);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Decryption of response failed for endpoint %s", ep_name);
|
||||
free(dec_inbuf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Invoke the request handler */
|
||||
uint8_t *plaintext_resp;
|
||||
ssize_t plaintext_resp_len;
|
||||
uint8_t *plaintext_resp = NULL;
|
||||
ssize_t plaintext_resp_len = 0;
|
||||
ret = ep->req_handler(session_id,
|
||||
dec_inbuf, dec_inbuf_len,
|
||||
&plaintext_resp, &plaintext_resp_len,
|
||||
ep->priv_data);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Request handler for %s failed", ep_name);
|
||||
*outbuf = NULL;
|
||||
*outlen = 0;
|
||||
free(plaintext_resp);
|
||||
free(dec_inbuf);
|
||||
return ret;
|
||||
}
|
||||
|
@ -189,12 +209,20 @@ esp_err_t protocomm_req_handle(protocomm_t *pc, const char *ep_name, uint32_t se
|
|||
uint8_t *enc_resp = (uint8_t *) malloc(plaintext_resp_len);
|
||||
if (!enc_resp) {
|
||||
ESP_LOGE(TAG, "Failed to allocate decrypt buf len %d", inlen);
|
||||
free(plaintext_resp);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
ssize_t enc_resp_len = plaintext_resp_len;
|
||||
pc->sec->encrypt(session_id, plaintext_resp, plaintext_resp_len,
|
||||
enc_resp, &enc_resp_len);
|
||||
ret = pc->sec->encrypt(session_id, plaintext_resp, plaintext_resp_len,
|
||||
enc_resp, &enc_resp_len);
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Encryption of response failed for endpoint %s", ep_name);
|
||||
free(enc_resp);
|
||||
free(plaintext_resp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* We no more need plaintext response */
|
||||
free(plaintext_resp);
|
||||
|
@ -257,7 +285,7 @@ esp_err_t protocomm_set_security(protocomm_t *pc, const char *ep_name,
|
|||
if (sec->init) {
|
||||
ret = sec->init();
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error initialising security");
|
||||
ESP_LOGE(TAG, "Error initializing security");
|
||||
protocomm_remove_endpoint(pc, ep_name);
|
||||
return ret;
|
||||
}
|
||||
|
@ -305,40 +333,22 @@ static int protocomm_version_handler(uint32_t session_id,
|
|||
uint8_t **outbuf, ssize_t *outlen,
|
||||
void *priv_data)
|
||||
{
|
||||
const char *resp_match = "SUCCESS";
|
||||
const char *resp_fail = "FAIL";
|
||||
bool match = false;
|
||||
char *version = strndup((const char *)inbuf, inlen);
|
||||
protocomm_t *pc = (protocomm_t *) priv_data;
|
||||
*outbuf = NULL;
|
||||
*outlen = 0;
|
||||
|
||||
if ((pc->ver != NULL) && (version != NULL)) {
|
||||
ESP_LOGV(TAG, "Protocol version of device : %s", pc->ver);
|
||||
ESP_LOGV(TAG, "Protocol version of client : %s", version);
|
||||
if (strcmp(pc->ver, version) == 0) {
|
||||
match = true;
|
||||
}
|
||||
} else if ((pc->ver == NULL) && (version == NULL)) {
|
||||
match = true;
|
||||
if (!pc->ver) {
|
||||
*outlen = 0;
|
||||
*outbuf = NULL;
|
||||
return ESP_OK;
|
||||
}
|
||||
free(version);
|
||||
|
||||
if (!match) {
|
||||
ESP_LOGE(TAG, "Protocol version mismatch");
|
||||
}
|
||||
|
||||
const char *result_msg = match ? resp_match : resp_fail;
|
||||
|
||||
/* Output is a non null terminated string with length specified */
|
||||
*outlen = strlen(result_msg);
|
||||
*outbuf = malloc(strlen(result_msg));
|
||||
*outlen = strlen(pc->ver);
|
||||
*outbuf = malloc(*outlen);
|
||||
if (outbuf == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to allocate memory for version check response");
|
||||
ESP_LOGE(TAG, "Failed to allocate memory for version response");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
memcpy(*outbuf, result_msg, *outlen);
|
||||
memcpy(*outbuf, pc->ver, *outlen);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ struct protocomm {
|
|||
int (*remove_endpoint)(const char *ep_name);
|
||||
|
||||
/* Pointer to security layer instance to be used internally for
|
||||
* establising secure sessions */
|
||||
* establishing secure sessions */
|
||||
const protocomm_security_t *sec;
|
||||
|
||||
/* Pointer to proof of possession object */
|
||||
|
|
|
@ -36,6 +36,8 @@ static esp_err_t sec0_session_setup(uint32_t session_id,
|
|||
S0SessionResp *s0resp = (S0SessionResp *) malloc(sizeof(S0SessionResp));
|
||||
if (!out || !s0resp) {
|
||||
ESP_LOGE(TAG, "Error allocating response");
|
||||
free(out);
|
||||
free(s0resp);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
sec0_payload__init(out);
|
||||
|
@ -79,6 +81,7 @@ static esp_err_t sec0_req_handler(const protocomm_security_pop_t *pop, uint32_t
|
|||
}
|
||||
if (req->sec_ver != protocomm_security0.ver) {
|
||||
ESP_LOGE(TAG, "Security version mismatch. Closing connection");
|
||||
session_data__free_unpacked(req, NULL);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
|
@ -86,12 +89,12 @@ static esp_err_t sec0_req_handler(const protocomm_security_pop_t *pop, uint32_t
|
|||
ret = sec0_session_setup(session_id, req, &resp, pop);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Session setup error %d", ret);
|
||||
session_data__free_unpacked(req, NULL);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
session_data__free_unpacked(req, NULL);
|
||||
|
||||
resp.sec_ver = req->sec_ver;
|
||||
session_data__free_unpacked(req, NULL);
|
||||
|
||||
*outlen = session_data__get_packed_size(&resp);
|
||||
*outbuf = (uint8_t *) malloc(*outlen);
|
||||
|
|
|
@ -38,8 +38,9 @@ static const char* TAG = "security1";
|
|||
#define PUBLIC_KEY_LEN 32
|
||||
#define SZ_RANDOM 16
|
||||
|
||||
#define SESSION_STATE_1 1 /* Session in state 1 */
|
||||
#define SESSION_STATE_SETUP 2 /* Session setup successful */
|
||||
#define SESSION_STATE_CMD0 0 /* Session is not setup */
|
||||
#define SESSION_STATE_CMD1 1 /* Session is not setup */
|
||||
#define SESSION_STATE_DONE 2 /* Session setup successful */
|
||||
|
||||
typedef struct session {
|
||||
/* Session data */
|
||||
|
@ -82,22 +83,12 @@ static esp_err_t handle_session_command1(uint32_t session_id,
|
|||
uint8_t check_buf[PUBLIC_KEY_LEN];
|
||||
int mbed_err;
|
||||
|
||||
if (!cur_session) {
|
||||
ESP_LOGE(TAG, "Data on session endpoint without session establishment");
|
||||
if (cur_session->state != SESSION_STATE_CMD1) {
|
||||
ESP_LOGE(TAG, "Invalid state of session %d (expected %d)", SESSION_STATE_CMD1, cur_session->state);
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (session_id != cur_session->id) {
|
||||
ESP_LOGE(TAG, "Invalid session");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (!in) {
|
||||
ESP_LOGE(TAG, "Empty session data");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Initialise crypto context */
|
||||
/* Initialize crypto context */
|
||||
mbedtls_aes_init(&cur_session->ctx_aes);
|
||||
memset(cur_session->stb, 0, sizeof(cur_session->stb));
|
||||
cur_session->nc_off = 0;
|
||||
|
@ -109,6 +100,7 @@ static esp_err_t handle_session_command1(uint32_t session_id,
|
|||
sizeof(cur_session->sym_key)*8);
|
||||
if (mbed_err != 0) {
|
||||
ESP_LOGE(TAG, "Failure at mbedtls_aes_setkey_enc with error code : -0x%x", -mbed_err);
|
||||
mbedtls_aes_free(&cur_session->ctx_aes);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
|
@ -118,6 +110,7 @@ static esp_err_t handle_session_command1(uint32_t session_id,
|
|||
in->sc1->client_verify_data.data, check_buf);
|
||||
if (mbed_err != 0) {
|
||||
ESP_LOGE(TAG, "Failure at mbedtls_aes_crypt_ctr with error code : -0x%x", -mbed_err);
|
||||
mbedtls_aes_free(&cur_session->ctx_aes);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
|
@ -127,19 +120,30 @@ static esp_err_t handle_session_command1(uint32_t session_id,
|
|||
if (mbedtls_ssl_safer_memcmp(check_buf, cur_session->device_pubkey,
|
||||
sizeof(cur_session->device_pubkey)) != 0) {
|
||||
ESP_LOGE(TAG, "Key mismatch. Close connection");
|
||||
mbedtls_aes_free(&cur_session->ctx_aes);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
Sec1Payload *out = (Sec1Payload *) malloc(sizeof(Sec1Payload));
|
||||
sec1_payload__init(out);
|
||||
SessionResp1 *out_resp = (SessionResp1 *) malloc(sizeof(SessionResp1));
|
||||
session_resp1__init(out_resp);
|
||||
if (!out || !out_resp) {
|
||||
ESP_LOGE(TAG, "Error allocating memory for response1");
|
||||
free(out);
|
||||
free(out_resp);
|
||||
mbedtls_aes_free(&cur_session->ctx_aes);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
sec1_payload__init(out);
|
||||
session_resp1__init(out_resp);
|
||||
out_resp->status = STATUS__Success;
|
||||
|
||||
uint8_t *outbuf = (uint8_t *) malloc(PUBLIC_KEY_LEN);
|
||||
if (!outbuf) {
|
||||
ESP_LOGE(TAG, "Error allocating ciphertext buffer");
|
||||
free(out);
|
||||
free(out_resp);
|
||||
mbedtls_aes_free(&cur_session->ctx_aes);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
|
@ -149,6 +153,10 @@ static esp_err_t handle_session_command1(uint32_t session_id,
|
|||
cur_session->client_pubkey, outbuf);
|
||||
if (mbed_err != 0) {
|
||||
ESP_LOGE(TAG, "Failure at mbedtls_aes_crypt_ctr with error code : -0x%x", -mbed_err);
|
||||
free(outbuf);
|
||||
free(out);
|
||||
free(out_resp);
|
||||
mbedtls_aes_free(&cur_session->ctx_aes);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
|
@ -163,8 +171,8 @@ static esp_err_t handle_session_command1(uint32_t session_id,
|
|||
resp->proto_case = SESSION_DATA__PROTO_SEC1;
|
||||
resp->sec1 = out;
|
||||
|
||||
ESP_LOGD(TAG, "Session successful");
|
||||
|
||||
cur_session->state = SESSION_STATE_DONE;
|
||||
ESP_LOGD(TAG, "Secure session established successfully");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
@ -172,32 +180,21 @@ static esp_err_t handle_session_command0(uint32_t session_id,
|
|||
SessionData *req, SessionData *resp,
|
||||
const protocomm_security_pop_t *pop)
|
||||
{
|
||||
ESP_LOGD(TAG, "Request to handle setup0_command");
|
||||
Sec1Payload *in = (Sec1Payload *) req->sec1;
|
||||
esp_err_t ret;
|
||||
int mbed_err;
|
||||
|
||||
if (!cur_session) {
|
||||
ESP_LOGE(TAG, "Data on session endpoint without session establishment");
|
||||
if (cur_session->state != SESSION_STATE_CMD0) {
|
||||
ESP_LOGE(TAG, "Invalid state of session %d (expected %d)", SESSION_STATE_CMD0, cur_session->state);
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (session_id != cur_session->id) {
|
||||
ESP_LOGE(TAG, "Invalid session");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (!in) {
|
||||
ESP_LOGE(TAG, "Empty session data");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (in->sc0->client_pubkey.len != PUBLIC_KEY_LEN) {
|
||||
ESP_LOGE(TAG, "Invalid public key length");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
cur_session->state = SESSION_STATE_1;
|
||||
|
||||
mbedtls_ecdh_context *ctx_server = malloc(sizeof(mbedtls_ecdh_context));
|
||||
mbedtls_entropy_context *entropy = malloc(sizeof(mbedtls_entropy_context));
|
||||
mbedtls_ctr_drbg_context *ctr_drbg = malloc(sizeof(mbedtls_ctr_drbg_context));
|
||||
|
@ -315,8 +312,10 @@ static esp_err_t handle_session_command0(uint32_t session_id,
|
|||
Sec1Payload *out = (Sec1Payload *) malloc(sizeof(Sec1Payload));
|
||||
SessionResp0 *out_resp = (SessionResp0 *) malloc(sizeof(SessionResp0));
|
||||
if (!out || !out_resp) {
|
||||
ESP_LOGE(TAG, "Error allocating memory for response");
|
||||
ret = ESP_FAIL;
|
||||
ESP_LOGE(TAG, "Error allocating memory for response0");
|
||||
ret = ESP_ERR_NO_MEM;
|
||||
free(out);
|
||||
free(out_resp);
|
||||
goto exit_cmd0;
|
||||
}
|
||||
|
||||
|
@ -338,6 +337,8 @@ static esp_err_t handle_session_command0(uint32_t session_id,
|
|||
resp->proto_case = SESSION_DATA__PROTO_SEC1;
|
||||
resp->sec1 = out;
|
||||
|
||||
cur_session->state = SESSION_STATE_CMD1;
|
||||
|
||||
ESP_LOGD(TAG, "Session setup phase1 done");
|
||||
ret = ESP_OK;
|
||||
|
||||
|
@ -361,6 +362,21 @@ static esp_err_t sec1_session_setup(uint32_t session_id,
|
|||
Sec1Payload *in = (Sec1Payload *) req->sec1;
|
||||
esp_err_t ret;
|
||||
|
||||
if (!cur_session) {
|
||||
ESP_LOGE(TAG, "Invalid session context data");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (session_id != cur_session->id) {
|
||||
ESP_LOGE(TAG, "Invalid session ID : %d (expected %d)", session_id, cur_session->id);
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (!in) {
|
||||
ESP_LOGE(TAG, "Empty session data");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
switch (in->msg) {
|
||||
case SEC1_MSG_TYPE__Session_Command0:
|
||||
ret = handle_session_command0(session_id, req, resp, pop);
|
||||
|
@ -411,30 +427,30 @@ static void sec1_session_setup_cleanup(uint32_t session_id, SessionData *resp)
|
|||
return;
|
||||
}
|
||||
|
||||
static esp_err_t sec1_init()
|
||||
static esp_err_t sec1_close_session(uint32_t session_id)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t sec1_cleanup()
|
||||
{
|
||||
if (cur_session) {
|
||||
ESP_LOGD(TAG, "Closing current session with id %u", cur_session->id);
|
||||
mbedtls_aes_free(&cur_session->ctx_aes);
|
||||
bzero(cur_session, sizeof(session_t));
|
||||
free(cur_session);
|
||||
cur_session = NULL;
|
||||
if (!cur_session || cur_session->id != session_id) {
|
||||
ESP_LOGE(TAG, "Attempt to close invalid session");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (cur_session->state == SESSION_STATE_DONE) {
|
||||
/* Free AES context data */
|
||||
mbedtls_aes_free(&cur_session->ctx_aes);
|
||||
}
|
||||
|
||||
bzero(cur_session, sizeof(session_t));
|
||||
free(cur_session);
|
||||
cur_session = NULL;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t sec1_new_session(uint32_t session_id)
|
||||
{
|
||||
if (cur_session && cur_session->id != session_id) {
|
||||
if (cur_session) {
|
||||
/* Only one session is allowed at a time */
|
||||
ESP_LOGE(TAG, "Closing old session with id %u", cur_session->id);
|
||||
sec1_cleanup();
|
||||
} else if (cur_session && cur_session->id == session_id) {
|
||||
return ESP_OK;
|
||||
sec1_close_session(cur_session->id);
|
||||
}
|
||||
|
||||
cur_session = (session_t *) calloc(1, sizeof(session_t));
|
||||
|
@ -447,16 +463,17 @@ static esp_err_t sec1_new_session(uint32_t session_id)
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t sec1_close_session(uint32_t session_id)
|
||||
static esp_err_t sec1_init()
|
||||
{
|
||||
if (!cur_session || cur_session->id != session_id) {
|
||||
ESP_LOGE(TAG, "Attempt to close invalid session");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
bzero(cur_session, sizeof(session_t));
|
||||
free(cur_session);
|
||||
cur_session = NULL;
|
||||
static esp_err_t sec1_cleanup()
|
||||
{
|
||||
if (cur_session) {
|
||||
ESP_LOGD(TAG, "Closing current session with id %u", cur_session->id);
|
||||
sec1_close_session(cur_session->id);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
@ -469,8 +486,15 @@ static esp_err_t sec1_decrypt(uint32_t session_id,
|
|||
}
|
||||
|
||||
if (!cur_session || cur_session->id != session_id) {
|
||||
ESP_LOGE(TAG, "Session with ID %d not found", session_id);
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (cur_session->state != SESSION_STATE_DONE) {
|
||||
ESP_LOGE(TAG, "Secure session not established");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
*outlen = inlen;
|
||||
int ret = mbedtls_aes_crypt_ctr(&cur_session->ctx_aes, inlen, &cur_session->nc_off,
|
||||
cur_session->rand, cur_session->stb, inbuf, outbuf);
|
||||
|
@ -497,6 +521,7 @@ static esp_err_t sec1_req_handler(const protocomm_security_pop_t *pop, uint32_t
|
|||
}
|
||||
if (req->sec_ver != protocomm_security1.ver) {
|
||||
ESP_LOGE(TAG, "Security version mismatch. Closing connection");
|
||||
session_data__free_unpacked(req, NULL);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
|
@ -504,12 +529,12 @@ static esp_err_t sec1_req_handler(const protocomm_security_pop_t *pop, uint32_t
|
|||
ret = sec1_session_setup(session_id, req, &resp, pop);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Session setup error %d", ret);
|
||||
session_data__free_unpacked(req, NULL);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
session_data__free_unpacked(req, NULL);
|
||||
|
||||
resp.sec_ver = req->sec_ver;
|
||||
session_data__free_unpacked(req, NULL);
|
||||
|
||||
*outlen = session_data__get_packed_size(&resp);
|
||||
*outbuf = (uint8_t *) malloc(*outlen);
|
||||
|
|
|
@ -103,7 +103,7 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_
|
|||
g_ble_cfg_p->exec_write_fn(event, gatts_if, param);
|
||||
break;
|
||||
case ESP_GATTS_MTU_EVT:
|
||||
ESP_LOGV(TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu);
|
||||
ESP_LOGD(TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu);
|
||||
if (g_ble_cfg_p->set_mtu_fn) {
|
||||
g_ble_cfg_p->set_mtu_fn(event, gatts_if, param);
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ typedef struct {
|
|||
} simple_ble_cfg_t;
|
||||
|
||||
|
||||
/** Initialise a simple ble connection
|
||||
/** Initialize a simple ble connection
|
||||
*
|
||||
* This function allocates memory and returns a pointer to the
|
||||
* configuration structure.
|
||||
|
|
|
@ -276,7 +276,7 @@ static void transport_simple_ble_exec_write(esp_gatts_cb_event_t event, esp_gatt
|
|||
static void transport_simple_ble_disconnect(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
|
||||
{
|
||||
esp_err_t ret;
|
||||
ESP_LOGV(TAG, "Inside disconnect w/ session - %d", param->disconnect.conn_id);
|
||||
ESP_LOGD(TAG, "Inside disconnect w/ session - %d", param->disconnect.conn_id);
|
||||
if (protoble_internal->pc_ble->sec &&
|
||||
protoble_internal->pc_ble->sec->close_transport_session) {
|
||||
ret = protoble_internal->pc_ble->sec->close_transport_session(param->disconnect.conn_id);
|
||||
|
@ -290,7 +290,7 @@ static void transport_simple_ble_disconnect(esp_gatts_cb_event_t event, esp_gatt
|
|||
static void transport_simple_ble_connect(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
|
||||
{
|
||||
esp_err_t ret;
|
||||
ESP_LOGV(TAG, "Inside BLE connect w/ conn_id - %d", param->connect.conn_id);
|
||||
ESP_LOGD(TAG, "Inside BLE connect w/ conn_id - %d", param->connect.conn_id);
|
||||
if (protoble_internal->pc_ble->sec &&
|
||||
protoble_internal->pc_ble->sec->new_transport_session) {
|
||||
ret = protoble_internal->pc_ble->sec->new_transport_session(param->connect.conn_id);
|
||||
|
@ -372,7 +372,7 @@ static void protocomm_ble_cleanup(void)
|
|||
if (protoble_internal->g_nu_lookup) {
|
||||
for (unsigned i = 0; i < protoble_internal->g_nu_lookup_count; i++) {
|
||||
if (protoble_internal->g_nu_lookup[i].name) {
|
||||
free(protoble_internal->g_nu_lookup[i].name);
|
||||
free((void *)protoble_internal->g_nu_lookup[i].name);
|
||||
}
|
||||
}
|
||||
free(protoble_internal->g_nu_lookup);
|
||||
|
@ -488,7 +488,7 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con
|
|||
}
|
||||
|
||||
prepare_write_env.prepare_buf = NULL;
|
||||
ESP_LOGV(TAG, "Waiting for client to connect ......");
|
||||
ESP_LOGD(TAG, "Waiting for client to connect ......");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ static void protocomm_console_task(void *arg)
|
|||
QueueHandle_t uart_queue;
|
||||
uart_event_t event;
|
||||
|
||||
ESP_LOGV(TAG, "Initialising UART on port %d", uart_num);
|
||||
ESP_LOGD(TAG, "Initializing UART on port %d", uart_num);
|
||||
uart_driver_install(uart_num, 256, 0, 8, &uart_queue, 0);
|
||||
/* Initialize the console */
|
||||
esp_console_config_t console_config = {
|
||||
|
@ -121,10 +121,6 @@ static void protocomm_console_task(void *arg)
|
|||
}
|
||||
}
|
||||
|
||||
if (pc_console->sec && pc_console->sec->cleanup) {
|
||||
pc_console->sec->cleanup();
|
||||
}
|
||||
|
||||
pc_console = NULL;
|
||||
esp_console_deinit();
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
static const char *TAG = "protocomm_httpd";
|
||||
static protocomm_t *pc_httpd; /* The global protocomm instance for HTTPD */
|
||||
static bool pc_ext_httpd_handle_provided = false;
|
||||
static uint32_t session_id = PROTOCOMM_NO_SESSION_ID;
|
||||
|
||||
#define MAX_REQ_BODY_LEN 4096
|
||||
|
@ -41,9 +42,9 @@ static esp_err_t common_post_handler(httpd_req_t *req)
|
|||
int cur_session_id = httpd_req_to_sockfd(req);
|
||||
|
||||
if (cur_session_id != session_id) {
|
||||
/* Initialise new security session */
|
||||
/* Initialize new security session */
|
||||
if (session_id != PROTOCOMM_NO_SESSION_ID) {
|
||||
ESP_LOGV(TAG, "Closing session with ID: %d", session_id);
|
||||
ESP_LOGD(TAG, "Closing session with ID: %d", session_id);
|
||||
/* Presently HTTP server doesn't support callback on socket closure so
|
||||
* previous session can only be closed when new session is requested */
|
||||
if (pc_httpd->sec && pc_httpd->sec->close_transport_session) {
|
||||
|
@ -65,7 +66,7 @@ static esp_err_t common_post_handler(httpd_req_t *req)
|
|||
}
|
||||
}
|
||||
session_id = cur_session_id;
|
||||
ESP_LOGV(TAG, "New session with ID: %d", cur_session_id);
|
||||
ESP_LOGD(TAG, "New session with ID: %d", cur_session_id);
|
||||
}
|
||||
|
||||
if (req->content_len <= 0) {
|
||||
|
@ -124,7 +125,7 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t protocomm_httpd_add_endpoint(const char *ep_name,
|
||||
static esp_err_t protocomm_httpd_add_endpoint(const char *ep_name,
|
||||
protocomm_req_handler_t req_handler,
|
||||
void *priv_data)
|
||||
{
|
||||
|
@ -132,7 +133,7 @@ esp_err_t protocomm_httpd_add_endpoint(const char *ep_name,
|
|||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "Adding endpoint : %s", ep_name);
|
||||
ESP_LOGD(TAG, "Adding endpoint : %s", ep_name);
|
||||
|
||||
/* Construct URI name by prepending '/' to ep_name */
|
||||
char* ep_uri = calloc(1, strlen(ep_name) + 2);
|
||||
|
@ -169,7 +170,7 @@ static esp_err_t protocomm_httpd_remove_endpoint(const char *ep_name)
|
|||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "Removing endpoint : %s", ep_name);
|
||||
ESP_LOGD(TAG, "Removing endpoint : %s", ep_name);
|
||||
|
||||
/* Construct URI name by prepending '/' to ep_name */
|
||||
char* ep_uri = calloc(1, strlen(ep_name) + 2);
|
||||
|
@ -207,28 +208,36 @@ esp_err_t protocomm_httpd_start(protocomm_t *pc, const protocomm_httpd_config_t
|
|||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* Private data will point to the HTTP server handle */
|
||||
pc->priv = calloc(1, sizeof(httpd_handle_t));
|
||||
if (!pc->priv) {
|
||||
ESP_LOGE(TAG, "Malloc failed for HTTP server handle");
|
||||
return ESP_ERR_NO_MEM;
|
||||
if (config->ext_handle_provided) {
|
||||
if (config->data.handle) {
|
||||
pc->priv = config->data.handle;
|
||||
pc_ext_httpd_handle_provided = true;
|
||||
} else {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
} else {
|
||||
/* Private data will point to the HTTP server handle */
|
||||
pc->priv = calloc(1, sizeof(httpd_handle_t));
|
||||
if (!pc->priv) {
|
||||
ESP_LOGE(TAG, "Malloc failed for HTTP server handle");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
/* Configure the HTTP server */
|
||||
httpd_config_t server_config = HTTPD_DEFAULT_CONFIG();
|
||||
server_config.server_port = config->data.config.port;
|
||||
server_config.stack_size = config->data.config.stack_size;
|
||||
server_config.task_priority = config->data.config.task_priority;
|
||||
server_config.lru_purge_enable = true;
|
||||
server_config.max_open_sockets = 1;
|
||||
|
||||
esp_err_t err;
|
||||
if ((err = httpd_start((httpd_handle_t *)pc->priv, &server_config)) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to start http server: %s", esp_err_to_name(err));
|
||||
free(pc->priv);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure the HTTP server */
|
||||
httpd_config_t server_config = HTTPD_DEFAULT_CONFIG();
|
||||
server_config.server_port = config->port;
|
||||
server_config.stack_size = config->stack_size;
|
||||
server_config.task_priority = config->task_priority;
|
||||
server_config.lru_purge_enable = true;
|
||||
server_config.max_open_sockets = 1;
|
||||
|
||||
esp_err_t err;
|
||||
if ((err = httpd_start((httpd_handle_t *)pc->priv, &server_config)) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to start http server: %s", esp_err_to_name(err));
|
||||
free(pc->priv);
|
||||
return err;
|
||||
}
|
||||
|
||||
pc->add_endpoint = protocomm_httpd_add_endpoint;
|
||||
pc->remove_endpoint = protocomm_httpd_remove_endpoint;
|
||||
pc_httpd = pc;
|
||||
|
@ -238,9 +247,13 @@ esp_err_t protocomm_httpd_start(protocomm_t *pc, const protocomm_httpd_config_t
|
|||
esp_err_t protocomm_httpd_stop(protocomm_t *pc)
|
||||
{
|
||||
if ((pc != NULL) && (pc == pc_httpd)) {
|
||||
httpd_handle_t *server_handle = (httpd_handle_t *) pc_httpd->priv;
|
||||
httpd_stop(*server_handle);
|
||||
free(server_handle);
|
||||
if (!pc_ext_httpd_handle_provided) {
|
||||
httpd_handle_t *server_handle = (httpd_handle_t *) pc_httpd->priv;
|
||||
httpd_stop(*server_handle);
|
||||
free(server_handle);
|
||||
} else {
|
||||
pc_ext_httpd_handle_provided = false;
|
||||
}
|
||||
pc_httpd->priv = NULL;
|
||||
pc_httpd = NULL;
|
||||
return ESP_OK;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <esp_log.h>
|
||||
#include <esp_system.h>
|
||||
#include <sys/random.h>
|
||||
#include <unistd.h>
|
||||
#include <unity.h>
|
||||
|
||||
#include <mbedtls/aes.h>
|
||||
|
@ -36,7 +37,7 @@
|
|||
|
||||
#include "session.pb-c.h"
|
||||
|
||||
#ifdef DO_HEAP_TRACING
|
||||
#ifdef CONFIG_HEAP_TRACING
|
||||
#include <esp_heap_trace.h>
|
||||
#define NUM_RECORDS 100
|
||||
static heap_trace_record_t trace_record[NUM_RECORDS]; // This buffer must be in internal RAM
|
||||
|
@ -492,6 +493,30 @@ abort_test_sec_endpoint:
|
|||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
#define TEST_VER_STR "<some version string>"
|
||||
|
||||
static esp_err_t test_ver_endpoint(session_t *session)
|
||||
{
|
||||
ssize_t ver_data_len = 0;
|
||||
uint8_t *ver_data = NULL;
|
||||
|
||||
esp_err_t ret = protocomm_req_handle(test_pc, "test-ver", session->id,
|
||||
NULL, 0, &ver_data, &ver_data_len);
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "test-ver handler failed");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (ver_data_len != strlen(TEST_VER_STR) || memcmp(TEST_VER_STR, ver_data, ver_data_len)) {
|
||||
ESP_LOGE(TAG, "incorrect response data from test-ver");
|
||||
free(ver_data);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
free(ver_data);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t test_req_endpoint(session_t *session)
|
||||
{
|
||||
uint32_t session_id = session->id;
|
||||
|
@ -514,7 +539,7 @@ static esp_err_t test_req_endpoint(session_t *session)
|
|||
enc_test_data, sizeof(enc_test_data),
|
||||
&enc_verify_data, &verify_data_len);
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
if (ret != ESP_OK || !verify_data_len) {
|
||||
ESP_LOGE(TAG, "test-ep handler failed");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
@ -600,6 +625,11 @@ static esp_err_t start_test_service(uint8_t sec_ver, const protocomm_security_po
|
|||
test_sec = &protocomm_security1;
|
||||
}
|
||||
|
||||
if (protocomm_set_version(test_pc, "test-ver", TEST_VER_STR) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set version");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (protocomm_add_endpoint(test_pc, "test-ep",
|
||||
test_req_handler,
|
||||
(void *) &test_priv_data) != ESP_OK) {
|
||||
|
@ -611,8 +641,6 @@ static esp_err_t start_test_service(uint8_t sec_ver, const protocomm_security_po
|
|||
|
||||
static void stop_test_service(void)
|
||||
{
|
||||
protocomm_remove_endpoint(test_pc, "test-ep");
|
||||
protocomm_unset_security(test_pc, "test-sec");
|
||||
test_sec = NULL;
|
||||
protocomm_delete(test_pc);
|
||||
test_pc = NULL;
|
||||
|
@ -913,8 +941,8 @@ static esp_err_t test_security1_weak_session (void)
|
|||
}
|
||||
|
||||
// Sending request data to echo endpoint encrypted with zero
|
||||
// public keys on both client and server side should pass
|
||||
if (test_req_endpoint(session) != ESP_OK) {
|
||||
// public keys on both client and server side should fail
|
||||
if (test_req_endpoint(session) == ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error testing request endpoint");
|
||||
stop_test_service();
|
||||
free(session);
|
||||
|
@ -938,6 +966,13 @@ static esp_err_t test_protocomm (session_t *session)
|
|||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// Check version endpoint
|
||||
if (test_ver_endpoint(session) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error testing version endpoint");
|
||||
stop_test_service();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// Intialise protocomm session with zero public keys
|
||||
if (test_new_session(session) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error creating new session");
|
||||
|
@ -1024,33 +1059,43 @@ static esp_err_t test_security0 (void)
|
|||
|
||||
TEST_CASE("leak test", "[PROTOCOMM]")
|
||||
{
|
||||
#ifdef DO_HEAP_TRACING
|
||||
#ifdef CONFIG_HEAP_TRACING
|
||||
heap_trace_init_standalone(trace_record, NUM_RECORDS);
|
||||
#endif
|
||||
|
||||
unsigned pre_start_mem = esp_get_free_heap_size();
|
||||
|
||||
#ifdef DO_HEAP_TRACING
|
||||
heap_trace_start(HEAP_TRACE_LEAKS);
|
||||
#endif
|
||||
|
||||
/* Run basic tests for the first time to allow for internal long
|
||||
* time allocations to happen (not related to protocomm) */
|
||||
test_security0();
|
||||
test_security1();
|
||||
usleep(1000);
|
||||
|
||||
#ifdef DO_HEAP_TRACING
|
||||
#ifdef CONFIG_HEAP_TRACING
|
||||
heap_trace_stop();
|
||||
heap_trace_dump();
|
||||
#endif
|
||||
|
||||
/* Run all tests passively. Any leaks due
|
||||
* to protocomm should show up now */
|
||||
unsigned pre_start_mem = esp_get_free_heap_size();
|
||||
|
||||
test_security0();
|
||||
test_security1();
|
||||
test_security1_no_encryption();
|
||||
test_security1_session_overflow();
|
||||
test_security1_wrong_pop();
|
||||
test_security1_insecure_client();
|
||||
test_security1_weak_session();
|
||||
|
||||
usleep(1000);
|
||||
|
||||
unsigned post_stop_mem = esp_get_free_heap_size();
|
||||
|
||||
if (pre_start_mem != post_stop_mem) {
|
||||
ESP_LOGE(TAG, "Mismatch in free heap size");
|
||||
ESP_LOGE(TAG, "Mismatch in free heap size : %d bytes", post_stop_mem - pre_start_mem);
|
||||
}
|
||||
|
||||
#ifdef DO_HEAP_TRACING
|
||||
TEST_ASSERT(pre_start_mem != post_stop_mem);
|
||||
#endif
|
||||
TEST_ASSERT(pre_start_mem == post_stop_mem);
|
||||
}
|
||||
|
||||
TEST_CASE("security 0 basic test", "[PROTOCOMM]")
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
|
||||
#include <lwip/inet.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief WiFi STA status for conveying back to the provisioning master
|
||||
*/
|
||||
|
@ -77,6 +81,15 @@ typedef struct {
|
|||
uint8_t channel; /*!< Channel of the AP */
|
||||
} wifi_prov_config_set_data_t;
|
||||
|
||||
/**
|
||||
* @brief Type of context data passed to each get/set/apply handler
|
||||
* function set in `wifi_prov_config_handlers` structure.
|
||||
*
|
||||
* This is passed as an opaque pointer, thereby allowing it be defined
|
||||
* later in application code as per requirements.
|
||||
*/
|
||||
typedef struct wifi_prov_ctx wifi_prov_ctx_t;
|
||||
|
||||
/**
|
||||
* @brief Internal handlers for receiving and responding to protocomm
|
||||
* requests from master
|
||||
|
@ -89,14 +102,16 @@ typedef struct wifi_prov_config_handlers {
|
|||
* Handler function called when connection status
|
||||
* of the slave (in WiFi station mode) is requested
|
||||
*/
|
||||
esp_err_t (*get_status_handler)(wifi_prov_config_get_data_t *resp_data);
|
||||
esp_err_t (*get_status_handler)(wifi_prov_config_get_data_t *resp_data,
|
||||
wifi_prov_ctx_t **ctx);
|
||||
|
||||
/**
|
||||
* Handler function called when WiFi connection configuration
|
||||
* (eg. AP SSID, password, etc.) of the slave (in WiFi station mode)
|
||||
* is to be set to user provided values
|
||||
*/
|
||||
esp_err_t (*set_config_handler)(const wifi_prov_config_set_data_t *req_data);
|
||||
esp_err_t (*set_config_handler)(const wifi_prov_config_set_data_t *req_data,
|
||||
wifi_prov_ctx_t **ctx);
|
||||
|
||||
/**
|
||||
* Handler function for applying the configuration that was set in
|
||||
|
@ -105,7 +120,12 @@ typedef struct wifi_prov_config_handlers {
|
|||
* updated connection status information when `get_status_handler` is
|
||||
* invoked again by the master.
|
||||
*/
|
||||
esp_err_t (*apply_config_handler)(void);
|
||||
esp_err_t (*apply_config_handler)(wifi_prov_ctx_t **ctx);
|
||||
|
||||
/**
|
||||
* Context pointer to be passed to above handler functions upon invocation
|
||||
*/
|
||||
wifi_prov_ctx_t *ctx;
|
||||
} wifi_prov_config_handlers_t;
|
||||
|
||||
/**
|
||||
|
@ -117,4 +137,8 @@ typedef struct wifi_prov_config_handlers {
|
|||
esp_err_t wifi_prov_config_data_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen,
|
||||
uint8_t **outbuf, ssize_t *outlen, void *priv_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -72,7 +72,7 @@ static esp_err_t cmd_get_status_handler(WiFiConfigPayload *req,
|
|||
resp_get_status__init(resp_payload);
|
||||
|
||||
wifi_prov_config_get_data_t resp_data;
|
||||
if (h->get_status_handler(&resp_data) == ESP_OK) {
|
||||
if (h->get_status_handler(&resp_data, &h->ctx) == ESP_OK) {
|
||||
if (resp_data.wifi_state == WIFI_PROV_STA_CONNECTING) {
|
||||
resp_payload->sta_state = WIFI_STATION_STATE__Connecting;
|
||||
resp_payload->state_case = RESP_GET_STATUS__STATE_CONNECTED;
|
||||
|
@ -158,7 +158,7 @@ static esp_err_t cmd_set_config_handler(WiFiConfigPayload *req,
|
|||
memcpy(req_data.bssid, req->cmd_set_config->bssid.data,
|
||||
req->cmd_set_config->bssid.len);
|
||||
req_data.channel = req->cmd_set_config->channel;
|
||||
if (h->set_config_handler(&req_data) == ESP_OK) {
|
||||
if (h->set_config_handler(&req_data, &h->ctx) == ESP_OK) {
|
||||
resp_payload->status = STATUS__Success;
|
||||
}
|
||||
|
||||
|
@ -185,7 +185,7 @@ static esp_err_t cmd_apply_config_handler(WiFiConfigPayload *req,
|
|||
|
||||
resp_apply_config__init(resp_payload);
|
||||
|
||||
if (h->apply_config_handler() == ESP_OK) {
|
||||
if (h->apply_config_handler(&h->ctx) == ESP_OK) {
|
||||
resp_payload->status = STATUS__Success;
|
||||
} else {
|
||||
resp_payload->status = STATUS__InvalidArgument;
|
||||
|
|
|
@ -54,8 +54,13 @@ For complete example see :example:`provisioning/softap_prov`
|
|||
{
|
||||
protocomm_t *pc = protocomm_new();
|
||||
|
||||
|
||||
/* Config for protocomm_httpd_start() */
|
||||
protocomm_httpd_config_t pc_config = PROTOCOMM_HTTPD_DEFAULT_CONFIG();
|
||||
protocomm_httpd_config_t pc_config = {
|
||||
.data = {
|
||||
.config = PROTOCOMM_HTTPD_DEFAULT_CONFIG()
|
||||
}
|
||||
};
|
||||
|
||||
/* Start protocomm server on top of HTTP */
|
||||
protocomm_httpd_start(pc, &pc_config);
|
||||
|
|
|
@ -4,7 +4,9 @@ Wi-Fi Provisioning
|
|||
Overview
|
||||
--------
|
||||
|
||||
This component provides protocomm endpoint handler - `wifi_prov_config_data_handler` - and related protobuf framework which can be used for Wi-Fi configuration in the context of device provisioning, though it may be used in non-provisioning cases as well. The configuration consists of three commands :
|
||||
This component provides protocomm endpoint handler - `wifi_prov_config_data_handler` - and related protobuf framework which can be used for Wi-Fi configuration in the context of device provisioning, though it may be used in non-provisioning cases as well.
|
||||
|
||||
The configuration consists of three commands :
|
||||
* `get_status` - For querying the Wi-Fi connection status
|
||||
* `set_config` - For setting the Wi-Fi connection credentials
|
||||
* `apply_config` - For applying the credentials saved during `set_config` and (re)start the Wi-Fi station
|
||||
|
@ -18,7 +20,7 @@ Application Example
|
|||
|
||||
::
|
||||
|
||||
esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data)
|
||||
esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data, wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
/* Fill the wifi_prov_config_get_data_t structure
|
||||
* with Wi-Fi station connection status information. */
|
||||
|
@ -26,7 +28,7 @@ Application Example
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data)
|
||||
esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data, wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
/* Copy contents of req_data->ssid and req_data->password
|
||||
* which are Wi-Fi AP credentials to which the device will connect */
|
||||
|
@ -34,7 +36,7 @@ Application Example
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t apply_config_handler(void)
|
||||
esp_err_t apply_config_handler(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
/* Apply the Wi-Fi STA credentials saved during set_config */
|
||||
|
||||
|
@ -47,6 +49,7 @@ Application Example
|
|||
.get_status_handler = get_status_handler,
|
||||
.set_config_handler = set_config_handler,
|
||||
.apply_config_handler = apply_config_handler,
|
||||
.ctx = NULL
|
||||
};
|
||||
|
||||
/* Set the endpoint handler */
|
||||
|
|
|
@ -188,7 +188,7 @@ esp_err_t app_prov_event_handler(void *ctx, system_event_t *event)
|
|||
|
||||
case SYSTEM_EVENT_STA_GOT_IP:
|
||||
ESP_LOGI(TAG, "STA Got IP");
|
||||
/* Station got IP. That means configuraion is successful.
|
||||
/* Station got IP. That means configuration is successful.
|
||||
* Schedule timer to stop provisioning app after 30 seconds. */
|
||||
g_prov->wifi_state = WIFI_PROV_STA_CONNECTED;
|
||||
if (g_prov && g_prov->timer) {
|
||||
|
@ -341,7 +341,7 @@ esp_err_t app_prov_start_ble_provisioning(int security, const protocomm_security
|
|||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
/* Initialise app data */
|
||||
/* Initialize app data */
|
||||
g_prov->pop = pop;
|
||||
g_prov->security = security;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* BLE based Provisioning Example
|
||||
/* SoftAP based Provisioning Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
|
@ -23,9 +23,32 @@
|
|||
|
||||
static const char* TAG = "app_prov_handler";
|
||||
|
||||
static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data)
|
||||
/* Provide definition of wifi_prov_ctx_t */
|
||||
struct wifi_prov_ctx {
|
||||
wifi_config_t wifi_cfg;
|
||||
};
|
||||
|
||||
static wifi_config_t *get_config(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
/* Initialise to zero */
|
||||
return (*ctx ? &(*ctx)->wifi_cfg : NULL);
|
||||
}
|
||||
|
||||
static wifi_config_t *new_config(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
free(*ctx);
|
||||
(*ctx) = (wifi_prov_ctx_t *) calloc(1, sizeof(wifi_prov_ctx_t));
|
||||
return get_config(ctx);
|
||||
}
|
||||
|
||||
static void free_config(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
free(*ctx);
|
||||
*ctx = NULL;
|
||||
}
|
||||
|
||||
static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data, wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
/* Initialize to zero */
|
||||
memset(resp_data, 0, sizeof(wifi_prov_config_get_data_t));
|
||||
|
||||
if (app_prov_get_wifi_state(&resp_data->wifi_state) != ESP_OK) {
|
||||
|
@ -60,16 +83,14 @@ static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data)
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
static wifi_config_t *wifi_cfg;
|
||||
|
||||
static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data)
|
||||
static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data, wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
wifi_config_t *wifi_cfg = get_config(ctx);
|
||||
if (wifi_cfg) {
|
||||
free(wifi_cfg);
|
||||
wifi_cfg = NULL;
|
||||
free_config(ctx);
|
||||
}
|
||||
|
||||
wifi_cfg = (wifi_config_t *) calloc(1, sizeof(wifi_config_t));
|
||||
wifi_cfg = new_config(ctx);
|
||||
if (!wifi_cfg) {
|
||||
ESP_LOGE(TAG, "Unable to alloc wifi config");
|
||||
return ESP_FAIL;
|
||||
|
@ -84,8 +105,9 @@ static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data)
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t apply_config_handler(void)
|
||||
static esp_err_t apply_config_handler(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
wifi_config_t *wifi_cfg = get_config(ctx);
|
||||
if (!wifi_cfg) {
|
||||
ESP_LOGE(TAG, "WiFi config not set");
|
||||
return ESP_FAIL;
|
||||
|
@ -94,8 +116,7 @@ static esp_err_t apply_config_handler(void)
|
|||
app_prov_configure_sta(wifi_cfg);
|
||||
ESP_LOGI(TAG, "WiFi Credentials Applied");
|
||||
|
||||
free(wifi_cfg);
|
||||
wifi_cfg = NULL;
|
||||
free_config(ctx);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
@ -103,4 +124,5 @@ wifi_prov_config_handlers_t wifi_prov_handlers = {
|
|||
.get_status_handler = get_status_handler,
|
||||
.set_config_handler = set_config_handler,
|
||||
.apply_config_handler = apply_config_handler,
|
||||
.ctx = NULL
|
||||
};
|
||||
|
|
|
@ -101,8 +101,8 @@ static void app_prov_stop_service(void)
|
|||
protocomm_delete(g_prov->pc);
|
||||
}
|
||||
|
||||
/* Callback to be invoked by timer */
|
||||
static void _stop_prov_cb(void * arg)
|
||||
/* Task spawned by timer callback */
|
||||
static void stop_prov_task(void * arg)
|
||||
{
|
||||
ESP_LOGI(TAG, "Stopping provisioning");
|
||||
app_prov_stop_service();
|
||||
|
@ -116,6 +116,14 @@ static void _stop_prov_cb(void * arg)
|
|||
free(g_prov);
|
||||
g_prov = NULL;
|
||||
ESP_LOGI(TAG, "Provisioning stopped");
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
/* Callback to be invoked by timer */
|
||||
static void _stop_prov_cb(void * arg)
|
||||
{
|
||||
xTaskCreate(&stop_prov_task, "stop_prov", 2048, NULL, tskIDLE_PRIORITY, NULL);
|
||||
}
|
||||
|
||||
/* Event handler for starting/stopping provisioning.
|
||||
|
@ -146,7 +154,7 @@ esp_err_t app_prov_event_handler(void *ctx, system_event_t *event)
|
|||
|
||||
case SYSTEM_EVENT_STA_GOT_IP:
|
||||
ESP_LOGI(TAG, "STA Got IP");
|
||||
/* Station got IP. That means configuraion is successful.
|
||||
/* Station got IP. That means configuration is successful.
|
||||
* Schedule timer to stop provisioning app after 30 seconds. */
|
||||
g_prov->wifi_state = WIFI_PROV_STA_CONNECTED;
|
||||
if (g_prov && g_prov->timer) {
|
||||
|
@ -299,7 +307,7 @@ esp_err_t app_prov_start_console_provisioning(int security, const protocomm_secu
|
|||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
/* Initialise app data */
|
||||
/* Initialize app data */
|
||||
g_prov->pop = pop;
|
||||
g_prov->security = security;
|
||||
|
||||
|
@ -308,7 +316,7 @@ esp_err_t app_prov_start_console_provisioning(int security, const protocomm_secu
|
|||
.callback = _stop_prov_cb,
|
||||
.arg = NULL,
|
||||
.dispatch_method = ESP_TIMER_TASK,
|
||||
.name = "stop_softap_tm"
|
||||
.name = "stop_console_tm"
|
||||
};
|
||||
esp_err_t err = esp_timer_create(&timer_conf, &g_prov->timer);
|
||||
if (err != ESP_OK) {
|
||||
|
|
|
@ -23,9 +23,32 @@
|
|||
|
||||
static const char* TAG = "app_prov_handler";
|
||||
|
||||
static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data)
|
||||
/* Provide definition of wifi_prov_ctx_t */
|
||||
struct wifi_prov_ctx {
|
||||
wifi_config_t wifi_cfg;
|
||||
};
|
||||
|
||||
static wifi_config_t *get_config(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
/* Initialise to zero */
|
||||
return (*ctx ? &(*ctx)->wifi_cfg : NULL);
|
||||
}
|
||||
|
||||
static wifi_config_t *new_config(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
free(*ctx);
|
||||
(*ctx) = (wifi_prov_ctx_t *) calloc(1, sizeof(wifi_prov_ctx_t));
|
||||
return get_config(ctx);
|
||||
}
|
||||
|
||||
static void free_config(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
free(*ctx);
|
||||
*ctx = NULL;
|
||||
}
|
||||
|
||||
static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data, wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
/* Initialize to zero */
|
||||
memset(resp_data, 0, sizeof(wifi_prov_config_get_data_t));
|
||||
|
||||
if (app_prov_get_wifi_state(&resp_data->wifi_state) != ESP_OK) {
|
||||
|
@ -60,16 +83,14 @@ static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data)
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
static wifi_config_t *wifi_cfg;
|
||||
|
||||
static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data)
|
||||
static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data, wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
wifi_config_t *wifi_cfg = get_config(ctx);
|
||||
if (wifi_cfg) {
|
||||
free(wifi_cfg);
|
||||
wifi_cfg = NULL;
|
||||
free_config(ctx);
|
||||
}
|
||||
|
||||
wifi_cfg = (wifi_config_t *) calloc(1, sizeof(wifi_config_t));
|
||||
wifi_cfg = new_config(ctx);
|
||||
if (!wifi_cfg) {
|
||||
ESP_LOGE(TAG, "Unable to alloc wifi config");
|
||||
return ESP_FAIL;
|
||||
|
@ -84,8 +105,9 @@ static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data)
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t apply_config_handler(void)
|
||||
static esp_err_t apply_config_handler(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
wifi_config_t *wifi_cfg = get_config(ctx);
|
||||
if (!wifi_cfg) {
|
||||
ESP_LOGE(TAG, "WiFi config not set");
|
||||
return ESP_FAIL;
|
||||
|
@ -94,8 +116,7 @@ static esp_err_t apply_config_handler(void)
|
|||
app_prov_configure_sta(wifi_cfg);
|
||||
ESP_LOGI(TAG, "WiFi Credentials Applied");
|
||||
|
||||
free(wifi_cfg);
|
||||
wifi_cfg = NULL;
|
||||
free_config(ctx);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
@ -103,4 +124,5 @@ wifi_prov_config_handlers_t wifi_prov_handlers = {
|
|||
.get_status_handler = get_status_handler,
|
||||
.set_config_handler = set_config_handler,
|
||||
.apply_config_handler = apply_config_handler,
|
||||
.ctx = NULL
|
||||
};
|
||||
|
|
|
@ -58,7 +58,11 @@ static esp_err_t app_prov_start_service(void)
|
|||
}
|
||||
|
||||
/* Config for protocomm_httpd_start() */
|
||||
protocomm_httpd_config_t pc_config = PROTOCOMM_HTTPD_DEFAULT_CONFIG();
|
||||
protocomm_httpd_config_t pc_config = {
|
||||
.data = {
|
||||
.config = PROTOCOMM_HTTPD_DEFAULT_CONFIG()
|
||||
}
|
||||
};
|
||||
|
||||
/* Start protocomm server on top of HTTP */
|
||||
if (protocomm_httpd_start(g_prov->pc, &pc_config) != ESP_OK) {
|
||||
|
@ -112,8 +116,8 @@ static void app_prov_stop_service(void)
|
|||
protocomm_delete(g_prov->pc);
|
||||
}
|
||||
|
||||
/* Callback to be invoked by timer */
|
||||
static void _stop_softap_cb(void * arg)
|
||||
/* Task spawned by timer callback */
|
||||
static void stop_prov_task(void * arg)
|
||||
{
|
||||
ESP_LOGI(TAG, "Stopping provisioning");
|
||||
app_prov_stop_service();
|
||||
|
@ -128,6 +132,14 @@ static void _stop_softap_cb(void * arg)
|
|||
free(g_prov);
|
||||
g_prov = NULL;
|
||||
ESP_LOGI(TAG, "Provisioning stopped");
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
/* Callback to be invoked by timer */
|
||||
static void _stop_prov_cb(void * arg)
|
||||
{
|
||||
xTaskCreate(&stop_prov_task, "stop_prov", 2048, NULL, tskIDLE_PRIORITY, NULL);
|
||||
}
|
||||
|
||||
/* Event handler for starting/stopping provisioning.
|
||||
|
@ -158,7 +170,7 @@ esp_err_t app_prov_event_handler(void *ctx, system_event_t *event)
|
|||
|
||||
case SYSTEM_EVENT_STA_GOT_IP:
|
||||
ESP_LOGI(TAG, "STA Got IP");
|
||||
/* Station got IP. That means configuraion is successful.
|
||||
/* Station got IP. That means configuration is successful.
|
||||
* Schedule timer to stop provisioning app after 30 seconds. */
|
||||
g_prov->wifi_state = WIFI_PROV_STA_CONNECTED;
|
||||
if (g_prov && g_prov->timer) {
|
||||
|
@ -170,7 +182,7 @@ esp_err_t app_prov_event_handler(void *ctx, system_event_t *event)
|
|||
* to reconnect and get STA connection status from the device.
|
||||
* Otherwise, the AP will be turned off before the user can
|
||||
* reconnect and thus the user app will see connection timed out,
|
||||
* signalling a failure in provisioning. */
|
||||
* signaling a failure in provisioning. */
|
||||
esp_timer_start_once(g_prov->timer, 30000*1000U);
|
||||
}
|
||||
break;
|
||||
|
@ -299,7 +311,7 @@ esp_err_t app_prov_configure_sta(wifi_config_t *wifi_cfg)
|
|||
|
||||
static esp_err_t start_wifi_ap(const char *ssid, const char *pass)
|
||||
{
|
||||
/* Initialise WiFi with default configuration */
|
||||
/* Initialize WiFi with default configuration */
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
esp_err_t err = esp_wifi_init(&cfg);
|
||||
if (err != ESP_OK) {
|
||||
|
@ -368,7 +380,7 @@ esp_err_t app_prov_start_softap_provisioning(const char *ssid, const char *pass,
|
|||
|
||||
/* Create timer object as a member of app data */
|
||||
esp_timer_create_args_t timer_conf = {
|
||||
.callback = _stop_softap_cb,
|
||||
.callback = _stop_prov_cb,
|
||||
.arg = NULL,
|
||||
.dispatch_method = ESP_TIMER_TASK,
|
||||
.name = "stop_softap_tm"
|
||||
|
|
|
@ -24,6 +24,29 @@
|
|||
|
||||
static const char* TAG = "app_prov_handler";
|
||||
|
||||
/* Provide definition of wifi_prov_ctx_t */
|
||||
struct wifi_prov_ctx {
|
||||
wifi_config_t wifi_cfg;
|
||||
};
|
||||
|
||||
static wifi_config_t *get_config(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
return (*ctx ? &(*ctx)->wifi_cfg : NULL);
|
||||
}
|
||||
|
||||
static wifi_config_t *new_config(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
free(*ctx);
|
||||
(*ctx) = (wifi_prov_ctx_t *) calloc(1, sizeof(wifi_prov_ctx_t));
|
||||
return get_config(ctx);
|
||||
}
|
||||
|
||||
static void free_config(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
free(*ctx);
|
||||
*ctx = NULL;
|
||||
}
|
||||
|
||||
/****************** Handler for Custom Configuration *******************/
|
||||
static esp_err_t custom_config_handler(const custom_config_t *config)
|
||||
{
|
||||
|
@ -35,9 +58,9 @@ static esp_err_t custom_config_handler(const custom_config_t *config)
|
|||
custom_prov_config_handler_t custom_prov_handler = custom_config_handler;
|
||||
|
||||
/****************** Handlers for Wi-Fi Configuration *******************/
|
||||
static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data)
|
||||
static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data, wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
/* Initialise to zero */
|
||||
/* Initialize to zero */
|
||||
memset(resp_data, 0, sizeof(wifi_prov_config_get_data_t));
|
||||
|
||||
if (app_prov_get_wifi_state(&resp_data->wifi_state) != ESP_OK) {
|
||||
|
@ -72,16 +95,14 @@ static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data)
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
static wifi_config_t *wifi_cfg;
|
||||
|
||||
static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data)
|
||||
static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data, wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
wifi_config_t *wifi_cfg = get_config(ctx);
|
||||
if (wifi_cfg) {
|
||||
free(wifi_cfg);
|
||||
wifi_cfg = NULL;
|
||||
free_config(ctx);
|
||||
}
|
||||
|
||||
wifi_cfg = (wifi_config_t *) calloc(1, sizeof(wifi_config_t));
|
||||
wifi_cfg = new_config(ctx);
|
||||
if (!wifi_cfg) {
|
||||
ESP_LOGE(TAG, "Unable to alloc wifi config");
|
||||
return ESP_FAIL;
|
||||
|
@ -96,8 +117,9 @@ static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data)
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t apply_config_handler(void)
|
||||
static esp_err_t apply_config_handler(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
wifi_config_t *wifi_cfg = get_config(ctx);
|
||||
if (!wifi_cfg) {
|
||||
ESP_LOGE(TAG, "WiFi config not set");
|
||||
return ESP_FAIL;
|
||||
|
@ -106,8 +128,7 @@ static esp_err_t apply_config_handler(void)
|
|||
app_prov_configure_sta(wifi_cfg);
|
||||
ESP_LOGI(TAG, "WiFi Credentials Applied");
|
||||
|
||||
free(wifi_cfg);
|
||||
wifi_cfg = NULL;
|
||||
free_config(ctx);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
@ -115,4 +136,5 @@ wifi_prov_config_handlers_t wifi_prov_handlers = {
|
|||
.get_status_handler = get_status_handler,
|
||||
.set_config_handler = set_config_handler,
|
||||
.apply_config_handler = apply_config_handler,
|
||||
.ctx = NULL
|
||||
};
|
||||
|
|
|
@ -56,8 +56,11 @@ static esp_err_t app_prov_start_service(void)
|
|||
}
|
||||
|
||||
/* Config for protocomm_httpd_start() */
|
||||
protocomm_httpd_config_t pc_config = PROTOCOMM_HTTPD_DEFAULT_CONFIG();
|
||||
|
||||
protocomm_httpd_config_t pc_config = {
|
||||
.data = {
|
||||
.config = PROTOCOMM_HTTPD_DEFAULT_CONFIG()
|
||||
}
|
||||
};
|
||||
/* Start protocomm server on top of HTTP */
|
||||
if (protocomm_httpd_start(g_prov->pc, &pc_config) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to start protocomm HTTP server");
|
||||
|
@ -99,8 +102,8 @@ static void app_prov_stop_service(void)
|
|||
protocomm_delete(g_prov->pc);
|
||||
}
|
||||
|
||||
/* Callback to be invoked by timer */
|
||||
static void _stop_softap_cb(void * arg)
|
||||
/* Task spawned by timer callback */
|
||||
static void stop_prov_task(void * arg)
|
||||
{
|
||||
ESP_LOGI(TAG, "Stopping provisioning");
|
||||
app_prov_stop_service();
|
||||
|
@ -115,6 +118,14 @@ static void _stop_softap_cb(void * arg)
|
|||
free(g_prov);
|
||||
g_prov = NULL;
|
||||
ESP_LOGI(TAG, "Provisioning stopped");
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
/* Callback to be invoked by timer */
|
||||
static void _stop_prov_cb(void * arg)
|
||||
{
|
||||
xTaskCreate(&stop_prov_task, "stop_prov", 2048, NULL, tskIDLE_PRIORITY, NULL);
|
||||
}
|
||||
|
||||
/* Event handler for starting/stopping provisioning.
|
||||
|
@ -145,7 +156,7 @@ esp_err_t app_prov_event_handler(void *ctx, system_event_t *event)
|
|||
|
||||
case SYSTEM_EVENT_STA_GOT_IP:
|
||||
ESP_LOGI(TAG, "STA Got IP");
|
||||
/* Station got IP. That means configuraion is successful.
|
||||
/* Station got IP. That means configuration is successful.
|
||||
* Schedule timer to stop provisioning app after 30 seconds. */
|
||||
g_prov->wifi_state = WIFI_PROV_STA_CONNECTED;
|
||||
if (g_prov && g_prov->timer) {
|
||||
|
@ -157,7 +168,7 @@ esp_err_t app_prov_event_handler(void *ctx, system_event_t *event)
|
|||
* to reconnect and get STA connection status from the device.
|
||||
* Otherwise, the AP will be turned off before the user can
|
||||
* reconnect and thus the user app will see connection timed out,
|
||||
* signalling a failure in provisioning. */
|
||||
* signaling a failure in provisioning. */
|
||||
esp_timer_start_once(g_prov->timer, 30000*1000U);
|
||||
}
|
||||
break;
|
||||
|
@ -287,7 +298,7 @@ esp_err_t app_prov_configure_sta(wifi_config_t *wifi_cfg)
|
|||
|
||||
static esp_err_t start_wifi_ap(const char *ssid, const char *pass)
|
||||
{
|
||||
/* Initialise WiFi with default configuration */
|
||||
/* Initialize WiFi with default configuration */
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
esp_err_t err = esp_wifi_init(&cfg);
|
||||
if (err != ESP_OK) {
|
||||
|
@ -350,13 +361,13 @@ esp_err_t app_prov_start_softap_provisioning(const char *ssid, const char *pass,
|
|||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
/* Initialise app data */
|
||||
/* Initialize app data */
|
||||
g_prov->pop = pop;
|
||||
g_prov->security = security;
|
||||
|
||||
/* Create timer object as a member of app data */
|
||||
esp_timer_create_args_t timer_conf = {
|
||||
.callback = _stop_softap_cb,
|
||||
.callback = _stop_prov_cb,
|
||||
.arg = NULL,
|
||||
.dispatch_method = ESP_TIMER_TASK,
|
||||
.name = "stop_softap_tm"
|
||||
|
|
|
@ -23,9 +23,32 @@
|
|||
|
||||
static const char* TAG = "app_prov_handler";
|
||||
|
||||
static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data)
|
||||
/* Provide definition of wifi_prov_ctx_t */
|
||||
struct wifi_prov_ctx {
|
||||
wifi_config_t wifi_cfg;
|
||||
};
|
||||
|
||||
static wifi_config_t *get_config(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
/* Initialise to zero */
|
||||
return (*ctx ? &(*ctx)->wifi_cfg : NULL);
|
||||
}
|
||||
|
||||
static wifi_config_t *new_config(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
free(*ctx);
|
||||
(*ctx) = (wifi_prov_ctx_t *) calloc(1, sizeof(wifi_prov_ctx_t));
|
||||
return get_config(ctx);
|
||||
}
|
||||
|
||||
static void free_config(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
free(*ctx);
|
||||
*ctx = NULL;
|
||||
}
|
||||
|
||||
static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data, wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
/* Initialize to zero */
|
||||
memset(resp_data, 0, sizeof(wifi_prov_config_get_data_t));
|
||||
|
||||
if (app_prov_get_wifi_state(&resp_data->wifi_state) != ESP_OK) {
|
||||
|
@ -60,16 +83,14 @@ static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data)
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
static wifi_config_t *wifi_cfg;
|
||||
|
||||
static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data)
|
||||
static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data, wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
wifi_config_t *wifi_cfg = get_config(ctx);
|
||||
if (wifi_cfg) {
|
||||
free(wifi_cfg);
|
||||
wifi_cfg = NULL;
|
||||
free_config(ctx);
|
||||
}
|
||||
|
||||
wifi_cfg = (wifi_config_t *) calloc(1, sizeof(wifi_config_t));
|
||||
wifi_cfg = new_config(ctx);
|
||||
if (!wifi_cfg) {
|
||||
ESP_LOGE(TAG, "Unable to alloc wifi config");
|
||||
return ESP_FAIL;
|
||||
|
@ -84,8 +105,9 @@ static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data)
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t apply_config_handler(void)
|
||||
static esp_err_t apply_config_handler(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
wifi_config_t *wifi_cfg = get_config(ctx);
|
||||
if (!wifi_cfg) {
|
||||
ESP_LOGE(TAG, "WiFi config not set");
|
||||
return ESP_FAIL;
|
||||
|
@ -94,8 +116,7 @@ static esp_err_t apply_config_handler(void)
|
|||
app_prov_configure_sta(wifi_cfg);
|
||||
ESP_LOGI(TAG, "WiFi Credentials Applied");
|
||||
|
||||
free(wifi_cfg);
|
||||
wifi_cfg = NULL;
|
||||
free_config(ctx);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
@ -103,4 +124,5 @@ wifi_prov_config_handlers_t wifi_prov_handlers = {
|
|||
.get_status_handler = get_status_handler,
|
||||
.set_config_handler = set_config_handler,
|
||||
.apply_config_handler = apply_config_handler,
|
||||
.ctx = NULL
|
||||
};
|
||||
|
|
|
@ -59,7 +59,7 @@ def get_transport(sel_transport, softap_endpoint=None, ble_devname=None):
|
|||
def version_match(tp, protover):
|
||||
try:
|
||||
response = tp.send_data('proto-ver', protover)
|
||||
if response != "SUCCESS":
|
||||
if response != protover:
|
||||
return False
|
||||
return True
|
||||
except RuntimeError as e:
|
||||
|
|
Loading…
Reference in a new issue