mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-05-21 00:56:38 +08:00
feature/protocomm: Added the protocomm component from idf.
This commit is contained in:
25
components/protocomm/CMakeLists.txt
Normal file
25
components/protocomm/CMakeLists.txt
Normal file
@ -0,0 +1,25 @@
|
||||
set(COMPONENT_ADD_INCLUDEDIRS include/common
|
||||
include/security
|
||||
include/transports)
|
||||
set(COMPONENT_PRIV_INCLUDEDIRS proto-c src/common src/simple_ble)
|
||||
set(COMPONENT_SRCS "src/common/protocomm.c"
|
||||
"src/security/security0.c"
|
||||
"src/security/security1.c"
|
||||
"proto-c/constants.pb-c.c"
|
||||
"proto-c/sec0.pb-c.c"
|
||||
"proto-c/sec1.pb-c.c"
|
||||
"proto-c/session.pb-c.c"
|
||||
"src/transports/protocomm_console.c"
|
||||
"src/transports/protocomm_httpd.c")
|
||||
|
||||
set(COMPONENT_PRIV_REQUIRES protobuf-c mbedtls console esp_http_server bt)
|
||||
|
||||
if(CONFIG_BT_ENABLED)
|
||||
if(CONFIG_BLUEDROID_ENABLED)
|
||||
list(APPEND COMPONENT_SRCS
|
||||
"src/simple_ble/simple_ble.c"
|
||||
"src/transports/protocomm_ble.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
register_component()
|
7
components/protocomm/component.mk
Normal file
7
components/protocomm/component.mk
Normal file
@ -0,0 +1,7 @@
|
||||
COMPONENT_ADD_INCLUDEDIRS := include/common include/security include/transports
|
||||
COMPONENT_PRIV_INCLUDEDIRS := proto-c src/common src/simple_ble
|
||||
COMPONENT_SRCDIRS := src/common src/security proto-c src/simple_ble src/transports
|
||||
|
||||
ifneq ($(filter y, $(CONFIG_BT_ENABLED) $(CONFIG_BLUEDROID_ENABLED)),y y)
|
||||
COMPONENT_OBJEXCLUDE := src/simple_ble/simple_ble.o src/transports/protocomm_ble.o
|
||||
endif
|
235
components/protocomm/include/common/protocomm.h
Normal file
235
components/protocomm/include/common/protocomm.h
Normal file
@ -0,0 +1,235 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <protocomm_security.h>
|
||||
#include <esp_err.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Function prototype for protocomm endpoint handler
|
||||
*/
|
||||
typedef esp_err_t (*protocomm_req_handler_t)(
|
||||
uint32_t session_id, /*!< Session ID for identifying protocomm client */
|
||||
const uint8_t *inbuf, /*!< Pointer to user provided input data buffer */
|
||||
ssize_t inlen, /*!< Length o the input buffer */
|
||||
uint8_t **outbuf, /*!< Pointer to output buffer allocated by handler */
|
||||
ssize_t *outlen, /*!< Length of the allocated output buffer */
|
||||
void *priv_data /*!< Private data passed to the handler (NULL if not used) */
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief This structure corresponds to a unique instance of protocomm
|
||||
* returned when the API `protocomm_new()` is called. The remaining
|
||||
* Protocomm APIs require this object as the first parameter.
|
||||
*
|
||||
* @note Structure of the protocomm object is kept private
|
||||
*/
|
||||
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 initialized to NULL.
|
||||
*
|
||||
* @return
|
||||
* - protocomm_t* : On success
|
||||
* - NULL : No memory for allocating new instance
|
||||
*/
|
||||
protocomm_t *protocomm_new();
|
||||
|
||||
/**
|
||||
* @brief Delete a protocomm instance
|
||||
*
|
||||
* This API will deallocate a protocomm instance that was created
|
||||
* using `protocomm_new()`.
|
||||
*
|
||||
* @param[in] pc Pointer to the protocomm instance to be deleted
|
||||
*/
|
||||
void protocomm_delete(protocomm_t *pc);
|
||||
|
||||
/**
|
||||
* @brief Add endpoint request handler for a protocomm instance
|
||||
*
|
||||
* This API will bind an endpoint handler function to the specified
|
||||
* endpoint name, along with any private data that needs to be pass to
|
||||
* the handler at the time of call.
|
||||
*
|
||||
* @note
|
||||
* - An endpoint must be bound to a valid protocomm instance,
|
||||
* created using `protocomm_new()`.
|
||||
* - This function internally calls the registered `add_endpoint()`
|
||||
* 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
|
||||
* @param[in] h Endpoint handler function
|
||||
* @param[in] priv_data Pointer to private data to be passed as a
|
||||
* parameter to the handler function on call.
|
||||
* Pass NULL if not needed.
|
||||
*
|
||||
* @return
|
||||
* - 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
|
||||
*/
|
||||
esp_err_t protocomm_add_endpoint(protocomm_t *pc, const char *ep_name,
|
||||
protocomm_req_handler_t h, void *priv_data);
|
||||
|
||||
/**
|
||||
* @brief Remove endpoint request handler for a protocomm instance
|
||||
*
|
||||
* This API will remove a registered endpoint handler identified by
|
||||
* an endpoint name.
|
||||
*
|
||||
* @note
|
||||
* - This function internally calls the registered `remove_endpoint()`
|
||||
* function 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
|
||||
*
|
||||
* @return
|
||||
* - 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_remove_endpoint(protocomm_t *pc, const char *ep_name);
|
||||
|
||||
/**
|
||||
* @brief Calls the registered handler of an endpoint session
|
||||
* 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 caller.
|
||||
*
|
||||
* @param[in] pc Pointer to the protocomm instance
|
||||
* @param[in] ep_name Endpoint identifier(name) string
|
||||
* @param[in] session_id Unique ID for a communication session
|
||||
* @param[in] inbuf Input buffer contains input request data which is to be
|
||||
* processed by the registered handler
|
||||
* @param[in] inlen Length of the input buffer
|
||||
* @param[out] outbuf Pointer to internally allocated output buffer,
|
||||
* where the resulting response data output from
|
||||
* the registered handler is to be stored
|
||||
* @param[out] outlen Buffer length of the allocated output buffer
|
||||
*
|
||||
* @return
|
||||
* - 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
|
||||
* - ESP_ERR_INVALID_ARG : Null instance/name arguments
|
||||
*/
|
||||
esp_err_t protocomm_req_handle(protocomm_t *pc, const char *ep_name, uint32_t session_id,
|
||||
const uint8_t *inbuf, ssize_t inlen,
|
||||
uint8_t **outbuf, ssize_t *outlen);
|
||||
|
||||
/**
|
||||
* @brief Add endpoint security for a protocomm instance
|
||||
*
|
||||
* This API will bind a security session establisher to the specified
|
||||
* endpoint name, along with any proof of possession that may be required
|
||||
* for authenticating a session client.
|
||||
*
|
||||
* @note
|
||||
* - An endpoint must be bound to a valid protocomm instance,
|
||||
* created using `protocomm_new()`.
|
||||
* - The choice of security can be any `protocomm_security_t` instance.
|
||||
* Choices `protocomm_security0` and `protocomm_security1` are readily available.
|
||||
*
|
||||
* @param[in] pc Pointer to the protocomm instance
|
||||
* @param[in] ep_name Endpoint identifier(name) string
|
||||
* @param[in] sec Pointer to endpoint security instance
|
||||
* @param[in] pop Pointer to proof of possession for authenticating a client
|
||||
*
|
||||
* @return
|
||||
* - 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
|
||||
* - ESP_ERR_INVALID_ARG : Null instance/name/handler arguments
|
||||
*/
|
||||
esp_err_t protocomm_set_security(protocomm_t *pc, const char *ep_name,
|
||||
const protocomm_security_t *sec,
|
||||
const protocomm_security_pop_t *pop);
|
||||
|
||||
/**
|
||||
* @brief Remove endpoint security for a protocomm instance
|
||||
*
|
||||
* This API will remove a registered security endpoint identified by
|
||||
* an endpoint name.
|
||||
*
|
||||
* @param[in] pc Pointer to the protocomm instance
|
||||
* @param[in] ep_name Endpoint identifier(name) string
|
||||
*
|
||||
* @return
|
||||
* - 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_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 verified by clients through the endpoint.
|
||||
*
|
||||
* @note
|
||||
* - An endpoint must be bound to a valid protocomm instance,
|
||||
* created using `protocomm_new()`.
|
||||
|
||||
* @param[in] pc Pointer to the protocomm instance
|
||||
* @param[in] ep_name Endpoint identifier(name) string
|
||||
* @param[in] version Version identifier(name) string
|
||||
*
|
||||
* @return
|
||||
* - 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
|
||||
* - ESP_ERR_INVALID_ARG : Null instance/name/handler arguments
|
||||
*/
|
||||
esp_err_t protocomm_set_version(protocomm_t *pc, const char *ep_name,
|
||||
const char *version);
|
||||
|
||||
/**
|
||||
* @brief Remove version verification endpoint from a protocomm instance
|
||||
*
|
||||
* This API will remove a registered version endpoint identified by
|
||||
* an endpoint name.
|
||||
*
|
||||
* @param[in] pc Pointer to the protocomm instance
|
||||
* @param[in] ep_name Endpoint identifier(name) string
|
||||
*
|
||||
* @return
|
||||
* - 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
|
101
components/protocomm/include/security/protocomm_security.h
Normal file
101
components/protocomm/include/security/protocomm_security.h
Normal file
@ -0,0 +1,101 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <esp_err.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Proof Of Possession for authenticating a secure session
|
||||
*/
|
||||
typedef struct protocomm_security_pop {
|
||||
/**
|
||||
* Pointer to buffer containing the proof of possession data
|
||||
*/
|
||||
const uint8_t *data;
|
||||
|
||||
/**
|
||||
* Length (in bytes) of the proof of possession data
|
||||
*/
|
||||
uint16_t len;
|
||||
} protocomm_security_pop_t;
|
||||
|
||||
/**
|
||||
* @brief Protocomm security object structure.
|
||||
*
|
||||
* The member functions are used for implementing secure
|
||||
* protocomm sessions.
|
||||
*
|
||||
* @note This structure should not have any dynamic
|
||||
* members to allow re-entrancy
|
||||
*/
|
||||
typedef struct protocomm_security {
|
||||
/**
|
||||
* Unique version number of security implementation
|
||||
*/
|
||||
int ver;
|
||||
|
||||
/**
|
||||
* Function for initializing/allocating security
|
||||
* infrastructure
|
||||
*/
|
||||
esp_err_t (*init)();
|
||||
|
||||
/**
|
||||
* Function for deallocating security infrastructure
|
||||
*/
|
||||
esp_err_t (*cleanup)();
|
||||
|
||||
/**
|
||||
* Starts new secure transport session with specified ID
|
||||
*/
|
||||
esp_err_t (*new_transport_session)(uint32_t session_id);
|
||||
|
||||
/**
|
||||
* Closes a secure transport session with specified ID
|
||||
*/
|
||||
esp_err_t (*close_transport_session)(uint32_t session_id);
|
||||
|
||||
/**
|
||||
* Handler function for authenticating connection
|
||||
* request and establishing secure session
|
||||
*/
|
||||
esp_err_t (*security_req_handler)(const protocomm_security_pop_t *pop,
|
||||
uint32_t session_id,
|
||||
const uint8_t *inbuf, ssize_t inlen,
|
||||
uint8_t **outbuf, ssize_t *outlen,
|
||||
void *priv_data);
|
||||
|
||||
/**
|
||||
* Function which implements the encryption algorithm
|
||||
*/
|
||||
esp_err_t (*encrypt)(uint32_t session_id,
|
||||
const uint8_t *inbuf, ssize_t inlen,
|
||||
uint8_t *outbuf, ssize_t *outlen);
|
||||
|
||||
/**
|
||||
* Function which implements the decryption algorithm
|
||||
*/
|
||||
esp_err_t (*decrypt)(uint32_t session_id,
|
||||
const uint8_t *inbuf, ssize_t inlen,
|
||||
uint8_t *outbuf, ssize_t *outlen);
|
||||
} protocomm_security_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
33
components/protocomm/include/security/protocomm_security0.h
Normal file
33
components/protocomm/include/security/protocomm_security0.h
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <protocomm_security.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Protocomm security version 0 implementation
|
||||
*
|
||||
* This is a simple implementation to be used when no
|
||||
* security is required for the protocomm instance
|
||||
*/
|
||||
extern const protocomm_security_t protocomm_security0;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
33
components/protocomm/include/security/protocomm_security1.h
Normal file
33
components/protocomm/include/security/protocomm_security1.h
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <protocomm_security.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Protocomm security version 1 implementation
|
||||
*
|
||||
* 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
|
100
components/protocomm/include/transports/protocomm_ble.h
Normal file
100
components/protocomm/include/transports/protocomm_ble.h
Normal file
@ -0,0 +1,100 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <protocomm.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* BLE device name cannot be larger than this value
|
||||
*/
|
||||
#define MAX_BLE_DEVNAME_LEN 13
|
||||
|
||||
/**
|
||||
* @brief This structure maps handler required by protocomm layer to
|
||||
* UUIDs which are used to uniquely identify BLE characteristics
|
||||
* from a smartphone or a similar client device.
|
||||
*/
|
||||
typedef struct name_uuid {
|
||||
/**
|
||||
* Name of the handler, which is passed to protocomm layer
|
||||
*/
|
||||
const char *name;
|
||||
|
||||
/**
|
||||
* UUID to be assigned to the BLE characteristic which is
|
||||
* mapped to the handler
|
||||
*/
|
||||
uint16_t uuid;
|
||||
} protocomm_ble_name_uuid_t;
|
||||
|
||||
/**
|
||||
* @brief Config parameters for protocomm BLE service
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* BLE device name being broadcast at the time of provisioning
|
||||
*/
|
||||
char device_name[MAX_BLE_DEVNAME_LEN];
|
||||
uint8_t service_uuid[16]; /*!< SSID of the provisioning service */
|
||||
ssize_t nu_lookup_count; /*!< Number of entries in the Name-UUID lookup table */
|
||||
|
||||
/**
|
||||
* Pointer to the Name-UUID lookup table
|
||||
*/
|
||||
protocomm_ble_name_uuid_t *nu_lookup;
|
||||
} protocomm_ble_config_t;
|
||||
|
||||
/**
|
||||
* @brief Start Bluetooth Low Energy based transport layer for provisioning
|
||||
*
|
||||
* Initialize and start required BLE service for provisioning. This includes
|
||||
* 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 initializing BLE
|
||||
*
|
||||
* @return
|
||||
* - 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
|
||||
* - ESP_ERR_INVALID_ARG : Null arguments
|
||||
*/
|
||||
esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Stop Bluetooth Low Energy based transport layer for provisioning
|
||||
*
|
||||
* Stops service/task responsible for BLE based interactions for provisioning
|
||||
*
|
||||
* @note You might want to optionally reclaim memory from Bluetooth.
|
||||
* Refer to the documentation of `esp_bt_mem_release` in that case.
|
||||
*
|
||||
* @param[in] pc Same protocomm instance that was passed to protocomm_ble_start()
|
||||
*
|
||||
* @return
|
||||
* - 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
|
67
components/protocomm/include/transports/protocomm_console.h
Normal file
67
components/protocomm/include/transports/protocomm_console.h
Normal file
@ -0,0 +1,67 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <protocomm.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PROTOCOMM_CONSOLE_DEFAULT_CONFIG() { \
|
||||
.stack_size = 4096, \
|
||||
.task_priority = tskIDLE_PRIORITY + 3, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Config parameters for protocomm console
|
||||
*/
|
||||
typedef struct {
|
||||
size_t stack_size; /*!< Stack size of console task */
|
||||
unsigned task_priority; /*!< Priority of console task */
|
||||
} protocomm_console_config_t;
|
||||
|
||||
/**
|
||||
* @brief Start console based protocomm transport
|
||||
*
|
||||
* @note This is a singleton. ie. Protocomm can have multiple instances, but only
|
||||
* one instance can be bound to a console based transport layer.
|
||||
*
|
||||
* @param[in] pc Protocomm instance pointer obtained from protocomm_new()
|
||||
* @param[in] config Config param structure for protocomm console
|
||||
*
|
||||
* @return
|
||||
* - 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
|
||||
* - ESP_FAIL : Failed to start console thread
|
||||
*/
|
||||
esp_err_t protocomm_console_start(protocomm_t *pc, const protocomm_console_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Stop console protocomm transport
|
||||
*
|
||||
* @param[in] pc Same protocomm instance that was passed to protocomm_console_start()
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Success
|
||||
* - ESP_ERR_INVALID_ARG : Null / incorrect protocomm instance pointer
|
||||
*/
|
||||
esp_err_t protocomm_console_stop(protocomm_t *pc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
107
components/protocomm/include/transports/protocomm_httpd.h
Normal file
107
components/protocomm/include/transports/protocomm_httpd.h
Normal file
@ -0,0 +1,107 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <protocomm.h>
|
||||
|
||||
#define PROTOCOMM_HTTPD_DEFAULT_CONFIG() { \
|
||||
.port = 80, \
|
||||
.stack_size = 4096, \
|
||||
.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 */
|
||||
|
||||
/**
|
||||
* Stack size of server task, adjusted depending
|
||||
* upon stack usage of endpoint handler
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* @brief Start HTTPD protocomm transport
|
||||
*
|
||||
* This API internally creates a framework to allow endpoint registration and security
|
||||
* configuration for the protocomm.
|
||||
*
|
||||
* @note This is a singleton. ie. Protocomm can have multiple instances, but only
|
||||
* 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 initializing HTTP server
|
||||
*
|
||||
* @return
|
||||
* - 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
|
||||
* - ESP_ERR_NO_MEM : Memory allocation for server resource failed
|
||||
* - ESP_ERR_HTTPD_* : HTTP server error on start
|
||||
*/
|
||||
esp_err_t protocomm_httpd_start(protocomm_t *pc, const protocomm_httpd_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Stop HTTPD protocomm transport
|
||||
*
|
||||
* This API cleans up the HTTPD transport protocomm and frees all the handlers registered
|
||||
* with the protocomm.
|
||||
*
|
||||
* @param[in] pc Same protocomm instance that was passed to protocomm_httpd_start()
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Success
|
||||
* - ESP_ERR_INVALID_ARG : Null / incorrect protocomm instance pointer
|
||||
*/
|
||||
esp_err_t protocomm_httpd_stop(protocomm_t *pc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
49
components/protocomm/proto-c/constants.pb-c.c
Normal file
49
components/protocomm/proto-c/constants.pb-c.c
Normal file
@ -0,0 +1,49 @@
|
||||
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
|
||||
/* Generated from: constants.proto */
|
||||
|
||||
/* Do not generate deprecated warnings for self */
|
||||
#ifndef PROTOBUF_C__NO_DEPRECATED
|
||||
#define PROTOBUF_C__NO_DEPRECATED
|
||||
#endif
|
||||
|
||||
#include "constants.pb-c.h"
|
||||
static const ProtobufCEnumValue status__enum_values_by_number[8] =
|
||||
{
|
||||
{ "Success", "STATUS__Success", 0 },
|
||||
{ "InvalidSecScheme", "STATUS__InvalidSecScheme", 1 },
|
||||
{ "InvalidProto", "STATUS__InvalidProto", 2 },
|
||||
{ "TooManySessions", "STATUS__TooManySessions", 3 },
|
||||
{ "InvalidArgument", "STATUS__InvalidArgument", 4 },
|
||||
{ "InternalError", "STATUS__InternalError", 5 },
|
||||
{ "CryptoError", "STATUS__CryptoError", 6 },
|
||||
{ "InvalidSession", "STATUS__InvalidSession", 7 },
|
||||
};
|
||||
static const ProtobufCIntRange status__value_ranges[] = {
|
||||
{0, 0},{0, 8}
|
||||
};
|
||||
static const ProtobufCEnumValueIndex status__enum_values_by_name[8] =
|
||||
{
|
||||
{ "CryptoError", 6 },
|
||||
{ "InternalError", 5 },
|
||||
{ "InvalidArgument", 4 },
|
||||
{ "InvalidProto", 2 },
|
||||
{ "InvalidSecScheme", 1 },
|
||||
{ "InvalidSession", 7 },
|
||||
{ "Success", 0 },
|
||||
{ "TooManySessions", 3 },
|
||||
};
|
||||
const ProtobufCEnumDescriptor status__descriptor =
|
||||
{
|
||||
PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,
|
||||
"Status",
|
||||
"Status",
|
||||
"Status",
|
||||
"",
|
||||
8,
|
||||
status__enum_values_by_number,
|
||||
8,
|
||||
status__enum_values_by_name,
|
||||
1,
|
||||
status__value_ranges,
|
||||
NULL,NULL,NULL,NULL /* reserved[1234] */
|
||||
};
|
53
components/protocomm/proto-c/constants.pb-c.h
Normal file
53
components/protocomm/proto-c/constants.pb-c.h
Normal file
@ -0,0 +1,53 @@
|
||||
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
|
||||
/* Generated from: constants.proto */
|
||||
|
||||
#ifndef PROTOBUF_C_constants_2eproto__INCLUDED
|
||||
#define PROTOBUF_C_constants_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 1003000 < 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
|
||||
|
||||
|
||||
|
||||
|
||||
/* --- enums --- */
|
||||
|
||||
/*
|
||||
* Allowed values for the status
|
||||
* of a protocomm instance
|
||||
*/
|
||||
typedef enum _Status {
|
||||
STATUS__Success = 0,
|
||||
STATUS__InvalidSecScheme = 1,
|
||||
STATUS__InvalidProto = 2,
|
||||
STATUS__TooManySessions = 3,
|
||||
STATUS__InvalidArgument = 4,
|
||||
STATUS__InternalError = 5,
|
||||
STATUS__CryptoError = 6,
|
||||
STATUS__InvalidSession = 7
|
||||
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(STATUS)
|
||||
} Status;
|
||||
|
||||
/* --- messages --- */
|
||||
|
||||
/* --- per-message closures --- */
|
||||
|
||||
|
||||
/* --- services --- */
|
||||
|
||||
|
||||
/* --- descriptors --- */
|
||||
|
||||
extern const ProtobufCEnumDescriptor status__descriptor;
|
||||
|
||||
PROTOBUF_C__END_DECLS
|
||||
|
||||
|
||||
#endif /* PROTOBUF_C_constants_2eproto__INCLUDED */
|
293
components/protocomm/proto-c/sec0.pb-c.c
Normal file
293
components/protocomm/proto-c/sec0.pb-c.c
Normal file
@ -0,0 +1,293 @@
|
||||
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
|
||||
/* Generated from: sec0.proto */
|
||||
|
||||
/* Do not generate deprecated warnings for self */
|
||||
#ifndef PROTOBUF_C__NO_DEPRECATED
|
||||
#define PROTOBUF_C__NO_DEPRECATED
|
||||
#endif
|
||||
|
||||
#include "sec0.pb-c.h"
|
||||
void s0_session_cmd__init
|
||||
(S0SessionCmd *message)
|
||||
{
|
||||
static const S0SessionCmd init_value = S0_SESSION_CMD__INIT;
|
||||
*message = init_value;
|
||||
}
|
||||
size_t s0_session_cmd__get_packed_size
|
||||
(const S0SessionCmd *message)
|
||||
{
|
||||
assert(message->base.descriptor == &s0_session_cmd__descriptor);
|
||||
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||
}
|
||||
size_t s0_session_cmd__pack
|
||||
(const S0SessionCmd *message,
|
||||
uint8_t *out)
|
||||
{
|
||||
assert(message->base.descriptor == &s0_session_cmd__descriptor);
|
||||
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||
}
|
||||
size_t s0_session_cmd__pack_to_buffer
|
||||
(const S0SessionCmd *message,
|
||||
ProtobufCBuffer *buffer)
|
||||
{
|
||||
assert(message->base.descriptor == &s0_session_cmd__descriptor);
|
||||
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||
}
|
||||
S0SessionCmd *
|
||||
s0_session_cmd__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data)
|
||||
{
|
||||
return (S0SessionCmd *)
|
||||
protobuf_c_message_unpack (&s0_session_cmd__descriptor,
|
||||
allocator, len, data);
|
||||
}
|
||||
void s0_session_cmd__free_unpacked
|
||||
(S0SessionCmd *message,
|
||||
ProtobufCAllocator *allocator)
|
||||
{
|
||||
if(!message)
|
||||
return;
|
||||
assert(message->base.descriptor == &s0_session_cmd__descriptor);
|
||||
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||
}
|
||||
void s0_session_resp__init
|
||||
(S0SessionResp *message)
|
||||
{
|
||||
static const S0SessionResp init_value = S0_SESSION_RESP__INIT;
|
||||
*message = init_value;
|
||||
}
|
||||
size_t s0_session_resp__get_packed_size
|
||||
(const S0SessionResp *message)
|
||||
{
|
||||
assert(message->base.descriptor == &s0_session_resp__descriptor);
|
||||
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||
}
|
||||
size_t s0_session_resp__pack
|
||||
(const S0SessionResp *message,
|
||||
uint8_t *out)
|
||||
{
|
||||
assert(message->base.descriptor == &s0_session_resp__descriptor);
|
||||
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||
}
|
||||
size_t s0_session_resp__pack_to_buffer
|
||||
(const S0SessionResp *message,
|
||||
ProtobufCBuffer *buffer)
|
||||
{
|
||||
assert(message->base.descriptor == &s0_session_resp__descriptor);
|
||||
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||
}
|
||||
S0SessionResp *
|
||||
s0_session_resp__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data)
|
||||
{
|
||||
return (S0SessionResp *)
|
||||
protobuf_c_message_unpack (&s0_session_resp__descriptor,
|
||||
allocator, len, data);
|
||||
}
|
||||
void s0_session_resp__free_unpacked
|
||||
(S0SessionResp *message,
|
||||
ProtobufCAllocator *allocator)
|
||||
{
|
||||
if(!message)
|
||||
return;
|
||||
assert(message->base.descriptor == &s0_session_resp__descriptor);
|
||||
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||
}
|
||||
void sec0_payload__init
|
||||
(Sec0Payload *message)
|
||||
{
|
||||
static const Sec0Payload init_value = SEC0_PAYLOAD__INIT;
|
||||
*message = init_value;
|
||||
}
|
||||
size_t sec0_payload__get_packed_size
|
||||
(const Sec0Payload *message)
|
||||
{
|
||||
assert(message->base.descriptor == &sec0_payload__descriptor);
|
||||
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||
}
|
||||
size_t sec0_payload__pack
|
||||
(const Sec0Payload *message,
|
||||
uint8_t *out)
|
||||
{
|
||||
assert(message->base.descriptor == &sec0_payload__descriptor);
|
||||
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||
}
|
||||
size_t sec0_payload__pack_to_buffer
|
||||
(const Sec0Payload *message,
|
||||
ProtobufCBuffer *buffer)
|
||||
{
|
||||
assert(message->base.descriptor == &sec0_payload__descriptor);
|
||||
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||
}
|
||||
Sec0Payload *
|
||||
sec0_payload__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data)
|
||||
{
|
||||
return (Sec0Payload *)
|
||||
protobuf_c_message_unpack (&sec0_payload__descriptor,
|
||||
allocator, len, data);
|
||||
}
|
||||
void sec0_payload__free_unpacked
|
||||
(Sec0Payload *message,
|
||||
ProtobufCAllocator *allocator)
|
||||
{
|
||||
if(!message)
|
||||
return;
|
||||
assert(message->base.descriptor == &sec0_payload__descriptor);
|
||||
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||
}
|
||||
#define s0_session_cmd__field_descriptors NULL
|
||||
#define s0_session_cmd__field_indices_by_name NULL
|
||||
#define s0_session_cmd__number_ranges NULL
|
||||
const ProtobufCMessageDescriptor s0_session_cmd__descriptor =
|
||||
{
|
||||
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
|
||||
"S0SessionCmd",
|
||||
"S0SessionCmd",
|
||||
"S0SessionCmd",
|
||||
"",
|
||||
sizeof(S0SessionCmd),
|
||||
0,
|
||||
s0_session_cmd__field_descriptors,
|
||||
s0_session_cmd__field_indices_by_name,
|
||||
0, s0_session_cmd__number_ranges,
|
||||
(ProtobufCMessageInit) s0_session_cmd__init,
|
||||
NULL,NULL,NULL /* reserved[123] */
|
||||
};
|
||||
static const ProtobufCFieldDescriptor s0_session_resp__field_descriptors[1] =
|
||||
{
|
||||
{
|
||||
"status",
|
||||
1,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_ENUM,
|
||||
0, /* quantifier_offset */
|
||||
offsetof(S0SessionResp, status),
|
||||
&status__descriptor,
|
||||
NULL,
|
||||
0, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
};
|
||||
static const unsigned s0_session_resp__field_indices_by_name[] = {
|
||||
0, /* field[0] = status */
|
||||
};
|
||||
static const ProtobufCIntRange s0_session_resp__number_ranges[1 + 1] =
|
||||
{
|
||||
{ 1, 0 },
|
||||
{ 0, 1 }
|
||||
};
|
||||
const ProtobufCMessageDescriptor s0_session_resp__descriptor =
|
||||
{
|
||||
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
|
||||
"S0SessionResp",
|
||||
"S0SessionResp",
|
||||
"S0SessionResp",
|
||||
"",
|
||||
sizeof(S0SessionResp),
|
||||
1,
|
||||
s0_session_resp__field_descriptors,
|
||||
s0_session_resp__field_indices_by_name,
|
||||
1, s0_session_resp__number_ranges,
|
||||
(ProtobufCMessageInit) s0_session_resp__init,
|
||||
NULL,NULL,NULL /* reserved[123] */
|
||||
};
|
||||
static const ProtobufCFieldDescriptor sec0_payload__field_descriptors[3] =
|
||||
{
|
||||
{
|
||||
"msg",
|
||||
1,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_ENUM,
|
||||
0, /* quantifier_offset */
|
||||
offsetof(Sec0Payload, msg),
|
||||
&sec0_msg_type__descriptor,
|
||||
NULL,
|
||||
0, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"sc",
|
||||
20,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_MESSAGE,
|
||||
offsetof(Sec0Payload, payload_case),
|
||||
offsetof(Sec0Payload, sc),
|
||||
&s0_session_cmd__descriptor,
|
||||
NULL,
|
||||
0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"sr",
|
||||
21,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_MESSAGE,
|
||||
offsetof(Sec0Payload, payload_case),
|
||||
offsetof(Sec0Payload, sr),
|
||||
&s0_session_resp__descriptor,
|
||||
NULL,
|
||||
0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
};
|
||||
static const unsigned sec0_payload__field_indices_by_name[] = {
|
||||
0, /* field[0] = msg */
|
||||
1, /* field[1] = sc */
|
||||
2, /* field[2] = sr */
|
||||
};
|
||||
static const ProtobufCIntRange sec0_payload__number_ranges[2 + 1] =
|
||||
{
|
||||
{ 1, 0 },
|
||||
{ 20, 1 },
|
||||
{ 0, 3 }
|
||||
};
|
||||
const ProtobufCMessageDescriptor sec0_payload__descriptor =
|
||||
{
|
||||
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
|
||||
"Sec0Payload",
|
||||
"Sec0Payload",
|
||||
"Sec0Payload",
|
||||
"",
|
||||
sizeof(Sec0Payload),
|
||||
3,
|
||||
sec0_payload__field_descriptors,
|
||||
sec0_payload__field_indices_by_name,
|
||||
2, sec0_payload__number_ranges,
|
||||
(ProtobufCMessageInit) sec0_payload__init,
|
||||
NULL,NULL,NULL /* reserved[123] */
|
||||
};
|
||||
static const ProtobufCEnumValue sec0_msg_type__enum_values_by_number[2] =
|
||||
{
|
||||
{ "S0_Session_Command", "SEC0_MSG_TYPE__S0_Session_Command", 0 },
|
||||
{ "S0_Session_Response", "SEC0_MSG_TYPE__S0_Session_Response", 1 },
|
||||
};
|
||||
static const ProtobufCIntRange sec0_msg_type__value_ranges[] = {
|
||||
{0, 0},{0, 2}
|
||||
};
|
||||
static const ProtobufCEnumValueIndex sec0_msg_type__enum_values_by_name[2] =
|
||||
{
|
||||
{ "S0_Session_Command", 0 },
|
||||
{ "S0_Session_Response", 1 },
|
||||
};
|
||||
const ProtobufCEnumDescriptor sec0_msg_type__descriptor =
|
||||
{
|
||||
PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,
|
||||
"Sec0MsgType",
|
||||
"Sec0MsgType",
|
||||
"Sec0MsgType",
|
||||
"",
|
||||
2,
|
||||
sec0_msg_type__enum_values_by_number,
|
||||
2,
|
||||
sec0_msg_type__enum_values_by_name,
|
||||
1,
|
||||
sec0_msg_type__value_ranges,
|
||||
NULL,NULL,NULL,NULL /* reserved[1234] */
|
||||
};
|
178
components/protocomm/proto-c/sec0.pb-c.h
Normal file
178
components/protocomm/proto-c/sec0.pb-c.h
Normal file
@ -0,0 +1,178 @@
|
||||
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
|
||||
/* Generated from: sec0.proto */
|
||||
|
||||
#ifndef PROTOBUF_C_sec0_2eproto__INCLUDED
|
||||
#define PROTOBUF_C_sec0_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 1003000 < 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
|
||||
|
||||
#include "constants.pb-c.h"
|
||||
|
||||
typedef struct _S0SessionCmd S0SessionCmd;
|
||||
typedef struct _S0SessionResp S0SessionResp;
|
||||
typedef struct _Sec0Payload Sec0Payload;
|
||||
|
||||
|
||||
/* --- enums --- */
|
||||
|
||||
/*
|
||||
* A message must be of type Cmd or Resp
|
||||
*/
|
||||
typedef enum _Sec0MsgType {
|
||||
SEC0_MSG_TYPE__S0_Session_Command = 0,
|
||||
SEC0_MSG_TYPE__S0_Session_Response = 1
|
||||
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SEC0_MSG_TYPE)
|
||||
} Sec0MsgType;
|
||||
|
||||
/* --- messages --- */
|
||||
|
||||
/*
|
||||
* Data structure of Session command/request packet
|
||||
*/
|
||||
struct _S0SessionCmd
|
||||
{
|
||||
ProtobufCMessage base;
|
||||
};
|
||||
#define S0_SESSION_CMD__INIT \
|
||||
{ PROTOBUF_C_MESSAGE_INIT (&s0_session_cmd__descriptor) \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Data structure of Session response packet
|
||||
*/
|
||||
struct _S0SessionResp
|
||||
{
|
||||
ProtobufCMessage base;
|
||||
Status status;
|
||||
};
|
||||
#define S0_SESSION_RESP__INIT \
|
||||
{ PROTOBUF_C_MESSAGE_INIT (&s0_session_resp__descriptor) \
|
||||
, STATUS__Success }
|
||||
|
||||
|
||||
typedef enum {
|
||||
SEC0_PAYLOAD__PAYLOAD__NOT_SET = 0,
|
||||
SEC0_PAYLOAD__PAYLOAD_SC = 20,
|
||||
SEC0_PAYLOAD__PAYLOAD_SR = 21
|
||||
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SEC0_PAYLOAD__PAYLOAD)
|
||||
} Sec0Payload__PayloadCase;
|
||||
|
||||
/*
|
||||
* Payload structure of session data
|
||||
*/
|
||||
struct _Sec0Payload
|
||||
{
|
||||
ProtobufCMessage base;
|
||||
/*
|
||||
*!< Type of message
|
||||
*/
|
||||
Sec0MsgType msg;
|
||||
Sec0Payload__PayloadCase payload_case;
|
||||
union {
|
||||
/*
|
||||
*!< Payload data interpreted as Cmd
|
||||
*/
|
||||
S0SessionCmd *sc;
|
||||
/*
|
||||
*!< Payload data interpreted as Resp
|
||||
*/
|
||||
S0SessionResp *sr;
|
||||
};
|
||||
};
|
||||
#define SEC0_PAYLOAD__INIT \
|
||||
{ PROTOBUF_C_MESSAGE_INIT (&sec0_payload__descriptor) \
|
||||
, SEC0_MSG_TYPE__S0_Session_Command, SEC0_PAYLOAD__PAYLOAD__NOT_SET, {0} }
|
||||
|
||||
|
||||
/* S0SessionCmd methods */
|
||||
void s0_session_cmd__init
|
||||
(S0SessionCmd *message);
|
||||
size_t s0_session_cmd__get_packed_size
|
||||
(const S0SessionCmd *message);
|
||||
size_t s0_session_cmd__pack
|
||||
(const S0SessionCmd *message,
|
||||
uint8_t *out);
|
||||
size_t s0_session_cmd__pack_to_buffer
|
||||
(const S0SessionCmd *message,
|
||||
ProtobufCBuffer *buffer);
|
||||
S0SessionCmd *
|
||||
s0_session_cmd__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data);
|
||||
void s0_session_cmd__free_unpacked
|
||||
(S0SessionCmd *message,
|
||||
ProtobufCAllocator *allocator);
|
||||
/* S0SessionResp methods */
|
||||
void s0_session_resp__init
|
||||
(S0SessionResp *message);
|
||||
size_t s0_session_resp__get_packed_size
|
||||
(const S0SessionResp *message);
|
||||
size_t s0_session_resp__pack
|
||||
(const S0SessionResp *message,
|
||||
uint8_t *out);
|
||||
size_t s0_session_resp__pack_to_buffer
|
||||
(const S0SessionResp *message,
|
||||
ProtobufCBuffer *buffer);
|
||||
S0SessionResp *
|
||||
s0_session_resp__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data);
|
||||
void s0_session_resp__free_unpacked
|
||||
(S0SessionResp *message,
|
||||
ProtobufCAllocator *allocator);
|
||||
/* Sec0Payload methods */
|
||||
void sec0_payload__init
|
||||
(Sec0Payload *message);
|
||||
size_t sec0_payload__get_packed_size
|
||||
(const Sec0Payload *message);
|
||||
size_t sec0_payload__pack
|
||||
(const Sec0Payload *message,
|
||||
uint8_t *out);
|
||||
size_t sec0_payload__pack_to_buffer
|
||||
(const Sec0Payload *message,
|
||||
ProtobufCBuffer *buffer);
|
||||
Sec0Payload *
|
||||
sec0_payload__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data);
|
||||
void sec0_payload__free_unpacked
|
||||
(Sec0Payload *message,
|
||||
ProtobufCAllocator *allocator);
|
||||
/* --- per-message closures --- */
|
||||
|
||||
typedef void (*S0SessionCmd_Closure)
|
||||
(const S0SessionCmd *message,
|
||||
void *closure_data);
|
||||
typedef void (*S0SessionResp_Closure)
|
||||
(const S0SessionResp *message,
|
||||
void *closure_data);
|
||||
typedef void (*Sec0Payload_Closure)
|
||||
(const Sec0Payload *message,
|
||||
void *closure_data);
|
||||
|
||||
/* --- services --- */
|
||||
|
||||
|
||||
/* --- descriptors --- */
|
||||
|
||||
extern const ProtobufCEnumDescriptor sec0_msg_type__descriptor;
|
||||
extern const ProtobufCMessageDescriptor s0_session_cmd__descriptor;
|
||||
extern const ProtobufCMessageDescriptor s0_session_resp__descriptor;
|
||||
extern const ProtobufCMessageDescriptor sec0_payload__descriptor;
|
||||
|
||||
PROTOBUF_C__END_DECLS
|
||||
|
||||
|
||||
#endif /* PROTOBUF_C_sec0_2eproto__INCLUDED */
|
549
components/protocomm/proto-c/sec1.pb-c.c
Normal file
549
components/protocomm/proto-c/sec1.pb-c.c
Normal file
@ -0,0 +1,549 @@
|
||||
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
|
||||
/* Generated from: sec1.proto */
|
||||
|
||||
/* Do not generate deprecated warnings for self */
|
||||
#ifndef PROTOBUF_C__NO_DEPRECATED
|
||||
#define PROTOBUF_C__NO_DEPRECATED
|
||||
#endif
|
||||
|
||||
#include "sec1.pb-c.h"
|
||||
void session_cmd1__init
|
||||
(SessionCmd1 *message)
|
||||
{
|
||||
static const SessionCmd1 init_value = SESSION_CMD1__INIT;
|
||||
*message = init_value;
|
||||
}
|
||||
size_t session_cmd1__get_packed_size
|
||||
(const SessionCmd1 *message)
|
||||
{
|
||||
assert(message->base.descriptor == &session_cmd1__descriptor);
|
||||
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||
}
|
||||
size_t session_cmd1__pack
|
||||
(const SessionCmd1 *message,
|
||||
uint8_t *out)
|
||||
{
|
||||
assert(message->base.descriptor == &session_cmd1__descriptor);
|
||||
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||
}
|
||||
size_t session_cmd1__pack_to_buffer
|
||||
(const SessionCmd1 *message,
|
||||
ProtobufCBuffer *buffer)
|
||||
{
|
||||
assert(message->base.descriptor == &session_cmd1__descriptor);
|
||||
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||
}
|
||||
SessionCmd1 *
|
||||
session_cmd1__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data)
|
||||
{
|
||||
return (SessionCmd1 *)
|
||||
protobuf_c_message_unpack (&session_cmd1__descriptor,
|
||||
allocator, len, data);
|
||||
}
|
||||
void session_cmd1__free_unpacked
|
||||
(SessionCmd1 *message,
|
||||
ProtobufCAllocator *allocator)
|
||||
{
|
||||
if(!message)
|
||||
return;
|
||||
assert(message->base.descriptor == &session_cmd1__descriptor);
|
||||
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||
}
|
||||
void session_resp1__init
|
||||
(SessionResp1 *message)
|
||||
{
|
||||
static const SessionResp1 init_value = SESSION_RESP1__INIT;
|
||||
*message = init_value;
|
||||
}
|
||||
size_t session_resp1__get_packed_size
|
||||
(const SessionResp1 *message)
|
||||
{
|
||||
assert(message->base.descriptor == &session_resp1__descriptor);
|
||||
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||
}
|
||||
size_t session_resp1__pack
|
||||
(const SessionResp1 *message,
|
||||
uint8_t *out)
|
||||
{
|
||||
assert(message->base.descriptor == &session_resp1__descriptor);
|
||||
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||
}
|
||||
size_t session_resp1__pack_to_buffer
|
||||
(const SessionResp1 *message,
|
||||
ProtobufCBuffer *buffer)
|
||||
{
|
||||
assert(message->base.descriptor == &session_resp1__descriptor);
|
||||
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||
}
|
||||
SessionResp1 *
|
||||
session_resp1__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data)
|
||||
{
|
||||
return (SessionResp1 *)
|
||||
protobuf_c_message_unpack (&session_resp1__descriptor,
|
||||
allocator, len, data);
|
||||
}
|
||||
void session_resp1__free_unpacked
|
||||
(SessionResp1 *message,
|
||||
ProtobufCAllocator *allocator)
|
||||
{
|
||||
if(!message)
|
||||
return;
|
||||
assert(message->base.descriptor == &session_resp1__descriptor);
|
||||
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||
}
|
||||
void session_cmd0__init
|
||||
(SessionCmd0 *message)
|
||||
{
|
||||
static const SessionCmd0 init_value = SESSION_CMD0__INIT;
|
||||
*message = init_value;
|
||||
}
|
||||
size_t session_cmd0__get_packed_size
|
||||
(const SessionCmd0 *message)
|
||||
{
|
||||
assert(message->base.descriptor == &session_cmd0__descriptor);
|
||||
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||
}
|
||||
size_t session_cmd0__pack
|
||||
(const SessionCmd0 *message,
|
||||
uint8_t *out)
|
||||
{
|
||||
assert(message->base.descriptor == &session_cmd0__descriptor);
|
||||
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||
}
|
||||
size_t session_cmd0__pack_to_buffer
|
||||
(const SessionCmd0 *message,
|
||||
ProtobufCBuffer *buffer)
|
||||
{
|
||||
assert(message->base.descriptor == &session_cmd0__descriptor);
|
||||
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||
}
|
||||
SessionCmd0 *
|
||||
session_cmd0__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data)
|
||||
{
|
||||
return (SessionCmd0 *)
|
||||
protobuf_c_message_unpack (&session_cmd0__descriptor,
|
||||
allocator, len, data);
|
||||
}
|
||||
void session_cmd0__free_unpacked
|
||||
(SessionCmd0 *message,
|
||||
ProtobufCAllocator *allocator)
|
||||
{
|
||||
if(!message)
|
||||
return;
|
||||
assert(message->base.descriptor == &session_cmd0__descriptor);
|
||||
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||
}
|
||||
void session_resp0__init
|
||||
(SessionResp0 *message)
|
||||
{
|
||||
static const SessionResp0 init_value = SESSION_RESP0__INIT;
|
||||
*message = init_value;
|
||||
}
|
||||
size_t session_resp0__get_packed_size
|
||||
(const SessionResp0 *message)
|
||||
{
|
||||
assert(message->base.descriptor == &session_resp0__descriptor);
|
||||
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||
}
|
||||
size_t session_resp0__pack
|
||||
(const SessionResp0 *message,
|
||||
uint8_t *out)
|
||||
{
|
||||
assert(message->base.descriptor == &session_resp0__descriptor);
|
||||
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||
}
|
||||
size_t session_resp0__pack_to_buffer
|
||||
(const SessionResp0 *message,
|
||||
ProtobufCBuffer *buffer)
|
||||
{
|
||||
assert(message->base.descriptor == &session_resp0__descriptor);
|
||||
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||
}
|
||||
SessionResp0 *
|
||||
session_resp0__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data)
|
||||
{
|
||||
return (SessionResp0 *)
|
||||
protobuf_c_message_unpack (&session_resp0__descriptor,
|
||||
allocator, len, data);
|
||||
}
|
||||
void session_resp0__free_unpacked
|
||||
(SessionResp0 *message,
|
||||
ProtobufCAllocator *allocator)
|
||||
{
|
||||
if(!message)
|
||||
return;
|
||||
assert(message->base.descriptor == &session_resp0__descriptor);
|
||||
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||
}
|
||||
void sec1_payload__init
|
||||
(Sec1Payload *message)
|
||||
{
|
||||
static const Sec1Payload init_value = SEC1_PAYLOAD__INIT;
|
||||
*message = init_value;
|
||||
}
|
||||
size_t sec1_payload__get_packed_size
|
||||
(const Sec1Payload *message)
|
||||
{
|
||||
assert(message->base.descriptor == &sec1_payload__descriptor);
|
||||
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||
}
|
||||
size_t sec1_payload__pack
|
||||
(const Sec1Payload *message,
|
||||
uint8_t *out)
|
||||
{
|
||||
assert(message->base.descriptor == &sec1_payload__descriptor);
|
||||
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||
}
|
||||
size_t sec1_payload__pack_to_buffer
|
||||
(const Sec1Payload *message,
|
||||
ProtobufCBuffer *buffer)
|
||||
{
|
||||
assert(message->base.descriptor == &sec1_payload__descriptor);
|
||||
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||
}
|
||||
Sec1Payload *
|
||||
sec1_payload__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data)
|
||||
{
|
||||
return (Sec1Payload *)
|
||||
protobuf_c_message_unpack (&sec1_payload__descriptor,
|
||||
allocator, len, data);
|
||||
}
|
||||
void sec1_payload__free_unpacked
|
||||
(Sec1Payload *message,
|
||||
ProtobufCAllocator *allocator)
|
||||
{
|
||||
if(!message)
|
||||
return;
|
||||
assert(message->base.descriptor == &sec1_payload__descriptor);
|
||||
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||
}
|
||||
static const ProtobufCFieldDescriptor session_cmd1__field_descriptors[1] =
|
||||
{
|
||||
{
|
||||
"client_verify_data",
|
||||
2,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
0, /* quantifier_offset */
|
||||
offsetof(SessionCmd1, client_verify_data),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
};
|
||||
static const unsigned session_cmd1__field_indices_by_name[] = {
|
||||
0, /* field[0] = client_verify_data */
|
||||
};
|
||||
static const ProtobufCIntRange session_cmd1__number_ranges[1 + 1] =
|
||||
{
|
||||
{ 2, 0 },
|
||||
{ 0, 1 }
|
||||
};
|
||||
const ProtobufCMessageDescriptor session_cmd1__descriptor =
|
||||
{
|
||||
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
|
||||
"SessionCmd1",
|
||||
"SessionCmd1",
|
||||
"SessionCmd1",
|
||||
"",
|
||||
sizeof(SessionCmd1),
|
||||
1,
|
||||
session_cmd1__field_descriptors,
|
||||
session_cmd1__field_indices_by_name,
|
||||
1, session_cmd1__number_ranges,
|
||||
(ProtobufCMessageInit) session_cmd1__init,
|
||||
NULL,NULL,NULL /* reserved[123] */
|
||||
};
|
||||
static const ProtobufCFieldDescriptor session_resp1__field_descriptors[2] =
|
||||
{
|
||||
{
|
||||
"status",
|
||||
1,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_ENUM,
|
||||
0, /* quantifier_offset */
|
||||
offsetof(SessionResp1, status),
|
||||
&status__descriptor,
|
||||
NULL,
|
||||
0, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"device_verify_data",
|
||||
3,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
0, /* quantifier_offset */
|
||||
offsetof(SessionResp1, device_verify_data),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
};
|
||||
static const unsigned session_resp1__field_indices_by_name[] = {
|
||||
1, /* field[1] = device_verify_data */
|
||||
0, /* field[0] = status */
|
||||
};
|
||||
static const ProtobufCIntRange session_resp1__number_ranges[2 + 1] =
|
||||
{
|
||||
{ 1, 0 },
|
||||
{ 3, 1 },
|
||||
{ 0, 2 }
|
||||
};
|
||||
const ProtobufCMessageDescriptor session_resp1__descriptor =
|
||||
{
|
||||
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
|
||||
"SessionResp1",
|
||||
"SessionResp1",
|
||||
"SessionResp1",
|
||||
"",
|
||||
sizeof(SessionResp1),
|
||||
2,
|
||||
session_resp1__field_descriptors,
|
||||
session_resp1__field_indices_by_name,
|
||||
2, session_resp1__number_ranges,
|
||||
(ProtobufCMessageInit) session_resp1__init,
|
||||
NULL,NULL,NULL /* reserved[123] */
|
||||
};
|
||||
static const ProtobufCFieldDescriptor session_cmd0__field_descriptors[1] =
|
||||
{
|
||||
{
|
||||
"client_pubkey",
|
||||
1,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
0, /* quantifier_offset */
|
||||
offsetof(SessionCmd0, client_pubkey),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
};
|
||||
static const unsigned session_cmd0__field_indices_by_name[] = {
|
||||
0, /* field[0] = client_pubkey */
|
||||
};
|
||||
static const ProtobufCIntRange session_cmd0__number_ranges[1 + 1] =
|
||||
{
|
||||
{ 1, 0 },
|
||||
{ 0, 1 }
|
||||
};
|
||||
const ProtobufCMessageDescriptor session_cmd0__descriptor =
|
||||
{
|
||||
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
|
||||
"SessionCmd0",
|
||||
"SessionCmd0",
|
||||
"SessionCmd0",
|
||||
"",
|
||||
sizeof(SessionCmd0),
|
||||
1,
|
||||
session_cmd0__field_descriptors,
|
||||
session_cmd0__field_indices_by_name,
|
||||
1, session_cmd0__number_ranges,
|
||||
(ProtobufCMessageInit) session_cmd0__init,
|
||||
NULL,NULL,NULL /* reserved[123] */
|
||||
};
|
||||
static const ProtobufCFieldDescriptor session_resp0__field_descriptors[3] =
|
||||
{
|
||||
{
|
||||
"status",
|
||||
1,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_ENUM,
|
||||
0, /* quantifier_offset */
|
||||
offsetof(SessionResp0, status),
|
||||
&status__descriptor,
|
||||
NULL,
|
||||
0, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"device_pubkey",
|
||||
2,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
0, /* quantifier_offset */
|
||||
offsetof(SessionResp0, device_pubkey),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"device_random",
|
||||
3,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
0, /* quantifier_offset */
|
||||
offsetof(SessionResp0, device_random),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
};
|
||||
static const unsigned session_resp0__field_indices_by_name[] = {
|
||||
1, /* field[1] = device_pubkey */
|
||||
2, /* field[2] = device_random */
|
||||
0, /* field[0] = status */
|
||||
};
|
||||
static const ProtobufCIntRange session_resp0__number_ranges[1 + 1] =
|
||||
{
|
||||
{ 1, 0 },
|
||||
{ 0, 3 }
|
||||
};
|
||||
const ProtobufCMessageDescriptor session_resp0__descriptor =
|
||||
{
|
||||
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
|
||||
"SessionResp0",
|
||||
"SessionResp0",
|
||||
"SessionResp0",
|
||||
"",
|
||||
sizeof(SessionResp0),
|
||||
3,
|
||||
session_resp0__field_descriptors,
|
||||
session_resp0__field_indices_by_name,
|
||||
1, session_resp0__number_ranges,
|
||||
(ProtobufCMessageInit) session_resp0__init,
|
||||
NULL,NULL,NULL /* reserved[123] */
|
||||
};
|
||||
static const ProtobufCFieldDescriptor sec1_payload__field_descriptors[5] =
|
||||
{
|
||||
{
|
||||
"msg",
|
||||
1,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_ENUM,
|
||||
0, /* quantifier_offset */
|
||||
offsetof(Sec1Payload, msg),
|
||||
&sec1_msg_type__descriptor,
|
||||
NULL,
|
||||
0, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"sc0",
|
||||
20,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_MESSAGE,
|
||||
offsetof(Sec1Payload, payload_case),
|
||||
offsetof(Sec1Payload, sc0),
|
||||
&session_cmd0__descriptor,
|
||||
NULL,
|
||||
0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"sr0",
|
||||
21,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_MESSAGE,
|
||||
offsetof(Sec1Payload, payload_case),
|
||||
offsetof(Sec1Payload, sr0),
|
||||
&session_resp0__descriptor,
|
||||
NULL,
|
||||
0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"sc1",
|
||||
22,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_MESSAGE,
|
||||
offsetof(Sec1Payload, payload_case),
|
||||
offsetof(Sec1Payload, sc1),
|
||||
&session_cmd1__descriptor,
|
||||
NULL,
|
||||
0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"sr1",
|
||||
23,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_MESSAGE,
|
||||
offsetof(Sec1Payload, payload_case),
|
||||
offsetof(Sec1Payload, sr1),
|
||||
&session_resp1__descriptor,
|
||||
NULL,
|
||||
0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
};
|
||||
static const unsigned sec1_payload__field_indices_by_name[] = {
|
||||
0, /* field[0] = msg */
|
||||
1, /* field[1] = sc0 */
|
||||
3, /* field[3] = sc1 */
|
||||
2, /* field[2] = sr0 */
|
||||
4, /* field[4] = sr1 */
|
||||
};
|
||||
static const ProtobufCIntRange sec1_payload__number_ranges[2 + 1] =
|
||||
{
|
||||
{ 1, 0 },
|
||||
{ 20, 1 },
|
||||
{ 0, 5 }
|
||||
};
|
||||
const ProtobufCMessageDescriptor sec1_payload__descriptor =
|
||||
{
|
||||
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
|
||||
"Sec1Payload",
|
||||
"Sec1Payload",
|
||||
"Sec1Payload",
|
||||
"",
|
||||
sizeof(Sec1Payload),
|
||||
5,
|
||||
sec1_payload__field_descriptors,
|
||||
sec1_payload__field_indices_by_name,
|
||||
2, sec1_payload__number_ranges,
|
||||
(ProtobufCMessageInit) sec1_payload__init,
|
||||
NULL,NULL,NULL /* reserved[123] */
|
||||
};
|
||||
static const ProtobufCEnumValue sec1_msg_type__enum_values_by_number[4] =
|
||||
{
|
||||
{ "Session_Command0", "SEC1_MSG_TYPE__Session_Command0", 0 },
|
||||
{ "Session_Response0", "SEC1_MSG_TYPE__Session_Response0", 1 },
|
||||
{ "Session_Command1", "SEC1_MSG_TYPE__Session_Command1", 2 },
|
||||
{ "Session_Response1", "SEC1_MSG_TYPE__Session_Response1", 3 },
|
||||
};
|
||||
static const ProtobufCIntRange sec1_msg_type__value_ranges[] = {
|
||||
{0, 0},{0, 4}
|
||||
};
|
||||
static const ProtobufCEnumValueIndex sec1_msg_type__enum_values_by_name[4] =
|
||||
{
|
||||
{ "Session_Command0", 0 },
|
||||
{ "Session_Command1", 2 },
|
||||
{ "Session_Response0", 1 },
|
||||
{ "Session_Response1", 3 },
|
||||
};
|
||||
const ProtobufCEnumDescriptor sec1_msg_type__descriptor =
|
||||
{
|
||||
PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,
|
||||
"Sec1MsgType",
|
||||
"Sec1MsgType",
|
||||
"Sec1MsgType",
|
||||
"",
|
||||
4,
|
||||
sec1_msg_type__enum_values_by_number,
|
||||
4,
|
||||
sec1_msg_type__enum_values_by_name,
|
||||
1,
|
||||
sec1_msg_type__value_ranges,
|
||||
NULL,NULL,NULL,NULL /* reserved[1234] */
|
||||
};
|
268
components/protocomm/proto-c/sec1.pb-c.h
Normal file
268
components/protocomm/proto-c/sec1.pb-c.h
Normal file
@ -0,0 +1,268 @@
|
||||
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
|
||||
/* Generated from: sec1.proto */
|
||||
|
||||
#ifndef PROTOBUF_C_sec1_2eproto__INCLUDED
|
||||
#define PROTOBUF_C_sec1_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 1003000 < 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
|
||||
|
||||
#include "constants.pb-c.h"
|
||||
|
||||
typedef struct _SessionCmd1 SessionCmd1;
|
||||
typedef struct _SessionResp1 SessionResp1;
|
||||
typedef struct _SessionCmd0 SessionCmd0;
|
||||
typedef struct _SessionResp0 SessionResp0;
|
||||
typedef struct _Sec1Payload Sec1Payload;
|
||||
|
||||
|
||||
/* --- enums --- */
|
||||
|
||||
/*
|
||||
* A message must be of type Cmd0 / Cmd1 / Resp0 / Resp1
|
||||
*/
|
||||
typedef enum _Sec1MsgType {
|
||||
SEC1_MSG_TYPE__Session_Command0 = 0,
|
||||
SEC1_MSG_TYPE__Session_Response0 = 1,
|
||||
SEC1_MSG_TYPE__Session_Command1 = 2,
|
||||
SEC1_MSG_TYPE__Session_Response1 = 3
|
||||
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SEC1_MSG_TYPE)
|
||||
} Sec1MsgType;
|
||||
|
||||
/* --- messages --- */
|
||||
|
||||
/*
|
||||
* Data structure of Session command1 packet
|
||||
*/
|
||||
struct _SessionCmd1
|
||||
{
|
||||
ProtobufCMessage base;
|
||||
ProtobufCBinaryData client_verify_data;
|
||||
};
|
||||
#define SESSION_CMD1__INIT \
|
||||
{ PROTOBUF_C_MESSAGE_INIT (&session_cmd1__descriptor) \
|
||||
, {0,NULL} }
|
||||
|
||||
|
||||
/*
|
||||
* Data structure of Session response1 packet
|
||||
*/
|
||||
struct _SessionResp1
|
||||
{
|
||||
ProtobufCMessage base;
|
||||
Status status;
|
||||
ProtobufCBinaryData device_verify_data;
|
||||
};
|
||||
#define SESSION_RESP1__INIT \
|
||||
{ PROTOBUF_C_MESSAGE_INIT (&session_resp1__descriptor) \
|
||||
, STATUS__Success, {0,NULL} }
|
||||
|
||||
|
||||
/*
|
||||
* Data structure of Session command0 packet
|
||||
*/
|
||||
struct _SessionCmd0
|
||||
{
|
||||
ProtobufCMessage base;
|
||||
ProtobufCBinaryData client_pubkey;
|
||||
};
|
||||
#define SESSION_CMD0__INIT \
|
||||
{ PROTOBUF_C_MESSAGE_INIT (&session_cmd0__descriptor) \
|
||||
, {0,NULL} }
|
||||
|
||||
|
||||
/*
|
||||
* Data structure of Session response0 packet
|
||||
*/
|
||||
struct _SessionResp0
|
||||
{
|
||||
ProtobufCMessage base;
|
||||
Status status;
|
||||
ProtobufCBinaryData device_pubkey;
|
||||
ProtobufCBinaryData device_random;
|
||||
};
|
||||
#define SESSION_RESP0__INIT \
|
||||
{ PROTOBUF_C_MESSAGE_INIT (&session_resp0__descriptor) \
|
||||
, STATUS__Success, {0,NULL}, {0,NULL} }
|
||||
|
||||
|
||||
typedef enum {
|
||||
SEC1_PAYLOAD__PAYLOAD__NOT_SET = 0,
|
||||
SEC1_PAYLOAD__PAYLOAD_SC0 = 20,
|
||||
SEC1_PAYLOAD__PAYLOAD_SR0 = 21,
|
||||
SEC1_PAYLOAD__PAYLOAD_SC1 = 22,
|
||||
SEC1_PAYLOAD__PAYLOAD_SR1 = 23
|
||||
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SEC1_PAYLOAD__PAYLOAD)
|
||||
} Sec1Payload__PayloadCase;
|
||||
|
||||
/*
|
||||
* Payload structure of session data
|
||||
*/
|
||||
struct _Sec1Payload
|
||||
{
|
||||
ProtobufCMessage base;
|
||||
/*
|
||||
*!< Type of message
|
||||
*/
|
||||
Sec1MsgType msg;
|
||||
Sec1Payload__PayloadCase payload_case;
|
||||
union {
|
||||
/*
|
||||
*!< Payload data interpreted as Cmd0
|
||||
*/
|
||||
SessionCmd0 *sc0;
|
||||
/*
|
||||
*!< Payload data interpreted as Resp0
|
||||
*/
|
||||
SessionResp0 *sr0;
|
||||
/*
|
||||
*!< Payload data interpreted as Cmd1
|
||||
*/
|
||||
SessionCmd1 *sc1;
|
||||
/*
|
||||
*!< Payload data interpreted as Resp1
|
||||
*/
|
||||
SessionResp1 *sr1;
|
||||
};
|
||||
};
|
||||
#define SEC1_PAYLOAD__INIT \
|
||||
{ PROTOBUF_C_MESSAGE_INIT (&sec1_payload__descriptor) \
|
||||
, SEC1_MSG_TYPE__Session_Command0, SEC1_PAYLOAD__PAYLOAD__NOT_SET, {0} }
|
||||
|
||||
|
||||
/* SessionCmd1 methods */
|
||||
void session_cmd1__init
|
||||
(SessionCmd1 *message);
|
||||
size_t session_cmd1__get_packed_size
|
||||
(const SessionCmd1 *message);
|
||||
size_t session_cmd1__pack
|
||||
(const SessionCmd1 *message,
|
||||
uint8_t *out);
|
||||
size_t session_cmd1__pack_to_buffer
|
||||
(const SessionCmd1 *message,
|
||||
ProtobufCBuffer *buffer);
|
||||
SessionCmd1 *
|
||||
session_cmd1__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data);
|
||||
void session_cmd1__free_unpacked
|
||||
(SessionCmd1 *message,
|
||||
ProtobufCAllocator *allocator);
|
||||
/* SessionResp1 methods */
|
||||
void session_resp1__init
|
||||
(SessionResp1 *message);
|
||||
size_t session_resp1__get_packed_size
|
||||
(const SessionResp1 *message);
|
||||
size_t session_resp1__pack
|
||||
(const SessionResp1 *message,
|
||||
uint8_t *out);
|
||||
size_t session_resp1__pack_to_buffer
|
||||
(const SessionResp1 *message,
|
||||
ProtobufCBuffer *buffer);
|
||||
SessionResp1 *
|
||||
session_resp1__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data);
|
||||
void session_resp1__free_unpacked
|
||||
(SessionResp1 *message,
|
||||
ProtobufCAllocator *allocator);
|
||||
/* SessionCmd0 methods */
|
||||
void session_cmd0__init
|
||||
(SessionCmd0 *message);
|
||||
size_t session_cmd0__get_packed_size
|
||||
(const SessionCmd0 *message);
|
||||
size_t session_cmd0__pack
|
||||
(const SessionCmd0 *message,
|
||||
uint8_t *out);
|
||||
size_t session_cmd0__pack_to_buffer
|
||||
(const SessionCmd0 *message,
|
||||
ProtobufCBuffer *buffer);
|
||||
SessionCmd0 *
|
||||
session_cmd0__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data);
|
||||
void session_cmd0__free_unpacked
|
||||
(SessionCmd0 *message,
|
||||
ProtobufCAllocator *allocator);
|
||||
/* SessionResp0 methods */
|
||||
void session_resp0__init
|
||||
(SessionResp0 *message);
|
||||
size_t session_resp0__get_packed_size
|
||||
(const SessionResp0 *message);
|
||||
size_t session_resp0__pack
|
||||
(const SessionResp0 *message,
|
||||
uint8_t *out);
|
||||
size_t session_resp0__pack_to_buffer
|
||||
(const SessionResp0 *message,
|
||||
ProtobufCBuffer *buffer);
|
||||
SessionResp0 *
|
||||
session_resp0__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data);
|
||||
void session_resp0__free_unpacked
|
||||
(SessionResp0 *message,
|
||||
ProtobufCAllocator *allocator);
|
||||
/* Sec1Payload methods */
|
||||
void sec1_payload__init
|
||||
(Sec1Payload *message);
|
||||
size_t sec1_payload__get_packed_size
|
||||
(const Sec1Payload *message);
|
||||
size_t sec1_payload__pack
|
||||
(const Sec1Payload *message,
|
||||
uint8_t *out);
|
||||
size_t sec1_payload__pack_to_buffer
|
||||
(const Sec1Payload *message,
|
||||
ProtobufCBuffer *buffer);
|
||||
Sec1Payload *
|
||||
sec1_payload__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data);
|
||||
void sec1_payload__free_unpacked
|
||||
(Sec1Payload *message,
|
||||
ProtobufCAllocator *allocator);
|
||||
/* --- per-message closures --- */
|
||||
|
||||
typedef void (*SessionCmd1_Closure)
|
||||
(const SessionCmd1 *message,
|
||||
void *closure_data);
|
||||
typedef void (*SessionResp1_Closure)
|
||||
(const SessionResp1 *message,
|
||||
void *closure_data);
|
||||
typedef void (*SessionCmd0_Closure)
|
||||
(const SessionCmd0 *message,
|
||||
void *closure_data);
|
||||
typedef void (*SessionResp0_Closure)
|
||||
(const SessionResp0 *message,
|
||||
void *closure_data);
|
||||
typedef void (*Sec1Payload_Closure)
|
||||
(const Sec1Payload *message,
|
||||
void *closure_data);
|
||||
|
||||
/* --- services --- */
|
||||
|
||||
|
||||
/* --- descriptors --- */
|
||||
|
||||
extern const ProtobufCEnumDescriptor sec1_msg_type__descriptor;
|
||||
extern const ProtobufCMessageDescriptor session_cmd1__descriptor;
|
||||
extern const ProtobufCMessageDescriptor session_resp1__descriptor;
|
||||
extern const ProtobufCMessageDescriptor session_cmd0__descriptor;
|
||||
extern const ProtobufCMessageDescriptor session_resp0__descriptor;
|
||||
extern const ProtobufCMessageDescriptor sec1_payload__descriptor;
|
||||
|
||||
PROTOBUF_C__END_DECLS
|
||||
|
||||
|
||||
#endif /* PROTOBUF_C_sec1_2eproto__INCLUDED */
|
147
components/protocomm/proto-c/session.pb-c.c
Normal file
147
components/protocomm/proto-c/session.pb-c.c
Normal file
@ -0,0 +1,147 @@
|
||||
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
|
||||
/* Generated from: session.proto */
|
||||
|
||||
/* Do not generate deprecated warnings for self */
|
||||
#ifndef PROTOBUF_C__NO_DEPRECATED
|
||||
#define PROTOBUF_C__NO_DEPRECATED
|
||||
#endif
|
||||
|
||||
#include "session.pb-c.h"
|
||||
void session_data__init
|
||||
(SessionData *message)
|
||||
{
|
||||
static const SessionData init_value = SESSION_DATA__INIT;
|
||||
*message = init_value;
|
||||
}
|
||||
size_t session_data__get_packed_size
|
||||
(const SessionData *message)
|
||||
{
|
||||
assert(message->base.descriptor == &session_data__descriptor);
|
||||
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||
}
|
||||
size_t session_data__pack
|
||||
(const SessionData *message,
|
||||
uint8_t *out)
|
||||
{
|
||||
assert(message->base.descriptor == &session_data__descriptor);
|
||||
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||
}
|
||||
size_t session_data__pack_to_buffer
|
||||
(const SessionData *message,
|
||||
ProtobufCBuffer *buffer)
|
||||
{
|
||||
assert(message->base.descriptor == &session_data__descriptor);
|
||||
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||
}
|
||||
SessionData *
|
||||
session_data__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data)
|
||||
{
|
||||
return (SessionData *)
|
||||
protobuf_c_message_unpack (&session_data__descriptor,
|
||||
allocator, len, data);
|
||||
}
|
||||
void session_data__free_unpacked
|
||||
(SessionData *message,
|
||||
ProtobufCAllocator *allocator)
|
||||
{
|
||||
if(!message)
|
||||
return;
|
||||
assert(message->base.descriptor == &session_data__descriptor);
|
||||
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||
}
|
||||
static const ProtobufCFieldDescriptor session_data__field_descriptors[3] =
|
||||
{
|
||||
{
|
||||
"sec_ver",
|
||||
2,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_ENUM,
|
||||
0, /* quantifier_offset */
|
||||
offsetof(SessionData, sec_ver),
|
||||
&sec_scheme_version__descriptor,
|
||||
NULL,
|
||||
0, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"sec0",
|
||||
10,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_MESSAGE,
|
||||
offsetof(SessionData, proto_case),
|
||||
offsetof(SessionData, sec0),
|
||||
&sec0_payload__descriptor,
|
||||
NULL,
|
||||
0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"sec1",
|
||||
11,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_MESSAGE,
|
||||
offsetof(SessionData, proto_case),
|
||||
offsetof(SessionData, sec1),
|
||||
&sec1_payload__descriptor,
|
||||
NULL,
|
||||
0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
};
|
||||
static const unsigned session_data__field_indices_by_name[] = {
|
||||
1, /* field[1] = sec0 */
|
||||
2, /* field[2] = sec1 */
|
||||
0, /* field[0] = sec_ver */
|
||||
};
|
||||
static const ProtobufCIntRange session_data__number_ranges[2 + 1] =
|
||||
{
|
||||
{ 2, 0 },
|
||||
{ 10, 1 },
|
||||
{ 0, 3 }
|
||||
};
|
||||
const ProtobufCMessageDescriptor session_data__descriptor =
|
||||
{
|
||||
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
|
||||
"SessionData",
|
||||
"SessionData",
|
||||
"SessionData",
|
||||
"",
|
||||
sizeof(SessionData),
|
||||
3,
|
||||
session_data__field_descriptors,
|
||||
session_data__field_indices_by_name,
|
||||
2, session_data__number_ranges,
|
||||
(ProtobufCMessageInit) session_data__init,
|
||||
NULL,NULL,NULL /* reserved[123] */
|
||||
};
|
||||
static const ProtobufCEnumValue sec_scheme_version__enum_values_by_number[2] =
|
||||
{
|
||||
{ "SecScheme0", "SEC_SCHEME_VERSION__SecScheme0", 0 },
|
||||
{ "SecScheme1", "SEC_SCHEME_VERSION__SecScheme1", 1 },
|
||||
};
|
||||
static const ProtobufCIntRange sec_scheme_version__value_ranges[] = {
|
||||
{0, 0},{0, 2}
|
||||
};
|
||||
static const ProtobufCEnumValueIndex sec_scheme_version__enum_values_by_name[2] =
|
||||
{
|
||||
{ "SecScheme0", 0 },
|
||||
{ "SecScheme1", 1 },
|
||||
};
|
||||
const ProtobufCEnumDescriptor sec_scheme_version__descriptor =
|
||||
{
|
||||
PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,
|
||||
"SecSchemeVersion",
|
||||
"SecSchemeVersion",
|
||||
"SecSchemeVersion",
|
||||
"",
|
||||
2,
|
||||
sec_scheme_version__enum_values_by_number,
|
||||
2,
|
||||
sec_scheme_version__enum_values_by_name,
|
||||
1,
|
||||
sec_scheme_version__value_ranges,
|
||||
NULL,NULL,NULL,NULL /* reserved[1234] */
|
||||
};
|
114
components/protocomm/proto-c/session.pb-c.h
Normal file
114
components/protocomm/proto-c/session.pb-c.h
Normal file
@ -0,0 +1,114 @@
|
||||
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
|
||||
/* Generated from: session.proto */
|
||||
|
||||
#ifndef PROTOBUF_C_session_2eproto__INCLUDED
|
||||
#define PROTOBUF_C_session_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 1003000 < 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
|
||||
|
||||
#include "sec0.pb-c.h"
|
||||
#include "sec1.pb-c.h"
|
||||
|
||||
typedef struct _SessionData SessionData;
|
||||
|
||||
|
||||
/* --- enums --- */
|
||||
|
||||
/*
|
||||
* Allowed values for the type of security
|
||||
* being used in a protocomm session
|
||||
*/
|
||||
typedef enum _SecSchemeVersion {
|
||||
/*
|
||||
*!< Unsecured - plaintext communication
|
||||
*/
|
||||
SEC_SCHEME_VERSION__SecScheme0 = 0,
|
||||
/*
|
||||
*!< Security scheme 1 - Curve25519 + AES-256-CTR
|
||||
*/
|
||||
SEC_SCHEME_VERSION__SecScheme1 = 1
|
||||
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SEC_SCHEME_VERSION)
|
||||
} SecSchemeVersion;
|
||||
|
||||
/* --- messages --- */
|
||||
|
||||
typedef enum {
|
||||
SESSION_DATA__PROTO__NOT_SET = 0,
|
||||
SESSION_DATA__PROTO_SEC0 = 10,
|
||||
SESSION_DATA__PROTO_SEC1 = 11
|
||||
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SESSION_DATA__PROTO)
|
||||
} SessionData__ProtoCase;
|
||||
|
||||
/*
|
||||
* Data structure exchanged when establishing
|
||||
* secure session between Host and Client
|
||||
*/
|
||||
struct _SessionData
|
||||
{
|
||||
ProtobufCMessage base;
|
||||
/*
|
||||
*!< Type of security
|
||||
*/
|
||||
SecSchemeVersion sec_ver;
|
||||
SessionData__ProtoCase proto_case;
|
||||
union {
|
||||
/*
|
||||
*!< Payload data in case of security 0
|
||||
*/
|
||||
Sec0Payload *sec0;
|
||||
/*
|
||||
*!< Payload data in case of security 1
|
||||
*/
|
||||
Sec1Payload *sec1;
|
||||
};
|
||||
};
|
||||
#define SESSION_DATA__INIT \
|
||||
{ PROTOBUF_C_MESSAGE_INIT (&session_data__descriptor) \
|
||||
, SEC_SCHEME_VERSION__SecScheme0, SESSION_DATA__PROTO__NOT_SET, {0} }
|
||||
|
||||
|
||||
/* SessionData methods */
|
||||
void session_data__init
|
||||
(SessionData *message);
|
||||
size_t session_data__get_packed_size
|
||||
(const SessionData *message);
|
||||
size_t session_data__pack
|
||||
(const SessionData *message,
|
||||
uint8_t *out);
|
||||
size_t session_data__pack_to_buffer
|
||||
(const SessionData *message,
|
||||
ProtobufCBuffer *buffer);
|
||||
SessionData *
|
||||
session_data__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data);
|
||||
void session_data__free_unpacked
|
||||
(SessionData *message,
|
||||
ProtobufCAllocator *allocator);
|
||||
/* --- per-message closures --- */
|
||||
|
||||
typedef void (*SessionData_Closure)
|
||||
(const SessionData *message,
|
||||
void *closure_data);
|
||||
|
||||
/* --- services --- */
|
||||
|
||||
|
||||
/* --- descriptors --- */
|
||||
|
||||
extern const ProtobufCEnumDescriptor sec_scheme_version__descriptor;
|
||||
extern const ProtobufCMessageDescriptor session_data__descriptor;
|
||||
|
||||
PROTOBUF_C__END_DECLS
|
||||
|
||||
|
||||
#endif /* PROTOBUF_C_session_2eproto__INCLUDED */
|
13
components/protocomm/proto/README.md
Normal file
13
components/protocomm/proto/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Protobuf files for implementing protocol communication packets
|
||||
|
||||
Protocomm uses Google Protobuf for language, transport and architecture agnostic protocol communication. These proto files define the protocomm packet structure, separated across multiple files:
|
||||
* contants.proto - Defines the "Status" structure for conveying the success or failure of a single protocomm transaction
|
||||
* sec0.proto - Defines the Security0 Command and Response packet structures
|
||||
* sec1.proto - Defines the Security1 Command and Response packet structures
|
||||
* session.proto - Defines the protocomm transacion packets for session establishment which internally has a Security packet as payload
|
||||
|
||||
Note : These proto files are not automatically compiled during the build process.
|
||||
|
||||
Run "make" (Optional) to generate the respective C and Python files. The generated C files are used by protocomm itself to create, delete and manipulate transaction packets. The generated Python files can be used by python based applications for implementing client side interface to protocomm layer.
|
||||
|
||||
Compilation requires protoc (Protobuf Compiler) and protoc-c (Protobuf C Compiler) installed. Since the generated files are to remain the same, as long as the proto files are not modified, therefore the generated files are already available under "protocomm/proto-c" and "protocomm/python" directories, and thus running make (and installing the Protobuf compilers) is optional.
|
14
components/protocomm/proto/constants.proto
Normal file
14
components/protocomm/proto/constants.proto
Normal file
@ -0,0 +1,14 @@
|
||||
syntax = "proto3";
|
||||
|
||||
/* Allowed values for the status
|
||||
* of a protocomm instance */
|
||||
enum Status {
|
||||
Success = 0;
|
||||
InvalidSecScheme = 1;
|
||||
InvalidProto = 2;
|
||||
TooManySessions = 3;
|
||||
InvalidArgument = 4;
|
||||
InternalError = 5;
|
||||
CryptoError = 6;
|
||||
InvalidSession = 7;
|
||||
}
|
7
components/protocomm/proto/makefile
Normal file
7
components/protocomm/proto/makefile
Normal file
@ -0,0 +1,7 @@
|
||||
all: c_proto python_proto
|
||||
|
||||
c_proto: *.proto
|
||||
@protoc-c --c_out=../proto-c/ -I . *.proto
|
||||
|
||||
python_proto: *.proto
|
||||
@protoc --python_out=../python/ -I . *.proto
|
28
components/protocomm/proto/sec0.proto
Normal file
28
components/protocomm/proto/sec0.proto
Normal file
@ -0,0 +1,28 @@
|
||||
syntax = "proto3";
|
||||
|
||||
import "constants.proto";
|
||||
|
||||
/* Data structure of Session command/request packet */
|
||||
message S0SessionCmd {
|
||||
|
||||
}
|
||||
|
||||
/* Data structure of Session response packet */
|
||||
message S0SessionResp {
|
||||
Status status = 1;
|
||||
}
|
||||
|
||||
/* A message must be of type Cmd or Resp */
|
||||
enum Sec0MsgType {
|
||||
S0_Session_Command = 0;
|
||||
S0_Session_Response = 1;
|
||||
}
|
||||
|
||||
/* Payload structure of session data */
|
||||
message Sec0Payload {
|
||||
Sec0MsgType msg = 1; /*!< Type of message */
|
||||
oneof payload {
|
||||
S0SessionCmd sc = 20; /*!< Payload data interpreted as Cmd */
|
||||
S0SessionResp sr = 21; /*!< Payload data interpreted as Resp */
|
||||
}
|
||||
}
|
45
components/protocomm/proto/sec1.proto
Normal file
45
components/protocomm/proto/sec1.proto
Normal file
@ -0,0 +1,45 @@
|
||||
syntax = "proto3";
|
||||
|
||||
import "constants.proto";
|
||||
|
||||
/* Data structure of Session command1 packet */
|
||||
message SessionCmd1 {
|
||||
bytes client_verify_data = 2;
|
||||
}
|
||||
|
||||
/* Data structure of Session response1 packet */
|
||||
message SessionResp1 {
|
||||
Status status = 1;
|
||||
bytes device_verify_data = 3;
|
||||
}
|
||||
|
||||
/* Data structure of Session command0 packet */
|
||||
message SessionCmd0 {
|
||||
bytes client_pubkey = 1;
|
||||
}
|
||||
|
||||
/* Data structure of Session response0 packet */
|
||||
message SessionResp0 {
|
||||
Status status = 1;
|
||||
bytes device_pubkey = 2;
|
||||
bytes device_random = 3;
|
||||
}
|
||||
|
||||
/* A message must be of type Cmd0 / Cmd1 / Resp0 / Resp1 */
|
||||
enum Sec1MsgType {
|
||||
Session_Command0 = 0;
|
||||
Session_Response0 = 1;
|
||||
Session_Command1 = 2;
|
||||
Session_Response1 = 3;
|
||||
}
|
||||
|
||||
/* Payload structure of session data */
|
||||
message Sec1Payload {
|
||||
Sec1MsgType msg = 1; /*!< Type of message */
|
||||
oneof payload {
|
||||
SessionCmd0 sc0 = 20; /*!< Payload data interpreted as Cmd0 */
|
||||
SessionResp0 sr0 = 21; /*!< Payload data interpreted as Resp0 */
|
||||
SessionCmd1 sc1 = 22; /*!< Payload data interpreted as Cmd1 */
|
||||
SessionResp1 sr1 = 23; /*!< Payload data interpreted as Resp1 */
|
||||
}
|
||||
}
|
21
components/protocomm/proto/session.proto
Normal file
21
components/protocomm/proto/session.proto
Normal file
@ -0,0 +1,21 @@
|
||||
syntax = "proto3";
|
||||
|
||||
import "sec0.proto";
|
||||
import "sec1.proto";
|
||||
|
||||
/* Allowed values for the type of security
|
||||
* being used in a protocomm session */
|
||||
enum SecSchemeVersion {
|
||||
SecScheme0 = 0; /*!< Unsecured - plaintext communication */
|
||||
SecScheme1 = 1; /*!< Security scheme 1 - Curve25519 + AES-256-CTR*/
|
||||
}
|
||||
|
||||
/* Data structure exchanged when establishing
|
||||
* secure session between Host and Client */
|
||||
message SessionData {
|
||||
SecSchemeVersion sec_ver = 2; /*!< Type of security */
|
||||
oneof proto {
|
||||
Sec0Payload sec0 = 10; /*!< Payload data in case of security 0 */
|
||||
Sec1Payload sec1 = 11; /*!< Payload data in case of security 1 */
|
||||
}
|
||||
}
|
87
components/protocomm/python/constants_pb2.py
Normal file
87
components/protocomm/python/constants_pb2.py
Normal file
@ -0,0 +1,87 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: constants.proto
|
||||
|
||||
import sys
|
||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
||||
from google.protobuf.internal import enum_type_wrapper
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf import descriptor_pb2
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='constants.proto',
|
||||
package='',
|
||||
syntax='proto3',
|
||||
serialized_pb=_b('\n\x0f\x63onstants.proto*\x9f\x01\n\x06Status\x12\x0b\n\x07Success\x10\x00\x12\x14\n\x10InvalidSecScheme\x10\x01\x12\x10\n\x0cInvalidProto\x10\x02\x12\x13\n\x0fTooManySessions\x10\x03\x12\x13\n\x0fInvalidArgument\x10\x04\x12\x11\n\rInternalError\x10\x05\x12\x0f\n\x0b\x43ryptoError\x10\x06\x12\x12\n\x0eInvalidSession\x10\x07\x62\x06proto3')
|
||||
)
|
||||
|
||||
_STATUS = _descriptor.EnumDescriptor(
|
||||
name='Status',
|
||||
full_name='Status',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
values=[
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='Success', index=0, number=0,
|
||||
options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='InvalidSecScheme', index=1, number=1,
|
||||
options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='InvalidProto', index=2, number=2,
|
||||
options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='TooManySessions', index=3, number=3,
|
||||
options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='InvalidArgument', index=4, number=4,
|
||||
options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='InternalError', index=5, number=5,
|
||||
options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='CryptoError', index=6, number=6,
|
||||
options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='InvalidSession', index=7, number=7,
|
||||
options=None,
|
||||
type=None),
|
||||
],
|
||||
containing_type=None,
|
||||
options=None,
|
||||
serialized_start=20,
|
||||
serialized_end=179,
|
||||
)
|
||||
_sym_db.RegisterEnumDescriptor(_STATUS)
|
||||
|
||||
Status = enum_type_wrapper.EnumTypeWrapper(_STATUS)
|
||||
Success = 0
|
||||
InvalidSecScheme = 1
|
||||
InvalidProto = 2
|
||||
TooManySessions = 3
|
||||
InvalidArgument = 4
|
||||
InternalError = 5
|
||||
CryptoError = 6
|
||||
InvalidSession = 7
|
||||
|
||||
|
||||
DESCRIPTOR.enum_types_by_name['Status'] = _STATUS
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
|
||||
# @@protoc_insertion_point(module_scope)
|
196
components/protocomm/python/sec0_pb2.py
Normal file
196
components/protocomm/python/sec0_pb2.py
Normal file
@ -0,0 +1,196 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: sec0.proto
|
||||
|
||||
import sys
|
||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
||||
from google.protobuf.internal import enum_type_wrapper
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf import descriptor_pb2
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
import constants_pb2 as constants__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='sec0.proto',
|
||||
package='',
|
||||
syntax='proto3',
|
||||
serialized_pb=_b('\n\nsec0.proto\x1a\x0f\x63onstants.proto\"\x0e\n\x0cS0SessionCmd\"(\n\rS0SessionResp\x12\x17\n\x06status\x18\x01 \x01(\x0e\x32\x07.Status\"n\n\x0bSec0Payload\x12\x19\n\x03msg\x18\x01 \x01(\x0e\x32\x0c.Sec0MsgType\x12\x1b\n\x02sc\x18\x14 \x01(\x0b\x32\r.S0SessionCmdH\x00\x12\x1c\n\x02sr\x18\x15 \x01(\x0b\x32\x0e.S0SessionRespH\x00\x42\t\n\x07payload*>\n\x0bSec0MsgType\x12\x16\n\x12S0_Session_Command\x10\x00\x12\x17\n\x13S0_Session_Response\x10\x01\x62\x06proto3')
|
||||
,
|
||||
dependencies=[constants__pb2.DESCRIPTOR,])
|
||||
|
||||
_SEC0MSGTYPE = _descriptor.EnumDescriptor(
|
||||
name='Sec0MsgType',
|
||||
full_name='Sec0MsgType',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
values=[
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='S0_Session_Command', index=0, number=0,
|
||||
options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='S0_Session_Response', index=1, number=1,
|
||||
options=None,
|
||||
type=None),
|
||||
],
|
||||
containing_type=None,
|
||||
options=None,
|
||||
serialized_start=201,
|
||||
serialized_end=263,
|
||||
)
|
||||
_sym_db.RegisterEnumDescriptor(_SEC0MSGTYPE)
|
||||
|
||||
Sec0MsgType = enum_type_wrapper.EnumTypeWrapper(_SEC0MSGTYPE)
|
||||
S0_Session_Command = 0
|
||||
S0_Session_Response = 1
|
||||
|
||||
|
||||
|
||||
_S0SESSIONCMD = _descriptor.Descriptor(
|
||||
name='S0SessionCmd',
|
||||
full_name='S0SessionCmd',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=31,
|
||||
serialized_end=45,
|
||||
)
|
||||
|
||||
|
||||
_S0SESSIONRESP = _descriptor.Descriptor(
|
||||
name='S0SessionResp',
|
||||
full_name='S0SessionResp',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='status', full_name='S0SessionResp.status', index=0,
|
||||
number=1, type=14, cpp_type=8, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=47,
|
||||
serialized_end=87,
|
||||
)
|
||||
|
||||
|
||||
_SEC0PAYLOAD = _descriptor.Descriptor(
|
||||
name='Sec0Payload',
|
||||
full_name='Sec0Payload',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='msg', full_name='Sec0Payload.msg', index=0,
|
||||
number=1, type=14, cpp_type=8, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='sc', full_name='Sec0Payload.sc', index=1,
|
||||
number=20, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='sr', full_name='Sec0Payload.sr', index=2,
|
||||
number=21, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
_descriptor.OneofDescriptor(
|
||||
name='payload', full_name='Sec0Payload.payload',
|
||||
index=0, containing_type=None, fields=[]),
|
||||
],
|
||||
serialized_start=89,
|
||||
serialized_end=199,
|
||||
)
|
||||
|
||||
_S0SESSIONRESP.fields_by_name['status'].enum_type = constants__pb2._STATUS
|
||||
_SEC0PAYLOAD.fields_by_name['msg'].enum_type = _SEC0MSGTYPE
|
||||
_SEC0PAYLOAD.fields_by_name['sc'].message_type = _S0SESSIONCMD
|
||||
_SEC0PAYLOAD.fields_by_name['sr'].message_type = _S0SESSIONRESP
|
||||
_SEC0PAYLOAD.oneofs_by_name['payload'].fields.append(
|
||||
_SEC0PAYLOAD.fields_by_name['sc'])
|
||||
_SEC0PAYLOAD.fields_by_name['sc'].containing_oneof = _SEC0PAYLOAD.oneofs_by_name['payload']
|
||||
_SEC0PAYLOAD.oneofs_by_name['payload'].fields.append(
|
||||
_SEC0PAYLOAD.fields_by_name['sr'])
|
||||
_SEC0PAYLOAD.fields_by_name['sr'].containing_oneof = _SEC0PAYLOAD.oneofs_by_name['payload']
|
||||
DESCRIPTOR.message_types_by_name['S0SessionCmd'] = _S0SESSIONCMD
|
||||
DESCRIPTOR.message_types_by_name['S0SessionResp'] = _S0SESSIONRESP
|
||||
DESCRIPTOR.message_types_by_name['Sec0Payload'] = _SEC0PAYLOAD
|
||||
DESCRIPTOR.enum_types_by_name['Sec0MsgType'] = _SEC0MSGTYPE
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
S0SessionCmd = _reflection.GeneratedProtocolMessageType('S0SessionCmd', (_message.Message,), dict(
|
||||
DESCRIPTOR = _S0SESSIONCMD,
|
||||
__module__ = 'sec0_pb2'
|
||||
# @@protoc_insertion_point(class_scope:S0SessionCmd)
|
||||
))
|
||||
_sym_db.RegisterMessage(S0SessionCmd)
|
||||
|
||||
S0SessionResp = _reflection.GeneratedProtocolMessageType('S0SessionResp', (_message.Message,), dict(
|
||||
DESCRIPTOR = _S0SESSIONRESP,
|
||||
__module__ = 'sec0_pb2'
|
||||
# @@protoc_insertion_point(class_scope:S0SessionResp)
|
||||
))
|
||||
_sym_db.RegisterMessage(S0SessionResp)
|
||||
|
||||
Sec0Payload = _reflection.GeneratedProtocolMessageType('Sec0Payload', (_message.Message,), dict(
|
||||
DESCRIPTOR = _SEC0PAYLOAD,
|
||||
__module__ = 'sec0_pb2'
|
||||
# @@protoc_insertion_point(class_scope:Sec0Payload)
|
||||
))
|
||||
_sym_db.RegisterMessage(Sec0Payload)
|
||||
|
||||
|
||||
# @@protoc_insertion_point(module_scope)
|
335
components/protocomm/python/sec1_pb2.py
Normal file
335
components/protocomm/python/sec1_pb2.py
Normal file
@ -0,0 +1,335 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: sec1.proto
|
||||
|
||||
import sys
|
||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
||||
from google.protobuf.internal import enum_type_wrapper
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf import descriptor_pb2
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
import constants_pb2 as constants__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='sec1.proto',
|
||||
package='',
|
||||
syntax='proto3',
|
||||
serialized_pb=_b('\n\nsec1.proto\x1a\x0f\x63onstants.proto\")\n\x0bSessionCmd1\x12\x1a\n\x12\x63lient_verify_data\x18\x02 \x01(\x0c\"C\n\x0cSessionResp1\x12\x17\n\x06status\x18\x01 \x01(\x0e\x32\x07.Status\x12\x1a\n\x12\x64\x65vice_verify_data\x18\x03 \x01(\x0c\"$\n\x0bSessionCmd0\x12\x15\n\rclient_pubkey\x18\x01 \x01(\x0c\"U\n\x0cSessionResp0\x12\x17\n\x06status\x18\x01 \x01(\x0e\x32\x07.Status\x12\x15\n\rdevice_pubkey\x18\x02 \x01(\x0c\x12\x15\n\rdevice_random\x18\x03 \x01(\x0c\"\xa9\x01\n\x0bSec1Payload\x12\x19\n\x03msg\x18\x01 \x01(\x0e\x32\x0c.Sec1MsgType\x12\x1b\n\x03sc0\x18\x14 \x01(\x0b\x32\x0c.SessionCmd0H\x00\x12\x1c\n\x03sr0\x18\x15 \x01(\x0b\x32\r.SessionResp0H\x00\x12\x1b\n\x03sc1\x18\x16 \x01(\x0b\x32\x0c.SessionCmd1H\x00\x12\x1c\n\x03sr1\x18\x17 \x01(\x0b\x32\r.SessionResp1H\x00\x42\t\n\x07payload*g\n\x0bSec1MsgType\x12\x14\n\x10Session_Command0\x10\x00\x12\x15\n\x11Session_Response0\x10\x01\x12\x14\n\x10Session_Command1\x10\x02\x12\x15\n\x11Session_Response1\x10\x03\x62\x06proto3')
|
||||
,
|
||||
dependencies=[constants__pb2.DESCRIPTOR,])
|
||||
|
||||
_SEC1MSGTYPE = _descriptor.EnumDescriptor(
|
||||
name='Sec1MsgType',
|
||||
full_name='Sec1MsgType',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
values=[
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='Session_Command0', index=0, number=0,
|
||||
options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='Session_Response0', index=1, number=1,
|
||||
options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='Session_Command1', index=2, number=2,
|
||||
options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='Session_Response1', index=3, number=3,
|
||||
options=None,
|
||||
type=None),
|
||||
],
|
||||
containing_type=None,
|
||||
options=None,
|
||||
serialized_start=440,
|
||||
serialized_end=543,
|
||||
)
|
||||
_sym_db.RegisterEnumDescriptor(_SEC1MSGTYPE)
|
||||
|
||||
Sec1MsgType = enum_type_wrapper.EnumTypeWrapper(_SEC1MSGTYPE)
|
||||
Session_Command0 = 0
|
||||
Session_Response0 = 1
|
||||
Session_Command1 = 2
|
||||
Session_Response1 = 3
|
||||
|
||||
|
||||
|
||||
_SESSIONCMD1 = _descriptor.Descriptor(
|
||||
name='SessionCmd1',
|
||||
full_name='SessionCmd1',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='client_verify_data', full_name='SessionCmd1.client_verify_data', index=0,
|
||||
number=2, type=12, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b(""),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=31,
|
||||
serialized_end=72,
|
||||
)
|
||||
|
||||
|
||||
_SESSIONRESP1 = _descriptor.Descriptor(
|
||||
name='SessionResp1',
|
||||
full_name='SessionResp1',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='status', full_name='SessionResp1.status', index=0,
|
||||
number=1, type=14, cpp_type=8, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='device_verify_data', full_name='SessionResp1.device_verify_data', index=1,
|
||||
number=3, type=12, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b(""),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=74,
|
||||
serialized_end=141,
|
||||
)
|
||||
|
||||
|
||||
_SESSIONCMD0 = _descriptor.Descriptor(
|
||||
name='SessionCmd0',
|
||||
full_name='SessionCmd0',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='client_pubkey', full_name='SessionCmd0.client_pubkey', index=0,
|
||||
number=1, type=12, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b(""),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=143,
|
||||
serialized_end=179,
|
||||
)
|
||||
|
||||
|
||||
_SESSIONRESP0 = _descriptor.Descriptor(
|
||||
name='SessionResp0',
|
||||
full_name='SessionResp0',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='status', full_name='SessionResp0.status', index=0,
|
||||
number=1, type=14, cpp_type=8, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='device_pubkey', full_name='SessionResp0.device_pubkey', index=1,
|
||||
number=2, type=12, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b(""),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='device_random', full_name='SessionResp0.device_random', index=2,
|
||||
number=3, type=12, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b(""),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=181,
|
||||
serialized_end=266,
|
||||
)
|
||||
|
||||
|
||||
_SEC1PAYLOAD = _descriptor.Descriptor(
|
||||
name='Sec1Payload',
|
||||
full_name='Sec1Payload',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='msg', full_name='Sec1Payload.msg', index=0,
|
||||
number=1, type=14, cpp_type=8, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='sc0', full_name='Sec1Payload.sc0', index=1,
|
||||
number=20, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='sr0', full_name='Sec1Payload.sr0', index=2,
|
||||
number=21, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='sc1', full_name='Sec1Payload.sc1', index=3,
|
||||
number=22, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='sr1', full_name='Sec1Payload.sr1', index=4,
|
||||
number=23, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
_descriptor.OneofDescriptor(
|
||||
name='payload', full_name='Sec1Payload.payload',
|
||||
index=0, containing_type=None, fields=[]),
|
||||
],
|
||||
serialized_start=269,
|
||||
serialized_end=438,
|
||||
)
|
||||
|
||||
_SESSIONRESP1.fields_by_name['status'].enum_type = constants__pb2._STATUS
|
||||
_SESSIONRESP0.fields_by_name['status'].enum_type = constants__pb2._STATUS
|
||||
_SEC1PAYLOAD.fields_by_name['msg'].enum_type = _SEC1MSGTYPE
|
||||
_SEC1PAYLOAD.fields_by_name['sc0'].message_type = _SESSIONCMD0
|
||||
_SEC1PAYLOAD.fields_by_name['sr0'].message_type = _SESSIONRESP0
|
||||
_SEC1PAYLOAD.fields_by_name['sc1'].message_type = _SESSIONCMD1
|
||||
_SEC1PAYLOAD.fields_by_name['sr1'].message_type = _SESSIONRESP1
|
||||
_SEC1PAYLOAD.oneofs_by_name['payload'].fields.append(
|
||||
_SEC1PAYLOAD.fields_by_name['sc0'])
|
||||
_SEC1PAYLOAD.fields_by_name['sc0'].containing_oneof = _SEC1PAYLOAD.oneofs_by_name['payload']
|
||||
_SEC1PAYLOAD.oneofs_by_name['payload'].fields.append(
|
||||
_SEC1PAYLOAD.fields_by_name['sr0'])
|
||||
_SEC1PAYLOAD.fields_by_name['sr0'].containing_oneof = _SEC1PAYLOAD.oneofs_by_name['payload']
|
||||
_SEC1PAYLOAD.oneofs_by_name['payload'].fields.append(
|
||||
_SEC1PAYLOAD.fields_by_name['sc1'])
|
||||
_SEC1PAYLOAD.fields_by_name['sc1'].containing_oneof = _SEC1PAYLOAD.oneofs_by_name['payload']
|
||||
_SEC1PAYLOAD.oneofs_by_name['payload'].fields.append(
|
||||
_SEC1PAYLOAD.fields_by_name['sr1'])
|
||||
_SEC1PAYLOAD.fields_by_name['sr1'].containing_oneof = _SEC1PAYLOAD.oneofs_by_name['payload']
|
||||
DESCRIPTOR.message_types_by_name['SessionCmd1'] = _SESSIONCMD1
|
||||
DESCRIPTOR.message_types_by_name['SessionResp1'] = _SESSIONRESP1
|
||||
DESCRIPTOR.message_types_by_name['SessionCmd0'] = _SESSIONCMD0
|
||||
DESCRIPTOR.message_types_by_name['SessionResp0'] = _SESSIONRESP0
|
||||
DESCRIPTOR.message_types_by_name['Sec1Payload'] = _SEC1PAYLOAD
|
||||
DESCRIPTOR.enum_types_by_name['Sec1MsgType'] = _SEC1MSGTYPE
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
SessionCmd1 = _reflection.GeneratedProtocolMessageType('SessionCmd1', (_message.Message,), dict(
|
||||
DESCRIPTOR = _SESSIONCMD1,
|
||||
__module__ = 'sec1_pb2'
|
||||
# @@protoc_insertion_point(class_scope:SessionCmd1)
|
||||
))
|
||||
_sym_db.RegisterMessage(SessionCmd1)
|
||||
|
||||
SessionResp1 = _reflection.GeneratedProtocolMessageType('SessionResp1', (_message.Message,), dict(
|
||||
DESCRIPTOR = _SESSIONRESP1,
|
||||
__module__ = 'sec1_pb2'
|
||||
# @@protoc_insertion_point(class_scope:SessionResp1)
|
||||
))
|
||||
_sym_db.RegisterMessage(SessionResp1)
|
||||
|
||||
SessionCmd0 = _reflection.GeneratedProtocolMessageType('SessionCmd0', (_message.Message,), dict(
|
||||
DESCRIPTOR = _SESSIONCMD0,
|
||||
__module__ = 'sec1_pb2'
|
||||
# @@protoc_insertion_point(class_scope:SessionCmd0)
|
||||
))
|
||||
_sym_db.RegisterMessage(SessionCmd0)
|
||||
|
||||
SessionResp0 = _reflection.GeneratedProtocolMessageType('SessionResp0', (_message.Message,), dict(
|
||||
DESCRIPTOR = _SESSIONRESP0,
|
||||
__module__ = 'sec1_pb2'
|
||||
# @@protoc_insertion_point(class_scope:SessionResp0)
|
||||
))
|
||||
_sym_db.RegisterMessage(SessionResp0)
|
||||
|
||||
Sec1Payload = _reflection.GeneratedProtocolMessageType('Sec1Payload', (_message.Message,), dict(
|
||||
DESCRIPTOR = _SEC1PAYLOAD,
|
||||
__module__ = 'sec1_pb2'
|
||||
# @@protoc_insertion_point(class_scope:Sec1Payload)
|
||||
))
|
||||
_sym_db.RegisterMessage(Sec1Payload)
|
||||
|
||||
|
||||
# @@protoc_insertion_point(module_scope)
|
125
components/protocomm/python/session_pb2.py
Normal file
125
components/protocomm/python/session_pb2.py
Normal file
@ -0,0 +1,125 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: session.proto
|
||||
|
||||
import sys
|
||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
||||
from google.protobuf.internal import enum_type_wrapper
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf import descriptor_pb2
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
import sec0_pb2 as sec0__pb2
|
||||
import sec1_pb2 as sec1__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='session.proto',
|
||||
package='',
|
||||
syntax='proto3',
|
||||
serialized_pb=_b('\n\rsession.proto\x1a\nsec0.proto\x1a\nsec1.proto\"v\n\x0bSessionData\x12\"\n\x07sec_ver\x18\x02 \x01(\x0e\x32\x11.SecSchemeVersion\x12\x1c\n\x04sec0\x18\n \x01(\x0b\x32\x0c.Sec0PayloadH\x00\x12\x1c\n\x04sec1\x18\x0b \x01(\x0b\x32\x0c.Sec1PayloadH\x00\x42\x07\n\x05proto*2\n\x10SecSchemeVersion\x12\x0e\n\nSecScheme0\x10\x00\x12\x0e\n\nSecScheme1\x10\x01\x62\x06proto3')
|
||||
,
|
||||
dependencies=[sec0__pb2.DESCRIPTOR,sec1__pb2.DESCRIPTOR,])
|
||||
|
||||
_SECSCHEMEVERSION = _descriptor.EnumDescriptor(
|
||||
name='SecSchemeVersion',
|
||||
full_name='SecSchemeVersion',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
values=[
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='SecScheme0', index=0, number=0,
|
||||
options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='SecScheme1', index=1, number=1,
|
||||
options=None,
|
||||
type=None),
|
||||
],
|
||||
containing_type=None,
|
||||
options=None,
|
||||
serialized_start=161,
|
||||
serialized_end=211,
|
||||
)
|
||||
_sym_db.RegisterEnumDescriptor(_SECSCHEMEVERSION)
|
||||
|
||||
SecSchemeVersion = enum_type_wrapper.EnumTypeWrapper(_SECSCHEMEVERSION)
|
||||
SecScheme0 = 0
|
||||
SecScheme1 = 1
|
||||
|
||||
|
||||
|
||||
_SESSIONDATA = _descriptor.Descriptor(
|
||||
name='SessionData',
|
||||
full_name='SessionData',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='sec_ver', full_name='SessionData.sec_ver', index=0,
|
||||
number=2, type=14, cpp_type=8, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='sec0', full_name='SessionData.sec0', index=1,
|
||||
number=10, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='sec1', full_name='SessionData.sec1', index=2,
|
||||
number=11, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
_descriptor.OneofDescriptor(
|
||||
name='proto', full_name='SessionData.proto',
|
||||
index=0, containing_type=None, fields=[]),
|
||||
],
|
||||
serialized_start=41,
|
||||
serialized_end=159,
|
||||
)
|
||||
|
||||
_SESSIONDATA.fields_by_name['sec_ver'].enum_type = _SECSCHEMEVERSION
|
||||
_SESSIONDATA.fields_by_name['sec0'].message_type = sec0__pb2._SEC0PAYLOAD
|
||||
_SESSIONDATA.fields_by_name['sec1'].message_type = sec1__pb2._SEC1PAYLOAD
|
||||
_SESSIONDATA.oneofs_by_name['proto'].fields.append(
|
||||
_SESSIONDATA.fields_by_name['sec0'])
|
||||
_SESSIONDATA.fields_by_name['sec0'].containing_oneof = _SESSIONDATA.oneofs_by_name['proto']
|
||||
_SESSIONDATA.oneofs_by_name['proto'].fields.append(
|
||||
_SESSIONDATA.fields_by_name['sec1'])
|
||||
_SESSIONDATA.fields_by_name['sec1'].containing_oneof = _SESSIONDATA.oneofs_by_name['proto']
|
||||
DESCRIPTOR.message_types_by_name['SessionData'] = _SESSIONDATA
|
||||
DESCRIPTOR.enum_types_by_name['SecSchemeVersion'] = _SECSCHEMEVERSION
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
SessionData = _reflection.GeneratedProtocolMessageType('SessionData', (_message.Message,), dict(
|
||||
DESCRIPTOR = _SESSIONDATA,
|
||||
__module__ = 'session_pb2'
|
||||
# @@protoc_insertion_point(class_scope:SessionData)
|
||||
))
|
||||
_sym_db.RegisterMessage(SessionData)
|
||||
|
||||
|
||||
# @@protoc_insertion_point(module_scope)
|
393
components/protocomm/src/common/protocomm.c
Normal file
393
components/protocomm/src/common/protocomm.c
Normal file
@ -0,0 +1,393 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <esp_err.h>
|
||||
#include <esp_log.h>
|
||||
#include <rom/queue.h>
|
||||
|
||||
#include <protocomm.h>
|
||||
#include <protocomm_security.h>
|
||||
|
||||
#include "protocomm_priv.h"
|
||||
|
||||
static const char *TAG = "protocomm";
|
||||
|
||||
protocomm_t *protocomm_new()
|
||||
{
|
||||
protocomm_t *pc;
|
||||
|
||||
pc = (protocomm_t *) calloc(1, sizeof(protocomm_t));
|
||||
if (!pc) {
|
||||
ESP_LOGE(TAG, "Error allocating protocomm");
|
||||
return NULL;
|
||||
}
|
||||
SLIST_INIT(&pc->endpoints);
|
||||
|
||||
return pc;
|
||||
}
|
||||
|
||||
void protocomm_delete(protocomm_t *pc)
|
||||
{
|
||||
if (pc == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
protocomm_ep_t *it, *tmp;
|
||||
/* Remove endpoints first */
|
||||
SLIST_FOREACH_SAFE(it, &pc->endpoints, next, tmp) {
|
||||
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);
|
||||
}
|
||||
|
||||
static protocomm_ep_t *search_endpoint(protocomm_t *pc, const char *ep_name)
|
||||
{
|
||||
protocomm_ep_t *it;
|
||||
SLIST_FOREACH(it, &pc->endpoints, next) {
|
||||
if (strcmp(it->ep_name, ep_name) == 0) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static esp_err_t protocomm_add_endpoint_internal(protocomm_t *pc, const char *ep_name,
|
||||
protocomm_req_handler_t h, void *priv_data,
|
||||
uint32_t flag)
|
||||
{
|
||||
if ((pc == NULL) || (ep_name == NULL) || (h == NULL)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
protocomm_ep_t *ep;
|
||||
esp_err_t ret;
|
||||
|
||||
ep = search_endpoint(pc, ep_name);
|
||||
if (ep) {
|
||||
ESP_LOGE(TAG, "Endpoint with this name already exists");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (pc->add_endpoint) {
|
||||
ret = pc->add_endpoint(ep_name, h, priv_data);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error adding endpoint");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ep = (protocomm_ep_t *) calloc(1, sizeof(protocomm_ep_t));
|
||||
if (!ep) {
|
||||
ESP_LOGE(TAG, "Error allocating endpoint resource");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
/* Initialize ep handler */
|
||||
ep->ep_name = ep_name;
|
||||
ep->req_handler = h;
|
||||
ep->priv_data = priv_data;
|
||||
ep->flag = flag;
|
||||
|
||||
/* Add endpoint to the head of the singly linked list */
|
||||
SLIST_INSERT_HEAD(&pc->endpoints, ep, next);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t protocomm_add_endpoint(protocomm_t *pc, const char *ep_name,
|
||||
protocomm_req_handler_t h, void *priv_data)
|
||||
{
|
||||
return protocomm_add_endpoint_internal(pc, ep_name, h, priv_data, REQ_EP);
|
||||
}
|
||||
|
||||
esp_err_t protocomm_remove_endpoint(protocomm_t *pc, const char *ep_name)
|
||||
{
|
||||
if ((pc == NULL) || (ep_name == NULL)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (pc->remove_endpoint) {
|
||||
pc->remove_endpoint(ep_name);
|
||||
}
|
||||
|
||||
protocomm_ep_t *it, *tmp;
|
||||
SLIST_FOREACH_SAFE(it, &pc->endpoints, next, tmp) {
|
||||
if (strcmp(ep_name, it->ep_name) == 0) {
|
||||
SLIST_REMOVE(&pc->endpoints, it, protocomm_ep, next);
|
||||
free(it);
|
||||
return ESP_OK;
|
||||
}
|
||||
}
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
esp_err_t protocomm_req_handle(protocomm_t *pc, const char *ep_name, uint32_t session_id,
|
||||
const uint8_t *inbuf, ssize_t inlen,
|
||||
uint8_t **outbuf, ssize_t *outlen)
|
||||
{
|
||||
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);
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
if (ep->flag & SEC_EP) {
|
||||
/* Call the registered endpoint handler for establishing secure session */
|
||||
ret = ep->req_handler(session_id, inbuf, inlen, outbuf, outlen, ep->priv_data);
|
||||
ESP_LOGD(TAG, "SEC_EP Req handler returned %d", ret);
|
||||
} else if (ep->flag & REQ_EP) {
|
||||
if (pc->sec && pc->sec->decrypt) {
|
||||
/* Decrypt the data first */
|
||||
uint8_t *dec_inbuf = (uint8_t *) malloc(inlen);
|
||||
if (!dec_inbuf) {
|
||||
ESP_LOGE(TAG, "Failed to allocate decrypt buf len %d", inlen);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
ssize_t dec_inbuf_len = inlen;
|
||||
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 = 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);
|
||||
free(plaintext_resp);
|
||||
free(dec_inbuf);
|
||||
return ret;
|
||||
}
|
||||
/* We don't need decrypted data anymore */
|
||||
free(dec_inbuf);
|
||||
|
||||
/* Encrypt response to be sent back */
|
||||
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;
|
||||
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);
|
||||
|
||||
/* Set outbuf and outlen appropriately */
|
||||
*outbuf = enc_resp;
|
||||
*outlen = enc_resp_len;
|
||||
} else {
|
||||
/* No encryption */
|
||||
ret = ep->req_handler(session_id,
|
||||
inbuf, inlen,
|
||||
outbuf, outlen,
|
||||
ep->priv_data);
|
||||
ESP_LOGD(TAG, "No encrypt ret %d", ret);
|
||||
}
|
||||
} else if (ep->flag & VER_EP) {
|
||||
ret = ep->req_handler(session_id, inbuf, inlen, outbuf, outlen, ep->priv_data);
|
||||
ESP_LOGD(TAG, "VER_EP Req handler returned %d", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int protocomm_common_security_handler(uint32_t session_id,
|
||||
const uint8_t *inbuf, ssize_t inlen,
|
||||
uint8_t **outbuf, ssize_t *outlen,
|
||||
void *priv_data)
|
||||
{
|
||||
protocomm_t *pc = (protocomm_t *) priv_data;
|
||||
|
||||
if (pc->sec && pc->sec->security_req_handler) {
|
||||
return pc->sec->security_req_handler(pc->pop, session_id,
|
||||
inbuf, inlen,
|
||||
outbuf, outlen,
|
||||
priv_data);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t protocomm_set_security(protocomm_t *pc, const char *ep_name,
|
||||
const protocomm_security_t *sec,
|
||||
const protocomm_security_pop_t *pop)
|
||||
{
|
||||
if ((pc == NULL) || (ep_name == NULL) || (sec == NULL)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (pc->sec) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
esp_err_t ret = protocomm_add_endpoint_internal(pc, ep_name,
|
||||
protocomm_common_security_handler,
|
||||
(void *) pc, SEC_EP);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error adding security endpoint");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (sec->init) {
|
||||
ret = sec->init();
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error initializing security");
|
||||
protocomm_remove_endpoint(pc, ep_name);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
pc->sec = sec;
|
||||
|
||||
if (pop) {
|
||||
pc->pop = malloc(sizeof(protocomm_security_pop_t));
|
||||
if (pc->pop == NULL) {
|
||||
ESP_LOGE(TAG, "Error allocating Proof of Possession");
|
||||
if (pc->sec && pc->sec->cleanup) {
|
||||
pc->sec->cleanup();
|
||||
pc->sec = NULL;
|
||||
}
|
||||
|
||||
protocomm_remove_endpoint(pc, ep_name);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
memcpy((void *)pc->pop, pop, sizeof(protocomm_security_pop_t));
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t protocomm_unset_security(protocomm_t *pc, const char *ep_name)
|
||||
{
|
||||
if ((pc == NULL) || (ep_name == NULL)) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (pc->sec && pc->sec->cleanup) {
|
||||
pc->sec->cleanup();
|
||||
pc->sec = NULL;
|
||||
}
|
||||
|
||||
if (pc->pop) {
|
||||
free(pc->pop);
|
||||
pc->pop = NULL;
|
||||
}
|
||||
|
||||
return protocomm_remove_endpoint(pc, ep_name);
|
||||
}
|
||||
|
||||
static int protocomm_version_handler(uint32_t session_id,
|
||||
const uint8_t *inbuf, ssize_t inlen,
|
||||
uint8_t **outbuf, ssize_t *outlen,
|
||||
void *priv_data)
|
||||
{
|
||||
protocomm_t *pc = (protocomm_t *) priv_data;
|
||||
if (!pc->ver) {
|
||||
*outlen = 0;
|
||||
*outbuf = NULL;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Output is a non null terminated string with length specified */
|
||||
*outlen = strlen(pc->ver);
|
||||
*outbuf = malloc(*outlen);
|
||||
if (outbuf == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to allocate memory for version response");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
memcpy(*outbuf, pc->ver, *outlen);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t protocomm_set_version(protocomm_t *pc, const char *ep_name, const char *version)
|
||||
{
|
||||
if ((pc == NULL) || (ep_name == NULL) || (version == NULL)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (pc->ver) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
pc->ver = strdup(version);
|
||||
if (pc->ver == NULL) {
|
||||
ESP_LOGE(TAG, "Error allocating version string");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
esp_err_t ret = protocomm_add_endpoint_internal(pc, ep_name,
|
||||
protocomm_version_handler,
|
||||
(void *) pc, VER_EP);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error adding version endpoint");
|
||||
return ret;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t protocomm_unset_version(protocomm_t *pc, const char *ep_name)
|
||||
{
|
||||
if ((pc == NULL) || (ep_name == NULL)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (pc->ver) {
|
||||
free((char *)pc->ver);
|
||||
pc->ver = NULL;
|
||||
}
|
||||
|
||||
return protocomm_remove_endpoint(pc, ep_name);
|
||||
}
|
79
components/protocomm/src/common/protocomm_priv.h
Normal file
79
components/protocomm/src/common/protocomm_priv.h
Normal file
@ -0,0 +1,79 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <rom/queue.h>
|
||||
#include <protocomm_security.h>
|
||||
#include <esp_err.h>
|
||||
|
||||
#define PROTOCOMM_NO_SESSION_ID UINT32_MAX
|
||||
|
||||
/* Bit Flags for indicating intended functionality of handler to either
|
||||
* process request or establish secure session */
|
||||
#define REQ_EP (1 << 0) /*!< Flag indicating request handling endpoint */
|
||||
#define SEC_EP (1 << 1) /*!< Flag indicating security handling endpoint */
|
||||
#define VER_EP (1 << 2) /*!< Flag indicating version handling endpoint */
|
||||
|
||||
/**
|
||||
* @brief Protocomm endpoint table entry prototype
|
||||
*
|
||||
* The structure of an entry stored in the endpoint table.
|
||||
*/
|
||||
typedef struct protocomm_ep {
|
||||
const char *ep_name; /*!< Unique endpoint name */
|
||||
protocomm_req_handler_t req_handler; /*!< Request handler function */
|
||||
|
||||
/* Pointer to private data to be passed as a parameter to the handler
|
||||
* function at the time of call. Set to NULL if not used. */
|
||||
void *priv_data;
|
||||
|
||||
uint32_t flag; /*!< Flag indicating endpoint functionality */
|
||||
|
||||
/* Next endpoint entry in the singly linked list for storing endpoint handlers */
|
||||
SLIST_ENTRY(protocomm_ep) next;
|
||||
} protocomm_ep_t;
|
||||
|
||||
/**
|
||||
* @brief Prototype structure of a Protocomm instance
|
||||
*
|
||||
* This structure corresponds to a unique instance of protocomm returned,
|
||||
* when the API protocomm_new() is called. The remaining Protocomm
|
||||
* APIs require this object as the first parameter.
|
||||
*/
|
||||
struct protocomm {
|
||||
/* Function Prototype of transport specific function, which is called
|
||||
* internally when protocomm_add_endpoint() is invoked. */
|
||||
int (*add_endpoint)(const char *ep_name, protocomm_req_handler_t h, void *priv_data);
|
||||
|
||||
/* Function Prototype of transport specific function, which is called
|
||||
* internally when protocomm_remove_endpoint() is invoked. */
|
||||
int (*remove_endpoint)(const char *ep_name);
|
||||
|
||||
/* Pointer to security layer instance to be used internally for
|
||||
* establishing secure sessions */
|
||||
const protocomm_security_t *sec;
|
||||
|
||||
/* Pointer to proof of possession object */
|
||||
protocomm_security_pop_t *pop;
|
||||
|
||||
/* Head of the singly linked list for storing endpoint handlers */
|
||||
SLIST_HEAD(eptable_t, protocomm_ep) endpoints;
|
||||
|
||||
/* Private data to be used internally by the protocomm instance */
|
||||
void* priv;
|
||||
|
||||
/* Application specific version string */
|
||||
const char* ver;
|
||||
};
|
114
components/protocomm/src/security/security0.c
Normal file
114
components/protocomm/src/security/security0.c
Normal file
@ -0,0 +1,114 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <esp_err.h>
|
||||
#include <esp_log.h>
|
||||
|
||||
#include <protocomm_security.h>
|
||||
#include <protocomm_security0.h>
|
||||
|
||||
#include "session.pb-c.h"
|
||||
#include "sec0.pb-c.h"
|
||||
#include "constants.pb-c.h"
|
||||
|
||||
static const char* TAG = "security0";
|
||||
|
||||
static esp_err_t sec0_session_setup(uint32_t session_id,
|
||||
SessionData *req, SessionData *resp,
|
||||
const protocomm_security_pop_t *pop)
|
||||
{
|
||||
Sec0Payload *out = (Sec0Payload *) malloc(sizeof(Sec0Payload));
|
||||
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);
|
||||
s0_session_resp__init(s0resp);
|
||||
s0resp->status = STATUS__Success;
|
||||
|
||||
out->msg = SEC0_MSG_TYPE__S0_Session_Response;
|
||||
out->payload_case = SEC0_PAYLOAD__PAYLOAD_SR;
|
||||
out->sr = s0resp;
|
||||
|
||||
resp->proto_case = SESSION_DATA__PROTO_SEC0;
|
||||
resp->sec0 = out;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void sec0_session_setup_cleanup(uint32_t session_id, SessionData *resp)
|
||||
{
|
||||
if (!resp) {
|
||||
return;
|
||||
}
|
||||
|
||||
free(resp->sec0->sr);
|
||||
free(resp->sec0);
|
||||
return;
|
||||
}
|
||||
|
||||
static esp_err_t sec0_req_handler(const protocomm_security_pop_t *pop, uint32_t session_id,
|
||||
const uint8_t *inbuf, ssize_t inlen,
|
||||
uint8_t **outbuf, ssize_t *outlen,
|
||||
void *priv_data)
|
||||
{
|
||||
SessionData *req;
|
||||
SessionData resp;
|
||||
esp_err_t ret;
|
||||
|
||||
req = session_data__unpack(NULL, inlen, inbuf);
|
||||
if (!req) {
|
||||
ESP_LOGE(TAG, "Unable to unpack setup_req");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
session_data__init(&resp);
|
||||
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;
|
||||
}
|
||||
|
||||
resp.sec_ver = req->sec_ver;
|
||||
session_data__free_unpacked(req, NULL);
|
||||
|
||||
*outlen = session_data__get_packed_size(&resp);
|
||||
*outbuf = (uint8_t *) malloc(*outlen);
|
||||
if (!*outbuf) {
|
||||
ESP_LOGE(TAG, "System out of memory");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
session_data__pack(&resp, *outbuf);
|
||||
|
||||
sec0_session_setup_cleanup(session_id, &resp);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
const protocomm_security_t protocomm_security0 = {
|
||||
.ver = 0,
|
||||
.security_req_handler = sec0_req_handler,
|
||||
};
|
560
components/protocomm/src/security/security1.c
Normal file
560
components/protocomm/src/security/security1.c
Normal file
@ -0,0 +1,560 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <esp_err.h>
|
||||
#include <esp_log.h>
|
||||
|
||||
#include <mbedtls/aes.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/ecdh.h>
|
||||
#include <mbedtls/error.h>
|
||||
#include <mbedtls/ssl_internal.h>
|
||||
|
||||
#include <protocomm_security.h>
|
||||
#include <protocomm_security1.h>
|
||||
|
||||
#include "session.pb-c.h"
|
||||
#include "sec1.pb-c.h"
|
||||
#include "constants.pb-c.h"
|
||||
|
||||
static const char* TAG = "security1";
|
||||
|
||||
#define PUBLIC_KEY_LEN 32
|
||||
#define SZ_RANDOM 16
|
||||
|
||||
#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 */
|
||||
uint32_t id;
|
||||
uint8_t state;
|
||||
uint8_t device_pubkey[PUBLIC_KEY_LEN];
|
||||
uint8_t client_pubkey[PUBLIC_KEY_LEN];
|
||||
uint8_t sym_key[PUBLIC_KEY_LEN];
|
||||
uint8_t rand[SZ_RANDOM];
|
||||
|
||||
/* mbedtls context data for AES */
|
||||
mbedtls_aes_context ctx_aes;
|
||||
unsigned char stb[16];
|
||||
size_t nc_off;
|
||||
} session_t;
|
||||
|
||||
static session_t *cur_session;
|
||||
|
||||
static void flip_endian(uint8_t *data, size_t len)
|
||||
{
|
||||
uint8_t swp_buf;
|
||||
for (int i = 0; i < len/2; i++) {
|
||||
swp_buf = data[i];
|
||||
data[i] = data[len - i - 1];
|
||||
data[len - i - 1] = swp_buf;
|
||||
}
|
||||
}
|
||||
|
||||
static void hexdump(const char *msg, uint8_t *buf, int len)
|
||||
{
|
||||
ESP_LOGD(TAG, "%s:", msg);
|
||||
ESP_LOG_BUFFER_HEX_LEVEL(TAG, buf, len, ESP_LOG_DEBUG);
|
||||
}
|
||||
|
||||
static esp_err_t handle_session_command1(uint32_t session_id,
|
||||
SessionData *req, SessionData *resp)
|
||||
{
|
||||
ESP_LOGD(TAG, "Request to handle setup1_command");
|
||||
Sec1Payload *in = (Sec1Payload *) req->sec1;
|
||||
uint8_t check_buf[PUBLIC_KEY_LEN];
|
||||
int mbed_err;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* Initialize crypto context */
|
||||
mbedtls_aes_init(&cur_session->ctx_aes);
|
||||
memset(cur_session->stb, 0, sizeof(cur_session->stb));
|
||||
cur_session->nc_off = 0;
|
||||
|
||||
hexdump("Client verifier", in->sc1->client_verify_data.data,
|
||||
in->sc1->client_verify_data.len);
|
||||
|
||||
mbed_err = mbedtls_aes_setkey_enc(&cur_session->ctx_aes, cur_session->sym_key,
|
||||
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;
|
||||
}
|
||||
|
||||
mbed_err = mbedtls_aes_crypt_ctr(&cur_session->ctx_aes,
|
||||
PUBLIC_KEY_LEN, &cur_session->nc_off,
|
||||
cur_session->rand, cur_session->stb,
|
||||
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;
|
||||
}
|
||||
|
||||
hexdump("Dec Client verifier", check_buf, sizeof(check_buf));
|
||||
|
||||
/* constant time memcmp */
|
||||
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));
|
||||
SessionResp1 *out_resp = (SessionResp1 *) malloc(sizeof(SessionResp1));
|
||||
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;
|
||||
}
|
||||
|
||||
mbed_err = mbedtls_aes_crypt_ctr(&cur_session->ctx_aes,
|
||||
PUBLIC_KEY_LEN, &cur_session->nc_off,
|
||||
cur_session->rand, cur_session->stb,
|
||||
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;
|
||||
}
|
||||
|
||||
out_resp->device_verify_data.data = outbuf;
|
||||
out_resp->device_verify_data.len = PUBLIC_KEY_LEN;
|
||||
hexdump("Device verify data", outbuf, PUBLIC_KEY_LEN);
|
||||
|
||||
out->msg = SEC1_MSG_TYPE__Session_Response1;
|
||||
out->payload_case = SEC1_PAYLOAD__PAYLOAD_SR1;
|
||||
out->sr1 = out_resp;
|
||||
|
||||
resp->proto_case = SESSION_DATA__PROTO_SEC1;
|
||||
resp->sec1 = out;
|
||||
|
||||
cur_session->state = SESSION_STATE_DONE;
|
||||
ESP_LOGD(TAG, "Secure session established successfully");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
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->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 (in->sc0->client_pubkey.len != PUBLIC_KEY_LEN) {
|
||||
ESP_LOGE(TAG, "Invalid public key length");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
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));
|
||||
if (!ctx_server || !ctx_server || !ctr_drbg) {
|
||||
ESP_LOGE(TAG, "Failed to allocate memory for mbedtls context");
|
||||
free(ctx_server);
|
||||
free(entropy);
|
||||
free(ctr_drbg);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
mbedtls_ecdh_init(ctx_server);
|
||||
mbedtls_ctr_drbg_init(ctr_drbg);
|
||||
mbedtls_entropy_init(entropy);
|
||||
|
||||
mbed_err = mbedtls_ctr_drbg_seed(ctr_drbg, mbedtls_entropy_func,
|
||||
entropy, NULL, 0);
|
||||
if (mbed_err != 0) {
|
||||
ESP_LOGE(TAG, "Failed at mbedtls_ctr_drbg_seed with error code : -0x%x", -mbed_err);
|
||||
ret = ESP_FAIL;
|
||||
goto exit_cmd0;
|
||||
}
|
||||
|
||||
mbed_err = mbedtls_ecp_group_load(&ctx_server->grp, MBEDTLS_ECP_DP_CURVE25519);
|
||||
if (mbed_err != 0) {
|
||||
ESP_LOGE(TAG, "Failed at mbedtls_ecp_group_load with error code : -0x%x", -mbed_err);
|
||||
ret = ESP_FAIL;
|
||||
goto exit_cmd0;
|
||||
}
|
||||
|
||||
mbed_err = mbedtls_ecdh_gen_public(&ctx_server->grp, &ctx_server->d, &ctx_server->Q,
|
||||
mbedtls_ctr_drbg_random, ctr_drbg);
|
||||
if (mbed_err != 0) {
|
||||
ESP_LOGE(TAG, "Failed at mbedtls_ecdh_gen_public with error code : -0x%x", -mbed_err);
|
||||
ret = ESP_FAIL;
|
||||
goto exit_cmd0;
|
||||
}
|
||||
|
||||
mbed_err = mbedtls_mpi_write_binary(&ctx_server->Q.X,
|
||||
cur_session->device_pubkey,
|
||||
PUBLIC_KEY_LEN);
|
||||
if (mbed_err != 0) {
|
||||
ESP_LOGE(TAG, "Failed at mbedtls_mpi_write_binary with error code : -0x%x", -mbed_err);
|
||||
ret = ESP_FAIL;
|
||||
goto exit_cmd0;
|
||||
}
|
||||
flip_endian(cur_session->device_pubkey, PUBLIC_KEY_LEN);
|
||||
|
||||
memcpy(cur_session->client_pubkey, in->sc0->client_pubkey.data, PUBLIC_KEY_LEN);
|
||||
|
||||
uint8_t *dev_pubkey = cur_session->device_pubkey;
|
||||
uint8_t *cli_pubkey = cur_session->client_pubkey;
|
||||
hexdump("Device pubkey", dev_pubkey, PUBLIC_KEY_LEN);
|
||||
hexdump("Client pubkey", cli_pubkey, PUBLIC_KEY_LEN);
|
||||
|
||||
mbed_err = mbedtls_mpi_lset(&ctx_server->Qp.Z, 1);
|
||||
if (mbed_err != 0) {
|
||||
ESP_LOGE(TAG, "Failed at mbedtls_mpi_lset with error code : -0x%x", -mbed_err);
|
||||
ret = ESP_FAIL;
|
||||
goto exit_cmd0;
|
||||
}
|
||||
|
||||
flip_endian(cur_session->client_pubkey, PUBLIC_KEY_LEN);
|
||||
mbed_err = mbedtls_mpi_read_binary(&ctx_server->Qp.X, cli_pubkey, PUBLIC_KEY_LEN);
|
||||
flip_endian(cur_session->client_pubkey, PUBLIC_KEY_LEN);
|
||||
if (mbed_err != 0) {
|
||||
ESP_LOGE(TAG, "Failed at mbedtls_mpi_read_binary with error code : -0x%x", -mbed_err);
|
||||
ret = ESP_FAIL;
|
||||
goto exit_cmd0;
|
||||
}
|
||||
|
||||
mbed_err = mbedtls_ecdh_compute_shared(&ctx_server->grp, &ctx_server->z, &ctx_server->Qp,
|
||||
&ctx_server->d, mbedtls_ctr_drbg_random, ctr_drbg);
|
||||
if (mbed_err != 0) {
|
||||
ESP_LOGE(TAG, "Failed at mbedtls_ecdh_compute_shared with error code : -0x%x", -mbed_err);
|
||||
ret = ESP_FAIL;
|
||||
goto exit_cmd0;
|
||||
}
|
||||
|
||||
mbed_err = mbedtls_mpi_write_binary(&ctx_server->z, cur_session->sym_key, PUBLIC_KEY_LEN);
|
||||
if (mbed_err != 0) {
|
||||
ESP_LOGE(TAG, "Failed at mbedtls_mpi_write_binary with error code : -0x%x", -mbed_err);
|
||||
ret = ESP_FAIL;
|
||||
goto exit_cmd0;
|
||||
}
|
||||
flip_endian(cur_session->sym_key, PUBLIC_KEY_LEN);
|
||||
|
||||
if (pop != NULL && pop->data != NULL && pop->len != 0) {
|
||||
ESP_LOGD(TAG, "Adding proof of possession");
|
||||
uint8_t sha_out[PUBLIC_KEY_LEN];
|
||||
|
||||
mbed_err = mbedtls_sha256_ret((const unsigned char *) pop->data, pop->len, sha_out, 0);
|
||||
if (mbed_err != 0) {
|
||||
ESP_LOGE(TAG, "Failed at mbedtls_sha256_ret with error code : -0x%x", -mbed_err);
|
||||
ret = ESP_FAIL;
|
||||
goto exit_cmd0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < PUBLIC_KEY_LEN; i++) {
|
||||
cur_session->sym_key[i] ^= sha_out[i];
|
||||
}
|
||||
}
|
||||
|
||||
hexdump("Shared key", cur_session->sym_key, PUBLIC_KEY_LEN);
|
||||
|
||||
mbed_err = mbedtls_ctr_drbg_random(ctr_drbg, cur_session->rand, SZ_RANDOM);
|
||||
if (mbed_err != 0) {
|
||||
ESP_LOGE(TAG, "Failed at mbedtls_ctr_drbg_random with error code : -0x%x", -mbed_err);
|
||||
ret = ESP_FAIL;
|
||||
goto exit_cmd0;
|
||||
}
|
||||
|
||||
hexdump("Device random", cur_session->rand, SZ_RANDOM);
|
||||
|
||||
Sec1Payload *out = (Sec1Payload *) malloc(sizeof(Sec1Payload));
|
||||
SessionResp0 *out_resp = (SessionResp0 *) malloc(sizeof(SessionResp0));
|
||||
if (!out || !out_resp) {
|
||||
ESP_LOGE(TAG, "Error allocating memory for response0");
|
||||
ret = ESP_ERR_NO_MEM;
|
||||
free(out);
|
||||
free(out_resp);
|
||||
goto exit_cmd0;
|
||||
}
|
||||
|
||||
sec1_payload__init(out);
|
||||
session_resp0__init(out_resp);
|
||||
|
||||
out_resp->status = STATUS__Success;
|
||||
|
||||
out_resp->device_pubkey.data = dev_pubkey;
|
||||
out_resp->device_pubkey.len = PUBLIC_KEY_LEN;
|
||||
|
||||
out_resp->device_random.data = (uint8_t *) cur_session->rand;
|
||||
out_resp->device_random.len = SZ_RANDOM;
|
||||
|
||||
out->msg = SEC1_MSG_TYPE__Session_Response0;
|
||||
out->payload_case = SEC1_PAYLOAD__PAYLOAD_SR0;
|
||||
out->sr0 = out_resp;
|
||||
|
||||
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;
|
||||
|
||||
exit_cmd0:
|
||||
mbedtls_ecdh_free(ctx_server);
|
||||
free(ctx_server);
|
||||
|
||||
mbedtls_ctr_drbg_free(ctr_drbg);
|
||||
free(ctr_drbg);
|
||||
|
||||
mbedtls_entropy_free(entropy);
|
||||
free(entropy);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t sec1_session_setup(uint32_t session_id,
|
||||
SessionData *req, SessionData *resp,
|
||||
const protocomm_security_pop_t *pop)
|
||||
{
|
||||
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);
|
||||
break;
|
||||
case SEC1_MSG_TYPE__Session_Command1:
|
||||
ret = handle_session_command1(session_id, req, resp);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(TAG, "Invalid security message type");
|
||||
ret = ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static void sec1_session_setup_cleanup(uint32_t session_id, SessionData *resp)
|
||||
{
|
||||
Sec1Payload *out = resp->sec1;
|
||||
|
||||
if (!out) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (out->msg) {
|
||||
case SEC1_MSG_TYPE__Session_Response0:
|
||||
{
|
||||
SessionResp0 *out_resp0 = out->sr0;
|
||||
if (out_resp0) {
|
||||
free(out_resp0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SEC1_MSG_TYPE__Session_Response1:
|
||||
{
|
||||
SessionResp1 *out_resp1 = out->sr1;
|
||||
if (out_resp1) {
|
||||
free(out_resp1->device_verify_data.data);
|
||||
free(out_resp1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
free(out);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static esp_err_t sec1_close_session(uint32_t session_id)
|
||||
{
|
||||
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) {
|
||||
/* Only one session is allowed at a time */
|
||||
ESP_LOGE(TAG, "Closing old session with id %u", cur_session->id);
|
||||
sec1_close_session(cur_session->id);
|
||||
}
|
||||
|
||||
cur_session = (session_t *) calloc(1, sizeof(session_t));
|
||||
if (!cur_session) {
|
||||
ESP_LOGE(TAG, "Error allocating session structure");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
cur_session->id = session_id;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t sec1_init()
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static esp_err_t sec1_decrypt(uint32_t session_id,
|
||||
const uint8_t *inbuf, ssize_t inlen,
|
||||
uint8_t *outbuf, ssize_t *outlen)
|
||||
{
|
||||
if (*outlen < inlen) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
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);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed at mbedtls_aes_crypt_ctr with error code : %d", ret);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t sec1_req_handler(const protocomm_security_pop_t *pop, uint32_t session_id,
|
||||
const uint8_t *inbuf, ssize_t inlen,
|
||||
uint8_t **outbuf, ssize_t *outlen,
|
||||
void *priv_data)
|
||||
{
|
||||
SessionData *req;
|
||||
SessionData resp;
|
||||
esp_err_t ret;
|
||||
|
||||
req = session_data__unpack(NULL, inlen, inbuf);
|
||||
if (!req) {
|
||||
ESP_LOGE(TAG, "Unable to unpack setup_req");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
session_data__init(&resp);
|
||||
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;
|
||||
}
|
||||
|
||||
resp.sec_ver = req->sec_ver;
|
||||
session_data__free_unpacked(req, NULL);
|
||||
|
||||
*outlen = session_data__get_packed_size(&resp);
|
||||
*outbuf = (uint8_t *) malloc(*outlen);
|
||||
if (!*outbuf) {
|
||||
ESP_LOGE(TAG, "System out of memory");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
session_data__pack(&resp, *outbuf);
|
||||
|
||||
sec1_session_setup_cleanup(session_id, &resp);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
const protocomm_security_t protocomm_security1 = {
|
||||
.ver = 1,
|
||||
.init = sec1_init,
|
||||
.cleanup = sec1_cleanup,
|
||||
.new_transport_session = sec1_new_session,
|
||||
.close_transport_session = sec1_close_session,
|
||||
.security_req_handler = sec1_req_handler,
|
||||
.encrypt = sec1_decrypt, /* Encrypt == decrypt for AES-CTR */
|
||||
.decrypt = sec1_decrypt,
|
||||
};
|
268
components/protocomm/src/simple_ble/simple_ble.c
Normal file
268
components/protocomm/src/simple_ble/simple_ble.c
Normal file
@ -0,0 +1,268 @@
|
||||
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <esp_system.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_bt.h>
|
||||
#include <esp_gap_ble_api.h>
|
||||
#include <esp_gatts_api.h>
|
||||
#include <esp_bt_main.h>
|
||||
#include <esp_gatt_common_api.h>
|
||||
|
||||
#include "simple_ble.h"
|
||||
|
||||
#define SIMPLE_BLE_MAX_GATT_TABLE_SIZE 20
|
||||
|
||||
static const char *TAG = "simple_ble";
|
||||
|
||||
static simple_ble_cfg_t *g_ble_cfg_p;
|
||||
static uint16_t g_gatt_table_map[SIMPLE_BLE_MAX_GATT_TABLE_SIZE];
|
||||
|
||||
uint16_t simple_ble_get_uuid(uint16_t handle)
|
||||
{
|
||||
uint16_t *uuid_ptr;
|
||||
|
||||
for (int i = 0; i < SIMPLE_BLE_MAX_GATT_TABLE_SIZE; i++) {
|
||||
if (g_gatt_table_map[i] == handle) {
|
||||
uuid_ptr = (uint16_t *) g_ble_cfg_p->gatt_db[i].att_desc.uuid_p;
|
||||
return *uuid_ptr;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
|
||||
{
|
||||
switch (event) {
|
||||
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
|
||||
esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t p_gatts_if, esp_ble_gatts_cb_param_t *param)
|
||||
{
|
||||
static esp_gatt_if_t gatts_if = ESP_GATT_IF_NONE;
|
||||
esp_err_t ret;
|
||||
uint8_t service_instance_id = 0;
|
||||
if (event == ESP_GATTS_REG_EVT) {
|
||||
if (param->reg.status == ESP_GATT_OK) {
|
||||
gatts_if = p_gatts_if;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "reg app failed, app_id 0x0x%x, status %d",
|
||||
param->reg.app_id,
|
||||
param->reg.status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (gatts_if != ESP_GATT_IF_NONE && gatts_if != p_gatts_if) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event) {
|
||||
case ESP_GATTS_REG_EVT:
|
||||
ret = esp_ble_gatts_create_attr_tab(g_ble_cfg_p->gatt_db, gatts_if, g_ble_cfg_p->gatt_db_count, service_instance_id);
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "create attr table failed, error code = 0x%x", ret);
|
||||
return;
|
||||
}
|
||||
ret = esp_ble_gap_set_device_name(g_ble_cfg_p->device_name);
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "set device name failed, error code = 0x%x", ret);
|
||||
return;
|
||||
}
|
||||
ret = esp_ble_gap_config_adv_data(&g_ble_cfg_p->adv_data);
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "config adv data failed, error code = 0x%x", ret);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case ESP_GATTS_READ_EVT:
|
||||
g_ble_cfg_p->read_fn(event, gatts_if, param);
|
||||
break;
|
||||
case ESP_GATTS_WRITE_EVT:
|
||||
g_ble_cfg_p->write_fn(event, gatts_if, param);
|
||||
break;
|
||||
case ESP_GATTS_EXEC_WRITE_EVT:
|
||||
g_ble_cfg_p->exec_write_fn(event, gatts_if, param);
|
||||
break;
|
||||
case ESP_GATTS_MTU_EVT:
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case ESP_GATTS_CONF_EVT:
|
||||
ESP_LOGD(TAG, "ESP_GATTS_CONF_EVT, status = %d", param->conf.status);
|
||||
break;
|
||||
case ESP_GATTS_START_EVT:
|
||||
ESP_LOGD(TAG, "SERVICE_START_EVT, status %d, service_handle %d", param->start.status, param->start.service_handle);
|
||||
break;
|
||||
case ESP_GATTS_CONNECT_EVT:
|
||||
ESP_LOGD(TAG, "ESP_GATTS_CONNECT_EVT, conn_id = %d", param->connect.conn_id);
|
||||
g_ble_cfg_p->connect_fn(event, gatts_if, param);
|
||||
esp_ble_conn_update_params_t conn_params = {0};
|
||||
memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
|
||||
/* For the iOS system, please refer the official Apple documents about BLE connection parameters restrictions. */
|
||||
conn_params.latency = 0;
|
||||
conn_params.max_int = 0x20; // max_int = 0x20*1.25ms = 40ms
|
||||
conn_params.min_int = 0x10; // min_int = 0x10*1.25ms = 20ms
|
||||
conn_params.timeout = 400; // timeout = 400*10ms = 4000ms
|
||||
esp_ble_gap_update_conn_params(&conn_params);
|
||||
break;
|
||||
case ESP_GATTS_DISCONNECT_EVT:
|
||||
ESP_LOGD(TAG, "ESP_GATTS_DISCONNECT_EVT, reason = %d", param->disconnect.reason);
|
||||
g_ble_cfg_p->disconnect_fn(event, gatts_if, param);
|
||||
esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params);
|
||||
break;
|
||||
case ESP_GATTS_CREAT_ATTR_TAB_EVT: {
|
||||
if (param->add_attr_tab.status != ESP_GATT_OK) {
|
||||
ESP_LOGE(TAG, "creating the attribute table failed, error code=0x%x", param->add_attr_tab.status);
|
||||
} else if (param->add_attr_tab.num_handle != g_ble_cfg_p->gatt_db_count) {
|
||||
ESP_LOGE(TAG, "created attribute table abnormally ");
|
||||
} else {
|
||||
ESP_LOGD(TAG, "created attribute table successfully, the number handle = %d", param->add_attr_tab.num_handle);
|
||||
memcpy(g_gatt_table_map, param->add_attr_tab.handles, param->add_attr_tab.num_handle * sizeof(g_gatt_table_map[0]));
|
||||
/* We assume, for now, that the first entry is always the index to the 'service' definition */
|
||||
esp_ble_gatts_start_service(g_gatt_table_map[0]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ESP_GATTS_STOP_EVT:
|
||||
case ESP_GATTS_OPEN_EVT:
|
||||
case ESP_GATTS_CANCEL_OPEN_EVT:
|
||||
case ESP_GATTS_CLOSE_EVT:
|
||||
case ESP_GATTS_LISTEN_EVT:
|
||||
case ESP_GATTS_CONGEST_EVT:
|
||||
case ESP_GATTS_UNREG_EVT:
|
||||
case ESP_GATTS_DELETE_EVT:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
simple_ble_cfg_t *simple_ble_init()
|
||||
{
|
||||
simple_ble_cfg_t *ble_cfg_p = (simple_ble_cfg_t *) malloc(sizeof(simple_ble_cfg_t));
|
||||
if (ble_cfg_p == NULL) {
|
||||
ESP_LOGE(TAG, "No memory for simple_ble_cfg_t");
|
||||
return NULL;
|
||||
}
|
||||
return ble_cfg_p;
|
||||
}
|
||||
|
||||
esp_err_t simple_ble_deinit()
|
||||
{
|
||||
free(g_ble_cfg_p->gatt_db);
|
||||
free(g_ble_cfg_p);
|
||||
g_ble_cfg_p = NULL;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Expects the pointer stays valid throughout */
|
||||
esp_err_t simple_ble_start(simple_ble_cfg_t *cfg)
|
||||
{
|
||||
g_ble_cfg_p = cfg;
|
||||
ESP_LOGD(TAG, "Free mem at start of simple_ble_init %d", esp_get_free_heap_size());
|
||||
esp_err_t ret;
|
||||
|
||||
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
|
||||
ret = esp_bt_controller_init(&bt_cfg);
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "%s enable controller failed %d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "%s enable controller failed %d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = esp_bluedroid_init();
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "%s init bluetooth failed %d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = esp_bluedroid_enable();
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "%s enable bluetooth failed %d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = esp_ble_gatts_register_callback(gatts_profile_event_handler);
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "gatts register error, error code = 0x%x", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = esp_ble_gap_register_callback(gap_event_handler);
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "gap register error, error code = 0x%x", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint16_t app_id = 0x55;
|
||||
ret = esp_ble_gatts_app_register(app_id);
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "gatts app register error, error code = 0x%x", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(500);
|
||||
if (local_mtu_ret) {
|
||||
ESP_LOGE(TAG, "set local MTU failed, error code = 0x%x", local_mtu_ret);
|
||||
}
|
||||
ESP_LOGD(TAG, "Free mem at end of simple_ble_init %d", esp_get_free_heap_size());
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t simple_ble_stop()
|
||||
{
|
||||
esp_err_t err;
|
||||
ESP_LOGD(TAG, "Free mem at start of simple_ble_stop %d", esp_get_free_heap_size());
|
||||
err = esp_bluedroid_disable();
|
||||
if (err != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_LOGD(TAG, "esp_bluedroid_disable called successfully");
|
||||
err = esp_bluedroid_deinit();
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
ESP_LOGD(TAG, "esp_bluedroid_deinit called successfully");
|
||||
err = esp_bt_controller_disable();
|
||||
if (err != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* The API `esp_bt_controller_deinit` will have to be removed when we add support for
|
||||
* `reset to provisioning`
|
||||
*/
|
||||
ESP_LOGD(TAG, "esp_bt_controller_disable called successfully");
|
||||
err = esp_bt_controller_deinit();
|
||||
if (err != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_LOGD(TAG, "esp_bt_controller_deinit called successfully");
|
||||
|
||||
ESP_LOGD(TAG, "Free mem at end of simple_ble_stop %d", esp_get_free_heap_size());
|
||||
return ESP_OK;
|
||||
}
|
107
components/protocomm/src/simple_ble/simple_ble.h
Normal file
107
components/protocomm/src/simple_ble/simple_ble.h
Normal file
@ -0,0 +1,107 @@
|
||||
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#ifndef _SIMPLE_BLE_
|
||||
#define _SIMPLE_BLE_
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <esp_gap_ble_api.h>
|
||||
#include <esp_gatts_api.h>
|
||||
|
||||
typedef void (simple_ble_cb_t)(esp_gatts_cb_event_t event, esp_gatt_if_t p_gatts_if, esp_ble_gatts_cb_param_t *param);
|
||||
|
||||
/**
|
||||
* This structure is populated with the details required
|
||||
* to create an instance of BLE easily. It requires function
|
||||
* pointers, advertising parameters and gatt description table
|
||||
*/
|
||||
typedef struct {
|
||||
/** Name to be displayed to devices scanning for ESP32 */
|
||||
const char *device_name;
|
||||
/** Advertising data content, according to "Supplement to the Bluetooth Core Specification" */
|
||||
esp_ble_adv_data_t adv_data;
|
||||
/** Parameters to configure the nature of advertising */
|
||||
esp_ble_adv_params_t adv_params;
|
||||
/** Descriptor table which consists the configuration required by services and characteristics */
|
||||
esp_gatts_attr_db_t *gatt_db;
|
||||
/** Number of entries in the gatt_db descriptor table */
|
||||
ssize_t gatt_db_count;
|
||||
/** BLE read callback */
|
||||
simple_ble_cb_t *read_fn;
|
||||
/** BLE write callback */
|
||||
simple_ble_cb_t *write_fn;
|
||||
/** BLE exec write callback */
|
||||
simple_ble_cb_t *exec_write_fn;
|
||||
/** Client disconnect callback */
|
||||
simple_ble_cb_t *disconnect_fn;
|
||||
/** Client connect callback */
|
||||
simple_ble_cb_t *connect_fn;
|
||||
/** MTU set callback */
|
||||
simple_ble_cb_t *set_mtu_fn;
|
||||
} simple_ble_cfg_t;
|
||||
|
||||
|
||||
/** Initialize a simple ble connection
|
||||
*
|
||||
* This function allocates memory and returns a pointer to the
|
||||
* configuration structure.
|
||||
*
|
||||
* @return simple_ble_cfg_t* Pointer to configuration structure
|
||||
*/
|
||||
simple_ble_cfg_t *simple_ble_init();
|
||||
|
||||
/** Deallocates memory
|
||||
*
|
||||
* This function deallocate memory of the configuration structure.
|
||||
*
|
||||
* @return ESP_OK
|
||||
*/
|
||||
esp_err_t simple_ble_deinit();
|
||||
|
||||
/** Starts BLE service
|
||||
*
|
||||
* This function makes calls to the GATT and GAP APIs
|
||||
* to initialize the BLE service as per parameters stored
|
||||
* in the config structure. At the end of this function,
|
||||
* one should be able to scan and connect to the ESP32 device
|
||||
* using BLE.
|
||||
* This API sets the MTU size to 500 (this is not part of the config structure)
|
||||
*
|
||||
* @return ESP_OK on success, and appropriate error code for failure
|
||||
*/
|
||||
esp_err_t simple_ble_start(simple_ble_cfg_t *cfg);
|
||||
|
||||
/** Stops the BLE service
|
||||
*
|
||||
* This API is called to stop the BLE service.
|
||||
* This includes calls to disable and deinit bluedroid and bt controller.
|
||||
*
|
||||
* @return ESP_OK on success, and appropriate error code for failure
|
||||
*/
|
||||
esp_err_t simple_ble_stop();
|
||||
|
||||
/** Convert handle to UUID of characteristic
|
||||
*
|
||||
* This function can be easily used to get the corresponding
|
||||
* UUID for a characteristic that has been created, and the one for
|
||||
* which we only have the handle for.
|
||||
*
|
||||
* @return uuid the UUID of the handle, -1 in case of invalid handle
|
||||
*/
|
||||
uint16_t simple_ble_get_uuid(uint16_t handle);
|
||||
|
||||
#endif /* _SIMPLE_BLE_ */
|
510
components/protocomm/src/transports/protocomm_ble.c
Normal file
510
components/protocomm/src/transports/protocomm_ble.c
Normal file
@ -0,0 +1,510 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_gatt_common_api.h>
|
||||
|
||||
#include <protocomm.h>
|
||||
#include <protocomm_ble.h>
|
||||
|
||||
#include "protocomm_priv.h"
|
||||
#include "simple_ble.h"
|
||||
|
||||
#define CHAR_VAL_LEN_MAX (256 + 1)
|
||||
#define PREPARE_BUF_MAX_SIZE CHAR_VAL_LEN_MAX
|
||||
|
||||
static const char *TAG = "protocomm_ble";
|
||||
|
||||
/* BLE specific configuration parameters */
|
||||
const uint16_t GATTS_SERVICE_UUID_PROV = 0xFFFF;
|
||||
const uint16_t primary_service_uuid = ESP_GATT_UUID_PRI_SERVICE;
|
||||
const uint16_t character_declaration_uuid = ESP_GATT_UUID_CHAR_DECLARE;
|
||||
const uint8_t char_prop_read_write = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE;
|
||||
|
||||
typedef struct {
|
||||
uint8_t *prepare_buf;
|
||||
int prepare_len;
|
||||
uint16_t handle;
|
||||
} prepare_type_env_t;
|
||||
|
||||
static prepare_type_env_t prepare_write_env;
|
||||
|
||||
typedef struct _protocomm_ble {
|
||||
protocomm_t *pc_ble;
|
||||
protocomm_ble_name_uuid_t *g_nu_lookup;
|
||||
ssize_t g_nu_lookup_count;
|
||||
uint16_t gatt_mtu;
|
||||
} _protocomm_ble_internal_t;
|
||||
|
||||
static _protocomm_ble_internal_t *protoble_internal;
|
||||
|
||||
static esp_ble_adv_params_t adv_params = {
|
||||
.adv_int_min = 0x100,
|
||||
.adv_int_max = 0x100,
|
||||
.adv_type = ADV_TYPE_IND,
|
||||
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
|
||||
.channel_map = ADV_CHNL_ALL,
|
||||
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
|
||||
};
|
||||
|
||||
static char* protocomm_ble_device_name = NULL;
|
||||
|
||||
/* The length of adv data must be less than 31 bytes */
|
||||
static esp_ble_adv_data_t adv_data = {
|
||||
.set_scan_rsp = false,
|
||||
.include_name = true,
|
||||
.include_txpower = true,
|
||||
.min_interval = 0x100,
|
||||
.max_interval = 0x100,
|
||||
.appearance = ESP_BLE_APPEARANCE_UNKNOWN,
|
||||
.manufacturer_len = 0,
|
||||
.p_manufacturer_data = NULL,
|
||||
.service_data_len = 0,
|
||||
.p_service_data = NULL,
|
||||
.service_uuid_len = 0,
|
||||
.p_service_uuid = NULL,
|
||||
.flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
|
||||
};
|
||||
|
||||
static void hexdump(const char *msg, uint8_t *buf, int len)
|
||||
{
|
||||
ESP_LOGD(TAG, "%s:", msg);
|
||||
ESP_LOG_BUFFER_HEX_LEVEL(TAG, buf, len, ESP_LOG_DEBUG);
|
||||
}
|
||||
|
||||
static const char *handle_to_handler(uint16_t handle)
|
||||
{
|
||||
uint16_t uuid = simple_ble_get_uuid(handle);
|
||||
for (int i = 0; i < protoble_internal->g_nu_lookup_count; i++) {
|
||||
if (protoble_internal->g_nu_lookup[i].uuid == uuid ) {
|
||||
return protoble_internal->g_nu_lookup[i].name;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void transport_simple_ble_read(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
|
||||
{
|
||||
static const uint8_t *read_buf = NULL;
|
||||
static uint16_t read_len = 0;
|
||||
esp_gatt_status_t status = ESP_OK;
|
||||
|
||||
ESP_LOGD(TAG, "Inside read w/ session - %d on param %d %d",
|
||||
param->read.conn_id, param->read.handle, read_len);
|
||||
if (!read_len) {
|
||||
ESP_LOGD(TAG, "Reading attr value first time");
|
||||
status = esp_ble_gatts_get_attr_value(param->read.handle, &read_len, &read_buf);
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Subsequent read request for attr value");
|
||||
}
|
||||
|
||||
esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *) malloc(sizeof(esp_gatt_rsp_t));
|
||||
if (gatt_rsp != NULL) {
|
||||
gatt_rsp->attr_value.len = MIN(read_len, (protoble_internal->gatt_mtu - 1));
|
||||
if (read_len && read_buf) {
|
||||
memcpy(gatt_rsp->attr_value.value,
|
||||
read_buf + param->read.offset,
|
||||
gatt_rsp->attr_value.len);
|
||||
}
|
||||
read_len -= gatt_rsp->attr_value.len;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "%s, malloc failed", __func__);
|
||||
return;
|
||||
}
|
||||
esp_err_t err = esp_ble_gatts_send_response(gatts_if, param->read.conn_id,
|
||||
param->read.trans_id, status, gatt_rsp);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Send response error in read");
|
||||
}
|
||||
free(gatt_rsp);
|
||||
}
|
||||
|
||||
static esp_err_t prepare_write_event_env(esp_gatt_if_t gatts_if,
|
||||
esp_ble_gatts_cb_param_t *param)
|
||||
{
|
||||
ESP_LOGD(TAG, "prepare write, handle = %d, value len = %d",
|
||||
param->write.handle, param->write.len);
|
||||
esp_gatt_status_t status = ESP_GATT_OK;
|
||||
if (prepare_write_env.prepare_buf == NULL) {
|
||||
prepare_write_env.prepare_buf = (uint8_t *) malloc(PREPARE_BUF_MAX_SIZE * sizeof(uint8_t));
|
||||
if (prepare_write_env.prepare_buf == NULL) {
|
||||
ESP_LOGE(TAG, "%s , failed tp allocate preparebuf", __func__);
|
||||
status = ESP_GATT_NO_RESOURCES;
|
||||
}
|
||||
/* prepare_write_env.prepare_len = 0; */
|
||||
} else {
|
||||
if (param->write.offset > PREPARE_BUF_MAX_SIZE) {
|
||||
status = ESP_GATT_INVALID_OFFSET;
|
||||
} else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) {
|
||||
status = ESP_GATT_INVALID_ATTR_LEN;
|
||||
}
|
||||
}
|
||||
memcpy(prepare_write_env.prepare_buf + param->write.offset,
|
||||
param->write.value,
|
||||
param->write.len);
|
||||
prepare_write_env.prepare_len += param->write.len;
|
||||
prepare_write_env.handle = param->write.handle;
|
||||
if (param->write.need_rsp) {
|
||||
esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *) malloc(sizeof(esp_gatt_rsp_t));
|
||||
if (gatt_rsp != NULL) {
|
||||
gatt_rsp->attr_value.len = param->write.len;
|
||||
gatt_rsp->attr_value.handle = param->write.handle;
|
||||
gatt_rsp->attr_value.offset = param->write.offset;
|
||||
gatt_rsp->attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE;
|
||||
memcpy(gatt_rsp->attr_value.value, param->write.value, param->write.len);
|
||||
esp_err_t response_err = esp_ble_gatts_send_response(gatts_if, param->write.conn_id,
|
||||
param->write.trans_id, status,
|
||||
gatt_rsp);
|
||||
if (response_err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Send response error in prep write");
|
||||
}
|
||||
free(gatt_rsp);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "%s, malloc failed", __func__);
|
||||
}
|
||||
}
|
||||
if (status != ESP_GATT_OK) {
|
||||
if (prepare_write_env.prepare_buf) {
|
||||
free(prepare_write_env.prepare_buf);
|
||||
prepare_write_env.prepare_buf = NULL;
|
||||
prepare_write_env.prepare_len = 0;
|
||||
}
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void transport_simple_ble_write(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
|
||||
{
|
||||
uint8_t *outbuf = NULL;
|
||||
ssize_t outlen = 0;
|
||||
esp_err_t ret;
|
||||
|
||||
ESP_LOGD(TAG, "Inside write with session - %d on attr handle - %d \nLen -%d IS Prep - %d",
|
||||
param->write.conn_id, param->write.handle, param->write.len, param->write.is_prep);
|
||||
|
||||
if (param->write.is_prep) {
|
||||
ret = prepare_write_event_env(gatts_if, param);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error appending to prepare buffer");
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
ESP_LOGD(TAG, "is_prep not set");
|
||||
}
|
||||
|
||||
ret = protocomm_req_handle(protoble_internal->pc_ble,
|
||||
handle_to_handler(param->write.handle),
|
||||
param->exec_write.conn_id,
|
||||
param->write.value,
|
||||
param->write.len,
|
||||
&outbuf, &outlen);
|
||||
if (ret == ESP_OK) {
|
||||
ret = esp_ble_gatts_set_attr_value(param->write.handle, outlen, outbuf);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set the session attribute value");
|
||||
}
|
||||
ret = esp_ble_gatts_send_response(gatts_if, param->write.conn_id,
|
||||
param->write.trans_id, ESP_GATT_OK, NULL);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Send response error in write");
|
||||
}
|
||||
hexdump("Response from write", outbuf, outlen);
|
||||
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Invalid content received, killing connection");
|
||||
esp_ble_gatts_close(gatts_if, param->write.conn_id);
|
||||
}
|
||||
if (outbuf) {
|
||||
free(outbuf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void transport_simple_ble_exec_write(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
|
||||
{
|
||||
esp_err_t err;
|
||||
uint8_t *outbuf = NULL;
|
||||
ssize_t outlen = 0;
|
||||
ESP_LOGD(TAG, "Inside exec_write w/ session - %d", param->exec_write.conn_id);
|
||||
|
||||
if ((param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC)
|
||||
&&
|
||||
prepare_write_env.prepare_buf) {
|
||||
err = protocomm_req_handle(protoble_internal->pc_ble,
|
||||
handle_to_handler(prepare_write_env.handle),
|
||||
param->exec_write.conn_id,
|
||||
prepare_write_env.prepare_buf,
|
||||
prepare_write_env.prepare_len,
|
||||
&outbuf, &outlen);
|
||||
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Invalid content received, killing connection");
|
||||
esp_ble_gatts_close(gatts_if, param->write.conn_id);
|
||||
} else {
|
||||
hexdump("Response from exec write", outbuf, outlen);
|
||||
esp_ble_gatts_set_attr_value(prepare_write_env.handle, outlen, outbuf);
|
||||
}
|
||||
}
|
||||
if (prepare_write_env.prepare_buf) {
|
||||
free(prepare_write_env.prepare_buf);
|
||||
prepare_write_env.prepare_buf = NULL;
|
||||
prepare_write_env.prepare_len = 0;
|
||||
}
|
||||
|
||||
err = esp_ble_gatts_send_response(gatts_if, param->exec_write.conn_id, param->exec_write.trans_id, ESP_GATT_OK, NULL);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Send response error in exec write");
|
||||
}
|
||||
if (outbuf) {
|
||||
free(outbuf);
|
||||
}
|
||||
}
|
||||
|
||||
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_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);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "error closing the session after disconnect");
|
||||
}
|
||||
}
|
||||
protoble_internal->gatt_mtu = ESP_GATT_DEF_BLE_MTU_SIZE;
|
||||
}
|
||||
|
||||
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_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);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "error creating the session");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void transport_simple_ble_set_mtu(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
|
||||
{
|
||||
protoble_internal->gatt_mtu = param->mtu.mtu;
|
||||
return;
|
||||
}
|
||||
|
||||
static esp_err_t protocomm_ble_add_endpoint(const char *ep_name,
|
||||
protocomm_req_handler_t req_handler,
|
||||
void *priv_data)
|
||||
{
|
||||
/* Endpoint UUID already added when protocomm_ble_start() was called */
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t protocomm_ble_remove_endpoint(const char *ep_name)
|
||||
{
|
||||
/* Endpoint UUID will be removed when protocomm_ble_stop() is called */
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t populate_gatt_db(esp_gatts_attr_db_t **gatt_db_generated)
|
||||
{
|
||||
int i;
|
||||
/* We need esp_gatts_attr_db_t of size 2 * number of handlers + 1 for service */
|
||||
ssize_t gatt_db_generated_entries = 2 * protoble_internal->g_nu_lookup_count + 1;
|
||||
|
||||
*gatt_db_generated = (esp_gatts_attr_db_t *) malloc(sizeof(esp_gatts_attr_db_t) *
|
||||
(gatt_db_generated_entries));
|
||||
if ((*gatt_db_generated) == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to assign memory to gatt_db");
|
||||
return -1;
|
||||
}
|
||||
/* Declare service */
|
||||
(*gatt_db_generated)[0].attr_control.auto_rsp = ESP_GATT_RSP_BY_APP;
|
||||
|
||||
(*gatt_db_generated)[0].att_desc.uuid_length = ESP_UUID_LEN_16;
|
||||
(*gatt_db_generated)[0].att_desc.uuid_p = (uint8_t *) &primary_service_uuid;
|
||||
(*gatt_db_generated)[0].att_desc.perm = ESP_GATT_PERM_READ;
|
||||
(*gatt_db_generated)[0].att_desc.max_length = sizeof(uint16_t);
|
||||
(*gatt_db_generated)[0].att_desc.length = sizeof(GATTS_SERVICE_UUID_PROV);
|
||||
(*gatt_db_generated)[0].att_desc.value = (uint8_t *) &GATTS_SERVICE_UUID_PROV;
|
||||
|
||||
/* Declare characteristics */
|
||||
for (i = 1 ; i < gatt_db_generated_entries ; i++) {
|
||||
(*gatt_db_generated)[i].attr_control.auto_rsp = ESP_GATT_RSP_BY_APP;
|
||||
|
||||
(*gatt_db_generated)[i].att_desc.uuid_length = ESP_UUID_LEN_16;
|
||||
(*gatt_db_generated)[i].att_desc.perm = ESP_GATT_PERM_READ |
|
||||
ESP_GATT_PERM_WRITE;
|
||||
|
||||
if (i % 2 == 1) { /* Char Declaration */
|
||||
(*gatt_db_generated)[i].att_desc.uuid_p = (uint8_t *) &character_declaration_uuid;
|
||||
(*gatt_db_generated)[i].att_desc.max_length = sizeof(uint8_t);
|
||||
(*gatt_db_generated)[i].att_desc.length = sizeof(uint8_t);
|
||||
(*gatt_db_generated)[i].att_desc.value = (uint8_t *) &char_prop_read_write;
|
||||
} else { /* Char Value */
|
||||
(*gatt_db_generated)[i].att_desc.uuid_p = (uint8_t *)&protoble_internal->g_nu_lookup[i / 2 - 1].uuid;
|
||||
(*gatt_db_generated)[i].att_desc.max_length = CHAR_VAL_LEN_MAX;
|
||||
(*gatt_db_generated)[i].att_desc.length = 0;
|
||||
(*gatt_db_generated)[i].att_desc.value = NULL;
|
||||
}
|
||||
}
|
||||
return gatt_db_generated_entries;
|
||||
}
|
||||
|
||||
static void protocomm_ble_cleanup(void)
|
||||
{
|
||||
if (protoble_internal) {
|
||||
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((void *)protoble_internal->g_nu_lookup[i].name);
|
||||
}
|
||||
}
|
||||
free(protoble_internal->g_nu_lookup);
|
||||
}
|
||||
free(protoble_internal);
|
||||
protoble_internal = NULL;
|
||||
}
|
||||
if (protocomm_ble_device_name) {
|
||||
free(protocomm_ble_device_name);
|
||||
protocomm_ble_device_name = NULL;
|
||||
}
|
||||
if (adv_data.p_service_uuid) {
|
||||
free(adv_data.p_service_uuid);
|
||||
adv_data.p_service_uuid = NULL;
|
||||
adv_data.service_uuid_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *config)
|
||||
{
|
||||
if (!pc || !config || !config->device_name || !config->nu_lookup) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (protoble_internal) {
|
||||
ESP_LOGE(TAG, "Protocomm BLE already started");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* Store service UUID internally */
|
||||
adv_data.service_uuid_len = sizeof(config->service_uuid);
|
||||
adv_data.p_service_uuid = malloc(sizeof(config->service_uuid));
|
||||
if (adv_data.p_service_uuid == NULL) {
|
||||
ESP_LOGE(TAG, "Error allocating memory for storing service UUID");
|
||||
protocomm_ble_cleanup();
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
memcpy(adv_data.p_service_uuid, config->service_uuid, adv_data.service_uuid_len);
|
||||
|
||||
/* Store BLE device name internally */
|
||||
protocomm_ble_device_name = strdup(config->device_name);
|
||||
if (protocomm_ble_device_name == NULL) {
|
||||
ESP_LOGE(TAG, "Error allocating memory for storing BLE device name");
|
||||
protocomm_ble_cleanup();
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
protoble_internal = (_protocomm_ble_internal_t *) calloc(1, sizeof(_protocomm_ble_internal_t));
|
||||
if (protoble_internal == NULL) {
|
||||
ESP_LOGE(TAG, "Error allocating internal protocomm structure");
|
||||
protocomm_ble_cleanup();
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
protoble_internal->g_nu_lookup_count = config->nu_lookup_count;
|
||||
protoble_internal->g_nu_lookup = malloc(config->nu_lookup_count * sizeof(protocomm_ble_name_uuid_t));
|
||||
if (protoble_internal->g_nu_lookup == NULL) {
|
||||
ESP_LOGE(TAG, "Error allocating internal name UUID table");
|
||||
protocomm_ble_cleanup();
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < protoble_internal->g_nu_lookup_count; i++) {
|
||||
protoble_internal->g_nu_lookup[i].uuid = config->nu_lookup[i].uuid;
|
||||
protoble_internal->g_nu_lookup[i].name = strdup(config->nu_lookup[i].name);
|
||||
if (protoble_internal->g_nu_lookup[i].name == NULL) {
|
||||
ESP_LOGE(TAG, "Error allocating internal name UUID entry");
|
||||
protocomm_ble_cleanup();
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
pc->add_endpoint = protocomm_ble_add_endpoint;
|
||||
pc->remove_endpoint = protocomm_ble_remove_endpoint;
|
||||
protoble_internal->pc_ble = pc;
|
||||
protoble_internal->gatt_mtu = ESP_GATT_DEF_BLE_MTU_SIZE;
|
||||
|
||||
simple_ble_cfg_t *ble_config = simple_ble_init();
|
||||
if (ble_config == NULL) {
|
||||
ESP_LOGE(TAG, "Ran out of memory for BLE config");
|
||||
protocomm_ble_cleanup();
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
/* Set function pointers required for simple BLE layer */
|
||||
ble_config->read_fn = transport_simple_ble_read;
|
||||
ble_config->write_fn = transport_simple_ble_write;
|
||||
ble_config->exec_write_fn = transport_simple_ble_exec_write;
|
||||
ble_config->disconnect_fn = transport_simple_ble_disconnect;
|
||||
ble_config->connect_fn = transport_simple_ble_connect;
|
||||
ble_config->set_mtu_fn = transport_simple_ble_set_mtu;
|
||||
|
||||
/* Set parameters required for advertising */
|
||||
ble_config->adv_data = adv_data;
|
||||
ble_config->adv_params = adv_params;
|
||||
|
||||
ble_config->device_name = protocomm_ble_device_name;
|
||||
ble_config->gatt_db_count = populate_gatt_db(&ble_config->gatt_db);
|
||||
|
||||
if (ble_config->gatt_db_count == -1) {
|
||||
ESP_LOGE(TAG, "Invalid GATT database count");
|
||||
simple_ble_deinit();
|
||||
protocomm_ble_cleanup();
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
esp_err_t err = simple_ble_start(ble_config);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "simple_ble_start failed w/ error code 0x%x", err);
|
||||
simple_ble_deinit();
|
||||
protocomm_ble_cleanup();
|
||||
return err;
|
||||
}
|
||||
|
||||
prepare_write_env.prepare_buf = NULL;
|
||||
ESP_LOGD(TAG, "Waiting for client to connect ......");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t protocomm_ble_stop(protocomm_t *pc)
|
||||
{
|
||||
if ((pc != NULL) &&
|
||||
(protoble_internal != NULL ) &&
|
||||
(pc == protoble_internal->pc_ble)) {
|
||||
esp_err_t ret = ESP_OK;
|
||||
ret = simple_ble_stop();
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "BLE stop failed");
|
||||
}
|
||||
simple_ble_deinit();
|
||||
protocomm_ble_cleanup();
|
||||
return ret;
|
||||
}
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
224
components/protocomm/src/transports/protocomm_console.c
Normal file
224
components/protocomm/src/transports/protocomm_console.c
Normal file
@ -0,0 +1,224 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_console.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <freertos/queue.h>
|
||||
#include <driver/uart.h>
|
||||
|
||||
#include <protocomm.h>
|
||||
#include <protocomm_console.h>
|
||||
|
||||
#include "protocomm_priv.h"
|
||||
|
||||
static const char *TAG = "protocomm_console";
|
||||
|
||||
static uint32_t session_id = PROTOCOMM_NO_SESSION_ID;
|
||||
static protocomm_t *pc_console = NULL; /* The global protocomm instance for console */
|
||||
static TaskHandle_t console_task = NULL;
|
||||
|
||||
esp_err_t protocomm_console_stop(protocomm_t *pc)
|
||||
{
|
||||
if (pc != pc_console) {
|
||||
ESP_LOGE(TAG, "Incorrect stop request");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Stopping console...");
|
||||
xTaskNotifyGive(console_task);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static ssize_t hex2bin(const char *hexstr, uint8_t *bytes)
|
||||
{
|
||||
size_t hexstrLen = strlen(hexstr);
|
||||
ssize_t bytesLen = hexstrLen / 2;
|
||||
|
||||
int count = 0;
|
||||
const char *pos = hexstr;
|
||||
|
||||
for(count = 0; count < bytesLen; count++) {
|
||||
sscanf(pos, "%2hhx", &bytes[count]);
|
||||
pos += 2;
|
||||
}
|
||||
|
||||
return bytesLen;
|
||||
}
|
||||
|
||||
static bool stopped(void)
|
||||
{
|
||||
uint32_t flag = 0;
|
||||
xTaskNotifyWait(0, 0, &flag, (TickType_t) 10/portTICK_RATE_MS);
|
||||
return (flag != 0);
|
||||
}
|
||||
|
||||
static void protocomm_console_task(void *arg)
|
||||
{
|
||||
int uart_num = (int) arg;
|
||||
uint8_t linebuf[256];
|
||||
int i, cmd_ret;
|
||||
esp_err_t ret;
|
||||
QueueHandle_t uart_queue;
|
||||
uart_event_t event;
|
||||
|
||||
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 = {
|
||||
.max_cmdline_args = 8,
|
||||
.max_cmdline_length = 256,
|
||||
};
|
||||
|
||||
esp_console_init(&console_config);
|
||||
esp_console_register_help_command();
|
||||
|
||||
while (!stopped()) {
|
||||
uart_write_bytes(uart_num, "\n>> ", 4);
|
||||
memset(linebuf, 0, sizeof(linebuf));
|
||||
i = 0;
|
||||
do {
|
||||
ret = xQueueReceive(uart_queue, (void * )&event, (TickType_t) 10/portTICK_RATE_MS);
|
||||
if (ret != pdPASS) {
|
||||
if (stopped()) {
|
||||
break;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (event.type == UART_DATA) {
|
||||
while (uart_read_bytes(uart_num, (uint8_t *) &linebuf[i], 1, 0)) {
|
||||
if (linebuf[i] == '\r') {
|
||||
uart_write_bytes(uart_num, "\r\n", 2);
|
||||
} else {
|
||||
uart_write_bytes(uart_num, (char *) &linebuf[i], 1);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
} while ((i < 255) && linebuf[i-1] != '\r');
|
||||
if (stopped()) {
|
||||
break;
|
||||
}
|
||||
ret = esp_console_run((char *) linebuf, &cmd_ret);
|
||||
if (ret < 0) {
|
||||
ESP_LOGE(TAG, "Console dispatcher error\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pc_console = NULL;
|
||||
esp_console_deinit();
|
||||
|
||||
ESP_LOGI(TAG, "Console stopped");
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static int common_cmd_handler(int argc, char** argv)
|
||||
{
|
||||
if (argc < 3) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
int i, ret;
|
||||
|
||||
uint32_t cur_session_id = atoi(argv[1]);
|
||||
|
||||
uint8_t *buf = (uint8_t *) malloc(strlen(argv[2]));
|
||||
uint8_t *outbuf;
|
||||
ssize_t outlen;
|
||||
ssize_t len = hex2bin(argv[2], buf);
|
||||
|
||||
if (cur_session_id != session_id) {
|
||||
if (pc_console->sec && pc_console->sec->new_transport_session) {
|
||||
ret = pc_console->sec->new_transport_session(cur_session_id);
|
||||
if (ret == ESP_OK) {
|
||||
session_id = cur_session_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = protocomm_req_handle(pc_console, argv[0], cur_session_id, buf, len, &outbuf, &outlen);
|
||||
free(buf);
|
||||
|
||||
if (ret == ESP_OK) {
|
||||
printf("\r\n");
|
||||
for (i = 0; i < outlen; i++) {
|
||||
printf("%02x", outbuf[i]);
|
||||
}
|
||||
printf("\r\n");
|
||||
|
||||
/* Transport is responsible for freeing the transmit buffer */
|
||||
free(outbuf);
|
||||
|
||||
return ESP_OK;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t protocomm_console_add_endpoint(const char *ep_name, protocomm_req_handler_t req_handler, void *priv_data)
|
||||
{
|
||||
(void) req_handler;
|
||||
(void) priv_data;
|
||||
|
||||
esp_err_t ret;
|
||||
esp_console_cmd_t cmd;
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
cmd.command = ep_name;
|
||||
cmd.help = "";
|
||||
cmd.func = common_cmd_handler;
|
||||
|
||||
ret = esp_console_cmd_register(&cmd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t protocomm_console_remove_endpoint(const char *ep_name)
|
||||
{
|
||||
/* Command deletion happens internally in esp_console_deinit function */
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t protocomm_console_start(protocomm_t *pc, const protocomm_console_config_t *config)
|
||||
{
|
||||
if (pc == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (pc_console != NULL) {
|
||||
if (pc_console == pc) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
else {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (xTaskCreate(protocomm_console_task, "protocomm_console",
|
||||
config->stack_size, NULL, config->task_priority, &console_task) != pdPASS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
pc->add_endpoint = protocomm_console_add_endpoint;
|
||||
pc->remove_endpoint = protocomm_console_remove_endpoint;
|
||||
pc_console = pc;
|
||||
return ESP_OK;
|
||||
}
|
262
components/protocomm/src/transports/protocomm_httpd.c
Normal file
262
components/protocomm/src/transports/protocomm_httpd.c
Normal file
@ -0,0 +1,262 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_err.h>
|
||||
|
||||
#include <esp_http_server.h>
|
||||
|
||||
#include <protocomm.h>
|
||||
#include <protocomm_httpd.h>
|
||||
|
||||
#include "protocomm_priv.h"
|
||||
|
||||
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
|
||||
|
||||
static esp_err_t common_post_handler(httpd_req_t *req)
|
||||
{
|
||||
esp_err_t ret;
|
||||
uint8_t *outbuf = NULL;
|
||||
char *req_body = NULL;
|
||||
const char *ep_name = NULL;
|
||||
ssize_t outlen;
|
||||
|
||||
int cur_session_id = httpd_req_to_sockfd(req);
|
||||
|
||||
if (cur_session_id != session_id) {
|
||||
/* Initialize new security session */
|
||||
if (session_id != PROTOCOMM_NO_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) {
|
||||
ret = pc_httpd->sec->close_transport_session(session_id);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to close session with ID: %d", session_id);
|
||||
ret = ESP_FAIL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
session_id = PROTOCOMM_NO_SESSION_ID;
|
||||
}
|
||||
if (pc_httpd->sec && pc_httpd->sec->new_transport_session) {
|
||||
ret = pc_httpd->sec->new_transport_session(cur_session_id);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to launch new session with ID: %d", cur_session_id);
|
||||
ret = ESP_FAIL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
session_id = cur_session_id;
|
||||
ESP_LOGD(TAG, "New session with ID: %d", cur_session_id);
|
||||
}
|
||||
|
||||
if (req->content_len <= 0) {
|
||||
ESP_LOGE(TAG, "Content length not found");
|
||||
ret = ESP_FAIL;
|
||||
goto out;
|
||||
} else if (req->content_len > MAX_REQ_BODY_LEN) {
|
||||
ESP_LOGE(TAG, "Request content length should be less than 4kb");
|
||||
ret = ESP_FAIL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
req_body = (char *) malloc(req->content_len);
|
||||
if (!req_body) {
|
||||
ESP_LOGE(TAG, "Unable to allocate for request length %d", req->content_len);
|
||||
ret = ESP_ERR_NO_MEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
size_t recv_size = 0;
|
||||
while (recv_size < req->content_len) {
|
||||
ret = httpd_req_recv(req, req_body + recv_size, req->content_len - recv_size);
|
||||
if (ret < 0) {
|
||||
ret = ESP_FAIL;
|
||||
goto out;
|
||||
}
|
||||
recv_size += ret;
|
||||
}
|
||||
|
||||
/* Extract the endpoint name from URI string of type "/ep_name" */
|
||||
ep_name = req->uri + 1;
|
||||
|
||||
ret = protocomm_req_handle(pc_httpd, ep_name, session_id,
|
||||
(uint8_t *)req_body, recv_size, &outbuf, &outlen);
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Data handler failed");
|
||||
ret = ESP_FAIL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = httpd_resp_send(req, (char *)outbuf, outlen);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "HTTP send failed");
|
||||
ret = ESP_FAIL;
|
||||
goto out;
|
||||
}
|
||||
ret = ESP_OK;
|
||||
out:
|
||||
if (req_body) {
|
||||
free(req_body);
|
||||
}
|
||||
if (outbuf) {
|
||||
free(outbuf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t protocomm_httpd_add_endpoint(const char *ep_name,
|
||||
protocomm_req_handler_t req_handler,
|
||||
void *priv_data)
|
||||
{
|
||||
if (pc_httpd == NULL) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
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);
|
||||
if (!ep_uri) {
|
||||
ESP_LOGE(TAG, "Malloc failed for ep uri");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
/* Create URI handler structure */
|
||||
sprintf(ep_uri, "/%s", ep_name);
|
||||
httpd_uri_t config_handler = {
|
||||
.uri = ep_uri,
|
||||
.method = HTTP_POST,
|
||||
.handler = common_post_handler,
|
||||
.user_ctx = NULL
|
||||
};
|
||||
|
||||
/* Register URI handler */
|
||||
esp_err_t err;
|
||||
httpd_handle_t *server = (httpd_handle_t *) pc_httpd->priv;
|
||||
if ((err = httpd_register_uri_handler(*server, &config_handler)) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Uri handler register failed: %s", esp_err_to_name(err));
|
||||
free(ep_uri);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
free(ep_uri);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t protocomm_httpd_remove_endpoint(const char *ep_name)
|
||||
{
|
||||
if (pc_httpd == NULL) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
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);
|
||||
if (!ep_uri) {
|
||||
ESP_LOGE(TAG, "Malloc failed for ep uri");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
sprintf(ep_uri, "/%s", ep_name);
|
||||
|
||||
/* Unregister URI handler */
|
||||
esp_err_t err;
|
||||
httpd_handle_t *server = (httpd_handle_t *) pc_httpd->priv;
|
||||
if ((err = httpd_unregister_uri_handler(*server, ep_uri, HTTP_POST)) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Uri handler de-register failed: %s", esp_err_to_name(err));
|
||||
free(ep_uri);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
free(ep_uri);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t protocomm_httpd_start(protocomm_t *pc, const protocomm_httpd_config_t *config)
|
||||
{
|
||||
if (!pc || !config) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (pc_httpd) {
|
||||
if (pc == pc_httpd) {
|
||||
ESP_LOGE(TAG, "HTTP server already running for this protocomm instance");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
ESP_LOGE(TAG, "HTTP server started for another protocomm instance");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
pc->add_endpoint = protocomm_httpd_add_endpoint;
|
||||
pc->remove_endpoint = protocomm_httpd_remove_endpoint;
|
||||
pc_httpd = pc;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t protocomm_httpd_stop(protocomm_t *pc)
|
||||
{
|
||||
if ((pc != NULL) && (pc == pc_httpd)) {
|
||||
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;
|
||||
}
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
7
components/protocomm/test/CMakeLists.txt
Normal file
7
components/protocomm/test/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
set(COMPONENT_SRCDIRS ".")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ".")
|
||||
set(COMPONENT_PRIV_INCLUDEDIRS "../proto-c/")
|
||||
|
||||
set(COMPONENT_REQUIRES unity mbedtls protocomm protobuf-c)
|
||||
|
||||
register_component()
|
2
components/protocomm/test/component.mk
Normal file
2
components/protocomm/test/component.mk
Normal file
@ -0,0 +1,2 @@
|
||||
COMPONENT_PRIV_INCLUDEDIRS := ../proto-c/
|
||||
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive
|
1134
components/protocomm/test/test_protocomm.c
Normal file
1134
components/protocomm/test/test_protocomm.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user