Merge branch 'feature/assisted_claiming' into 'master'

esp_claim: Add support for "Assisted Claiming"

See merge request app-frameworks/esp-rainmaker!158
This commit is contained in:
Piyush Shah
2020-09-17 13:00:39 +08:00
12 changed files with 1373 additions and 256 deletions

View File

@@ -12,6 +12,12 @@ set(core_srcs "src/core/esp_rmaker_core.c"
"src/core/esp_rmaker_utils.c"
"src/core/esp_rmaker_user_mapping.c")
if(CONFIG_ESP_RMAKER_ASSISTED_CLAIM)
list(APPEND core_srcs
"src/core/esp_rmaker_claim.c"
"src/core/esp_rmaker_claim.pb-c.c")
endif()
if(CONFIG_ESP_RMAKER_SELF_CLAIM)
list(APPEND core_srcs
"src/core/esp_rmaker_claim.c")

View File

@@ -15,9 +15,19 @@ menu "ESP RainMaker Config"
help
ESP RainMaker Claiming Service Base URL.
config ESP_RMAKER_ASSISTED_CLAIM
bool "Use Assisted Claiming"
depends on IDF_TARGET_ESP32 && BT_ENABLED
select MBEDTLS_HARDWARE_MPI
default y
help
Use Assisted Claiming i.e. get the MQTT credentials
from the claiming service via assistance from clients,
like the phone apps.
config ESP_RMAKER_MQTT_HOST
string "ESP RainMaker MQTT Host"
depends on ESP_RMAKER_SELF_CLAIM
depends on ESP_RMAKER_SELF_CLAIM || ESP_RMAKER_ASSISTED_CLAIM
default "a1p72mufdu6064-ats.iot.us-east-1.amazonaws.com"
help
ESP RainMaker MQTT Host name.

View File

@@ -2,8 +2,11 @@ COMPONENT_SRCDIRS := src/core src/mqtt src/ota src/standard_types src/console
COMPONENT_ADD_INCLUDEDIRS := include
COMPONENT_PRIV_INCLUDEDIRS := src/core src/ota src/console
ifndef CONFIG_ESP_RMAKER_ASSISTED_CLAIM
COMPONENT_OBJEXCLUDE += src/core/esp_rmaker_claim.pb-c.o
ifndef CONFIG_ESP_RMAKER_SELF_CLAIM
COMPONENT_OBJEXCLUDE += src/core/esp_rmaker_claim.o
endif
endif
COMPONENT_EMBED_TXTFILES := server_certs/mqtt_server.crt server_certs/claim_service_server.crt server_certs/ota_server.crt

View File

