Files

424 lines
18 KiB
C

/*================================================================
Copyright (c) 2021, Quectel Wireless Solutions Co., Ltd. All rights reserved.
Quectel Wireless Solutions Proprietary and Confidential.
=================================================================*/
#ifndef MBEDTLS_LIB_H
#define MBEDTLS_LIB_H
#include "mbedtls/net_sockets.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/debug.h"
#include "mbedtls/entropy.h"
#include "mbedtls/pk.h"
#include "mbedtls/ssl.h"
#include "mbedtls/x509_crt.h"
#include "mbedtls/sha1.h"
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include "md.h"
void mbedtls_net_free( mbedtls_net_context *ctx );
void mbedtls_x509_crt_free( mbedtls_x509_crt *crt );
void mbedtls_pk_free( mbedtls_pk_context *ctx );
void mbedtls_ssl_free( mbedtls_ssl_context *ssl );
void mbedtls_ssl_config_free( mbedtls_ssl_config *conf );
void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx );
void mbedtls_entropy_free( mbedtls_entropy_context *ctx );
void mbedtls_net_init( mbedtls_net_context *ctx );
void mbedtls_ssl_init( mbedtls_ssl_context *ssl );
void mbedtls_ssl_config_init( mbedtls_ssl_config *conf );
void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
void mbedtls_x509_crt_init( mbedtls_x509_crt *crt );
void mbedtls_pk_init( mbedtls_pk_context *ctx );
void mbedtls_entropy_init( mbedtls_entropy_context *ctx );
void mbedtls_debug_set_threshold( int threshold );
void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
void (*f_dbg)(void *, int, const char *, int, const char *),
void *p_dbg );
int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
int (*f_entropy)(void *, unsigned char *, size_t),
void *p_entropy,
const unsigned char *custom,
size_t len );
int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain,
const unsigned char *buf,
size_t buflen );
int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path );
int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
const char *path, const char *pwd );
int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
const unsigned char *psk, size_t psk_len,
const unsigned char *psk_identity, size_t psk_identity_len );
int mbedtls_net_connect( mbedtls_net_context *ctx,
#if defined (MBEDTLS_WITH_ASR)
int cid,
#endif
const char *host,
const char *port, int proto );
int mbedtls_net_bind( mbedtls_net_context *ctx,
#if defined (MBEDTLS_WITH_ASR)
int cid,
#endif
const char *bind_ip,
const char *port, int proto );
int mbedtls_net_set_block( mbedtls_net_context *ctx );
int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
int endpoint, int transport, int preset );
void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy );
void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode );
void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
mbedtls_x509_crt *ca_chain,
mbedtls_x509_crl *ca_crl );
int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf,
mbedtls_x509_crt *own_cert,
mbedtls_pk_context *pk_key );
void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout );
int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
const mbedtls_ssl_config *conf );
void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf,
const int *ciphersuites );
int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname );
void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
void *p_bio,
mbedtls_ssl_send_t *f_send,
mbedtls_ssl_recv_t *f_recv,
mbedtls_ssl_recv_timeout_t *f_recv_timeout );
int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl );
uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl );
int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl );
int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len );
int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len );
void mbedtls_ssl_conf_cert_time_vality_check( mbedtls_ssl_config *conf, int disable_chk);
int mbedtls_entropy_func( void *data, unsigned char *output, size_t len );
int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output,
size_t output_len );
int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf,
size_t len, uint32_t timeout );
int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len );
int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len );
int mbedtls_md_starts( mbedtls_md_context_t *ctx );
int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen );
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output );
#ifdef QUEC_MEBEDTLS_OPEN
#define _IN_ /* indicate an input parameter */
#define _OU_ /* indicate a output parameter */
/* log print/upload related variables */
/* MAX size of log buffer for one log item including header and content */
#define MAX_LOG_MSG_LEN (511)
#define TIME_FORMAT_STR_LEN (20)
#include <time.h>
#include "utlTime.h"
#ifdef timerclear
#undef timerclear
#endif
#ifdef timerisset
#undef timerisset
#endif
#ifdef timercmp
#undef timercmp
#endif
#ifdef timeradd
#undef timeradd
#endif
#ifdef timersub
#undef timersub
#endif
#define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
#define timercmp(tvp, uvp, cmp) \
(((tvp)->tv_sec == (uvp)->tv_sec) ? \
((tvp)->tv_usec cmp (uvp)->tv_usec) : \
((tvp)->tv_sec cmp (uvp)->tv_sec))
#define timeradd(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
if ((vvp)->tv_usec >= 1000000) { \
(vvp)->tv_sec++; \
(vvp)->tv_usec -= 1000000; \
} \
} while (0)
#define timersub(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
if ((vvp)->tv_usec < 0) { \
(vvp)->tv_sec--; \
(vvp)->tv_usec += 1000000; \
} \
} while (0)
/**************** QCloud IoT C-SDK constants begin ************************/
/* MAX size of client ID */
#define MAX_SIZE_OF_CLIENT_ID (80)
/* MAX size of product ID */
#define MAX_SIZE_OF_PRODUCT_ID (10)
/* MAX size of product secret */
#define MAX_SIZE_OF_PRODUCT_SECRET (32)
/* MAX size of device name */
#define MAX_SIZE_OF_DEVICE_NAME (48)
/* MAX size of device secret */
#define MAX_SIZE_OF_DEVICE_SECRET (64)
/* MAX size of device cert file name */
#define MAX_SIZE_OF_DEVICE_CERT_FILE_NAME (128)
/* MAX size of device key file name */
#define MAX_SIZE_OF_DEVICE_SECRET_FILE_NAME (128)
/* MAX size of region len */
#define MAX_SIZE_OF_REGION (64)
/* MAX num of subdevice */
#define MAX_NUM_SUB_DEV (1)
typedef enum {
QCLOUD_RET_MQTT_ALREADY_CONNECTED = 4, // Already connected with MQTT server
QCLOUD_RET_MQTT_CONNACK_CONNECTION_ACCEPTED = 3, // MQTT connection accepted by server
QCLOUD_RET_MQTT_MANUALLY_DISCONNECTED = 2, // Manually disconnected with MQTT server
QCLOUD_RET_MQTT_RECONNECTED = 1, // Reconnected with MQTT server successfully
QCLOUD_RET_SUCCESS = 0, // Successful return
QCLOUD_ERR_FAILURE = -1001, // Generic failure return
QCLOUD_ERR_INVAL = -1002, // Invalid parameter
QCLOUD_ERR_DEV_INFO = -1003, // Fail to get device info
QCLOUD_ERR_MALLOC = -1004, // Fail to malloc memory
QCLOUD_ERR_HTTP_CLOSED = -3, // HTTP server close the connection
QCLOUD_ERR_HTTP = -4, // HTTP unknown error
QCLOUD_ERR_HTTP_PRTCL = -5, // HTTP protocol error
QCLOUD_ERR_HTTP_UNRESOLVED_DNS = -6, // HTTP DNS resolve failed
QCLOUD_ERR_HTTP_PARSE = -7, // HTTP URL parse failed
QCLOUD_ERR_HTTP_CONN = -8, // HTTP connect failed
QCLOUD_ERR_HTTP_AUTH = -9, // HTTP auth failed
QCLOUD_ERR_HTTP_NOT_FOUND = -10, // HTTP 404
QCLOUD_ERR_HTTP_TIMEOUT = -11, // HTTP timeout
QCLOUD_ERR_MQTT_PUSH_TO_LIST_FAILED = -102, // Fail to push node to MQTT waiting list
QCLOUD_ERR_MQTT_NO_CONN = -103, // Not connected with MQTT server
QCLOUD_ERR_MQTT_UNKNOWN = -104, // MQTT unknown error
QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT = -105, // Reconnecting with MQTT server
QCLOUD_ERR_MQTT_RECONNECT_TIMEOUT = -106, // MQTT reconnect timeout
QCLOUD_ERR_MQTT_MAX_SUBSCRIPTIONS = -107, // MQTT topic subscription out of range
QCLOUD_ERR_MQTT_SUB = -108, // MQTT topic subscription fail
QCLOUD_ERR_MQTT_NOTHING_TO_READ = -109, // MQTT nothing to read
QCLOUD_ERR_MQTT_PACKET_READ = -110, // Something wrong when reading MQTT packet
QCLOUD_ERR_MQTT_REQUEST_TIMEOUT = -111, // MQTT request timeout
QCLOUD_ERR_MQTT_CONNACK_UNKNOWN = -112, // MQTT connection refused: unknown error
QCLOUD_ERR_MQTT_CONNACK_UNACCEPTABLE_PROTOCOL_VERSION = -113, // MQTT connection refused: protocol version invalid
QCLOUD_ERR_MQTT_CONNACK_IDENTIFIER_REJECTED = -114, // MQTT connection refused: identifier rejected
QCLOUD_ERR_MQTT_CONNACK_SERVER_UNAVAILABLE = -115, // MQTT connection refused: service not available
QCLOUD_ERR_MQTT_CONNACK_BAD_USERDATA = -116, // MQTT connection refused: bad user name or password
QCLOUD_ERR_MQTT_CONNACK_NOT_AUTHORIZED = -117, // MQTT connection refused: not authorized
QCLOUD_ERR_RX_MESSAGE_INVAL = -118, // MQTT received invalid msg
QCLOUD_ERR_BUF_TOO_SHORT = -119, // MQTT recv buffer not enough
QCLOUD_ERR_MQTT_QOS_NOT_SUPPORT = -120, // MQTT QoS level not supported
QCLOUD_ERR_MQTT_UNSUB_FAIL = -121, // MQTT unsubscribe failed
QCLOUD_ERR_JSON_PARSE = -132, // JSON parsing error
QCLOUD_ERR_JSON_BUFFER_TRUNCATED = -133, // JSON buffer truncated
QCLOUD_ERR_JSON_BUFFER_TOO_SMALL = -134, // JSON parsing buffer not enough
QCLOUD_ERR_JSON = -135, // JSON generation error
QCLOUD_ERR_MAX_JSON_TOKEN = -136, // JSON token out of range
QCLOUD_ERR_MAX_APPENDING_REQUEST = -137, // appending request out of range
QCLOUD_ERR_MAX_TOPIC_LENGTH = -138, // Topic length oversize
QCLOUD_ERR_COAP_NULL = -150, // COAP null pointer
QCLOUD_ERR_COAP_DATA_SIZE = -151, // COAP data size out of range
QCLOUD_ERR_COAP_INTERNAL = -152, // COAP interval error
QCLOUD_ERR_COAP_BADMSG = -153, // COAP bad msg
QCLOUD_ERR_DTLS_PEER_CLOSE_NOTIFY = -160, // DTLS connection is closed
QCLOUD_ERR_PROPERTY_EXIST = -201, // property already exist
QCLOUD_ERR_NOT_PROPERTY_EXIST = -202, // property not exist
QCLOUD_ERR_REPORT_TIMEOUT = -203, // update timeout
QCLOUD_ERR_REPORT_REJECTED = -204, // update rejected by server
QCLOUD_ERR_GET_TIMEOUT = -205, // get timeout
QCLOUD_ERR_GET_REJECTED = -206, // get rejected by server
QCLOUD_ERR_ACTION_EXIST = -210, // acion already exist
QCLOUD_ERR_NOT_ACTION_EXIST = -211, // acion not exist
QCLOUD_ERR_GATEWAY_CREATE_SESSION_FAIL = -221, // Gateway fail to create sub-device session
QCLOUD_ERR_GATEWAY_SESSION_NO_EXIST = -222, // Gateway sub-device session not exist
QCLOUD_ERR_GATEWAY_SESSION_TIMEOUT = -223, // Gateway sub-device session timeout
QCLOUD_ERR_GATEWAY_SUBDEV_ONLINE = -224, // Gateway sub-device online
QCLOUD_ERR_GATEWAY_SUBDEV_OFFLINE = -225, // Gateway sub-device offline
QCLOUD_ERR_TCP_SOCKET_FAILED = -601, // TLS TCP socket connect fail
QCLOUD_ERR_TCP_UNKNOWN_HOST = -602, // TCP unknown host (DNS fail)
QCLOUD_ERR_TCP_CONNECT = -603, // TCP/UDP socket connect fail
QCLOUD_ERR_TCP_READ_TIMEOUT = -604, // TCP read timeout
QCLOUD_ERR_TCP_WRITE_TIMEOUT = -605, // TCP write timeout
QCLOUD_ERR_TCP_READ_FAIL = -606, // TCP read error
QCLOUD_ERR_TCP_WRITE_FAIL = -607, // TCP write error
QCLOUD_ERR_TCP_PEER_SHUTDOWN = -608, // TCP server close connection
QCLOUD_ERR_TCP_NOTHING_TO_READ = -609, // TCP socket nothing to read
QCLOUD_ERR_SSL_INIT = -701, // TLS/SSL init fail
QCLOUD_ERR_SSL_CERT = -702, // TLS/SSL certificate issue
QCLOUD_ERR_SSL_CONNECT = -703, // TLS/SSL connect fail
QCLOUD_ERR_SSL_CONNECT_TIMEOUT = -704, // TLS/SSL connect timeout
QCLOUD_ERR_SSL_WRITE_TIMEOUT = -705, // TLS/SSL write timeout
QCLOUD_ERR_SSL_WRITE = -706, // TLS/SSL write error
QCLOUD_ERR_SSL_READ_TIMEOUT = -707, // TLS/SSL read timeout
QCLOUD_ERR_SSL_READ = -708, // TLS/SSL read error
QCLOUD_ERR_SSL_NOTHING_TO_READ = -709, // TLS/SSL nothing to read
QCLOUD_ERR_BIND_PARA_ERR = -801, // bind sub device param error
QCLOUD_ERR_BIND_SUBDEV_ERR = -802, // sub device not exist or illegal
QCLOUD_ERR_BIND_SIGN_ERR = -803, // signature check err
QCLOUD_ERR_BIND_SIGN_METHOD_RRR = -804, // signmethod not supporte
QCLOUD_ERR_BIND_SIGN_EXPIRED = -805, // signature expired
QCLOUD_ERR_BIND_BEEN_BINDED = -806, // sub device has been binded by other gateway
QCLOUD_ERR_BIND_SUBDEV_FORBID = -807, // sub device not allow to bind
QCLOUD_ERR_BIND_OP_FORBID = -808, // operation not permit
QCLOUD_ERR_BIND_REPEATED_REQ = -809, // repeated bind request,has been binded
} IoT_Return_Code;
typedef struct {
unsigned char profile_idx;
const char *ca_crt;
uint16_t ca_crt_len;
#ifdef AUTH_MODE_CERT
// Device with certificate
const char *cert_file; // public certificate file
const char *key_file; // pravite certificate file
#else
// Device with PSK
const char *psk; // PSK string
char psk_id[MAX_SIZE_OF_CLIENT_ID + 1]; // PSK ID
#endif
size_t psk_length; // PSK length
unsigned int timeout_ms; // SSL handshake timeout in millisecond
}SSLConnectParams;
typedef SSLConnectParams TLSConnectParams;
typedef bool (*LogMessageHandler)(const char *message);
typedef enum { eLOG_DISABLE = 0, eLOG_ERROR = 1, eLOG_WARN = 2, eLOG_INFO = 3, eLOG_DEBUG = 4 } LOG_LEVEL;
struct Timer {
struct timeval end_time;
};
typedef struct Timer Timer;
/**
* @brief Check if a timer is expired
*
* Call this function passing in a timer to check if that timer has expired.
*
* @param timer - pointer to the timer to be checked for expiration
* @return bool - true = timer expired, false = timer not expired
*/
bool expired(Timer *timer);
/**
* @brief Create a timer (milliseconds)
*
* Sets the timer to expire in a specified number of milliseconds.
*
* @param timer - pointer to the timer to be set to expire in milliseconds
* @param timeout_ms - set the timer to expire in this number of milliseconds
*/
void countdown_ms(Timer *timer, unsigned int timeout_ms);
/**
* @brief Create a timer (seconds)
*
* Sets the timer to expire in a specified number of seconds.
*
* @param timer - pointer to the timer to be set to expire in seconds
* @param timeout - set the timer to expire in this number of seconds
*/
void countdown(Timer *timer, unsigned int timeout);
/**
* @brief Check the time remaining on a give timer
*
* Checks the input timer and returns the number of milliseconds remaining on
* the timer.
*
* @param timer - pointer to the timer to be set to checked
* @return int - milliseconds left on the countdown timer
*/
int left_ms(Timer *timer);
/**
* @brief Initialize a timer
*
* Performs any initialization required to the timer passed in.
*
* @param timer - pointer to the timer to be initialized
*/
void InitTimer(Timer *timer);
/**
* @brief Malloc memory
*
* @param size Expected memory size (unit: byte)
* @return pointer to the memory
*/
void *HAL_Malloc(_IN_ uint32_t size);
/**
* @brief Free memory
*
* @param ptr pointer to the pre-malloc memory
*/
void HAL_Free(_IN_ void *ptr);
void IOT_Log_Gen(const char *file, const char *func, const int line, const int level, const char *fmt, ...);
/* Simple APIs for log generation in different level */
#define Log_d(fmt, ...) IOT_Log_Gen(__FILE__, __FUNCTION__, __LINE__, eLOG_DEBUG, fmt, ##__VA_ARGS__)
#define Log_i(fmt, ...) IOT_Log_Gen(__FILE__, __FUNCTION__, __LINE__, eLOG_INFO, fmt, ##__VA_ARGS__)
#define Log_w(fmt, ...) IOT_Log_Gen(__FILE__, __FUNCTION__, __LINE__, eLOG_WARN, fmt, ##__VA_ARGS__)
#define Log_e(fmt, ...) IOT_Log_Gen(__FILE__, __FUNCTION__, __LINE__, eLOG_ERROR, fmt, ##__VA_ARGS__)
#endif
#endif