@@ -23,51 +23,45 @@
#include "mbedtls/md.h"
#include "mbedtls/sha512.h"
#include "soc/soc.h"
#include "soc/efuse_reg.h"
#include "esp_efuse.h"
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/event_groups.h>
#include <wifi_provisioning/manager.h>
#include <esp_event.h>
#include <esp_tls.h>
#include <esp_rmaker_core.h>
#include <string.h>
#include <esp_wifi.h>
#include <esp_log.h>
#include <esp_http_client.h>
#include <esp_rmaker_storage.h>
#include "esp_rmaker_client_data.h"
#include <json_generator.h>
#include <json_parser.h>
#include "esp_rmaker_internal.h"
#include "esp_rmaker_storage.h"
#include "esp_rmaker_client_data.h"
#include "esp_rmaker_claim.h"
static const char *TAG = "esp_claim";
#ifdef CONFIG_ESP_RMAKER_SELF_CLAIM
#include "soc/soc.h"
#include "soc/efuse_reg.h"
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#define CLAIM_BASE_URL CONFIG_ESP_RMAKER_CLAIM_SERVICE_BASE_URL
#define CLAIM_INIT_PATH "claim/initiate"
#define CLAIM_VERIFY_PATH "claim/verify"
#define CLAIM_PK_SIZE 2048
#define MAX_CSR_SIZE 1024
#define MAX_PAYLOAD_SIZE 3072
typedef struct {
unsigned char csr[MAX_CSR_SIZE];
char payload[MAX_PAYLOAD_SIZE];
mbedtls_pk_context key;
} esp_rmaker_claim_data_t;
esp_rmaker_claim_data_t *g_claim_data;
static EventGroupHandle_t self_claim_event_group;
static const int SELF_CLAIM_TASK_BIT = BIT0;
extern uint8_t claim_service_server_root_ca_pem_start[] asm("_binary_claim_service_server_crt_start");
extern uint8_t claim_service_server_root_ca_pem_end[] asm("_binary_claim_service_server_crt_end");
#endif /* CONFIG_ESP_RMAKER_SELF_CLAIM */
#define CLAIM_PK_SIZE 2048
static EventGroupHandle_t claim_event_group;
static const int CLAIM_TASK_BIT = BIT0;
static void escape_new_line(esp_rmaker_claim_data_t *data)
{
char *str = (char *)data->csr;
@@ -107,6 +101,167 @@ static void unescape_new_line(char *str)
*target_str = '\0';
}
static esp_err_t esp_rmaker_claim_generate_csr(esp_rmaker_claim_data_t *claim_data, const char *common_name)
{
if (!claim_data || !common_name) {
ESP_LOGE(TAG, "claim_data or common_name cannot be NULL.");
return ESP_ERR_INVALID_ARG;
}
const char *pers = "gen_csr";
mbedtls_x509write_csr csr;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_entropy_context entropy;
/* Generating CSR from the private key */
mbedtls_x509write_csr_init(&csr);
mbedtls_x509write_csr_set_md_alg(&csr, MBEDTLS_MD_SHA256);
mbedtls_ctr_drbg_init(&ctr_drbg);
ESP_LOGD(TAG, "Seeding the random number generator.");
mbedtls_entropy_init(&entropy);
int ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen(pers));
if (ret != 0) {
ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned -0x%04x", -ret );
goto exit;
}
char subject_name[50];
snprintf(subject_name, sizeof(subject_name), "CN=%s", common_name);
ret = mbedtls_x509write_csr_set_subject_name(&csr, subject_name);
if (ret != 0) {
ESP_LOGE(TAG, "mbedtls_x509write_csr_set_subject_name returned %d", ret );
goto exit;
}
memset(claim_data->csr, 0, sizeof(claim_data->csr));
mbedtls_x509write_csr_set_key(&csr, &claim_data->key);
ESP_LOGD(TAG, "Generating PEM");
ret = mbedtls_x509write_csr_pem(&csr, claim_data->csr, sizeof(claim_data->csr), mbedtls_ctr_drbg_random, &ctr_drbg);
if (ret < 0) {
ESP_LOGE(TAG, "mbedtls_x509write_csr_pem returned -0x%04x", -ret );
goto exit;
}
ESP_LOGD(TAG, "CSR generated.");
claim_data->state = RMAKER_CLAIM_STATE_CSR_GENERATED;
exit:
mbedtls_x509write_csr_free(&csr);
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
return ret;
}
static esp_err_t esp_rmaker_claim_generate_key(esp_rmaker_claim_data_t *claim_data)
{
const char *pers = "gen_key";
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_pk_free(&claim_data->key);
mbedtls_pk_init(&claim_data->key);
mbedtls_ctr_drbg_init(&ctr_drbg);
memset(claim_data->payload, 0, sizeof(claim_data->payload));
ESP_LOGD(TAG, "Seeding the random number generator.");
mbedtls_entropy_init(&entropy);
int ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen(pers));
if (ret != 0) {
ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned -0x%04x", -ret );
mbedtls_pk_free(&claim_data->key);
goto exit;
}
ESP_LOGW(TAG, "Generating the private key. This may take time." );
ret = mbedtls_pk_setup(&claim_data->key, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA));
if (ret != 0) {
ESP_LOGE(TAG, "mbedtls_pk_setup returned -0x%04x", -ret );
mbedtls_pk_free(&claim_data->key);
goto exit;
}
ret = mbedtls_rsa_gen_key(mbedtls_pk_rsa(claim_data->key), mbedtls_ctr_drbg_random, &ctr_drbg, CLAIM_PK_SIZE, 65537); /* here, 65537 is the RSA exponent */
if (ret != 0) {
ESP_LOGE(TAG, "mbedtls_rsa_gen_key returned -0x%04x", -ret );
mbedtls_pk_free(&claim_data->key);
goto exit;
}
claim_data->state = RMAKER_CLAIM_STATE_PK_GENERATED;
ESP_LOGD(TAG, "Converting Private Key to PEM...");
ret = mbedtls_pk_write_key_pem(&claim_data->key, (unsigned char *)claim_data->payload, sizeof(claim_data->payload));
if (ret != 0) {
ESP_LOGE(TAG, "mbedtls_pk_write_key_pem returned -0x%04x", -ret );
mbedtls_pk_free(&claim_data->key);
}
exit:
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
return ret;
}
/* Parse the Claim Init response and generate Claim Verify request
*
* Claim Verify Response format:
* {"certificate":"<certificate>"}
*/
static esp_err_t handle_claim_verify_response(esp_rmaker_claim_data_t *claim_data)
{
ESP_LOGD(TAG, "Claim Verify Response: %s", claim_data->payload);
jparse_ctx_t jctx;
if (json_parse_start(&jctx, claim_data->payload, strlen(claim_data->payload)) == 0) {
int required_len = 0;
if (json_obj_get_strlen(&jctx, "certificate", &required_len) == 0) {
required_len++; /* For NULL termination */
char *certificate = calloc(1, required_len);
if (!certificate) {
json_parse_end(&jctx);
ESP_LOGE(TAG, "Failed to allocate %d bytes for certificate.", required_len);
return ESP_ERR_NO_MEM;
}
json_obj_get_string(&jctx, "certificate", certificate, required_len);
json_parse_end(&jctx);
unescape_new_line(certificate);
esp_err_t err = esp_rmaker_storage_set(ESP_RMAKER_CLIENT_CERT_NVS_KEY, certificate, strlen(certificate));
free(certificate);
return err;
} else {
ESP_LOGE(TAG, "Claim Verify Response invalid.");
}
}
ESP_LOGE(TAG, "Failed to parse Claim Verify Response.");
return ESP_FAIL;
}
static esp_err_t generate_claim_init_request(esp_rmaker_claim_data_t *claim_data)
{
if (claim_data->state < RMAKER_CLAIM_STATE_PK_GENERATED) {
return ESP_ERR_INVALID_STATE;
}
uint8_t eth_mac[6];
esp_err_t err = esp_wifi_get_mac(WIFI_IF_STA, eth_mac);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Could not fetch MAC address. Please initialise Wi-Fi first");
return err;
}
snprintf(claim_data->payload, sizeof(claim_data->payload),
"{\"mac_addr\":\"%02X%02X%02X%02X%02X%02X\",\"platform\":\"%s\"}",
eth_mac[0], eth_mac[1], eth_mac[2], eth_mac[3], eth_mac[4], eth_mac[5], CONFIG_IDF_TARGET);
claim_data->payload_len = strlen(claim_data->payload);
claim_data->payload_offset = 0;
return ESP_OK;
}
void esp_rmaker_claim_data_free(esp_rmaker_claim_data_t *claim_data)
{
if(claim_data) {
mbedtls_pk_free(&claim_data->key);
free(claim_data);
}
}
#ifdef CONFIG_ESP_RMAKER_SELF_CLAIM
static esp_err_t read_hmac_key(uint32_t *out_hmac_key, size_t hmac_key_size)
{
/* ESP32-S2 HMAC Key programming scheme */
@@ -153,7 +308,7 @@ static esp_err_t hmac_challenge(const char* hmac_request, unsigned char *hmac_re
* Claim Verify Request format
* {"auth_id":"<claim-id-from-init>", "challenge_response":"<64byte-response-in-hex>, "csr":"<csr-generated-earlier>"}
*/
static esp_err_t handle_claim_init_response(esp_rmaker_claim_data_t *claim_data)
static esp_err_t handle_self_claim_init_response(esp_rmaker_claim_data_t *claim_data)
{
ESP_LOGD(TAG, "Claim Init Response: %s", claim_data->payload);
jparse_ctx_t jctx;
@@ -192,39 +347,6 @@ static esp_err_t handle_claim_init_response(esp_rmaker_claim_data_t *claim_data)
ESP_LOGE(TAG, "Failed to parse Claim Init Response.");
return ESP_FAIL;
}
/* Parse the Claim Init response and generate Claim Verify request
*
* Claim Verify Response format:
* {"certificate":"<certificate>"}
*/
static esp_err_t handle_claim_verify_response(esp_rmaker_claim_data_t *claim_data)
{
ESP_LOGD(TAG, "Claim Verify Response: %s", claim_data->payload);
jparse_ctx_t jctx;
if (json_parse_start(&jctx, claim_data->payload, strlen(claim_data->payload)) == 0) {
int required_len = 0;
if (json_obj_get_strlen(&jctx, "certificate", &required_len) == 0) {
required_len++; /* For NULL termination */
char *certificate = calloc(1, required_len);
if (!certificate) {
json_parse_end(&jctx);
ESP_LOGE(TAG, "Failed to allocate %d bytes for certificate.", required_len);
return ESP_ERR_NO_MEM;
}
json_obj_get_string(&jctx, "certificate", certificate, required_len);
json_parse_end(&jctx);
unescape_new_line(certificate);
esp_err_t err = esp_rmaker_storage_set(ESP_RMAKER_CLIENT_CERT_NVS_KEY, certificate, strlen(certificate));
free(certificate);
return err;
} else {
ESP_LOGE(TAG, "Claim Verify Response invalid.");
}
}
ESP_LOGE(TAG, "Failed to parse Claim Verify Response.");
return ESP_FAIL;
}
static esp_err_t esp_rmaker_claim_perform_common(esp_rmaker_claim_data_t *claim_data, const char *path)
{
char url[100];
@@ -280,12 +402,22 @@ static esp_err_t esp_rmaker_claim_perform_common(esp_rmaker_claim_data_t *claim_
}
static esp_err_t esp_rmaker_claim_perform_init(esp_rmaker_claim_data_t *claim_data)
{
esp_err_t err = esp_rmaker_claim_perform_common(claim_data, CLAIM_INIT_PATH);
esp_err_t err = generate_claim_init_request(claim_data);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to generate Claim init request");
return err;
}
err = esp_rmaker_claim_perform_common(claim_data, CLAIM_INIT_PATH);
if (err != OK) {
ESP_LOGE(TAG, "Claim Init Request Failed.");
return err;
}
err = handle_claim_init_response(claim_data);
claim_data->state = RMAKER_CLAIM_STATE_INIT;
err = handle_self_claim_init_response(claim_data);
if (err == ESP_OK) {
claim_data->state = RMAKER_CLAIM_STATE_INIT_DONE;
}
return err;
}
@@ -296,175 +428,390 @@ static esp_err_t esp_rmaker_claim_perform_verify(esp_rmaker_claim_data_t *claim_
ESP_LOGE(TAG, "Claim Verify Failed.");
return err;
}
claim_data->state = RMAKER_CLAIM_STATE_VERIFY;
err = handle_claim_verify_response(claim_data);
if (err == ESP_OK) {
claim_data->state = RMAKER_CLAIM_STATE_VERIFY_DONE;
}
return err;
}
esp_err_t esp_rmaker_self_claim_perform(void)
esp_err_t esp_rmaker_self_claim_perform(esp_rmaker_claim_data_t *claim_data)
{
ESP_LOGI(TAG, "Starting the Self Claim Process. This may take time.");
if (g_claim_data == NULL) {
if (claim_data == NULL) {
ESP_LOGE(TAG, "Self claiming not initialised.");
return ESP_ERR_INVALID_STATE;
}
esp_err_t err = esp_rmaker_claim_perform_init(g_claim_data);
esp_err_t err = esp_rmaker_claim_perform_init(claim_data);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Claim Init Sequence Failed.");
return err;
}
err = esp_rmaker_claim_perform_verify(g_claim_data);
err = esp_rmaker_claim_perform_verify(claim_data);
if (err == ESP_OK) {
ESP_LOGI(TAG, "Self Claiming was successful. Certificate received.");
ESP_LOGW(TAG, "The first MQTT connection attempt may fail. The subsequent ones should work.");
}
free(g_claim_data);
g_claim_data = NULL;
esp_rmaker_claim_data_free(claim_data);
return err;
}
static esp_err_t generate_key(esp_rmaker_claim_data_t *claim_data)
#endif /* CONFIG_ESP_RMAKER_SELF_CLAIM */
#ifdef CONFIG_ESP_RMAKER_ASSISTED_CLAIM
static EventGroupHandle_t claim_csr_event_group;
static const int CLAIM_CSR_TASK_BIT = BIT1;
static void esp_rmaker_claim_csr_task(void *args)
{
const char *pers = "gen_key";
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_pk_free(&claim_data->key);
mbedtls_pk_init(&claim_data->key);
mbedtls_ctr_drbg_init(&ctr_drbg);
memset(claim_data->payload, 0, sizeof(claim_data->payload));
ESP_LOGD(TAG, "Seeding the random number generator.");
mbedtls_entropy_init(&entropy);
int ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen(pers));
if (ret != 0) {
ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned -0x%04x", -ret );
mbedtls_pk_free(&claim_data->key);
goto exit;
esp_rmaker_claim_data_t *claim_data = (esp_rmaker_claim_data_t *)args;
esp_rmaker_claim_generate_csr(claim_data, esp_rmaker_get_node_id());
xEventGroupSetBits(claim_csr_event_group, CLAIM_CSR_TASK_BIT);
vTaskDelete(NULL);
}
static esp_err_t _esp_rmaker_claim_generate_csr(esp_rmaker_claim_data_t *claim_data)
{
claim_csr_event_group = xEventGroupCreate();
if (!claim_csr_event_group) {
ESP_LOGE(TAG, "Couldn't create CSR event group.");
return ESP_ERR_NO_MEM;
}
ESP_LOGD(TAG, "Generating the private key..." );
ret = mbedtls_pk_setup(&claim_data->key, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA));
if (ret != 0) {
ESP_LOGE(TAG, "mbedtls_pk_setup returned -0x%04x", -ret );
mbedtls_pk_free(&claim_data->key);
goto exit;
#define ESP_RMAKER_CLAIM_CSR_TASK_STACK_SIZE (10 * 1024)
if (xTaskCreate(&esp_rmaker_claim_csr_task, "claim_csr_task", ESP_RMAKER_CLAIM_CSR_TASK_STACK_SIZE,
claim_data, (CONFIG_ESP_RMAKER_TASK_PRIORITY + 1), NULL) != pdPASS) {
ESP_LOGE(TAG, "Couldn't create CSR generation task");
vEventGroupDelete(claim_csr_event_group);
return ESP_ERR_NO_MEM;
}
ret = mbedtls_rsa_gen_key(mbedtls_pk_rsa(claim_data->key), mbedtls_ctr_drbg_random, &ctr_drbg, CLAIM_PK_SIZE, 65537); /* here, 65537 is the RSA exponent */
if (ret != 0) {
ESP_LOGE(TAG, "mbedtls_rsa_gen_key returned -0x%04x", -ret );
mbedtls_pk_free(&claim_data->key);
goto exit;
/* Wait for claim init to complete */
xEventGroupWaitBits(claim_csr_event_group, CLAIM_CSR_TASK_BIT, false, true, portMAX_DELAY);
if (claim_data->state == RMAKER_CLAIM_STATE_CSR_GENERATED) {
return ESP_OK;
}
return ESP_FAIL;
}
/* Parse the Claim Init response and generate Claim Verify request
*
* Claim Init Response format:
* {"node_id":"<unique-node-id>"}
*
* Claim Verify Request format
* {"csr":"<csr-generated>"}
*/
static esp_err_t handle_assisted_claim_init_response(esp_rmaker_claim_data_t *claim_data)
{
ESP_LOGD(TAG, "Claim Init Response: %s", claim_data->payload);
jparse_ctx_t jctx;
if (json_parse_start(&jctx, claim_data->payload, strlen(claim_data->payload)) == 0) {
char node_id[64];
int ret = json_obj_get_string(&jctx, "node_id", node_id, sizeof(node_id));
json_parse_end(&jctx);
if (ret == 0) {
esp_rmaker_storage_set("node_id", node_id, strlen(node_id));
esp_rmaker_change_node_id(node_id, strlen(node_id));
/* We use _esp_rmaker_claim_generate_csr instead of esp_rmaker_claim_generate_csr()
* because the thread in whose context this function is called doesn't have
* enough stack memory to generate CSR. A new thread with larger stack is spawned
* to generate the CSR by the below function.
*/
esp_err_t err = _esp_rmaker_claim_generate_csr(claim_data);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to generate CSR.");
return err;
}
escape_new_line(claim_data);
ESP_LOGD(TAG, "Converting Private Key to PEM...");
ret = mbedtls_pk_write_key_pem(&claim_data->key, (unsigned char *)claim_data->payload, sizeof(claim_data->payload));
if (ret != 0) {
ESP_LOGE(TAG, "mbedtls_pk_write_key_pem returned -0x%04x", -ret );
mbedtls_pk_free(&claim_data->key);
goto exit;
json_gen_str_t jstr;
json_gen_str_start(&jstr, claim_data->payload, sizeof(claim_data->payload), NULL, NULL);
json_gen_start_object(&jstr);
json_gen_obj_set_string(&jstr, "csr", (char *)claim_data->csr);
json_gen_end_object(&jstr);
json_gen_str_end(&jstr);
claim_data->payload_len = strlen(claim_data->payload);
claim_data->payload_offset = 0;
return ESP_OK;
} else {
ESP_LOGE(TAG, "Claim Init Response invalid.");
}
}
exit:
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
return ret;
ESP_LOGE(TAG, "Failed to parse Claim Init Response.");
return ESP_FAIL;
}
#include <esp_rmaker_claim.pb-c.h>
#define CLAIM_FRAGMENT_SIZE 200
esp_err_t esp_rmaker_assisted_claim_handle_start(RmakerClaim__RMakerClaimPayload *command,
RmakerClaim__RMakerClaimPayload *response, esp_rmaker_claim_data_t *claim_data)
{
if (claim_data->state < RMAKER_CLAIM_STATE_PK_GENERATED) {
ESP_LOGE(TAG, "PK not created. Cannot proceed with Assisted Claiming.");
response->resppayload->status = RMAKER_CLAIM__RMAKER_CLAIM_STATUS__InvalidState;
return ESP_OK;
}
if (generate_claim_init_request(claim_data) != ESP_OK) {
return ESP_OK;
}
RmakerClaim__PayloadBuf *payload_buf = response->resppayload->buf;
payload_buf->offset = 0;
payload_buf->totallen = claim_data->payload_len;
payload_buf->payload.data = (uint8_t *)claim_data->payload;
payload_buf->payload.len = claim_data->payload_len;
response->resppayload->status = RMAKER_CLAIM__RMAKER_CLAIM_STATUS__Success;
claim_data->state = RMAKER_CLAIM_STATE_INIT;
ESP_LOGI(TAG, "Assisted Claiming Started.");
return ESP_OK;
}
static esp_err_t generate_csr(esp_rmaker_claim_data_t *claim_data)
/* Return ESP_OK if this is just an application layer error. The response content will
* indicate error to the client.
*/
ProtobufCBinaryData *esp_rmaker_assisted_claim_validate_data(RmakerClaim__PayloadBuf *recv_payload,
RmakerClaim__RMakerClaimPayload *response, esp_rmaker_claim_data_t *claim_data)
{
const char *pers = "gen_csr";
mbedtls_x509write_csr csr;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_entropy_context entropy;
/* Generating CSR from the private key */
mbedtls_x509write_csr_init(&csr);
mbedtls_x509write_csr_set_md_alg(&csr, MBEDTLS_MD_SHA256);
mbedtls_ctr_drbg_init(&ctr_drbg);
ESP_LOGD(TAG, "Seeding the random number generator.");
mbedtls_entropy_init(&entropy);
int ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen(pers));
if (ret != 0) {
ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned -0x%04x", -ret );
goto exit;
if (recv_payload == NULL) {
ESP_LOGE(TAG, "Empty response received. Cannot proceed.");
response->resppayload->status = RMAKER_CLAIM__RMAKER_CLAIM_STATUS__InvalidParam;
return NULL;
}
char subject_name[20];
snprintf(subject_name, sizeof(subject_name), "CN=%s", esp_rmaker_get_node_id());
ret = mbedtls_x509write_csr_set_subject_name(&csr, subject_name);
if (ret != 0) {
ESP_LOGE(TAG, "mbedtls_x509write_csr_set_subject_name returned %d", ret );
goto exit;
/* Read the command */
ProtobufCBinaryData *recv_payload_buf = &recv_payload->payload;
if (!recv_payload_buf) {
ESP_LOGE(TAG, "No data received. Cannot proceed.");
response->resppayload->status = RMAKER_CLAIM__RMAKER_CLAIM_STATUS__InvalidParam;
return NULL;
}
memset(claim_data->csr, 0, sizeof(claim_data->csr));
mbedtls_x509write_csr_set_key(&csr, &claim_data->key);
ESP_LOGD(TAG, "Generating PEM");
ret = mbedtls_x509write_csr_pem(&csr, claim_data->csr, sizeof(claim_data->csr), mbedtls_ctr_drbg_random, &ctr_drbg);
if (ret < 0) {
ESP_LOGE(TAG, "mbedtls_x509write_csr_pem returned -0x%04x", -ret );
goto exit;
if ((recv_payload_buf->len + recv_payload->offset) > recv_payload->totallen) {
ESP_LOGE(TAG, "Received data exceeds total length.");
response->resppayload->status = RMAKER_CLAIM__RMAKER_CLAIM_STATUS__InvalidParam;
return NULL;
}
ESP_LOGD(TAG, "CSR generated.");
exit:
mbedtls_x509write_csr_free(&csr);
mbedtls_pk_free(&claim_data->key);
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
return ret;
if (recv_payload_buf->len >= sizeof(claim_data->payload)) {
ESP_LOGE(TAG, "Received data too long (%d bytes).", recv_payload_buf->len);
response->resppayload->status = RMAKER_CLAIM__RMAKER_CLAIM_STATUS__NoMemory;
return NULL;
}
return recv_payload_buf;
}
esp_err_t __esp_rmaker_self_claim_init(void)
/* Return ESP_OK if this is just an application layer error. The response content will
* indicate error to the client.
*/
esp_err_t esp_rmaker_assisted_claim_handle_init(RmakerClaim__RMakerClaimPayload *command,
RmakerClaim__RMakerClaimPayload *response, esp_rmaker_claim_data_t *claim_data)
{
if (claim_data->state < RMAKER_CLAIM_STATE_INIT) {
ESP_LOGE(TAG, "Claiming hasn't started. Cannot proceed with init handling.");
response->resppayload->status = RMAKER_CLAIM__RMAKER_CLAIM_STATUS__InvalidState;
return ESP_OK;
} else if (claim_data->state != RMAKER_CLAIM_STATE_INIT_DONE) {
if (command->payload_case != RMAKER_CLAIM__RMAKER_CLAIM_PAYLOAD__PAYLOAD_CMD_PAYLOAD) {
ESP_LOGE(TAG, "Invalid response received for Claim Init. Cannot proceed.");
response->resppayload->status = RMAKER_CLAIM__RMAKER_CLAIM_STATUS__InvalidParam;
return ESP_OK;
}
RmakerClaim__PayloadBuf *recv_payload = command->cmdpayload;
ProtobufCBinaryData *recv_payload_buf = esp_rmaker_assisted_claim_validate_data
(recv_payload, response, claim_data);
if (!recv_payload_buf) {
ESP_LOGE(TAG, "Failed to get Claim Init Data.");
return ESP_OK;
}
if (recv_payload_buf->len != recv_payload->totallen) {
ESP_LOGE(TAG, "Claim Init Data length not equal to total length. Cannot proceed.");
response->resppayload->status = RMAKER_CLAIM__RMAKER_CLAIM_STATUS__InvalidParam;
return ESP_OK;
}
memset(claim_data->payload, 0, sizeof(claim_data->payload));
memcpy(claim_data->payload, recv_payload_buf->data, recv_payload_buf->len);
if (handle_assisted_claim_init_response(claim_data) != ESP_OK) {
response->resppayload->status = RMAKER_CLAIM__RMAKER_CLAIM_STATUS__InvalidParam;
ESP_LOGE(TAG, "Error handling Claim Init response.");
return ESP_OK;
} else {
claim_data->state = RMAKER_CLAIM_STATE_INIT_DONE;
}
}
RmakerClaim__PayloadBuf *payload_buf = response->resppayload->buf;
payload_buf->totallen = claim_data->payload_len;
payload_buf->offset = claim_data->payload_offset;
payload_buf->payload.data = (uint8_t *)claim_data->payload + claim_data->payload_offset;
payload_buf->payload.len = (claim_data->payload_len - claim_data->payload_offset) > CLAIM_FRAGMENT_SIZE ?
CLAIM_FRAGMENT_SIZE : (claim_data->payload_len - claim_data->payload_offset);
claim_data->payload_offset += payload_buf->payload.len;
response->resppayload->status = RMAKER_CLAIM__RMAKER_CLAIM_STATUS__Success;
if (claim_data->payload_offset == claim_data->payload_len) {
ESP_LOGD(TAG, "Finished sending Claim Verify Payload.");
claim_data->state = RMAKER_CLAIM_STATE_VERIFY;
}
return ESP_OK;
}
/* Return ESP_OK if this is just an application layer error. The response content will
* indicate error to the client.
*/
esp_err_t esp_rmaker_assisted_claim_handle_verify(RmakerClaim__RMakerClaimPayload *command,
RmakerClaim__RMakerClaimPayload *response, esp_rmaker_claim_data_t *claim_data)
{
if (claim_data->state < RMAKER_CLAIM_STATE_VERIFY) {
ESP_LOGE(TAG, "Invalid state. Cannot proceed with verify handling.");
response->resppayload->status = RMAKER_CLAIM__RMAKER_CLAIM_STATUS__InvalidState;
return ESP_OK;
}
if (command->payload_case != RMAKER_CLAIM__RMAKER_CLAIM_PAYLOAD__PAYLOAD_CMD_PAYLOAD) {
ESP_LOGE(TAG, "Invalid response received for Claim Verify. Cannot proceed.");
response->resppayload->status = RMAKER_CLAIM__RMAKER_CLAIM_STATUS__InvalidParam;
return ESP_OK;
}
RmakerClaim__PayloadBuf *recv_payload = command->cmdpayload;
ProtobufCBinaryData *recv_payload_buf = esp_rmaker_assisted_claim_validate_data
(recv_payload, response, claim_data);
if (!recv_payload_buf) {
ESP_LOGE(TAG, "Failed to get Claim Verify Data.");
return ESP_OK;
}
/* If offset is 0, this is the start of the fragmented data. */
if (recv_payload->offset == 0) {
memset(claim_data->payload, 0, sizeof(claim_data->payload));
claim_data->payload_offset = 0;
claim_data->payload_len = 0;
}
claim_data->payload_offset = recv_payload->offset;
memcpy(claim_data->payload + claim_data->payload_offset, recv_payload_buf->data, recv_payload_buf->len);
claim_data->payload_len += recv_payload_buf->len;
if ((recv_payload->offset + recv_payload_buf->len) == recv_payload->totallen) {
ESP_LOGD(TAG, "Received complete response of len = %d bytes for Claim Verify", recv_payload->totallen);
if (handle_claim_verify_response(claim_data) == ESP_OK) {
ESP_LOGI(TAG,"Assisted Claiming was Successful.");
claim_data->state = RMAKER_CLAIM_STATE_VERIFY_DONE;
if (claim_event_group) {
xEventGroupSetBits(claim_event_group, CLAIM_TASK_BIT);
}
} else {
response->resppayload->status = RMAKER_CLAIM__RMAKER_CLAIM_STATUS__InvalidParam;
return ESP_OK;
}
}
response->resppayload->status = RMAKER_CLAIM__RMAKER_CLAIM_STATUS__Success;
return ESP_OK;
}
esp_err_t esp_rmaker_claiming_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, uint8_t **outbuf, ssize_t *outlen, void *priv_data)
{
esp_rmaker_claim_data_t *claim_data = (esp_rmaker_claim_data_t *)priv_data;
if (!priv_data) {
ESP_LOGE(TAG, "Claim data cannot be NULL. Cannot proceed with Assisted Claiming.");
return ESP_ERR_INVALID_STATE;
}
RmakerClaim__RMakerClaimPayload *command;
command = rmaker_claim__rmaker_claim_payload__unpack(NULL, inlen, inbuf);
if (!command) {
ESP_LOGE(TAG, "No Claim command received");
return ESP_ERR_INVALID_ARG;
}
/* Initialise the response objects */
RmakerClaim__RMakerClaimPayload response;
rmaker_claim__rmaker_claim_payload__init(&response);
response.msg = command->msg + 1;
response.payload_case = RMAKER_CLAIM__RMAKER_CLAIM_PAYLOAD__PAYLOAD_RESP_PAYLOAD;
RmakerClaim__RespPayload resppayload;
rmaker_claim__resp_payload__init(&resppayload);
resppayload.status = RMAKER_CLAIM__RMAKER_CLAIM_STATUS__Fail;
response.resppayload = &resppayload;
RmakerClaim__PayloadBuf payload_buf;
rmaker_claim__payload_buf__init(&payload_buf);
resppayload.buf = &payload_buf;
ESP_LOGD(TAG, "Received claim command: %d", command->msg);
/* Handle the received command */
switch (command->msg) {
case RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeCmdClaimStart:
esp_rmaker_assisted_claim_handle_start(command, &response, claim_data);
break;
case RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeCmdClaimInit:
esp_rmaker_assisted_claim_handle_init(command, &response, claim_data);
break;
case RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeCmdClaimVerify:
esp_rmaker_assisted_claim_handle_verify(command, &response, claim_data);
break;
case RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeCmdClaimAbort:
memset(claim_data->payload, 0, sizeof(claim_data->payload));
claim_data->payload_len = 0;
claim_data->payload_offset = 0;
/* Go back to RMAKER_CLAIM_STATE_PK_GENERATED, so that claim can restart */
claim_data->state = RMAKER_CLAIM_STATE_PK_GENERATED;
resppayload.status = RMAKER_CLAIM__RMAKER_CLAIM_STATUS__Success;
ESP_LOGW(TAG, "Assisted Claiming Aborted.");
break;
default:
break;
}
*outlen = rmaker_claim__rmaker_claim_payload__get_packed_size(&response);
*outbuf = (uint8_t *)malloc(*outlen);
rmaker_claim__rmaker_claim_payload__pack(&response, *outbuf);
rmaker_claim__rmaker_claim_payload__free_unpacked(command, NULL);
return ESP_OK;
}
#define CLAIM_ENDPOINT "rmaker_claim"
static void event_handler(void* arg, esp_event_base_t event_base,
int event_id, void* event_data)
{
if (event_base == WIFI_PROV_EVENT) {
switch (event_id) {
case WIFI_PROV_INIT: {
static const char *capabilities[] = {"claim"};
wifi_prov_mgr_set_app_info("rmaker", "1.0", capabilities, 1);
if (wifi_prov_mgr_endpoint_create(CLAIM_ENDPOINT) != ESP_OK) {
ESP_LOGE(TAG, "Failed to create claim end point.");
}
break;
}
case WIFI_PROV_START:
if (wifi_prov_mgr_endpoint_register(CLAIM_ENDPOINT, esp_rmaker_claiming_handler, arg) != ESP_OK) {
ESP_LOGE(TAG, "Failed to register claim end point.");
}
break;
default:
break;
}
}
}
#endif /* CONFIG_ESP_RMAKER_ASSISTED_CLAIM */
esp_err_t __esp_rmaker_claim_init(esp_rmaker_claim_data_t *claim_data)
{
char hexstr[9];
uint32_t my_random;
esp_err_t err;
ESP_LOGI(TAG, "Initialising Self Claiming. This may take time.");
/* Check if the claim data structure is already allocated. If yes, free it */
if (g_claim_data) {
free(g_claim_data);
g_claim_data = NULL;
char *key = esp_rmaker_get_client_key();
if (key) {
mbedtls_pk_free(&claim_data->key);
mbedtls_pk_init(&claim_data->key);
if (mbedtls_pk_parse_key(&claim_data->key, (uint8_t *)key, strlen(key) + 1, NULL, 0) == 0) {
ESP_LOGI(TAG, "Private key already exists. No need to re-initialise it.");
claim_data->state = RMAKER_CLAIM_STATE_PK_GENERATED;
}
free(key);
}
/* Allocate memory for the claim data */
g_claim_data = calloc(1, sizeof(esp_rmaker_claim_data_t));
if (!g_claim_data) {
ESP_LOGE(TAG, "Failed to allocate %d bytes for Claim data.", sizeof(esp_rmaker_claim_data_t));
return ESP_ERR_NO_MEM;
if (claim_data->state != RMAKER_CLAIM_STATE_PK_GENERATED) {
/* Generate the Private Key */
err = esp_rmaker_claim_generate_key(claim_data);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to generate private key.");
return err;
}
err = esp_rmaker_storage_set(ESP_RMAKER_CLIENT_KEY_NVS_KEY, claim_data->payload, strlen((char *)claim_data->payload));
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to save private key to storage.");
return err;
}
}
/* Check if the CSR is already available. If yes, just generate the payload for claim init
* and return from here instead of re-generating the key and CSR
*/
void *csr = esp_rmaker_get_client_csr();
if (csr) {
snprintf(g_claim_data->payload, sizeof(g_claim_data->payload), "{\"mac_addr\":\"%s\",\"platform\":\"esp32s2\"}",
esp_rmaker_get_node_id());
strncpy((char *)g_claim_data->csr, csr, (sizeof(g_claim_data->csr) - 1));
g_claim_data->csr[sizeof(g_claim_data->csr) - 1] = 0;
free(csr);
ESP_LOGI(TAG, "CSR already exists. No need to re-initialise Claiming.");
return ESP_OK;
}
/* Generate the Private Key */
err = generate_key(g_claim_data);
if (err != ESP_OK) {
free(g_claim_data);
g_claim_data = NULL;
ESP_LOGE(TAG, "Failed to generate private key.");
return err;
}
/* Store the key in the storage */
ESP_LOGD(TAG, "Storing private key to NVS...");
err = esp_rmaker_storage_set(ESP_RMAKER_CLIENT_KEY_NVS_KEY, g_claim_data->payload, strlen((char *)g_claim_data->payload));
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to store private key to storage.");
free(g_claim_data);
g_claim_data = NULL;
}
/* Generate random hex string */
memset(hexstr, 0, sizeof(hexstr));
esp_fill_random(&my_random, sizeof(my_random));
@@ -473,74 +820,115 @@ esp_err_t __esp_rmaker_self_claim_init(void)
/* Store the PoP in the storage */
err = esp_rmaker_storage_set(ESP_RMAKER_CLIENT_RANDOM_NVS_KEY, hexstr, strlen(hexstr));
if (err != ESP_OK) {
free(g_claim_data);
g_claim_data = NULL;
ESP_LOGE(TAG, "Failed to store random number to storage");
return err;
}
/* Generate CSR */
err = generate_csr(g_claim_data);
ESP_LOGD(TAG, "CSR generated successfully.");
#ifdef CONFIG_ESP_RMAKER_SELF_CLAIM
err = esp_rmaker_claim_generate_csr(claim_data, esp_rmaker_get_node_id());
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to generate CSR for Claiming");
free(g_claim_data);
g_claim_data = NULL;
ESP_LOGE(TAG, "Failed to generate CSR.");
return err;
}
/* New line characters from the CSR need to be removed and replaced with explicit \n for the claiming
/* New line characters from the CSR need to be removed and replaced with explicit \n for the claiming
* service to parse properly. Make that change here and store the CSR in storage.
*/
escape_new_line(g_claim_data);
err = esp_rmaker_storage_set(ESP_RMAKER_CLIENT_CSR_NVS_KEY, g_claim_data->csr, strlen((char *)g_claim_data->csr));
if (err != ESP_OK) {
free(g_claim_data);
g_claim_data = NULL;
return err;
} else {
ESP_LOGI(TAG, "Self Claiming initialised successfully.");
}
snprintf(g_claim_data->payload, sizeof(g_claim_data->payload), "{\"mac_addr\":\"%s\",\"platform\":\"esp32s2\"}",
esp_rmaker_get_node_id());
escape_new_line(claim_data);
#endif /* CONFIG_ESP_RMAKER_SELF_CLAIM */
return err;
}
void esp_rmaker_self_claim_task(void *args)
void esp_rmaker_claim_task(void *args)
{
esp_err_t err = __esp_rmaker_self_claim_init();
if (args) {
*((esp_err_t *)args) = err;
if (!args) {
ESP_LOGE(TAG, "Arguments for claiming task cannot be NULL");
return;
}
xEventGroupSetBits(self_claim_event_group, SELF_CLAIM_TASK_BIT);
esp_rmaker_claim_data_t *claim_data = calloc(1, sizeof(esp_rmaker_claim_data_t));
if (!claim_data) {
ESP_LOGE(TAG, "Failed to allocate memory for claim data.");
return;
}
if (__esp_rmaker_claim_init(claim_data) != ESP_OK) {
esp_rmaker_claim_data_free(claim_data);
} else {
*((esp_rmaker_claim_data_t **)args) = claim_data;
}
xEventGroupSetBits(claim_event_group, CLAIM_TASK_BIT);
vTaskDelete(NULL);
}
esp_err_t esp_rmaker_self_claim_init(void)
static esp_rmaker_claim_data_t *esp_rmaker_claim_init(void)
{
self_claim_event_group = xEventGroupCreate();
if (!self_claim_event_group) {
static bool claim_init_done;
if (claim_init_done) {
ESP_LOGE(TAG, "Claim already initialised");
return NULL;
}
claim_event_group = xEventGroupCreate();
if (!claim_event_group) {
ESP_LOGE(TAG, "Couldn't create event group");
return NULL;
}
esp_rmaker_claim_data_t *claim_data = NULL;
#define ESP_RMAKER_CLAIM_TASK_STACK_SIZE (10 * 1024)
/* Using tskIDLE_PRIORITY so that the time consuming tasks, especially
* PK generation does not trigger task WatchDog timer.
*/
if (xTaskCreate(&esp_rmaker_claim_task, "claim_task", ESP_RMAKER_CLAIM_TASK_STACK_SIZE,
&claim_data, tskIDLE_PRIORITY, NULL) != pdPASS) {
ESP_LOGE(TAG, "Couldn't create Claim task");
vEventGroupDelete(claim_event_group);
return NULL;
}
/* Wait for claim init to complete */
xEventGroupWaitBits(claim_event_group, CLAIM_TASK_BIT, false, true, portMAX_DELAY);
vEventGroupDelete(claim_event_group);
claim_event_group = NULL;
return claim_data;
}
#ifdef CONFIG_ESP_RMAKER_SELF_CLAIM
esp_rmaker_claim_data_t *esp_rmaker_self_claim_init(void)
{
ESP_LOGI(TAG, "Initialising Self Claiming. This may take time.");
return esp_rmaker_claim_init();
}
#endif
#ifdef CONFIG_ESP_RMAKER_ASSISTED_CLAIM
esp_err_t esp_rmaker_assisted_claim_perform(esp_rmaker_claim_data_t *claim_data)
{
if (claim_data == NULL) {
ESP_LOGE(TAG, "Assisted claiming not initialised.");
return ESP_ERR_INVALID_STATE;
}
claim_event_group = xEventGroupCreate();
if (!claim_event_group) {
ESP_LOGE(TAG, "Couldn't create event group");
return ESP_ERR_NO_MEM;
}
esp_err_t *err = (esp_err_t *)calloc(1, sizeof(esp_err_t));
if (!err) {
ESP_LOGE(TAG, "Couldn't allocate err");
vEventGroupDelete(self_claim_event_group);
return ESP_ERR_NO_MEM;
/* Wait for assisted claim to complete */
ESP_LOGI(TAG, "Waiting for assisted claim to finish.");
xEventGroupWaitBits(claim_event_group, CLAIM_TASK_BIT, false, true, portMAX_DELAY);
esp_err_t err = ESP_FAIL;
if (claim_data->state == RMAKER_CLAIM_STATE_VERIFY_DONE) {
err = ESP_OK;
}
#define ESP_RMAKER_SELF_CLAIM_TASK_STACK_SIZE (10 * 1024)
if (xTaskCreate(&esp_rmaker_self_claim_task, "self_claim_task", ESP_RMAKER_SELF_CLAIM_TASK_STACK_SIZE, err, (CONFIG_ESP_RMAKER_TASK_PRIORITY + 1), NULL) != pdPASS) {
ESP_LOGE(TAG, "Couldn't create Self Claim task");
free(err);
vEventGroupDelete(self_claim_event_group);
return ESP_ERR_NO_MEM;
}
/* Wait for self claim to complete */
xEventGroupWaitBits(self_claim_event_group, SELF_CLAIM_TASK_BIT, false, true, portMAX_DELAY);
esp_err_t ret = *err;
free(err);
vEventGroupDelete(self_claim_event_group);
return ret;
esp_event_handler_unregister(WIFI_PROV_EVENT, WIFI_PROV_INIT, &event_handler);
esp_event_handler_unregister(WIFI_PROV_EVENT, WIFI_PROV_START, &event_handler);
esp_rmaker_claim_data_free(claim_data);
vEventGroupDelete(claim_event_group);
return err;
}
esp_rmaker_claim_data_t *esp_rmaker_assisted_claim_init(void)
{
ESP_LOGI(TAG, "Initialising Assisted Claiming. This may take time.");
esp_rmaker_claim_data_t *claim_data = esp_rmaker_claim_init();
if (claim_data) {
esp_event_handler_register(WIFI_PROV_EVENT, WIFI_PROV_INIT, &event_handler, claim_data);
esp_event_handler_register(WIFI_PROV_EVENT, WIFI_PROV_START, &event_handler, claim_data);
}
return claim_data;
}
#endif

View File

@@ -12,6 +12,38 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <mbedtls/pk.h>
#include <esp_err.h>
esp_err_t esp_rmaker_self_claim_init(void);
esp_err_t esp_rmaker_self_claim_perform(void);
#define MAX_CSR_SIZE 1024
#define MAX_PAYLOAD_SIZE 3072
typedef enum {
RMAKER_CLAIM_STATE_PK_GENERATED = 1,
RMAKER_CLAIM_STATE_INIT,
RMAKER_CLAIM_STATE_INIT_DONE,
RMAKER_CLAIM_STATE_CSR_GENERATED,
RMAKER_CLAIM_STATE_VERIFY,
RMAKER_CLAIM_STATE_VERIFY_DONE,
} esp_rmaker_claim_state_t;
typedef struct {
esp_rmaker_claim_state_t state;
unsigned char csr[MAX_CSR_SIZE];
char payload[MAX_PAYLOAD_SIZE];
size_t payload_offset;
size_t payload_len;
mbedtls_pk_context key;
} esp_rmaker_claim_data_t;
#ifdef CONFIG_ESP_RMAKER_SELF_CLAIM
esp_rmaker_claim_data_t * esp_rmaker_self_claim_init(void);
esp_err_t esp_rmaker_self_claim_perform(esp_rmaker_claim_data_t *claim_data);
#endif
#ifdef CONFIG_ESP_RMAKER_ASSISTED_CLAIM
esp_rmaker_claim_data_t * esp_rmaker_assisted_claim_init(void);
esp_err_t esp_rmaker_assisted_claim_perform(esp_rmaker_claim_data_t *claim_data);
#endif
void esp_rmaker_claim_data_free(esp_rmaker_claim_data_t *claim_data);

View File

@@ -0,0 +1,398 @@
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
/* Generated from: esp_rmaker_claim.proto */
/* Do not generate deprecated warnings for self */
#ifndef PROTOBUF_C__NO_DEPRECATED
#define PROTOBUF_C__NO_DEPRECATED
#endif
#include "esp_rmaker_claim.pb-c.h"
void rmaker_claim__payload_buf__init
(RmakerClaim__PayloadBuf *message)
{
static const RmakerClaim__PayloadBuf init_value = RMAKER_CLAIM__PAYLOAD_BUF__INIT;
*message = init_value;
}
size_t rmaker_claim__payload_buf__get_packed_size
(const RmakerClaim__PayloadBuf *message)
{
assert(message->base.descriptor == &rmaker_claim__payload_buf__descriptor);
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
}
size_t rmaker_claim__payload_buf__pack
(const RmakerClaim__PayloadBuf *message,
uint8_t *out)
{
assert(message->base.descriptor == &rmaker_claim__payload_buf__descriptor);
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
}
size_t rmaker_claim__payload_buf__pack_to_buffer
(const RmakerClaim__PayloadBuf *message,
ProtobufCBuffer *buffer)
{
assert(message->base.descriptor == &rmaker_claim__payload_buf__descriptor);
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
}
RmakerClaim__PayloadBuf *
rmaker_claim__payload_buf__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data)
{
return (RmakerClaim__PayloadBuf *)
protobuf_c_message_unpack (&rmaker_claim__payload_buf__descriptor,
allocator, len, data);
}
void rmaker_claim__payload_buf__free_unpacked
(RmakerClaim__PayloadBuf *message,
ProtobufCAllocator *allocator)
{
if(!message)
return;
assert(message->base.descriptor == &rmaker_claim__payload_buf__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
void rmaker_claim__resp_payload__init
(RmakerClaim__RespPayload *message)
{
static const RmakerClaim__RespPayload init_value = RMAKER_CLAIM__RESP_PAYLOAD__INIT;
*message = init_value;
}
size_t rmaker_claim__resp_payload__get_packed_size
(const RmakerClaim__RespPayload *message)
{
assert(message->base.descriptor == &rmaker_claim__resp_payload__descriptor);
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
}
size_t rmaker_claim__resp_payload__pack
(const RmakerClaim__RespPayload *message,
uint8_t *out)
{
assert(message->base.descriptor == &rmaker_claim__resp_payload__descriptor);
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
}
size_t rmaker_claim__resp_payload__pack_to_buffer
(const RmakerClaim__RespPayload *message,
ProtobufCBuffer *buffer)
{
assert(message->base.descriptor == &rmaker_claim__resp_payload__descriptor);
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
}
RmakerClaim__RespPayload *
rmaker_claim__resp_payload__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data)
{
return (RmakerClaim__RespPayload *)
protobuf_c_message_unpack (&rmaker_claim__resp_payload__descriptor,
allocator, len, data);
}
void rmaker_claim__resp_payload__free_unpacked
(RmakerClaim__RespPayload *message,
ProtobufCAllocator *allocator)
{
if(!message)
return;
assert(message->base.descriptor == &rmaker_claim__resp_payload__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
void rmaker_claim__rmaker_claim_payload__init
(RmakerClaim__RMakerClaimPayload *message)
{
static const RmakerClaim__RMakerClaimPayload init_value = RMAKER_CLAIM__RMAKER_CLAIM_PAYLOAD__INIT;
*message = init_value;
}
size_t rmaker_claim__rmaker_claim_payload__get_packed_size
(const RmakerClaim__RMakerClaimPayload *message)
{
assert(message->base.descriptor == &rmaker_claim__rmaker_claim_payload__descriptor);
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
}
size_t rmaker_claim__rmaker_claim_payload__pack
(const RmakerClaim__RMakerClaimPayload *message,
uint8_t *out)
{
assert(message->base.descriptor == &rmaker_claim__rmaker_claim_payload__descriptor);
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
}
size_t rmaker_claim__rmaker_claim_payload__pack_to_buffer
(const RmakerClaim__RMakerClaimPayload *message,
ProtobufCBuffer *buffer)
{
assert(message->base.descriptor == &rmaker_claim__rmaker_claim_payload__descriptor);
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
}
RmakerClaim__RMakerClaimPayload *
rmaker_claim__rmaker_claim_payload__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data)
{
return (RmakerClaim__RMakerClaimPayload *)
protobuf_c_message_unpack (&rmaker_claim__rmaker_claim_payload__descriptor,
allocator, len, data);
}
void rmaker_claim__rmaker_claim_payload__free_unpacked
(RmakerClaim__RMakerClaimPayload *message,
ProtobufCAllocator *allocator)
{
if(!message)
return;
assert(message->base.descriptor == &rmaker_claim__rmaker_claim_payload__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
static const ProtobufCFieldDescriptor rmaker_claim__payload_buf__field_descriptors[3] =
{
{
"Offset",
1,
PROTOBUF_C_LABEL_NONE,
PROTOBUF_C_TYPE_UINT32,
0, /* quantifier_offset */
offsetof(RmakerClaim__PayloadBuf, offset),
NULL,
NULL,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"Payload",
2,
PROTOBUF_C_LABEL_NONE,
PROTOBUF_C_TYPE_BYTES,
0, /* quantifier_offset */
offsetof(RmakerClaim__PayloadBuf, payload),
NULL,
NULL,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"TotalLen",
3,
PROTOBUF_C_LABEL_NONE,
PROTOBUF_C_TYPE_UINT32,
0, /* quantifier_offset */
offsetof(RmakerClaim__PayloadBuf, totallen),
NULL,
NULL,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
};
static const unsigned rmaker_claim__payload_buf__field_indices_by_name[] = {
0, /* field[0] = Offset */
1, /* field[1] = Payload */
2, /* field[2] = TotalLen */
};
static const ProtobufCIntRange rmaker_claim__payload_buf__number_ranges[1 + 1] =
{
{ 1, 0 },
{ 0, 3 }
};
const ProtobufCMessageDescriptor rmaker_claim__payload_buf__descriptor =
{
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"rmaker_claim.PayloadBuf",
"PayloadBuf",
"RmakerClaim__PayloadBuf",
"rmaker_claim",
sizeof(RmakerClaim__PayloadBuf),
3,
rmaker_claim__payload_buf__field_descriptors,
rmaker_claim__payload_buf__field_indices_by_name,
1, rmaker_claim__payload_buf__number_ranges,
(ProtobufCMessageInit) rmaker_claim__payload_buf__init,
NULL,NULL,NULL /* reserved[123] */
};
static const ProtobufCFieldDescriptor rmaker_claim__resp_payload__field_descriptors[2] =
{
{
"Status",
1,
PROTOBUF_C_LABEL_NONE,
PROTOBUF_C_TYPE_ENUM,
0, /* quantifier_offset */
offsetof(RmakerClaim__RespPayload, status),
&rmaker_claim__rmaker_claim_status__descriptor,
NULL,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"Buf",
2,
PROTOBUF_C_LABEL_NONE,
PROTOBUF_C_TYPE_MESSAGE,
0, /* quantifier_offset */
offsetof(RmakerClaim__RespPayload, buf),
&rmaker_claim__payload_buf__descriptor,
NULL,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
};
static const unsigned rmaker_claim__resp_payload__field_indices_by_name[] = {
1, /* field[1] = Buf */
0, /* field[0] = Status */
};
static const ProtobufCIntRange rmaker_claim__resp_payload__number_ranges[1 + 1] =
{
{ 1, 0 },
{ 0, 2 }
};
const ProtobufCMessageDescriptor rmaker_claim__resp_payload__descriptor =
{
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"rmaker_claim.RespPayload",
"RespPayload",
"RmakerClaim__RespPayload",
"rmaker_claim",
sizeof(RmakerClaim__RespPayload),
2,
rmaker_claim__resp_payload__field_descriptors,
rmaker_claim__resp_payload__field_indices_by_name,
1, rmaker_claim__resp_payload__number_ranges,
(ProtobufCMessageInit) rmaker_claim__resp_payload__init,
NULL,NULL,NULL /* reserved[123] */
};
static const ProtobufCFieldDescriptor rmaker_claim__rmaker_claim_payload__field_descriptors[3] =
{
{
"msg",
1,
PROTOBUF_C_LABEL_NONE,
PROTOBUF_C_TYPE_ENUM,
0, /* quantifier_offset */
offsetof(RmakerClaim__RMakerClaimPayload, msg),
&rmaker_claim__rmaker_claim_msg_type__descriptor,
NULL,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"cmdPayload",
10,
PROTOBUF_C_LABEL_NONE,
PROTOBUF_C_TYPE_MESSAGE,
offsetof(RmakerClaim__RMakerClaimPayload, payload_case),
offsetof(RmakerClaim__RMakerClaimPayload, cmdpayload),
&rmaker_claim__payload_buf__descriptor,
NULL,
0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"respPayload",
11,
PROTOBUF_C_LABEL_NONE,
PROTOBUF_C_TYPE_MESSAGE,
offsetof(RmakerClaim__RMakerClaimPayload, payload_case),
offsetof(RmakerClaim__RMakerClaimPayload, resppayload),
&rmaker_claim__resp_payload__descriptor,
NULL,
0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
};
static const unsigned rmaker_claim__rmaker_claim_payload__field_indices_by_name[] = {
1, /* field[1] = cmdPayload */
0, /* field[0] = msg */
2, /* field[2] = respPayload */
};
static const ProtobufCIntRange rmaker_claim__rmaker_claim_payload__number_ranges[2 + 1] =
{
{ 1, 0 },
{ 10, 1 },
{ 0, 3 }
};
const ProtobufCMessageDescriptor rmaker_claim__rmaker_claim_payload__descriptor =
{
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"rmaker_claim.RMakerClaimPayload",
"RMakerClaimPayload",
"RmakerClaim__RMakerClaimPayload",
"rmaker_claim",
sizeof(RmakerClaim__RMakerClaimPayload),
3,
rmaker_claim__rmaker_claim_payload__field_descriptors,
rmaker_claim__rmaker_claim_payload__field_indices_by_name,
2, rmaker_claim__rmaker_claim_payload__number_ranges,
(ProtobufCMessageInit) rmaker_claim__rmaker_claim_payload__init,
NULL,NULL,NULL /* reserved[123] */
};
static const ProtobufCEnumValue rmaker_claim__rmaker_claim_status__enum_values_by_number[5] =
{
{ "Success", "RMAKER_CLAIM__RMAKER_CLAIM_STATUS__Success", 0 },
{ "Fail", "RMAKER_CLAIM__RMAKER_CLAIM_STATUS__Fail", 1 },
{ "InvalidParam", "RMAKER_CLAIM__RMAKER_CLAIM_STATUS__InvalidParam", 2 },
{ "InvalidState", "RMAKER_CLAIM__RMAKER_CLAIM_STATUS__InvalidState", 3 },
{ "NoMemory", "RMAKER_CLAIM__RMAKER_CLAIM_STATUS__NoMemory", 4 },
};
static const ProtobufCIntRange rmaker_claim__rmaker_claim_status__value_ranges[] = {
{0, 0},{0, 5}
};
static const ProtobufCEnumValueIndex rmaker_claim__rmaker_claim_status__enum_values_by_name[5] =
{
{ "Fail", 1 },
{ "InvalidParam", 2 },
{ "InvalidState", 3 },
{ "NoMemory", 4 },
{ "Success", 0 },
};
const ProtobufCEnumDescriptor rmaker_claim__rmaker_claim_status__descriptor =
{
PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,
"rmaker_claim.RMakerClaimStatus",
"RMakerClaimStatus",
"RmakerClaim__RMakerClaimStatus",
"rmaker_claim",
5,
rmaker_claim__rmaker_claim_status__enum_values_by_number,
5,
rmaker_claim__rmaker_claim_status__enum_values_by_name,
1,
rmaker_claim__rmaker_claim_status__value_ranges,
NULL,NULL,NULL,NULL /* reserved[1234] */
};
static const ProtobufCEnumValue rmaker_claim__rmaker_claim_msg_type__enum_values_by_number[8] =
{
{ "TypeCmdClaimStart", "RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeCmdClaimStart", 0 },
{ "TypeRespClaimStart", "RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeRespClaimStart", 1 },
{ "TypeCmdClaimInit", "RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeCmdClaimInit", 2 },
{ "TypeRespClaimInit", "RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeRespClaimInit", 3 },
{ "TypeCmdClaimVerify", "RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeCmdClaimVerify", 4 },
{ "TypeRespClaimVerify", "RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeRespClaimVerify", 5 },
{ "TypeCmdClaimAbort", "RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeCmdClaimAbort", 6 },
{ "TypeRespClaimAbort", "RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeRespClaimAbort", 7 },
};
static const ProtobufCIntRange rmaker_claim__rmaker_claim_msg_type__value_ranges[] = {
{0, 0},{0, 8}
};
static const ProtobufCEnumValueIndex rmaker_claim__rmaker_claim_msg_type__enum_values_by_name[8] =
{
{ "TypeCmdClaimAbort", 6 },
{ "TypeCmdClaimInit", 2 },
{ "TypeCmdClaimStart", 0 },
{ "TypeCmdClaimVerify", 4 },
{ "TypeRespClaimAbort", 7 },
{ "TypeRespClaimInit", 3 },
{ "TypeRespClaimStart", 1 },
{ "TypeRespClaimVerify", 5 },
};
const ProtobufCEnumDescriptor rmaker_claim__rmaker_claim_msg_type__descriptor =
{
PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,
"rmaker_claim.RMakerClaimMsgType",
"RMakerClaimMsgType",
"RmakerClaim__RMakerClaimMsgType",
"rmaker_claim",
8,
rmaker_claim__rmaker_claim_msg_type__enum_values_by_number,
8,
rmaker_claim__rmaker_claim_msg_type__enum_values_by_name,
1,
rmaker_claim__rmaker_claim_msg_type__value_ranges,
NULL,NULL,NULL,NULL /* reserved[1234] */
};

View File

@@ -0,0 +1,175 @@
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
/* Generated from: esp_rmaker_claim.proto */
#ifndef PROTOBUF_C_esp_5frmaker_5fclaim_2eproto__INCLUDED
#define PROTOBUF_C_esp_5frmaker_5fclaim_2eproto__INCLUDED
#include <protobuf-c/protobuf-c.h>
PROTOBUF_C__BEGIN_DECLS
#if PROTOBUF_C_VERSION_NUMBER < 1003000
# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers.
#elif 1003003 < PROTOBUF_C_MIN_COMPILER_VERSION
# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c.
#endif
typedef struct _RmakerClaim__PayloadBuf RmakerClaim__PayloadBuf;
typedef struct _RmakerClaim__RespPayload RmakerClaim__RespPayload;
typedef struct _RmakerClaim__RMakerClaimPayload RmakerClaim__RMakerClaimPayload;
/* --- enums --- */
typedef enum _RmakerClaim__RMakerClaimStatus {
RMAKER_CLAIM__RMAKER_CLAIM_STATUS__Success = 0,
RMAKER_CLAIM__RMAKER_CLAIM_STATUS__Fail = 1,
RMAKER_CLAIM__RMAKER_CLAIM_STATUS__InvalidParam = 2,
RMAKER_CLAIM__RMAKER_CLAIM_STATUS__InvalidState = 3,
RMAKER_CLAIM__RMAKER_CLAIM_STATUS__NoMemory = 4
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(RMAKER_CLAIM__RMAKER_CLAIM_STATUS)
} RmakerClaim__RMakerClaimStatus;
typedef enum _RmakerClaim__RMakerClaimMsgType {
RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeCmdClaimStart = 0,
RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeRespClaimStart = 1,
RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeCmdClaimInit = 2,
RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeRespClaimInit = 3,
RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeCmdClaimVerify = 4,
RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeRespClaimVerify = 5,
RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeCmdClaimAbort = 6,
RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeRespClaimAbort = 7
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE)
} RmakerClaim__RMakerClaimMsgType;
/* --- messages --- */
struct _RmakerClaim__PayloadBuf
{
ProtobufCMessage base;
uint32_t offset;
ProtobufCBinaryData payload;
uint32_t totallen;
};
#define RMAKER_CLAIM__PAYLOAD_BUF__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&rmaker_claim__payload_buf__descriptor) \
, 0, {0,NULL}, 0 }
struct _RmakerClaim__RespPayload
{
ProtobufCMessage base;
RmakerClaim__RMakerClaimStatus status;
RmakerClaim__PayloadBuf *buf;
};
#define RMAKER_CLAIM__RESP_PAYLOAD__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&rmaker_claim__resp_payload__descriptor) \
, RMAKER_CLAIM__RMAKER_CLAIM_STATUS__Success, NULL }
typedef enum {
RMAKER_CLAIM__RMAKER_CLAIM_PAYLOAD__PAYLOAD__NOT_SET = 0,
RMAKER_CLAIM__RMAKER_CLAIM_PAYLOAD__PAYLOAD_CMD_PAYLOAD = 10,
RMAKER_CLAIM__RMAKER_CLAIM_PAYLOAD__PAYLOAD_RESP_PAYLOAD = 11
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(RMAKER_CLAIM__RMAKER_CLAIM_PAYLOAD__PAYLOAD)
} RmakerClaim__RMakerClaimPayload__PayloadCase;
struct _RmakerClaim__RMakerClaimPayload
{
ProtobufCMessage base;
RmakerClaim__RMakerClaimMsgType msg;
RmakerClaim__RMakerClaimPayload__PayloadCase payload_case;
union {
RmakerClaim__PayloadBuf *cmdpayload;
RmakerClaim__RespPayload *resppayload;
};
};
#define RMAKER_CLAIM__RMAKER_CLAIM_PAYLOAD__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&rmaker_claim__rmaker_claim_payload__descriptor) \
, RMAKER_CLAIM__RMAKER_CLAIM_MSG_TYPE__TypeCmdClaimStart, RMAKER_CLAIM__RMAKER_CLAIM_PAYLOAD__PAYLOAD__NOT_SET, {0} }
/* RmakerClaim__PayloadBuf methods */
void rmaker_claim__payload_buf__init
(RmakerClaim__PayloadBuf *message);
size_t rmaker_claim__payload_buf__get_packed_size
(const RmakerClaim__PayloadBuf *message);
size_t rmaker_claim__payload_buf__pack
(const RmakerClaim__PayloadBuf *message,
uint8_t *out);
size_t rmaker_claim__payload_buf__pack_to_buffer
(const RmakerClaim__PayloadBuf *message,
ProtobufCBuffer *buffer);
RmakerClaim__PayloadBuf *
rmaker_claim__payload_buf__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void rmaker_claim__payload_buf__free_unpacked
(RmakerClaim__PayloadBuf *message,
ProtobufCAllocator *allocator);
/* RmakerClaim__RespPayload methods */
void rmaker_claim__resp_payload__init
(RmakerClaim__RespPayload *message);
size_t rmaker_claim__resp_payload__get_packed_size
(const RmakerClaim__RespPayload *message);
size_t rmaker_claim__resp_payload__pack
(const RmakerClaim__RespPayload *message,
uint8_t *out);
size_t rmaker_claim__resp_payload__pack_to_buffer
(const RmakerClaim__RespPayload *message,
ProtobufCBuffer *buffer);
RmakerClaim__RespPayload *
rmaker_claim__resp_payload__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void rmaker_claim__resp_payload__free_unpacked
(RmakerClaim__RespPayload *message,
ProtobufCAllocator *allocator);
/* RmakerClaim__RMakerClaimPayload methods */
void rmaker_claim__rmaker_claim_payload__init
(RmakerClaim__RMakerClaimPayload *message);
size_t rmaker_claim__rmaker_claim_payload__get_packed_size
(const RmakerClaim__RMakerClaimPayload *message);
size_t rmaker_claim__rmaker_claim_payload__pack
(const RmakerClaim__RMakerClaimPayload *message,
uint8_t *out);
size_t rmaker_claim__rmaker_claim_payload__pack_to_buffer
(const RmakerClaim__RMakerClaimPayload *message,
ProtobufCBuffer *buffer);
RmakerClaim__RMakerClaimPayload *
rmaker_claim__rmaker_claim_payload__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void rmaker_claim__rmaker_claim_payload__free_unpacked
(RmakerClaim__RMakerClaimPayload *message,
ProtobufCAllocator *allocator);
/* --- per-message closures --- */
typedef void (*RmakerClaim__PayloadBuf_Closure)
(const RmakerClaim__PayloadBuf *message,
void *closure_data);
typedef void (*RmakerClaim__RespPayload_Closure)
(const RmakerClaim__RespPayload *message,
void *closure_data);
typedef void (*RmakerClaim__RMakerClaimPayload_Closure)
(const RmakerClaim__RMakerClaimPayload *message,
void *closure_data);
/* --- services --- */
/* --- descriptors --- */
extern const ProtobufCEnumDescriptor rmaker_claim__rmaker_claim_status__descriptor;
extern const ProtobufCEnumDescriptor rmaker_claim__rmaker_claim_msg_type__descriptor;
extern const ProtobufCMessageDescriptor rmaker_claim__payload_buf__descriptor;
extern const ProtobufCMessageDescriptor rmaker_claim__resp_payload__descriptor;
extern const ProtobufCMessageDescriptor rmaker_claim__rmaker_claim_payload__descriptor;
PROTOBUF_C__END_DECLS
#endif /* PROTOBUF_C_esp_5frmaker_5fclaim_2eproto__INCLUDED */

View File

@@ -0,0 +1,41 @@
syntax = "proto3";
package rmaker_claim;
enum RMakerClaimStatus {
Success = 0;
Fail = 1;
InvalidParam = 2;
InvalidState = 3;
NoMemory = 4;
}
message PayloadBuf {
uint32 Offset = 1;
bytes Payload = 2;
uint32 TotalLen = 3;
}
message RespPayload {
RMakerClaimStatus Status = 1;
PayloadBuf Buf = 2;
}
enum RMakerClaimMsgType {
TypeCmdClaimStart = 0;
TypeRespClaimStart = 1;
TypeCmdClaimInit = 2;
TypeRespClaimInit = 3;
TypeCmdClaimVerify = 4;
TypeRespClaimVerify = 5;
TypeCmdClaimAbort = 6;
TypeRespClaimAbort = 7;
}
message RMakerClaimPayload {
RMakerClaimMsgType msg = 1;
oneof payload {
PayloadBuf cmdPayload = 10;
RespPayload respPayload = 11;
}
}

View File

@@ -28,11 +28,11 @@ extern uint8_t mqtt_server_root_ca_pem_end[] asm("_binary_mqtt_server_crt_end");
char * esp_rmaker_get_mqtt_host()
{
char *host = esp_rmaker_storage_get(ESP_RMAKER_MQTT_HOST_NVS_KEY);
#ifdef CONFIG_ESP_RMAKER_SELF_CLAIM
#if defined(CONFIG_ESP_RMAKER_SELF_CLAIM) || defined(CONFIG_ESP_RMAKER_ASSISTED_CLAIM)
if (!host) {
return strdup(CONFIG_ESP_RMAKER_MQTT_HOST);
}
#endif /* CONFIG_ESP_RMAKER_SELF_CLAIM */
#endif /* defined(CONFIG_ESP_RMAKER_SELF_CLAIM) || defined(CONFIG_ESP_RMAKER_ASSISTED_CLAIM) */
return host;
}

View File

@@ -41,6 +41,9 @@ static const char *TAG = "esp_rmaker_core";
#define ESP_RMAKER_TASK_STACK CONFIG_ESP_RMAKER_TASK_STACK
#define ESP_RMAKER_TASK_PRIORITY CONFIG_ESP_RMAKER_TASK_PRIORITY
#if defined(CONFIG_ESP_RMAKER_SELF_CLAIM) || defined(CONFIG_ESP_RMAKER_ASSISTED_CLAIM)
#define ESP_RMAKER_CLAIM_ENABLED
#endif
#define ESP_RMAKER_CHECK_HANDLE(rval) \
{ \
@@ -68,9 +71,10 @@ typedef struct {
esp_rmaker_state_t state;
bool mqtt_connected;
esp_rmaker_mqtt_config_t *mqtt_config;
#ifdef CONFIG_ESP_RMAKER_SELF_CLAIM
bool self_claim;
#endif /* CONFIG_ESP_RMAKER_SELF_CLAIM */
#ifdef ESP_RMAKER_CLAIM_ENABLED
bool need_claim;
esp_rmaker_claim_data_t *claim_data;
#endif /* ESP_RMAKER_CLAIM_ENABLED */
QueueHandle_t work_queue;
} esp_rmaker_priv_data_t;
@@ -79,7 +83,7 @@ static esp_rmaker_priv_data_t *esp_rmaker_priv_data;
static char *esp_rmaker_populate_node_id()
{
char *node_id = esp_rmaker_storage_get("node_id");
#ifdef CONFIG_ESP_RMAKER_SELF_CLAIM
#ifdef ESP_RMAKER_CLAIM_ENABLED
if (!node_id) {
uint8_t eth_mac[6];
esp_err_t err = esp_wifi_get_mac(WIFI_IF_STA, eth_mac);
@@ -91,16 +95,42 @@ static char *esp_rmaker_populate_node_id()
snprintf(node_id, ESP_CLAIM_NODE_ID_SIZE + 1, "%02X%02X%02X%02X%02X%02X",
eth_mac[0], eth_mac[1], eth_mac[2], eth_mac[3], eth_mac[4], eth_mac[5]);
}
#endif /* CONFIG_ESP_RMAKER_SELF_CLAIM */
#endif /* ESP_RMAKER_CLAIM_ENABLED */
return node_id;
}
esp_err_t esp_rmaker_change_node_id(char *node_id, size_t len)
{
if(esp_rmaker_priv_data) {
char *new_node_id = strndup(node_id, len);
if (!new_node_id) {
ESP_LOGE(TAG, "Failed to allocate %d bytes for new node_id.", len);
return ESP_ERR_NO_MEM;
}
if (esp_rmaker_priv_data->node_id) {
free(esp_rmaker_priv_data->node_id);
}
esp_rmaker_priv_data->node_id = new_node_id;
_esp_rmaker_node_t *node = (_esp_rmaker_node_t *)esp_rmaker_get_node();
node->node_id = new_node_id;
ESP_LOGI(TAG, "New Node ID ----- %s", new_node_id);
return ESP_OK;
}
return ESP_ERR_INVALID_STATE;
}
/* Event handler for catching system events */
static void esp_rmaker_event_handler(void* arg, esp_event_base_t event_base,
int event_id, void* event_data)
{
if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
#ifdef CONFIG_ESP_RMAKER_ASSISTED_CLAIM
if (esp_rmaker_priv_data->claim_data) {
ESP_LOGE(TAG, "Node connected to Wi-Fi without Assisted claiming. Cannot proceed to MQTT connection.");
ESP_LOGE(TAG, "Please update your phone apps and repeat Wi-Fi provisioning with BLE transport.");
}
#endif
/* Signal rmaker thread to continue execution */
xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_EVENT);
}
@@ -114,6 +144,11 @@ static esp_err_t esp_rmaker_deinit_priv_data(esp_rmaker_priv_data_t *rmaker_priv
if (rmaker_priv_data->work_queue) {
vQueueDelete(rmaker_priv_data->work_queue);
}
#ifdef ESP_RMAKER_CLAIM_ENABLED
if (rmaker_priv_data->claim_data) {
esp_rmaker_claim_data_free(rmaker_priv_data->claim_data);
}
#endif
if (rmaker_priv_data->mqtt_config) {
esp_rmaker_clean_mqtt_config(rmaker_priv_data->mqtt_config);
free(rmaker_priv_data->mqtt_config);
@@ -188,20 +223,26 @@ static esp_err_t esp_rmaker_init(const esp_rmaker_config_t *config)
}
esp_rmaker_priv_data->mqtt_config = esp_rmaker_get_mqtt_config();
if (!esp_rmaker_priv_data->mqtt_config) {
#ifdef ESP_RMAKER_CLAIM_ENABLED
#ifdef CONFIG_ESP_RMAKER_SELF_CLAIM
esp_rmaker_priv_data->self_claim = true;
if (esp_rmaker_self_claim_init() != ESP_OK) {
esp_rmaker_priv_data->claim_data = esp_rmaker_self_claim_init();
#endif
#ifdef CONFIG_ESP_RMAKER_ASSISTED_CLAIM
esp_rmaker_priv_data->claim_data = esp_rmaker_assisted_claim_init();
#endif
if (!esp_rmaker_priv_data->claim_data) {
esp_rmaker_deinit_priv_data(esp_rmaker_priv_data);
esp_rmaker_priv_data = NULL;
ESP_LOGE(TAG, "Failed to initialise Self Claiming.");
ESP_LOGE(TAG, "Failed to initialise Claiming.");
return ESP_FAIL;
}
esp_rmaker_priv_data->need_claim = true;
#else
esp_rmaker_deinit_priv_data(esp_rmaker_priv_data);
esp_rmaker_priv_data = NULL;
ESP_LOGE(TAG, "Failed to initialise MQTT Config. Please perform \"claiming\" using RainMaker CLI.");
return ESP_FAIL;
#endif /* !CONFIG_ESP_RMAKER_SELF_CLAIM */
#endif /* !ESP_RMAKER_CLAIM_ENABLED */
} else {
if (esp_rmaker_mqtt_init(esp_rmaker_priv_data->mqtt_config) != ESP_OK) {
esp_rmaker_deinit_priv_data(esp_rmaker_priv_data);
@@ -296,25 +337,46 @@ static void esp_rmaker_task(void *param)
esp_rmaker_priv_data->state = ESP_RMAKER_STATE_STARTING;
esp_err_t err;
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &esp_rmaker_event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &esp_rmaker_event_handler, esp_rmaker_priv_data));
/* Assisted claiming needs to be done before Wi-Fi connection */
#ifdef CONFIG_ESP_RMAKER_ASSISTED_CLAIM
if (esp_rmaker_priv_data->need_claim) {
esp_rmaker_post_event(RMAKER_EVENT_CLAIM_STARTED, NULL, 0);
err = esp_rmaker_assisted_claim_perform(esp_rmaker_priv_data->claim_data);
if (err != ESP_OK) {
esp_rmaker_post_event(RMAKER_EVENT_CLAIM_FAILED, NULL, 0);
ESP_LOGE(TAG, "esp_rmaker_self_claim_perform() returned %d. Aborting", err);
vTaskDelete(NULL);
}
esp_rmaker_priv_data->claim_data = NULL;
esp_rmaker_post_event(RMAKER_EVENT_CLAIM_SUCCESSFUL, NULL, 0);
}
#endif
/* Wait for Wi-Fi connection */
xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_EVENT, false, true, portMAX_DELAY);
vEventGroupDelete(wifi_event_group);
if (esp_rmaker_priv_data->enable_time_sync) {
#ifdef CONFIG_MBEDTLS_HAVE_TIME_DATE
esp_rmaker_time_wait_for_sync(portMAX_DELAY);
#endif
}
/* Self claiming can be done only after Wi-Fi connection */
#ifdef CONFIG_ESP_RMAKER_SELF_CLAIM
if (esp_rmaker_priv_data->self_claim) {
if (esp_rmaker_priv_data->need_claim) {
esp_rmaker_post_event(RMAKER_EVENT_CLAIM_STARTED, NULL, 0);
err = esp_rmaker_self_claim_perform();
err = esp_rmaker_self_claim_perform(esp_rmaker_priv_data->claim_data);
if (err != ESP_OK) {
esp_rmaker_post_event(RMAKER_EVENT_CLAIM_FAILED, NULL, 0);
ESP_LOGE(TAG, "esp_rmaker_self_claim_perform() returned %d. Aborting", err);
vTaskDelete(NULL);
}
esp_rmaker_priv_data->claim_data = NULL;
esp_rmaker_post_event(RMAKER_EVENT_CLAIM_SUCCESSFUL, NULL, 0);
}
#endif
#ifdef ESP_RMAKER_CLAIM_ENABLED
if (esp_rmaker_priv_data->need_claim) {
esp_rmaker_priv_data->mqtt_config = esp_rmaker_get_mqtt_config();
if (!esp_rmaker_priv_data->mqtt_config) {
ESP_LOGE(TAG, "Failed to initialise MQTT Config after claiming. Aborting");
@@ -325,8 +387,9 @@ static void esp_rmaker_task(void *param)
ESP_LOGE(TAG, "esp_rmaker_mqtt_init() returned %d. Aborting", err);
vTaskDelete(NULL);
}
esp_rmaker_priv_data->need_claim = false;
}
#endif /* CONFIG_ESP_RMAKER_SELF_CLAIM */
#endif /* ESP_RMAKER_CLAIM_ENABLED */
err = esp_rmaker_mqtt_connect();
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_rmaker_mqtt_connect() returned %d. Aborting", err);

View File

@@ -79,6 +79,7 @@ typedef struct {
} _esp_rmaker_node_t;
esp_rmaker_node_t *esp_rmaker_node_create(const char *name, const char *type);
esp_err_t esp_rmaker_change_node_id(char *node_id, size_t len);
esp_err_t esp_rmaker_report_value(const esp_rmaker_param_val_t *val, char *key, json_gen_str_t *jptr);
esp_err_t esp_rmaker_report_data_type(esp_rmaker_val_type_t type, json_gen_str_t *jptr);
esp_err_t esp_rmaker_report_node_config(void);

View File

@@ -8,7 +8,7 @@ menu "ESP RainMaker App Wi-Fi Provisioning"
choice APP_WIFI_PROV_TRANSPORT
bool "Provisioning Transport method"
default APP_WIFI_PROV_TRANSPORT_SOFTAP
default APP_WIFI_PROV_TRANSPORT_BLE
help
Wi-Fi provisioning component offers both, SoftAP and BLE transports. Choose any one.