diff --git a/AVRIoT.X/Makefile b/AVRIoT.X/Makefile new file mode 100644 index 0000000..fca8e2c --- /dev/null +++ b/AVRIoT.X/Makefile @@ -0,0 +1,113 @@ +# +# There exist several targets which are by default empty and which can be +# used for execution of your targets. These targets are usually executed +# before and after some main targets. They are: +# +# .build-pre: called before 'build' target +# .build-post: called after 'build' target +# .clean-pre: called before 'clean' target +# .clean-post: called after 'clean' target +# .clobber-pre: called before 'clobber' target +# .clobber-post: called after 'clobber' target +# .all-pre: called before 'all' target +# .all-post: called after 'all' target +# .help-pre: called before 'help' target +# .help-post: called after 'help' target +# +# Targets beginning with '.' are not intended to be called on their own. +# +# Main targets can be executed directly, and they are: +# +# build build a specific configuration +# clean remove built files from a configuration +# clobber remove all built files +# all build all configurations +# help print help mesage +# +# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and +# .help-impl are implemented in nbproject/makefile-impl.mk. +# +# Available make variables: +# +# CND_BASEDIR base directory for relative paths +# CND_DISTDIR default top distribution directory (build artifacts) +# CND_BUILDDIR default top build directory (object files, ...) +# CONF name of current configuration +# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) +# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) +# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) +# CND_PACKAGE_DIR_${CONF} directory of package (current configuration) +# CND_PACKAGE_NAME_${CONF} name of package (current configuration) +# CND_PACKAGE_PATH_${CONF} path to package (current configuration) +# +# NOCDDL + + +# Environment +MKDIR=mkdir +CP=cp +CCADMIN=CCadmin +RANLIB=ranlib + + +# build +build: .build-post + +.build-pre: +# Add your pre 'build' code here... + +.build-post: .build-impl +# Add your post 'build' code here... + + +# clean +clean: .clean-post + +.clean-pre: +# Add your pre 'clean' code here... +# WARNING: the IDE does not call this target since it takes a long time to +# simply run make. Instead, the IDE removes the configuration directories +# under build and dist directly without calling make. +# This target is left here so people can do a clean when running a clean +# outside the IDE. + +.clean-post: .clean-impl +# Add your post 'clean' code here... + + +# clobber +clobber: .clobber-post + +.clobber-pre: +# Add your pre 'clobber' code here... + +.clobber-post: .clobber-impl +# Add your post 'clobber' code here... + + +# all +all: .all-post + +.all-pre: +# Add your pre 'all' code here... + +.all-post: .all-impl +# Add your post 'all' code here... + + +# help +help: .help-post + +.help-pre: +# Add your pre 'help' code here... + +.help-post: .help-impl +# Add your post 'help' code here... + + + +# include project implementation makefile +include nbproject/Makefile-impl.mk + +# include project make variables +include nbproject/Makefile-variables.mk diff --git a/AVRIoT.X/main.c b/AVRIoT.X/main.c new file mode 100644 index 0000000..7b9d198 --- /dev/null +++ b/AVRIoT.X/main.c @@ -0,0 +1,36 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include "mcc_generated_files/application_manager.h" + +int main(void) +{ + application_init(); + + while (1) + { + runScheduler(); + } + + return 0; +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_example.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_example.c new file mode 100644 index 0000000..ea1a448 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_example.c @@ -0,0 +1,83 @@ +/* + + * \file + * \brief CryptoAuthLib Basic API methods - a simple crypto authentication API. + * These methods manage a global ATCADevice object behind the scenes. They also + * manage the wake/idle state transitions so callers don't need to. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. +*/ + +#include "CryptoAuth_example.h" +#include +#include +#include + + +void CryptoAuth_Example(void){ + + uint8_t random_number[32]; + uint8_t serial_number[9]; + int i = 0; + int j = 0; + int loop = 10; + + while(loop--) + { + atcab_read_serial_number(serial_number); + + printf("Serial Number: \r\n"); + + while (i < 9) { + printf("%02X ", serial_number[i]); + i++; + } + printf("\r\n"); + printf("\r\n"); + + i = 0; + + atcab_random(random_number); + + printf("Generated 32-byte Random Number: \r\n"); + + while (i < 32) { + while (j < 4) { + printf("0x%02X ", random_number[i]); + j++; + i++; + } + printf("\r\n"); + j = 0; + } + printf("\r\n"); + i = 0; + j = 0; + + } + + + printf("\r\n"); + +} + diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_example.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_example.h new file mode 100644 index 0000000..336fdf1 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_example.h @@ -0,0 +1,34 @@ +/* + + * \file + * \brief CryptoAuthLib Basic API methods - a simple crypto authentication API. + * These methods manage a global ATCADevice object behind the scenes. They also + * manage the wake/idle state transitions so callers don't need to. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. +*/ + +#include "../cryptoauthlib_config.h" +#include "../CryptoAuthenticationLibrary/cryptoauthlib.h" + +void CryptoAuth_Example(void); diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.c new file mode 100644 index 0000000..712c2c1 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.c @@ -0,0 +1,63 @@ +/* + + * \file + * \brief CryptoAuthLib Basic API methods - a simple crypto authentication API. + * These methods manage a global ATCADevice object behind the scenes. They also + * manage the wake/idle state transitions so callers don't need to. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. +*/ + +#include +#include "CryptoAuth_init.h" + +struct atca_command _gmyCommand; +struct atca_iface _gmyIface; +struct atca_device _gMyDevice = {&_gmyCommand, &_gmyIface}; + +ATCAIfaceCfg secureCfg = { + .iface_type = ATCA_I2C_IFACE, + .devtype = ATECC608A, + .atcai2c.slave_address = 0xB0, + .atcai2c.bus = 2, + .atcai2c.baud = 100000, + .wake_delay = 1560, + .rx_retries = 20 +}; + + +bool CryptoAuth_Initialize(void) +{ + uint8_t calInitialzeStatus; + calInitialzeStatus = atcab_init(&secureCfg); + if (calInitialzeStatus != ATCA_SUCCESS) + { + return false; + } + else + { + atcab_lock_data_slot(0); + return true; + } +} + diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.h new file mode 100644 index 0000000..e615d34 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.h @@ -0,0 +1,35 @@ +/* + + * \file + * \brief CryptoAuthLib Basic API methods - a simple crypto authentication API. + * These methods manage a global ATCADevice object behind the scenes. They also + * manage the wake/idle state transitions so callers don't need to. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. +*/ + +#include +#include "cryptoauthlib_config.h" +#include "CryptoAuthenticationLibrary/cryptoauthlib.h" + +bool CryptoAuth_Initialize(void); diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/MicrochipDisclaimer b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/MicrochipDisclaimer new file mode 100644 index 0000000..ac75260 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/MicrochipDisclaimer @@ -0,0 +1,27 @@ + + * \file + * \brief CryptoAuthLib Basic API methods - a simple crypto authentication API. + * These methods manage a global ATCADevice object behind the scenes. They also + * manage the wake/idle state transitions so callers don't need to. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_bool.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_bool.h new file mode 100644 index 0000000..47d800d --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_bool.h @@ -0,0 +1,43 @@ +/** + * \file + * + * \brief bool define for systems that don't have it + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef _ATCA_BOOL_H +#define _ATCA_BOOL_H + +#if defined(_MSC_VER) && (_MSC_VER <= 1700) +// VS2012 and earlier don't support stdbool.h + #ifndef __cplusplus + #define bool unsigned char + #define false 0 + #define true 1 + #endif +#else + #include +#endif + +#endif \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.c new file mode 100644 index 0000000..3002e2a --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.c @@ -0,0 +1,126 @@ +/** + * \file + * \brief a set of default configurations for various ATCA devices and interfaces + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include +#include "atca_cfgs.h" +#include "atca_iface.h" +#include "atca_device.h" + +/** \defgroup config Configuration (cfg_) + * \brief Logical device configurations describe the CryptoAuth device type and logical interface. + @{ */ + +/* if the number of these configurations grows large, we can #ifdef them based on required device support */ + +/** \brief default configuration for an ECCx08A device */ +ATCAIfaceCfg cfg_ateccx08a_i2c_default = { + .iface_type = ATCA_I2C_IFACE, + .devtype = ATECC508A, + .atcai2c.slave_address = 0xC0, + .atcai2c.bus = 2, + .atcai2c.baud = 400000, + //.atcai2c.baud = 100000, + .wake_delay = 1500, + .rx_retries = 20 +}; + +/** \brief default configuration for an ECCx08A device on the logical SWI bus over UART*/ +ATCAIfaceCfg cfg_ateccx08a_swi_default = { + .iface_type = ATCA_SWI_IFACE, + .devtype = ATECC508A, + .atcaswi.bus = 4, + .wake_delay = 1500, + .rx_retries = 10 +}; + +/** \brief default configuration for Kit protocol over the device's async interface */ +ATCAIfaceCfg cfg_ateccx08a_kitcdc_default = { + .iface_type = ATCA_UART_IFACE, + .devtype = ATECC508A, + .atcauart.port = 0, + .atcauart.baud = 115200, + .atcauart.wordsize = 8, + .atcauart.parity = 2, + .atcauart.stopbits = 1, + .rx_retries = 1, +}; + +/** \brief default configuration for Kit protocol over the device's async interface */ +ATCAIfaceCfg cfg_ateccx08a_kithid_default = { + .iface_type = ATCA_HID_IFACE, + .devtype = ATECC508A, + .atcahid.idx = 0, + .atcahid.vid = 0x03EB, + .atcahid.pid = 0x2312, + .atcahid.packetsize = 64, + .atcahid.guid = { 0x4d, 0x1e, 0x55, 0xb2, 0xf1, 0x6f, 0x11, 0xcf, 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 }, +}; + +/** \brief default configuration for a SHA204A device on the first logical I2C bus */ +ATCAIfaceCfg cfg_atsha204a_i2c_default = { + .iface_type = ATCA_I2C_IFACE, + .devtype = ATSHA204A, + .atcai2c.slave_address = 0xC8, + .atcai2c.bus = 2, + .atcai2c.baud = 400000, + .wake_delay = 2560, + .rx_retries = 20 +}; + +/** \brief default configuration for an SHA204A device on the logical SWI bus over UART*/ +ATCAIfaceCfg cfg_atsha204a_swi_default = { + .iface_type = ATCA_SWI_IFACE, + .devtype = ATSHA204A, + .atcaswi.bus = 4, + .wake_delay = 2560, + .rx_retries = 10 +}; + +/** \brief default configuration for Kit protocol over the device's async interface */ +ATCAIfaceCfg cfg_atsha204a_kitcdc_default = { + .iface_type = ATCA_UART_IFACE, + .devtype = ATSHA204A, + .atcauart.port = 0, + .atcauart.baud = 115200, + .atcauart.wordsize = 8, + .atcauart.parity = 2, + .atcauart.stopbits = 1, + .rx_retries = 1, +}; + +/** \brief default configuration for Kit protocol over the device's async interface */ +ATCAIfaceCfg cfg_atsha204a_kithid_default = { + .iface_type = ATCA_HID_IFACE, + .devtype = ATSHA204A, + .atcahid.idx = 0, + .atcahid.vid = 0x03EB, + .atcahid.pid = 0x2312, + .atcahid.packetsize = 64, + .atcahid.guid = { 0x4d, 0x1e, 0x55, 0xb2, 0xf1, 0x6f, 0x11, 0xcf, 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 }, +}; + +/** @} */ diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.h new file mode 100644 index 0000000..49d5167 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.h @@ -0,0 +1,67 @@ +/** + * \file + * \brief a set of default configurations for various ATCA devices and interfaces + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +#ifndef ATCA_CFGS_H_ +#define ATCA_CFGS_H_ + +#include "atca_iface.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \brief default configuration for an ECCx08A device on the first logical I2C bus */ +extern ATCAIfaceCfg cfg_ateccx08a_i2c_default; + +/** \brief default configuration for an ECCx08A device on the logical SWI bus over UART*/ +extern ATCAIfaceCfg cfg_ateccx08a_swi_default; + +/** \brief default configuration for Kit protocol over a CDC interface */ +extern ATCAIfaceCfg cfg_ateccx08a_kitcdc_default; + +/** \brief default configuration for Kit protocol over a HID interface */ +extern ATCAIfaceCfg cfg_ateccx08a_kithid_default; + + +/** \brief default configuration for a SHA204A device on the first logical I2C bus */ +extern ATCAIfaceCfg cfg_atsha204a_i2c_default; + +/** \brief default configuration for an SHA204A device on the logical SWI bus over UART*/ +extern ATCAIfaceCfg cfg_atsha204a_swi_default; + +/** \brief default configuration for Kit protocol over a CDC interface */ +extern ATCAIfaceCfg cfg_atsha204a_kitcdc_default; + +/** \brief default configuration for Kit protocol over a HID interface for SHA204 */ +extern ATCAIfaceCfg cfg_atsha204a_kithid_default; + +#ifdef __cplusplus +} +#endif +#endif /* ATCA_CFGS_H_ */ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.c new file mode 100644 index 0000000..036625a --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.c @@ -0,0 +1,765 @@ +/** + * \file + * \brief Microchip CryptoAuthentication device command builder - this is the main object that builds the command + * byte strings for the given device. It does not execute the command. The basic flow is to call + * a command method to build the command you want given the parameters and then send that byte string + * through the device interface. + * + * The primary goal of the command builder is to wrap the given parameters with the correct packet size and CRC. + * The caller should first fill in the parameters required in the ATCAPacket parameter given to the command. + * The command builder will deal with the mechanics of creating a valid packet using the parameter information. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include +#include +#include "atca_command.h" +#include "atca_devtypes.h" + +/** \brief ATCACommand CheckMAC method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS + */ +ATCA_STATUS atCheckMAC(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + packet->opcode = ATCA_CHECKMAC; + packet->txsize = CHECKMAC_COUNT; + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand Counter method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atCounter(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + packet->opcode = ATCA_COUNTER; + packet->txsize = COUNTER_COUNT; + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand DeriveKey method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \param[in] has_mac hasMAC determines if MAC data is present in the packet input + * \return ATCA_SUCCESS + */ +ATCA_STATUS atDeriveKey(ATCACommand ca_cmd, ATCAPacket *packet, bool has_mac) +{ + // Set the opcode & parameters + packet->opcode = ATCA_DERIVE_KEY; + + // hasMAC must be given since the packet does not have any implicit information to + // know if it has a mac or not unless the size is preset + if (has_mac) + { + packet->txsize = DERIVE_KEY_COUNT_LARGE; + } + else + { + packet->txsize = DERIVE_KEY_COUNT_SMALL; + } + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand ECDH method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS + */ +ATCA_STATUS atECDH(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + packet->opcode = ATCA_ECDH; + packet->txsize = ECDH_COUNT; + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand Generate Digest method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \param[in] is_no_mac_key Should be true if GenDig is being run on a slot that has its SlotConfig.NoMac bit set + * \return ATCA_SUCCESS + */ +ATCA_STATUS atGenDig(ATCACommand ca_cmd, ATCAPacket *packet, bool is_no_mac_key) +{ + // Set the opcode & parameters + packet->opcode = ATCA_GENDIG; + + if (packet->param1 == GENDIG_ZONE_SHARED_NONCE) // shared nonce mode + { + packet->txsize = GENDIG_COUNT + 32; + } + else if (is_no_mac_key) + { + packet->txsize = GENDIG_COUNT + 4; // noMac keys use 4 bytes of OtherData in calculation + } + else + { + packet->txsize = GENDIG_COUNT; + } + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand Generate Key method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS + */ +ATCA_STATUS atGenKey(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + packet->opcode = ATCA_GENKEY; + + if (packet->param1 & GENKEY_MODE_PUBKEY_DIGEST) + { + packet->txsize = GENKEY_COUNT_DATA; + } + else + { + packet->txsize = GENKEY_COUNT; + } + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand HMAC method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS + */ +ATCA_STATUS atHMAC(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + packet->opcode = ATCA_HMAC; + packet->txsize = HMAC_COUNT; + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand Info method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS + */ +ATCA_STATUS atInfo(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + packet->opcode = ATCA_INFO; + packet->txsize = INFO_COUNT; + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand Lock method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS + */ +ATCA_STATUS atLock(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + packet->opcode = ATCA_LOCK; + packet->txsize = LOCK_COUNT; + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand MAC method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS + */ +ATCA_STATUS atMAC(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + // variable packet size + packet->opcode = ATCA_MAC; + if (!(packet->param1 & MAC_MODE_BLOCK2_TEMPKEY)) + { + packet->txsize = MAC_COUNT_LONG; + } + else + { + packet->txsize = MAC_COUNT_SHORT; + } + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand Nonce method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atNonce(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + // variable packet size + uint8_t calc_mode = packet->param1 & NONCE_MODE_MASK; + + packet->opcode = ATCA_NONCE; + + if ((calc_mode == NONCE_MODE_SEED_UPDATE || calc_mode == NONCE_MODE_NO_SEED_UPDATE)) + { + // Calculated nonce mode, 20 byte NumInm + packet->txsize = NONCE_COUNT_SHORT; + } + else if (calc_mode == NONCE_MODE_PASSTHROUGH) + { + // PAss-through nonce mode + if ((packet->param1 & NONCE_MODE_INPUT_LEN_MASK) == NONCE_MODE_INPUT_LEN_64) + { + // 64 byte NumIn + packet->txsize = NONCE_COUNT_LONG_64; + } + else + { + // 32 byte NumIn + packet->txsize = NONCE_COUNT_LONG; + } + } + else + { + return ATCA_BAD_PARAM; + } + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand Pause method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS + */ +ATCA_STATUS atPause(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + packet->opcode = ATCA_PAUSE; + packet->txsize = PAUSE_COUNT; + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand PrivWrite method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS + */ +ATCA_STATUS atPrivWrite(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + packet->opcode = ATCA_PRIVWRITE; + packet->txsize = PRIVWRITE_COUNT; + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand Random method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS + */ +ATCA_STATUS atRandom(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + packet->opcode = ATCA_RANDOM; + packet->txsize = RANDOM_COUNT; + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand Read method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS + */ +ATCA_STATUS atRead(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + packet->opcode = ATCA_READ; + packet->txsize = READ_COUNT; + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand SecureBoot method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS + */ +ATCA_STATUS atSecureBoot(ATCACommand ca_cmd, ATCAPacket *packet) +{ + packet->opcode = ATCA_SECUREBOOT; + packet->txsize = ATCA_CMD_SIZE_MIN; + + //variable transmit size based on mode encoding + switch (packet->param1 & SECUREBOOT_MODE_MASK) + { + case SECUREBOOT_MODE_FULL: + case SECUREBOOT_MODE_FULL_COPY: + packet->txsize += (SECUREBOOT_DIGEST_SIZE + SECUREBOOT_SIGNATURE_SIZE); + break; + + case SECUREBOOT_MODE_FULL_STORE: + packet->txsize += SECUREBOOT_DIGEST_SIZE; + break; + + default: + return ATCA_BAD_PARAM; + break; + } + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand SHA method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \param[in] write_context_size the length of the sha write_context data + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atSHA(ATCACommand ca_cmd, ATCAPacket *packet, uint16_t write_context_size) +{ + // Set the opcode & parameters + packet->opcode = ATCA_SHA; + + switch (packet->param1 & SHA_MODE_MASK) + { + case SHA_MODE_SHA256_START: // START + case SHA_MODE_HMAC_START: + case SHA_MODE_SHA256_PUBLIC: + packet->txsize = ATCA_CMD_SIZE_MIN; + break; + + case SHA_MODE_SHA256_UPDATE: // UPDATE + packet->txsize = ATCA_CMD_SIZE_MIN + packet->param2; + break; + + case SHA_MODE_SHA256_END: // END + case SHA_MODE_HMAC_END: + // check the given packet for a size variable in param2. If it is > 0, it should + // be 0-63, incorporate that size into the packet + packet->txsize = ATCA_CMD_SIZE_MIN + packet->param2; + break; + + case SHA_MODE_READ_CONTEXT: + packet->txsize = ATCA_CMD_SIZE_MIN; + break; + + case SHA_MODE_WRITE_CONTEXT: + packet->txsize = ATCA_CMD_SIZE_MIN + write_context_size; + break; + + default: + return ATCA_BAD_PARAM; + } + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand Sign method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS + */ +ATCA_STATUS atSign(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + packet->opcode = ATCA_SIGN; + packet->txsize = SIGN_COUNT; + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand UpdateExtra method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS + */ +ATCA_STATUS atUpdateExtra(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + packet->opcode = ATCA_UPDATE_EXTRA; + packet->txsize = UPDATE_COUNT; + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand ECDSA Verify method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atVerify(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + packet->opcode = ATCA_VERIFY; + + // variable packet size based on mode + switch (packet->param1 & VERIFY_MODE_MASK) + { + case VERIFY_MODE_STORED: + packet->txsize = VERIFY_256_STORED_COUNT; + break; + + case VERIFY_MODE_VALIDATE_EXTERNAL: + packet->txsize = VERIFY_256_EXTERNAL_COUNT; + break; + + case VERIFY_MODE_EXTERNAL: + packet->txsize = VERIFY_256_EXTERNAL_COUNT; + break; + + case VERIFY_MODE_VALIDATE: + case VERIFY_MODE_INVALIDATE: + packet->txsize = VERIFY_256_VALIDATE_COUNT; + break; + + default: + return ATCA_BAD_PARAM; + } + + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand Write method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \param[in] has_mac Flag to indicate whether a mac is present or not + * \return ATCA_SUCCESS + */ +ATCA_STATUS atWrite(ATCACommand ca_cmd, ATCAPacket *packet, bool has_mac) +{ + // Set the opcode & parameters + packet->opcode = ATCA_WRITE; + + packet->txsize = 7; + if (packet->param1 & ATCA_ZONE_READWRITE_32) + { + packet->txsize += ATCA_BLOCK_SIZE; + } + else + { + packet->txsize += ATCA_WORD_SIZE; + } + if (has_mac) + { + packet->txsize += WRITE_MAC_SIZE; + } + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand AES method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS + */ +ATCA_STATUS atAES(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + packet->opcode = ATCA_AES; + packet->txsize = ATCA_CMD_SIZE_MIN; + + if ((packet->param1 & AES_MODE_OP_MASK) == AES_MODE_GFM) + { + packet->txsize += ATCA_AES_GFM_SIZE; + } + else + { + packet->txsize += AES_DATA_SIZE; + } + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief ATCACommand AES method + * \param[in] ca_cmd instance + * \param[in] packet pointer to the packet containing the command being built + * \return ATCA_SUCCESS + */ +ATCA_STATUS atSelfTest(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + packet->opcode = ATCA_SELFTEST; + packet->txsize = ATCA_CMD_SIZE_MIN; + atCalcCrc(packet); + return ATCA_SUCCESS; +} + + + +/** \brief ATCACommand KDF method + * \param[in] ca_cmd Instance + * \param[in] packet Pointer to the packet containing the command being + * built. + * \return ATCA_SUCCESS + */ +ATCA_STATUS atKDF(ATCACommand ca_cmd, ATCAPacket *packet) +{ + // Set the opcode & parameters + packet->opcode = ATCA_KDF; + + // Set TX size + if ((packet->param1 & KDF_MODE_ALG_MASK) == KDF_MODE_ALG_AES) + { + // AES algorithm has a fixed message size + packet->txsize = ATCA_CMD_SIZE_MIN + KDF_DETAILS_SIZE + AES_DATA_SIZE; + } + else + { + // All other algorithms encode message size in the last byte of details + packet->txsize = ATCA_CMD_SIZE_MIN + KDF_DETAILS_SIZE + packet->data[3]; + } + atCalcCrc(packet); + return ATCA_SUCCESS; +} + +/** \brief Initializer for ATCACommand + * \param[in] device_type Specifies which set of commands and execution times + * should be associated with this command object. + * \param[in] ca_cmd Pre-allocated command structure to initialize. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS initATCACommand(ATCADeviceType device_type, ATCACommand ca_cmd) +{ + if (ca_cmd == NULL) + { + return ATCA_BAD_PARAM; + } + + ca_cmd->dt = device_type; + ca_cmd->clock_divider = 0; + + return ATCA_SUCCESS; +} + +#ifndef ATCA_NO_HEAP +/** \brief constructor for ATCACommand + * \param[in] device_type Specifies which set of commands and execution times + * should be associated with this command object. + * \return Initialized object on success. NULL on failure. + */ +ATCACommand newATCACommand(ATCADeviceType device_type) +{ + ATCACommand ca_cmd; + ATCA_STATUS status; + + ca_cmd = (ATCACommand)malloc(sizeof(*ca_cmd)); + status = initATCACommand(device_type, ca_cmd); + if (status != ATCA_SUCCESS) + { + free(ca_cmd); + ca_cmd = NULL; + return NULL; + } + + return ca_cmd; +} +#endif + +#ifndef ATCA_NO_HEAP +/** \brief ATCACommand destructor + * \param[in] ca_cmd instance of a command object + */ +void deleteATCACommand(ATCACommand *ca_cmd) +{ + if (ca_cmd == NULL) + { + return; + } + + free(*ca_cmd); + *ca_cmd = NULL; +} +#endif + +/** \brief Calculates CRC over the given raw data and returns the CRC in + * little-endian byte order. + * + * \param[in] length Size of data not including the CRC byte positions + * \param[in] data Pointer to the data over which to compute the CRC + * \param[out] crc_le Pointer to the place where the two-bytes of CRC will be + * returned in little-endian byte order. + */ +void atCRC(size_t length, const uint8_t *data, uint8_t *crc_le) +{ + size_t counter; + uint16_t crc_register = 0; + uint16_t polynom = 0x8005; + uint8_t shift_register; + uint8_t data_bit, crc_bit; + + for (counter = 0; counter < length; counter++) + { + for (shift_register = 0x01; shift_register > 0x00; shift_register <<= 1) + { + data_bit = (data[counter] & shift_register) ? 1 : 0; + crc_bit = crc_register >> 15; + crc_register <<= 1; + if (data_bit != crc_bit) + { + crc_register ^= polynom; + } + } + } + crc_le[0] = (uint8_t)(crc_register & 0x00FF); + crc_le[1] = (uint8_t)(crc_register >> 8); +} + + +/** \brief This function calculates CRC and adds it to the correct offset in the packet data + * \param[in] packet Packet to calculate CRC data for + */ + +void atCalcCrc(ATCAPacket *packet) +{ + uint8_t length, *crc; + + length = packet->txsize - ATCA_CRC_SIZE; + // computer pointer to CRC in the packet + crc = &(packet->txsize) + length; + + // stuff CRC into packet + atCRC(length, &(packet->txsize), crc); +} + + +/** \brief This function checks the consistency of a response. + * \param[in] response pointer to response + * \return ATCA_SUCCESS on success, otherwise ATCA_RX_CRC_ERROR + */ + +ATCA_STATUS atCheckCrc(const uint8_t *response) +{ + uint8_t crc[ATCA_CRC_SIZE]; + uint8_t count = response[ATCA_COUNT_IDX]; + + count -= ATCA_CRC_SIZE; + atCRC(count, response, crc); + + return (crc[0] == response[count] && crc[1] == response[count + 1]) ? ATCA_SUCCESS : ATCA_RX_CRC_ERROR; +} + + +/** \brief determines if a given device type is a SHA device or a superset of a SHA device + * \param[in] device_type Type of device to check for family type + * \return boolean indicating whether the given device is a SHA family device. + */ + +bool atIsSHAFamily(ATCADeviceType device_type) +{ + switch (device_type) + { + case ATSHA204A: + case ATECC108A: + case ATECC508A: + case ATECC608A: + return true; + break; + + default: + return false; + break; + } +} + +/** \brief determines if a given device type is an ECC device or a superset of a ECC device + * \param[in] device_type Type of device to check for family type + * \return boolean indicating whether the given device is an ECC family device. + */ +bool atIsECCFamily(ATCADeviceType device_type) +{ + switch (device_type) + { + case ATECC108A: + case ATECC508A: + case ATECC608A: + return true; + break; + default: + return false; + break; + } +} + +/** \brief checks for basic error frame in data + * \param[in] data pointer to received data - expected to be in the form of a CA device response frame + * \return ATCA_SUCCESS on success, otherwise an error code. + */ + +ATCA_STATUS isATCAError(uint8_t *data) +{ + if (data[0] == 0x04) // error packets are always 4 bytes long + { + switch (data[1]) + { + case 0x00: //No Error + return ATCA_SUCCESS; + case 0x01: // checkmac or verify failed + return ATCA_CHECKMAC_VERIFY_FAILED; + break; + case 0x03: // command received byte length, opcode or parameter was illegal + return ATCA_PARSE_ERROR; + break; + case 0x05: // computation error during ECC processing causing invalid results + return ATCA_STATUS_ECC; + break; + case 0x07: // chip is in self test failure mode + return ATCA_STATUS_SELFTEST_ERROR; + break; + case 0x08: //random number generator health test error + return ATCA_HEALTH_TEST_ERROR; + case 0x0f: // chip can't execute the command + return ATCA_EXECUTION_ERROR; + break; + case 0x11: // chip was successfully woken up + return ATCA_WAKE_SUCCESS; + break; + case 0xff: // bad crc found (command not properly received by device) or other comm error + return ATCA_STATUS_CRC; + break; + default: + return ATCA_GEN_FAIL; + break; + } + } + else + { + return ATCA_SUCCESS; + } +} + +/** @} */ diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.h new file mode 100644 index 0000000..1ad6f96 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.h @@ -0,0 +1,762 @@ +/** + * \file + * \brief Microchip Crypto Auth device command object - this is a command builder only, it does + * not send the command. The result of a command method is a fully formed packet, ready to send + * to the ATCAIFace object to dispatch. + * + * This command object supports the ATSHA and ATECC device family. + * The command list is a superset of all device commands for this family. The command object + * differentiates the packet contents based on specific device type within the family. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef ATCA_COMMAND_H +#define ATCA_COMMAND_H + +#include "atca_compiler.h" +#include "atca_status.h" +#include "atca_devtypes.h" +#include "cryptoauthlib_config.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup command ATCACommand (atca_) + \brief CryptoAuthLib command builder object, ATCACommand. Member functions for the ATCACommand object. + @{ */ + +/** \brief atca_command is the C object backing ATCACommand. + */ +struct atca_command +{ + ATCADeviceType dt; + uint8_t clock_divider; + uint16_t execution_time_msec; +}; + +/*--- ATCACommand ---------*/ +typedef struct atca_command* ATCACommand; + +ATCA_STATUS initATCACommand(ATCADeviceType device_type, ATCACommand ca_cmd); +ATCACommand newATCACommand(ATCADeviceType device_type); +void deleteATCACommand(ATCACommand *ca_cmd); + +/* add ATCACommand declarations here + * + * since these are still C functions, not classes, naming is an important + * consideration to keep the namespace from colliding with other 3rd party + * libraries or even ourselves/ASF. + * + * Basic conventions: + * all methods start with the prefix 'at' + * all method names must be unique, obviously + * all method implementations should be proceeded by their Doxygen comment header + * + **/ + + +// this is the ATCACommand parameter structure. The caller to the command method must +// initialize param1, param2 and data if appropriate. The command method will fill in the rest +// and initialize the packet so it's ready to send via the ATCAIFace. +// this particular structure mimics the ATSHA and ATECC family device's command structures + +// Note: pack @ 2 is required, @ 1 causes word alignment crash (though it should not), a known bug in GCC. +// @2, the wire still has the intended byte alignment with arm-eabi. this is likely the least portable part of atca +#if defined(__XC16__)||defined(__XC32__) +#pragma pack( push, ATCAPacket, 2 ) +#endif + +/** \brief an ATCA packet structure. This is a superset of the packet transmitted on the wire. It's also + * used as a buffer for receiving the response + */ +typedef struct +{ + + // used for transmit/send + uint8_t _reserved; // used by HAL layer as needed (I/O tokens, Word address values) + + //--- start of packet i/o frame---- + uint8_t txsize; + uint8_t opcode; + uint8_t param1; // often same as mode + uint16_t param2; + uint8_t data[192]; // includes 2-byte CRC. data size is determined by largest possible data section of any + // command + crc (see: x08 verify data1 + data2 + data3 + data4) + // this is an explicit design trade-off (space) resulting in simplicity in use + // and implementation + //--- end of packet i/o frame + + // used for receive + uint8_t execTime; // execution time of command by opcode + + // structure should be packed since it will be transmitted over the wire + // this method varies by compiler. As new compilers are supported, add their structure packing method here + +} ATCAPacket; + +#if defined(__XC16__)||defined(__XC32__) +#pragma pack( pop, ATCAPacket) +#endif + + +ATCA_STATUS atCheckMAC(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atCounter(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atDeriveKey(ATCACommand ca_cmd, ATCAPacket *packet, bool has_mac); +ATCA_STATUS atECDH(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atGenDig(ATCACommand ca_cmd, ATCAPacket *packet, bool is_no_mac_key); +ATCA_STATUS atGenKey(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atHMAC(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atInfo(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atLock(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atMAC(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atNonce(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atPause(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atPrivWrite(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atRandom(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atRead(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atSecureBoot(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atSHA(ATCACommand ca_cmd, ATCAPacket *packet, uint16_t write_context_size); +ATCA_STATUS atSign(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atUpdateExtra(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atVerify(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atWrite(ATCACommand ca_cmd, ATCAPacket *packet, bool has_mac); +ATCA_STATUS atAES(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atSelfTest(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atKDF(ATCACommand ca_cmd, ATCAPacket *packet); + +bool atIsSHAFamily(ATCADeviceType device_type); +bool atIsECCFamily(ATCADeviceType device_type); +ATCA_STATUS isATCAError(uint8_t *data); + + +// command helpers +void atCRC(size_t length, const uint8_t *data, uint8_t *crc_le); +void atCalcCrc(ATCAPacket *pkt); +ATCA_STATUS atCheckCrc(const uint8_t *response); + + +/* command definitions */ + +//! minimum number of bytes in command (from count byte to second CRC byte) +#define ATCA_CMD_SIZE_MIN ((uint8_t)7) +//! maximum size of command packet (Verify) +#define ATCA_CMD_SIZE_MAX ((uint8_t)4 * 36 + 7) +//! status byte for success +#define CMD_STATUS_SUCCESS ((uint8_t)0x00) +//! status byte after wake-up +#define CMD_STATUS_WAKEUP ((uint8_t)0x11) +//! command parse error +#define CMD_STATUS_BYTE_PARSE ((uint8_t)0x03) +//! command ECC error +#define CMD_STATUS_BYTE_ECC ((uint8_t)0x05) +//! command execution error +#define CMD_STATUS_BYTE_EXEC ((uint8_t)0x0F) +//! communication error +#define CMD_STATUS_BYTE_COMM ((uint8_t)0xFF) + +/** \name Opcodes for Crypto Authentication device commands + @{ */ +#define ATCA_CHECKMAC ((uint8_t)0x28) //!< CheckMac command op-code +#define ATCA_DERIVE_KEY ((uint8_t)0x1C) //!< DeriveKey command op-code +#define ATCA_INFO ((uint8_t)0x30) //!< Info command op-code +#define ATCA_GENDIG ((uint8_t)0x15) //!< GenDig command op-code +#define ATCA_GENKEY ((uint8_t)0x40) //!< GenKey command op-code +#define ATCA_HMAC ((uint8_t)0x11) //!< HMAC command op-code +#define ATCA_LOCK ((uint8_t)0x17) //!< Lock command op-code +#define ATCA_MAC ((uint8_t)0x08) //!< MAC command op-code +#define ATCA_NONCE ((uint8_t)0x16) //!< Nonce command op-code +#define ATCA_PAUSE ((uint8_t)0x01) //!< Pause command op-code +#define ATCA_PRIVWRITE ((uint8_t)0x46) //!< PrivWrite command op-code +#define ATCA_RANDOM ((uint8_t)0x1B) //!< Random command op-code +#define ATCA_READ ((uint8_t)0x02) //!< Read command op-code +#define ATCA_SIGN ((uint8_t)0x41) //!< Sign command op-code +#define ATCA_UPDATE_EXTRA ((uint8_t)0x20) //!< UpdateExtra command op-code +#define ATCA_VERIFY ((uint8_t)0x45) //!< GenKey command op-code +#define ATCA_WRITE ((uint8_t)0x12) //!< Write command op-code +#define ATCA_ECDH ((uint8_t)0x43) //!< ECDH command op-code +#define ATCA_COUNTER ((uint8_t)0x24) //!< Counter command op-code +#define ATCA_SHA ((uint8_t)0x47) //!< SHA command op-code +#define ATCA_AES ((uint8_t)0x51) //!< AES command op-code +#define ATCA_KDF ((uint8_t)0x56) //!< KDF command op-code +#define ATCA_SECUREBOOT ((uint8_t)0x80) //!< Secure Boot command op-code +#define ATCA_SELFTEST ((uint8_t)0x77) //!< Self test command op-code + + + + +/** @} */ + + +/** \name Definitions of Data and Packet Sizes + @{ */ +#define ATCA_BLOCK_SIZE (32) //!< size of a block +#define ATCA_WORD_SIZE (4) //!< size of a word +#define ATCA_PUB_KEY_PAD (4) //!< size of the public key pad +#define ATCA_SERIAL_NUM_SIZE (9) //!< number of bytes in the device serial number +#define ATCA_RSP_SIZE_VAL ((uint8_t)7) //!< size of response packet containing four bytes of data +#define ATCA_KEY_COUNT (16) //!< number of keys +#define ATCA_ECC_CONFIG_SIZE (128) //!< size of configuration zone +#define ATCA_SHA_CONFIG_SIZE (88) //!< size of configuration zone +#define ATCA_OTP_SIZE (64) //!< size of OTP zone +#define ATCA_DATA_SIZE (ATCA_KEY_COUNT * ATCA_KEY_SIZE) //!< size of data zone +#define ATCA_AES_GFM_SIZE ATCA_BLOCK_SIZE //!< size of GFM data + +#define ATCA_CHIPMODE_OFFSET (19) //!< ChipMode byte offset within the configuration zone +#define ATCA_CHIPMODE_I2C_ADDRESS_FLAG ((uint8_t)0x01) //!< ChipMode I2C Address in UserExtraAdd flag +#define ATCA_CHIPMODE_TTL_ENABLE_FLAG ((uint8_t)0x02) //!< ChipMode TTLenable flag +#define ATCA_CHIPMODE_WATCHDOG_MASK ((uint8_t)0x04) //!< ChipMode watchdog duration mask +#define ATCA_CHIPMODE_WATCHDOG_SHORT ((uint8_t)0x00) //!< ChipMode short watchdog (~1.3s) +#define ATCA_CHIPMODE_WATCHDOG_LONG ((uint8_t)0x04) //!< ChipMode long watchdog (~13s) +#define ATCA_CHIPMODE_CLOCK_DIV_MASK ((uint8_t)0xF8) //!< ChipMode clock divider mask +#define ATCA_CHIPMODE_CLOCK_DIV_M0 ((uint8_t)0x00) //!< ChipMode clock divider M0 +#define ATCA_CHIPMODE_CLOCK_DIV_M1 ((uint8_t)0x28) //!< ChipMode clock divider M1 +#define ATCA_CHIPMODE_CLOCK_DIV_M2 ((uint8_t)0x68) //!< ChipMode clock divider M2 + +#define ATCA_COUNT_SIZE ((uint8_t)1) //!< Number of bytes in the command packet Count +#define ATCA_CRC_SIZE ((uint8_t)2) //!< Number of bytes in the command packet CRC +#define ATCA_PACKET_OVERHEAD (ATCA_COUNT_SIZE + ATCA_CRC_SIZE) //!< Number of bytes in the command packet + +#define ATCA_PUB_KEY_SIZE (64) //!< size of a p256 public key +#define ATCA_PRIV_KEY_SIZE (32) //!< size of a p256 private key +#define ATCA_SIG_SIZE (64) //!< size of a p256 signature +#define ATCA_KEY_SIZE (32) //!< size of a symmetric SHA key +#define RSA2048_KEY_SIZE (256) //!< size of a RSA private key + +#define ATCA_RSP_SIZE_MIN ((uint8_t)4) //!< minimum number of bytes in response +#define ATCA_RSP_SIZE_4 ((uint8_t)7) //!< size of response packet containing 4 bytes data +#define ATCA_RSP_SIZE_72 ((uint8_t)75) //!< size of response packet containing 64 bytes data +#define ATCA_RSP_SIZE_64 ((uint8_t)67) //!< size of response packet containing 64 bytes data +#define ATCA_RSP_SIZE_32 ((uint8_t)35) //!< size of response packet containing 32 bytes data +#define ATCA_RSP_SIZE_16 ((uint8_t)19) //!< size of response packet containing 16 bytes data +#define ATCA_RSP_SIZE_MAX ((uint8_t)75) //!< maximum size of response packet (GenKey and Verify command) + +#define OUTNONCE_SIZE (32) //!< Size of the OutNonce response expected from several commands + +/** \name Definitions for Command Parameter Ranges + @{ */ +#define ATCA_KEY_ID_MAX ((uint8_t)15) //!< maximum value for key id +#define ATCA_OTP_BLOCK_MAX ((uint8_t)1) //!< maximum value for OTP block +/** @} */ + +/** \name Definitions for Indexes Common to All Commands + @{ */ +#define ATCA_COUNT_IDX (0) //!< command packet index for count +#define ATCA_OPCODE_IDX (1) //!< command packet index for op-code +#define ATCA_PARAM1_IDX (2) //!< command packet index for first parameter +#define ATCA_PARAM2_IDX (3) //!< command packet index for second parameter +#define ATCA_DATA_IDX (5) //!< command packet index for data load +#define ATCA_RSP_DATA_IDX (1) //!< buffer index of data in response +/** @} */ + +/** \name Definitions for Zone and Address Parameters + @{ */ +#define ATCA_ZONE_CONFIG ((uint8_t)0x00) //!< Configuration zone +#define ATCA_ZONE_OTP ((uint8_t)0x01) //!< OTP (One Time Programming) zone +#define ATCA_ZONE_DATA ((uint8_t)0x02) //!< Data zone +#define ATCA_ZONE_MASK ((uint8_t)0x03) //!< Zone mask +#define ATCA_ZONE_ENCRYPTED ((uint8_t)0x40) //!< Zone bit 6 set: Write is encrypted with an unlocked data zone. +#define ATCA_ZONE_READWRITE_32 ((uint8_t)0x80) //!< Zone bit 7 set: Access 32 bytes, otherwise 4 bytes. +#define ATCA_ADDRESS_MASK_CONFIG (0x001F) //!< Address bits 5 to 7 are 0 for Configuration zone. +#define ATCA_ADDRESS_MASK_OTP (0x000F) //!< Address bits 4 to 7 are 0 for OTP zone. +#define ATCA_ADDRESS_MASK (0x007F) //!< Address bit 7 to 15 are always 0. +#define ATCA_TEMPKEY_KEYID (0xFFFF) //!< KeyID when referencing TempKey +/** @} */ + +/** \name Definitions for Key types + @{ */ +#define ATCA_B283_KEY_TYPE 0 //!< B283 NIST ECC key +#define ATCA_K283_KEY_TYPE 1 //!< K283 NIST ECC key +#define ATCA_P256_KEY_TYPE 4 //!< P256 NIST ECC key +#define ATCA_AES_KEY_TYPE 6 //!< AES-128 Key +#define ATCA_SHA_KEY_TYPE 7 //!< SHA key or other data +/** @} */ + +/** \name Definitions for the AES Command + @{ */ +#define AES_MODE_IDX ATCA_PARAM1_IDX //!< AES command index for mode +#define AES_KEYID_IDX ATCA_PARAM2_IDX //!< AES command index for key id +#define AES_INPUT_IDX ATCA_DATA_IDX //!< AES command index for input data +#define AES_COUNT (23) //!< AES command packet size +#define AES_MODE_MASK ((uint8_t)0xC7) //!< AES mode bits 3 to 5 are 0 +#define AES_MODE_KEY_BLOCK_MASK ((uint8_t)0xC0) //!< AES mode mask for key block field +#define AES_MODE_OP_MASK ((uint8_t)0x07) //!< AES mode operation mask +#define AES_MODE_ENCRYPT ((uint8_t)0x00) //!< AES mode: Encrypt +#define AES_MODE_DECRYPT ((uint8_t)0x01) //!< AES mode: Decrypt +#define AES_MODE_GFM ((uint8_t)0x03) //!< AES mode: GFM calculation +#define AES_MODE_KEY_BLOCK_POS (6) //!< Bit shift for key block in mode +#define AES_DATA_SIZE (16) //!< size of AES encrypt/decrypt data +#define AES_RSP_SIZE ATCA_RSP_SIZE_16 //!< AES command response packet size +/** @} */ + +/** \name Definitions for the CheckMac Command + @{ */ +#define CHECKMAC_MODE_IDX ATCA_PARAM1_IDX //!< CheckMAC command index for mode +#define CHECKMAC_KEYID_IDX ATCA_PARAM2_IDX //!< CheckMAC command index for key identifier +#define CHECKMAC_CLIENT_CHALLENGE_IDX ATCA_DATA_IDX //!< CheckMAC command index for client challenge +#define CHECKMAC_CLIENT_RESPONSE_IDX (37) //!< CheckMAC command index for client response +#define CHECKMAC_DATA_IDX (69) //!< CheckMAC command index for other data +#define CHECKMAC_COUNT (84) //!< CheckMAC command packet size +#define CHECKMAC_MODE_CHALLENGE ((uint8_t)0x00) //!< CheckMAC mode 0: first SHA block from key id +#define CHECKMAC_MODE_BLOCK2_TEMPKEY ((uint8_t)0x01) //!< CheckMAC mode bit 0: second SHA block from TempKey +#define CHECKMAC_MODE_BLOCK1_TEMPKEY ((uint8_t)0x02) //!< CheckMAC mode bit 1: first SHA block from TempKey +#define CHECKMAC_MODE_SOURCE_FLAG_MATCH ((uint8_t)0x04) //!< CheckMAC mode bit 2: match TempKey.SourceFlag +#define CHECKMAC_MODE_INCLUDE_OTP_64 ((uint8_t)0x20) //!< CheckMAC mode bit 5: include first 64 OTP bits +#define CHECKMAC_MODE_MASK ((uint8_t)0x27) //!< CheckMAC mode bits 3, 4, 6, and 7 are 0. +#define CHECKMAC_CLIENT_CHALLENGE_SIZE (32) //!< CheckMAC size of client challenge +#define CHECKMAC_CLIENT_RESPONSE_SIZE (32) //!< CheckMAC size of client response +#define CHECKMAC_OTHER_DATA_SIZE (13) //!< CheckMAC size of "other data" +#define CHECKMAC_CLIENT_COMMAND_SIZE (4) //!< CheckMAC size of client command header size inside "other data" +#define CHECKMAC_CMD_MATCH (0) //!< CheckMAC return value when there is a match +#define CHECKMAC_CMD_MISMATCH (1) //!< CheckMAC return value when there is a mismatch +#define CHECKMAC_RSP_SIZE ATCA_RSP_SIZE_MIN //!< CheckMAC response packet size +/** @} */ + +/** \name Definitions for the Counter command + @{ */ +#define COUNTER_COUNT ATCA_CMD_SIZE_MIN +#define COUNTER_MODE_IDX ATCA_PARAM1_IDX //!< Counter command index for mode +#define COUNTER_KEYID_IDX ATCA_PARAM2_IDX //!< Counter command index for key id +#define COUNTER_MODE_MASK ((uint8_t)0x01) //!< Counter mode bits 1 to 7 are 0 +#define COUNTER_MAX_VALUE ((uint32_t)2097151) //!< Counter maximum value of the counter +#define COUNTER_MODE_READ ((uint8_t)0x00) //!< Counter command mode for reading +#define COUNTER_MODE_INCREMENT ((uint8_t)0x01) //!< Counter command mode for incrementing +#define COUNTER_RSP_SIZE ATCA_RSP_SIZE_4 //!< Counter command response packet size +/** @} */ + +/** \name Definitions for the DeriveKey Command + @{ */ +#define DERIVE_KEY_RANDOM_IDX ATCA_PARAM1_IDX //!< DeriveKey command index for random bit +#define DERIVE_KEY_TARGETKEY_IDX ATCA_PARAM2_IDX //!< DeriveKey command index for target slot +#define DERIVE_KEY_MAC_IDX ATCA_DATA_IDX //!< DeriveKey command index for optional MAC +#define DERIVE_KEY_COUNT_SMALL ATCA_CMD_SIZE_MIN //!< DeriveKey command packet size without MAC +#define DERIVE_KEY_MODE ((uint8_t)0x04) //!< DeriveKey command mode set to 4 as in datasheet +#define DERIVE_KEY_COUNT_LARGE (39) //!< DeriveKey command packet size with MAC +#define DERIVE_KEY_RANDOM_FLAG ((uint8_t)4) //!< DeriveKey 1. parameter; has to match TempKey.SourceFlag +#define DERIVE_KEY_MAC_SIZE (32) //!< DeriveKey MAC size +#define DERIVE_KEY_RSP_SIZE ATCA_RSP_SIZE_MIN //!< DeriveKey response packet size +/** @} */ + +/** \name Definitions for the ECDH Command + @{ */ +#define ECDH_PREFIX_MODE ((uint8_t)0x00) +#define ECDH_COUNT (ATCA_CMD_SIZE_MIN + ATCA_PUB_KEY_SIZE) +#define ECDH_MODE_SOURCE_MASK ((uint8_t)0x01) +#define ECDH_MODE_SOURCE_EEPROM_SLOT ((uint8_t)0x00) +#define ECDH_MODE_SOURCE_TEMPKEY ((uint8_t)0x01) +#define ECDH_MODE_OUTPUT_MASK ((uint8_t)0x02) +#define ECDH_MODE_OUTPUT_CLEAR ((uint8_t)0x00) +#define ECDH_MODE_OUTPUT_ENC ((uint8_t)0x02) +#define ECDH_MODE_COPY_MASK ((uint8_t)0x0C) +#define ECDH_MODE_COPY_COMPATIBLE ((uint8_t)0x00) +#define ECDH_MODE_COPY_EEPROM_SLOT ((uint8_t)0x04) +#define ECDH_MODE_COPY_TEMP_KEY ((uint8_t)0x08) +#define ECDH_MODE_COPY_OUTPUT_BUFFER ((uint8_t)0x0C) +#define ECDH_KEY_SIZE ATCA_BLOCK_SIZE //!< ECDH output data size +#define ECDH_RSP_SIZE ATCA_RSP_SIZE_64 //!< ECDH command packet size +/** @} */ + +/** \name Definitions for the GenDig Command + @{ */ +#define GENDIG_ZONE_IDX ATCA_PARAM1_IDX //!< GenDig command index for zone +#define GENDIG_KEYID_IDX ATCA_PARAM2_IDX //!< GenDig command index for key id +#define GENDIG_DATA_IDX ATCA_DATA_IDX //!< GenDig command index for optional data +#define GENDIG_COUNT ATCA_CMD_SIZE_MIN //!< GenDig command packet size without "other data" +#define GENDIG_ZONE_CONFIG ((uint8_t)0) //!< GenDig zone id config. Use KeyID to specify any of the four 256-bit blocks of the Configuration zone. +#define GENDIG_ZONE_OTP ((uint8_t)1) //!< GenDig zone id OTP. Use KeyID to specify either the first or second 256-bit block of the OTP zone. +#define GENDIG_ZONE_DATA ((uint8_t)2) //!< GenDig zone id data. Use KeyID to specify a slot in the Data zone or a transport key in the hardware array. +#define GENDIG_ZONE_SHARED_NONCE ((uint8_t)3) //!< GenDig zone id shared nonce. KeyID specifies the location of the input value in the message generation. +#define GENDIG_ZONE_COUNTER ((uint8_t)4) //!< GenDig zone id counter. KeyID specifies the monotonic counter ID to be included in the message generation. +#define GENDIG_ZONE_KEY_CONFIG ((uint8_t)5) //!< GenDig zone id key config. KeyID specifies the slot for which the configuration information is to be included in the message generation. +#define GENDIG_RSP_SIZE ATCA_RSP_SIZE_MIN //!< GenDig command response packet size +/** @} */ + +/** \name Definitions for the GenKey Command + @{ */ +#define GENKEY_MODE_IDX ATCA_PARAM1_IDX //!< GenKey command index for mode +#define GENKEY_KEYID_IDX ATCA_PARAM2_IDX //!< GenKey command index for key id +#define GENKEY_DATA_IDX (5) //!< GenKey command index for other data +#define GENKEY_COUNT ATCA_CMD_SIZE_MIN //!< GenKey command packet size without "other data" +#define GENKEY_COUNT_DATA (10) //!< GenKey command packet size with "other data" +#define GENKEY_OTHER_DATA_SIZE (3) //!< GenKey size of "other data" +#define GENKEY_MODE_MASK ((uint8_t)0x1C) //!< GenKey mode bits 0 to 1 and 5 to 7 are 0 +#define GENKEY_MODE_PRIVATE ((uint8_t)0x04) //!< GenKey mode: private key generation +#define GENKEY_MODE_PUBLIC ((uint8_t)0x00) //!< GenKey mode: public key calculation +#define GENKEY_MODE_DIGEST ((uint8_t)0x08) //!< GenKey mode: PubKey digest will be created after the public key is calculated +#define GENKEY_MODE_PUBKEY_DIGEST ((uint8_t)0x10) //!< GenKey mode: Calculate PubKey digest on the public key in KeyId +#define GENKEY_PRIVATE_TO_TEMPKEY ((uint16_t)0xFFFF) //!< GenKey Create private key and store to tempkey (608 only) +#define GENKEY_RSP_SIZE_SHORT ATCA_RSP_SIZE_MIN //!< GenKey response packet size in Digest mode +#define GENKEY_RSP_SIZE_LONG ATCA_RSP_SIZE_64 //!< GenKey response packet size when returning a public key +/** @} */ + +/** \name Definitions for the HMAC Command + @{ */ +#define HMAC_MODE_IDX ATCA_PARAM1_IDX //!< HMAC command index for mode +#define HMAC_KEYID_IDX ATCA_PARAM2_IDX //!< HMAC command index for key id +#define HMAC_COUNT ATCA_CMD_SIZE_MIN //!< HMAC command packet size +#define HMAC_MODE_FLAG_TK_RAND ((uint8_t)0x00) //!< HMAC mode bit 2: The value of this bit must match the value in TempKey.SourceFlag or the command will return an error. +#define HMAC_MODE_FLAG_TK_NORAND ((uint8_t)0x04) //!< HMAC mode bit 2: The value of this bit must match the value in TempKey.SourceFlag or the command will return an error. +#define HMAC_MODE_FLAG_OTP88 ((uint8_t)0x10) //!< HMAC mode bit 4: Include the first 88 OTP bits (OTP[0] through OTP[10]) in the message.; otherwise, the corresponding message bits are set to zero. Not applicable for ATECC508A. +#define HMAC_MODE_FLAG_OTP64 ((uint8_t)0x20) //!< HMAC mode bit 5: Include the first 64 OTP bits (OTP[0] through OTP[7]) in the message.; otherwise, the corresponding message bits are set to zero. If Mode[4] is set, the value of this mode bit is ignored. Not applicable for ATECC508A. +#define HMAC_MODE_FLAG_FULLSN ((uint8_t)0x40) //!< HMAC mode bit 6: If set, include the 48 bits SN[2:3] and SN[4:7] in the message.; otherwise, the corresponding message bits are set to zero. +#define HMAC_MODE_MASK ((uint8_t)0x74) //!< HMAC mode bits 0, 1, 3, and 7 are 0. +#define HMAC_DIGEST_SIZE (32) //!< HMAC size of digest response +#define HMAC_RSP_SIZE ATCA_RSP_SIZE_32 //!< HMAC command response packet size +/** @} */ + +/** \name Definitions for the Info Command + @{ */ +#define INFO_PARAM1_IDX ATCA_PARAM1_IDX //!< Info command index for 1. parameter +#define INFO_PARAM2_IDX ATCA_PARAM2_IDX //!< Info command index for 2. parameter +#define INFO_COUNT ATCA_CMD_SIZE_MIN //!< Info command packet size +#define INFO_MODE_REVISION ((uint8_t)0x00) //!< Info mode Revision +#define INFO_MODE_KEY_VALID ((uint8_t)0x01) //!< Info mode KeyValid +#define INFO_MODE_STATE ((uint8_t)0x02) //!< Info mode State +#define INFO_MODE_GPIO ((uint8_t)0x03) //!< Info mode GPIO +#define INFO_MODE_VOL_KEY_PERMIT ((uint8_t)0x04) //!< Info mode GPIO +#define INFO_MODE_MAX ((uint8_t)0x03) //!< Info mode maximum value +#define INFO_NO_STATE ((uint8_t)0x00) //!< Info mode is not the state mode. +#define INFO_OUTPUT_STATE_MASK ((uint8_t)0x01) //!< Info output state mask +#define INFO_DRIVER_STATE_MASK ((uint8_t)0x02) //!< Info driver state mask +#define INFO_PARAM2_SET_LATCH_STATE ((uint16_t)0x0002) //!< Info param2 to set the persistent latch state. +#define INFO_PARAM2_LATCH_SET ((uint16_t)0x0001) //!< Info param2 to set the persistent latch +#define INFO_PARAM2_LATCH_CLEAR ((uint16_t)0x0000) //!< Info param2 to clear the persistent latch +#define INFO_SIZE ((uint8_t)0x04) //!< Info return size +#define INFO_RSP_SIZE ATCA_RSP_SIZE_VAL //!< Info command response packet size +/** @} */ + +/** \name Definitions for the KDF Command + @{ */ +#define KDF_MODE_IDX ATCA_PARAM1_IDX //!< KDF command index for mode +#define KDF_KEYID_IDX ATCA_PARAM2_IDX //!< KDF command index for key id +#define KDF_DETAILS_IDX ATCA_DATA_IDX //!< KDF command index for details +#define KDF_DETAILS_SIZE 4 //!< KDF details (param3) size +#define KDF_MESSAGE_IDX (ATCA_DATA_IDX + KDF_DETAILS_SIZE) + +#define KDF_MODE_SOURCE_MASK ((uint8_t)0x03) //!< KDF mode source key mask +#define KDF_MODE_SOURCE_TEMPKEY ((uint8_t)0x00) //!< KDF mode source key in TempKey +#define KDF_MODE_SOURCE_TEMPKEY_UP ((uint8_t)0x01) //!< KDF mode source key in upper TempKey +#define KDF_MODE_SOURCE_SLOT ((uint8_t)0x02) //!< KDF mode source key in a slot +#define KDF_MODE_SOURCE_ALTKEYBUF ((uint8_t)0x03) //!< KDF mode source key in alternate key buffer + +#define KDF_MODE_TARGET_MASK ((uint8_t)0x1C) //!< KDF mode target key mask +#define KDF_MODE_TARGET_TEMPKEY ((uint8_t)0x00) //!< KDF mode target key in TempKey +#define KDF_MODE_TARGET_TEMPKEY_UP ((uint8_t)0x04) //!< KDF mode target key in upper TempKey +#define KDF_MODE_TARGET_SLOT ((uint8_t)0x08) //!< KDF mode target key in slot +#define KDF_MODE_TARGET_ALTKEYBUF ((uint8_t)0x0C) //!< KDF mode target key in alternate key buffer +#define KDF_MODE_TARGET_OUTPUT ((uint8_t)0x10) //!< KDF mode target key in output buffer +#define KDF_MODE_TARGET_OUTPUT_ENC ((uint8_t)0x14) //!< KDF mode target key encrypted in output buffer + +#define KDF_MODE_ALG_MASK ((uint8_t)0x60) //!< KDF mode algorithm mask +#define KDF_MODE_ALG_PRF ((uint8_t)0x00) //!< KDF mode PRF algorithm +#define KDF_MODE_ALG_AES ((uint8_t)0x20) //!< KDF mode AES algorithm +#define KDF_MODE_ALG_HKDF ((uint8_t)0x40) //!< KDF mode HKDF algorithm + +#define KDF_DETAILS_PRF_KEY_LEN_MASK ((uint32_t)0x00000003) //!< KDF details for PRF, source key length mask +#define KDF_DETAILS_PRF_KEY_LEN_16 ((uint32_t)0x00000000) //!< KDF details for PRF, source key length is 16 bytes +#define KDF_DETAILS_PRF_KEY_LEN_32 ((uint32_t)0x00000001) //!< KDF details for PRF, source key length is 32 bytes +#define KDF_DETAILS_PRF_KEY_LEN_48 ((uint32_t)0x00000002) //!< KDF details for PRF, source key length is 48 bytes +#define KDF_DETAILS_PRF_KEY_LEN_64 ((uint32_t)0x00000003) //!< KDF details for PRF, source key length is 64 bytes + +#define KDF_DETAILS_PRF_TARGET_LEN_MASK ((uint32_t)0x00000100) //!< KDF details for PRF, target length mask +#define KDF_DETAILS_PRF_TARGET_LEN_32 ((uint32_t)0x00000000) //!< KDF details for PRF, target length is 32 bytes +#define KDF_DETAILS_PRF_TARGET_LEN_64 ((uint32_t)0x00000100) //!< KDF details for PRF, target length is 64 bytes + +#define KDF_DETAILS_PRF_AEAD_MASK ((uint32_t)0x00000600) //!< KDF details for PRF, AEAD processing mask +#define KDF_DETAILS_PRF_AEAD_MODE0 ((uint32_t)0x00000000) //!< KDF details for PRF, AEAD no processing +#define KDF_DETAILS_PRF_AEAD_MODE1 ((uint32_t)0x00000200) //!< KDF details for PRF, AEAD First 32 go to target, second 32 go to output buffer + +#define KDF_DETAILS_AES_KEY_LOC_MASK ((uint32_t)0x00000003) //!< KDF details for AES, key location mask + +#define KDF_DETAILS_HKDF_MSG_LOC_MASK ((uint32_t)0x00000003) //!< KDF details for HKDF, message location mask +#define KDF_DETAILS_HKDF_MSG_LOC_SLOT ((uint32_t)0x00000000) //!< KDF details for HKDF, message location in slot +#define KDF_DETAILS_HKDF_MSG_LOC_TEMPKEY ((uint32_t)0x00000001) //!< KDF details for HKDF, message location in TempKey +#define KDF_DETAILS_HKDF_MSG_LOC_INPUT ((uint32_t)0x00000002) //!< KDF details for HKDF, message location in input parameter +#define KDF_DETAILS_HKDF_MSG_LOC_IV ((uint32_t)0x00000003) //!< KDF details for HKDF, message location is a special IV function +#define KDF_DETAILS_HKDF_ZERO_KEY ((uint32_t)0x00000004) //!< KDF details for HKDF, key is 32 bytes of zero +/** @} */ + +/** \name Definitions for the Lock Command + @{ */ +#define LOCK_ZONE_IDX ATCA_PARAM1_IDX //!< Lock command index for zone +#define LOCK_SUMMARY_IDX ATCA_PARAM2_IDX //!< Lock command index for summary +#define LOCK_COUNT ATCA_CMD_SIZE_MIN //!< Lock command packet size +#define LOCK_ZONE_CONFIG ((uint8_t)0x00) //!< Lock zone is Config +#define LOCK_ZONE_DATA ((uint8_t)0x01) //!< Lock zone is OTP or Data +#define LOCK_ZONE_DATA_SLOT ((uint8_t)0x02) //!< Lock slot of Data +#define LOCK_ZONE_NO_CRC ((uint8_t)0x80) //!< Lock command: Ignore summary. +#define LOCK_ZONE_MASK (0xBF) //!< Lock parameter 1 bits 6 are 0. +#define ATCA_UNLOCKED (0x55) //!< Value indicating an unlocked zone +#define ATCA_LOCKED (0x00) //!< Value indicating a locked zone +#define LOCK_RSP_SIZE ATCA_RSP_SIZE_MIN //!< Lock command response packet size +/** @} */ + +/** \name Definitions for the MAC Command + @{ */ +#define MAC_MODE_IDX ATCA_PARAM1_IDX //!< MAC command index for mode +#define MAC_KEYID_IDX ATCA_PARAM2_IDX //!< MAC command index for key id +#define MAC_CHALLENGE_IDX ATCA_DATA_IDX //!< MAC command index for optional challenge +#define MAC_COUNT_SHORT ATCA_CMD_SIZE_MIN //!< MAC command packet size without challenge +#define MAC_COUNT_LONG (39) //!< MAC command packet size with challenge +#define MAC_MODE_CHALLENGE ((uint8_t)0x00) //!< MAC mode 0: first SHA block from data slot +#define MAC_MODE_BLOCK2_TEMPKEY ((uint8_t)0x01) //!< MAC mode bit 0: second SHA block from TempKey +#define MAC_MODE_BLOCK1_TEMPKEY ((uint8_t)0x02) //!< MAC mode bit 1: first SHA block from TempKey +#define MAC_MODE_SOURCE_FLAG_MATCH ((uint8_t)0x04) //!< MAC mode bit 2: match TempKey.SourceFlag +#define MAC_MODE_PTNONCE_TEMPKEY ((uint8_t)0x06) //!< MAC mode bit 0: second SHA block from TempKey +#define MAC_MODE_PASSTHROUGH ((uint8_t)0x07) //!< MAC mode bit 0-2: pass-through mode +#define MAC_MODE_INCLUDE_OTP_88 ((uint8_t)0x10) //!< MAC mode bit 4: include first 88 OTP bits +#define MAC_MODE_INCLUDE_OTP_64 ((uint8_t)0x20) //!< MAC mode bit 5: include first 64 OTP bits +#define MAC_MODE_INCLUDE_SN ((uint8_t)0x40) //!< MAC mode bit 6: include serial number +#define MAC_CHALLENGE_SIZE (32) //!< MAC size of challenge +#define MAC_SIZE (32) //!< MAC size of response +#define MAC_MODE_MASK ((uint8_t)0x77) //!< MAC mode bits 3 and 7 are 0. +#define MAC_RSP_SIZE ATCA_RSP_SIZE_32 //!< MAC command response packet size +/** @} */ + +/** \name Definitions for the Nonce Command + @{ */ +#define NONCE_MODE_IDX ATCA_PARAM1_IDX //!< Nonce command index for mode +#define NONCE_PARAM2_IDX ATCA_PARAM2_IDX //!< Nonce command index for 2. parameter +#define NONCE_INPUT_IDX ATCA_DATA_IDX //!< Nonce command index for input data +#define NONCE_COUNT_SHORT (ATCA_CMD_SIZE_MIN + 20) //!< Nonce command packet size for 20 bytes of NumIn +#define NONCE_COUNT_LONG (ATCA_CMD_SIZE_MIN + 32) //!< Nonce command packet size for 32 bytes of NumIn +#define NONCE_COUNT_LONG_64 (ATCA_CMD_SIZE_MIN + 64) //!< Nonce command packet size for 64 bytes of NumIn +#define NONCE_MODE_MASK ((uint8_t)0x03) //!< Nonce mode bits 2 to 7 are 0. +#define NONCE_MODE_SEED_UPDATE ((uint8_t)0x00) //!< Nonce mode: update seed +#define NONCE_MODE_NO_SEED_UPDATE ((uint8_t)0x01) //!< Nonce mode: do not update seed +#define NONCE_MODE_INVALID ((uint8_t)0x02) //!< Nonce mode 2 is invalid. +#define NONCE_MODE_PASSTHROUGH ((uint8_t)0x03) //!< Nonce mode: pass-through + +#define NONCE_MODE_INPUT_LEN_MASK ((uint8_t)0x20) //!< Nonce mode: input size mask +#define NONCE_MODE_INPUT_LEN_32 ((uint8_t)0x00) //!< Nonce mode: input size is 32 bytes +#define NONCE_MODE_INPUT_LEN_64 ((uint8_t)0x20) //!< Nonce mode: input size is 64 bytes + +#define NONCE_MODE_TARGET_MASK ((uint8_t)0xC0) //!< Nonce mode: target mask +#define NONCE_MODE_TARGET_TEMPKEY ((uint8_t)0x00) //!< Nonce mode: target is TempKey +#define NONCE_MODE_TARGET_MSGDIGBUF ((uint8_t)0x40) //!< Nonce mode: target is Message Digest Buffer +#define NONCE_MODE_TARGET_ALTKEYBUF ((uint8_t)0x80) //!< Nonce mode: target is Alternate Key Buffer + +#define NONCE_ZERO_CALC_MASK ((uint16_t)0x8000) //!< Nonce zero (param2): calculation mode mask +#define NONCE_ZERO_CALC_RANDOM ((uint16_t)0x0000) //!< Nonce zero (param2): calculation mode random, use RNG in calculation and return RNG output +#define NONCE_ZERO_CALC_TEMPKEY ((uint16_t)0x8000) //!< Nonce zero (param2): calculation mode TempKey, use TempKey in calculation and return new TempKey value + +#define NONCE_NUMIN_SIZE (20) //!< Nonce NumIn size for random modes +#define NONCE_NUMIN_SIZE_PASSTHROUGH (32) //!< Nonce NumIn size for 32-byte pass-through mode + +#define NONCE_RSP_SIZE_SHORT ATCA_RSP_SIZE_MIN //!< Nonce command response packet size with no output +#define NONCE_RSP_SIZE_LONG ATCA_RSP_SIZE_32 //!< Nonce command response packet size with output +/** @} */ + +/** \name Definitions for the Pause Command + @{ */ +#define PAUSE_SELECT_IDX ATCA_PARAM1_IDX //!< Pause command index for Selector +#define PAUSE_PARAM2_IDX ATCA_PARAM2_IDX //!< Pause command index for 2. parameter +#define PAUSE_COUNT ATCA_CMD_SIZE_MIN //!< Pause command packet size +#define PAUSE_RSP_SIZE ATCA_RSP_SIZE_MIN //!< Pause command response packet size +/** @} */ + +/** \name Definitions for the PrivWrite Command + @{ */ +#define PRIVWRITE_ZONE_IDX ATCA_PARAM1_IDX //!< PrivWrite command index for zone +#define PRIVWRITE_KEYID_IDX ATCA_PARAM2_IDX //!< PrivWrite command index for KeyID +#define PRIVWRITE_VALUE_IDX ( 5) //!< PrivWrite command index for value +#define PRIVWRITE_MAC_IDX (41) //!< PrivWrite command index for MAC +#define PRIVWRITE_COUNT (75) //!< PrivWrite command packet size +#define PRIVWRITE_ZONE_MASK ((uint8_t)0x40) //!< PrivWrite zone bits 0 to 5 and 7 are 0. +#define PRIVWRITE_MODE_ENCRYPT ((uint8_t)0x40) //!< PrivWrite mode: encrypted +#define PRIVWRITE_RSP_SIZE ATCA_RSP_SIZE_MIN //!< PrivWrite command response packet size +/** @} */ + +/** \name Definitions for the Random Command + @{ */ +#define RANDOM_MODE_IDX ATCA_PARAM1_IDX //!< Random command index for mode +#define RANDOM_PARAM2_IDX ATCA_PARAM2_IDX //!< Random command index for 2. parameter +#define RANDOM_COUNT ATCA_CMD_SIZE_MIN //!< Random command packet size +#define RANDOM_SEED_UPDATE ((uint8_t)0x00) //!< Random mode for automatic seed update +#define RANDOM_NO_SEED_UPDATE ((uint8_t)0x01) //!< Random mode for no seed update +#define RANDOM_NUM_SIZE ((uint8_t)32) //!< Number of bytes in the data packet of a random command +#define RANDOM_RSP_SIZE ATCA_RSP_SIZE_32 //!< Random command response packet size +/** @} */ + +/** \name Definitions for the Read Command + @{ */ +#define READ_ZONE_IDX ATCA_PARAM1_IDX //!< Read command index for zone +#define READ_ADDR_IDX ATCA_PARAM2_IDX //!< Read command index for address +#define READ_COUNT ATCA_CMD_SIZE_MIN //!< Read command packet size +#define READ_ZONE_MASK ((uint8_t)0x83) //!< Read zone bits 2 to 6 are 0. +#define READ_4_RSP_SIZE ATCA_RSP_SIZE_VAL //!< Read command response packet size when reading 4 bytes +#define READ_32_RSP_SIZE ATCA_RSP_SIZE_32 //!< Read command response packet size when reading 32 bytes +/** @} */ + +/** \name Definitions for the SecureBoot Command + @{ */ +#define SECUREBOOT_MODE_IDX ATCA_PARAM1_IDX //!< SecureBoot command index for mode +#define SECUREBOOT_DIGEST_SIZE (32) //!< SecureBoot digest input size +#define SECUREBOOT_SIGNATURE_SIZE (64) //!< SecureBoot signature input size +#define SECUREBOOT_COUNT_DIG (ATCA_CMD_SIZE_MIN + SECUREBOOT_DIGEST_SIZE) //!< SecureBoot command packet size for just a digest +#define SECUREBOOT_COUNT_DIG_SIG (ATCA_CMD_SIZE_MIN + SECUREBOOT_DIGEST_SIZE + SECUREBOOT_SIGNATURE_SIZE) //!< SecureBoot command packet size for a digest and signature +#define SECUREBOOT_MAC_SIZE (32) //!< SecureBoot MAC output size +#define SECUREBOOT_RSP_SIZE_NO_MAC ATCA_RSP_SIZE_MIN //!< SecureBoot response packet size for no MAC +#define SECUREBOOT_RSP_SIZE_MAC (ATCA_PACKET_OVERHEAD + SECUREBOOT_MAC_SIZE) //!< SecureBoot response packet size with MAC + +#define SECUREBOOT_MODE_MASK ((uint8_t)0x07) //!< SecureBoot mode mask +#define SECUREBOOT_MODE_FULL ((uint8_t)0x05) //!< SecureBoot mode Full +#define SECUREBOOT_MODE_FULL_STORE ((uint8_t)0x06) //!< SecureBoot mode FullStore +#define SECUREBOOT_MODE_FULL_COPY ((uint8_t)0x07) //!< SecureBoot mode FullCopy +#define SECUREBOOT_MODE_PROHIBIT_FLAG ((uint8_t)0x40) //!< SecureBoot mode flag to prohibit SecureBoot until next power cycle +#define SECUREBOOT_MODE_ENC_MAC_FLAG ((uint8_t)0x80) //!< SecureBoot mode flag for encrypted digest and returning validating MAC + +#define SECUREBOOTCONFIG_OFFSET (70) //!< SecureBootConfig byte offset into the configuration zone +#define SECUREBOOTCONFIG_MODE_MASK ((uint16_t)0x0003) //!< Mask for SecureBootMode field in SecureBootConfig value +#define SECUREBOOTCONFIG_MODE_DISABLED ((uint16_t)0x0000) //!< Disabled SecureBootMode in SecureBootConfig value +#define SECUREBOOTCONFIG_MODE_FULL_BOTH ((uint16_t)0x0001) //!< Both digest and signature always required SecureBootMode in SecureBootConfig value +#define SECUREBOOTCONFIG_MODE_FULL_SIG ((uint16_t)0x0002) //!< Signature stored SecureBootMode in SecureBootConfig value +#define SECUREBOOTCONFIG_MODE_FULL_DIG ((uint16_t)0x0003) //!< Digest stored SecureBootMode in SecureBootConfig value +/** @} */ + +/** \name Definitions for the SelfTest Command + @{ */ +#define SELFTEST_MODE_IDX ATCA_PARAM1_IDX //!< SelfTest command index for mode +#define SELFTEST_COUNT ATCA_CMD_SIZE_MIN //!< SelfTest command packet size +#define SELFTEST_MODE_RNG ((uint8_t)0x01) //!< SelfTest mode RNG DRBG function +#define SELFTEST_MODE_ECDSA_SIGN_VERIFY ((uint8_t)0x02) //!< SelfTest mode ECDSA verify function +#define SELFTEST_MODE_ECDH ((uint8_t)0x08) //!< SelfTest mode ECDH function +#define SELFTEST_MODE_AES ((uint8_t)0x10) //!< SelfTest mode AES encrypt function +#define SELFTEST_MODE_SHA ((uint8_t)0x20) //!< SelfTest mode SHA function +#define SELFTEST_MODE_ALL ((uint8_t)0x3B) //!< SelfTest mode all algorithms +#define SELFTEST_RSP_SIZE ATCA_RSP_SIZE_MIN //!< SelfTest command response packet size +/** @} */ + +/** \name Definitions for the SHA Command + @{ */ +#define SHA_COUNT_SHORT ATCA_CMD_SIZE_MIN +#define SHA_COUNT_LONG ATCA_CMD_SIZE_MIN //!< Just a starting size +#define ATCA_SHA_DIGEST_SIZE (32) +#define SHA_DATA_MAX (64) +#define ATCA_SHA256_BLOCK_SIZE (64) +#define SHA_CONTEXT_MAX_SIZE (99) + +#define SHA_MODE_MASK ((uint8_t)0x07) //!< Mask the bit 0-2 +#define SHA_MODE_SHA256_START ((uint8_t)0x00) //!< Initialization, does not accept a message +#define SHA_MODE_SHA256_UPDATE ((uint8_t)0x01) //!< Add 64 bytes in the meesage to the SHA context +#define SHA_MODE_SHA256_END ((uint8_t)0x02) //!< Complete the calculation and return the digest +#define SHA_MODE_SHA256_PUBLIC ((uint8_t)0x03) //!< Add 64 byte ECC public key in the slot to the SHA context +#define SHA_MODE_HMAC_START ((uint8_t)0x04) //!< Initialization, HMAC calculation +#define SHA_MODE_HMAC_UPDATE ((uint8_t)0x01) //!< Add 64 bytes in the meesage to the SHA context +#define SHA_MODE_HMAC_END ((uint8_t)0x05) //!< Complete the HMAC computation and return digest +#define SHA_MODE_608_HMAC_END ((uint8_t)0x02) //!< Complete the HMAC computation and return digest... Different command on 608 +#define SHA_MODE_READ_CONTEXT ((uint8_t)0x06) //!< Read current SHA-256 context out of the device +#define SHA_MODE_WRITE_CONTEXT ((uint8_t)0x07) //!< Restore a SHA-256 context into the device +#define SHA_MODE_TARGET_MASK ((uint8_t)0xC0) //!< Resulting digest target location mask +#define SHA_MODE_TARGET_TEMPKEY ((uint8_t)0x00) //!< Place resulting digest both in Output buffer and TempKey +#define SHA_MODE_TARGET_MSGDIGBUF ((uint8_t)0x40) //!< Place resulting digest both in Output buffer and Message Digest Buffer +#define SHA_MODE_TARGET_OUT_ONLY ((uint8_t)0xC0) //!< Place resulting digest both in Output buffer ONLY + +#define SHA_RSP_SIZE ATCA_RSP_SIZE_32 //!< SHA command response packet size +#define SHA_RSP_SIZE_SHORT ATCA_RSP_SIZE_MIN //!< SHA command response packet size only status code +#define SHA_RSP_SIZE_LONG ATCA_RSP_SIZE_32 //!< SHA command response packet size +/** @} */ + +/** @} *//** \name Definitions for the Sign Command + @{ */ +#define SIGN_MODE_IDX ATCA_PARAM1_IDX //!< Sign command index for mode +#define SIGN_KEYID_IDX ATCA_PARAM2_IDX //!< Sign command index for key id +#define SIGN_COUNT ATCA_CMD_SIZE_MIN //!< Sign command packet size +#define SIGN_MODE_MASK ((uint8_t)0xE1) //!< Sign mode bits 1 to 4 are 0 +#define SIGN_MODE_INTERNAL ((uint8_t)0x00) //!< Sign mode 0: internal +#define SIGN_MODE_INVALIDATE ((uint8_t)0x01) //!< Sign mode bit 1: Signature will be used for Verify(Invalidate) +#define SIGN_MODE_INCLUDE_SN ((uint8_t)0x40) //!< Sign mode bit 6: include serial number +#define SIGN_MODE_EXTERNAL ((uint8_t)0x80) //!< Sign mode bit 7: external +#define SIGN_MODE_SOURCE_MASK ((uint8_t)0x20) //!< Sign mode message source mask +#define SIGN_MODE_SOURCE_TEMPKEY ((uint8_t)0x00) //!< Sign mode message source is TempKey +#define SIGN_MODE_SOURCE_MSGDIGBUF ((uint8_t)0x20) //!< Sign mode message source is the Message Digest Buffer +#define SIGN_RSP_SIZE ATCA_RSP_SIZE_MAX //!< Sign command response packet size +/** @} */ + +/** \name Definitions for the UpdateExtra Command + @{ */ +#define UPDATE_MODE_IDX ATCA_PARAM1_IDX //!< UpdateExtra command index for mode +#define UPDATE_VALUE_IDX ATCA_PARAM2_IDX //!< UpdateExtra command index for new value +#define UPDATE_COUNT ATCA_CMD_SIZE_MIN //!< UpdateExtra command packet size +#define UPDATE_MODE_USER_EXTRA ((uint8_t)0x00) //!< UpdateExtra mode update UserExtra (config byte 84) +#define UPDATE_MODE_SELECTOR ((uint8_t)0x01) //!< UpdateExtra mode update Selector (config byte 85) +#define UPDATE_MODE_USER_EXTRA_ADD UPDATE_MODE_SELECTOR //!< UpdateExtra mode update UserExtraAdd (config byte 85) +#define UPDATE_MODE_DEC_COUNTER ((uint8_t)0x02) //!< UpdateExtra mode: decrement counter +#define UPDATE_RSP_SIZE ATCA_RSP_SIZE_MIN //!< UpdateExtra command response packet size +/** @} */ + +/** \name Definitions for the Verify Command + @{ */ +#define VERIFY_MODE_IDX ATCA_PARAM1_IDX //!< Verify command index for mode +#define VERIFY_KEYID_IDX ATCA_PARAM2_IDX //!< Verify command index for key id +#define VERIFY_DATA_IDX ( 5) //!< Verify command index for data +#define VERIFY_256_STORED_COUNT ( 71) //!< Verify command packet size for 256-bit key in stored mode +#define VERIFY_283_STORED_COUNT ( 79) //!< Verify command packet size for 283-bit key in stored mode +#define VERIFY_256_VALIDATE_COUNT ( 90) //!< Verify command packet size for 256-bit key in validate mode +#define VERIFY_283_VALIDATE_COUNT ( 98) //!< Verify command packet size for 283-bit key in validate mode +#define VERIFY_256_EXTERNAL_COUNT (135) //!< Verify command packet size for 256-bit key in external mode +#define VERIFY_283_EXTERNAL_COUNT (151) //!< Verify command packet size for 283-bit key in external mode +#define VERIFY_256_KEY_SIZE ( 64) //!< Verify key size for 256-bit key +#define VERIFY_283_KEY_SIZE ( 72) //!< Verify key size for 283-bit key +#define VERIFY_256_SIGNATURE_SIZE ( 64) //!< Verify signature size for 256-bit key +#define VERIFY_283_SIGNATURE_SIZE ( 72) //!< Verify signature size for 283-bit key +#define VERIFY_OTHER_DATA_SIZE ( 19) //!< Verify size of "other data" +#define VERIFY_MODE_MASK ((uint8_t)0x03) //!< Verify mode bits 2 to 7 are 0 +#define VERIFY_MODE_STORED ((uint8_t)0x00) //!< Verify mode: stored +#define VERIFY_MODE_VALIDATE_EXTERNAL ((uint8_t)0x01) //!< Verify mode: validate external +#define VERIFY_MODE_EXTERNAL ((uint8_t)0x02) //!< Verify mode: external +#define VERIFY_MODE_VALIDATE ((uint8_t)0x03) //!< Verify mode: validate +#define VERIFY_MODE_INVALIDATE ((uint8_t)0x07) //!< Verify mode: invalidate +#define VERIFY_MODE_SOURCE_MASK ((uint8_t)0x20) //!< Verify mode message source mask +#define VERIFY_MODE_SOURCE_TEMPKEY ((uint8_t)0x00) //!< Verify mode message source is TempKey +#define VERIFY_MODE_SOURCE_MSGDIGBUF ((uint8_t)0x20) //!< Verify mode message source is the Message Digest Buffer +#define VERIFY_MODE_MAC_FLAG ((uint8_t)0x80) //!< Verify mode: MAC +#define VERIFY_KEY_B283 ((uint16_t)0x0000) //!< Verify key type: B283 +#define VERIFY_KEY_K283 ((uint16_t)0x0001) //!< Verify key type: K283 +#define VERIFY_KEY_P256 ((uint16_t)0x0004) //!< Verify key type: P256 +#define VERIFY_RSP_SIZE ATCA_RSP_SIZE_MIN //!< Verify command response packet size +#define VERIFY_RSP_SIZE_MAC ATCA_RSP_SIZE_32 //!< Verify command response packet size with validating MAC +/** @} */ + +/** \name Definitions for the Write Command + @{ */ +#define WRITE_ZONE_IDX ATCA_PARAM1_IDX //!< Write command index for zone +#define WRITE_ADDR_IDX ATCA_PARAM2_IDX //!< Write command index for address +#define WRITE_VALUE_IDX ATCA_DATA_IDX //!< Write command index for data +#define WRITE_MAC_VS_IDX ( 9) //!< Write command index for MAC following short data +#define WRITE_MAC_VL_IDX (37) //!< Write command index for MAC following long data +#define WRITE_MAC_SIZE (32) //!< Write MAC size +#define WRITE_ZONE_MASK ((uint8_t)0xC3) //!< Write zone bits 2 to 5 are 0. +#define WRITE_ZONE_WITH_MAC ((uint8_t)0x40) //!< Write zone bit 6: write encrypted with MAC +#define WRITE_ZONE_OTP ((uint8_t)1) //!< Write zone id OTP +#define WRITE_ZONE_DATA ((uint8_t)2) //!< Write zone id data +#define WRITE_RSP_SIZE ATCA_RSP_SIZE_MIN //!< Write command response packet size +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_compiler.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_compiler.h new file mode 100644 index 0000000..3955372 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_compiler.h @@ -0,0 +1,88 @@ +/** + * \file + * \brief CryptoAuthLiub is meant to be portable across architectures, even + * non-Microchip architectures and compiler environments. This file is + * for isolating compiler specific macros. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +#ifndef ATCA_COMPILER_H_ +#define ATCA_COMPILER_H_ + +#if defined(__clang__) +/* Clang/LLVM. ---------------------------------------------- */ +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define ATCA_UINT32_HOST_TO_BE(x) (x) +#define ATCA_UINT32_BE_TO_HOST(x) (x) +#define ATCA_UINT64_HOST_TO_BE(x) (x) +#define ATCA_UINT64_BE_TO_HOST(x) (x) +#else +#define ATCA_UINT32_HOST_TO_BE(x) __builtin_bswap32(x) +#define ATCA_UINT32_BE_TO_HOST(x) __builtin_bswap32(x) +#define ATCA_UINT64_HOST_TO_BE(x) __builtin_bswap64(x) +#define ATCA_UINT64_BE_TO_HOST(x) __builtin_bswap64(x) +#endif + +#elif defined(__ICC) || defined(__INTEL_COMPILER) +/* Intel ICC/ICPC. ------------------------------------------ */ + +#elif defined(__GNUC__) || defined(__GNUG__) +/* GNU GCC/G++. --------------------------------------------- */ +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define ATCA_UINT32_HOST_TO_BE(x) (x) +#define ATCA_UINT32_BE_TO_HOST(x) (x) +#define ATCA_UINT64_HOST_TO_BE(x) (x) +#define ATCA_UINT64_BE_TO_HOST(x) (x) +#else +#define ATCA_UINT32_HOST_TO_BE(x) __builtin_bswap32(x) +#define ATCA_UINT32_BE_TO_HOST(x) __builtin_bswap32(x) +#define ATCA_UINT64_HOST_TO_BE(x) __builtin_bswap64(x) +#define ATCA_UINT64_BE_TO_HOST(x) __builtin_bswap64(x) +#endif + +#elif defined(__HP_cc) || defined(__HP_aCC) +/* Hewlett-Packard C/aC++. ---------------------------------- */ + +#elif defined(__IBMC__) || defined(__IBMCPP__) +/* IBM XL C/C++. -------------------------------------------- */ + +#elif defined(_MSC_VER) +/* Microsoft Visual Studio. --------------------------------- */ +// MSVC is usually always little-endian architecture +#include +#define ATCA_UINT32_HOST_TO_BE(x) _byteswap_ulong(x) +#define ATCA_UINT32_BE_TO_HOST(x) _byteswap_ulong(x) +#define ATCA_UINT64_HOST_TO_BE(x) _byteswap_uint64(x) +#define ATCA_UINT64_BE_TO_HOST(x) _byteswap_uint64(x) + +#elif defined(__PGI) +/* Portland Group PGCC/PGCPP. ------------------------------- */ + +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +/* Oracle Solaris Studio. ----------------------------------- */ + +#endif + +#endif /* ATCA_COMPILER_H_ */ diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.c new file mode 100644 index 0000000..5492c6a --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.c @@ -0,0 +1,174 @@ +/** + * \file + * \brief Microchip CryptoAuth device object + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include +#include "atca_device.h" + +/** \defgroup device ATCADevice (atca_) + * \brief ATCADevice object - composite of command and interface objects + @{ */ + + +#ifndef ATCA_NO_HEAP +/** \brief constructor for a Microchip CryptoAuth device + * \param[in] cfg Interface configuration object + * \return Reference to a new ATCADevice on success. NULL on failure. + */ +ATCADevice newATCADevice(ATCAIfaceCfg *cfg) +{ + ATCADevice ca_dev = NULL; + ATCA_STATUS status; + + if (cfg == NULL) + { + return NULL; + } + + ca_dev = (ATCADevice)malloc(sizeof(*ca_dev)); + if (ca_dev == NULL) + { + return NULL; + } + + ca_dev->mCommands = (ATCACommand)malloc(sizeof(*(ca_dev->mCommands))); + if (ca_dev->mCommands == NULL) + { + free(ca_dev); + ca_dev = NULL; + return NULL; + } + + ca_dev->mIface = (ATCAIface)malloc(sizeof(*(ca_dev->mIface))); + if (ca_dev->mIface == NULL) + { + free(ca_dev->mCommands); + free(ca_dev); + ca_dev = NULL; + return NULL; + } + + status = initATCADevice(cfg, ca_dev); + if (status != ATCA_SUCCESS) + { + free(ca_dev->mIface); + free(ca_dev->mCommands); + free(ca_dev); + ca_dev = NULL; + return NULL; + } + + return ca_dev; +} + +/** \brief destructor for a device NULLs reference after object is freed + * \param[in] ca_dev pointer to a reference to a device + */ +void deleteATCADevice(ATCADevice *ca_dev) +{ + if (ca_dev == NULL) + { + return; + } + + releaseATCADevice(*ca_dev); + deleteATCACommand(&(*ca_dev)->mCommands); + // Free iface manually as we don't want to call releaseATCAIface twice + if ((*ca_dev)->mIface) + { + free((*ca_dev)->mIface); + (*ca_dev)->mIface = NULL; + } + + free(*ca_dev); + *ca_dev = NULL; +} +#endif + +/** \brief Initializer for an Microchip CryptoAuth device + * \param[in] cfg pointer to an interface configuration object + * \param[inout] ca_dev As input, pre-allocated structure to be initialized. + * mCommands and mIface members should point to existing + * structures to be initialized. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS initATCADevice(ATCAIfaceCfg *cfg, ATCADevice ca_dev) +{ + ATCA_STATUS status; + + if (cfg == NULL || ca_dev == NULL || ca_dev->mCommands == NULL || ca_dev->mIface == NULL) + { + return ATCA_BAD_PARAM; + } + + status = initATCACommand(cfg->devtype, ca_dev->mCommands); + if (status != ATCA_SUCCESS) + { + return status; + } + + status = initATCAIface(cfg, ca_dev->mIface); + if (status != ATCA_SUCCESS) + { + return status; + } + + return ATCA_SUCCESS; +} + +/** \brief returns a reference to the ATCACommand object for the device + * \param[in] dev reference to a device + * \return reference to the ATCACommand object for the device + */ +ATCACommand atGetCommands(ATCADevice dev) +{ + return dev->mCommands; +} + +/** \brief returns a reference to the ATCAIface interface object for the device + * \param[in] dev reference to a device + * \return reference to the ATCAIface object for the device + */ +ATCAIface atGetIFace(ATCADevice dev) +{ + return dev->mIface; +} + +/** \brief Release any resources associated with the device. + * \param[in] ca_dev Device to release + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS releaseATCADevice(ATCADevice ca_dev) +{ + if (ca_dev == NULL) + { + return ATCA_BAD_PARAM; + } + + return releaseATCAIface(ca_dev->mIface); +} + +/** @} */ diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.h new file mode 100644 index 0000000..15fa544 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.h @@ -0,0 +1,66 @@ +/** + * \file + * + * \brief Microchip Crypto Auth device object + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef ATCA_DEVICE_H +#define ATCA_DEVICE_H + +#include "atca_command.h" +#include "atca_iface.h" +/** \defgroup device ATCADevice (atca_) + @{ */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \brief atca_device is the C object backing ATCADevice. See the + * atca_device.h file for details on the ATCADevice methods. + */ +struct atca_device +{ + ATCACommand mCommands; //!< Command set for a given CryptoAuth device + ATCAIface mIface; //!< Physical interface +}; + +typedef struct atca_device * ATCADevice; + +ATCA_STATUS initATCADevice(ATCAIfaceCfg* cfg, ATCADevice cadev); +ATCADevice newATCADevice(ATCAIfaceCfg *cfg); +ATCA_STATUS releaseATCADevice(ATCADevice ca_dev); +void deleteATCADevice(ATCADevice *ca_dev); + +ATCACommand atGetCommands(ATCADevice dev); +ATCAIface atGetIFace(ATCADevice dev); + + + +#ifdef __cplusplus +} +#endif +/** @} */ +#endif diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_devtypes.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_devtypes.h new file mode 100644 index 0000000..6c34266 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_devtypes.h @@ -0,0 +1,54 @@ +/** + * \file + * \brief Microchip Crypto Auth + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +#ifndef ATCA_DEVTYPES_H_ +#define ATCA_DEVTYPES_H_ + +/** \defgroup device ATCADevice (atca_) + @{ */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \brief The supported Device type in Cryptoauthlib library */ +typedef enum +{ + ATSHA204A, + ATECC108A, + ATECC508A, + ATECC608A, + ATCA_DEV_UNKNOWN = 0x20 +} ATCADeviceType; + +#ifdef __cplusplus +} +#endif +/** @} */ +#endif /* ATCA_DEVTYPES_H_ */ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.c new file mode 100644 index 0000000..d3ad6f6 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.c @@ -0,0 +1,372 @@ +/** + * \file + * \brief Implements an execution handler that executes a given command on a + * device and returns the results. + * + * This implementation wraps Polling and No polling (simple wait) schemes into + * a single method and use it across the library. Polling is used by default, + * however, by defining the ATCA_NO_POLL symbol the code will instead wait an + * estimated max execution time before requesting the result. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include +#include +#include "atca_command.h" +#include "atca_device.h" +#include "atca_execution.h" +#include "atca_devtypes.h" +#include "hal/atca_hal.h" + +#ifndef ATCA_POLLING_INIT_TIME_MSEC +#define ATCA_POLLING_INIT_TIME_MSEC 1 +#endif + +#ifndef ATCA_POLLING_FREQUENCY_TIME_MSEC +#define ATCA_POLLING_FREQUENCY_TIME_MSEC 2 +#endif + +#ifndef ATCA_POLLING_MAX_TIME_MSEC +#define ATCA_POLLING_MAX_TIME_MSEC 2500 +#endif + +#ifdef ATCA_NO_POLL +// *INDENT-OFF* - Preserve time formatting from the code formatter +/*Execution times for ATSHA204A supported commands...*/ +static const device_execution_time_t device_execution_time_204[] = { + { ATCA_CHECKMAC, 38}, + { ATCA_DERIVE_KEY, 62}, + { ATCA_GENDIG, 43}, + { ATCA_HMAC, 69}, + { ATCA_INFO, 2}, + { ATCA_LOCK, 24}, + { ATCA_MAC, 35}, + { ATCA_NONCE, 60}, + { ATCA_PAUSE, 2}, + { ATCA_RANDOM, 50}, + { ATCA_READ, 5}, + { ATCA_SHA, 22}, + { ATCA_UPDATE_EXTRA, 12}, + { ATCA_WRITE, 42} +}; + +/*Execution times for ATECC108A supported commands...*/ +static const device_execution_time_t device_execution_time_108[] = { + { ATCA_CHECKMAC, 13}, + { ATCA_COUNTER, 20}, + { ATCA_DERIVE_KEY, 50}, + { ATCA_GENDIG, 11}, + { ATCA_GENKEY, 115}, + { ATCA_HMAC, 23}, + { ATCA_INFO, 2}, + { ATCA_LOCK, 32}, + { ATCA_MAC, 14}, + { ATCA_NONCE, 29}, + { ATCA_PAUSE, 3}, + { ATCA_PRIVWRITE, 48}, + { ATCA_RANDOM, 23}, + { ATCA_READ, 5}, + { ATCA_SHA, 9}, + { ATCA_SIGN, 60}, + { ATCA_UPDATE_EXTRA, 10}, + { ATCA_VERIFY, 72}, + { ATCA_WRITE, 26} +}; + +/*Execution times for ATECC508A supported commands...*/ +static const device_execution_time_t device_execution_time_508[] = { + { ATCA_CHECKMAC, 13}, + { ATCA_COUNTER, 20}, + { ATCA_DERIVE_KEY, 50}, + { ATCA_ECDH, 58}, + { ATCA_GENDIG, 11}, + { ATCA_GENKEY, 115}, + { ATCA_HMAC, 23}, + { ATCA_INFO, 2}, + { ATCA_LOCK, 32}, + { ATCA_MAC, 14}, + { ATCA_NONCE, 29}, + { ATCA_PAUSE, 3}, + { ATCA_PRIVWRITE, 48}, + { ATCA_RANDOM, 23}, + { ATCA_READ, 5}, + { ATCA_SHA, 9}, + { ATCA_SIGN, 60}, + { ATCA_UPDATE_EXTRA, 10}, + { ATCA_VERIFY, 72}, + { ATCA_WRITE, 26} +}; + +/*Execution times for ATECC608A-M0 supported commands...*/ +static const device_execution_time_t device_execution_time_608_m0[] = { + { ATCA_AES, 27}, + { ATCA_CHECKMAC, 40}, + { ATCA_COUNTER, 25}, + { ATCA_DERIVE_KEY, 50}, + { ATCA_ECDH, 75}, + { ATCA_GENDIG, 25}, + { ATCA_GENKEY, 115}, + { ATCA_INFO, 5}, + { ATCA_KDF, 165}, + { ATCA_LOCK, 35}, + { ATCA_MAC, 55}, + { ATCA_NONCE, 20}, + { ATCA_PRIVWRITE, 50}, + { ATCA_RANDOM, 23}, + { ATCA_READ, 5}, + { ATCA_SECUREBOOT, 80}, + { ATCA_SELFTEST, 250}, + { ATCA_SHA, 36}, + { ATCA_SIGN, 115}, + { ATCA_UPDATE_EXTRA, 10}, + { ATCA_VERIFY, 105}, + { ATCA_WRITE, 45} +}; + +/*Execution times for ATECC608A-M1 supported commands...*/ +static const device_execution_time_t device_execution_time_608_m1[] = { + { ATCA_AES, 27}, + { ATCA_CHECKMAC, 40}, + { ATCA_COUNTER, 25}, + { ATCA_DERIVE_KEY, 50}, + { ATCA_ECDH, 172}, + { ATCA_GENDIG, 35}, + { ATCA_GENKEY, 215}, + { ATCA_INFO, 5}, + { ATCA_KDF, 165}, + { ATCA_LOCK, 35}, + { ATCA_MAC, 55}, + { ATCA_NONCE, 20}, + { ATCA_PRIVWRITE, 50}, + { ATCA_RANDOM, 23}, + { ATCA_READ, 5}, + { ATCA_SECUREBOOT, 160}, + { ATCA_SELFTEST, 625}, + { ATCA_SHA, 42}, + { ATCA_SIGN, 220}, + { ATCA_UPDATE_EXTRA, 10}, + { ATCA_VERIFY, 295}, + { ATCA_WRITE, 45} +}; + +/*Execution times for ATECC608A-M2 supported commands...*/ +static const device_execution_time_t device_execution_time_608_m2[] = { + { ATCA_AES, 27}, + { ATCA_CHECKMAC, 40}, + { ATCA_COUNTER, 25}, + { ATCA_DERIVE_KEY, 50}, + { ATCA_ECDH, 531}, + { ATCA_GENDIG, 35}, + { ATCA_GENKEY, 653}, + { ATCA_INFO, 5}, + { ATCA_KDF, 165}, + { ATCA_LOCK, 35}, + { ATCA_MAC, 55}, + { ATCA_NONCE, 20}, + { ATCA_PRIVWRITE, 50}, + { ATCA_RANDOM, 23}, + { ATCA_READ, 5}, + { ATCA_SECUREBOOT, 480}, + { ATCA_SELFTEST, 2324}, + { ATCA_SHA, 75}, + { ATCA_SIGN, 665}, + { ATCA_UPDATE_EXTRA, 10}, + { ATCA_VERIFY, 1085}, + { ATCA_WRITE, 45} +}; +// *INDENT-ON* +#endif + +#ifdef ATCA_NO_POLL +/** \brief return the typical execution time for the given command + * \param[in] opcode Opcode value of the command + * \param[in] ca_cmd Command object for which the execution times are associated + * \return ATCA_SUCCESS + */ +ATCA_STATUS atGetExecTime(uint8_t opcode, ATCACommand ca_cmd) +{ + ATCA_STATUS status = ATCA_SUCCESS; + const device_execution_time_t *execution_times; + uint8_t i, no_of_commands; + + + switch (ca_cmd->dt) + { + case ATSHA204A: + execution_times = device_execution_time_204; + no_of_commands = sizeof(device_execution_time_204) / sizeof(device_execution_time_t); + break; + + case ATECC108A: + execution_times = device_execution_time_108; + no_of_commands = sizeof(device_execution_time_108) / sizeof(device_execution_time_t); + break; + + case ATECC508A: + execution_times = device_execution_time_508; + no_of_commands = sizeof(device_execution_time_508) / sizeof(device_execution_time_t); + break; + + case ATECC608A: + if (ca_cmd->clock_divider == ATCA_CHIPMODE_CLOCK_DIV_M1) + { + execution_times = device_execution_time_608_m1; + no_of_commands = sizeof(device_execution_time_608_m1) / sizeof(device_execution_time_t); + } + else if (ca_cmd->clock_divider == ATCA_CHIPMODE_CLOCK_DIV_M2) + { + execution_times = device_execution_time_608_m2; + no_of_commands = sizeof(device_execution_time_608_m2) / sizeof(device_execution_time_t); + } + else + { + // Assume default M0 clock divider + execution_times = device_execution_time_608_m0; + no_of_commands = sizeof(device_execution_time_608_m0) / sizeof(device_execution_time_t); + } + break; + + default: + no_of_commands = 0; + execution_times = NULL; + break; + } + + ca_cmd->execution_time_msec = ATCA_UNSUPPORTED_CMD; + + for (i = 0; i < no_of_commands; i++) + { + if (execution_times[i].opcode == opcode) + { + ca_cmd->execution_time_msec = execution_times[i].execution_time_msec; + break; + } + } + + if (ca_cmd->execution_time_msec == ATCA_UNSUPPORTED_CMD) + { + status = ATCA_BAD_OPCODE; + } + + return status; +} +#endif + +/** \brief Wakes up device, sends the packet, waits for command completion, + * receives response, and puts the device into the idle state. + * + * \param[inout] packet As input, the packet to be sent. As output, the + * data buffer in the packet structure will contain the + * response. + * \param[in] device CryptoAuthentication device to send the command to. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atca_execute_command(ATCAPacket* packet, ATCADevice device) +{ + ATCA_STATUS status; + uint32_t execution_or_wait_time; + uint32_t max_delay_count; + uint16_t rxsize; + + do + { +#ifdef ATCA_NO_POLL + if ((status = atGetExecTime(packet->opcode, device->mCommands)) != ATCA_SUCCESS) + { + return status; + } + execution_or_wait_time = device->mCommands->execution_time_msec; + max_delay_count = 0; +#else + execution_or_wait_time = ATCA_POLLING_INIT_TIME_MSEC; + max_delay_count = ATCA_POLLING_MAX_TIME_MSEC / ATCA_POLLING_FREQUENCY_TIME_MSEC; +#endif + + if ((status = atwake(device->mIface)) != ATCA_SUCCESS) + { + break; + } + + // send the command + if ((status = atsend(device->mIface, (uint8_t*)packet, packet->txsize)) != ATCA_SUCCESS) + { + break; + } + + // Delay for execution time or initial wait before polling + atca_delay_ms(execution_or_wait_time); + + do + { + memset(packet->data, 0, sizeof(packet->data)); + // receive the response + rxsize = sizeof(packet->data); + if ((status = atreceive(device->mIface, packet->data, &rxsize)) == ATCA_SUCCESS) + { + break; + } + +#ifndef ATCA_NO_POLL + // delay for polling frequency time + atca_delay_ms(ATCA_POLLING_FREQUENCY_TIME_MSEC); +#endif + } + while (max_delay_count-- > 0); + if (status != ATCA_SUCCESS) + { + break; + } + + // Check response size + if (rxsize < 4) + { + if (rxsize > 0) + { + status = ATCA_RX_FAIL; + } + else + { + status = ATCA_RX_NO_RESPONSE; + } + break; + } + + if ((status = atCheckCrc(packet->data)) != ATCA_SUCCESS) + { + break; + } + + if ((status = isATCAError(packet->data)) != ATCA_SUCCESS) + { + break; + } + } + while (0); + + atidle(device->mIface); + return status; +} + +/** @} */ diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.h new file mode 100644 index 0000000..e8ae17c --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.h @@ -0,0 +1,68 @@ +/** + * \file + * \brief Defines an execution handler that executes a given command on a + * device and returns the results. + * + * The basic flow is to wake the device, send the command, wait/poll for + * completion, and finally receives the response from the device and does + * basic checks before returning to caller. + * + * This handler supports the ATSHA and ATECC device family. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +#ifndef ATCA_EXECUTION_H +#define ATCA_EXECUTION_H + +#include "atca_status.h" +#include "atca_command.h" +#include "atca_device.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ATCA_UNSUPPORTED_CMD ((uint16_t)0xFFFF) + +#ifdef ATCA_NO_POLL +/** \brief Structure to hold the device execution time and the opcode for the + * corresponding command + */ +typedef struct +{ + uint8_t opcode; + uint16_t execution_time_msec; +}device_execution_time_t; + +ATCA_STATUS atGetExecTime(uint8_t opcode, ATCACommand ca_cmd); +#endif + +ATCA_STATUS atca_execute_command(ATCAPacket* packet, ATCADevice device); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.c new file mode 100644 index 0000000..b3afb51 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.c @@ -0,0 +1,271 @@ +/** + * \file + * + * \brief Microchip CryptoAuthLib hardware interface object + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include +#include "atca_iface.h" +#include "hal/atca_hal.h" + +/** \defgroup interface ATCAIface (atca_) + * \brief Abstract interface to all CryptoAuth device types. This interface + * connects to the HAL implementation and abstracts the physical details of the + * device communication from all the upper layers of CryptoAuthLib + @{ */ + + +#ifndef ATCA_POST_DELAY_MSEC +/* \brief How long to wait after an initial wake failure for the POSt to + * complete. + * If Power-on self test (POST) is enabled, the self test will run on waking + * from sleep or during power-on, which delays the wake reply. + */ +#define ATCA_POST_DELAY_MSEC 25 +#endif + +ATCA_STATUS _atinit(ATCAIface ca_iface, ATCAHAL_t *hal); + +/** \brief Initializer for ATCAIface objects + * \param[in] cfg Logical configuration for the interface + * \param[in] ca_iface Interface structure to initialize. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS initATCAIface(ATCAIfaceCfg *cfg, ATCAIface ca_iface) +{ + ATCA_STATUS status; + + if (cfg == NULL || ca_iface == NULL) + { + return ATCA_BAD_PARAM; + } + + ca_iface->mType = cfg->iface_type; + ca_iface->mIfaceCFG = cfg; + + status = atinit(ca_iface); + if (status != ATCA_SUCCESS) + { + return status; + } + + return ATCA_SUCCESS; +} + +#ifndef ATCA_NO_HEAP +/** \brief Constructor for ATCAIface objects + * \param[in] cfg Logical configuration for the interface + * \return New interface instance on success. NULL on failure. + */ +ATCAIface newATCAIface(ATCAIfaceCfg *cfg) +{ + ATCAIface ca_iface; + ATCA_STATUS status; + + ca_iface = (ATCAIface)malloc(sizeof(struct atca_iface)); + status = initATCAIface(cfg, ca_iface); + if (status != ATCA_SUCCESS) + { + free(ca_iface); + ca_iface = NULL; + return NULL; + } + + return ca_iface; +} +#endif + +/** \brief Performs the HAL initialization by calling intermediate HAL wrapper + * function. If using the basic API, the atcab_init() function should + * be called instead. + * \param[in] ca_iface Device to interact with. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atinit(ATCAIface ca_iface) +{ + ATCA_STATUS status = ATCA_COMM_FAIL; + ATCAHAL_t hal; + + _atinit(ca_iface, &hal); + + status = ca_iface->atinit(&hal, ca_iface->mIfaceCFG); + if (status == ATCA_SUCCESS) + { + ca_iface->hal_data = hal.hal_data; + + // Perform the post init + status = ca_iface->atpostinit(ca_iface); + } + + return status; +} + +/** \brief Sends the data to the device by calling intermediate HAL wrapper + * function. + * \param[in] ca_iface Device to interact with. + * \param[in] txdata Data to be transmitted to the device. + * \param[in] txlength Number of bytes to be transmitted to the device. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atsend(ATCAIface ca_iface, uint8_t *txdata, int txlength) +{ + return ca_iface->atsend(ca_iface, txdata, txlength); +} + +/**\brief Receives data from the device by calling intermediate HAL wrapper + * function. + * \param[in] ca_iface Device to interact with. + * \param[out] rxdata Data received will be returned here. + * \param[inout] rxlength As input, the size of the rxdata buffer. + * As output, the number of bytes received. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atreceive(ATCAIface ca_iface, uint8_t *rxdata, uint16_t *rxlength) +{ + return ca_iface->atreceive(ca_iface, rxdata, rxlength); +} + +/** \brief Wakes up the device by calling intermediate HAL wrapper function. + * If using the basic API, the atcab_wakeup() function should be used + * instead. + * \param[in] ca_iface Device to interact with. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atwake(ATCAIface ca_iface) +{ + ATCA_STATUS status = ca_iface->atwake(ca_iface); + + if (status == ATCA_WAKE_FAILED) + { + // The device might be performing a POST. Wait for it to complete + // and try again. + atca_delay_ms(ATCA_POST_DELAY_MSEC); + + status = ca_iface->atwake(ca_iface); + } + + return status; +} + + +/** \brief Puts the device into idle state by calling intermediate HAL wrapper + * function. If using the basic API, the atcab_idle() function should + * be used instead. + * \param[in] ca_iface Device to interact with. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atidle(ATCAIface ca_iface) +{ + ATCA_STATUS status; + + status = ca_iface->atidle(ca_iface); + atca_delay_ms(1); + return status; +} + +/** \brief Puts the device into sleep state by calling intermediate HAL wrapper + * function. If using the basic API, the atcab_sleep() function should + * be used instead. + * \param[in] ca_iface Device to interact with. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atsleep(ATCAIface ca_iface) +{ + ATCA_STATUS status; + + status = ca_iface->atsleep(ca_iface); + atca_delay_ms(1); + return status; +} + + +/** \brief Returns the logical interface configuration for the device. + * \param[in] ca_iface Device interface. + * \return Logical interface configuration. + */ +ATCAIfaceCfg * atgetifacecfg(ATCAIface ca_iface) +{ + return ca_iface->mIfaceCFG; +} + + +/** \brief Returns the HAL data pointer for the device. + * \param[in] ca_iface Device interface. + * \return HAL data pointer. + */ +void* atgetifacehaldat(ATCAIface ca_iface) +{ + return ca_iface->hal_data; +} + +/** \brief Instruct the HAL driver to release any resources associated with + * this interface. + * \param[in] ca_iface Device interface. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS releaseATCAIface(ATCAIface ca_iface) +{ + if (ca_iface == NULL) + { + return ATCA_BAD_PARAM; + } + + return hal_iface_release(ca_iface->mType, ca_iface->hal_data); +} + +#ifndef ATCA_NO_HEAP +/** \brief Instruct the HAL driver to release any resources associated with + * this interface, then delete the object. + * \param[in] ca_iface Device interface. + */ +void deleteATCAIface(ATCAIface *ca_iface) +{ + if (ca_iface == NULL) + { + return; + } + + releaseATCAIface(*ca_iface); + free(*ca_iface); + *ca_iface = NULL; +} +#endif + +ATCA_STATUS _atinit(ATCAIface ca_iface, ATCAHAL_t *hal) +{ + // get method mapping to HAL methods for this interface + hal_iface_init(ca_iface->mIfaceCFG, hal); + ca_iface->atinit = hal->halinit; + ca_iface->atpostinit = hal->halpostinit; + ca_iface->atsend = hal->halsend; + ca_iface->atreceive = hal->halreceive; + ca_iface->atwake = hal->halwake; + ca_iface->atsleep = hal->halsleep; + ca_iface->atidle = hal->halidle; + ca_iface->hal_data = hal->hal_data; + + return ATCA_SUCCESS; +} +/** @} */ diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.h new file mode 100644 index 0000000..8db967b --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.h @@ -0,0 +1,173 @@ +/** + * \file + * + * \brief Microchip Crypto Auth hardware interface object + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef ATCA_IFACE_H +#define ATCA_IFACE_H + +/** \defgroup interface ATCAIface (atca_) + * \brief Abstract interface to all CryptoAuth device types. This interface + * connects to the HAL implementation and abstracts the physical details of the + * device communication from all the upper layers of CryptoAuthLib + @{ */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "atca_command.h" + +typedef enum +{ + ATCA_I2C_IFACE, + ATCA_SWI_IFACE, + ATCA_UART_IFACE, + ATCA_SPI_IFACE, + ATCA_HID_IFACE, + ATCA_CUSTOM_IFACE, + // additional physical interface types here + ATCA_UNKNOWN_IFACE, +} ATCAIfaceType; + +/* ATCAIfaceCfg is a mediator object between a completely abstract notion of a + physical interface and an actual physical interface. + + The main purpose of it is to keep hardware specifics from bleeding into the + higher levels - hardware specifics could include things like framework + specific items (ASF SERCOM) vs a non-Microchip I2C library constant that + defines an I2C port. But I2C has roughly the same parameters regardless of + architecture and framework. + */ + +typedef struct +{ + + ATCAIfaceType iface_type; // active iface - how to interpret the union below + ATCADeviceType devtype; // explicit device type + + union // each instance of an iface cfg defines a single type of interface + { + struct ATCAI2C + { + uint8_t slave_address; // 8-bit slave address + uint8_t bus; // logical i2c bus number, 0-based - HAL will map this to a pin pair for SDA SCL + uint32_t baud; // typically 400000 + } atcai2c; + + struct ATCASWI + { + uint8_t bus; // logical SWI bus - HAL will map this to a pin or uart port + } atcaswi; + + struct ATCAUART + { + int port; // logic port number + uint32_t baud; // typically 115200 + uint8_t wordsize; // usually 8 + uint8_t parity; // 0 == even, 1 == odd, 2 == none + uint8_t stopbits; // 0,1,2 + } atcauart; + + struct ATCAHID + { + int idx; // HID enumeration index + uint32_t vid; // Vendor ID of kit (0x03EB for CK101) + uint32_t pid; // Product ID of kit (0x2312 for CK101) + uint32_t packetsize; // Size of the USB packet + uint8_t guid[16]; // The GUID for this HID device + } atcahid; + + struct ATCACUSTOM + { + ATCA_STATUS (*halinit)(void *hal, void *cfg); + ATCA_STATUS (*halpostinit)(void *iface); + ATCA_STATUS (*halsend)(void *iface, uint8_t *txdata, int txlength); + ATCA_STATUS (*halreceive)(void *iface, uint8_t* rxdata, uint16_t* rxlength); + ATCA_STATUS (*halwake)(void *iface); + ATCA_STATUS (*halidle)(void *iface); + ATCA_STATUS (*halsleep)(void *iface); + ATCA_STATUS (*halrelease)(void* hal_data); + } atcacustom; + + }; + + uint16_t wake_delay; // microseconds of tWHI + tWLO which varies based on chip type + int rx_retries; // the number of retries to attempt for receiving bytes + void * cfg_data; // opaque data used by HAL in device discovery +} ATCAIfaceCfg; +typedef struct atca_iface * ATCAIface; + + +/** \brief atca_iface is the C object backing ATCAIface. See the atca_iface.h file for + * details on the ATCAIface methods + */ + +struct atca_iface +{ + ATCAIfaceType mType; + ATCAIfaceCfg *mIfaceCFG; // points to previous defined/given Cfg object, caller manages this + + ATCA_STATUS (*atinit)(void *hal, ATCAIfaceCfg *); + ATCA_STATUS (*atpostinit)(ATCAIface hal); + ATCA_STATUS (*atsend)(ATCAIface hal, uint8_t *txdata, int txlength); + ATCA_STATUS (*atreceive)(ATCAIface hal, uint8_t *rxdata, uint16_t *rxlength); + ATCA_STATUS (*atwake)(ATCAIface hal); + ATCA_STATUS (*atidle)(ATCAIface hal); + ATCA_STATUS (*atsleep)(ATCAIface hal); + + // treat as private + void *hal_data; // generic pointer used by HAL to point to architecture specific structure + // no ATCA object should touch this except HAL, HAL manages this pointer and memory it points to +}; + +ATCA_STATUS initATCAIface(ATCAIfaceCfg *cfg, ATCAIface ca_iface); +ATCAIface newATCAIface(ATCAIfaceCfg *cfg); +ATCA_STATUS releaseATCAIface(ATCAIface ca_iface); +void deleteATCAIface(ATCAIface *ca_iface); + +// IFace methods +ATCA_STATUS atinit(ATCAIface ca_iface); +ATCA_STATUS atpostinit(ATCAIface ca_iface); +ATCA_STATUS atsend(ATCAIface ca_iface, uint8_t *txdata, int txlength); +ATCA_STATUS atreceive(ATCAIface ca_iface, uint8_t *rxdata, uint16_t *rxlength); +ATCA_STATUS atwake(ATCAIface ca_iface); +ATCA_STATUS atidle(ATCAIface ca_iface); +ATCA_STATUS atsleep(ATCAIface ca_iface); + +// accessors +ATCAIfaceCfg * atgetifacecfg(ATCAIface ca_iface); +void* atgetifacehaldat(ATCAIface ca_iface); + + +#ifdef __cplusplus +} +#endif +/** @} */ +#endif + + + diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_status.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_status.h new file mode 100644 index 0000000..036c597 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atca_status.h @@ -0,0 +1,84 @@ +/** + * \file + * + * \brief Microchip Crypto Auth status codes + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef _ATCA_STATUS_H +#define _ATCA_STATUS_H + +#include +#include "atca_bool.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* all status codes for the ATCA lib are defined here */ + +typedef enum +{ + ATCA_SUCCESS = 0x00, //!< Function succeeded. + ATCA_CONFIG_ZONE_LOCKED = 0x01, + ATCA_DATA_ZONE_LOCKED = 0x02, + ATCA_WAKE_FAILED = 0xD0, //!< response status byte indicates CheckMac failure (status byte = 0x01) + ATCA_CHECKMAC_VERIFY_FAILED = 0xD1, //!< response status byte indicates CheckMac failure (status byte = 0x01) + ATCA_PARSE_ERROR = 0xD2, //!< response status byte indicates parsing error (status byte = 0x03) + ATCA_STATUS_CRC = 0xD4, //!< response status byte indicates DEVICE did not receive data properly (status byte = 0xFF) + ATCA_STATUS_UNKNOWN = 0xD5, //!< response status byte is unknown + ATCA_STATUS_ECC = 0xD6, //!< response status byte is ECC fault (status byte = 0x05) + ATCA_STATUS_SELFTEST_ERROR = 0xD7, //!< response status byte is Self Test Error, chip in failure mode (status byte = 0x07) + ATCA_FUNC_FAIL = 0xE0, //!< Function could not execute due to incorrect condition / state. + ATCA_GEN_FAIL = 0xE1, //!< unspecified error + ATCA_BAD_PARAM = 0xE2, //!< bad argument (out of range, null pointer, etc.) + ATCA_INVALID_ID = 0xE3, //!< invalid device id, id not set + ATCA_INVALID_SIZE = 0xE4, //!< Count value is out of range or greater than buffer size. + ATCA_RX_CRC_ERROR = 0xE5, //!< CRC error in data received from device + ATCA_RX_FAIL = 0xE6, //!< Timed out while waiting for response. Number of bytes received is > 0. + ATCA_RX_NO_RESPONSE = 0xE7, //!< Not an error while the Command layer is polling for a command response. + ATCA_RESYNC_WITH_WAKEUP = 0xE8, //!< Re-synchronization succeeded, but only after generating a Wake-up + ATCA_PARITY_ERROR = 0xE9, //!< for protocols needing parity + ATCA_TX_TIMEOUT = 0xEA, //!< for Microchip PHY protocol, timeout on transmission waiting for master + ATCA_RX_TIMEOUT = 0xEB, //!< for Microchip PHY protocol, timeout on receipt waiting for master + ATCA_TOO_MANY_COMM_RETRIES = 0xEC, //!< Device did not respond too many times during a transmission. Could indicate no device present. + ATCA_SMALL_BUFFER = 0xED, //!< Supplied buffer is too small for data required + ATCA_COMM_FAIL = 0xF0, //!< Communication with device failed. Same as in hardware dependent modules. + ATCA_TIMEOUT = 0xF1, //!< Timed out while waiting for response. Number of bytes received is 0. + ATCA_BAD_OPCODE = 0xF2, //!< opcode is not supported by the device + ATCA_WAKE_SUCCESS = 0xF3, //!< received proper wake token + ATCA_EXECUTION_ERROR = 0xF4, //!< chip was in a state where it could not execute the command, response status byte indicates command execution error (status byte = 0x0F) + ATCA_UNIMPLEMENTED = 0xF5, //!< Function or some element of it hasn't been implemented yet + ATCA_ASSERT_FAILURE = 0xF6, //!< Code failed run-time consistency check + ATCA_TX_FAIL = 0xF7, //!< Failed to write + ATCA_NOT_LOCKED = 0xF8, //!< required zone was not locked + ATCA_NO_DEVICES = 0xF9, //!< For protocols that support device discovery (kit protocol), no devices were found + ATCA_HEALTH_TEST_ERROR = 0xFA, //!< random number generator health test error + ATCA_ALLOC_FAILURE = 0xFB, //!< Couldn't allocate required memory +} ATCA_STATUS; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert.h new file mode 100644 index 0000000..a9ca5e9 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert.h @@ -0,0 +1,66 @@ +/** + * \file + * \brief Declarations common to all atcacert code. + * + * These are common definitions used by all the atcacert code. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef ATCACERT_H +#define ATCACERT_H + +#include +#include + +/** \defgroup atcacert_ Certificate manipulation methods (atcacert_) + * + * \brief + * These methods provide convenient ways to perform certification I/O with + * CryptoAuth chips and perform certificate manipulation in memory + * + @{ */ +#ifndef FALSE +#define FALSE (0) +#endif +#ifndef TRUE +#define TRUE (1) +#endif + +#define ATCACERT_E_SUCCESS 0 //!< Operation completed successfully. +#define ATCACERT_E_ERROR 1 //!< General error. +#define ATCACERT_E_BAD_PARAMS 2 //!< Invalid/bad parameter passed to function. +#define ATCACERT_E_BUFFER_TOO_SMALL 3 //!< Supplied buffer for output is too small to hold the result. +#define ATCACERT_E_DECODING_ERROR 4 //!< Data being decoded/parsed has an invalid format. +#define ATCACERT_E_INVALID_DATE 5 //!< Date is invalid. +#define ATCACERT_E_UNIMPLEMENTED 6 //!< Function is unimplemented for the current configuration. +#define ATCACERT_E_UNEXPECTED_ELEM_SIZE 7 //!< A certificate element size was not what was expected. +#define ATCACERT_E_ELEM_MISSING 8 //!< The certificate element isn't defined for the certificate definition. +#define ATCACERT_E_ELEM_OUT_OF_BOUNDS 9 //!< Certificate element is out of bounds for the given certificate. +#define ATCACERT_E_BAD_CERT 10 //!< Certificate structure is bad in some way. +#define ATCACERT_E_WRONG_CERT_DEF 11 +#define ATCACERT_E_VERIFY_FAILED 12 //!< Certificate or challenge/response verification failed. +#define ATCACERT_E_INVALID_TRANSFORM 13 //!< Invalid transform passed to function. + +/** @} */ +#endif \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.c new file mode 100644 index 0000000..6d6daa9 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.c @@ -0,0 +1,366 @@ +/** + * \file + * \brief Client side cert i/o methods. These declarations deal with the client-side, the node being authenticated, + * of the authentication process. It is assumed the client has an ECC CryptoAuthentication device + * (e.g. ATECC508A) and the certificates are stored on that device. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +#include +#include "atcacert_client.h" +#include "atcacert_pem.h" +#include "cryptoauthlib.h" +#include "basic/atca_basic.h" + +// Perform floor integer division (-1 / 2 == -1) instead of truncate towards zero (-1 / 2 == 0) +static int floor_div(int a, int b) +{ + int d = a / b; + int r = a % b; + + return r ? (d - ((a < 0) ^ (b < 0))) : d; +} + +int atcacert_get_response(uint8_t device_private_key_slot, + const uint8_t challenge[32], + uint8_t response[64]) +{ + if (device_private_key_slot > 15 || challenge == NULL || response == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + return atcab_sign(device_private_key_slot, challenge, response); +} + +int atcacert_read_device_loc(const atcacert_device_loc_t* device_loc, + uint8_t* data) +{ + int ret = 0; + + if (device_loc->zone == DEVZONE_DATA && device_loc->is_genkey) + { + uint8_t public_key[ATCA_PUB_KEY_SIZE]; + if (device_loc->offset + device_loc->count > sizeof(public_key)) + { + return ATCACERT_E_BAD_PARAMS; + } + + ret = atcab_get_pubkey(device_loc->slot, public_key); + if (ret != ATCA_SUCCESS) + { + return ret; + } + memcpy(data, &public_key[device_loc->offset], device_loc->count); + } + else + { + size_t count = device_loc->count; + size_t zone_size; + ret = atcab_get_zone_size(device_loc->zone, device_loc->slot, &zone_size); + if (ret != ATCA_SUCCESS) + { + return ret; + } + if (device_loc->offset + device_loc->count > zone_size) + { + if (device_loc->offset > zone_size) + { + return ATCACERT_E_BAD_PARAMS; + } + count = zone_size - device_loc->offset; + } + + ret = atcab_read_bytes_zone( + device_loc->zone, + device_loc->slot, + device_loc->offset, + data, + count); + if (ret != ATCA_SUCCESS) + { + return ret; + } + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_read_cert(const atcacert_def_t* cert_def, + const uint8_t ca_public_key[64], + uint8_t* cert, + size_t* cert_size) +{ + int ret = 0; + atcacert_device_loc_t device_locs[16]; + size_t device_locs_count = 0; + size_t i = 0; + atcacert_build_state_t build_state; + + if (cert_def == NULL || cert == NULL || cert_size == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + ret = atcacert_get_device_locs( + cert_def, + device_locs, + &device_locs_count, + sizeof(device_locs) / sizeof(device_locs[0]), + ATCA_BLOCK_SIZE); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_cert_build_start(&build_state, cert_def, cert, cert_size, ca_public_key); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + for (i = 0; i < device_locs_count; i++) + { + static uint8_t data[416]; + ret = atcacert_read_device_loc(&device_locs[i], data); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_cert_build_process(&build_state, &device_locs[i], data); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + } + + ret = atcacert_cert_build_finish(&build_state); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_write_cert(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size) +{ + int ret = 0; + atcacert_device_loc_t device_locs[16]; + size_t device_locs_count = 0; + size_t i = 0; + + if (cert_def == NULL || cert == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + ret = atcacert_get_device_locs( + cert_def, + device_locs, + &device_locs_count, + sizeof(device_locs) / sizeof(device_locs[0]), + ATCA_BLOCK_SIZE); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + for (i = 0; i < device_locs_count; i++) + { + int end_block; + int start_block; + static uint8_t data[416]; + int block; + + if (device_locs[i].zone == DEVZONE_CONFIG) + { + continue; // Cert data isn't written to the config zone, only read + } + if (device_locs[i].zone == DEVZONE_DATA && device_locs[i].is_genkey) + { + continue; // Public key is generated not written + + } + ret = atcacert_get_device_data(cert_def, cert, cert_size, &device_locs[i], data); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + start_block = device_locs[i].offset / ATCA_BLOCK_SIZE; + end_block = floor_div((int)(device_locs[i].offset + device_locs[i].count) - 1, ATCA_BLOCK_SIZE); + for (block = start_block; block <= end_block; block++) + { + ret = atcab_write_zone( + device_locs[i].zone, + device_locs[i].slot, + (uint8_t)block, + 0, + &data[(block - start_block) * ATCA_BLOCK_SIZE], + ATCA_BLOCK_SIZE); + if (ret != ATCA_SUCCESS) + { + return ret; + } + } + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_create_csr_pem(const atcacert_def_t* csr_def, char* csr, size_t* csr_size) +{ + ATCA_STATUS status = ATCA_SUCCESS; + size_t csr_max_size; + size_t csr_der_size; + + // Check the pointers + if (csr_def == NULL || csr == NULL || csr_size == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + csr_max_size = *csr_size; + *csr_size = 0; + + // Create DER CSR + csr_der_size = csr_max_size; + status = atcacert_create_csr(csr_def, (uint8_t*)csr, &csr_der_size); + if (status != ATCACERT_E_SUCCESS) + { + return status; + } + + // Move the DER CSR to the end of the buffer, so we can encode it into + // PEM in place. + memmove(csr + (csr_max_size - csr_der_size), csr, csr_der_size); + + *csr_size = csr_max_size; + status = atcacert_encode_pem_csr((uint8_t*)(csr + (csr_max_size - csr_der_size)), csr_der_size, csr, csr_size); + if (status != ATCACERT_E_SUCCESS) + { + return status; + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_create_csr(const atcacert_def_t* csr_def, uint8_t* csr, size_t* csr_size) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint8_t pub_key[ATCA_PUB_KEY_SIZE] = { 0 }; + uint8_t sig[ATCA_SIG_SIZE] = { 0 }; + const atcacert_device_loc_t* pub_dev_loc = NULL; + const atcacert_cert_loc_t* pub_loc = NULL; + uint16_t key_slot = 0; + uint16_t priv_key_slot = 0; + uint8_t tbs_digest[ATCA_BLOCK_SIZE] = { 0 }; + size_t csr_max_size = 0; + + do + { + // Check the pointers + if (csr_def == NULL || csr == NULL || csr == NULL || csr_size == NULL) + { + status = ATCACERT_E_BAD_PARAMS; + BREAK(status, "Null input parameter"); + } + // Check the csr buffer size + if (*csr_size < csr_def->cert_template_size) + { + status = ATCACERT_E_BUFFER_TOO_SMALL; + BREAK(status, "CSR buffer size too small"); + } + // Copy the CSR template into the CSR that will be returned + memcpy(csr, csr_def->cert_template, csr_def->cert_template_size); + csr_max_size = *csr_size; + *csr_size = csr_def->cert_template_size; + + // Get a few elements from the csr_def structure + pub_loc = &(csr_def->std_cert_elements[STDCERT_PUBLIC_KEY]); + pub_dev_loc = &(csr_def->public_key_dev_loc); + key_slot = pub_dev_loc->slot; + priv_key_slot = csr_def->private_key_slot; + + // Get the public key from the device + if (pub_dev_loc->is_genkey) + { + // Calculate the public key from the private key + status = atcab_get_pubkey(key_slot, pub_key); + if (status != ATCA_SUCCESS) + { + BREAK(status, "Could not generate public key"); + } + } + else + { + // Read the public key from a slot + status = atcab_read_pubkey(key_slot, pub_key); + if (status != ATCA_SUCCESS) + { + BREAK(status, "Could not read public key"); + } + } + // Insert the public key into the CSR template + status = atcacert_set_cert_element(csr_def, pub_loc, csr, *csr_size, pub_key, ATCA_PUB_KEY_SIZE); + if (status != ATCA_SUCCESS) + { + BREAK(status, "Setting CSR public key failed"); + } + + // Get the CSR TBS digest + status = atcacert_get_tbs_digest(csr_def, csr, *csr_size, tbs_digest); + if (status != ATCA_SUCCESS) + { + BREAK(status, "Get TBS digest failed"); + } + + // Sign the TBS digest + status = atcab_sign(priv_key_slot, tbs_digest, sig); + if (status != ATCA_SUCCESS) + { + BREAK(status, "Signing CSR failed"); + } + + // Insert the signature into the CSR template + status = atcacert_set_signature(csr_def, csr, csr_size, csr_max_size, sig); + if (status != ATCA_SUCCESS) + { + BREAK(status, "Setting CSR signature failed"); + } + + // The exact size of the csr cannot be determined until after adding the signature + // it is returned in the csr_size parameter. (*csr_size = *csr_size;) + + } + while (false); + + return status; +} + + diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.h new file mode 100644 index 0000000..18dfa31 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.h @@ -0,0 +1,152 @@ +/** + * \file + * \brief Client side cert i/o methods. These declarations deal with the client-side, the node being authenticated, + * of the authentication process. It is assumed the client has an ECC CryptoAuthentication device + * (e.g. ATECC508A) and the certificates are stored on that device. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +#ifndef ATCACERT_CLIENT_H +#define ATCACERT_CLIENT_H + +#include +#include +#include "atcacert_def.h" + +// Inform function naming when compiling in C++ +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup atcacert_ Certificate manipulation methods (atcacert_) + * + * \brief + * These methods provide convenient ways to perform certification I/O with + * CryptoAuth chips and perform certificate manipulation in memory + * + @{ */ + +/** \brief Read the data from a device location. + * + * \param[in] device_loc Device location to read data from. + * \param[out] data Data read is returned here. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_read_device_loc(const atcacert_device_loc_t* device_loc, + uint8_t* data); + +/** + * \brief Reads the certificate specified by the certificate definition from the + * ATECC508A device. + * + * This process involves reading the dynamic cert data from the device and combining it + * with the template found in the certificate definition. + * + * \param[in] cert_def Certificate definition describing where to find the dynamic + * certificate information on the device and how to incorporate it + * into the template. + * \param[in] ca_public_key The ECC P256 public key of the certificate authority that signed + * this certificate. Formatted as the 32 byte X and Y integers + * concatenated together (64 bytes total). Set to NULL if the + * authority key id is not needed, set properly in the cert_def + * template, or stored on the device as specifed in the + * cert_def cert_elements. + * \param[out] cert Buffer to received the certificate. + * \param[inout] cert_size As input, the size of the cert buffer in bytes. + * As output, the size of the certificate returned in cert in bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_read_cert(const atcacert_def_t* cert_def, + const uint8_t ca_public_key[64], + uint8_t* cert, + size_t* cert_size); + +/** + * \brief Take a full certificate and write it to the ATECC508A device according to the + * certificate definition. + * + * \param[in] cert_def Certificate definition describing where the dynamic certificate + * information is and how to store it on the device. + * \param[in] cert Full certificate to be stored. + * \param[in] cert_size Size of the full certificate in bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_write_cert(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size); + +/** + * \brief Creates a CSR specified by the CSR definition from the ATECC508A device. + * This process involves reading the dynamic CSR data from the device and combining it + * with the template found in the CSR definition, then signing it. Return the CSR int der format + * \param[in] csr_def CSR definition describing where to find the dynamic CSR information + * on the device and how to incorporate it into the template. + * \param[out] csr Buffer to receive the CSR. + * \param[inout] csr_size As input, the size of the CSR buffer in bytes. + * As output, the size of the CSR returned in cert in bytes. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +int atcacert_create_csr(const atcacert_def_t* csr_def, uint8_t* csr, size_t* csr_size); + +/** + * \brief Creates a CSR specified by the CSR definition from the ATECC508A device. + * This process involves reading the dynamic CSR data from the device and combining it + * with the template found in the CSR definition, then signing it. Return the CSR int der format + * \param[in] csr_def CSR definition describing where to find the dynamic CSR information + * on the device and how to incorporate it into the template. + * \param[out] csr Buffer to received the CSR formatted as PEM. + * \param[inout] csr_size As input, the size of the CSR buffer in bytes. + * As output, the size of the CSR as PEM returned in cert in bytes. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +int atcacert_create_csr_pem(const atcacert_def_t* csr_def, char* csr, size_t* csr_size); + +/** + * \brief Calculates the response to a challenge sent from the host. + * + * The challenge-response protocol is an ECDSA Sign and Verify. This performs the ECDSA Sign on the + * challenge and returns the signature as the response. + * + * \param[in] device_private_key_slot Slot number for the device's private key. This must be the + * same slot used to generate the public key included in the + * device's certificate. + * \param[in] challenge Challenge to generate the response for. Must be 32 bytes. + * \param[out] response Response will be returned in this buffer. 64 bytes. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +int atcacert_get_response(uint8_t device_private_key_slot, + const uint8_t challenge[32], + uint8_t response[64]); + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.c new file mode 100644 index 0000000..6876860 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.c @@ -0,0 +1,1102 @@ +/** + * \file + * \brief Date handling with regard to certificates. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include +#include "atcacert_date.h" + + +const size_t ATCACERT_DATE_FORMAT_SIZES[ATCACERT_DATE_FORMAT_SIZES_COUNT] = { + DATEFMT_ISO8601_SEP_SIZE, + DATEFMT_RFC5280_UTC_SIZE, + DATEFMT_POSIX_UINT32_BE_SIZE, + DATEFMT_POSIX_UINT32_LE_SIZE, + DATEFMT_RFC5280_GEN_SIZE +}; + +int atcacert_date_enc(atcacert_date_format_t format, + const atcacert_tm_utc_t* timestamp, + uint8_t* formatted_date, + size_t* formatted_date_size) +{ + if (timestamp == NULL || formatted_date_size == NULL || format < 0 || format >= sizeof(ATCACERT_DATE_FORMAT_SIZES) / sizeof(ATCACERT_DATE_FORMAT_SIZES[0])) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (formatted_date != NULL && *formatted_date_size < ATCACERT_DATE_FORMAT_SIZES[format]) + { + *formatted_date_size = ATCACERT_DATE_FORMAT_SIZES[format]; + return ATCACERT_E_BUFFER_TOO_SMALL; + } + *formatted_date_size = ATCACERT_DATE_FORMAT_SIZES[format]; + if (formatted_date == NULL) + { + return ATCACERT_E_SUCCESS; // Caller just wanted + + } + switch (format) + { + case DATEFMT_ISO8601_SEP: return atcacert_date_enc_iso8601_sep(timestamp, formatted_date); + case DATEFMT_RFC5280_UTC: return atcacert_date_enc_rfc5280_utc(timestamp, formatted_date); + case DATEFMT_POSIX_UINT32_BE: return atcacert_date_enc_posix_uint32_be(timestamp, formatted_date); + case DATEFMT_POSIX_UINT32_LE: return atcacert_date_enc_posix_uint32_le(timestamp, formatted_date); + case DATEFMT_RFC5280_GEN: return atcacert_date_enc_rfc5280_gen(timestamp, formatted_date); + default: return ATCACERT_E_BAD_PARAMS; + } + + return ATCACERT_E_BAD_PARAMS; +} + +int atcacert_date_dec(atcacert_date_format_t format, + const uint8_t* formatted_date, + size_t formatted_date_size, + atcacert_tm_utc_t* timestamp) +{ + if (formatted_date == NULL || timestamp == NULL || format < 0 || format >= sizeof(ATCACERT_DATE_FORMAT_SIZES) / sizeof(ATCACERT_DATE_FORMAT_SIZES[0])) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (formatted_date_size < ATCACERT_DATE_FORMAT_SIZES[format]) + { + return ATCACERT_E_DECODING_ERROR; // Not enough data to parse this date format + + } + switch (format) + { + case DATEFMT_ISO8601_SEP: return atcacert_date_dec_iso8601_sep(formatted_date, timestamp); + case DATEFMT_RFC5280_UTC: return atcacert_date_dec_rfc5280_utc(formatted_date, timestamp); + case DATEFMT_POSIX_UINT32_BE: return atcacert_date_dec_posix_uint32_be(formatted_date, timestamp); + case DATEFMT_POSIX_UINT32_LE: return atcacert_date_dec_posix_uint32_le(formatted_date, timestamp); + case DATEFMT_RFC5280_GEN: return atcacert_date_dec_rfc5280_gen(formatted_date, timestamp); + default: return ATCACERT_E_BAD_PARAMS; + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_date_get_max_date(atcacert_date_format_t format, atcacert_tm_utc_t* timestamp) +{ + + if (timestamp == NULL || format < 0 || format >= sizeof(ATCACERT_DATE_FORMAT_SIZES) / sizeof(ATCACERT_DATE_FORMAT_SIZES[0])) + { + return ATCACERT_E_BAD_PARAMS; + } + + switch (format) + { + case DATEFMT_ISO8601_SEP: + timestamp->tm_year = 9999 - 1900; + timestamp->tm_mon = 12 - 1; + timestamp->tm_mday = 31; + timestamp->tm_hour = 23; + timestamp->tm_min = 59; + timestamp->tm_sec = 59; + break; + + case DATEFMT_RFC5280_UTC: + timestamp->tm_year = 2049 - 1900; + timestamp->tm_mon = 12 - 1; + timestamp->tm_mday = 31; + timestamp->tm_hour = 23; + timestamp->tm_min = 59; + timestamp->tm_sec = 59; + break; + + case DATEFMT_POSIX_UINT32_BE: + timestamp->tm_year = 2106 - 1900; + timestamp->tm_mon = 2 - 1; + timestamp->tm_mday = 7; + timestamp->tm_hour = 6; + timestamp->tm_min = 28; + timestamp->tm_sec = 15; + break; + + case DATEFMT_POSIX_UINT32_LE: + timestamp->tm_year = 2106 - 1900; + timestamp->tm_mon = 2 - 1; + timestamp->tm_mday = 7; + timestamp->tm_hour = 6; + timestamp->tm_min = 28; + timestamp->tm_sec = 15; + break; + + case DATEFMT_RFC5280_GEN: + timestamp->tm_year = 9999 - 1900; + timestamp->tm_mon = 12 - 1; + timestamp->tm_mday = 31; + timestamp->tm_hour = 23; + timestamp->tm_min = 59; + timestamp->tm_sec = 59; + break; + + default: return ATCACERT_E_BAD_PARAMS; + } + + return ATCACERT_E_SUCCESS; +} + +/** + * \brief Convert an unsigned integer to a zero padded string with no terminating null. + */ +static uint8_t* uint_to_str(uint32_t num, int width, uint8_t* str) +{ + uint8_t* ret = str + width; + int i; + + // Pre-fill the string width with zeros + for (i = 0; i < width; i++) + { + *(str++) = '0'; + } + // Convert the number from right to left + for (; num; num /= 10) + { + *(--str) = '0' + (num % 10); + } + + return ret; +} + +/** + * \brief Convert a number string as a zero padded unsigned integer back into a number + */ +static const uint8_t* str_to_uint(const uint8_t* str, int width, uint32_t* num) +{ + const uint8_t* error_ret = str; + const uint8_t* good_ret = str + width; + uint32_t prev_num = 0; + uint32_t digit_value = 1; + int digit; + + str += width - 1; + *num = 0; + for (digit = 0; digit < width; digit++) + { + if (*str < '0' || *str > '9') + { + return error_ret; // Character is not a digit + } + if (digit >= 10) + { + if (*str != '0') + { + return error_ret; // Number is larger than the output can handle + } + continue; + } + if (digit == 9 && *str > '4') + { + return error_ret; // Number is larger than the output can handle + + } + *num += digit_value * (*str - '0'); + if (*num < prev_num) + { + return error_ret; // Number rolled over, it is larger than the output can handle + + } + digit_value *= 10; + prev_num = *num; + str--; + } + + return good_ret; +} + +/** + * \brief Convert a number string as a zero padded unsigned integer back into a number constrained + * to an integer's size. + */ +static const uint8_t* str_to_int(const uint8_t* str, int width, int* num) +{ + uint32_t unum = 0; + const uint8_t* ret = str_to_uint(str, width, &unum); + + if (ret != str && unum > 2147483647UL) + { + ret = str; // Number exceeds int32's range + } + *num = (int)unum; + return ret; +} + +int atcacert_date_enc_iso8601_sep(const atcacert_tm_utc_t* timestamp, + uint8_t formatted_date[DATEFMT_ISO8601_SEP_SIZE]) +{ + uint8_t* cur_pos = formatted_date; + int year = 0; + + if (timestamp == NULL || formatted_date == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + year = timestamp->tm_year + 1900; + + if (year < 0 || year > 9999) + { + return ATCACERT_E_INVALID_DATE; + } + cur_pos = uint_to_str(year, 4, cur_pos); + + *(cur_pos++) = '-'; + + if (timestamp->tm_mon < 0 || timestamp->tm_mon > 11) + { + return ATCACERT_E_INVALID_DATE; + } + cur_pos = uint_to_str(timestamp->tm_mon + 1, 2, cur_pos); + + *(cur_pos++) = '-'; + + if (timestamp->tm_mday < 1 || timestamp->tm_mday > 31) + { + return ATCACERT_E_INVALID_DATE; + } + cur_pos = uint_to_str(timestamp->tm_mday, 2, cur_pos); + + *(cur_pos++) = 'T'; + + if (timestamp->tm_hour < 0 || timestamp->tm_hour > 23) + { + return ATCACERT_E_INVALID_DATE; + } + cur_pos = uint_to_str(timestamp->tm_hour, 2, cur_pos); + + *(cur_pos++) = ':'; + + if (timestamp->tm_min < 0 || timestamp->tm_min > 59) + { + return ATCACERT_E_INVALID_DATE; + } + cur_pos = uint_to_str(timestamp->tm_min, 2, cur_pos); + + *(cur_pos++) = ':'; + + if (timestamp->tm_sec < 0 || timestamp->tm_sec > 59) + { + return ATCACERT_E_INVALID_DATE; + } + cur_pos = uint_to_str(timestamp->tm_sec, 2, cur_pos); + + *(cur_pos++) = 'Z'; + + return ATCACERT_E_SUCCESS; +} + +int atcacert_date_dec_iso8601_sep(const uint8_t formatted_date[DATEFMT_ISO8601_SEP_SIZE], + atcacert_tm_utc_t* timestamp) +{ + const uint8_t* cur_pos = formatted_date; + const uint8_t* new_pos = NULL; + + if (formatted_date == NULL || timestamp == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + memset(timestamp, 0, sizeof(*timestamp)); + + new_pos = str_to_int(cur_pos, 4, ×tamp->tm_year); + if (new_pos == cur_pos) + { + return ATCACERT_E_DECODING_ERROR; // There was a problem converting the string to a number + } + cur_pos = new_pos; + timestamp->tm_year -= 1900; + + if (*(cur_pos++) != '-') + { + return ATCACERT_E_DECODING_ERROR; // Unexpected separator + + } + new_pos = str_to_int(cur_pos, 2, ×tamp->tm_mon); + if (new_pos == cur_pos) + { + return ATCACERT_E_DECODING_ERROR; // There was a problem converting the string to a number + } + cur_pos = new_pos; + timestamp->tm_mon -= 1; + + if (*(cur_pos++) != '-') + { + return ATCACERT_E_DECODING_ERROR; // Unexpected separator + + } + new_pos = str_to_int(cur_pos, 2, ×tamp->tm_mday); + if (new_pos == cur_pos) + { + return ATCACERT_E_DECODING_ERROR; // There was a problem converting the string to a number + } + cur_pos = new_pos; + + if (*(cur_pos++) != 'T') + { + return ATCACERT_E_DECODING_ERROR; // Unexpected separator + + } + new_pos = str_to_int(cur_pos, 2, ×tamp->tm_hour); + if (new_pos == cur_pos) + { + return ATCACERT_E_DECODING_ERROR; // There was a problem converting the string to a number + } + cur_pos = new_pos; + + if (*(cur_pos++) != ':') + { + return ATCACERT_E_DECODING_ERROR; // Unexpected separator + + } + new_pos = str_to_int(cur_pos, 2, ×tamp->tm_min); + if (new_pos == cur_pos) + { + return ATCACERT_E_DECODING_ERROR; // There was a problem converting the string to a number + } + cur_pos = new_pos; + + if (*(cur_pos++) != ':') + { + return ATCACERT_E_DECODING_ERROR; // Unexpected separator + + } + new_pos = str_to_int(cur_pos, 2, ×tamp->tm_sec); + if (new_pos == cur_pos) + { + return ATCACERT_E_DECODING_ERROR; // There was a problem converting the string to a number + } + cur_pos = new_pos; + + if (*(cur_pos++) != 'Z') + { + return ATCACERT_E_DECODING_ERROR; // Unexpected UTC marker + + } + return ATCACERT_E_SUCCESS; +} + +int atcacert_date_enc_rfc5280_utc(const atcacert_tm_utc_t* timestamp, + uint8_t formatted_date[DATEFMT_RFC5280_UTC_SIZE]) +{ + uint8_t* cur_pos = formatted_date; + int year = 0; + + if (timestamp == NULL || formatted_date == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + year = timestamp->tm_year + 1900; + + if (year >= 1950 && year <= 1999) + { + year = year - 1900; + } + else if (year >= 2000 && year <= 2049) + { + year = year - 2000; + } + else + { + return ATCACERT_E_INVALID_DATE; // Year out of range for RFC2459 UTC format + } + cur_pos = uint_to_str(year, 2, cur_pos); + + if (timestamp->tm_mon < 0 || timestamp->tm_mon > 11) + { + return ATCACERT_E_INVALID_DATE; + } + cur_pos = uint_to_str(timestamp->tm_mon + 1, 2, cur_pos); + + if (timestamp->tm_mday < 1 || timestamp->tm_mday > 31) + { + return ATCACERT_E_INVALID_DATE; + } + cur_pos = uint_to_str(timestamp->tm_mday, 2, cur_pos); + + if (timestamp->tm_hour < 0 || timestamp->tm_hour > 23) + { + return ATCACERT_E_INVALID_DATE; + } + cur_pos = uint_to_str(timestamp->tm_hour, 2, cur_pos); + + if (timestamp->tm_min < 0 || timestamp->tm_min > 59) + { + return ATCACERT_E_INVALID_DATE; + } + cur_pos = uint_to_str(timestamp->tm_min, 2, cur_pos); + + if (timestamp->tm_sec < 0 || timestamp->tm_sec > 59) + { + return ATCACERT_E_INVALID_DATE; + } + cur_pos = uint_to_str(timestamp->tm_sec, 2, cur_pos); + + *(cur_pos++) = 'Z'; + + return ATCACERT_E_SUCCESS; +} + +int atcacert_date_dec_rfc5280_utc(const uint8_t formatted_date[DATEFMT_RFC5280_UTC_SIZE], + atcacert_tm_utc_t* timestamp) +{ + const uint8_t* cur_pos = formatted_date; + const uint8_t* new_pos = NULL; + + if (formatted_date == NULL || timestamp == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + memset(timestamp, 0, sizeof(*timestamp)); + + new_pos = str_to_int(cur_pos, 2, ×tamp->tm_year); + if (new_pos == cur_pos) + { + return ATCACERT_E_DECODING_ERROR; // There was a problem converting the string to a number + } + cur_pos = new_pos; + if (timestamp->tm_year < 50) + { + timestamp->tm_year += 2000; + } + else + { + timestamp->tm_year += 1900; + } + timestamp->tm_year -= 1900; + + new_pos = str_to_int(cur_pos, 2, ×tamp->tm_mon); + if (new_pos == cur_pos) + { + return ATCACERT_E_DECODING_ERROR; // There was a problem converting the string to a number + } + cur_pos = new_pos; + timestamp->tm_mon -= 1; + + new_pos = str_to_int(cur_pos, 2, ×tamp->tm_mday); + if (new_pos == cur_pos) + { + return ATCACERT_E_DECODING_ERROR; // There was a problem converting the string to a number + } + cur_pos = new_pos; + + new_pos = str_to_int(cur_pos, 2, ×tamp->tm_hour); + if (new_pos == cur_pos) + { + return ATCACERT_E_DECODING_ERROR; // There was a problem converting the string to a number + } + cur_pos = new_pos; + + new_pos = str_to_int(cur_pos, 2, ×tamp->tm_min); + if (new_pos == cur_pos) + { + return ATCACERT_E_DECODING_ERROR; // There was a problem converting the string to a number + } + cur_pos = new_pos; + + new_pos = str_to_int(cur_pos, 2, ×tamp->tm_sec); + if (new_pos == cur_pos) + { + return ATCACERT_E_DECODING_ERROR; // There was a problem converting the string to a number + } + cur_pos = new_pos; + + if (*(cur_pos++) != 'Z') + { + return ATCACERT_E_DECODING_ERROR; // Unexpected UTC marker + + } + return ATCACERT_E_SUCCESS; +} + +int atcacert_date_enc_rfc5280_gen(const atcacert_tm_utc_t* timestamp, + uint8_t formatted_date[DATEFMT_RFC5280_GEN_SIZE]) +{ + uint8_t* cur_pos = formatted_date; + int year = 0; + + if (timestamp == NULL || formatted_date == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + year = timestamp->tm_year + 1900; + + if (year < 0 || year > 9999) + { + return ATCACERT_E_INVALID_DATE; + } + cur_pos = uint_to_str(year, 4, cur_pos); + + if (timestamp->tm_mon < 0 || timestamp->tm_mon > 11) + { + return ATCACERT_E_INVALID_DATE; + } + cur_pos = uint_to_str(timestamp->tm_mon + 1, 2, cur_pos); + + if (timestamp->tm_mday < 1 || timestamp->tm_mday > 31) + { + return ATCACERT_E_INVALID_DATE; + } + cur_pos = uint_to_str(timestamp->tm_mday, 2, cur_pos); + + if (timestamp->tm_hour < 0 || timestamp->tm_hour > 23) + { + return ATCACERT_E_INVALID_DATE; + } + cur_pos = uint_to_str(timestamp->tm_hour, 2, cur_pos); + + if (timestamp->tm_min < 0 || timestamp->tm_min > 59) + { + return ATCACERT_E_INVALID_DATE; + } + cur_pos = uint_to_str(timestamp->tm_min, 2, cur_pos); + + if (timestamp->tm_sec < 0 || timestamp->tm_sec > 59) + { + return ATCACERT_E_INVALID_DATE; + } + cur_pos = uint_to_str(timestamp->tm_sec, 2, cur_pos); + + *(cur_pos++) = 'Z'; + + return ATCACERT_E_SUCCESS; +} + +int atcacert_date_dec_rfc5280_gen(const uint8_t formatted_date[DATEFMT_RFC5280_GEN_SIZE], + atcacert_tm_utc_t* timestamp) +{ + const uint8_t* cur_pos = formatted_date; + const uint8_t* new_pos = NULL; + + if (formatted_date == NULL || timestamp == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + memset(timestamp, 0, sizeof(*timestamp)); + + new_pos = str_to_int(cur_pos, 4, ×tamp->tm_year); + if (new_pos == cur_pos) + { + return ATCACERT_E_DECODING_ERROR; // There was a problem converting the string to a number + } + cur_pos = new_pos; + timestamp->tm_year -= 1900; + + new_pos = str_to_int(cur_pos, 2, ×tamp->tm_mon); + if (new_pos == cur_pos) + { + return ATCACERT_E_DECODING_ERROR; // There was a problem converting the string to a number + } + cur_pos = new_pos; + timestamp->tm_mon -= 1; + + new_pos = str_to_int(cur_pos, 2, ×tamp->tm_mday); + if (new_pos == cur_pos) + { + return ATCACERT_E_DECODING_ERROR; // There was a problem converting the string to a number + } + cur_pos = new_pos; + + new_pos = str_to_int(cur_pos, 2, ×tamp->tm_hour); + if (new_pos == cur_pos) + { + return ATCACERT_E_DECODING_ERROR; // There was a problem converting the string to a number + } + cur_pos = new_pos; + + new_pos = str_to_int(cur_pos, 2, ×tamp->tm_min); + if (new_pos == cur_pos) + { + return ATCACERT_E_DECODING_ERROR; // There was a problem converting the string to a number + } + cur_pos = new_pos; + + new_pos = str_to_int(cur_pos, 2, ×tamp->tm_sec); + if (new_pos == cur_pos) + { + return ATCACERT_E_DECODING_ERROR; // There was a problem converting the string to a number + } + cur_pos = new_pos; + + if (*(cur_pos++) != 'Z') + { + return ATCACERT_E_DECODING_ERROR; // Unexpected UTC marker + + } + return ATCACERT_E_SUCCESS; +} + +static int is_leap_year(int year) +{ + return (year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)); +} + +static uint32_t get_year_secs(int year) +{ + if (is_leap_year(year)) + { + return (31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31) * 86400; + } + else + { + return (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31) * 86400; + } +} + +static uint32_t get_month_secs(int year, int mon) +{ + static const uint32_t month_secs[] = { 2678400, 2419200, 2678400, 2592000, 2678400, 2592000, 2678400, 2678400, 2592000, 2678400, 2592000, 2678400 }; + + if (mon == 1 && is_leap_year(year)) + { + return 2505600; + } + else if (mon < 12) + { + return month_secs[mon]; + } + else + { + return 0; + } +} + +static atcacert_tm_utc_t *atcacert_gmtime32(const uint32_t *posix_time, atcacert_tm_utc_t *result) +{ + uint32_t secs_remaining = *posix_time; + uint32_t secs = 0; + + result->tm_year = 1970; + result->tm_mon = 0; + result->tm_mday = 1; + result->tm_hour = 0; + result->tm_min = 0; + result->tm_sec = 0; + + secs = get_year_secs(result->tm_year); + while (secs_remaining >= secs) + { + result->tm_year++; + secs_remaining -= secs; + secs = get_year_secs(result->tm_year); + } + + secs = get_month_secs(result->tm_year, result->tm_mon); + while (secs_remaining >= secs) + { + result->tm_mon++; + secs_remaining -= secs; + secs = get_month_secs(result->tm_year, result->tm_mon); + } + + result->tm_year -= 1900; + + result->tm_mday += secs_remaining / 86400; + secs_remaining %= 86400; + + result->tm_hour += secs_remaining / 3600; + secs_remaining %= 3600; + + result->tm_min += secs_remaining / 60; + secs_remaining %= 60; + + result->tm_sec += secs_remaining; + + return result; +} + +static uint32_t atcacert_mkgmtime32(const atcacert_tm_utc_t *timeptr) +{ + uint32_t posix_time = 0; + int cur_value = 0; + int year = timeptr->tm_year + 1900; + + cur_value = year - 1; + while (cur_value >= 1970) + { + posix_time += get_year_secs(cur_value--); + } + + cur_value = timeptr->tm_mon - 1; + while (cur_value >= 0) + { + posix_time += get_month_secs(year, cur_value--); + } + + posix_time += (uint32_t)(timeptr->tm_mday - 1) * 86400; + posix_time += (uint32_t)timeptr->tm_hour * 3600; + posix_time += (uint32_t)timeptr->tm_min * 60; + posix_time += (uint32_t)timeptr->tm_sec; + + return posix_time; +} + +static int atcacert_date_enc_posix_uint32(const atcacert_tm_utc_t* timestamp, uint32_t* posix_uint32) +{ + //atcacert_tm_utc_t timestamp_nc; + //time_t posix_time = 0; + int year = 0; + + if (timestamp == NULL || posix_uint32 == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + year = timestamp->tm_year + 1900; + + if (year > 2106 || year < 1970) + { + return ATCACERT_E_INVALID_DATE; //Timestamp out of range for POSIX time. + } + if (timestamp->tm_mon < 0 || timestamp->tm_mon > 11) + { + return ATCACERT_E_INVALID_DATE; + } + if (timestamp->tm_mday < 1 || timestamp->tm_mday > 31) + { + return ATCACERT_E_INVALID_DATE; + } + if (timestamp->tm_hour < 0 || timestamp->tm_hour > 23) + { + return ATCACERT_E_INVALID_DATE; + } + if (timestamp->tm_min < 0 || timestamp->tm_min > 59) + { + return ATCACERT_E_INVALID_DATE; + } + if (timestamp->tm_sec < 0 || timestamp->tm_sec > 59) + { + return ATCACERT_E_INVALID_DATE; + } + // Check for date past max date for POSIX time + if (year == 2106) + { + if (timestamp->tm_mon > 1) + { + return ATCACERT_E_INVALID_DATE; + } + if (timestamp->tm_mon == 1) + { + if (timestamp->tm_mday > 7) + { + return ATCACERT_E_INVALID_DATE; + } + if (timestamp->tm_mday == 7) + { + if (timestamp->tm_hour > 6) + { + return ATCACERT_E_INVALID_DATE; + } + if (timestamp->tm_hour == 6) + { + if (timestamp->tm_min > 28) + { + return ATCACERT_E_INVALID_DATE; + } + if (timestamp->tm_min == 28) + { + if (timestamp->tm_sec > 14) + { + return ATCACERT_E_INVALID_DATE; + } + } + } + } + } + } + +//#ifdef WIN32 +// timestamp_nc = *timestamp; +// posix_time = _mkgmtime(×tamp_nc); +// if (posix_time == -1) +// return ATCACERT_E_INVALID_DATE; +//#elif defined _BSD_SOURCE || defined _SVID_SOURCE +// timestamp_nc = *timestamp; +// posix_time = timegm(×tamp_nc); +// if (posix_time == -1) +// return ATCACERT_E_INVALID_DATE; +//#else +// // In order for this to work, we need to make sure mktime is using GMT. Since this can +// // vary from system to system, I'm putting this "assert" in every time since it may not +// // be caught early on. +// memset(×tamp_nc, 0, sizeof(timestamp_nc)); +// timestamp_nc.tm_year = 2013 - 1900; +// timestamp_nc.tm_mon = 11 - 1; +// timestamp_nc.tm_mday = 10; +// timestamp_nc.tm_hour = 9; +// timestamp_nc.tm_min = 8; +// timestamp_nc.tm_sec = 7; +// posix_time = mktime(×tamp_nc); +// if (posix_time != 1384074487) +// return ATCACERT_E_UNIMPLEMENTED; // mktime isn't using GMT as the timezone, this needs to be fixed +// +// timestamp_nc = *timestamp; +// posix_time = mktime(×tamp_nc); +// if (posix_time == -1) +// return ATCACERT_E_INVALID_DATE; +//#endif +// +// *posix_uint32 = (uint32_t)posix_time; + + *posix_uint32 = atcacert_mkgmtime32(timestamp); + + return ATCACERT_E_SUCCESS; +} + +int atcacert_date_enc_posix_uint32_be(const atcacert_tm_utc_t* timestamp, + uint8_t formatted_date[DATEFMT_POSIX_UINT32_BE_SIZE]) +{ + uint32_t posix_uint32 = 0; + int ret = 0; + + if (timestamp == NULL || formatted_date == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + ret = atcacert_date_enc_posix_uint32(timestamp, &posix_uint32); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + formatted_date[0] = (uint8_t)((posix_uint32 >> 24) & 0xFF); + formatted_date[1] = (uint8_t)((posix_uint32 >> 16) & 0xFF); + formatted_date[2] = (uint8_t)((posix_uint32 >> 8) & 0xFF); + formatted_date[3] = (uint8_t)((posix_uint32 >> 0) & 0xFF); + + return ATCACERT_E_SUCCESS; +} + +static int atcacert_date_dec_posix_uint32(uint32_t posix_uint32, + atcacert_tm_utc_t* timestamp) +{ +//#ifdef WIN32 +// time_t posix_time = (time_t)posix_uint32; +// errno_t ret = 0; +// +// if (timestamp == NULL) +// return ATCACERT_E_BAD_PARAMS; +// +// memset(timestamp, 0, sizeof(*timestamp)); +// ret = gmtime_s(timestamp, &posix_time); +// if (ret != 0) +// return ATCACERT_E_DECODING_ERROR; // Failed to convert to timestamp structure +//#else +// time_t posix_time = (time_t)posix_uint32; +// atcacert_tm_utc_t* ret = NULL; +// if (timestamp == NULL) +// return ATCACERT_E_BAD_PARAMS; +// +// memset(timestamp, 0, sizeof(*timestamp)); +// ret = gmtime_r(&posix_time, timestamp); +// if (ret == NULL) +// return ATCACERT_E_DECODING_ERROR; // Failed to convert to timestamp structure +//#endif + atcacert_gmtime32(&posix_uint32, timestamp); + + return ATCACERT_E_SUCCESS; +} + +int atcacert_date_dec_posix_uint32_be(const uint8_t formatted_date[DATEFMT_POSIX_UINT32_BE_SIZE], + atcacert_tm_utc_t* timestamp) +{ + uint32_t posix_uint32 = 0; + + if (formatted_date == NULL || timestamp == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + posix_uint32 = + ((uint32_t)formatted_date[0] << 24) | + ((uint32_t)formatted_date[1] << 16) | + ((uint32_t)formatted_date[2] << 8) | + ((uint32_t)formatted_date[3]); + + return atcacert_date_dec_posix_uint32(posix_uint32, timestamp); +} + +int atcacert_date_enc_posix_uint32_le(const atcacert_tm_utc_t* timestamp, + uint8_t formatted_date[DATEFMT_POSIX_UINT32_LE_SIZE]) +{ + uint32_t posix_uint32 = 0; + int ret = 0; + + if (timestamp == NULL || formatted_date == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + ret = atcacert_date_enc_posix_uint32(timestamp, &posix_uint32); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + formatted_date[0] = (uint8_t)((posix_uint32 >> 0) & 0xFF); + formatted_date[1] = (uint8_t)((posix_uint32 >> 8) & 0xFF); + formatted_date[2] = (uint8_t)((posix_uint32 >> 16) & 0xFF); + formatted_date[3] = (uint8_t)((posix_uint32 >> 24) & 0xFF); + + return ATCACERT_E_SUCCESS; +} + +int atcacert_date_dec_posix_uint32_le(const uint8_t formatted_date[DATEFMT_POSIX_UINT32_LE_SIZE], + atcacert_tm_utc_t* timestamp) +{ + uint32_t posix_uint32 = 0; + + if (formatted_date == NULL || timestamp == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + posix_uint32 = + ((uint32_t)formatted_date[3] << 24) | + ((uint32_t)formatted_date[2] << 16) | + ((uint32_t)formatted_date[1] << 8) | + ((uint32_t)formatted_date[0]); + + return atcacert_date_dec_posix_uint32(posix_uint32, timestamp); +} + +int atcacert_date_enc_compcert(const atcacert_tm_utc_t* issue_date, + uint8_t expire_years, + uint8_t enc_dates[3]) +{ + /* + * Issue and expire dates are compressed/encoded as below + * +---------------+---------------+---------------+ + * | Byte 1 | Byte 2 | Byte 3 | + * +---------------+---------------+---------------+ + * | | | | | | | | | | | | | | | | | | | | | | | | | + * | 5 bits | 4 bits| 5 bits | 5 bits | 5 bits | + * | Year | Month | Day | Hour | Expire | + * | | | | | Years | + * +---------+-------+---------+---------+---------+ + * + * Minutes and seconds are always zero. + */ + if (issue_date == NULL || enc_dates == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + if ((issue_date->tm_year + 1900) < 2000 || (issue_date->tm_year + 1900) > 2031) + { + return ATCACERT_E_INVALID_DATE; + } + if (issue_date->tm_mon < 0 || issue_date->tm_mon > 11) + { + return ATCACERT_E_INVALID_DATE; + } + if (issue_date->tm_mday < 1 || issue_date->tm_mday > 31) + { + return ATCACERT_E_INVALID_DATE; + } + if (issue_date->tm_hour < 0 || issue_date->tm_hour > 23) + { + return ATCACERT_E_INVALID_DATE; + } + if (expire_years > 31) + { + return ATCACERT_E_INVALID_DATE; + } + + memset(enc_dates, 0, 3); + + enc_dates[0] = (enc_dates[0] & 0x07) | (((issue_date->tm_year + 1900 - 2000) & 0x1F) << 3); + enc_dates[0] = (enc_dates[0] & 0xF8) | (((issue_date->tm_mon + 1) & 0x0F) >> 1); + enc_dates[1] = (enc_dates[1] & 0x7F) | (((issue_date->tm_mon + 1) & 0x0F) << 7); + enc_dates[1] = (enc_dates[1] & 0x83) | ((issue_date->tm_mday & 0x1F) << 2); + enc_dates[1] = (enc_dates[1] & 0xFC) | ((issue_date->tm_hour & 0x1F) >> 3); + enc_dates[2] = (enc_dates[2] & 0x1F) | ((issue_date->tm_hour & 0x1F) << 5); + enc_dates[2] = (enc_dates[2] & 0xE0) | (expire_years & 0x1F); + + return ATCACERT_E_SUCCESS; +} + +int atcacert_date_dec_compcert(const uint8_t enc_dates[3], + atcacert_date_format_t expire_date_format, + atcacert_tm_utc_t* issue_date, + atcacert_tm_utc_t* expire_date) +{ + int ret = ATCACERT_E_SUCCESS; + uint8_t expire_years = 0; + + /* + * Issue and expire dates are compressed/encoded as below + * +---------------+---------------+---------------+ + * | Byte 1 | Byte 2 | Byte 3 | + * +---------------+---------------+---------------+ + * | | | | | | | | | | | | | | | | | | | | | | | | | + * | 5 bits | 4 bits| 5 bits | 5 bits | 5 bits | + * | Year | Month | Day | Hour | Expire | + * | | | | | Years | + * +---------+-------+---------+---------+---------+ + * + * Minutes and seconds are always zero. + */ + + if (enc_dates == NULL || issue_date == NULL || expire_date == NULL || expire_date_format < 0 || expire_date_format >= sizeof(ATCACERT_DATE_FORMAT_SIZES) / sizeof(ATCACERT_DATE_FORMAT_SIZES[0])) + { + return ATCACERT_E_BAD_PARAMS; + } + + memset(issue_date, 0, sizeof(*issue_date)); + memset(expire_date, 0, sizeof(*expire_date)); + + issue_date->tm_year = (enc_dates[0] >> 3) + 2000 - 1900; + issue_date->tm_mon = (((enc_dates[0] & 0x07) << 1) | ((enc_dates[1] & 0x80) >> 7)) - 1; + issue_date->tm_mday = ((enc_dates[1] & 0x7C) >> 2); + issue_date->tm_hour = ((enc_dates[1] & 0x03) << 3) | ((enc_dates[2] & 0xE0) >> 5); + + expire_years = (enc_dates[2] & 0x1F); + + if (expire_years != 0) + { + expire_date->tm_year = issue_date->tm_year + expire_years; + expire_date->tm_mon = issue_date->tm_mon; + expire_date->tm_mday = issue_date->tm_mday; + expire_date->tm_hour = issue_date->tm_hour; + } + else + { + // Expire years of 0, means no expiration. Set to max date for the given expiration date format. + ret = atcacert_date_get_max_date(expire_date_format, expire_date); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + } + + return ATCACERT_E_SUCCESS; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.h new file mode 100644 index 0000000..e42a68e --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.h @@ -0,0 +1,194 @@ +/** + * \file + * \brief Declarations for date handling with regard to certificates. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef ATCACERT_DATE_H +#define ATCACERT_DATE_H + +#include +#include "atcacert.h" + + + +// Inform function naming when compiling in C++ +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup atcacert_ Certificate manipulation methods (atcacert_) + * + * \brief + * These methods provide convenient ways to perform certification I/O with + * CryptoAuth chips and perform certificate manipulation in memory + * + @{ */ + +/** + * Holds a broken-down date in UTC. Mimics atcacert_tm_utc_t from time.h. + */ +typedef struct atcacert_tm_utc_s +{ + int tm_sec; // 0 to 59 + int tm_min; // 0 to 59 + int tm_hour; // 0 to 23 + int tm_mday; // 1 to 31 + int tm_mon; // 0 to 11 + int tm_year; // years since 1900 +} atcacert_tm_utc_t; + +/** + * Date formats. + */ +typedef enum atcacert_date_format_e +{ + DATEFMT_ISO8601_SEP, //!< ISO8601 full date YYYY-MM-DDThh:mm:ssZ + DATEFMT_RFC5280_UTC, //!< RFC 5280 (X.509) 4.1.2.5.1 UTCTime format YYMMDDhhmmssZ + DATEFMT_POSIX_UINT32_BE, //!< POSIX (aka UNIX) date format. Seconds since Jan 1, 1970. 32 bit unsigned integer, big endian. + DATEFMT_POSIX_UINT32_LE, //!< POSIX (aka UNIX) date format. Seconds since Jan 1, 1970. 32 bit unsigned integer, little endian. + DATEFMT_RFC5280_GEN //!< RFC 5280 (X.509) 4.1.2.5.2 GeneralizedTime format YYYYMMDDhhmmssZ +} atcacert_date_format_t; + +#define DATEFMT_ISO8601_SEP_SIZE (20) +#define DATEFMT_RFC5280_UTC_SIZE (13) +#define DATEFMT_POSIX_UINT32_BE_SIZE (4) +#define DATEFMT_POSIX_UINT32_LE_SIZE (4) +#define DATEFMT_RFC5280_GEN_SIZE (15) +#define DATEFMT_MAX_SIZE DATEFMT_ISO8601_SEP_SIZE +#define ATCACERT_DATE_FORMAT_SIZES_COUNT 5 + +extern const size_t ATCACERT_DATE_FORMAT_SIZES[ATCACERT_DATE_FORMAT_SIZES_COUNT]; + +/** + * \brief Format a timestamp according to the format type. + * + * \param[in] format Format to use. + * \param[in] timestamp Timestamp to format. + * \param[out] formatted_date Formatted date will be returned in this buffer. + * \param[inout] formatted_date_size As input, the size of the formatted_date buffer. + * As output, the size of the returned formatted_date. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_date_enc(atcacert_date_format_t format, + const atcacert_tm_utc_t* timestamp, + uint8_t* formatted_date, + size_t* formatted_date_size); + +/** + * \brief Parse a formatted timestamp according to the specified format. + * + * \param[in] format Format to parse the formatted date as. + * \param[in] formatted_date Formatted date to be parsed. + * \param[in] formatted_date_size Size of the formatted date in bytes. + * \param[out] timestamp Parsed timestamp is returned here. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_date_dec(atcacert_date_format_t format, + const uint8_t* formatted_date, + size_t formatted_date_size, + atcacert_tm_utc_t* timestamp); + +/** + * \brief Encode the issue and expire dates in the format used by the compressed certificate. + * + * \param[in] issue_date Issue date to encode. Note that minutes and seconds will be ignored. + * \param[in] expire_years Expire date is expressed as a number of years past the issue date. + * 0 should be used if there is no expire date. + * \param[out] enc_dates Encoded dates for use in the compressed certificate is returned here. + * 3 bytes. + * + * \return 0 on success + */ +int atcacert_date_enc_compcert(const atcacert_tm_utc_t * issue_date, + uint8_t expire_years, + uint8_t enc_dates[3]); + +/** + * \brief Decode the issue and expire dates from the format used by the compressed certificate. + * + * \param[in] enc_dates Encoded date from the compressed certificate. 3 bytes. + * \param[in] expire_date_format Expire date format. Only used to determine max date when no + * expiration date is specified by the encoded date. + * \param[out] issue_date Decoded issue date is returned here. + * \param[out] expire_date Decoded expire date is returned here. If there is no + * expiration date, the expire date will be set to a maximum + * value for the given expire_date_format. + * + * \return 0 on success + */ +int atcacert_date_dec_compcert(const uint8_t enc_dates[3], + atcacert_date_format_t expire_date_format, + atcacert_tm_utc_t* issue_date, + atcacert_tm_utc_t* expire_date); + +/** + * \brief Return the maximum date available for the given format. + * + * \param[in] format Format to get the max date for. + * \param[out] timestamp Max date is returned here. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_date_get_max_date(atcacert_date_format_t format, atcacert_tm_utc_t* timestamp); + +int atcacert_date_enc_iso8601_sep(const atcacert_tm_utc_t * timestamp, + uint8_t formatted_date[DATEFMT_ISO8601_SEP_SIZE]); + +int atcacert_date_dec_iso8601_sep(const uint8_t formatted_date[DATEFMT_ISO8601_SEP_SIZE], + atcacert_tm_utc_t* timestamp); + +int atcacert_date_enc_rfc5280_utc(const atcacert_tm_utc_t * timestamp, + uint8_t formatted_date[DATEFMT_RFC5280_UTC_SIZE]); + +int atcacert_date_dec_rfc5280_utc(const uint8_t formatted_date[DATEFMT_RFC5280_UTC_SIZE], + atcacert_tm_utc_t* timestamp); + +int atcacert_date_enc_rfc5280_gen(const atcacert_tm_utc_t * timestamp, + uint8_t formatted_date[DATEFMT_RFC5280_GEN_SIZE]); + +int atcacert_date_dec_rfc5280_gen(const uint8_t formatted_date[DATEFMT_RFC5280_GEN_SIZE], + atcacert_tm_utc_t* timestamp); + +int atcacert_date_enc_posix_uint32_be(const atcacert_tm_utc_t * timestamp, + uint8_t formatted_date[DATEFMT_POSIX_UINT32_BE_SIZE]); + +int atcacert_date_dec_posix_uint32_be(const uint8_t formatted_date[DATEFMT_POSIX_UINT32_BE_SIZE], + atcacert_tm_utc_t* timestamp); + +int atcacert_date_enc_posix_uint32_le(const atcacert_tm_utc_t * timestamp, + uint8_t formatted_date[DATEFMT_POSIX_UINT32_LE_SIZE]); + +int atcacert_date_dec_posix_uint32_le(const uint8_t formatted_date[DATEFMT_POSIX_UINT32_LE_SIZE], + atcacert_tm_utc_t* timestamp); + + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.c new file mode 100644 index 0000000..7cc01f1 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.c @@ -0,0 +1,1786 @@ +/** + * \file + * \brief Main certificate definition implementation. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atcacert_def.h" +#include "crypto/atca_crypto_sw_sha1.h" +#include "crypto/atca_crypto_sw_sha2.h" +#include "atcacert_der.h" +#include "atcacert_date.h" +#include +#include "basic/atca_helpers.h" + +#define ATCACERT_MIN(x, y) ((x) < (y) ? (x) : (y)) +#define ATCACERT_MAX(x, y) ((x) >= (y) ? (x) : (y)) + +int atcacert_merge_device_loc(atcacert_device_loc_t* device_locs, + size_t* device_locs_count, + size_t device_locs_max_count, + const atcacert_device_loc_t* device_loc, + size_t block_size) +{ + size_t i = 0; + size_t new_offset; + size_t new_end; + + if (device_locs == NULL || device_locs_count == NULL || device_loc == NULL || block_size <= 0) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (device_loc->zone == DEVZONE_NONE || device_loc->count == 0) + { + return ATCACERT_E_SUCCESS; // New device location doesn't exist + + } + new_offset = (device_loc->offset / block_size) * block_size; // Round down to block_size + new_end = device_loc->offset + device_loc->count; + new_end = ((new_end % block_size) ? new_end / block_size + 1 : new_end / block_size) * block_size; // Round up to block size + + // Try to merge with an existing device location + for (i = 0; i < *device_locs_count; ++i) + { + atcacert_device_loc_t* cur_device_loc = &device_locs[i]; + size_t cur_end = cur_device_loc->offset + cur_device_loc->count; + + if (device_loc->zone != cur_device_loc->zone) + { + continue; // Not the same zone, can't merge + } + if (device_loc->zone == DEVZONE_DATA && device_loc->slot != cur_device_loc->slot) + { + continue; // Not the same slot, can't merge + } + if (device_loc->zone == DEVZONE_DATA && device_loc->is_genkey != cur_device_loc->is_genkey) + { + continue; // Not the same read method, can't merge. + } + if (new_end < cur_device_loc->offset || new_offset > cur_end) + { + continue; // Same zone, but non-continuous areas + + } + if (device_loc->offset < cur_device_loc->offset) + { + cur_device_loc->offset = device_loc->offset; + } + + if (new_end > cur_end) + { + cur_device_loc->count = (uint16_t)(new_end - cur_device_loc->offset); + } + else + { + cur_device_loc->count = (uint16_t)(cur_end - cur_device_loc->offset); + } + break; + } + + if (i == *device_locs_count) + { + // New device_loc wasn't merged into an existing one, add to the end of the list + if (*device_locs_count >= device_locs_max_count) + { + return ATCACERT_E_BUFFER_TOO_SMALL; // No room to add to list + + } + device_locs[*device_locs_count] = *device_loc; + // Adjust for block size + device_locs[*device_locs_count].offset = (uint16_t)new_offset; + device_locs[*device_locs_count].count = (uint16_t)(new_end - new_offset); + (*device_locs_count)++; + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_get_device_locs(const atcacert_def_t* cert_def, + atcacert_device_loc_t* device_locs, + size_t* device_locs_count, + size_t device_locs_max_count, + size_t block_size) +{ + int ret = 0; + size_t i; + + if (cert_def == NULL || device_locs == NULL || device_locs_count == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + ret = atcacert_merge_device_loc( + device_locs, + device_locs_count, + device_locs_max_count, + &cert_def->comp_cert_dev_loc, + block_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_merge_device_loc( + device_locs, + device_locs_count, + device_locs_max_count, + &cert_def->cert_sn_dev_loc, + block_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_merge_device_loc( + device_locs, + device_locs_count, + device_locs_max_count, + &cert_def->public_key_dev_loc, + block_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + if (cert_def->cert_elements_count > 0 && cert_def->cert_elements == NULL) + { + return ATCACERT_E_BAD_CERT; // Cert def is in an invalid state + + } + for (i = 0; i < cert_def->cert_elements_count; i++) + { + ret = atcacert_merge_device_loc( + device_locs, + device_locs_count, + device_locs_max_count, + &cert_def->cert_elements[i].device_loc, + block_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + } + + // Add the device SN to the list if the cert serial number scheme requires it + if (cert_def->sn_source == SNSRC_DEVICE_SN + || cert_def->sn_source == SNSRC_DEVICE_SN_HASH + || cert_def->sn_source == SNSRC_DEVICE_SN_HASH_POS + || cert_def->sn_source == SNSRC_DEVICE_SN_HASH_RAW) + { + // Device SN is config zone bytes 0-3 and 8-12 + atcacert_device_loc_t device_sn_loc = { + .zone = DEVZONE_CONFIG, + .slot = 0, // Ignored + .is_genkey = FALSE, // Ignored + .offset = 0, + .count = 13 + }; + + ret = atcacert_merge_device_loc( + device_locs, + device_locs_count, + device_locs_max_count, + &device_sn_loc, + block_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + } + + return ATCACERT_E_SUCCESS; +} + +static const uint8_t* atcacert_is_device_loc_match(const atcacert_device_loc_t* device_loc_dest, + const atcacert_device_loc_t* device_loc_src, + const uint8_t* src_data) +{ + size_t dest_end = device_loc_dest->offset + device_loc_dest->count; + size_t src_end = device_loc_src->offset + device_loc_src->count; + + if (device_loc_dest->zone == DEVZONE_NONE || device_loc_dest->count <= 0) + { + return NULL; // device_loc_dest is a null location + } + if (device_loc_src->zone == DEVZONE_NONE || device_loc_src->count <= 0) + { + return NULL; // device_loc_src is a null location + } + if (device_loc_dest->zone != device_loc_src->zone) + { + return NULL; + } + if (device_loc_dest->zone == DEVZONE_DATA && device_loc_dest->slot != device_loc_src->slot) + { + return NULL; + } + if (device_loc_dest->zone == DEVZONE_DATA && device_loc_dest->is_genkey != device_loc_src->is_genkey) + { + return NULL; + } + + if (device_loc_dest->offset < device_loc_src->offset || dest_end > src_end) + { + return NULL; + } + + // device_loc_dest is encompassed by device_loc_src, return a pointer to the data for device_loc_dest + return src_data + (device_loc_dest->offset - device_loc_src->offset); +} + +static int get_effective_offset(const atcacert_def_t* cert_def, const uint8_t* cert, size_t ref_offset) +{ + size_t sn_offset = 0; + + if (cert_def->type != CERTTYPE_X509 || cert_def->sn_source != SNSRC_STORED_DYNAMIC) + { + return 0; + } + + sn_offset = cert_def->std_cert_elements[STDCERT_CERT_SN].offset; + if (ref_offset <= sn_offset) + { + return 0; + } + + return (int)cert[sn_offset] - (int)cert_def->cert_template[sn_offset]; +} + +int atcacert_cert_build_start(atcacert_build_state_t* build_state, + const atcacert_def_t* cert_def, + uint8_t* cert, + size_t* cert_size, + const uint8_t ca_public_key[64]) +{ + int ret = 0; + + if (build_state == NULL || cert_def == NULL || cert == NULL || cert_size == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + memset(build_state, 0, sizeof(*build_state)); + + build_state->cert_def = cert_def; + build_state->cert = cert; + build_state->cert_size = cert_size; + build_state->max_cert_size = *cert_size; + build_state->is_device_sn = FALSE; + + if (build_state->max_cert_size < build_state->cert_def->cert_template_size) + { + *build_state->cert_size = build_state->cert_def->cert_template_size; + return ATCACERT_E_BUFFER_TOO_SMALL; // cert buffer is too small to contain the template + } + + // Initialize the cert buffer with the cert template + *build_state->cert_size = build_state->cert_def->cert_template_size; + memcpy(build_state->cert, build_state->cert_def->cert_template, build_state->cert_def->cert_template_size); + + if (build_state->cert_def->type == CERTTYPE_X509) + { + // Set a fake signature that should result in the largest X.509 cert. This will ensure + // the cert buffer is large enough early in the cert rebuilding process. + uint8_t large_sig[64]; + memset(large_sig, 0xFF, sizeof(large_sig)); + ret = atcacert_set_signature( + build_state->cert_def, + build_state->cert, + build_state->cert_size, + build_state->max_cert_size, + large_sig); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + } + + if (ca_public_key != NULL) + { + // Set the authority key ID + ret = atcacert_set_auth_key_id( + build_state->cert_def, + build_state->cert, + *build_state->cert_size, + ca_public_key); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_cert_build_process(atcacert_build_state_t* build_state, + const atcacert_device_loc_t* device_loc, + const uint8_t* device_data) +{ + int ret = 0; + size_t i = 0; + const uint8_t* data = NULL; + uint8_t public_key[64]; + static const atcacert_device_loc_t device_sn_dev_loc = { + .zone = DEVZONE_CONFIG, + .slot = 0, + .is_genkey = FALSE, + .offset = 0, + .count = 13 + }; + + if (build_state == NULL || device_loc == NULL || device_data == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + data = atcacert_is_device_loc_match(&build_state->cert_def->cert_sn_dev_loc, device_loc, device_data); + if (data != NULL) + { + ret = atcacert_set_cert_sn( + build_state->cert_def, + build_state->cert, + build_state->cert_size, + build_state->max_cert_size, + data, + build_state->cert_def->cert_sn_dev_loc.count); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + } + + data = atcacert_is_device_loc_match(&build_state->cert_def->public_key_dev_loc, device_loc, device_data); + if (data != NULL) + { + if (build_state->cert_def->public_key_dev_loc.count == 72) + { + // Public key is formatted with padding bytes in front of the X and Y components + atcacert_public_key_remove_padding(data, public_key); + ret = atcacert_set_subj_public_key( + build_state->cert_def, + build_state->cert, + *build_state->cert_size, + public_key); + } + else if (build_state->cert_def->public_key_dev_loc.count == 64) + { + ret = atcacert_set_subj_public_key( + build_state->cert_def, + build_state->cert, + *build_state->cert_size, + data); + } + else + { + return ATCACERT_E_BAD_CERT; // Unexpected public key size + + } + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + } + + data = atcacert_is_device_loc_match(&build_state->cert_def->comp_cert_dev_loc, device_loc, device_data); + if (data != NULL) + { + if (build_state->cert_def->comp_cert_dev_loc.count != 72) + { + return ATCACERT_E_BAD_CERT; // Unexpected compressed certificate size + + } + ret = atcacert_set_comp_cert( + build_state->cert_def, + build_state->cert, + build_state->cert_size, + build_state->max_cert_size, + data); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + } + + if (build_state->cert_def->cert_elements_count > 0 && build_state->cert_def->cert_elements == NULL) + { + return ATCACERT_E_BAD_CERT; + } + for (i = 0; i < build_state->cert_def->cert_elements_count; i++) + { + size_t j; + + + + data = atcacert_is_device_loc_match(&build_state->cert_def->cert_elements[i].device_loc, device_loc, device_data); + if (data != NULL) + { + uint8_t tf_buffer1[256]; + uint8_t tf_buffer2[256]; + uint8_t *dest_pt; + + size_t data_size = build_state->cert_def->cert_elements[i].cert_loc.count; + dest_pt = tf_buffer1; + + for (j = 0; j < sizeof(build_state->cert_def->cert_elements[i].transforms) / sizeof(atcacert_transform_t); j++) + { + size_t destination_size; + atcacert_transform_t transform; + + destination_size = sizeof(tf_buffer1); + transform = build_state->cert_def->cert_elements[i].transforms[j]; + + if (transform == TF_NONE) + { + break; + } + + if (j == 0) + { + data_size = build_state->cert_def->cert_elements[i].device_loc.count; + } + + if ((ret = atcacert_transform_data(transform, data, data_size, dest_pt, &destination_size)) != ATCACERT_E_SUCCESS) + { + return ret; + } + + data_size = destination_size; + + /* The below logic switches between the buffer tf_buffer1 & tf_buffer2 for the transform input & output. + The first transform stores output data to tf_buffer1 and the second transform takes the tf_buffer1 as input & + stores the output in tf_buffer2. + */ + + if ((j % 2) == 0) + { + data = dest_pt; + dest_pt = tf_buffer2; + } + else + { + data = tf_buffer2; + dest_pt = tf_buffer1; + + } + + } + + ret = atcacert_set_cert_element( + build_state->cert_def, + &build_state->cert_def->cert_elements[i].cert_loc, + build_state->cert, + *build_state->cert_size, + data, + data_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + } + } + + data = atcacert_is_device_loc_match(&device_sn_dev_loc, device_loc, device_data); + if (data != NULL) + { + // Get the device SN + build_state->is_device_sn = TRUE; + memcpy(&build_state->device_sn[0], &data[0], 4); + memcpy(&build_state->device_sn[4], &data[8], 5); + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_cert_build_finish(atcacert_build_state_t* build_state) +{ + int ret = 0; + const uint8_t* device_sn = NULL; + + if (build_state == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (build_state->is_device_sn) + { + device_sn = build_state->device_sn; + } + + ret = atcacert_gen_cert_sn(build_state->cert_def, build_state->cert, *build_state->cert_size, device_sn); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + return ret; +} + +int atcacert_is_device_loc_overlap(const atcacert_device_loc_t* device_loc1, + const atcacert_device_loc_t* device_loc2) +{ + if (device_loc1->zone != device_loc2->zone) + { + return FALSE; // Zones don't match, can't overlap + } + if (device_loc1->zone == DEVZONE_DATA && device_loc1->slot != device_loc2->slot) + { + return FALSE; // Data zone, slots don't match, can't overlap + } + if (device_loc1->zone == DEVZONE_DATA && device_loc1->is_genkey != device_loc2->is_genkey) + { + return FALSE; // Data zone, same slot, but read method doesn't match, can't overlap + + } + return !( device_loc1->offset + device_loc1->count <= device_loc2->offset + || device_loc1->offset >= device_loc2->offset + device_loc2->count); +} + +static void atcacert_copy_device_loc_data(const atcacert_device_loc_t* device_loc_src, + const uint8_t* data_src, + const atcacert_device_loc_t* device_loc_dest, + uint8_t* data_dest) +{ + size_t offset = ATCACERT_MAX(device_loc_src->offset, device_loc_dest->offset); + size_t end = ATCACERT_MIN(device_loc_src->offset + device_loc_src->count, device_loc_dest->offset + device_loc_dest->count); + + memcpy(&data_dest[offset - device_loc_dest->offset], &data_src[offset - device_loc_src->offset], end - offset); +} + +int atcacert_get_device_data(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + const atcacert_device_loc_t* device_loc, + uint8_t* device_data) +{ + int ret = 0; + int i = 0; + uint8_t temp_buf[256]; // Must be at least 72 bytes + size_t temp_buf_size = sizeof(temp_buf); + + if (cert_def == NULL || cert == NULL || device_loc == NULL || device_data == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + // Certificate serial number + if (atcacert_is_device_loc_overlap(&cert_def->cert_sn_dev_loc, device_loc)) + { + ret = atcacert_get_cert_sn(cert_def, cert, cert_size, temp_buf, &temp_buf_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + atcacert_copy_device_loc_data(&cert_def->cert_sn_dev_loc, temp_buf, device_loc, device_data); + } + + // Subject public key + if (atcacert_is_device_loc_overlap(&cert_def->public_key_dev_loc, device_loc)) + { + ret = atcacert_get_subj_public_key(cert_def, cert, cert_size, temp_buf); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + if (cert_def->public_key_dev_loc.count == 72) + { + // Public key is formatted with padding bytes in front of the X and Y components + atcacert_public_key_add_padding(temp_buf, temp_buf); + } + else if (cert_def->public_key_dev_loc.count != 64) + { + return ATCACERT_E_BAD_CERT; // Unexpected public key size + } + atcacert_copy_device_loc_data(&cert_def->public_key_dev_loc, temp_buf, device_loc, device_data); + } + + // Compressed certificate + if (atcacert_is_device_loc_overlap(&cert_def->comp_cert_dev_loc, device_loc)) + { + ret = atcacert_get_comp_cert(cert_def, cert, cert_size, temp_buf); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + if (cert_def->comp_cert_dev_loc.count != 72) + { + return ATCACERT_E_BAD_CERT; // Unexpected compressed certificate size + } + atcacert_copy_device_loc_data(&cert_def->comp_cert_dev_loc, temp_buf, device_loc, device_data); + } + + // Additional custom certificate elements + if (cert_def->cert_elements_count > 0 && cert_def->cert_elements == NULL) + { + return ATCACERT_E_BAD_CERT; + } + for (i = 0; i < cert_def->cert_elements_count; i++) + { + if (atcacert_is_device_loc_overlap(&cert_def->cert_elements[i].device_loc, device_loc)) + { + if (sizeof(temp_buf) < cert_def->cert_elements[i].device_loc.count) + { + return ATCACERT_E_BUFFER_TOO_SMALL; + } + ret = atcacert_get_cert_element( + cert_def, + &cert_def->cert_elements[i].cert_loc, + cert, + cert_size, + temp_buf, + cert_def->cert_elements[i].device_loc.count); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + atcacert_copy_device_loc_data(&cert_def->cert_elements[i].device_loc, temp_buf, device_loc, device_data); + } + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_set_subj_public_key(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t cert_size, + const uint8_t subj_public_key[64]) +{ + int ret = 0; + uint8_t key_id[20]; + + if (cert_def == NULL || cert == NULL || subj_public_key == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + ret = atcacert_set_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_PUBLIC_KEY], cert, cert_size, subj_public_key, 64); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_get_key_id(subj_public_key, key_id); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_set_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_SUBJ_KEY_ID], cert, cert_size, key_id, 20); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_get_subj_public_key(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + uint8_t subj_public_key[64]) +{ + if (cert_def == NULL || cert == NULL || subj_public_key == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + return atcacert_get_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_PUBLIC_KEY], cert, cert_size, subj_public_key, 64); +} + +int atcacert_get_subj_key_id(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + uint8_t subj_key_id[20]) +{ + if (cert_def == NULL || cert == NULL || subj_key_id == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + return atcacert_get_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_SUBJ_KEY_ID], cert, cert_size, subj_key_id, 20); +} + +int atcacert_set_signature(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t* cert_size, + size_t max_cert_size, + const uint8_t signature[64]) +{ + int ret = 0; + uint16_t sig_offset; + size_t cur_der_sig_size; + size_t new_der_sig_size; + size_t old_cert_der_length_size; + uint32_t new_cert_length; + + if (cert_def == NULL || cert == NULL || cert_size == NULL || signature == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + sig_offset = cert_def->std_cert_elements[STDCERT_SIGNATURE].offset; + sig_offset += get_effective_offset(cert_def, cert, sig_offset); + + // Non X.509 signatures are treated like normal certificate elements + if (cert_def->type != CERTTYPE_X509) + { + return atcacert_set_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_SIGNATURE], cert, *cert_size, signature, 64); + } + + if (sig_offset >= *cert_size) + { + return ATCACERT_E_ELEM_OUT_OF_BOUNDS; // Signature element is shown as past the end of the certificate + + } + // Current size of the signature is from its offset to the end of the cert + cur_der_sig_size = *cert_size - sig_offset; + + // Find the size of buffer available for the new DER signature + new_der_sig_size = max_cert_size - sig_offset; + + // Set the new signature + ret = atcacert_der_enc_ecdsa_sig_value(signature, &cert[sig_offset], &new_der_sig_size); + if (ret != ATCACERT_E_SUCCESS) + { + if (ret == ATCACERT_E_BUFFER_TOO_SMALL) + { + *cert_size += (int)new_der_sig_size - (int)cur_der_sig_size; // Report the size needed + } + return ret; + } + + *cert_size += (int)new_der_sig_size - (int)cur_der_sig_size; + + old_cert_der_length_size = *cert_size - 1; + ret = atcacert_der_adjust_length( + &cert[1], + &old_cert_der_length_size, + (int)new_der_sig_size - (int)cur_der_sig_size, + &new_cert_length); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + // Tag, length, value + if (1 + old_cert_der_length_size + new_cert_length != *cert_size) + { + return ATCACERT_E_BAD_CERT; + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_get_signature(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + uint8_t signature[64]) +{ + uint16_t sig_offset; + size_t der_sig_size = 0; + + if (cert_def == NULL || cert == NULL || signature == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + sig_offset = cert_def->std_cert_elements[STDCERT_SIGNATURE].offset; + sig_offset += get_effective_offset(cert_def, cert, sig_offset); + + // Non X.509 signatures are treated like normal certificate elements + if (cert_def->type != CERTTYPE_X509) + { + return atcacert_get_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_SIGNATURE], cert, cert_size, signature, 64); + } + + if (sig_offset >= cert_size) + { + return ATCACERT_E_ELEM_OUT_OF_BOUNDS; // Signature element is shown as past the end of the certificate + + } + der_sig_size = cert_size - sig_offset; + return atcacert_der_dec_ecdsa_sig_value(&cert[sig_offset], &der_sig_size, signature); +} + +int atcacert_set_issue_date(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t cert_size, + const atcacert_tm_utc_t* timestamp) +{ + int ret = 0; + uint8_t formatted_date[DATEFMT_MAX_SIZE]; + size_t formatted_date_size = sizeof(formatted_date); + + if (cert_def == NULL || cert == NULL || timestamp == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (cert_def->std_cert_elements[STDCERT_ISSUE_DATE].count == 0) + { + return ATCACERT_E_SUCCESS; // No issue date to be set + + } + ret = atcacert_date_enc(cert_def->issue_date_format, timestamp, formatted_date, &formatted_date_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_set_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_ISSUE_DATE], cert, cert_size, formatted_date, formatted_date_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_get_issue_date(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + atcacert_tm_utc_t* timestamp) +{ + int ret = 0; + uint8_t formatted_date[DATEFMT_MAX_SIZE]; + size_t formatted_date_size = sizeof(formatted_date); + + if (cert_def == NULL || cert == NULL || timestamp == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (cert_def->issue_date_format > sizeof(ATCACERT_DATE_FORMAT_SIZES) / sizeof(ATCACERT_DATE_FORMAT_SIZES[0])) + { + return ATCACERT_E_ERROR; // Format is out of range + + } + formatted_date_size = ATCACERT_DATE_FORMAT_SIZES[cert_def->issue_date_format]; + if (formatted_date_size > sizeof(formatted_date)) + { + return ATCACERT_E_ERROR; // DATEFMT_MAX_SIZE is wrong + + } + ret = atcacert_get_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_ISSUE_DATE], cert, cert_size, formatted_date, formatted_date_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_date_dec(cert_def->issue_date_format, formatted_date, formatted_date_size, timestamp); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_set_expire_date(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t cert_size, + const atcacert_tm_utc_t* timestamp) +{ + int ret = 0; + uint8_t formatted_date[DATEFMT_MAX_SIZE]; + size_t formatted_date_size = sizeof(formatted_date); + + if (cert_def == NULL || cert == NULL || timestamp == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (cert_def->std_cert_elements[STDCERT_EXPIRE_DATE].count == 0) + { + return ATCACERT_E_SUCCESS; // No expire date to be set + + } + ret = atcacert_date_enc(cert_def->expire_date_format, timestamp, formatted_date, &formatted_date_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_set_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_EXPIRE_DATE], cert, cert_size, formatted_date, formatted_date_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_get_expire_date(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + atcacert_tm_utc_t* timestamp) +{ + int ret = 0; + uint8_t formatted_date[DATEFMT_MAX_SIZE]; + size_t formatted_date_size = sizeof(formatted_date); + + if (cert_def == NULL || cert == NULL || timestamp == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (cert_def->expire_date_format > sizeof(ATCACERT_DATE_FORMAT_SIZES) / sizeof(ATCACERT_DATE_FORMAT_SIZES[0])) + { + return ATCACERT_E_ERROR; // Format is out of range + + } + formatted_date_size = ATCACERT_DATE_FORMAT_SIZES[cert_def->expire_date_format]; + if (formatted_date_size > sizeof(formatted_date)) + { + return ATCACERT_E_ERROR; // DATEFMT_MAX_SIZE is wrong + + } + ret = atcacert_get_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_EXPIRE_DATE], cert, cert_size, formatted_date, formatted_date_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_date_dec(cert_def->expire_date_format, formatted_date, formatted_date_size, timestamp); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + return ATCACERT_E_SUCCESS; +} + +static void uint8_to_hex(uint8_t num, uint8_t* hex_str) +{ + uint8_t nibble = (num >> 4) & 0x0F; + + if (nibble < 10) + { + *(hex_str++) = '0' + nibble; + } + else + { + *(hex_str++) = 'A' + (nibble - 10); + } + nibble = num & 0x0F; + if (nibble < 10) + { + *(hex_str++) = '0' + nibble; + } + else + { + *(hex_str++) = 'A' + (nibble - 10); + } +} + +int atcacert_set_signer_id(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t cert_size, + const uint8_t signer_id[2]) +{ + uint8_t hex_str[4]; + + if (cert_def == NULL || cert == NULL || signer_id == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + uint8_to_hex(signer_id[0], &hex_str[0]); + uint8_to_hex(signer_id[1], &hex_str[2]); + + return atcacert_set_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_SIGNER_ID], cert, cert_size, hex_str, 4); +} + +static int hex_to_uint8(const uint8_t hex_str[2], uint8_t* num) +{ + *num = 0; + + if (hex_str[0] >= '0' && hex_str[0] <= '9') + { + *num += (hex_str[0] - '0') << 4; + } + else if (hex_str[0] >= 'A' && hex_str[0] <= 'F') + { + *num += (hex_str[0] - 'A' + 10) << 4; + } + else if (hex_str[0] >= 'a' && hex_str[0] <= 'f') + { + *num += (hex_str[0] - 'a' + 10) << 4; + } + else + { + return ATCACERT_E_DECODING_ERROR; + } + + if (hex_str[1] >= '0' && hex_str[1] <= '9') + { + *num += (hex_str[1] - '0'); + } + else if (hex_str[1] >= 'A' && hex_str[1] <= 'F') + { + *num += (hex_str[1] - 'A' + 10); + } + else if (hex_str[1] >= 'a' && hex_str[1] <= 'f') + { + *num += (hex_str[1] - 'a' + 10); + } + else + { + return ATCACERT_E_DECODING_ERROR; + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_get_signer_id(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + uint8_t signer_id[2]) +{ + int ret = 0; + uint8_t hex_str[4]; + + if (cert_def == NULL || cert == NULL || signer_id == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + ret = atcacert_get_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_SIGNER_ID], cert, cert_size, hex_str, 4); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = hex_to_uint8(&hex_str[0], &signer_id[0]); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = hex_to_uint8(&hex_str[2], &signer_id[1]); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_set_cert_sn(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t* cert_size, + size_t max_cert_size, + const uint8_t* cert_sn, + size_t cert_sn_size) +{ + if (cert_def == NULL || cert == NULL || cert_size == NULL || cert_sn == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (cert_def->type == CERTTYPE_X509 && cert_def->sn_source == SNSRC_STORED_DYNAMIC) + { + // The SN includes the header length, indicating this is a variable length SN + const atcacert_cert_loc_t* sn_cert_loc = &cert_def->std_cert_elements[STDCERT_CERT_SN]; + int sn_offset = (int)cert[sn_cert_loc->offset] - (int)cert_def->cert_template[sn_cert_loc->offset]; + + if (sn_offset != 0) + { + int ret = 0; + size_t der_len_offset = 0; + size_t cert_der_len = 0; + uint32_t cert_len = 0; + size_t tbs_der_len = 0; + + // The SN field has changed size + if (*cert_size + sn_offset > max_cert_size) + { + return ATCACERT_E_BUFFER_TOO_SMALL; // Cert buffer is too small for resizing + } + // Shift everything after the serial number to accommodate its new size + memmove( + &cert[sn_cert_loc->offset + sn_cert_loc->count], + &cert[sn_cert_loc->offset + sn_cert_loc->count + sn_offset], + *cert_size - (sn_cert_loc->offset + sn_cert_loc->count)); + *cert_size += sn_offset; + + // Adjust cert header length + der_len_offset = 1; // Right after first sequence tag + cert_der_len = *cert_size - der_len_offset; // Indicate how much buffer it has to work with + ret = atcacert_der_adjust_length( + &cert[der_len_offset], + &cert_der_len, + sn_offset, + &cert_len); + if (ret != 0) + { + return ret; + } + if (1 + cert_der_len + cert_len != *cert_size) + { + return ATCACERT_E_BAD_CERT; // Cert was malformed + + } + der_len_offset = 1 + cert_der_len + 1; // cert Tag (1), cert len, TBS tag (1) + tbs_der_len = *cert_size - der_len_offset; // Indicate how much buffer it has to work with: + ret = atcacert_der_adjust_length( + &cert[der_len_offset], + &tbs_der_len, + sn_offset, + NULL); + if (ret != 0) + { + return ret; + } + } + + if ((size_t)(cert[sn_cert_loc->offset] + 1) > cert_sn_size) + { + return ATCACERT_E_BAD_PARAMS; + } + cert_sn_size = cert[sn_cert_loc->offset] + 1; + + // Update Cert + } + + return atcacert_set_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_CERT_SN], cert, *cert_size, cert_sn, cert_sn_size); +} + +int atcacert_gen_cert_sn(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t cert_size, + const uint8_t device_sn[9]) +{ + int ret = 0; + size_t sn_size = 0; + uint8_t msg[64 + 3]; + uint8_t sn[32]; + atcacert_tm_utc_t issue_date; + + if (cert_def == NULL || cert == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (cert_def->sn_source == SNSRC_STORED || cert_def->sn_source == SNSRC_STORED_DYNAMIC || cert_def->std_cert_elements[STDCERT_CERT_SN].count == 0) + { + return ATCACERT_E_SUCCESS; // Certificate serial number is not generated or not in the certificate + + } + switch (cert_def->sn_source) + { + case SNSRC_DEVICE_SN: // Cert serial number is 0x40(MSB) + 9-byte device serial number. Only applies to device certificates. + if (device_sn == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + sn_size = 1 + 9; + sn[0] = 0x40; + memcpy(&sn[1], device_sn, 9); + break; + + case SNSRC_SIGNER_ID: // Cert serial number is 0x40(MSB) + 2-byte signer ID. Only applies to signer certificates. + sn_size = 1 + 2; + sn[0] = 0x40; + ret = atcacert_get_signer_id(cert_def, cert, cert_size, &sn[1]); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + break; + + case SNSRC_PUB_KEY_HASH_RAW: // Cert serial number is the SHA256(Subject public key + Encoded dates) + case SNSRC_PUB_KEY_HASH_POS: + case SNSRC_PUB_KEY_HASH: + if (cert_def->std_cert_elements[STDCERT_CERT_SN].count > 32) + { + return ATCACERT_E_UNEXPECTED_ELEM_SIZE; + } + sn_size = cert_def->std_cert_elements[STDCERT_CERT_SN].count; + + // Add public key to hash input + ret = atcacert_get_subj_public_key(cert_def, cert, cert_size, &msg[0]); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + // Add compressed/encoded dates to hash input + ret = atcacert_get_issue_date(cert_def, cert, cert_size, &issue_date); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + ret = atcacert_date_enc_compcert(&issue_date, cert_def->expire_years, &msg[64]); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + ret = atcac_sw_sha2_256(msg, 64 + 3, sn); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + if (cert_def->sn_source == SNSRC_PUB_KEY_HASH_POS || cert_def->sn_source == SNSRC_PUB_KEY_HASH) + { + sn[0] &= 0x7F; // Ensure the SN is positive + } + if (cert_def->sn_source == SNSRC_PUB_KEY_HASH) + { + sn[0] |= 0x40; // Ensure the SN doesn't have any trimmable bytes + } + break; + + case SNSRC_DEVICE_SN_HASH_RAW: // Cert serial number is the SHA256(Device SN + Encoded dates). Only applies to device certificates. + case SNSRC_DEVICE_SN_HASH_POS: + case SNSRC_DEVICE_SN_HASH: + if (device_sn == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + if (cert_def->std_cert_elements[STDCERT_CERT_SN].count > 32) + { + return ATCACERT_E_UNEXPECTED_ELEM_SIZE; + } + sn_size = cert_def->std_cert_elements[STDCERT_CERT_SN].count; + + // Add device SN to the hash input + memcpy(&msg[0], device_sn, 9); + + // Add compressed/encoded dates to hash input + ret = atcacert_get_issue_date(cert_def, cert, cert_size, &issue_date); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + ret = atcacert_date_enc_compcert(&issue_date, cert_def->expire_years, &msg[9]); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + ret = atcac_sw_sha2_256(msg, 9 + 3, sn); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + if (cert_def->sn_source == SNSRC_DEVICE_SN_HASH_POS || cert_def->sn_source == SNSRC_DEVICE_SN_HASH) + { + sn[0] &= 0x7F; // Ensure the SN is positive + } + if (cert_def->sn_source == SNSRC_DEVICE_SN_HASH) + { + sn[0] |= 0x40; // Ensure the SN doesn't have any trimmable bytes + } + break; + + default: + return ATCACERT_E_BAD_PARAMS; + } + + return atcacert_set_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_CERT_SN], cert, cert_size, sn, sn_size); +} + +int atcacert_get_cert_sn(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + uint8_t* cert_sn, + size_t* cert_sn_size) +{ + if (cert_def == NULL || cert == NULL || cert_sn == NULL || cert_sn_size == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (*cert_sn_size < cert_def->std_cert_elements[STDCERT_CERT_SN].count) + { + *cert_sn_size = cert_def->std_cert_elements[STDCERT_CERT_SN].count; + return ATCACERT_E_BUFFER_TOO_SMALL; + } + + *cert_sn_size = cert_def->std_cert_elements[STDCERT_CERT_SN].count; + + return atcacert_get_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_CERT_SN], cert, cert_size, cert_sn, *cert_sn_size); +} + +int atcacert_set_auth_key_id(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t cert_size, + const uint8_t auth_public_key[64]) +{ + int ret = 0; + uint8_t key_id[20]; + + if (cert_def == NULL || cert == NULL || auth_public_key == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + ret = atcacert_get_key_id(auth_public_key, key_id); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_set_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_AUTH_KEY_ID], cert, cert_size, key_id, 20); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_set_auth_key_id_raw(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t cert_size, + const uint8_t* auth_key_id) +{ + int ret = 0; + + if (cert_def == NULL || cert == NULL || auth_key_id == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + ret = atcacert_set_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_AUTH_KEY_ID], cert, cert_size, auth_key_id, cert_def->std_cert_elements[STDCERT_AUTH_KEY_ID].count); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_get_auth_key_id(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + uint8_t auth_key_id[20]) +{ + if (cert_def == NULL || cert == NULL || auth_key_id == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + return atcacert_get_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_AUTH_KEY_ID], cert, cert_size, auth_key_id, 20); +} + +int atcacert_set_comp_cert(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t* cert_size, + size_t max_cert_size, + const uint8_t comp_cert[72]) +{ + int ret = 0; + uint8_t enc_dates[3]; + uint8_t signer_id[2]; + uint8_t template_id; + uint8_t chain_id; + uint8_t sn_source; + uint8_t format; + atcacert_tm_utc_t issue_date; + atcacert_tm_utc_t expire_date; + + if (cert_def == NULL || cert == NULL || cert_size == NULL || comp_cert == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + format = comp_cert[70] & 0x0F; + if (format != 0) + { + return ATCACERT_E_DECODING_ERROR; // Unknown format + + } + memcpy(enc_dates, &comp_cert[64], 3); + memcpy(signer_id, &comp_cert[67], 2); + template_id = (comp_cert[69] >> 4) & 0x0F; + chain_id = comp_cert[69] & 0x0F; + sn_source = (comp_cert[70] >> 4) & 0x0F; + + if (template_id != cert_def->template_id || chain_id != cert_def->chain_id || sn_source != cert_def->sn_source) + { + return ATCACERT_E_WRONG_CERT_DEF; + } + + ret = atcacert_set_signature( + cert_def, + cert, + cert_size, + max_cert_size, + &comp_cert[0]); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_date_dec_compcert(enc_dates, cert_def->expire_date_format, &issue_date, &expire_date); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_set_issue_date(cert_def, cert, *cert_size, &issue_date); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_set_expire_date(cert_def, cert, *cert_size, &expire_date); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_set_signer_id(cert_def, cert, *cert_size, signer_id); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_get_comp_cert(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + uint8_t comp_cert[72]) +{ + int ret = 0; + atcacert_tm_utc_t issue_date; + + if (cert_def == NULL || cert == NULL || comp_cert == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + ret = atcacert_get_signature(cert_def, cert, cert_size, &comp_cert[0]); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_get_issue_date(cert_def, cert, cert_size, &issue_date); + if (ret == ATCACERT_E_ELEM_MISSING) + { + // No issue date in cert, just use lowest possible date + issue_date.tm_year = 2000 - 1900; + issue_date.tm_mon = 1 - 1; + issue_date.tm_mday = 1; + issue_date.tm_hour = 0; + issue_date.tm_min = 0; + issue_date.tm_sec = 0; + } + else if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + ret = atcacert_date_enc_compcert(&issue_date, cert_def->expire_years, &comp_cert[64]); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_get_signer_id(cert_def, cert, cert_size, &comp_cert[67]); + if (ret == ATCACERT_E_ELEM_MISSING) + { + memset(&comp_cert[67], 0, 2); // No signer ID in cert, use 0 + } + else if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + comp_cert[69] = ((cert_def->template_id & 0x0F) << 4) | (cert_def->chain_id & 0x0F); + comp_cert[70] = ((uint8_t)(cert_def->sn_source & 0x0F) << 4) | 0; + comp_cert[71] = 0; + + return ATCACERT_E_SUCCESS; +} + +int atcacert_get_tbs(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + const uint8_t** tbs, + size_t* tbs_size) +{ + int eff_offset = 0; + + if (cert_def == NULL || cert == NULL || tbs == NULL || tbs_size == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + eff_offset = get_effective_offset(cert_def, cert, cert_def->tbs_cert_loc.offset + cert_def->tbs_cert_loc.count); + + if ((size_t)(cert_def->tbs_cert_loc.offset + cert_def->tbs_cert_loc.count + eff_offset) > cert_size) + { + return ATCACERT_E_BAD_CERT; + } + + *tbs = &cert[cert_def->tbs_cert_loc.offset]; + *tbs_size = cert_def->tbs_cert_loc.count + eff_offset; + + return ATCACERT_E_SUCCESS; +} + +int atcacert_get_tbs_digest(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + uint8_t tbs_digest[32]) +{ + int ret = ATCACERT_E_SUCCESS; + const uint8_t* tbs = NULL; + size_t tbs_size = 0; + + if (cert_def == NULL || cert == NULL || tbs_digest == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + ret = atcacert_get_tbs(cert_def, cert, cert_size, &tbs, &tbs_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcac_sw_sha2_256(tbs, tbs_size, tbs_digest); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + return ret; +} + +int atcacert_set_cert_element(const atcacert_def_t* cert_def, + const atcacert_cert_loc_t* cert_loc, + uint8_t* cert, + size_t cert_size, + const uint8_t* data, + size_t data_size) +{ + int eff_offset = 0; + + if (cert_def == NULL || cert_loc == NULL || cert == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (cert_loc->count == 0) + { + return ATCACERT_E_SUCCESS; // This element doesn't exist in the cert, but we treat this as a success + + } + if (data == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + // Don't validate for dynamic cert SN + if (!(cert_def->type == CERTTYPE_X509 && + cert_def->sn_source == SNSRC_STORED_DYNAMIC && + cert_loc->offset == cert_def->std_cert_elements[STDCERT_CERT_SN].offset) && + data_size != cert_loc->count) + { + return ATCACERT_E_UNEXPECTED_ELEM_SIZE; + } + + eff_offset = get_effective_offset(cert_def, cert, cert_loc->offset); + + if ((size_t)(cert_loc->offset + data_size + eff_offset) > cert_size) + { + return ATCACERT_E_ELEM_OUT_OF_BOUNDS; + } + + memcpy(&cert[cert_loc->offset + eff_offset], data, data_size); + + return ATCACERT_E_SUCCESS; +} + +int atcacert_get_cert_element(const atcacert_def_t* cert_def, + const atcacert_cert_loc_t* cert_loc, + const uint8_t* cert, + size_t cert_size, + uint8_t* data, + size_t data_size) +{ + int eff_offset = 0; + + if (cert_def == NULL || cert_loc == NULL || cert == NULL || data == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (cert_loc->count == 0) + { + return ATCACERT_E_ELEM_MISSING; // This element doesn't exist in the certificate + + } + if (cert_loc->count != data_size) + { + return ATCACERT_E_UNEXPECTED_ELEM_SIZE; + } + + eff_offset = get_effective_offset(cert_def, cert, cert_loc->offset); + + if ((size_t)(cert_loc->offset + cert_loc->count + eff_offset) > cert_size) + { + return ATCACERT_E_ELEM_OUT_OF_BOUNDS; + } + + memcpy(data, &cert[cert_loc->offset + eff_offset], data_size); + + return ATCACERT_E_SUCCESS; +} + +int atcacert_get_key_id(const uint8_t public_key[64], uint8_t key_id[20]) +{ + uint8_t msg[65]; + + if (public_key == NULL || key_id == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + msg[0] = 0x04; + memcpy(&msg[1], public_key, 64); + + return atcac_sw_sha1(msg, sizeof(msg), key_id); +} + +void atcacert_public_key_add_padding(const uint8_t raw_key[64], uint8_t padded_key[72]) +{ + memmove(&padded_key[40], &raw_key[32], 32); // Move Y to padded position + memset(&padded_key[36], 0, 4); // Add Y padding bytes + memmove(&padded_key[4], &raw_key[0], 32); // Move X to padded position + memset(&padded_key[0], 0, 4); // Add X padding bytes +} + +void atcacert_public_key_remove_padding(const uint8_t padded_key[72], uint8_t raw_key[64]) +{ + memmove(&raw_key[0], &padded_key[4], 32); // Move X + memmove(&raw_key[32], &padded_key[40], 32); // Move Y +} + +int atcacert_transform_data(atcacert_transform_t transform, + const uint8_t* data, + size_t data_size, + uint8_t* destination, + size_t* destination_size) +{ + int status = ATCACERT_E_INVALID_TRANSFORM; + + if (destination == NULL || destination_size == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + switch (transform) + { + case TF_NONE: + if (*destination_size >= data_size) + { + memcpy(destination, data, data_size); + *destination_size = data_size; + } + else + { + status = ATCA_SMALL_BUFFER; + } + case TF_REVERSE: + status = atcab_reversal(data, data_size, destination, destination_size); + break; + case TF_BIN2HEX_UC: + status = atcab_bin2hex_(data, data_size, (char*)destination, destination_size, false, false, true); + break; + case TF_BIN2HEX_LC: + status = atcab_bin2hex_(data, data_size, (char*)destination, destination_size, false, false, false); + break; + case TF_HEX2BIN_UC: + status = atcab_hex2bin_((const char*)data, data_size, destination, destination_size, false); + break; + case TF_HEX2BIN_LC: + status = atcab_hex2bin_((const char*)data, data_size, destination, destination_size, false); + break; + case TF_BIN2HEX_SPACE_UC: + status = atcab_bin2hex_(data, data_size, (char*)destination, destination_size, false, true, true); + break; + case TF_BIN2HEX_SPACE_LC: + status = atcab_bin2hex_(data, data_size, (char*)destination, destination_size, false, true, false); + break; + case TF_HEX2BIN_SPACE_UC: + status = atcab_hex2bin_((const char*)data, data_size, destination, destination_size, true); + break; + case TF_HEX2BIN_SPACE_LC: + status = atcab_hex2bin_((const char*)data, data_size, destination, destination_size, true); + break; + default: + status = ATCACERT_E_INVALID_TRANSFORM; + break; + } + + return status; +} + +int atcacert_max_cert_size(const atcacert_def_t* cert_def, + size_t* max_cert_size) +{ + uint8_t template_sn_size; + + if (cert_def == NULL || max_cert_size == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (cert_def->type == CERTTYPE_X509) + { + // Signature offset plus the largest P-256 ECDSA-Sig-Value Bit String (zero padded R and S) + *max_cert_size = cert_def->std_cert_elements[STDCERT_SIGNATURE].offset + 75; + + if (cert_def->sn_source == SNSRC_STORED_DYNAMIC) + { + // Certificate definition uses a variable sized serial number + template_sn_size = cert_def->cert_template[cert_def->std_cert_elements[STDCERT_CERT_SN].offset]; + if (template_sn_size > 127) + { + // Certificate serial number is larger than expected. Multi-byte sizes not handled + // as this should never happen. + return ATCACERT_E_BAD_CERT; + } + + // Add the max possible serial number to the max size + *max_cert_size += 128 - template_sn_size; + } + } + else + { + // There are no variable length elements in custom certs, so the cert + // size is simply the template size + *max_cert_size = cert_def->cert_template_size; + } + + return ATCACERT_E_SUCCESS; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.h new file mode 100644 index 0000000..edb50c7 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.h @@ -0,0 +1,818 @@ +/** + * \file + * \brief Declarations for certificates related to ECC CryptoAuthentication devices. + * These are the definitions required to define a certificate and its various + * elements with regards to the CryptoAuthentication ECC devices. + * + * Only the dynamic elements of a certificate (the parts of the certificate + * that change from device to device) are stored on the ATECC device. The + * definitions here describe the form of the certificate, and where the + * dynamic elements can be found both on the ATECC device itself and in the + * certificate template. + * + * This also defines utility functions for working with the certificates and their definitions. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +#ifndef ATCACERT_DEF_H +#define ATCACERT_DEF_H + +#include +#include +#include "atcacert.h" +#include "atcacert_date.h" +#include "basic/atca_helpers.h" + +#define ATCA_MAX_TRANSFORMS 2 + + +/** \defgroup atcacert_ Certificate manipulation methods (atcacert_) + * + * \brief + * These methods provide convenient ways to perform certification I/O with + * CryptoAuth chips and perform certificate manipulation in memory + * + @{ */ + +/** + * Types of certificates. + */ +typedef enum atcacert_cert_type_e +{ + CERTTYPE_X509, //!< Standard X509 certificate + CERTTYPE_CUSTOM //!< Custom format +} atcacert_cert_type_t; + +/** + * Sources for the certificate serial number. + */ +typedef enum atcacert_cert_sn_src_e +{ + SNSRC_STORED = 0x0, //!< Cert serial is stored on the device. + SNSRC_STORED_DYNAMIC = 0x7, //!< Cert serial is stored on the device with the first byte being the DER size (X509 certs only). + SNSRC_DEVICE_SN = 0x8, //!< Cert serial number is 0x40(MSB) + 9-byte device serial number. Only applies to device certificates. + SNSRC_SIGNER_ID = 0x9, //!< Cert serial number is 0x40(MSB) + 2-byte signer ID. Only applies to signer certificates. + SNSRC_PUB_KEY_HASH = 0xA, //!< Cert serial number is the SHA256(Subject public key + Encoded dates), with uppermost 2 bits set to 01. + SNSRC_DEVICE_SN_HASH = 0xB, //!< Cert serial number is the SHA256(Device SN + Encoded dates), with uppermost 2 bits set to 01. Only applies to device certificates. + SNSRC_PUB_KEY_HASH_POS = 0xC, //!< Depreciated, don't use. Cert serial number is the SHA256(Subject public key + Encoded dates), with MSBit set to 0 to ensure it's positive. + SNSRC_DEVICE_SN_HASH_POS = 0xD, //!< Depreciated, don't use. Cert serial number is the SHA256(Device SN + Encoded dates), with MSBit set to 0 to ensure it's positive. Only applies to device certificates. + SNSRC_PUB_KEY_HASH_RAW = 0xE, //!< Depreciated, don't use. Cert serial number is the SHA256(Subject public key + Encoded dates). + SNSRC_DEVICE_SN_HASH_RAW = 0xF //!< Depreciated, don't use. Cert serial number is the SHA256(Device SN + Encoded dates). Only applies to device certificates. +} atcacert_cert_sn_src_t; + +/** + * ATECC device zones. The values match the Zone Encodings as specified in the datasheet. + */ +typedef enum atcacert_device_zone_e +{ + DEVZONE_CONFIG = 0x00, //!< Configuration zone. + DEVZONE_OTP = 0x01, //!< One Time Programmable zone. + DEVZONE_DATA = 0x02, //!< Data zone (slots). + DEVZONE_NONE = 0x07 //!< Special value used to indicate there is no device location. +} atcacert_device_zone_t; + +/** \brief How to transform the data from the device to the certificate. + */ +typedef enum atcacert_transform_e +{ + TF_NONE, //!< No transform, data is used byte for byte + TF_REVERSE, //!< Reverse the bytes (e.g. change endianness) + TF_BIN2HEX_UC, //!< Convert raw binary into ASCII hex, uppercase + TF_BIN2HEX_LC, //!< Convert raw binary into ASCII hex, lowercase + TF_HEX2BIN_UC, //!< Convert ASCII hex, uppercase to binary + TF_HEX2BIN_LC, //!< Convert ASCII hex, lowercase to binary + TF_BIN2HEX_SPACE_UC, //!< Convert raw binary into ASCII hex, uppercase space between bytes + TF_BIN2HEX_SPACE_LC, //!< Convert raw binary into ASCII hex, lowercase space between bytes + TF_HEX2BIN_SPACE_UC, //!< Convert ASCII hex, uppercase with spaces between bytes to binary + TF_HEX2BIN_SPACE_LC, //!< Convert ASCII hex, lowercase with spaces between bytes to binary +} atcacert_transform_t; + +/** + * Standard dynamic certificate elements. + */ +typedef enum atcacert_std_cert_element_e +{ + STDCERT_PUBLIC_KEY, + STDCERT_SIGNATURE, + STDCERT_ISSUE_DATE, + STDCERT_EXPIRE_DATE, + STDCERT_SIGNER_ID, + STDCERT_CERT_SN, + STDCERT_AUTH_KEY_ID, + STDCERT_SUBJ_KEY_ID, + STDCERT_NUM_ELEMENTS //!< Special item to give the number of elements in this enum +} atcacert_std_cert_element_t; + +// Some of these structures may need to be byte-accurate + +#pragma pack(push, 1) + +/** + * Defines a chunk of data in an ATECC device. + */ +typedef struct atcacert_device_loc_s +{ + atcacert_device_zone_t zone; //!< Zone in the device. + uint8_t slot; //!< Slot within the data zone. Only applies if zone is DEVZONE_DATA. + uint8_t is_genkey; //!< If true, use GenKey command to get the contents instead of Read. + uint16_t offset; //!< Byte offset in the zone. + uint16_t count; //!< Byte count. +} atcacert_device_loc_t; + +/** + * Defines a chunk of data in a certificate template. + */ +typedef struct atcacert_cert_loc_s +{ + uint16_t offset; //!< Byte offset in the certificate template. + uint16_t count; //!< Byte count. Set to 0 if it doesn't exist. +} atcacert_cert_loc_t; + +/** + * Defines a generic dynamic element for a certificate including the device and template locations. + */ + +typedef struct atcacert_cert_element_s +{ + char id[25]; //!< ID identifying this element. + atcacert_device_loc_t device_loc; //!< Location in the device for the element. + atcacert_cert_loc_t cert_loc; //!< Location in the certificate template for the element. + atcacert_transform_t transforms[ATCA_MAX_TRANSFORMS]; //!< List of transforms from device to cert for this element. +} atcacert_cert_element_t; + +/** + * Defines a certificate and all the pieces to work with it. + * + * If any of the standard certificate elements (std_cert_elements) are not a part of the certificate + * definition, set their count to 0 to indicate their absence. + */ +typedef struct atcacert_def_s +{ + atcacert_cert_type_t type; //!< Certificate type. + uint8_t template_id; //!< ID for the this certificate definition (4-bit value). + uint8_t chain_id; //!< ID for the certificate chain this definition is a part of (4-bit value). + uint8_t private_key_slot; //!< If this is a device certificate template, this is the device slot for the device private key. + atcacert_cert_sn_src_t sn_source; //!< Where the certificate serial number comes from (4-bit value). + atcacert_device_loc_t cert_sn_dev_loc; //!< Only applies when sn_source is SNSRC_STORED or SNSRC_STORED_DYNAMIC. Describes where to get the certificate serial number on the device. + atcacert_date_format_t issue_date_format; //!< Format of the issue date in the certificate. + atcacert_date_format_t expire_date_format; //!< format of the expire date in the certificate. + atcacert_cert_loc_t tbs_cert_loc; //!< Location in the certificate for the TBS (to be signed) portion. + uint8_t expire_years; //!< Number of years the certificate is valid for (5-bit value). 0 means no expiration. + atcacert_device_loc_t public_key_dev_loc; //!< Where on the device the public key can be found. + atcacert_device_loc_t comp_cert_dev_loc; //!< Where on the device the compressed cert can be found. + atcacert_cert_loc_t std_cert_elements[STDCERT_NUM_ELEMENTS]; //!< Where in the certificate template the standard cert elements are inserted. + const atcacert_cert_element_t* cert_elements; //!< Additional certificate elements outside of the standard certificate contents. + uint8_t cert_elements_count; //!< Number of additional certificate elements in cert_elements. + const uint8_t* cert_template; //!< Pointer to the actual certificate template data. + uint16_t cert_template_size; //!< Size of the certificate template in cert_template in bytes. + const struct atcacert_def_s* ca_cert_def; //!< Certificate definition of the CA certificate +} atcacert_def_t; + +/** + * Tracks the state of a certificate as it's being rebuilt from device information. + */ +typedef struct atcacert_build_state_s +{ + const atcacert_def_t* cert_def; //!< Certificate definition for the certificate being rebuilt. + uint8_t* cert; //!< Buffer to contain the rebuilt certificate. + size_t* cert_size; //!< Current size of the certificate in bytes. + size_t max_cert_size; //!< Max size of the cert buffer in bytes. + uint8_t is_device_sn; //!< Indicates the structure contains the device SN. + uint8_t device_sn[9]; //!< Storage for the device SN, when it's found. +} atcacert_build_state_t; + +#pragma pack(pop) + +// Inform function naming when compiling in C++ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Add all the device locations required to rebuild the specified certificate (cert_def) to + * a device locations list. + * + * The block_size parameter will adjust all added device locations to have a offset and count that + * aligns with that block size. This allows one to generate a list of device locations that matches + * specific read or write semantics (e.g. 4 byte or 32 byte reads). + * + * \param[in] cert_def Certificate definition containing all the device locations + * to add to the list. + * \param[inout] device_locs List of device locations to add to. + * \param[inout] device_locs_count As input, existing size of the device locations list. + * As output, the new size of the device locations list. + * \param[in] device_locs_max_count Maximum number of elements device_locs can hold. + * \param[in] block_size Block size to align all offsets and counts to when adding + * device locations. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_get_device_locs(const atcacert_def_t* cert_def, + atcacert_device_loc_t* device_locs, + size_t* device_locs_count, + size_t device_locs_max_count, + size_t block_size); + +/** + * \brief Starts the certificate rebuilding process. + * + * \param[out] build_state Structure is initialized to start the certificate building process. + * Will be passed to the other certificate building functions. + * \param[in] cert_def Certificate definition for the certificate being built. + * \param[in] cert Buffer to contain the rebuilt certificate. + * \param[in] cert_size As input, the size of the cert buffer in bytes. This value will be + * adjusted to the current/final size of the certificate through the + * building process. + * \param[in] ca_public_key ECC P256 public key of the certificate authority (issuer) for the + * certificate being built. Set to NULL if the authority key id is + * not needed, set properly in the cert_def template, or stored on the + * device as specified in the cert_def cert_elements. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_cert_build_start(atcacert_build_state_t* build_state, + const atcacert_def_t* cert_def, + uint8_t* cert, + size_t* cert_size, + const uint8_t ca_public_key[64]); + +/** + * \brief Process information read from the ATECC device. If it contains information for the + * certificate, it will be incorporated into the certificate. + * + * \param[in] build_state Current certificate building state. + * \param[in] device_loc Device location structure describing where on the device the following + * data came from. + * \param[in] device_data Actual data from the device. It should represent the offset and byte + * count specified in the device_loc parameter. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_cert_build_process(atcacert_build_state_t* build_state, + const atcacert_device_loc_t* device_loc, + const uint8_t* device_data); + +/** + * \brief Completes any final certificate processing required after all data from the device has + * been incorporated. + * + * The final certificate and its size in bytes are contained in the cert and cert_size elements + * of the build_state structure. This will be the same buffers as supplied to the + * atcacert_cert_build_start function at the beginning of the certificate rebuilding process. + * + * \param[in] build_state Current certificate build state. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_cert_build_finish(atcacert_build_state_t* build_state); + +/** + * \brief Gets the dynamic data that would be saved to the specified device location. This + * function is primarily used to break down a full certificate into the dynamic components + * to be saved to a device. + * + * The atcacert_add_device_locs function can be used to generate a list of device locations a + * particular certificate definition requires. + * + * \param[in] cert_def Certificate definition for the certificate we're getting data from. + * \param[in] cert Certificate to get the device data from. + * \param[in] cert_size Size of the certificate in bytes. + * \param[in] device_loc Device location to request data for. + * \param[out] device_data Buffer that represents the device data in device_loc. Required to be + * at least device_loc.count in size. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_get_device_data(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + const atcacert_device_loc_t* device_loc, + uint8_t* device_data); + +/** + * \brief Sets the subject public key and subject key ID in a certificate. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[inout] cert Certificate to update. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[in] subj_public_key Subject public key as X and Y integers concatenated together. 64 bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_set_subj_public_key(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t cert_size, + const uint8_t subj_public_key[64]); + +/** + * \brief Gets the subject public key from a certificate. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[in] cert Certificate to get element from. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[out] subj_public_key Subject public key is returned in this buffer. Formatted at X and Y + * integers concatenated together. 64 bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_get_subj_public_key(const atcacert_def_t * cert_def, + const uint8_t * cert, + size_t cert_size, + uint8_t subj_public_key[64]); + +/** + * \brief Gets the subject key ID from a certificate. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[in] cert Certificate to get element from. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[out] subj_key_id Subject key ID is returned in this buffer. 20 bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_get_subj_key_id(const atcacert_def_t * cert_def, + const uint8_t * cert, + size_t cert_size, + uint8_t subj_key_id[20]); + +/** + * \brief Sets the signature in a certificate. This may alter the size of the X.509 certificates. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[inout] cert Certificate to update. + * \param[inout] cert_size As input, size of the certificate (cert) in bytes. + * As output, the new size of the certificate. + * \param[in] max_cert_size Maximum size of the cert buffer. + * \param[in] signature Signature as R and S integers concatenated together. 64 bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_set_signature(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t* cert_size, + size_t max_cert_size, + const uint8_t signature[64]); + +/** + * \brief Gets the signature from a certificate. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[in] cert Certificate to get element from. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[out] signature Signature is returned in this buffer. Formatted at R and S integers + * concatenated together. 64 bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_get_signature(const atcacert_def_t * cert_def, + const uint8_t * cert, + size_t cert_size, + uint8_t signature[64]); + +/** + * \brief Sets the issue date (notBefore) in a certificate. Will be formatted according to the date + * format specified in the certificate definition. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[inout] cert Certificate to update. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[in] timestamp Issue date. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_set_issue_date(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t cert_size, + const atcacert_tm_utc_t* timestamp); + +/** + * \brief Gets the issue date from a certificate. Will be parsed according to the date format + * specified in the certificate definition. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[in] cert Certificate to get element from. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[out] timestamp Issue date is returned in this structure. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_get_issue_date(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + atcacert_tm_utc_t* timestamp); + +/** + * \brief Sets the expire date (notAfter) in a certificate. Will be formatted according to the date + * format specified in the certificate definition. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[inout] cert Certificate to update. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[in] timestamp Expire date. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_set_expire_date(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t cert_size, + const atcacert_tm_utc_t* timestamp); + +/** + * \brief Gets the expire date from a certificate. Will be parsed according to the date format + * specified in the certificate definition. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[in] cert Certificate to get element from. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[out] timestamp Expire date is returned in this structure. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_get_expire_date(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + atcacert_tm_utc_t* timestamp); + +/** + * \brief Sets the signer ID in a certificate. Will be formatted as 4 upper-case hex digits. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[inout] cert Certificate to update. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[in] signer_id Signer ID. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_set_signer_id(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t cert_size, + const uint8_t signer_id[2]); + +/** + * \brief Gets the signer ID from a certificate. Will be parsed as 4 upper-case hex digits. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[in] cert Certificate to get element from. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[out] signer_id Signer ID will be returned in this buffer. 2 bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_get_signer_id(const atcacert_def_t * cert_def, + const uint8_t * cert, + size_t cert_size, + uint8_t signer_id[2]); + +/** + * \brief Sets the certificate serial number in a certificate. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[inout] cert Certificate to update. + * \param[inout] cert_size Size of the certificate (cert) in bytes. + * \param[in] max_cert_size Maximum size of the cert buffer. + * \param[in] cert_sn Certificate serial number. + * \param[in] cert_sn_size Size of the certificate serial number in bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_set_cert_sn(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t* cert_size, + size_t max_cert_size, + const uint8_t* cert_sn, + size_t cert_sn_size); + +/** + * \brief Sets the certificate serial number by generating it from other information in the + * certificate using the scheme specified by sn_source in cert_def. See the + * + * This method requires certain elements in the certificate be set properly as they're used for + * generating the serial number. See atcacert_cert_sn_src_t for what elements should be set in the + * certificate beforehand. If the sn_source is set to SNSRC_STORED or SNSRC_STORED_DYNAMIC, the + * function will return ATCACERT_E_SUCCESS without making any changes to the certificate. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[inout] cert Certificate to update. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[in] device_sn Device serial number, only used if required by the sn_source scheme. + * Can be set to NULL, if not required. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_gen_cert_sn(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t cert_size, + const uint8_t device_sn[9]); + +/** + * \brief Gets the certificate serial number from a certificate. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[in] cert Certificate to get element from. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[out] cert_sn Certificate SN will be returned in this buffer. + * \param[inout] cert_sn_size As input, the size of the cert_sn buffer. + * As output, the size of the certificate SN (cert_sn) in bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_get_cert_sn(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + uint8_t* cert_sn, + size_t* cert_sn_size); + +/** + * \brief Sets the authority key ID in a certificate. Note that this takes the actual public key + * creates a key ID from it. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[inout] cert Certificate to update. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[in] auth_public_key Authority public key as X and Y integers concatenated together. + * 64 bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_set_auth_key_id(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t cert_size, + const uint8_t auth_public_key[64]); + +/** + * \brief Sets the authority key ID in a certificate. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[inout] cert Certificate to update. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[in] auth_key_id Authority key ID. Same size as defined in the cert_def. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_set_auth_key_id_raw(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t cert_size, + const uint8_t* auth_key_id); + +/** + * \brief Gets the authority key ID from a certificate. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[in] cert Certificate to get element from. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[out] auth_key_id Authority key ID is returned in this buffer. 20 bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_get_auth_key_id(const atcacert_def_t * cert_def, + const uint8_t * cert, + size_t cert_size, + uint8_t auth_key_id[20]); + +/** + * \brief Sets the signature, issue date, expire date, and signer ID found in the compressed + * certificate. This also checks fields common between the cert_def and the compressed + * certificate to make sure they match. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[inout] cert Certificate to update. + * \param[inout] cert_size As input, size of the certificate (cert) in bytes. + * As output, the new size of the certificate. + * \param[in] max_cert_size Maximum size of the cert buffer. + * \param[in] comp_cert Compressed certificate. 72 bytes. + * + * \return ATCACERT_E_SUCCESS on success. ATCACERT_E_WRONG_CERT_DEF if the template ID, chain ID, and/or SN source + * don't match between the cert_def and the compressed certificate. + */ +int atcacert_set_comp_cert(const atcacert_def_t* cert_def, + uint8_t* cert, + size_t* cert_size, + size_t max_cert_size, + const uint8_t comp_cert[72]); + +/** + * \brief Generate the compressed certificate for the given certificate. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[in] cert Certificate to generate the compressed certificate for. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[out] comp_cert Compressed certificate is returned in this buffer. 72 bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_get_comp_cert(const atcacert_def_t * cert_def, + const uint8_t * cert, + size_t cert_size, + uint8_t comp_cert[72]); + +/** + * \brief Get a pointer to the TBS data in a certificate. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[in] cert Certificate to get the TBS data pointer for. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[out] tbs Pointer to a const pointer that will be set the start of the TBS data. + * \param[out] tbs_size Size of the TBS data will be returned here. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_get_tbs(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + const uint8_t** tbs, + size_t* tbs_size); + +/** + * \brief Get the SHA256 digest of certificate's TBS data. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[in] cert Certificate to get the TBS data pointer for. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[out] tbs_digest TBS data digest will be returned here. 32 bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_get_tbs_digest(const atcacert_def_t * cert_def, + const uint8_t * cert, + size_t cert_size, + uint8_t tbs_digest[32]); + +/** + * \brief Sets an element in a certificate. The data_size must match the size in cert_loc. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[in] cert_loc Certificate location for this element. + * \param[inout] cert Certificate to update. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[in] data Element data to insert into the certificate. Buffer must contain + * cert_loc.count bytes to be copied into the certificate. + * \param[in] data_size Size of the data in bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_set_cert_element(const atcacert_def_t* cert_def, + const atcacert_cert_loc_t* cert_loc, + uint8_t* cert, + size_t cert_size, + const uint8_t* data, + size_t data_size); + +/** + * \brief Gets an element from a certificate. + * + * \param[in] cert_def Certificate definition for the certificate. + * \param[in] cert_loc Certificate location for this element. + * \param[in] cert Certificate to get element from. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[out] data Element data will be returned in this buffer. This buffer must be large + * enough to hold cert_loc.count bytes. + * \param[in] data_size Expected size of the cert element data. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_get_cert_element(const atcacert_def_t* cert_def, + const atcacert_cert_loc_t* cert_loc, + const uint8_t* cert, + size_t cert_size, + uint8_t* data, + size_t data_size); + + +// Below are utility functions for dealing with various bits for data conversion and wrangling + +/** + * \brief Calculates the key ID for a given public ECC P256 key. + * + * Uses method 1 for calculating the keyIdentifier as specified by RFC 5280, section 4.2.1.2: + * (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the + * value of the BIT STRING subjectPublicKey (excluding the tag, + * length, and number of unused bits). + * + * \param[in] public_key ECC P256 public key to calculate key key ID for. Formatted as the X and + * Y integers concatenated together. 64 bytes. + * \param[in] key_id Calculated key ID will be returned in this buffer. 20 bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_get_key_id(const uint8_t public_key[64], uint8_t key_id[20]); + +/** + * \brief Merge a new device location into a list of device locations. If the new location overlaps + * with an existing location, the existing one will be modified to encompass both. Otherwise + * the new location is appended to the end of the list. + * + * The block_size parameter will adjust all added device locations to have an offset and count that + * aligns with that block size. This allows one to generate a list of device locations that matches + * specific read/write semantics (e.g. 4 byte or 32 byte reads). Note that this block_size only + * applies to the device_loc being added. Existing device locations in the list won't be modified + * to match the block size. + * + * \param[inout] device_locs Existing device location list to merge the new device + * location into. + * \param[inout] device_locs_count As input, the existing number of items in the device_locs + * list. As output, the new size of the device_locs list. + * \param[in] device_locs_max_count Maximum number of items the device_locs list can hold. + * \param[in] device_loc New device location to be merged into the device_locs list. + * \param[in] block_size Block size to align all offsets and counts to when adding + * device location. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_merge_device_loc(atcacert_device_loc_t* device_locs, + size_t* device_locs_count, + size_t device_locs_max_count, + const atcacert_device_loc_t* device_loc, + size_t block_size); + +/** \brief Determines if the two device locations overlap. + * \param[in] device_loc1 First device location to check. + * \param[in] device_loc2 Second device location o check. + * \return 0 (false) if they don't overlap, non-zero if the do overlap. + */ +int atcacert_is_device_loc_overlap(const atcacert_device_loc_t* device_loc1, + const atcacert_device_loc_t* device_loc2); + +/** + * \brief Takes a raw P256 ECC public key and converts it to the padded version used by ATECC + * devices. Input and output buffers can point to the same location to do an in-place + * transform. + * + * \param[in] raw_key Public key as X and Y integers concatenated together. 64 bytes. + * \param[out] padded_key Padded key is returned in this buffer. X and Y integers are padded + * with 4 bytes of 0 in the MSB. 72 bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +void atcacert_public_key_add_padding(const uint8_t raw_key[64], uint8_t padded_key[72]); + +/** + * \brief Takes a padded public key used by ATECC devices and converts it to a raw P256 ECC public + * key. Input and output buffers can point to the same location to do an in-place transform. + * + * \param[out] padded_key X and Y integers are padded with 4 bytes of 0 in the MSB. 72 bytes. + * \param[in] raw_key Raw key is returned in this buffer. Public key as X and Y integers + * concatenated together. 64 bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +void atcacert_public_key_remove_padding(const uint8_t padded_key[72], uint8_t raw_key[64]); + +/** + * \brief Apply the specified transform to the specified data. + * + * \param[in] transform Transform to be performed. + * \param[in] data Input data to be transformed. + * \param[in] data_size Size of the input data in bytes. + * \param[out] destination Destination buffer to hold the transformed data. + * \param[inout] destination_size As input, the size of the destination buffer. + * As output the size of the transformed data. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_transform_data(atcacert_transform_t transform, + const uint8_t* data, + size_t data_size, + uint8_t* destination, + size_t* destination_size); + +/** \brief Return the maximum possible certificate size in bytes for a given + * cert def. Certificate can be variable size, so this gives an + * appropriate buffer size when reading the certificates. + * + * \param[in] cert_def Certificate definition to find a max size for. + * \param[out] max_cert_size Maximum certificate size will be returned here in bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_max_cert_size(const atcacert_def_t* cert_def, + size_t* max_cert_size); + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.c new file mode 100644 index 0000000..f35c68e --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.c @@ -0,0 +1,562 @@ +/** + * \file + * \brief functions required to work with DER encoded data related to X.509 certificates. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +#include "atcacert_der.h" +#include + +int atcacert_der_enc_length(uint32_t length, uint8_t* der_length, size_t* der_length_size) +{ + size_t der_length_size_calc = 0; + int exp = sizeof(length) - 1; + + if (der_length_size == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (length < 0x80) + { + // The length can take the short form with only one byte + der_length_size_calc = 1; + exp = 0; + } + else + { + // Length is long-form, encoded as a multi-byte big-endian unsigned integer + + // Find first non-zero octet + while (length / ((uint32_t)1 << (8 * exp)) == 0) + { + exp--; + } + + der_length_size_calc = 2 + exp; + } + + if (der_length != NULL && *der_length_size < der_length_size_calc) + { + *der_length_size = der_length_size_calc; + return ATCACERT_E_BUFFER_TOO_SMALL; + } + + *der_length_size = der_length_size_calc; + + if (der_length == NULL) + { + return ATCACERT_E_SUCCESS; // Caller is only requesting the size + + } + // Encode length in big-endian format + for (; exp >= 0; exp--) + { + der_length[der_length_size_calc - 1 - exp] = (uint8_t)((length >> (exp * 8)) & 0xFF); + } + + if (der_length_size_calc > 1) + { + der_length[0] = 0x80 | (uint8_t)(der_length_size_calc - 1); // Set number of bytes octet with long-form flag + + } + return ATCACERT_E_SUCCESS; +} + +int atcacert_der_dec_length(const uint8_t* der_length, size_t* der_length_size, uint32_t* length) +{ + if (der_length == NULL || der_length_size == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (*der_length_size < 1) + { + return ATCACERT_E_DECODING_ERROR; + } + + if (der_length[0] & 0x80) + { + // Long form + size_t num_bytes = der_length[0] & 0x7F; + size_t i; + if (*der_length_size < num_bytes + 1) + { + return ATCACERT_E_DECODING_ERROR; // Invalid DER length format, not enough data. + } + if (num_bytes == 0) + { + return ATCACERT_E_DECODING_ERROR; // Invalid DER length format, indefinite length not supported. + } + if (num_bytes > sizeof(*length)) + { + return ATCACERT_E_DECODING_ERROR; // Can't parse DER length format, larger than length. + + } + if (length != NULL) + { + // Decode integer in big-endian format + *length = 0; + for (i = 1; i <= num_bytes; i++) + { + *length += der_length[i] * ((uint32_t)1 << (8 * (num_bytes - i))); + } + } + *der_length_size = num_bytes + 1; // Return the actual number of bytes the DER length encoding used. + } + else + { + if (length != NULL) + { + *length = der_length[0]; + } + *der_length_size = 1; // Return the actual number of bytes the DER length encoding used. + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_der_adjust_length(uint8_t* der_length, size_t* der_length_size, int delta_length, uint32_t* new_length) +{ + int ret = 0; + size_t new_der_len_size = 0; + uint32_t old_len = 0; + uint32_t new_len = 0; + uint8_t new_der_length[5]; + + ret = atcacert_der_dec_length(der_length, der_length_size, &old_len); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + if (delta_length < 0 && (size_t)(-delta_length) > old_len) + { + return ATCACERT_E_ERROR; + } + new_len = old_len + delta_length; + + if (new_length != NULL) + { + *new_length = new_len; + } + + new_der_len_size = sizeof(new_der_length); + ret = atcacert_der_enc_length(new_len, new_der_length, &new_der_len_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + if (*der_length_size != new_der_len_size) + { + return ATCACERT_E_BAD_CERT; + } + + memcpy(der_length, new_der_length, new_der_len_size); + + return 0; +} + +int atcacert_der_enc_integer(const uint8_t* int_data, + size_t int_data_size, + uint8_t is_unsigned, + uint8_t* der_int, + size_t* der_int_size) +{ + uint8_t der_length[5]; + size_t der_length_size = sizeof(der_length); + size_t der_int_size_calc = 0; + size_t trim = 0; + size_t pad = 0; + int ret; + + if (int_data == NULL || der_int_size == NULL || int_data_size <= 0) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (!(is_unsigned && (int_data[0] & 0x80))) + { + // This is not an unsigned value that needs a padding byte, trim any unnecessary bytes. + // Trim a byte when the upper 9 bits are all 0s or all 1s. + while ( + (int_data_size - trim >= 2) && ( + ((int_data[trim] == 0x00) && ((int_data[trim + 1] & 0x80) == 0)) || + ((int_data[trim] == 0xFF) && ((int_data[trim + 1] & 0x80) != 0)))) + { + trim++; + } + } + else + { + // Will be adding extra byte for unsigned padding so it's not interpreted as negative + pad = 1; + } + + ret = atcacert_der_enc_length((uint32_t)(int_data_size + pad - trim), der_length, &der_length_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + der_int_size_calc = 1 + der_length_size + int_data_size + pad - trim; + + if (der_int != NULL && der_int_size_calc > *der_int_size) + { + *der_int_size = der_int_size_calc; + return ATCACERT_E_BUFFER_TOO_SMALL; + } + + *der_int_size = der_int_size_calc; + + if (der_int == NULL) + { + return ATCACERT_E_SUCCESS; // Caller just wanted the size of the encoded integer + + } + der_int[0] = 0x02; // Integer tag + memcpy(&der_int[1], der_length, der_length_size); // Integer length + if (pad) + { + der_int[der_length_size + 1] = 0; // Unsigned integer value requires padding byte so it's not interpreted as negative + } + memcpy(&der_int[der_length_size + 1 + pad], &int_data[trim], int_data_size - trim); // Integer value + + return ATCACERT_E_SUCCESS; +} + +int atcacert_der_dec_integer(const uint8_t* der_int, + size_t* der_int_size, + uint8_t* int_data, + size_t* int_data_size) +{ + int ret = 0; + size_t der_length_size = 0; + uint32_t int_data_size_calc = 0; + + if (der_int == NULL || der_int_size == NULL || (int_data != NULL && int_data_size == NULL)) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (*der_int_size < 1) + { + return ATCACERT_E_DECODING_ERROR; // No data to decode + + } + if (der_int[0] != 0x02) + { + return ATCACERT_E_DECODING_ERROR; // Not an integer tag + + } + der_length_size = *der_int_size - 1; + ret = atcacert_der_dec_length(&der_int[1], &der_length_size, &int_data_size_calc); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + if (*der_int_size < (1 + der_length_size + int_data_size_calc)) + { + return ATCACERT_E_DECODING_ERROR; // Invalid DER integer, not enough data. + + } + *der_int_size = (1 + der_length_size + int_data_size_calc); + + if (int_data == NULL && int_data_size == NULL) + { + return ATCACERT_E_SUCCESS; // Caller doesn't want the actual data, just the der_int_size + + } + if (int_data != NULL && *int_data_size < int_data_size_calc) + { + *int_data_size = int_data_size_calc; + return ATCACERT_E_BUFFER_TOO_SMALL; + } + + *int_data_size = int_data_size_calc; + + if (int_data == NULL) + { + return ATCACERT_E_SUCCESS; // Caller doesn't want the actual data, just the int_data_size + + } + memcpy(int_data, &der_int[1 + der_length_size], int_data_size_calc); + + return ATCACERT_E_SUCCESS; +} + +int atcacert_der_enc_ecdsa_sig_value(const uint8_t raw_sig[64], + uint8_t* der_sig, + size_t* der_sig_size) +{ + int ret = 0; + size_t r_size = 0; + size_t s_size = 0; + size_t der_sig_size_calc = 0; + + if (raw_sig == NULL || der_sig_size == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + // Find size of the DER encoded R integer + ret = atcacert_der_enc_integer(&raw_sig[0], 32, TRUE, NULL, &r_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + // Find size of the DER encoded S integer + ret = atcacert_der_enc_integer(&raw_sig[32], 32, TRUE, NULL, &s_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + // This calculation assumes all DER lengths are a single byte, which is fine for 32 byte + // R and S integers. + der_sig_size_calc = 5 + r_size + s_size; + + if (der_sig != NULL && *der_sig_size < der_sig_size_calc) + { + *der_sig_size = der_sig_size_calc; + return ATCACERT_E_BUFFER_TOO_SMALL; + } + + *der_sig_size = der_sig_size_calc; + + if (der_sig == NULL) + { + return ATCACERT_E_SUCCESS; // Caller just wanted the encoded size + + } + der_sig[0] = 0x03; // signatureValue bit string tag + der_sig[1] = (uint8_t)(der_sig_size_calc - 2); // signatureValue bit string length + der_sig[2] = 0x00; // signatureValue bit string spare bits + + // signatureValue bit string value is the DER encoding of ECDSA-Sig-Value + der_sig[3] = 0x30; // sequence tag + der_sig[4] = (uint8_t)(der_sig_size_calc - 5); // sequence length + + // Add R integer + ret = atcacert_der_enc_integer(&raw_sig[0], 32, TRUE, &der_sig[5], &r_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + // Add S integer + ret = atcacert_der_enc_integer(&raw_sig[32], 32, TRUE, &der_sig[5 + r_size], &s_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_der_dec_ecdsa_sig_value(const uint8_t* der_sig, + size_t* der_sig_size, + uint8_t raw_sig[64]) +{ + int ret = 0; + size_t curr_idx = 0; + size_t dec_size = 0; + uint32_t bs_length = 0; + uint32_t seq_length = 0; + size_t r_size = 0; + size_t s_size = 0; + uint8_t int_data[33]; + size_t int_data_size = 0; + + if (der_sig == NULL || der_sig_size == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (*der_sig_size < 1) + { + return ATCACERT_E_DECODING_ERROR; // No data to decode + + } + // signatureValue bit string tag + curr_idx = 0; + if (der_sig[curr_idx] != 0x03) + { + return ATCACERT_E_DECODING_ERROR; // Unexpected tag value + } + curr_idx++; + + // signatureValue bit string length + dec_size = *der_sig_size - curr_idx; + ret = atcacert_der_dec_length(&der_sig[curr_idx], &dec_size, &bs_length); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; // Failed to decode length + } + curr_idx += dec_size; + if (curr_idx + bs_length > *der_sig_size) + { + return ATCACERT_E_DECODING_ERROR; // Not enough data in buffer to decode the rest + + } + // signatureValue bit string spare bits + if (curr_idx >= *der_sig_size) + { + return ATCACERT_E_DECODING_ERROR; // No data left + } + if (der_sig[curr_idx] != 0x00) + { + return ATCACERT_E_DECODING_ERROR; // Unexpected spare bits value + } + curr_idx++; + + // signatureValue bit string value is the DER encoding of ECDSA-Sig-Value + + // sequence tag + if (curr_idx >= *der_sig_size) + { + return ATCACERT_E_DECODING_ERROR; // No data left + } + if (der_sig[curr_idx] != 0x30) + { + return ATCACERT_E_DECODING_ERROR; // Unexpected tag value + } + curr_idx++; + + // sequence length + if (curr_idx >= *der_sig_size) + { + return ATCACERT_E_DECODING_ERROR; // No data left + } + dec_size = *der_sig_size - curr_idx; + ret = atcacert_der_dec_length(&der_sig[curr_idx], &dec_size, &seq_length); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; // Failed to decode length + } + curr_idx += dec_size; + if (curr_idx + seq_length > *der_sig_size) + { + return ATCACERT_E_DECODING_ERROR; // Not enough data in buffer to decode the rest + + } + // R integer + if (curr_idx >= *der_sig_size) + { + return ATCACERT_E_DECODING_ERROR; // No data left + } + r_size = *der_sig_size - curr_idx; + int_data_size = sizeof(int_data); + ret = atcacert_der_dec_integer(&der_sig[curr_idx], &r_size, int_data, &int_data_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; // Failed to decode length + } + curr_idx += r_size; + + if (raw_sig != NULL) + { + memset(raw_sig, 0, 64); // Zero out the raw sig as the decoded integers may not touch all bytes + + } + if (int_data_size <= 32) + { + if (raw_sig != NULL) + { + memcpy(&raw_sig[32 - int_data_size], &int_data[0], int_data_size); + } + } + else if (int_data_size == 33) + { + if (int_data[0] != 0x00) + { + return ATCACERT_E_DECODING_ERROR; // R integer is too large + } + // DER integer was 0-padded to keep it positive + if (raw_sig != NULL) + { + memcpy(&raw_sig[0], &int_data[1], 32); + } + } + else + { + return ATCACERT_E_DECODING_ERROR; // R integer is too large + + } + // S integer + if (curr_idx >= *der_sig_size) + { + return ATCACERT_E_DECODING_ERROR; // No data left + } + s_size = *der_sig_size - curr_idx; + int_data_size = sizeof(int_data); + ret = atcacert_der_dec_integer(&der_sig[curr_idx], &s_size, int_data, &int_data_size); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; // Failed to decode length + } + curr_idx += s_size; + + if (int_data_size <= 32) + { + if (raw_sig != NULL) + { + memcpy(&raw_sig[64 - int_data_size], &int_data[0], int_data_size); + } + } + else if (int_data_size == 33) + { + if (int_data[0] != 0x00) + { + return ATCACERT_E_DECODING_ERROR; // S integer is too large + } + // DER integer was 0-padded to keep it positive + if (raw_sig != NULL) + { + memcpy(&raw_sig[32], &int_data[1], 32); + } + } + else + { + return ATCACERT_E_DECODING_ERROR; // S integer is too large + + } + if (seq_length != r_size + s_size) + { + return ATCACERT_E_DECODING_ERROR; // Unexpected extra data in sequence + + } + if (bs_length != r_size + s_size + 3) + { + return ATCACERT_E_DECODING_ERROR; // Unexpected extra data in bit string + + } + *der_sig_size = curr_idx; + + return ATCACERT_E_SUCCESS; +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.h new file mode 100644 index 0000000..432033c --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.h @@ -0,0 +1,165 @@ +/** + * \file + * \brief function declarations required to work with DER encoded data related to X.509 certificates. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +#ifndef ATCACERT_DER_H +#define ATCACERT_DER_H + +#include +#include +#include "atcacert.h" + +// Inform function naming when compiling in C++ +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup atcacert_ Certificate manipulation methods (atcacert_) + * + * \brief + * These methods provide convenient ways to perform certification I/O with + * CryptoAuth chips and perform certificate manipulation in memory + * + @{ */ + +/** + * \brief Encode a length in DER format. + * + * X.690 (http://www.itu.int/rec/T-REC-X.690/en) section 8.1.3, for encoding + * + * \param[in] length Length to be encoded. + * \param[out] der_length DER encoded length will returned in this buffer. + * \param[inout] der_length_size As input, size of der_length buffer in bytes. + * As output, the size of the DER length encoding in bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_der_enc_length(uint32_t length, uint8_t* der_length, size_t* der_length_size); + +/** + * \brief Decode a DER format length. + * + * X.690 (http://www.itu.int/rec/T-REC-X.690/en) section 8.1.3, for encoding + * + * \param[in] der_length DER encoded length. + * \param[inout] der_length_size As input, the size of the der_length buffer in bytes. + * As output, the size of the DER encoded length that was decoded. + * \param[out] length Decoded length is returned here. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_der_dec_length(const uint8_t* der_length, size_t* der_length_size, uint32_t* length); + +int atcacert_der_adjust_length(uint8_t* der_length, size_t* der_length_size, int delta_length, uint32_t* new_length); + +/** + * \brief Encode an ASN.1 integer in DER format, including tag and length fields. + * + * X.680 (http://www.itu.int/rec/T-REC-X.680/en) section 19.8, for tag value + * X.690 (http://www.itu.int/rec/T-REC-X.690/en) section 8.3, for encoding + * + * \param[in] int_data Raw integer in big-endian format. + * \param[in] int_data_size Size of the raw integer in bytes. + * \param[in] is_unsigned Indicate whether the input integer should be treated as unsigned. + * \param[out] der_int DER encoded integer is returned in this buffer. + * \param[inout] der_int_size As input, the size of the der_int buffer in bytes. + * As output, the size of the DER integer returned in bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_der_enc_integer(const uint8_t* int_data, + size_t int_data_size, + uint8_t is_unsigned, + uint8_t* der_int, + size_t* der_int_size); + +/** + * \brief Decode an ASN.1 DER encoded integer. + * + * X.680 (http://www.itu.int/rec/T-REC-X.680/en) section 19.8, for tag value + * X.690 (http://www.itu.int/rec/T-REC-X.690/en) section 8.3, for encoding + * + * \param[in] der_int DER encoded ASN.1 integer, including the tag and length fields. + * \param[inout] der_int_size As input, the size of the der_int buffer in bytes. + * As output, the size of the DER integer decoded in bytes. + * \param[out] int_data Decode integer is returned in this buffer in a signed big-endian + * format. + * \param[inout] int_data_size As input, the size of int_data in bytes. + * As output, the size of the decoded integer in bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_der_dec_integer(const uint8_t* der_int, + size_t* der_int_size, + uint8_t* int_data, + size_t* int_data_size); + +/** + * \brief Formats a raw ECDSA P256 signature in the DER encoding found in X.509 certificates. + * + * This will return the DER encoding of the signatureValue field as found in an X.509 certificate + * (RFC 5280). This include the tag, length, and value. The value of the signatureValue is the DER + * encoding of the ECDSA-Sig-Value as specified by RFC 5480 and SECG SEC1. + * + * \param[in] raw_sig P256 ECDSA signature to be formatted. Input format is R and S + * integers concatenated together. 64 bytes. + * \param[out] der_sig X.509 format signature (TLV of signatureValue) will be returned in + * this buffer. + * \param[inout] der_sig_size As input, the size of the x509_sig buffer in bytes. + * As output, the size of the returned X.509 signature in bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_der_enc_ecdsa_sig_value(const uint8_t raw_sig[64], + uint8_t* der_sig, + size_t* der_sig_size); + +/** + * \brief Parses an ECDSA P256 signature in the DER encoding as found in X.509 certificates. + * + * This will parse the DER encoding of the signatureValue field as found in an X.509 certificate + * (RFC 5280). x509_sig should include the tag, length, and value. The value of the signatureValue + * is the DER encoding of the ECDSA-Sig-Value as specified by RFC 5480 and SECG SEC1. + * + * \param[in] der_sig X.509 format signature (TLV of signatureValue) to be parsed. + * \param[inout] der_sig_size As input, size of the der_sig buffer in bytes. + * As output, size of the DER x.509 signature parsed from the buffer. + * \param[out] raw_sig Parsed P256 ECDSA signature will be returned in this buffer. + * Formatted as R and S integers concatenated together. 64 bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_der_dec_ecdsa_sig_value(const uint8_t * der_sig, + size_t * der_sig_size, + uint8_t raw_sig[64]); + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.c new file mode 100644 index 0000000..8bea860 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.c @@ -0,0 +1,105 @@ +/** + * \file + * \brief host side methods using CryptoAuth hardware + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atcacert_host_hw.h" +#include "basic/atca_basic.h" +#include "crypto/atca_crypto_sw_sha2.h" + + + + + +int atcacert_verify_cert_hw(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + const uint8_t ca_public_key[64]) +{ + int ret = 0; + uint8_t tbs_digest[32]; + uint8_t signature[64]; + bool is_verified = false; + + if (cert_def == NULL || ca_public_key == NULL || cert == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + ret = atcacert_get_tbs_digest(cert_def, cert, cert_size, tbs_digest); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_get_signature(cert_def, cert, cert_size, signature); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcab_verify_extern(tbs_digest, signature, ca_public_key, &is_verified); + if (ret != ATCA_SUCCESS) + { + return ret; + } + + return is_verified ? ATCACERT_E_SUCCESS : ATCACERT_E_VERIFY_FAILED; +} + + + + +int atcacert_gen_challenge_hw(uint8_t challenge[32]) +{ + if (challenge == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + return atcab_random(challenge); +} + + +int atcacert_verify_response_hw(const uint8_t device_public_key[64], + const uint8_t challenge[32], + const uint8_t response[64]) +{ + int ret = 0; + bool is_verified = false; + + if (device_public_key == NULL || challenge == NULL || response == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + ret = atcab_verify_extern(challenge, response, device_public_key, &is_verified); + if (ret != ATCA_SUCCESS) + { + return ret; + } + + return is_verified ? ATCACERT_E_SUCCESS : ATCACERT_E_VERIFY_FAILED; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.h new file mode 100644 index 0000000..5c4fce8 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.h @@ -0,0 +1,106 @@ +/** + * \file + * \brief host side methods using CryptoAuth hardware + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ +#ifndef ATCACERT_HOST_HA_H +#define ATCACERT_HOST_HA_H + +#include +#include +#include "atcacert_def.h" + +// Inform function naming when compiling in C++ +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup atcacert_ Certificate manipulation methods (atcacert_) + * + * \brief + * These methods provide convenient ways to perform certification I/O with + * CryptoAuth chips and perform certificate manipulation in memory + * + @{ */ + +/** + * \brief Verify a certificate against its certificate authority's public key using the host's ATECC + * device for crypto functions. + * + * \param[in] cert_def Certificate definition describing how to extract the TBS and signature + * components from the certificate specified. + * \param[in] cert Certificate to verify. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[in] ca_public_key The ECC P256 public key of the certificate authority that signed this + * certificate. Formatted as the 32 byte X and Y integers concatenated + * together (64 bytes total). + * + * \return ATCACERT_E_SUCCESS if the verify succeeds, ATCACERT_VERIFY_FAILED or ATCA_EXECUTION_ERROR if it fails to + * verify. ATCA_EXECUTION_ERROR may occur when the public key is invalid and doesn't fall + * on the P256 curve. + */ +int atcacert_verify_cert_hw(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + const uint8_t ca_public_key[64]); + + +/** + * \brief Generate a random challenge to be sent to the client using the RNG on the host's ATECC + * device. + * + * \param[out] challenge Random challenge is return here. 32 bytes. + * + * \return ATCACERT_E_SUCCESS on success, otherwise an error code. + */ +int atcacert_gen_challenge_hw(uint8_t challenge[32]); + + +/** + * \brief Verify a client's response to a challenge using the host's ATECC device for crypto + * functions. + * + * The challenge-response protocol is an ECDSA Sign and Verify. This performs an ECDSA verify on the + * response returned by the client, verifying the client has the private key counter-part to the + * public key returned in its certificate. + * + * \param[in] device_public_key Device public key as read from its certificate. Formatted as the X + * and Y integers concatenated together. 64 bytes. + * \param[in] challenge Challenge that was sent to the client. 32 bytes. + * \param[in] response Response returned from the client to be verified. 64 bytes. + * + * \return ATCACERT_E_SUCCESS if the verify succeeds, ATCACERT_VERIFY_FAILED or ATCA_EXECUTION_ERROR if it fails to + * verify. ATCA_EXECUTION_ERROR may occur when the public key is invalid and doesn't fall + * on the P256 curve. + */ +int atcacert_verify_response_hw(const uint8_t device_public_key[64], + const uint8_t challenge[32], + const uint8_t response[64]); + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.c new file mode 100644 index 0000000..e7255e1 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.c @@ -0,0 +1,97 @@ +/** + * \file + * \brief host side methods using software implementations + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atcacert_host_sw.h" +#include "crypto/atca_crypto_sw_sha2.h" +#include "crypto/atca_crypto_sw_ecdsa.h" +#include "crypto/atca_crypto_sw_rand.h" + + + + + + +int atcacert_verify_cert_sw(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + const uint8_t ca_public_key[64]) +{ + int ret = 0; + uint8_t tbs_digest[32]; + uint8_t signature[64]; + + if (cert_def == NULL || ca_public_key == NULL || cert == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + ret = atcacert_get_tbs_digest(cert_def, cert, cert_size, tbs_digest); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcacert_get_signature(cert_def, cert, cert_size, signature); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + ret = atcac_sw_ecdsa_verify_p256(tbs_digest, signature, ca_public_key); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + return ATCACERT_E_SUCCESS; +} + + + +int atcacert_gen_challenge_sw(uint8_t challenge[32]) +{ + if (challenge == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + return atcac_sw_random(challenge, 32); +} + + + +int atcacert_verify_response_sw(const uint8_t device_public_key[64], + const uint8_t challenge[32], + const uint8_t response[64]) +{ + if (device_public_key == NULL || challenge == NULL || response == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + return atcac_sw_ecdsa_verify_p256(challenge, response, device_public_key); +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.h new file mode 100644 index 0000000..1a4a0e5 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.h @@ -0,0 +1,106 @@ +/** + * \file + * \brief Host side methods using software implementations. host-side, the one authenticating + * a client, of the authentication process. Crypto functions are performed using a software library. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef ATCACERT_HOST_SOFT_H +#define ATCACERT_HOST_SOFT_H + +#include +#include +#include "atcacert_def.h" + +// Inform function naming when compiling in C++ +#ifdef __cplusplus +extern "C" { +#endif + + +/** \defgroup atcacert_ Certificate manipulation methods (atcacert_) + * + * \brief + * These methods provide convenient ways to perform certification I/O with + * CryptoAuth chips and perform certificate manipulation in memory + * + @{ */ + +/** + * \brief Verify a certificate against its certificate authority's public key using software crypto + * functions.The function is currently not implemented. + * + * \param[in] cert_def Certificate definition describing how to extract the TBS and signature + * components from the certificate specified. + * \param[in] cert Certificate to verify. + * \param[in] cert_size Size of the certificate (cert) in bytes. + * \param[in] ca_public_key The ECC P256 public key of the certificate authority that signed this + * certificate. Formatted as the 32 byte X and Y integers concatenated + * together (64 bytes total). + * + * \return ATCA_UNIMPLEMENTED , as the function is currently not implemented. + */ +int atcacert_verify_cert_sw(const atcacert_def_t* cert_def, + const uint8_t* cert, + size_t cert_size, + const uint8_t ca_public_key[64]); + + + +/** + * \brief Generate a random challenge to be sent to the client using a software PRNG.The function is currently not implemented. + * + * \param[out] challenge Random challenge is return here. 32 bytes. + * + * \return ATCA_UNIMPLEMENTED , as the function is currently not implemented. + */ +int atcacert_gen_challenge_sw(uint8_t challenge[32]); + + + + +/** + * \brief Verify a client's response to a challenge using software crypto functions.The function is currently not implemented. + * + * The challenge-response protocol is an ECDSA Sign and Verify. This performs an ECDSA verify on the + * response returned by the client, verifying the client has the private key counter-part to the + * public key returned in its certificate. + * + * \param[in] device_public_key Device public key as read from its certificate. Formatted as the X + * and Y integers concatenated together. 64 bytes. + * \param[in] challenge Challenge that was sent to the client. 32 bytes. + * \param[in] response Response returned from the client to be verified. 64 bytes. + * + * \return ATCA_UNIMPLEMENTED , as the function is currently not implemented. + */ +int atcacert_verify_response_sw(const uint8_t device_public_key[64], + const uint8_t challenge[32], + const uint8_t response[64]); + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.c new file mode 100644 index 0000000..c418900 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.c @@ -0,0 +1,165 @@ +#include "atcacert.h" +#include "atcacert_pem.h" +#include "../basic/atca_helpers.h" + +int atcacert_encode_pem(const uint8_t* der, + size_t der_size, + char* pem, + size_t* pem_size, + const char* header, + const char* footer) +{ + ATCA_STATUS status; + size_t max_pem_size; + size_t header_size; + size_t footer_size; + size_t b64_size; + size_t pem_index = 0; + + if (der == NULL || pem == NULL || pem_size == NULL || header == NULL || footer == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + max_pem_size = *pem_size; + *pem_size = 0; // Default to 0 + + // Add header + header_size = strlen(header); + if (pem_index + header_size + 2 > max_pem_size) + { + return ATCACERT_E_BUFFER_TOO_SMALL; + } + memcpy(&pem[pem_index], header, header_size); + pem_index += header_size; + memcpy(&pem[pem_index], "\r\n", 2); + pem_index += 2; + + // Add base64 encoded DER data with \r\n every 64 characters + b64_size = max_pem_size - pem_index; + status = atcab_base64encode(der, der_size, &pem[pem_index], &b64_size); + if (status != ATCACERT_E_SUCCESS) + { + if (status == ATCA_SMALL_BUFFER) + { + status = ATCACERT_E_BUFFER_TOO_SMALL; + } + return status; + } + pem_index += b64_size; + + // Add \r\n after data + footer_size = strlen(footer); + if (pem_index + 2 + footer_size + 2 + 1 > max_pem_size) + { + return ATCACERT_E_BUFFER_TOO_SMALL; + } + memcpy(&pem[pem_index], "\r\n", 2); + pem_index += 2; + + // Add footer + memcpy(&pem[pem_index], footer, footer_size); + pem_index += footer_size; + memcpy(&pem[pem_index], "\r\n", 2); + pem_index += 2; + + pem[pem_index] = 0; // Terminating null, not included in size + + // Set output size + *pem_size = pem_index; + + return ATCACERT_E_SUCCESS; +} + +int atcacert_decode_pem(const char* pem, + size_t pem_size, + uint8_t* der, + size_t* der_size, + const char* header, + const char* footer) +{ + ATCA_STATUS status; + const char* header_pos = NULL; + const char* data_pos = NULL; + const char* footer_pos = NULL; + + if (pem == NULL || der == NULL || der_size == NULL || header == NULL || footer == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + // Find the position of the header + header_pos = strstr(pem, header); + if (header_pos == NULL) + { + return ATCACERT_E_DECODING_ERROR; // Couldn't find header + } + + // Data should be right after the header. Not accounting for new lines as + // the base64 decode should skip over those. + data_pos = header_pos + strlen(header); + + // Find footer + footer_pos = strstr(pem, footer); + if (footer_pos == NULL || footer_pos < data_pos) + { + // Couldn't find footer or found it before the data + return ATCACERT_E_DECODING_ERROR; + } + + // Decode data + status = atcab_base64decode(data_pos, footer_pos - data_pos, der, der_size); + if (status != ATCA_SUCCESS) + { + if (status == ATCA_SMALL_BUFFER) + { + status = ATCACERT_E_BUFFER_TOO_SMALL; + } + return status; + } + + return ATCACERT_E_SUCCESS; +} + +int atcacert_encode_pem_cert(const uint8_t* der_cert, size_t der_cert_size, char* pem_cert, size_t* pem_cert_size) +{ + return atcacert_encode_pem( + der_cert, + der_cert_size, + pem_cert, + pem_cert_size, + PEM_CERT_BEGIN, + PEM_CERT_END); +} + +int atcacert_encode_pem_csr(const uint8_t* der_csr, size_t der_csr_size, char* pem_csr, size_t* pem_csr_size) +{ + return atcacert_encode_pem( + der_csr, + der_csr_size, + pem_csr, + pem_csr_size, + PEM_CSR_BEGIN, + PEM_CSR_END); +} + +int atcacert_decode_pem_cert(const char* pem_cert, size_t pem_cert_size, uint8_t* der_cert, size_t* der_cert_size) +{ + return atcacert_decode_pem( + pem_cert, + pem_cert_size, + der_cert, + der_cert_size, + PEM_CERT_BEGIN, + PEM_CERT_END); +} + +int atcacert_decode_pem_csr(const char* pem_csr, size_t pem_csr_size, uint8_t* der_csr, size_t* der_csr_size) +{ + return atcacert_decode_pem( + pem_csr, + pem_csr_size, + der_csr, + der_csr_size, + PEM_CSR_BEGIN, + PEM_CSR_END); +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.h new file mode 100644 index 0000000..d2bf022 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.h @@ -0,0 +1,126 @@ +/** + * \file + * \brief Functions for converting between DER and PEM formats. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef ATCACERT_PEM_H +#define ATCACERT_PEM_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PEM_CERT_BEGIN "-----BEGIN CERTIFICATE-----" +#define PEM_CERT_END "-----END CERTIFICATE-----" +#define PEM_CSR_BEGIN "-----BEGIN CERTIFICATE REQUEST-----" +#define PEM_CSR_END "-----END CERTIFICATE REQUEST-----" + +/** + * \brief Encode a DER data in PEM format. + * \param[in] der DER data to be encoded as PEM. + * \param[out] der_size DER data size in bytes. + * \param[out] pem PEM encoded data is returned here. + * \param[inout] pem_size As input, the size of the pem buffer. + * As output, the size of the PEM data. + * \param[in] header Header to place at the beginning of the PEM data. + * \param[in] footer Footer to place at the end of the PEM data. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +int atcacert_encode_pem(const uint8_t* der, + size_t der_size, + char* pem, + size_t* pem_size, + const char* header, + const char* footer); + +/** + * \brief Decode PEM data into DER format. + * \param[in] pem PEM data to decode to DER. + * \param[in] pem_size PEM data size in bytes. + * \param[out] der DER data is returned here. + * \param[inout] der_size As input, the size of the der buffer. + * As output, the size of the DER data. + * \param[in] header Header to find the beginning of the PEM data. + * \param[in] footer Footer to find the end of the PEM data. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +int atcacert_decode_pem(const char* pem, + size_t pem_size, + uint8_t* der, + size_t* der_size, + const char* header, + const char* footer); + +/** + * \brief Encode a DER certificate in PEM format. + * \param[in] der_cert DER certificate to be encoded as PEM. + * \param[out] der_cert_size DER certificate size in bytes. + * \param[out] pem_cert PEM encoded certificate is returned here. + * \param[inout] pem_cert_size As input, the size of the pem_cert buffer. + * As output, the size of the PEM certificate. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +int atcacert_encode_pem_cert(const uint8_t* der_cert, size_t der_cert_size, char* pem_cert, size_t* pem_cert_size); + +/** + * \brief Decode a PEM certificate into DER format. + * \param[in] pem_cert PEM certificate to decode to DER. + * \param[in] pem_cert_size PEM certificate size in bytes. + * \param[out] der_cert DER certificate is returned here. + * \param[inout] der_cert_size As input, the size of the der_cert buffer. + * As output, the size of the DER certificate. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +int atcacert_decode_pem_cert(const char* pem_cert, size_t pem_cert_size, uint8_t* der_cert, size_t* der_cert_size); + +/** + * \brief Encode a DER CSR in PEM format. + * \param[in] der_csr DER CSR to be encoded as PEM. + * \param[out] der_csr_size DER CSR size in bytes. + * \param[out] pem_csr PEM encoded CSR is returned here. + * \param[inout] pem_csr_size As input, the size of the pem_csr buffer. + * As output, the size of the PEM CSR. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +int atcacert_encode_pem_csr(const uint8_t* der_csr, size_t der_csr_size, char* pem_csr, size_t* pem_csr_size); + +/** + * \brief Extract the CSR certificate bytes from a PEM encoded CSR certificate + * \param[in] pem_csr PEM CSR to decode to DER. + * \param[in] pem_csr_size PEM CSR size in bytes. + * \param[out] der_csr DER CSR is returned here. + * \param[inout] der_csr_size As input, the size of the der_csr buffer. + * As output, the size of the DER CSR. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +int atcacert_decode_pem_csr(const char* pem_csr, size_t pem_csr_size, uint8_t* der_csr, size_t* der_csr_size); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/README.md b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/README.md new file mode 100644 index 0000000..79f8c2c --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/README.md @@ -0,0 +1,15 @@ +basic directory - Purpose +========================= +The purpose of this directory is to contain the files implementing the APIs for +a basic interface to the core CryptoAuthLib library. + +High-level functions like these make it very convenient to use the library when +standard configurations and defaults are in play. They are the easiest to use +when developing examples or trying to understand the "flow" of an +authentication operation without getting overwhelmed by the details. + +This makes simple jobs easy and if you need more sophistication and power, you +can employ the full power of the CryptoAuthLib object model. + +See the Doxygen documentation in cryptoauthlib/docs for details on the API of +the Basic commands. diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.c new file mode 100644 index 0000000..33627bc --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.c @@ -0,0 +1,420 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods. These methods provide a simpler way + * to access the core crypto methods. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +#include "atca_basic.h" +#include "host/atca_host.h" + +const char atca_version[] = { "20190517" }; // change for each release, yyyymmdd +ATCADevice _gDevice = NULL; +#ifdef ATCA_NO_HEAP +struct atca_command g_atcab_command; +struct atca_iface g_atcab_iface; +struct atca_device g_atcab_device; +#endif +#define MAX_BUSES 4 + +/** \brief basic API methods are all prefixed with atcab_ (CryptoAuthLib Basic) + * the fundamental premise of the basic API is it is based on a single interface + * instance and that instance is global, so all basic API commands assume that + * one global device is the one to operate on. + */ + +/** \brief returns a version string for the CryptoAuthLib release. + * The format of the version string returned is "yyyymmdd" + * \param[out] ver_str ptr to space to receive version string + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_version(char *ver_str) +{ + strcpy(ver_str, atca_version); + return ATCA_SUCCESS; +} + + +/** \brief Creates a global ATCADevice object used by Basic API. + * \param[in] cfg Logical interface configuration. Some predefined + * configurations can be found in atca_cfgs.h + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_init(ATCAIfaceCfg *cfg) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + + // If a device has already been initialized, release it + if (_gDevice) + { + atcab_release(); + } + +#ifdef ATCA_NO_HEAP + g_atcab_device.mCommands = &g_atcab_command; + g_atcab_device.mIface = &g_atcab_iface; + status = initATCADevice(cfg, &g_atcab_device); + if (status != ATCA_SUCCESS) + { + return status; + } + _gDevice = &g_atcab_device; +#else + _gDevice = newATCADevice(cfg); + if (_gDevice == NULL) + { + return ATCA_GEN_FAIL; + } +#endif + + if (cfg->devtype == ATECC608A) + { + if ((status = atcab_read_bytes_zone(ATCA_ZONE_CONFIG, 0, ATCA_CHIPMODE_OFFSET, &_gDevice->mCommands->clock_divider, 1)) != ATCA_SUCCESS) + { + return status; + } + _gDevice->mCommands->clock_divider &= ATCA_CHIPMODE_CLOCK_DIV_MASK; + } + + return ATCA_SUCCESS; +} + +/** \brief Initialize the global ATCADevice object to point to one of your + * choosing for use with all the atcab_ basic API. + * \param[in] ca_device ATCADevice instance to use as the global Basic API + * crypto device instance + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_init_device(ATCADevice ca_device) +{ + if (ca_device == NULL) + { + return ATCA_BAD_PARAM; + } + + if (atGetCommands(ca_device) == NULL || atGetIFace(ca_device) == NULL) + { + return ATCA_GEN_FAIL; + } + + // if there's already a device created, release it + if (_gDevice) + { + atcab_release(); + } + + _gDevice = ca_device; + + return ATCA_SUCCESS; +} + +/** \brief release (free) the global ATCADevice instance. + * This must be called in order to release or free up the interface. + * \return Returns ATCA_SUCCESS . + */ +ATCA_STATUS atcab_release(void) +{ +#ifdef ATCA_NO_HEAP + ATCA_STATUS status = releaseATCADevice(_gDevice); + if (status != ATCA_SUCCESS) + { + return status; + } + _gDevice = NULL; +#else + deleteATCADevice(&_gDevice); +#endif + return ATCA_SUCCESS; +} + +/** \brief Get the global device object. + * \return instance of global ATCADevice + */ +ATCADevice atcab_get_device(void) +{ + return _gDevice; +} + +/** \brief Get the current device type. + * \return Device type if basic api is initialized or ATCA_DEV_UNKNOWN. + */ +ATCADeviceType atcab_get_device_type(void) +{ + if (_gDevice) + { + return _gDevice->mIface->mIfaceCFG->devtype; + } + else + { + return ATCA_DEV_UNKNOWN; + } +} + +/** \brief wakeup the CryptoAuth device + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_wakeup(void) +{ + if (_gDevice == NULL) + { + return ATCA_GEN_FAIL; + } + + return atwake(_gDevice->mIface); +} + +/** \brief idle the CryptoAuth device + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_idle(void) +{ + if (_gDevice == NULL) + { + return ATCA_GEN_FAIL; + } + + return atidle(_gDevice->mIface); +} + +/** \brief invoke sleep on the CryptoAuth device + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_sleep(void) +{ + if (_gDevice == NULL) + { + return ATCA_GEN_FAIL; + } + + return atsleep(_gDevice->mIface); +} + + +/** \brief auto discovery of crypto auth devices + * + * Calls interface discovery functions and fills in cfg_array up to the maximum + * number of configurations either found or the size of the array. The cfg_array + * can have a mixture of interface types (ie: some I2C, some SWI or UART) depending upon + * which interfaces you've enabled + * + * \param[out] cfg_array ptr to an array of interface configs + * \param[in] max_ifaces maximum size of cfg_array + * \return ATCA_SUCCESS on success, otherwise an error code. + */ + + +ATCA_STATUS atcab_cfg_discover(ATCAIfaceCfg cfg_array[], int max_ifaces) +{ + int iface_num = 0; + int found = 0; + int i = 0; + +// this cumulatively gathers all the interfaces enabled by #defines + +#ifdef ATCA_HAL_I2C + int i2c_buses[MAX_BUSES]; + memset(i2c_buses, -1, sizeof(i2c_buses)); + hal_i2c_discover_buses(i2c_buses, MAX_BUSES); + + for (i = 0; i < MAX_BUSES && iface_num < max_ifaces; i++) + { + if (i2c_buses[i] != -1) + { + hal_i2c_discover_devices(i2c_buses[i], &cfg_array[iface_num], &found); + iface_num += found; + } + } +#endif + +#ifdef ATCA_HAL_SWI + int swi_buses[MAX_BUSES]; + memset(swi_buses, -1, sizeof(swi_buses)); + hal_swi_discover_buses(swi_buses, MAX_BUSES); + for (i = 0; i < MAX_BUSES && iface_num < max_ifaces; i++) + { + if (swi_buses[i] != -1) + { + hal_swi_discover_devices(swi_buses[i], &cfg_array[iface_num], &found); + iface_num += found; + } + } + +#endif + +#ifdef ATCA_HAL_UART + int uart_buses[MAX_BUSES]; + memset(uart_buses, -1, sizeof(uart_buses)); + hal_uart_discover_buses(uart_buses, MAX_BUSES); + for (i = 0; i < MAX_BUSES && iface_num < max_ifaces; i++) + { + if (uart_buses[i] != -1) + { + hal_uart_discover_devices(uart_buses[i], &cfg_array[iface_num], &found); + iface_num += found; + } + } +#endif + +#ifdef ATCA_HAL_KIT_CDC + int cdc_buses[MAX_BUSES]; + memset(cdc_buses, -1, sizeof(cdc_buses)); + hal_kit_cdc_discover_buses(cdc_buses, MAX_BUSES); + for (i = 0; i < MAX_BUSES && iface_num < max_ifaces; i++) + { + if (cdc_buses[i] != -1) + { + hal_kit_cdc_discover_devices(cdc_buses[i], &cfg_array[iface_num++], &found); + iface_num += found; + } + } +#endif + +#ifdef ATCA_HAL_KIT_HID + int hid_buses[MAX_BUSES]; + memset(hid_buses, -1, sizeof(hid_buses)); + hal_kit_hid_discover_buses(hid_buses, MAX_BUSES); + for (i = 0; i < MAX_BUSES && iface_num < max_ifaces; i++) + { + if (hid_buses[i] != -1) + { + hal_kit_hid_discover_devices(hid_buses[i], &cfg_array[iface_num++], &found); + iface_num += found; + } + } +#endif + return ATCA_SUCCESS; +} + +/** \brief common cleanup code which idles the device after any operation + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS _atcab_exit(void) +{ + return atcab_idle(); +} + +/** \brief Compute the address given the zone, slot, block, and offset + * \param[in] zone Zone to get address from. Config(0), OTP(1), or + * Data(2) which requires a slot. + * \param[in] slot Slot Id number for data zone and zero for other zones. + * \param[in] block Block number within the data or configuration or OTP zone . + * \param[in] offset Offset Number within the block of data or configuration or OTP zone. + * \param[out] addr Pointer to the address of data or configuration or OTP zone. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_get_addr(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint16_t* addr) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint8_t mem_zone = zone & 0x03; + + if (addr == NULL) + { + return ATCA_BAD_PARAM; + } + if ((mem_zone != ATCA_ZONE_CONFIG) && (mem_zone != ATCA_ZONE_DATA) && (mem_zone != ATCA_ZONE_OTP)) + { + return ATCA_BAD_PARAM; + } + do + { + // Initialize the addr to 00 + *addr = 0; + // Mask the offset + offset = offset & (uint8_t)0x07; + if ((mem_zone == ATCA_ZONE_CONFIG) || (mem_zone == ATCA_ZONE_OTP)) + { + *addr = block << 3; + *addr |= offset; + } + else // ATCA_ZONE_DATA + { + *addr = slot << 3; + *addr |= offset; + *addr |= block << 8; + } + } + while (0); + + return status; +} + +/** \brief Gets the size of the specified zone in bytes. + * + * \param[in] zone Zone to get size information from. Config(0), OTP(1), or + * Data(2) which requires a slot. + * \param[in] slot If zone is Data(2), the slot to query for size. + * \param[out] size Zone size is returned here. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_get_zone_size(uint8_t zone, uint16_t slot, size_t* size) +{ + ATCA_STATUS status = ATCA_SUCCESS; + + if (size == NULL) + { + return ATCA_BAD_PARAM; + } + + if (_gDevice->mIface->mIfaceCFG->devtype == ATSHA204A) + { + switch (zone) + { + case ATCA_ZONE_CONFIG: *size = 88; break; + case ATCA_ZONE_OTP: *size = 64; break; + case ATCA_ZONE_DATA: *size = 32; break; + default: status = ATCA_BAD_PARAM; break; + } + } + else + { + switch (zone) + { + case ATCA_ZONE_CONFIG: *size = 128; break; + case ATCA_ZONE_OTP: *size = 64; break; + case ATCA_ZONE_DATA: + if (slot < 8) + { + *size = 36; + } + else if (slot == 8) + { + *size = 416; + } + else if (slot < 16) + { + *size = 72; + } + else + { + status = ATCA_BAD_PARAM; + } + break; + default: status = ATCA_BAD_PARAM; break; + } + } + + return status; +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.h new file mode 100644 index 0000000..f6c04ea --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.h @@ -0,0 +1,256 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods - a simple crypto authentication API. + * These methods manage a global ATCADevice object behind the scenes. They also + * manage the wake/idle state transitions so callers don't need to. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "cryptoauthlib.h" +#include "crypto/atca_crypto_sw_sha2.h" +#include "cryptoauthlib_config.h" + +#ifndef ATCA_BASIC_H_ +#define ATCA_BASIC_H_ + +/** \defgroup atcab_ Basic Crypto API methods (atcab_) + * + * \brief + * These methods provide the most convenient, simple API to CryptoAuth chips + * + @{ */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLOCK_NUMBER(a) (a / 32) +#define WORD_OFFSET(a) ((a % 32) / 4) + +#define ATCA_AES_GCM_IV_STD_LENGTH 12 + + +extern ATCADevice _gDevice; + +// Basic global methods +ATCA_STATUS atcab_version(char *ver_str); +ATCA_STATUS atcab_init(ATCAIfaceCfg *cfg); +ATCA_STATUS atcab_init_device(ATCADevice ca_device); +ATCA_STATUS atcab_release(void); +ATCADevice atcab_get_device(void); +ATCADeviceType atcab_get_device_type(void); +ATCA_STATUS _atcab_exit(void); +ATCA_STATUS atcab_wakeup(void); +ATCA_STATUS atcab_idle(void); +ATCA_STATUS atcab_sleep(void); +ATCA_STATUS atcab_cfg_discover(ATCAIfaceCfg cfg_array[], int max); +ATCA_STATUS atcab_get_addr(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint16_t* addr); +ATCA_STATUS atcab_get_zone_size(uint8_t zone, uint16_t slot, size_t* size); + +// AES command functions +ATCA_STATUS atcab_aes(uint8_t mode, uint16_t key_id, const uint8_t* aes_in, uint8_t* aes_out); +ATCA_STATUS atcab_aes_encrypt(uint16_t key_id, uint8_t key_block, const uint8_t* plaintext, uint8_t* ciphertext); +ATCA_STATUS atcab_aes_decrypt(uint16_t key_id, uint8_t key_block, const uint8_t* ciphertext, uint8_t* plaintext); +ATCA_STATUS atcab_aes_gfm(const uint8_t* h, const uint8_t* input, uint8_t* output); + +typedef struct atca_aes_cbc_ctx +{ + uint16_t key_id; //!< Key location. Can either be a slot number or ATCA_TEMPKEY_KEYID for TempKey. + uint8_t key_block; //!< Index of the 16-byte block to use within the key location for the actual key. + uint8_t ciphertext[AES_DATA_SIZE]; //!< Ciphertext from last operation. +} atca_aes_cbc_ctx_t; + +ATCA_STATUS atcab_aes_cbc_init(atca_aes_cbc_ctx_t* ctx, uint16_t key_id, uint8_t key_block, const uint8_t* iv); +ATCA_STATUS atcab_aes_cbc_encrypt_block(atca_aes_cbc_ctx_t* ctx, const uint8_t* plaintext, uint8_t* ciphertext); +ATCA_STATUS atcab_aes_cbc_decrypt_block(atca_aes_cbc_ctx_t* ctx, const uint8_t* ciphertext, uint8_t* plaintext); + +typedef struct atca_aes_cmac_ctx +{ + atca_aes_cbc_ctx_t cbc_ctx; //!< CBC context + uint32_t block_size; //!< Number of bytes in current block. + uint8_t block[AES_DATA_SIZE]; //!< Unprocessed message storage. +} atca_aes_cmac_ctx_t; + +ATCA_STATUS atcab_aes_cmac_init(atca_aes_cmac_ctx_t* ctx, uint16_t key_id, uint8_t key_block); +ATCA_STATUS atcab_aes_cmac_update(atca_aes_cmac_ctx_t* ctx, const uint8_t* data, uint32_t data_size); +ATCA_STATUS atcab_aes_cmac_finish(atca_aes_cmac_ctx_t* ctx, uint8_t* cmac, uint32_t cmac_size); + +typedef struct atca_aes_ctr_ctx +{ + uint16_t key_id; //!< Key location. Can either be a slot number or ATCA_TEMPKEY_KEYID for TempKey. + uint8_t key_block; //!< Index of the 16-byte block to use within the key location for the actual key. + uint8_t cb[AES_DATA_SIZE]; //!< Counter block, comprises of nonce + count value (16 bytes). + uint8_t counter_size; //!< Size of counter in the initialization vector. +}atca_aes_ctr_ctx_t; + +ATCA_STATUS atcab_aes_ctr_init(atca_aes_ctr_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t counter_size, const uint8_t* iv); +ATCA_STATUS atcab_aes_ctr_init_rand(atca_aes_ctr_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t counter_size, uint8_t* iv); +ATCA_STATUS atcab_aes_ctr_block(atca_aes_ctr_ctx_t* ctx, const uint8_t* input, uint8_t* output); +ATCA_STATUS atcab_aes_ctr_encrypt_block(atca_aes_ctr_ctx_t* ctx, const uint8_t* plaintext, uint8_t* ciphertext); +ATCA_STATUS atcab_aes_ctr_decrypt_block(atca_aes_ctr_ctx_t* ctx, const uint8_t* ciphertext, uint8_t* plaintext); +ATCA_STATUS atcab_aes_ctr_increment(atca_aes_ctr_ctx_t* ctx); + +// CheckMAC command functions +ATCA_STATUS atcab_checkmac(uint8_t mode, uint16_t key_id, const uint8_t *challenge, const uint8_t *response, const uint8_t *other_data); + +// Counter command functions +ATCA_STATUS atcab_counter(uint8_t mode, uint16_t counter_id, uint32_t* counter_value); +ATCA_STATUS atcab_counter_increment(uint16_t counter_id, uint32_t* counter_value); +ATCA_STATUS atcab_counter_read(uint16_t counter_id, uint32_t* counter_value); + +// DeriveKey command functions +ATCA_STATUS atcab_derivekey(uint8_t mode, uint16_t key_id, const uint8_t* mac); + +// ECDH command functions +ATCA_STATUS atcab_ecdh_base(uint8_t mode, uint16_t key_id, const uint8_t* public_key, uint8_t* pms, uint8_t* out_nonce); +ATCA_STATUS atcab_ecdh(uint16_t key_id, const uint8_t* public_key, uint8_t* pms); +ATCA_STATUS atcab_ecdh_enc(uint16_t key_id, const uint8_t* public_key, uint8_t* pms, const uint8_t* read_key, uint16_t read_key_id); +ATCA_STATUS atcab_ecdh_ioenc(uint16_t key_id, const uint8_t* public_key, uint8_t* pms, const uint8_t* io_key); +ATCA_STATUS atcab_ecdh_tempkey(const uint8_t* public_key, uint8_t* pms); +ATCA_STATUS atcab_ecdh_tempkey_ioenc(const uint8_t* public_key, uint8_t* pms, const uint8_t* io_key); + +// GenDig command functions +ATCA_STATUS atcab_gendig(uint8_t zone, uint16_t key_id, const uint8_t *other_data, uint8_t other_data_size); + +// GenKey command functions +ATCA_STATUS atcab_genkey_base(uint8_t mode, uint16_t key_id, const uint8_t* other_data, uint8_t* public_key); +ATCA_STATUS atcab_genkey(uint16_t key_id, uint8_t* public_key); +ATCA_STATUS atcab_get_pubkey(uint16_t key_id, uint8_t* public_key); + +// HMAC command functions +ATCA_STATUS atcab_hmac(uint8_t mode, uint16_t key_id, uint8_t* digest); + +// Info command functions +ATCA_STATUS atcab_info_base(uint8_t mode, uint16_t param2, uint8_t* out_data); +ATCA_STATUS atcab_info(uint8_t* revision); +ATCA_STATUS atcab_info_set_latch(bool state); +ATCA_STATUS atcab_info_get_latch(bool* state); + +// KDF command functions +ATCA_STATUS atcab_kdf(uint8_t mode, uint16_t key_id, const uint32_t details, const uint8_t* message, uint8_t* out_data, uint8_t* out_nonce); + +// Lock command functions +ATCA_STATUS atcab_lock(uint8_t mode, uint16_t summary_crc); +ATCA_STATUS atcab_lock_config_zone(void); +ATCA_STATUS atcab_lock_config_zone_crc(uint16_t summary_crc); +ATCA_STATUS atcab_lock_data_zone(void); +ATCA_STATUS atcab_lock_data_zone_crc(uint16_t summary_crc); +ATCA_STATUS atcab_lock_data_slot(uint16_t slot); + +// MAC command functions +ATCA_STATUS atcab_mac(uint8_t mode, uint16_t key_id, const uint8_t* challenge, uint8_t* digest); + +// Nonce command functions +ATCA_STATUS atcab_nonce_base(uint8_t mode, uint16_t zero, const uint8_t *num_in, uint8_t* rand_out); +ATCA_STATUS atcab_nonce(const uint8_t *num_in); +ATCA_STATUS atcab_nonce_load(uint8_t target, const uint8_t *num_in, uint16_t num_in_size); +ATCA_STATUS atcab_nonce_rand(const uint8_t *num_in, uint8_t* rand_out); +ATCA_STATUS atcab_challenge(const uint8_t *num_in); +ATCA_STATUS atcab_challenge_seed_update(const uint8_t *num_in, uint8_t* rand_out); + +// PrivWrite command functions +ATCA_STATUS atcab_priv_write(uint16_t key_id, const uint8_t priv_key[36], uint16_t write_key_id, const uint8_t write_key[32]); + +// Random command functions +ATCA_STATUS atcab_random(uint8_t* rand_out); + +// Read command functions +ATCA_STATUS atcab_read_zone(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint8_t *data, uint8_t len); +ATCA_STATUS atcab_is_locked(uint8_t zone, bool *is_locked); +ATCA_STATUS atcab_is_slot_locked(uint16_t slot, bool *is_locked); +ATCA_STATUS atcab_read_bytes_zone(uint8_t zone, uint16_t slot, size_t offset, uint8_t *data, size_t length); +ATCA_STATUS atcab_read_serial_number(uint8_t* serial_number); +ATCA_STATUS atcab_read_pubkey(uint16_t slot, uint8_t *public_key); +ATCA_STATUS atcab_read_sig(uint16_t slot, uint8_t *sig); +ATCA_STATUS atcab_read_config_zone(uint8_t* config_data); +ATCA_STATUS atcab_cmp_config_zone(uint8_t* config_data, bool* same_config); +ATCA_STATUS atcab_read_enc(uint16_t key_id, uint8_t block, uint8_t *data, const uint8_t* enc_key, const uint16_t enc_key_id); + +// SecureBoot command functions +ATCA_STATUS atcab_secureboot(uint8_t mode, uint16_t param2, const uint8_t* digest, const uint8_t* signature, uint8_t* mac); +ATCA_STATUS atcab_secureboot_mac(uint8_t mode, const uint8_t* digest, const uint8_t* signature, const uint8_t* num_in, const uint8_t* io_key, bool* is_verified); + +// SelfTest command functions +ATCA_STATUS atcab_selftest(uint8_t mode, uint16_t param2, uint8_t* result); + +// SHA command functions +typedef struct atca_sha256_ctx +{ + uint32_t total_msg_size; //!< Total number of message bytes processed + uint32_t block_size; //!< Number of bytes in current block + uint8_t block[ATCA_SHA256_BLOCK_SIZE * 2]; //!< Unprocessed message storage +} atca_sha256_ctx_t; + +typedef atca_sha256_ctx_t atca_hmac_sha256_ctx_t; + +ATCA_STATUS atcab_sha_base(uint8_t mode, uint16_t length, const uint8_t* data_in, uint8_t* data_out, uint16_t* data_out_size); +ATCA_STATUS atcab_sha_start(void); +ATCA_STATUS atcab_sha_update(const uint8_t* message); +ATCA_STATUS atcab_sha_end(uint8_t *digest, uint16_t length, const uint8_t *message); +ATCA_STATUS atcab_sha_read_context(uint8_t* context, uint16_t* context_size); +ATCA_STATUS atcab_sha_write_context(const uint8_t* context, uint16_t context_size); +ATCA_STATUS atcab_sha(uint16_t length, const uint8_t *message, uint8_t *digest); +ATCA_STATUS atcab_hw_sha2_256(const uint8_t * data, size_t data_size, uint8_t* digest); +ATCA_STATUS atcab_hw_sha2_256_init(atca_sha256_ctx_t* ctx); +ATCA_STATUS atcab_hw_sha2_256_update(atca_sha256_ctx_t* ctx, const uint8_t* data, size_t data_size); +ATCA_STATUS atcab_hw_sha2_256_finish(atca_sha256_ctx_t* ctx, uint8_t* digest); +ATCA_STATUS atcab_sha_hmac_init(atca_hmac_sha256_ctx_t* ctx, uint16_t key_slot); +ATCA_STATUS atcab_sha_hmac_update(atca_hmac_sha256_ctx_t* ctx, const uint8_t* data, size_t data_size); +ATCA_STATUS atcab_sha_hmac_finish(atca_hmac_sha256_ctx_t* ctx, uint8_t* digest, uint8_t target); +ATCA_STATUS atcab_sha_hmac(const uint8_t * data, size_t data_size, uint16_t key_slot, uint8_t* digest, uint8_t target); + +// Sign command functions +ATCA_STATUS atcab_sign_base(uint8_t mode, uint16_t key_id, uint8_t *signature); +ATCA_STATUS atcab_sign(uint16_t key_id, const uint8_t *msg, uint8_t *signature); +ATCA_STATUS atcab_sign_internal(uint16_t key_id, bool is_invalidate, bool is_full_sn, uint8_t *signature); + +// UpdateExtra command functions +ATCA_STATUS atcab_updateextra(uint8_t mode, uint16_t new_value); + +// Verify command functions +ATCA_STATUS atcab_verify(uint8_t mode, uint16_t key_id, const uint8_t* signature, const uint8_t* public_key, const uint8_t* other_data, uint8_t* mac); +ATCA_STATUS atcab_verify_extern(const uint8_t *message, const uint8_t *signature, const uint8_t *public_key, bool *is_verified); +ATCA_STATUS atcab_verify_extern_mac(const uint8_t *message, const uint8_t* signature, const uint8_t* public_key, const uint8_t* num_in, const uint8_t* io_key, bool* is_verified); +ATCA_STATUS atcab_verify_stored(const uint8_t *message, const uint8_t *signature, uint16_t key_id, bool *is_verified); +ATCA_STATUS atcab_verify_stored_mac(const uint8_t *message, const uint8_t *signature, uint16_t key_id, const uint8_t* num_in, const uint8_t* io_key, bool* is_verified); + +ATCA_STATUS atcab_verify_validate(uint16_t key_id, const uint8_t *signature, const uint8_t *other_data, bool *is_verified); +ATCA_STATUS atcab_verify_invalidate(uint16_t key_id, const uint8_t *signature, const uint8_t *other_data, bool *is_verified); + +// Write command functions +ATCA_STATUS atcab_write(uint8_t zone, uint16_t address, const uint8_t *value, const uint8_t *mac); +ATCA_STATUS atcab_write_zone(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, const uint8_t *data, uint8_t len); +ATCA_STATUS atcab_write_bytes_zone(uint8_t zone, uint16_t slot, size_t offset_bytes, const uint8_t *data, size_t length); +ATCA_STATUS atcab_write_pubkey(uint16_t slot, const uint8_t *public_key); +ATCA_STATUS atcab_write_config_zone(const uint8_t* config_data); +ATCA_STATUS atcab_write_enc(uint16_t key_id, uint8_t block, const uint8_t *data, const uint8_t* enc_key, const uint16_t enc_key_id); +ATCA_STATUS atcab_write_config_counter(uint16_t counter_id, uint32_t counter_value); + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* ATCA_BASIC_H_ */ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_aes.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_aes.c new file mode 100644 index 0000000..993f701 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_aes.c @@ -0,0 +1,153 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for AES command. + * + * The AES command supports 128-bit AES encryption or decryption of small + * messages or data packets in ECB mode. Also can perform GFM (Galois Field + * Multiply) calculation in support of AES-GCM. + * + * \note List of devices that support this command - ATECC608A. Refer to device + * datasheet for full details. + * + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ +#include "atca_basic.h" +#include "atca_execution.h" +#ifdef _WIN32 +#include +#endif + + +/** \brief Compute the AES-128 encrypt, decrypt, or GFM calculation. + * \param[in] mode The mode for the AES command. + * \param[in] key_id Key location. Can either be a slot number or + * ATCA_TEMPKEY_KEYID for TempKey. + * \param[in] aes_in Input data to the AES command (16 bytes). + * \param[out] aes_out Output data from the AES command is returned here (16 + * bytes). + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes(uint8_t mode, uint16_t key_id, const uint8_t* aes_in, uint8_t* aes_out) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + + do + { + if (aes_in == NULL) + { + status = ATCA_BAD_PARAM; + break; + } + + // build a AES command + packet.param1 = mode; + packet.param2 = key_id; + if (AES_MODE_GFM == (mode & AES_MODE_GFM)) + { + memcpy(packet.data, aes_in, ATCA_AES_GFM_SIZE); + } + else + { + memcpy(packet.data, aes_in, AES_DATA_SIZE); + } + + if ((status = atAES(ca_cmd, &packet)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + if (aes_out && packet.data[ATCA_COUNT_IDX] >= (3 + AES_DATA_SIZE)) + { + // The AES command return a 16 byte data. + memcpy(aes_out, &packet.data[ATCA_RSP_DATA_IDX], AES_DATA_SIZE); + } + + } + while (0); + + return status; +} + +/** \brief Perform an AES-128 encrypt operation with a key in the device. + * + * \param[in] key_id Key location. Can either be a slot number or + * ATCA_TEMPKEY_KEYID for TempKey. + * \param[in] key_block Index of the 16-byte block to use within the key + * location for the actual key. + * \param[in] plaintext Input plaintext to be encrypted (16 bytes). + * \param[out] ciphertext Output ciphertext is returned here (16 bytes). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_encrypt(uint16_t key_id, uint8_t key_block, const uint8_t* plaintext, uint8_t* ciphertext) +{ + uint8_t mode; + + mode = AES_MODE_ENCRYPT | (AES_MODE_KEY_BLOCK_MASK & (key_block << AES_MODE_KEY_BLOCK_POS)); + return atcab_aes(mode, key_id, plaintext, ciphertext); +} + +/** \brief Perform an AES-128 decrypt operation with a key in the device. + * + * \param[in] key_id Key location. Can either be a slot number or + * ATCA_TEMPKEY_KEYID for TempKey. + * \param[in] key_block Index of the 16-byte block to use within the key + * location for the actual key. + * \param[in] ciphertext Input ciphertext to be decrypted (16 bytes). + * \param[out] plaintext Output plaintext is returned here (16 bytes). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_decrypt(uint16_t key_id, uint8_t key_block, const uint8_t* ciphertext, uint8_t* plaintext) +{ + uint8_t mode; + + mode = AES_MODE_DECRYPT | (AES_MODE_KEY_BLOCK_MASK & (key_block << AES_MODE_KEY_BLOCK_POS)); + return atcab_aes(mode, key_id, ciphertext, plaintext); +} + +/** \brief Perform a Galois Field Multiply (GFM) operation. + * + * \param[in] h First input value (16 bytes). + * \param[in] input Second input value (16 bytes). + * \param[out] output GFM result is returned here (16 bytes). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_gfm(const uint8_t* h, const uint8_t* input, uint8_t* output) +{ + uint8_t aes_in[AES_DATA_SIZE * 2]; + + memcpy(aes_in, h, AES_DATA_SIZE); + memcpy(aes_in + AES_DATA_SIZE, input, AES_DATA_SIZE); + // KeyID is ignored for GFM mode + return atcab_aes(AES_MODE_GFM, 0x0000, aes_in, output); +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_aes_cbc.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_aes_cbc.c new file mode 100644 index 0000000..1508b29 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_aes_cbc.c @@ -0,0 +1,144 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for AES CBC mode. + * + * The AES command supports 128-bit AES encryption or decryption of small + * messages or data packets in ECB mode. Also can perform GFM (Galois Field + * Multiply) calculation in support of AES-GCM. + * + * \note List of devices that support this command - ATECC608A. Refer to device + * datasheet for full details. + * + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ +#include "atca_basic.h" +#ifdef _WIN32 +#include +#endif + +/** \brief Initialize context for AES CBC operation. + * + * \param[in] ctx AES CBC context to be initialized + * \param[in] key_id Key location. Can either be a slot number or + * ATCA_TEMPKEY_KEYID for TempKey. + * \param[in] key_block Index of the 16-byte block to use within the key + * location for the actual key. + * \param[in] iv Initialization vector (16 bytes). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_cbc_init(atca_aes_cbc_ctx_t* ctx, uint16_t key_id, uint8_t key_block, const uint8_t* iv) +{ + if (ctx == NULL || iv == NULL) + { + return ATCA_BAD_PARAM; + } + + memset(ctx, 0, sizeof(*ctx)); + ctx->key_id = key_id; + ctx->key_block = key_block; + memcpy(ctx->ciphertext, iv, sizeof(ctx->ciphertext)); + + return ATCA_SUCCESS; +} + +/** \brief Encrypt a block of data using CBC mode and a key within the + * ATECC608A. atcab_aes_cbc_init() should be called before the + * first use of this function. + * + * \param[in] ctx AES CBC context. + * \param[in] plaintext Plaintext to be encrypted (16 bytes). + * \param[out] ciphertext Encrypted data is returned here (16 bytes). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_cbc_encrypt_block(atca_aes_cbc_ctx_t* ctx, const uint8_t* plaintext, uint8_t* ciphertext) +{ + uint8_t input[AES_DATA_SIZE]; + int i; + ATCA_STATUS status = ATCA_SUCCESS; + + if (ctx == NULL || plaintext == NULL || ciphertext == NULL) + { + return ATCA_BAD_PARAM; + } + + // XOR plaintext with previous block's ciphertext to get input value to block encrypt + for (i = 0; i < AES_DATA_SIZE; i++) + { + input[i] = plaintext[i] ^ ctx->ciphertext[i]; + } + + // Block encrypt of input data + status = atcab_aes_encrypt(ctx->key_id, ctx->key_block, input, ciphertext); + if (status != ATCA_SUCCESS) + { + return status; + } + + // Save copy of ciphertext for next block operation + memcpy(ctx->ciphertext, ciphertext, AES_DATA_SIZE); + + return status; +} + +/** \brief Decrypt a block of data using CBC mode and a key within the + * ATECC608A. atcab_aes_cbc_init() should be called before the + * first use of this function. + * + * \param[in] ctx AES CBC context. + * \param[in] ciphertext Ciphertext to be decrypted (16 bytes). + * \param[out] plaintext Decrypted data is returned here (16 bytes). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_cbc_decrypt_block(atca_aes_cbc_ctx_t* ctx, const uint8_t* ciphertext, uint8_t* plaintext) +{ + uint8_t output[AES_DATA_SIZE]; + int i; + ATCA_STATUS status = ATCA_SUCCESS; + + if (ctx == NULL || ciphertext == NULL || plaintext == NULL) + { + return ATCA_BAD_PARAM; + } + + // Block decrypt of ciphertext + status = atcab_aes_decrypt(ctx->key_id, ctx->key_block, ciphertext, output); + if (status != ATCA_SUCCESS) + { + return status; + } + + // XOR output with previous block's ciphertext to get plaintext + for (i = 0; i < AES_DATA_SIZE; i++) + { + plaintext[i] = output[i] ^ ctx->ciphertext[i]; + } + + // Save copy of ciphertext for next block operation + memcpy(ctx->ciphertext, ciphertext, AES_DATA_SIZE); + + return status; +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_aes_cmac.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_aes_cmac.c new file mode 100644 index 0000000..8f4d357 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_aes_cmac.c @@ -0,0 +1,218 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for AES CBC_MAC mode. + * + * The AES command supports 128-bit AES encryption or decryption of small + * messages or data packets in ECB mode. Also can perform GFM (Galois Field + * Multiply) calculation in support of AES-GCM. + * + * \note List of devices that support this command - ATECC608A. Refer to device + * datasheet for full details. + * + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ +#include "atca_basic.h" +#ifdef _WIN32 +#include +#endif + +static const uint8_t g_aes_zero_block[AES_DATA_SIZE] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/** \brief Initialize a CMAC calculation using an AES-128 key in the ATECC608A. + * + * \param[in] ctx AES-128 CMAC context. + * \param[in] key_id Key location. Can either be a slot number or + * ATCA_TEMPKEY_KEYID for TempKey. + * \param[in] key_block Index of the 16-byte block to use within the key + * location for the actual key. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_cmac_init(atca_aes_cmac_ctx_t* ctx, uint16_t key_id, uint8_t key_block) +{ + if (ctx == NULL) + { + return ATCA_BAD_PARAM; + } + memset(ctx, 0, sizeof(*ctx)); + // IV for CMAC CBC calculations is all zeros + return atcab_aes_cbc_init(&ctx->cbc_ctx, key_id, key_block, g_aes_zero_block); +} + +/** \brief Add data to an initialized CMAC calculation. + * + * \param[in] ctx AES-128 CMAC context. + * \param[in] data Data to be added. + * \param[in] data_size Size of the data to be added in bytes. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_cmac_update(atca_aes_cmac_ctx_t* ctx, const uint8_t* data, uint32_t data_size) +{ + uint32_t rem_size = AES_DATA_SIZE - ctx->block_size; + uint32_t copy_size = data_size > rem_size ? rem_size : data_size; + ATCA_STATUS status = ATCA_SUCCESS; + uint8_t ciphertext[AES_DATA_SIZE]; + uint32_t block_count; + uint32_t i; + + if (ctx == NULL || (data == NULL && data_size > 0)) + { + return ATCA_BAD_PARAM; + } + + memcpy(&ctx->block[ctx->block_size], data, copy_size); + + if (ctx->block_size + data_size < AES_DATA_SIZE + 1) + { + // The last block of a CMAC operation is handled specially, so we don't + // process a complete block unless we know there's data afterwards. + ctx->block_size += data_size; + return ATCA_SUCCESS; + } + + // Process the current block + status = atcab_aes_cbc_encrypt_block(&ctx->cbc_ctx, ctx->block, ciphertext); + if (status != ATCA_SUCCESS) + { + return status; + } + + // Process any additional blocks + data_size -= copy_size; // Adjust to the remaining message bytes + block_count = data_size / AES_DATA_SIZE; + if (block_count > 0 && data_size % AES_DATA_SIZE == 0) + { + block_count--; // Don't process last block because it may need special handling + } + for (i = 0; i < block_count; i++) + { + status = atcab_aes_cbc_encrypt_block(&ctx->cbc_ctx, &data[copy_size + i * AES_DATA_SIZE], ciphertext); + if (status != ATCA_SUCCESS) + { + return status; + } + data_size -= AES_DATA_SIZE; + } + + // Save any remaining data + ctx->block_size = data_size; + memcpy(ctx->block, &data[copy_size + block_count * AES_DATA_SIZE], ctx->block_size); + + return ATCA_SUCCESS; +} + +/** \brief Left shift an MSB buffer by 1 bit. + * + * \param[inout] data Data to left shift. + * \param[in] data_size Size of data in bytes. + */ +static void left_shift_one(uint8_t* data, size_t data_size) +{ + size_t i; + + for (i = 0; i < data_size; i++) + { + data[i] = data[i] << 1; + if (i + 1 < data_size && data[i + 1] & 0x80) + { + data[i] |= 0x01; // Next byte has a bit that needs to be shifted into this one + } + } +} + +/** \brief Finish a CMAC operation returning the CMAC value. + * + * \param[in] ctx AES-128 CMAC context. + * \param[out] cmac CMAC is returned here. + * \param[in] cmac_size Size of CMAC requested in bytes (max 16 bytes). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_cmac_finish(atca_aes_cmac_ctx_t* ctx, uint8_t* cmac, uint32_t cmac_size) +{ + uint32_t i; + uint8_t subkey[AES_DATA_SIZE]; + ATCA_STATUS status = ATCA_SUCCESS; + bool is_msb_one; + uint8_t cmac_full[AES_DATA_SIZE]; + + if (ctx == NULL || cmac == NULL || cmac_size > AES_DATA_SIZE) + { + return ATCA_BAD_PARAM; + } + + // Calculate L as AES Encrypt of an all zero block + status = atcab_aes_encrypt(ctx->cbc_ctx.key_id, ctx->cbc_ctx.key_block, g_aes_zero_block, subkey); + if (status != ATCA_SUCCESS) + { + return status; + } + + // Calculate subkey 1 + is_msb_one = (subkey[0] & 0x80); + left_shift_one(subkey, sizeof(subkey)); // L << 1 + if (is_msb_one) + { + subkey[AES_DATA_SIZE - 1] ^= 0x87; // (L << 1) XOR R128 + } + + if (ctx->block_size != AES_DATA_SIZE) + { + // Data is not a complete block, we calculate subkey 2 + is_msb_one = (subkey[0] & 0x80); + left_shift_one(subkey, sizeof(subkey)); // K1 << 1 + if (is_msb_one) + { + subkey[AES_DATA_SIZE - 1] ^= 0x87; // (K1 << 1) XOR R128 + } + + // Pad out an incomplete block starting with a 1 bit, followed by zeros + for (i = 0; i < AES_DATA_SIZE - ctx->block_size; i++) + { + ctx->block[ctx->block_size + i] = (i == 0 ? 0x80 : 0x00); + } + } + + // XOR last block with subkey + for (i = 0; i < AES_DATA_SIZE; i++) + { + ctx->block[i] ^= subkey[i]; + } + + // Process last block + status = atcab_aes_cbc_encrypt_block(&ctx->cbc_ctx, ctx->block, cmac_full); + if (status != ATCA_SUCCESS) + { + return status; + } + + memcpy(cmac, cmac_full, cmac_size); + + return ATCA_SUCCESS; +} + diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_aes_ctr.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_aes_ctr.c new file mode 100644 index 0000000..d8dbb37 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_aes_ctr.c @@ -0,0 +1,230 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for AES CTR mode. + * + * The AES command supports 128-bit AES encryption or decryption of small + * messages or data packets in ECB mode. Also can perform GFM (Galois Field + * Multiply) calculation in support of AES-GCM. + * + * \note List of devices that support this command - ATECC608A. Refer to device + * datasheet for full details. + * + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ +#include "basic/atca_basic.h" + +/** \brief Initialize context for AES CTR operation with an existing IV, which + * is common when start a decrypt operation. + * + * The IV is a combination of nonce (left-field) and big-endian counter + * (right-field). The counter_size field sets the size of the counter and the + * remaining bytes are assumed to be the nonce. + * + * \param[in] ctx AES CTR context to be initialized. + * \param[in] key_id Key location. Can either be a slot number or + * ATCA_TEMPKEY_KEYID for TempKey. + * \param[in] key_block Index of the 16-byte block to use within the key + * location for the actual key. + * \param[in] counter_size Size of counter in IV in bytes. 4 bytes is a + * common size. + * \param[in] iv Initialization vector (concatenation of nonce and + * counter) 16 bytes. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_ctr_init(atca_aes_ctr_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t counter_size, const uint8_t* iv) +{ + if (ctx == NULL || iv == NULL || counter_size > AES_DATA_SIZE) + { + return ATCA_BAD_PARAM; + } + memset(ctx, 0, sizeof(*ctx)); + ctx->key_id = key_id; + ctx->key_block = key_block; + ctx->counter_size = counter_size; + memcpy(ctx->cb, iv, AES_DATA_SIZE); + + return ATCA_SUCCESS; +} + +/** \brief Initialize context for AES CTR operation with a random nonce and + * counter set to 0 as the IV, which is common when starting an + * encrypt operation. + * + * The IV is a combination of nonce (left-field) and big-endian counter + * (right-field). The counter_size field sets the size of the counter and the + * remaining bytes are assumed to be the nonce. + * + * \param[in] ctx AES CTR context to be initialized. + * \param[in] key_id Key location. Can either be a slot number or + * ATCA_TEMPKEY_KEYID for TempKey. + * \param[in] key_block Index of the 16-byte block to use within the key + * location for the actual key. + * \param[in] counter_size Size of counter in IV in bytes. 4 bytes is a + * common size. + * \param[out] iv Initialization vector (concatenation of nonce and + * counter) is returned here (16 bytes). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_ctr_init_rand(atca_aes_ctr_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t counter_size, uint8_t* iv) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint8_t nonce_size; + + if (ctx == NULL || iv == NULL || counter_size > AES_DATA_SIZE) + { + return ATCA_BAD_PARAM; + } + memset(ctx, 0, sizeof(*ctx)); + ctx->key_id = key_id; + ctx->key_block = key_block; + ctx->counter_size = counter_size; + + // Generate random nonce + nonce_size = AES_DATA_SIZE - ctx->counter_size; + if (nonce_size != 0) + { + uint8_t random_nonce[32]; + status = atcab_random(random_nonce); + if (status != ATCA_SUCCESS) + { + return status; + } + memcpy(iv, random_nonce, nonce_size); + } + memcpy(ctx->cb, iv, AES_DATA_SIZE); + + return ATCA_SUCCESS; +} + +/** \brief Increments AES CTR counter value. + * + * \param[in,out] ctx AES CTR context + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_ctr_increment(atca_aes_ctr_ctx_t* ctx) +{ + size_t i; + + if (ctx == NULL || ctx->counter_size > AES_DATA_SIZE) + { + return ATCA_BAD_PARAM; + } + + // Increment the big-endian counter value + for (i = 0; i < ctx->counter_size; i++) + { + // Counter is right-aligned in buffer + if (++(ctx->cb[AES_DATA_SIZE - i - 1]) != 0) + { + break; + } + } + if (i >= ctx->counter_size) + { + // Counter overflowed + memset(&ctx->cb[AES_DATA_SIZE - ctx->counter_size], 0, ctx->counter_size); + } + + return ATCA_SUCCESS; +} + +/** \brief Process a block of data using CTR mode and a key within the + * ATECC608A device. atcab_aes_ctr_init() or atcab_aes_ctr_init_rand() + * should be called before the first use of this function. + * + * \param[in] ctx AES CTR context structure. + * \param[in] input Input data to be processed (16 bytes). + * \param[out] output Output data is returned here (16 bytes). + * + * \return ATCA_SUCCESS on success, ATCA_INVALID_SIZE on counter overflow, + * otherwise an error code. + */ +ATCA_STATUS atcab_aes_ctr_block(atca_aes_ctr_ctx_t* ctx, const uint8_t* input, uint8_t* output) +{ + uint8_t i; + ATCA_STATUS status = ATCA_SUCCESS; + uint8_t encrypted_counter[AES_DATA_SIZE]; + + if (ctx == NULL || input == NULL || output == NULL) + { + return ATCA_BAD_PARAM; + } + + // Block encrypt of counter block (128 bits) + status = atcab_aes_encrypt(ctx->key_id, ctx->key_block, ctx->cb, encrypted_counter); + if (status != ATCA_SUCCESS) + { + return status; + } + + // XOR output of AES encrypt with input to get output + for (i = 0; i < AES_DATA_SIZE; i++) + { + output[i] = encrypted_counter[i] ^ input[i]; + } + + status = atcab_aes_ctr_increment(ctx); + if (status != ATCA_SUCCESS) + { + return status; + } + + return status; +} + +/** \brief Encrypt a block of data using CTR mode and a key within the + * ATECC608A device. atcab_aes_ctr_init() or atcab_aes_ctr_init_rand() + * should be called before the first use of this function. + * + * \param[in] ctx AES CTR context structure. + * \param[in] plaintext Plaintext to be encrypted (16 bytes). + * \param[out] ciphertext Encrypted data is returned here (16 bytes). + * + * \return ATCA_SUCCESS on success, ATCA_INVALID_SIZE on counter overflow, + * otherwise an error code. + */ +ATCA_STATUS atcab_aes_ctr_encrypt_block(atca_aes_ctr_ctx_t* ctx, const uint8_t* plaintext, uint8_t* ciphertext) +{ + return atcab_aes_ctr_block(ctx, plaintext, ciphertext); +} + +/** \brief Decrypt a block of data using CTR mode and a key within the + * ATECC608A device. atcab_aes_ctr_init() or atcab_aes_ctr_init_rand() + * should be called before the first use of this function. + * + * \param[in] ctx AES CTR context structure. + * \param[in] ciphertext Ciphertext to be decrypted (16 bytes). + * \param[out] plaintext Decrypted data is returned here (16 bytes). + * + * \return ATCA_SUCCESS on success, ATCA_INVALID_SIZE on counter overflow, + * otherwise an error code. + */ +ATCA_STATUS atcab_aes_ctr_decrypt_block(atca_aes_ctr_ctx_t* ctx, const uint8_t* ciphertext, uint8_t* plaintext) +{ + return atcab_aes_ctr_block(ctx, ciphertext, plaintext); +} + diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_aes_gcm.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_aes_gcm.c new file mode 100644 index 0000000..0b2297f --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_aes_gcm.c @@ -0,0 +1,583 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for AES GCM mode. + * + * The AES command supports 128-bit AES encryption or decryption of small + * messages or data packets in ECB mode. Also can perform GFM (Galois Field + * Multiply) calculation in support of AES-GCM. + * + * \note List of devices that support this command - ATECC608A. Refer to device + * datasheet for full details. + * + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ +#include "atca_basic_aes_gcm.h" +#include "atca_compiler.h" + +/** \ingroup atcab_ + * @{ + */ + +const char* atca_basic_aes_gcm_version = "1.0"; + +/** \brief Performs running GHASH calculations using the current hash value, + * hash subkey, and data received. In case of partial blocks, the last + * block is padded with zeros to get the output. + * + * \param[in] h Subkey to use in GHASH calculations. + * \param[in] data Input data to hash. + * \param[in] data_size Data size in bytes. + * \param[in,out] y As input, current hash value. As output, the new + * hash output. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS atcab_aes_ghash(const uint8_t* h, const uint8_t* data, size_t data_size, uint8_t* y) +{ + ATCA_STATUS status; + uint8_t pad_bytes[AES_DATA_SIZE]; + size_t xor_index; + + if (h == NULL || data == NULL || y == NULL) + { + RETURN(ATCA_BAD_PARAM, "Null pointer"); + } + if (data_size == 0) + { + return ATCA_SUCCESS; + } + + while (data_size / AES_DATA_SIZE) + { + for (xor_index = 0; xor_index < AES_DATA_SIZE; xor_index++) + { + y[xor_index] ^= *data++; + } + + if (ATCA_SUCCESS != (status = atcab_aes_gfm(h, y, y))) + { + RETURN(status, "GHASH GFM (full block) failed"); + } + + data_size -= AES_DATA_SIZE; + } + + if (data_size) + { + memcpy(pad_bytes, data, data_size); + memset(&pad_bytes[data_size], 0, sizeof(pad_bytes) - data_size); + + for (xor_index = 0; xor_index < AES_DATA_SIZE; xor_index++) + { + y[xor_index] ^= pad_bytes[xor_index]; + } + + if (ATCA_SUCCESS != (status = atcab_aes_gfm(h, y, y))) + { + RETURN(status, "GHASH GFM (partial block) failed"); + } + } + + return ATCA_SUCCESS; +} + +/** \brief Increments AES GCM counter value. + * + * \param[in,out] cb AES GCM counter block to be incremented + * (16 bytes). + * \param[in] counter_size Counter size in bytes. Should be 4 for GCM. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS atcab_aes_gcm_increment(uint8_t* cb, size_t counter_size) +{ + size_t i; + + if (cb == NULL) + { + return ATCA_BAD_PARAM; + } + + // Not converting to uint32_t and incrementing as there may be alignment + // issues with the cb buffer + + // Increment the big-endian counter value + for (i = 0; i < counter_size; i++) + { + // Counter is right-aligned in buffer + if (++(cb[AES_DATA_SIZE - i - 1]) != 0) + { + break; + } + } + if (i >= counter_size) + { + // Counter overflowed + memset(&cb[AES_DATA_SIZE - counter_size], 0, counter_size); + } + + return ATCA_SUCCESS; +} + +/** \brief Initialize context for AES GCM operation with an existing IV, which + * is common when starting a decrypt operation. + * + * \param[in] ctx AES GCM context to be initialized. + * \param[in] key_id Key location. Can either be a slot number or + * ATCA_TEMPKEY_KEYID for TempKey. + * \param[in] key_block Index of the 16-byte block to use within the key + * location for the actual key. + * \param[in] iv Initialization vector. + * \param[in] iv_size Size of IV in bytes. Standard is 12 bytes. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_gcm_init(atca_aes_gcm_ctx_t* ctx, uint16_t key_id, uint8_t key_block, const uint8_t* iv, size_t iv_size) +{ + ATCA_STATUS status; + uint8_t ghash_data[AES_DATA_SIZE]; + uint32_t length; + + if (ctx == NULL || iv == NULL || iv_size == 0) + { + RETURN(ATCA_BAD_PARAM, "GCM init failed; Either null pointer or 0 iv_size"); + } + + memset(ctx, 0, sizeof(*ctx)); + + //Calculate H = CIPHK(0^128) + if (ATCA_SUCCESS != (status = atcab_aes_encrypt(key_id, key_block, ctx->h, ctx->h))) + { + RETURN(status, "GCM - H failed"); + } + + //Calculate J0 + if (iv_size == ATCA_AES_GCM_IV_STD_LENGTH) + { + //J0 = IV || 0^31 ||1. + memcpy(ctx->j0, iv, iv_size); + ctx->j0[AES_DATA_SIZE - 1] = 0x01; + } + else + { + //J0=GHASH(H, IV||0^(s+64)||[len(IV)]64) + if (ATCA_SUCCESS != (status = atcab_aes_ghash(ctx->h, iv, iv_size, ctx->j0))) + { + RETURN(status, "GCM - J0 (IV) failed"); + } + + memset(ghash_data, 0, AES_DATA_SIZE); + length = ATCA_UINT32_HOST_TO_BE((uint32_t)(iv_size * 8)); + memcpy(&ghash_data[12], &length, sizeof(length)); + if (ATCA_SUCCESS != (status = atcab_aes_ghash(ctx->h, ghash_data, sizeof(ghash_data), ctx->j0))) + { + RETURN(status, "GCM - J0 (IV Size) failed"); + } + } + + ctx->key_id = key_id; + ctx->key_block = key_block; + memcpy(ctx->cb, ctx->j0, AES_DATA_SIZE); + + if (ATCA_SUCCESS != (status = atcab_aes_gcm_increment(ctx->cb, 4))) + { + RETURN(status, "GCM CTR increment failed"); + } + + return ATCA_SUCCESS; +} + +/** \brief Initialize context for AES GCM operation with a IV composed of a + * random and optional fixed(free) field, which is common when + * starting an encrypt operation. + * + * \param[in] ctx AES CTR context to be initialized. + * \param[in] key_id Key location. Can either be a slot number or + * ATCA_TEMPKEY_KEYID for TempKey. + * \param[in] key_block Index of the 16-byte block to use within the + * key location for the actual key. + * \param[in] rand_size Size of the random field in bytes. Minimum and + * recommended size is 12 bytes. Max is 32 bytes. + * \param[in] free_field Fixed data to include in the IV after the + * random field. Can be NULL if not used. + * \param[in] free_field_size Size of the free field in bytes. + * \param[out] iv Initialization vector is returned here. Its + * size will be rand_size and free_field_size + * combined. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_gcm_init_rand(atca_aes_gcm_ctx_t* ctx, uint16_t key_id, uint8_t key_block, size_t rand_size, + const uint8_t* free_field, size_t free_field_size, uint8_t* iv) +{ + ATCA_STATUS status; + uint8_t random[RANDOM_NUM_SIZE]; + + if (ctx == NULL || iv == NULL || (free_field_size > 0 && free_field == NULL)) + { + RETURN(ATCA_BAD_PARAM, "Null pointer"); + } + // 800-38D 8.2.2 specifies a minimum rand_field size of 12 bytes (96 bits) + if (rand_size < 12 || rand_size > RANDOM_NUM_SIZE) + { + RETURN(ATCA_BAD_PARAM, "Bad rand_size"); + } + + if (ATCA_SUCCESS != (status = atcab_random(random))) + { + RETURN(status, "GCM init rand - Random Generation failed"); + } + memcpy(iv, random, rand_size); + memcpy(&iv[rand_size], free_field, free_field_size); + + if (ATCA_SUCCESS != (status = atcab_aes_gcm_init(ctx, key_id, key_block, iv, rand_size + free_field_size))) + { + RETURN(status, "GCM init failed"); + } + + return ATCA_SUCCESS; +} + +/** \brief Process Additional Authenticated Data (AAD) using GCM mode and a + * key within the ATECC608A device. + * + * This can be called multiple times. atcab_aes_gcm_init() or + * atcab_aes_gcm_init_rand() should be called before the first use of this + * function. When there is AAD to include, this should be called before + * atcab_aes_gcm_encrypt_update() or atcab_aes_gcm_decrypt_update(). + * + * \param[in] ctx AES GCM context + * \param[in] aad Additional authenticated data to be added + * \param[in] aad_size Size of aad in bytes + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_gcm_aad_update(atca_aes_gcm_ctx_t* ctx, const uint8_t* aad, uint32_t aad_size) +{ + ATCA_STATUS status; + uint32_t block_count; + uint32_t rem_size; + uint32_t copy_size; + + if (ctx == NULL || (aad_size > 0 && aad == NULL)) + { + RETURN(ATCA_BAD_PARAM, "Null pointer"); + } + + if (aad_size == 0) + { + return ATCA_SUCCESS; + } + + rem_size = AES_DATA_SIZE - (uint32_t)ctx->partial_aad_size; + copy_size = aad_size > rem_size ? rem_size : aad_size; + + // Copy data into current block + memcpy(&ctx->partial_aad[ctx->partial_aad_size], aad, copy_size); + + if (ctx->partial_aad_size + aad_size < AES_DATA_SIZE) + { + // Not enough data to finish off the current block + ctx->partial_aad_size += aad_size; + return ATCA_SUCCESS; + } + + // Process the current block + if (ATCA_SUCCESS != (status = atcab_aes_ghash(ctx->h, ctx->partial_aad, AES_DATA_SIZE, ctx->y))) + { + RETURN(status, "GCM - S (AAD) failed"); + } + + // Process any additional blocks + aad_size -= copy_size; // Adjust to the remaining aad bytes + block_count = aad_size / AES_DATA_SIZE; + if (ATCA_SUCCESS != (status = atcab_aes_ghash(ctx->h, &aad[copy_size], block_count * AES_DATA_SIZE, ctx->y))) + { + RETURN(status, "GCM - S (AAD) failed"); + } + + // Save any remaining data + ctx->aad_size += (block_count + 1) * AES_DATA_SIZE; + ctx->partial_aad_size = aad_size % AES_DATA_SIZE; + memcpy(ctx->partial_aad, &aad[copy_size + block_count * AES_DATA_SIZE], ctx->partial_aad_size); + + return ATCA_SUCCESS; +} + +/** \brief Process data using GCM mode and a key within the ATECC608A device. + * atcab_aes_gcm_init() or atcab_aes_gcm_init_rand() should be called + * before the first use of this function. + * + * \param[in] ctx AES GCM context structure. + * \param[in] input Data to be processed. + * \param[in] input_size Size of input in bytes. + * \param[out] output Output data is returned here. + * \param[in] is_encrypt Encrypt operation if true, otherwise decrypt. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS atcab_aes_gcm_update(atca_aes_gcm_ctx_t* ctx, const uint8_t* input, uint32_t input_size, + uint8_t* output, bool is_encrypt) +{ + ATCA_STATUS status; + uint32_t data_idx; + uint32_t i; + + if (ctx == NULL || (input_size > 0 && (input == NULL || output == NULL))) + { + RETURN(ATCA_BAD_PARAM, "Null pointer"); + } + + if (ctx->partial_aad_size > 0) + { + // We have a partial block of AAD that needs to be added + if (ATCA_SUCCESS != (status = atcab_aes_ghash(ctx->h, ctx->partial_aad, ctx->partial_aad_size, ctx->y))) + { + RETURN(status, "GCM - S (AAD partial) failed"); + } + ctx->aad_size += ctx->partial_aad_size; + ctx->partial_aad_size = 0; + } + + if (input_size == 0) + { + // Nothing to do + return ATCA_SUCCESS; + } + + data_idx = 0; + while (data_idx < input_size) + { + if (ctx->data_size % AES_DATA_SIZE == 0) + { + // Need to calculate next encrypted counter block + if (ATCA_SUCCESS != (status = atcab_aes_encrypt(ctx->key_id, ctx->key_block, ctx->cb, ctx->enc_cb))) + { + RETURN(status, "AES GCM CB encrypt failed"); + } + + // Increment counter + if (ATCA_SUCCESS != (status = atcab_aes_gcm_increment(ctx->cb, 4))) + { + RETURN(status, "AES GCM counter increment failed"); + } + } + + // Process data with current encrypted counter block + for (i = ctx->data_size % AES_DATA_SIZE; i < AES_DATA_SIZE && data_idx < input_size; i++, data_idx++) + { + output[data_idx] = input[data_idx] ^ ctx->enc_cb[i]; + // Save the current ciphertext block depending on whether this is an encrypt or decrypt operation + ctx->ciphertext_block[i] = is_encrypt ? output[data_idx] : input[data_idx]; + ctx->data_size += 1; + } + + if (ctx->data_size % AES_DATA_SIZE == 0) + { + // Calculate running hash with completed block + if (ATCA_SUCCESS != (status = atcab_aes_ghash(ctx->h, ctx->ciphertext_block, AES_DATA_SIZE, ctx->y))) + { + RETURN(status, "GCM - S (data) failed"); + } + } + } + + return ATCA_SUCCESS; +} + +/** \brief Encrypt data using GCM mode and a key within the ATECC608A device. + * atcab_aes_gcm_init() or atcab_aes_gcm_init_rand() should be called + * before the first use of this function. + * + * \param[in] ctx AES GCM context structure. + * \param[in] plaintext Plaintext to be encrypted (16 bytes). + * \param[in] plaintext_size Size of plaintext in bytes. + * \param[out] ciphertext Encrypted data is returned here. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_gcm_encrypt_update(atca_aes_gcm_ctx_t* ctx, const uint8_t* plaintext, uint32_t plaintext_size, uint8_t* ciphertext) +{ + return atcab_aes_gcm_update(ctx, plaintext, plaintext_size, ciphertext, true); +} + +/** \brief Complete GCM operation to generate the authentication tag. + * + * It calculates output block (S) by including AAD size and data size, then + * calculates the tag. This should be called last in a encrypt/decrypt + * operation. + * + * \param[in] ctx AES GCM context structure. + * \param[out] tag Authentication tag is returned here. + * \param[in] tag_size Required size for the tag. Must be 12 to 16 bytes. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS atcab_aes_gcm_calc_auth_tag(atca_aes_gcm_ctx_t* ctx, uint8_t* tag, size_t tag_size) +{ + ATCA_STATUS status; + size_t xor_index; + uint8_t temp_data[AES_DATA_SIZE]; + uint64_t length; + + if (ctx == NULL || tag == NULL) + { + RETURN(ATCA_BAD_PARAM, "Null pointer"); + } + // 800-38D 5.2.1.2 specifies these tags sizes + if (tag_size < 12 || tag_size > 16) + { + RETURN(ATCA_BAD_PARAM, "Invalid tag size"); + } + + memset(temp_data, 0, AES_DATA_SIZE); + length = ATCA_UINT64_HOST_TO_BE(((uint64_t)ctx->aad_size) * 8); + memcpy(&temp_data[0], &length, sizeof(length)); + length = ATCA_UINT64_HOST_TO_BE(((uint64_t)ctx->data_size) * 8); + memcpy(&temp_data[8], &length, sizeof(length)); + + //S = GHASH(H, [len(A)]64 || [len(C)]64)) + if (ATCA_SUCCESS != (status = atcab_aes_ghash(ctx->h, temp_data, AES_DATA_SIZE, ctx->y))) + { + RETURN(status, "GCM - S (lengths) failed"); + } + + //T = GCTR(J0, S) + if (ATCA_SUCCESS != (status = atcab_aes_encrypt(ctx->key_id, ctx->key_block, ctx->j0, temp_data))) + { + RETURN(status, "Tag GCTR Encryption failed"); + } + + for (xor_index = 0; xor_index < tag_size; xor_index++) + { + tag[xor_index] = temp_data[xor_index] ^ ctx->y[xor_index]; + } + + return ATCA_SUCCESS; +} + +/** \brief Complete a GCM encrypt operation returning the authentication tag. + * + * \param[in] ctx AES GCM context structure. + * \param[out] tag Authentication tag is returned here. + * \param[in] tag_size Tag size in bytes (12 to 16 bytes). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_gcm_encrypt_finish(atca_aes_gcm_ctx_t* ctx, uint8_t* tag, size_t tag_size) +{ + ATCA_STATUS status; + + if (ctx == NULL) + { + RETURN(ATCA_BAD_PARAM, "Null pointer"); + } + + if (ctx->partial_aad_size > 0) + { + // Incomplete AAD with no encrypted data, need to complete AAD hash + if (ATCA_SUCCESS != (status = atcab_aes_gcm_update(ctx, NULL, 0, NULL, true))) + { + RETURN(status, "GCM - S (AAD) failed"); + } + } + + // Update hash with any partial block of ciphertext + //S = GHASH(H, C || 0^u) + if (ATCA_SUCCESS != (status = atcab_aes_ghash(ctx->h, ctx->ciphertext_block, ctx->data_size % AES_DATA_SIZE, ctx->y))) + { + RETURN(status, "GCM - S (C - encrypt update) failed"); + } + + if (ATCA_SUCCESS != (status = atcab_aes_gcm_calc_auth_tag(ctx, tag, tag_size))) + { + RETURN(status, "GCM encrypt tag calculation failed"); + } + + return ATCA_SUCCESS; +} + +/** \brief Decrypt data using GCM mode and a key within the ATECC608A device. + * atcab_aes_gcm_init() or atcab_aes_gcm_init_rand() should be called + * before the first use of this function. + * + * \param[in] ctx AES GCM context structure. + * \param[in] ciphertext Ciphertext to be decrypted. + * \param[in] ciphertext_size Size of ciphertext in bytes. + * \param[out] plaintext Decrypted data is returned here. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_gcm_decrypt_update(atca_aes_gcm_ctx_t* ctx, const uint8_t* ciphertext, uint32_t ciphertext_size, uint8_t* plaintext) +{ + return atcab_aes_gcm_update(ctx, ciphertext, ciphertext_size, plaintext, false); +} + +/** \brief Complete a GCM decrypt operation verifying the authentication tag. + * + * \param[in] ctx AES GCM context structure. + * \param[in] tag Expected authentication tag. + * \param[in] tag_size Size of tag in bytes (12 to 16 bytes). + * \param[out] is_verified Returns whether or not the tag verified. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_aes_gcm_decrypt_finish(atca_aes_gcm_ctx_t* ctx, const uint8_t* tag, size_t tag_size, bool* is_verified) +{ + ATCA_STATUS status; + uint8_t calc_tag[AES_DATA_SIZE]; + + if (ctx == NULL || is_verified == NULL) + { + RETURN(ATCA_BAD_PARAM, "Null pointer"); + } + *is_verified = false; + + if (ctx->partial_aad_size > 0) + { + // Incomplete AAD with no decrypted data, need to complete AAD hash + if (ATCA_SUCCESS != (status = atcab_aes_gcm_update(ctx, NULL, 0, NULL, false))) + { + RETURN(status, "GCM - S (AAD) failed"); + } + } + + // Update hash with any partial block of ciphertext + //S = GHASH(H, C || 0^u) + if (ATCA_SUCCESS != (status = atcab_aes_ghash(ctx->h, ctx->ciphertext_block, ctx->data_size % AES_DATA_SIZE, ctx->y))) + { + RETURN(status, "GCM - S (C - encrypt update) failed"); + } + + if (ATCA_SUCCESS != (status = atcab_aes_gcm_calc_auth_tag(ctx, calc_tag, tag_size))) + { + RETURN(status, "Tag calculation failed"); + } + + *is_verified = (memcmp(calc_tag, tag, tag_size) == 0); + + return ATCA_SUCCESS; +} + +/** @} */ diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_aes_gcm.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_aes_gcm.h new file mode 100644 index 0000000..fce3b09 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_aes_gcm.h @@ -0,0 +1,67 @@ +/** + * \file + * \brief Unity tests for the cryptoauthlib AES GCM functions. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ +#ifndef ATCA_BASIC_AES_GCM_H_ +#define ATCA_BASIC_AES_GCM_H_ + +#include "cryptoauthlib.h" + +/** \ingroup atcab_ + * @{ + */ + +extern const char* atca_basic_aes_gcm_version; + +/** Context structure for AES GCM operations. + */ +typedef struct atca_aes_gcm_ctx +{ + uint16_t key_id; //!< Key location. Can either be a slot number or ATCA_TEMPKEY_KEYID for TempKey. + uint8_t key_block; //!< Index of the 16-byte block to use within the key location for the actual key. + uint8_t cb[AES_DATA_SIZE]; //!< Counter block, comprises of nonce + count value (16 bytes). + uint32_t data_size; //!< Size of the data being encrypted/decrypted in bytes. + uint32_t aad_size; //!< Size of the additional authenticated data in bytes. + uint8_t h[AES_DATA_SIZE]; //!< Subkey for ghash functions in GCM. + uint8_t j0[AES_DATA_SIZE]; //!< Precounter block generated from IV. + uint8_t y[AES_DATA_SIZE]; //!< Current GHASH output + uint8_t partial_aad[AES_DATA_SIZE]; //!< Partial blocks of data waiting to be processed + uint32_t partial_aad_size; //!< Amount of data in the partial block buffer + uint8_t enc_cb[AES_DATA_SIZE]; //!< Last encrypted counter block + uint8_t ciphertext_block[AES_DATA_SIZE]; //!< Last ciphertext block +} atca_aes_gcm_ctx_t; + +ATCA_STATUS atcab_aes_gcm_init(atca_aes_gcm_ctx_t* ctx, uint16_t key_id, uint8_t key_block, const uint8_t* iv, size_t iv_size); +ATCA_STATUS atcab_aes_gcm_init_rand(atca_aes_gcm_ctx_t* ctx, uint16_t key_id, uint8_t key_block, size_t rand_size, + const uint8_t* free_field, size_t free_field_size, uint8_t* iv); +ATCA_STATUS atcab_aes_gcm_aad_update(atca_aes_gcm_ctx_t* ctx, const uint8_t* aad, uint32_t aad_size); +ATCA_STATUS atcab_aes_gcm_encrypt_update(atca_aes_gcm_ctx_t* ctx, const uint8_t* plaintext, uint32_t plaintext_size, uint8_t* ciphertext); +ATCA_STATUS atcab_aes_gcm_encrypt_finish(atca_aes_gcm_ctx_t* ctx, uint8_t* tag, size_t tag_size); +ATCA_STATUS atcab_aes_gcm_decrypt_update(atca_aes_gcm_ctx_t* ctx, const uint8_t* ciphertext, uint32_t ciphertext_size, uint8_t* plaintext); +ATCA_STATUS atcab_aes_gcm_decrypt_finish(atca_aes_gcm_ctx_t* ctx, const uint8_t* tag, size_t tag_size, bool* is_verified); + +/** @} */ + +#endif \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.c new file mode 100644 index 0000000..0e70ba6 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.c @@ -0,0 +1,94 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for CheckMAC command. + * + * The CheckMac command calculates a MAC response that would have been + * generated on a different CryptoAuthentication device and then compares the + * result with input value. + * + * \note List of devices that support this command - ATSHA204A, ATECC108A, + * ATECC508A, and ATECC608A. There are differences in the modes that they + * support. Refer to device datasheets for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_basic.h" +#include "atca_execution.h" + +/** \brief Compares a MAC response with input values + * \param[in] mode Controls which fields within the device are used in + * the message + * \param[in] key_id Key location in the CryptoAuth device to use for the + * MAC + * \param[in] challenge Challenge data (32 bytes) + * \param[in] response MAC response data (32 bytes) + * \param[in] other_data OtherData parameter (13 bytes) + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_checkmac(uint8_t mode, uint16_t key_id, const uint8_t *challenge, const uint8_t *response, const uint8_t *other_data) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + + // Verify the inputs + if (response == NULL || other_data == NULL) + { + return ATCA_BAD_PARAM; + } + if (!(mode & CHECKMAC_MODE_BLOCK2_TEMPKEY) && challenge == NULL) + { + return ATCA_BAD_PARAM; + } + + do + { + // build Check MAC command + packet.param1 = mode; + packet.param2 = key_id; + if (challenge != NULL) + { + memcpy(&packet.data[0], challenge, CHECKMAC_CLIENT_CHALLENGE_SIZE); + } + else + { + memset(&packet.data[0], 0, CHECKMAC_CLIENT_CHALLENGE_SIZE); + } + memcpy(&packet.data[32], response, CHECKMAC_CLIENT_RESPONSE_SIZE); + memcpy(&packet.data[64], other_data, CHECKMAC_OTHER_DATA_SIZE); + + if ((status = atCheckMAC(ca_cmd, &packet)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command( (void*)&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + } + while (0); + + return status; +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.c new file mode 100644 index 0000000..76bd8a2 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.c @@ -0,0 +1,104 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for Counter command. + * + * The Counter command reads or increments the binary count value for one of the + * two monotonic counters + * + * \note List of devices that support this command - ATECC508A and ATECC608A. + * There are differences in the modes that they support. Refer to device + * datasheets for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ +#include "atca_basic.h" +#include "atca_execution.h" + + +/** \brief Compute the Counter functions + * \param[in] mode the mode used for the counter + * \param[in] counter_id The counter to be used + * \param[out] counter_value pointer to the counter value returned from device + * \return ATCA_SUCCESS on success, otherwise an error code. + */ + +ATCA_STATUS atcab_counter(uint8_t mode, uint16_t counter_id, uint32_t *counter_value) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + + do + { + if (counter_id > 1) + { + return ATCA_BAD_PARAM; + } + + // build a Counter command + packet.param1 = mode; + packet.param2 = counter_id; + + if ((status = atCounter(ca_cmd, &packet)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + if (counter_value != NULL && packet.data[ATCA_COUNT_IDX] >= 7) + { + *counter_value = ((uint32_t)packet.data[ATCA_RSP_DATA_IDX + 0] << 0) | + ((uint32_t)packet.data[ATCA_RSP_DATA_IDX + 1] << 8) | + ((uint32_t)packet.data[ATCA_RSP_DATA_IDX + 2] << 16) | + ((uint32_t)packet.data[ATCA_RSP_DATA_IDX + 3] << 24); + } + } + while (0); + + return status; +} + +/** \brief Increments one of the device's monotonic counters + * \param[in] counter_id Counter to be incremented + * \param[out] counter_value New value of the counter is returned here. Can be + * NULL if not needed. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_counter_increment(uint16_t counter_id, uint32_t* counter_value) +{ + return atcab_counter(COUNTER_MODE_INCREMENT, counter_id, counter_value); +} + +/** \brief Read one of the device's monotonic counters + * \param[in] counter_id Counter to be read + * \param[out] counter_value Counter value is returned here. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_counter_read(uint16_t counter_id, uint32_t* counter_value) +{ + return atcab_counter(COUNTER_MODE_READ, counter_id, counter_value); +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.c new file mode 100644 index 0000000..af1ac69 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.c @@ -0,0 +1,79 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for DeriveKey command. + * + * The DeriveKey command combines the current value of a key with the nonce + * stored in TempKey using SHA-256 and derives a new key. + * + * \note List of devices that support this command - ATSHA204A, ATECC108A, + * ATECC508A, and ATECC608A. There are differences in the modes that they + * support. Refer to device datasheets for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_basic.h" +#include "atca_execution.h" + +/** \brief Executes the DeviveKey command for deriving a new key from a + * nonce (TempKey) and an existing key. + * + * \param[in] mode Bit 2 must match the value in TempKey.SourceFlag + * \param[in] target_key Key slot to be written + * \param[in] mac Optional 32 byte MAC used to validate operation. NULL + * if not required. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_derivekey(uint8_t mode, uint16_t target_key, const uint8_t* mac) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + + do + { + // build a deriveKey command (pass through mode) + packet.param1 = mode; + packet.param2 = target_key; + + if (mac != NULL) + { + memcpy(packet.data, mac, MAC_SIZE); + } + + if ((status = atDeriveKey(ca_cmd, &packet, mac != NULL)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + } + while (0); + + return status; +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.c new file mode 100644 index 0000000..4e204b4 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.c @@ -0,0 +1,258 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for ECDH command. + * + * The ECDH command implements the Elliptic Curve Diffie-Hellman algorithm to + * combine an internal private key with an external public key to calculate a + * shared secret. + * + * \note List of devices that support this command - ATECC508A, ATECC608A. + * There are differences in the modes that they support. Refer to device + * datasheets for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_basic.h" +#include "atca_execution.h" +#include "host/atca_host.h" + + +/** \brief Base function for generating premaster secret key using ECDH. + * \param[in] mode Mode to be used for ECDH computation + * \param[in] key_id Slot of key for ECDH computation + * \param[in] public_key Public key input to ECDH calculation. X and Y + * integers in big-endian format. 64 bytes for P256 + * key. + * \param[out] pms Computed ECDH pre-master secret is returned here (32 + * bytes) if returned directly. Otherwise NULL. + * \param[out] out_nonce Nonce used to encrypt pre-master secret. NULL if + * output encryption not used. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_ecdh_base(uint8_t mode, uint16_t key_id, const uint8_t* public_key, uint8_t* pms, uint8_t* out_nonce) +{ + ATCAPacket packet; + ATCA_STATUS status = ATCA_GEN_FAIL; + + do + { + // Build Command + packet.param1 = mode; + packet.param2 = key_id; + memcpy(packet.data, public_key, ATCA_PUB_KEY_SIZE); + + if ((status = atECDH(_gDevice->mCommands, &packet)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + if (pms != NULL && packet.data[ATCA_COUNT_IDX] >= (3 + ATCA_KEY_SIZE)) + { + memcpy(pms, &packet.data[ATCA_RSP_DATA_IDX], ATCA_KEY_SIZE); + } + + if (out_nonce != NULL && packet.data[ATCA_COUNT_IDX] >= (3 + ATCA_KEY_SIZE * 2)) + { + memcpy(out_nonce, &packet.data[ATCA_RSP_DATA_IDX + ATCA_KEY_SIZE], ATCA_KEY_SIZE); + } + + } + while (0); + + return status; +} + +/** \brief ECDH command with a private key in a slot and the premaster secret + * is returned in the clear. + * + * \param[in] key_id Slot of key for ECDH computation + * \param[in] public_key Public key input to ECDH calculation. X and Y + * integers in big-endian format. 64 bytes for P256 + * key. + * \param[out] pms Computed ECDH premaster secret is returned here. + * 32 bytes. + * + * \return ATCA_SUCCESS on success + */ +ATCA_STATUS atcab_ecdh(uint16_t key_id, const uint8_t* public_key, uint8_t* pms) +{ + ATCA_STATUS status; + + status = atcab_ecdh_base(ECDH_PREFIX_MODE, key_id, public_key, pms, NULL); + + return status; +} + +/** \brief ECDH command with a private key in a slot and the premaster secret + * is read from the next slot. + * + * This function only works for even numbered slots with the proper + * configuration. + * + * \param[in] key_id Slot of key for ECDH computation + * \param[in] public_key Public key input to ECDH calculation. X and Y + * integers in big-endian format. 64 bytes for P256 + * key. + * \param[out] pms Computed ECDH premaster secret is returned here + * (32 bytes). + * \param[in] read_key Read key for the premaster secret slot (key_id|1). + * \param[in] read_key_id Read key slot for read_key. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_ecdh_enc(uint16_t key_id, const uint8_t* public_key, uint8_t* pms, const uint8_t* read_key, uint16_t read_key_id) +{ + ATCA_STATUS status = ATCA_SUCCESS; + + do + { + // Check the inputs + if (public_key == NULL || pms == NULL || read_key == NULL) + { + status = ATCA_BAD_PARAM; + BREAK(status, "Bad input parameters"); + } + + // Send the ECDH command with the public key provided + if ((status = atcab_ecdh(key_id, public_key, NULL)) != ATCA_SUCCESS) + { + BREAK(status, "ECDH Failed"); + } + + if ((status = atcab_read_enc(key_id | 0x0001, 0, pms, read_key, read_key_id)) != ATCA_SUCCESS) + { + BREAK(status, "Encrypted read failed"); + } + } + while (0); + + return status; +} + +/** \brief ECDH command with a private key in a slot and the premaster secret + * is returned encrypted using the IO protection key. + * + * \param[in] key_id Slot of key for ECDH computation + * \param[in] public_key Public key input to ECDH calculation. X and Y + * integers in big-endian format. 64 bytes for P256 + * key. + * \param[out] pms Computed ECDH premaster secret is returned here + * (32 bytes). + * \param[in] io_key IO protection key. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_ecdh_ioenc(uint16_t key_id, const uint8_t* public_key, uint8_t* pms, const uint8_t* io_key) +{ + uint8_t mode = ECDH_MODE_SOURCE_EEPROM_SLOT | ECDH_MODE_OUTPUT_ENC | ECDH_MODE_COPY_OUTPUT_BUFFER; + uint8_t out_nonce[ATCA_KEY_SIZE]; + atca_io_decrypt_in_out_t io_dec_params; + ATCA_STATUS status = ATCA_GEN_FAIL; + + // Perform ECDH operation requesting output buffer encryption + status = atcab_ecdh_base(mode, key_id, public_key, pms, out_nonce); + if (status != ATCA_SUCCESS) + { + return status; + } + + // Decrypt PMS + memset(&io_dec_params, 0, sizeof(io_dec_params)); + io_dec_params.io_key = io_key; + io_dec_params.out_nonce = out_nonce; + io_dec_params.data = pms; + io_dec_params.data_size = 32; + status = atcah_io_decrypt(&io_dec_params); + if (status != ATCA_SUCCESS) + { + return status; + } + + return status; +} + +/** \brief ECDH command with a private key in TempKey and the premaster secret + * is returned in the clear. + * + * \param[in] public_key Public key input to ECDH calculation. X and Y + * integers in big-endian format. 64 bytes for P256 + * key. + * \param[out] pms Computed ECDH premaster secret is returned here + * (32 bytes). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_ecdh_tempkey(const uint8_t* public_key, uint8_t* pms) +{ + // Perform ECDH operation with TempKey + uint8_t mode = ECDH_MODE_SOURCE_TEMPKEY | ECDH_MODE_COPY_OUTPUT_BUFFER; + + return atcab_ecdh_base(mode, 0x0000, public_key, pms, NULL); +} + +/** \brief ECDH command with a private key in TempKey and the premaster secret + * is returned encrypted using the IO protection key. + * + * \param[in] public_key Public key input to ECDH calculation. X and Y + * integers in big-endian format. 64 bytes for P256 + * key. + * \param[out] pms Computed ECDH premaster secret is returned here + * (32 bytes). + * \param[in] io_key IO protection key. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_ecdh_tempkey_ioenc(const uint8_t* public_key, uint8_t* pms, const uint8_t* io_key) +{ + uint8_t mode = ECDH_MODE_SOURCE_TEMPKEY | ECDH_MODE_OUTPUT_ENC | ECDH_MODE_COPY_OUTPUT_BUFFER; + uint8_t out_nonce[ATCA_KEY_SIZE]; + atca_io_decrypt_in_out_t io_dec_params; + ATCA_STATUS status = ATCA_GEN_FAIL; + + // Perform ECDH operation requesting output buffer encryption + status = atcab_ecdh_base(mode, 0x0000, public_key, pms, out_nonce); + if (status != ATCA_SUCCESS) + { + return status; + } + + // Decrypt PMS + memset(&io_dec_params, 0, sizeof(io_dec_params)); + io_dec_params.io_key = io_key; + io_dec_params.out_nonce = out_nonce; + io_dec_params.data = pms; + io_dec_params.data_size = 32; + status = atcah_io_decrypt(&io_dec_params); + if (status != ATCA_SUCCESS) + { + return status; + } + + return status; +} + diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.c new file mode 100644 index 0000000..c8e73b4 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.c @@ -0,0 +1,91 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for GenDig command. + * + * The GenDig command uses SHA-256 to combine a stored value with the contents + * of TempKey, which must have been valid prior to the execution of this + * command. + * + * \note List of devices that support this command - ATSHA204A, ATECC108A, + * ATECC508A, and ATECC608A. There are differences in the modes that + * they support. Refer to device datasheets for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_basic.h" +#include "atca_execution.h" + +/** \brief Issues a GenDig command, which performs a SHA256 hash on the source data indicated by zone with the + * contents of TempKey. See the CryptoAuth datasheet for your chip to see what the values of zone + * correspond to. + * \param[in] zone Designates the source of the data to hash with TempKey. + * \param[in] key_id Indicates the key, OTP block, or message order for shared nonce mode. + * \param[in] other_data Four bytes of data for SHA calculation when using a NoMac key, 32 bytes for + * "Shared Nonce" mode, otherwise ignored (can be NULL). + * \param[in] other_data_size Size of other_data in bytes. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_gendig(uint8_t zone, uint16_t key_id, const uint8_t *other_data, uint8_t other_data_size) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + bool is_no_mac_key = false; + + if (other_data_size > 0 && other_data == NULL) + { + return ATCA_BAD_PARAM; + } + + do + { + // build gendig command + packet.param1 = zone; + packet.param2 = key_id; + + if (packet.param1 == GENDIG_ZONE_SHARED_NONCE && other_data_size >= ATCA_BLOCK_SIZE) + { + memcpy(&packet.data[0], &other_data[0], ATCA_BLOCK_SIZE); + } + else if (packet.param1 == GENDIG_ZONE_DATA && other_data_size >= ATCA_WORD_SIZE) + { + memcpy(&packet.data[0], &other_data[0], ATCA_WORD_SIZE); + is_no_mac_key = true; + } + + if ((status = atGenDig(ca_cmd, &packet, is_no_mac_key)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + } + while (0); + + return status; +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.c new file mode 100644 index 0000000..742883a --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.c @@ -0,0 +1,122 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for GenKey command. + * + * The GenKey command is used for creating ECC private keys, generating ECC + * public keys, and for digest calculations involving public keys. + * + * \note List of devices that support this command - ATECC108A, ATECC508A, + * ATECC608A. There are differences in the modes that they support. Refer + * to device datasheets for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_basic.h" +#include "atca_execution.h" + +/** \brief Issues GenKey command, which can generate a private key, compute a + * public key, nd/or compute a digest of a public key. + * + * \param[in] mode Mode determines what operations the GenKey + * command performs. + * \param[in] key_id Slot to perform the GenKey command on. + * \param[in] other_data OtherData for PubKey digest calculation. Can be set + * to NULL otherwise. + * \param[out] public_key If the mode indicates a public key will be + * calculated, it will be returned here. Format will + * be the X and Y integers in big-endian format. + * 64 bytes for P256 curve. Set to NULL if public key + * isn't required. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_genkey_base(uint8_t mode, uint16_t key_id, const uint8_t* other_data, uint8_t* public_key) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + + do + { + // Build GenKey command + packet.param1 = mode; + packet.param2 = key_id; + if (other_data) + { + memcpy(packet.data, other_data, GENKEY_OTHER_DATA_SIZE); + } + + if ((status = atGenKey(ca_cmd, &packet)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + if (public_key && packet.data[ATCA_COUNT_IDX] > 4) + { + memcpy(public_key, &packet.data[ATCA_RSP_DATA_IDX], packet.data[ATCA_COUNT_IDX] - 3); + } + } + while (0); + + return status; +} + +/** \brief Issues GenKey command, which generates a new random private key in + * slot and returns the public key. + * + * \param[in] key_id Slot number where an ECC private key is configured. + * Can also be ATCA_TEMPKEY_KEYID to generate a private + * key in TempKey. + * \param[out] public_key Public key will be returned here. Format will be + * the X and Y integers in big-endian format. + * 64 bytes for P256 curve. Set to NULL if public key + * isn't required. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_genkey(uint16_t key_id, uint8_t *public_key) +{ + return atcab_genkey_base(GENKEY_MODE_PRIVATE, key_id, NULL, public_key); +} + +/** \brief Uses GenKey command to calculate the public key from an existing + * private key in a slot. + * + * \param[in] key_id Slot number of the private key. + * \param[out] public_key Public key will be returned here. Format will be + * the X and Y integers in big-endian format. + * 64 bytes for P256 curve. Set to NULL if public key + * isn't required. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_get_pubkey(uint16_t key_id, uint8_t *public_key) +{ + return atcab_genkey_base(GENKEY_MODE_PUBLIC, key_id, NULL, public_key); +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.c new file mode 100644 index 0000000..c40b68f --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.c @@ -0,0 +1,92 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for HMAC command. + * + * The HMAC command computes an HMAC/SHA-256 digest using a key stored in the + * device over a challenge stored in the TempKey register, and/or other + * information stored within the device. + * + * \note List of devices that support this command - ATSHA204A, ATECC108A, and + * ATECC508A . There are differences in the modes that they support. + * Refer to device datasheets for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +#include "atca_basic.h" +#include "atca_execution.h" + +/** \brief Issues a HMAC command, which computes an HMAC/SHA-256 digest of a + * key stored in the device, a challenge, and other information on the + * device. + * + * \param[in] mode Controls which fields within the device are used in the + * message. + * \param[in] key_id Which key is to be used to generate the response. + * Bits 0:3 only are used to select a slot but all 16 bits + * are used in the HMAC message. + * \param[out] digest HMAC digest is returned in this buffer (32 bytes). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_hmac(uint8_t mode, uint16_t key_id, uint8_t* digest) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + + do + { + if (digest == NULL) + { + status = ATCA_BAD_PARAM; + break; + } + // build HMAC command + packet.param1 = mode; + packet.param2 = key_id; + + if ((status = atHMAC(ca_cmd, &packet)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + if (packet.data[ATCA_COUNT_IDX] != HMAC_DIGEST_SIZE + 3) + { + status = ATCA_RX_FAIL; // Unexpected response size + break; + } + + memcpy(digest, &packet.data[ATCA_RSP_DATA_IDX], HMAC_DIGEST_SIZE); + + } + while (0); + + return status; +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.c new file mode 100644 index 0000000..85e8832 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.c @@ -0,0 +1,139 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for Info command. + * + * Info command returns a variety of static and dynamic information about the + * device and its state. Also is used to control the GPIO pin and the persistent + * latch. + * + * \note The ATSHA204A refers to this command as DevRev instead of Info, + * however, the OpCode and operation is the same. + * + * \note List of devices that support this command - ATSHA204A, ATECC108A, + * ATECC508A & ATECC608A. There are differences in the modes that they + * support. Refer to device datasheets for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ +#include "atca_basic.h" +#include "atca_execution.h" + +/** \brief Issues an Info command, which return internal device information and + * can control GPIO and the persistent latch. + * + * \param[in] mode Selects which mode to be used for info command. + * \param[in] param2 Selects the particular fields for the mode. + * \param[out] out_data Response from info command (4 bytes). Can be set to + * NULL if not required. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_info_base(uint8_t mode, uint16_t param2, uint8_t* out_data) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + + // build an info command + packet.param1 = mode; + packet.param2 = param2; + + do + { + + if ((status = atInfo(ca_cmd, &packet)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + if (out_data != NULL && packet.data[ATCA_COUNT_IDX] >= 7) + { + memcpy(out_data, &packet.data[ATCA_RSP_DATA_IDX], 4); + } + } + while (0); + + return status; +} + +/** \brief Use the Info command to get the device revision (DevRev). + * \param[out] revision Device revision is returned here (4 bytes). + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_info(uint8_t* revision) +{ + if (revision == NULL) + { + return ATCA_BAD_PARAM; + } + + return atcab_info_base(INFO_MODE_REVISION, 0, revision); +} + +/** \brief Use the Info command to get the persistent latch current state for + * an ATECC608A device. + * + * \param[out] state The state is returned here. Set (true) or Cler (false). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ + +ATCA_STATUS atcab_info_get_latch(bool* state) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t out_data[4]; + + if (state == NULL) + { + return ATCA_BAD_PARAM; + } + + status = atcab_info_base(INFO_MODE_VOL_KEY_PERMIT, 0, out_data); + if (status != ATCA_SUCCESS) + { + return status; + } + + *state = (out_data[0] == 1); + + return status; +} + +/** \brief Use the Info command to set the persistent latch state for an + * ATECC608A device. + * + * \param[out] state Persistent latch state. Set (true) or clear (false). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_info_set_latch(bool state) +{ + uint16_t param2 = INFO_PARAM2_SET_LATCH_STATE; + + param2 |= state ? INFO_PARAM2_LATCH_SET : INFO_PARAM2_LATCH_CLEAR; + return atcab_info_base(INFO_MODE_VOL_KEY_PERMIT, param2, NULL); +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.c new file mode 100644 index 0000000..5eaa8f5 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.c @@ -0,0 +1,136 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for KDF command. + * + * The KDF command implements one of a number of Key Derivation Functions (KDF). + * Generally this function combines a source key with an input string and + * creates a result key/digest/array. Three algorithms are currently supported: + * PRF, HKDF and AES. + * + * \note List of devices that support this command - ATECC608A. Refer to device + * datasheet for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_basic.h" +#include "atca_execution.h" + +/** \brief Executes the KDF command, which derives a new key in PRF, AES, or + * HKDF modes. + * + * Generally this function combines a source key with an input string and + * creates a result key/digest/array. + * + * \param[in] mode Mode determines KDF algorithm (PRF,AES,HKDF), source + * key location, and target key locations. + * \param[in] key_id Source and target key slots if locations are in the + * EEPROM. Source key slot is the LSB and target key + * slot is the MSB. + * \param[in] details Further information about the computation, depending + * on the algorithm (4 bytes). + * \param[in] message Input value from system (up to 128 bytes). Actual size + * of message is 16 bytes for AES algorithm or is encoded + * in the MSB of the details parameter for other + * algorithms. + * \param[out] out_data Output of the KDF function is returned here. If the + * result remains in the device, this can be NULL. + * \param[out] out_nonce If the output is encrypted, a 32 byte random nonce + * generated by the device is returned here. If output + * encryption is not used, this can be NULL. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_kdf(uint8_t mode, uint16_t key_id, const uint32_t details, const uint8_t* message, uint8_t* out_data, uint8_t* out_nonce) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + uint16_t out_data_size = 0; + + do + { + if (message == NULL) + { + return ATCA_BAD_PARAM; + } + + // Build the KDF command + packet.param1 = mode; + packet.param2 = key_id; + + // Add details parameter + packet.data[0] = details; + packet.data[1] = details >> 8; + packet.data[2] = details >> 16; + packet.data[3] = details >> 24; + + // Add input message + if ((mode & KDF_MODE_ALG_MASK) == KDF_MODE_ALG_AES) + { + // AES algorithm has a fixed message size + memcpy(&packet.data[KDF_DETAILS_SIZE], message, AES_DATA_SIZE); + } + else + { + // All other algorithms encode message size in the last byte of details + memcpy(&packet.data[KDF_DETAILS_SIZE], message, packet.data[3]); + } + + // Build command + if ((status = atKDF(ca_cmd, &packet)) != ATCA_SUCCESS) + { + break; + } + + // Run command + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + if (((mode & KDF_MODE_ALG_MASK) == KDF_MODE_ALG_PRF) && (details & KDF_DETAILS_PRF_TARGET_LEN_64)) + { + out_data_size = 64; + } + else + { + out_data_size = 32; + } + + // Return OutData if possible + if (out_data != NULL && packet.data[ATCA_COUNT_IDX] >= (ATCA_PACKET_OVERHEAD + out_data_size)) + { + memcpy(out_data, &packet.data[ATCA_RSP_DATA_IDX], out_data_size); + } + + // return OutNonce if possible + if (out_nonce != NULL && packet.data[ATCA_COUNT_IDX] >= (ATCA_PACKET_OVERHEAD + out_data_size + 32)) + { + memcpy(out_nonce, &packet.data[ATCA_RSP_DATA_IDX + out_data_size], 32); + } + } + while (false); + + return status; +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.c new file mode 100644 index 0000000..e5b4b0f --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.c @@ -0,0 +1,140 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for Lock command. + * + * The Lock command prevents future modifications of the Configuration zone, + * enables configured policies for Data and OTP zones, and can render + * individual slots read-only regardless of configuration. + * + * \note List of devices that support this command - ATSHA204A, ATECC108A, + * ATECC508A, ATECC608A. There are differences in the modes that they + * support. Refer to device datasheets for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_basic.h" +#include "atca_execution.h" + +/** \brief The Lock command prevents future modifications of the Configuration + * and/or Data and OTP zones. If the device is so configured, then + * this command can be used to lock individual data slots. This + * command fails if the designated area is already locked. + * + * \param[in] mode Zone, and/or slot, and summary check (bit 7). + * \param[in] summary_crc CRC of the config or data zones. Ignored for + * slot locks or when mode bit 7 is set. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_lock(uint8_t mode, uint16_t summary_crc) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + + // build command for lock zone and send + memset(&packet, 0, sizeof(packet)); + packet.param1 = mode; + packet.param2 = summary_crc; + + do + { + if ((status = atLock(ca_cmd, &packet)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + } + while (0); + + return status; +} + +/** \brief Unconditionally (no CRC required) lock the config zone. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_lock_config_zone(void) +{ + return atcab_lock(LOCK_ZONE_NO_CRC | LOCK_ZONE_CONFIG, 0); +} + +/** \brief Lock the config zone with summary CRC. + * + * The CRC is calculated over the entire config zone contents. 88 bytes for + * ATSHA devices, 128 bytes for ATECC devices. Lock will fail if the provided + * CRC doesn't match the internally calculated one. + * + * \param[in] summary_crc Expected CRC over the config zone. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_lock_config_zone_crc(uint16_t summary_crc) +{ + return atcab_lock(LOCK_ZONE_CONFIG, summary_crc); +} + +/** \brief Unconditionally (no CRC required) lock the data zone (slots and OTP). + * + * ConfigZone must be locked and DataZone must be unlocked for the zone to be successfully locked. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_lock_data_zone(void) +{ + return atcab_lock(LOCK_ZONE_NO_CRC | LOCK_ZONE_DATA, 0); +} + +/** \brief Lock the data zone (slots and OTP) with summary CRC. + * + * The CRC is calculated over the concatenated contents of all the slots and + * OTP at the end. Private keys (KeyConfig.Private=1) are skipped. Lock will + * fail if the provided CRC doesn't match the internally calculated one. + * + * \param[in] summary_crc Expected CRC over the data zone. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_lock_data_zone_crc(uint16_t summary_crc) +{ + return atcab_lock(LOCK_ZONE_DATA, summary_crc); +} + +/** \brief Lock an individual slot in the data zone on an ATECC device. Not + * available for ATSHA devices. Slot must be configured to be slot + * lockable (KeyConfig.Lockable=1). + * + * \param[in] slot Slot to be locked in data zone. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_lock_data_slot(uint16_t slot) +{ + return atcab_lock(((uint8_t)slot << 2) | LOCK_ZONE_DATA_SLOT, 0); +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.c new file mode 100644 index 0000000..1b59602 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.c @@ -0,0 +1,93 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for MAC command. + * + * The MAC command computes a SHA-256 digest of a key stored in the device, a + * challenge, and other information on the device. The output of this command + * is the digest of this message. + * + * \note List of devices that support this command - ATSHA204A, ATECC108A, + * ATECC508A, and ATECC608A. There are differences in the modes that they + * support. Refer to device datasheets for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_basic.h" +#include "atca_execution.h" + +/** \brief Executes MAC command, which computes a SHA-256 digest of a key + * stored in the device, a challenge, and other information on the + * device. + * + * \param[in] mode Controls which fields within the device are used in + * the message + * \param[in] key_id Key in the CryptoAuth device to use for the MAC + * \param[in] challenge Challenge message (32 bytes). May be NULL if mode + * indicates a challenge isn't required. + * \param[out] digest MAC response is returned here (32 bytes). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_mac(uint8_t mode, uint16_t key_id, const uint8_t* challenge, uint8_t* digest) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + + do + { + if (digest == NULL) + { + return ATCA_BAD_PARAM; + } + + // build mac command + packet.param1 = mode; + packet.param2 = key_id; + if (!(mode & MAC_MODE_BLOCK2_TEMPKEY)) + { + if (challenge == NULL) + { + return ATCA_BAD_PARAM; + } + memcpy(&packet.data[0], challenge, 32); // a 32-byte challenge + } + + if ((status = atMAC(ca_cmd, &packet)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + memcpy(digest, &packet.data[ATCA_RSP_DATA_IDX], MAC_SIZE); + + } + while (0); + + return status; +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.c new file mode 100644 index 0000000..f6d0b73 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.c @@ -0,0 +1,205 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for Nonce command. + * + * The Nonce command generates a nonce for use by a subsequent commands of the + * device by combining an internally generated random number with an input value + * from the system. + * + * \note List of devices that support this command - ATSHA204A, ATECC108A, + * ATECC508A, and ATECC608A. There are differences in the modes that they + * support. Refer to device datasheets for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_basic.h" +#include "atca_execution.h" + +/** \brief Executes Nonce command, which loads a random or fixed nonce/data + * into the device for use by subsequent commands. + * + * \param[in] mode Controls the mechanism of the internal RNG or fixed + * write. + * \param[in] zero Param2, normally 0, but can be used to indicate a + * nonce calculation mode (bit 15). + * \param[in] num_in Input value to either be included in the nonce + * calculation in random modes (20 bytes) or to be + * written directly (32 bytes or 64 bytes(ATECC608A)) + * in pass-through mode. + * \param[out] rand_out If using a random mode, the internally generated + * 32-byte random number that was used in the nonce + * calculation is returned here. Can be NULL if not + * needed. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_nonce_base(uint8_t mode, uint16_t zero, const uint8_t *num_in, uint8_t* rand_out) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t nonce_mode = mode & NONCE_MODE_MASK; + + do + { + // build a nonce command + packet.param1 = mode; + packet.param2 = zero; + + // Copy the right amount of NumIn data + if ((nonce_mode == NONCE_MODE_SEED_UPDATE || nonce_mode == NONCE_MODE_NO_SEED_UPDATE)) + { + memcpy(packet.data, num_in, NONCE_NUMIN_SIZE); + } + else if (nonce_mode == NONCE_MODE_PASSTHROUGH) + { + if ((mode & NONCE_MODE_INPUT_LEN_MASK) == NONCE_MODE_INPUT_LEN_64) + { + memcpy(packet.data, num_in, 64); + } + else + { + memcpy(packet.data, num_in, 32); + } + } + else + { + return ATCA_BAD_PARAM; + } + + if ((status = atNonce(ca_cmd, &packet)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + if ((rand_out != NULL) && (packet.data[ATCA_COUNT_IDX] >= 35)) + { + memcpy(&rand_out[0], &packet.data[ATCA_RSP_DATA_IDX], 32); + } + + } + while (0); + + return status; +} + + +/** \brief Execute a Nonce command in pass-through mode to initialize TempKey + * to a specified value. + * + * \param[in] num_in Data to be loaded into TempKey (32 bytes). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_nonce(const uint8_t *num_in) +{ + return atcab_nonce_base(NONCE_MODE_PASSTHROUGH, 0, num_in, NULL); +} + + +/** \brief Execute a Nonce command in pass-through mode to load one of the + * device's internal buffers with a fixed value. + * + * For the ATECC608A, available targets are TempKey (32 or 64 bytes), Message + * Digest Buffer (32 or 64 bytes), or the Alternate Key Buffer (32 bytes). For + * all other devices, only TempKey (32 bytes) is available. + * + * \param[in] target Target device buffer to load. Can be + * NONCE_MODE_TARGET_TEMPKEY, + * NONCE_MODE_TARGET_MSGDIGBUF, or + * NONCE_MODE_TARGET_ALTKEYBUF. + * \param[in] num_in Data to load into the buffer. + * \param[in] num_in_size Size of num_in in bytes. Can be 32 or 64 bytes + * depending on device and target. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_nonce_load(uint8_t target, const uint8_t *num_in, uint16_t num_in_size) +{ + uint8_t mode = NONCE_MODE_PASSTHROUGH | (NONCE_MODE_TARGET_MASK & target); + + if (num_in_size == 32) + { + mode |= NONCE_MODE_INPUT_LEN_32; + } + else if (num_in_size == 64) + { + mode |= NONCE_MODE_INPUT_LEN_64; + } + else + { + return ATCA_BAD_PARAM; + } + + return atcab_nonce_base(mode, 0, num_in, NULL); +} + +/** \brief Execute a Nonce command to generate a random nonce combining a host + * nonce (num_in) and a device random number. + * + * \param[in] num_in Host nonce to be combined with the device random + * number (20 bytes). + * \param[out] rand_out Internally generated 32-byte random number that was + * used in the nonce/challenge calculation is returned + * here. Can be NULL if not needed. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_nonce_rand(const uint8_t *num_in, uint8_t* rand_out) +{ + return atcab_nonce_base(NONCE_MODE_SEED_UPDATE, 0, num_in, rand_out); +} + +/** \brief Execute a Nonce command in pass-through mode to initialize TempKey + * to a specified value. + * + * \param[in] num_in Data to be loaded into TempKey (32 bytes). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_challenge(const uint8_t *num_in) +{ + return atcab_nonce_base(NONCE_MODE_PASSTHROUGH, 0, num_in, NULL); +} + +/** \brief Execute a Nonce command to generate a random challenge combining + * a host nonce (num_in) and a device random number. + * + * \param[in] num_in Host nonce to be combined with the device random + * number (20 bytes). + * \param[out] rand_out Internally generated 32-byte random number that was + * used in the nonce/challenge calculation is returned + * here. Can be NULL if not needed. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_challenge_seed_update(const uint8_t *num_in, uint8_t* rand_out) +{ + return atcab_nonce_base(NONCE_MODE_SEED_UPDATE, 0, num_in, rand_out); +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.c new file mode 100644 index 0000000..c2833ee --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.c @@ -0,0 +1,177 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for PrivWrite command. + * + * The PrivWrite command is used to write externally generated ECC private keys + * into the device. + * + * \note List of devices that support this command - ATECC108A, ATECC508A, and + * ATECC608A. There are differences in the modes that they support. Refer + * to device datasheets for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ +#include "atca_basic.h" +#include "atca_execution.h" +#include "host/atca_host.h" + +/** \brief Executes PrivWrite command, to write externally generated ECC + * private keys into the device. + * + * \param[in] key_id Slot to write the external private key into. + * \param[in] priv_key External private key (36 bytes) to be written. + * The first 4 bytes should be zero for P256 curve. + * \param[in] write_key_id Write key slot. Ignored if write_key is NULL. + * \param[in] write_key Write key (32 bytes). If NULL, perform an + * unencrypted PrivWrite, which is only available when + * the data zone is unlocked. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_priv_write(uint16_t key_id, const uint8_t priv_key[36], uint16_t write_key_id, const uint8_t write_key[32]) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + atca_nonce_in_out_t nonce_params; + atca_gen_dig_in_out_t gen_dig_param; + atca_write_mac_in_out_t host_mac_param; + atca_temp_key_t temp_key; + uint8_t serial_num[32]; // Buffer is larger than the 9 bytes required to make reads easier + uint8_t num_in[NONCE_NUMIN_SIZE] = { 0 }; + uint8_t rand_out[RANDOM_NUM_SIZE] = { 0 }; + uint8_t cipher_text[36] = { 0 }; + uint8_t host_mac[MAC_SIZE] = { 0 }; + uint8_t other_data[4] = { 0 }; + + if (key_id > 15 || priv_key == NULL) + { + return ATCA_BAD_PARAM; + } + + do + { + + if (write_key == NULL) + { + // Caller requested an unencrypted PrivWrite, which is only allowed when the data zone is unlocked + // build an PrivWrite command + packet.param1 = 0x00; // Mode is unencrypted write + packet.param2 = key_id; // Key ID + memcpy(&packet.data[0], priv_key, 36); // Private key + memset(&packet.data[36], 0, 32); // MAC (ignored for unencrypted write) + } + else + { + // Read the device SN + if ((status = atcab_read_zone(ATCA_ZONE_CONFIG, 0, 0, 0, serial_num, 32)) != ATCA_SUCCESS) + { + break; + } + // Make the SN continuous by moving SN[4:8] right after SN[0:3] + memmove(&serial_num[4], &serial_num[8], 5); + + // Send the random Nonce command + if ((status = atcab_nonce_rand(num_in, rand_out)) != ATCA_SUCCESS) + { + break; + } + + // Calculate Tempkey + memset(&temp_key, 0, sizeof(temp_key)); + memset(&nonce_params, 0, sizeof(nonce_params)); + nonce_params.mode = NONCE_MODE_SEED_UPDATE; + nonce_params.zero = 0; + nonce_params.num_in = num_in; + nonce_params.rand_out = rand_out; + nonce_params.temp_key = &temp_key; + if ((status = atcah_nonce(&nonce_params)) != ATCA_SUCCESS) + { + break; + } + + // Supply OtherData so GenDig behavior is the same for keys with SlotConfig.NoMac set + other_data[0] = ATCA_GENDIG; + other_data[1] = GENDIG_ZONE_DATA; + other_data[2] = (uint8_t)(write_key_id); + other_data[3] = (uint8_t)(write_key_id >> 8); + + // Send the GenDig command + if ((status = atcab_gendig(GENDIG_ZONE_DATA, write_key_id, other_data, sizeof(other_data))) != ATCA_SUCCESS) + { + break; + } + + // Calculate Tempkey + // NoMac bit isn't being considered here on purpose to remove having to read SlotConfig. + // OtherData is built to get the same result regardless of the NoMac bit. + memset(&gen_dig_param, 0, sizeof(gen_dig_param)); + gen_dig_param.zone = GENDIG_ZONE_DATA; + gen_dig_param.sn = serial_num; + gen_dig_param.key_id = write_key_id; + gen_dig_param.is_key_nomac = false; + gen_dig_param.stored_value = write_key; + gen_dig_param.other_data = other_data; + gen_dig_param.temp_key = &temp_key; + if ((status = atcah_gen_dig(&gen_dig_param)) != ATCA_SUCCESS) + { + break; + } + + // Calculate Auth MAC and cipher text + memset(&host_mac_param, 0, sizeof(host_mac_param)); + host_mac_param.zone = PRIVWRITE_MODE_ENCRYPT; + host_mac_param.key_id = key_id; + host_mac_param.sn = serial_num; + host_mac_param.input_data = &priv_key[0]; + host_mac_param.encrypted_data = cipher_text; + host_mac_param.auth_mac = host_mac; + host_mac_param.temp_key = &temp_key; + if ((status = atcah_privwrite_auth_mac(&host_mac_param)) != ATCA_SUCCESS) + { + break; + } + + // build a write command for encrypted writes + packet.param1 = PRIVWRITE_MODE_ENCRYPT; // Mode is encrypted write + packet.param2 = key_id; // Key ID + memcpy(&packet.data[0], cipher_text, sizeof(cipher_text)); + memcpy(&packet.data[sizeof(cipher_text)], host_mac, sizeof(host_mac)); + } + + if ((status = atPrivWrite(ca_cmd, &packet)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + } + while (0); + + return status; +} + diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.c new file mode 100644 index 0000000..6a28911 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.c @@ -0,0 +1,80 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for Random command. + * + * The Random command generates a random number for use by the system. + * + * \note List of devices that support this command - ATSHA204A, ATECC108A, + * ATECC508A, ATECC608A. There are differences in the modes that they + * support. Refer to device datasheets for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ +#include "atca_basic.h" +#include "atca_execution.h" + +/** \brief Executes Random command, which generates a 32 byte random number + * from the CryptoAuth device. + * + * \param[out] rand_out 32 bytes of random data is returned here. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_random(uint8_t *rand_out) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + + do + { + // build an random command + packet.param1 = RANDOM_SEED_UPDATE; + packet.param2 = 0x0000; + + if ((status = atRandom(ca_cmd, &packet)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + if (packet.data[ATCA_COUNT_IDX] != RANDOM_RSP_SIZE) + { + status = ATCA_RX_FAIL; + break; + } + + if (rand_out) + { + memcpy(rand_out, &packet.data[ATCA_RSP_DATA_IDX], RANDOM_NUM_SIZE); + } + } + while (0); + + + return status; +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.c new file mode 100644 index 0000000..472c7f7 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.c @@ -0,0 +1,713 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for Read command. + * + * The Read command reads words either 4-byte words or 32-byte blocks from one + * of the memory zones of the device. The data may optionally be encrypted + * before being returned to the system. + * + * \note List of devices that support this command - ATSHA204A, ATECC108A, + * ATECC508A, ATECC608A. There are differences in the modes that they + * support. Refer to device datasheets for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ +#include "atca_basic.h" +#include "atca_execution.h" +#include "host/atca_host.h" + + +/** \brief Executes Read command, which reads either 4 or 32 bytes of data from + * a given slot, configuration zone, or the OTP zone. + * + * When reading a slot or OTP, data zone must be locked and the slot + * configuration must not be secret for a slot to be successfully read. + * + * \param[in] zone Zone to be read from device. Options are + * ATCA_ZONE_CONFIG, ATCA_ZONE_OTP, or ATCA_ZONE_DATA. + * \param[in] slot Slot number for data zone and ignored for other zones. + * \param[in] block 32 byte block index within the zone. + * \param[in] offset 4 byte work index within the block. Ignored for 32 byte + * reads. + * \param[out] data Read data is returned here. + * \param[in] len Length of the data to be read. Must be either 4 or 32. + * + * returns ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_read_zone(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint8_t *data, uint8_t len) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + uint16_t addr; + + do + { + // Check the input parameters + if (data == NULL) + { + return ATCA_BAD_PARAM; + } + + if (len != 4 && len != 32) + { + return ATCA_BAD_PARAM; + } + + // The get address function checks the remaining variables + if ((status = atcab_get_addr(zone, slot, block, offset, &addr)) != ATCA_SUCCESS) + { + break; + } + + // If there are 32 bytes to read, then OR the bit into the mode + if (len == ATCA_BLOCK_SIZE) + { + zone = zone | ATCA_ZONE_READWRITE_32; + } + + // build a read command + packet.param1 = zone; + packet.param2 = addr; + + if ((status = atRead(ca_cmd, &packet)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + memcpy(data, &packet.data[1], len); + } + while (0); + + return status; +} +/** \brief Executes Read command, which reads the 9 byte serial number of the + * device from the config zone. + * + * \param[out] serial_number 9 byte serial number is returned here. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_read_serial_number(uint8_t* serial_number) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t read_buf[ATCA_BLOCK_SIZE]; + + if (!serial_number) + { + return ATCA_BAD_PARAM; + } + + do + { + if ((status = atcab_read_zone(ATCA_ZONE_CONFIG, 0, 0, 0, read_buf, ATCA_BLOCK_SIZE)) != ATCA_SUCCESS) + { + break; + } + memcpy(&serial_number[0], &read_buf[0], 4); + memcpy(&serial_number[4], &read_buf[8], 5); + } + while (0); + + return status; +} +/** \brief Executes Read command, which reads the configuration zone to see if + * the specified slot is locked. + * + * \param[in] slot Slot to query for locked (slot 0-15) + * \param[out] is_locked Lock state returned here. True if locked. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_is_slot_locked(uint16_t slot, bool *is_locked) +{ + ATCA_STATUS ret = ATCA_GEN_FAIL; + uint8_t data[ATCA_WORD_SIZE]; + uint16_t slot_locked; + + do + { + if (slot > 15) + { + return ATCA_BAD_PARAM; + } + if (is_locked == NULL) + { + return ATCA_BAD_PARAM; + } + + // Read the word with the lock bytes ( SlotLock[2], RFU[2] ) (config block = 2, word offset = 6) + if ((ret = atcab_read_zone(ATCA_ZONE_CONFIG, 0, 2 /*block*/, 6 /*offset*/, data, ATCA_WORD_SIZE)) != ATCA_SUCCESS) + { + break; + } + + slot_locked = ((uint16_t)data[0]) | ((uint16_t)data[1] << 8); + *is_locked = ((slot_locked & (1 << slot)) == 0); + } + while (0); + + return ret; +} + +/** \brief Executes Read command, which reads the configuration zone to see if + * the specified zone is locked. + * + * \param[in] zone The zone to query for locked (use LOCK_ZONE_CONFIG or + * LOCK_ZONE_DATA). + * \param[out] is_locked Lock state returned here. True if locked. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_is_locked(uint8_t zone, bool *is_locked) +{ + ATCA_STATUS ret = ATCA_GEN_FAIL; + uint8_t data[ATCA_WORD_SIZE]; + + do + { + if (is_locked == NULL) + { + return ATCA_BAD_PARAM; + } + + // Read the word with the lock bytes (UserExtra, Selector, LockValue, LockConfig) (config block = 2, word offset = 5) + if ((ret = atcab_read_zone(ATCA_ZONE_CONFIG, 0, 2 /*block*/, 5 /*offset*/, data, ATCA_WORD_SIZE)) != ATCA_SUCCESS) + { + break; + } + + // Determine the index into the word_data based on the zone we are querying for + switch (zone) + { + case LOCK_ZONE_CONFIG: *is_locked = (data[3] != 0x55); break; + case LOCK_ZONE_DATA: *is_locked = (data[2] != 0x55); break; + default: ret = ATCA_BAD_PARAM; break; + } + } + while (0); + + return ret; +} + +/** \brief Executes Read command on a slot configured for encrypted reads and + * decrypts the data to return it as plaintext. + * + * Data zone must be locked for this command to succeed. Can only read 32 byte + * blocks. + * + * \param[in] key_id The slot ID to read from. + * \param[in] block Index of the 32 byte block within the slot to read. + * \param[out] data Decrypted (plaintext) data from the read is returned + * here (32 bytes). + * \param[in] enc_key 32 byte ReadKey for the slot being read. + * \param[in] enc_key_id KeyID of the ReadKey being used. + * + * returns ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_read_enc(uint16_t key_id, uint8_t block, uint8_t *data, const uint8_t* enc_key, const uint16_t enc_key_id) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t zone = ATCA_ZONE_DATA | ATCA_ZONE_READWRITE_32; + atca_nonce_in_out_t nonce_params; + atca_gen_dig_in_out_t gen_dig_param; + atca_temp_key_t temp_key; + uint8_t serial_num[32]; + uint8_t num_in[NONCE_NUMIN_SIZE] = { 0 }; + uint8_t rand_out[RANDOM_NUM_SIZE] = { 0 }; + uint8_t other_data[4] = { 0 }; + int i = 0; + + do + { + // Verify inputs parameters + if (data == NULL || enc_key == NULL) + { + status = ATCA_BAD_PARAM; + break; + } + + // Read the device SN + if ((status = atcab_read_zone(ATCA_ZONE_CONFIG, 0, 0, 0, serial_num, 32)) != ATCA_SUCCESS) + { + break; + } + // Make the SN continuous by moving SN[4:8] right after SN[0:3] + memmove(&serial_num[4], &serial_num[8], 5); + + // Send the random Nonce command + if ((status = atcab_nonce_rand(num_in, rand_out)) != ATCA_SUCCESS) + { + BREAK(status, "Nonce failed"); + } + + // Calculate Tempkey + memset(&temp_key, 0, sizeof(temp_key)); + memset(&nonce_params, 0, sizeof(nonce_params)); + nonce_params.mode = NONCE_MODE_SEED_UPDATE; + nonce_params.zero = 0; + nonce_params.num_in = (uint8_t*)&num_in; + nonce_params.rand_out = (uint8_t*)&rand_out; + nonce_params.temp_key = &temp_key; + if ((status = atcah_nonce(&nonce_params)) != ATCA_SUCCESS) + { + BREAK(status, "Calc TempKey failed"); + } + + // Supply OtherData so GenDig behavior is the same for keys with SlotConfig.NoMac set + other_data[0] = ATCA_GENDIG; + other_data[1] = GENDIG_ZONE_DATA; + other_data[2] = (uint8_t)(enc_key_id); + other_data[3] = (uint8_t)(enc_key_id >> 8); + + // Send the GenDig command + if ((status = atcab_gendig(GENDIG_ZONE_DATA, enc_key_id, other_data, sizeof(other_data))) != ATCA_SUCCESS) + { + BREAK(status, "GenDig failed"); + } + + // Calculate Tempkey + // NoMac bit isn't being considered here on purpose to remove having to read SlotConfig. + // OtherData is built to get the same result regardless of the NoMac bit. + memset(&gen_dig_param, 0, sizeof(gen_dig_param)); + gen_dig_param.key_id = enc_key_id; + gen_dig_param.is_key_nomac = false; + gen_dig_param.sn = serial_num; + gen_dig_param.stored_value = enc_key; + gen_dig_param.zone = GENDIG_ZONE_DATA; + gen_dig_param.other_data = other_data; + gen_dig_param.temp_key = &temp_key; + if ((status = atcah_gen_dig(&gen_dig_param)) != ATCA_SUCCESS) + { + BREAK(status, ""); + } + + // Read Encrypted + if ((status = atcab_read_zone(zone, key_id, block, 0, data, ATCA_BLOCK_SIZE)) != ATCA_SUCCESS) + { + BREAK(status, "Read encrypted failed"); + } + + // Decrypt + for (i = 0; i < ATCA_BLOCK_SIZE; i++) + { + data[i] = data[i] ^ temp_key.value[i]; + } + + status = ATCA_SUCCESS; + + } + while (0); + + + return status; +} + +/** \brief Executes Read command to read the complete device configuration + * zone. + * + * \param[out] config_data Configuration zone data is returned here. 88 bytes + * for ATSHA devices, 128 bytes for ATECC devices. + * + * \returns ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_read_config_zone(uint8_t* config_data) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + + do + { + + // Verify the inputs + if (config_data == NULL) + { + status = ATCA_BAD_PARAM; + break; + } + + if (_gDevice->mIface->mIfaceCFG->devtype == ATSHA204A) + { + status = atcab_read_bytes_zone(ATCA_ZONE_CONFIG, 0, 0x00, config_data, ATCA_SHA_CONFIG_SIZE); + } + else + { + status = atcab_read_bytes_zone(ATCA_ZONE_CONFIG, 0, 0x00, config_data, ATCA_ECC_CONFIG_SIZE); + } + + if (status != ATCA_SUCCESS) + { + break; + } + + } + while (0); + + return status; +} + +/** \brief Compares a specified configuration zone with the configuration zone + * currently on the device. + * + * This only compares the static portions of the configuration zone and skips + * those that are unique per device (first 16 bytes) and areas that can change + * after the configuration zone has been locked (e.g. LastKeyUse). + * + * \param[in] config_data Full configuration data to compare the device + * against. + * \param[out] same_config Result is returned here. True if the static portions + * on the configuration zones are the same. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_cmp_config_zone(uint8_t* config_data, bool* same_config) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t device_config_data[ATCA_ECC_CONFIG_SIZE]; /** Max for all configs */ + size_t config_size = 0; + + do + { + // Check the inputs + if ((config_data == NULL) || (same_config == NULL)) + { + status = ATCA_BAD_PARAM; + BREAK(status, "Invalid Parameters"); + } + // Set the boolean to false + *same_config = false; + + // Read all of the configuration bytes from the device + if ((status = atcab_read_config_zone(device_config_data)) != ATCA_SUCCESS) + { + BREAK(status, "Read config zone failed"); + } + + /* Get the config size of the device being tested */ + if (ATCA_SUCCESS != (status = atcab_get_zone_size(ATCA_ZONE_CONFIG, 0, &config_size))) + { + BREAK(status, "Failed to get config zone size"); + } + + /* Compare the lower writable bytes (16-51) */ + if (memcmp(&device_config_data[16], &config_data[16], 52 - 16)) + { + /* Difference found */ + break; + } + + if (_gDevice->mIface->mIfaceCFG->devtype == ATECC608A) + { + /* Skip Counter[0], Counter[1], which can change during operation */ + + /* Compare UseLock through Reserved (68 --> 83) */ + if (memcmp(&device_config_data[68], &config_data[68], 84 - 68)) + { + /* Difference found */ + break; + } + + /* Skip UserExtra, UserExtraAdd, LockValue, LockConfig, and SlotLocked */ + + } + else + { + /* Skip the counter & LastKeyUse bytes [52-83] */ + /* Skip User Extra & Selector [84-85] */ + /* Skip all lock bytes [86-89] */ + } + + if (90 < config_size) + { + /* Compare the upper writable bytes (90-config_size) */ + if (memcmp(&device_config_data[90], &config_data[90], config_size - 90)) + { + /* Difference found */ + break; + } + } + + /* All Matched */ + *same_config = true; + } + while (0); + + return status; +} + + +/** \brief Executes Read command to read a 64 byte ECDSA P256 signature from a + * slot configured for clear reads. + * + * \param[in] slot Slot number to read from. Only slots 8 to 15 are large + * enough for a signature. + * \param[out] sig Signature will be returned here (64 bytes). Format will be + * the 32 byte R and S big-endian integers concatenated. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_read_sig(uint16_t slot, uint8_t* sig) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + + do + { + // Check the value of the slot + if (sig == NULL || slot < 8 || slot > 15) + { + return ATCA_BAD_PARAM; + } + + // Read the first block + if ((status = atcab_read_zone(ATCA_ZONE_DATA, slot, 0, 0, &sig[0], ATCA_BLOCK_SIZE)) != ATCA_SUCCESS) + { + break; + } + + // Read the second block + if ((status = atcab_read_zone(ATCA_ZONE_DATA, slot, 1, 0, &sig[ATCA_BLOCK_SIZE], ATCA_BLOCK_SIZE)) != ATCA_SUCCESS) + { + break; + } + } + while (0); + + return status; +} + +/** \brief Executes Read command to read an ECC P256 public key from a slot + * configured for clear reads. + * + * This function assumes the public key is stored using the ECC public key + * format specified in the datasheet. + * + * \param[in] slot Slot number to read from. Only slots 8 to 15 are + * large enough for a public key. + * \param[out] public_key Public key is returned here (64 bytes). Format will + * be the 32 byte X and Y big-endian integers + * concatenated. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_read_pubkey(uint16_t slot, uint8_t *public_key) +{ + ATCA_STATUS ret = ATCA_GEN_FAIL; + uint8_t read_buf[ATCA_BLOCK_SIZE]; + uint8_t block = 0; + uint8_t offset = 0; + uint8_t cpy_index = 0; + uint8_t cpy_size = 0; + uint8_t read_index = 0; + + // Check the pointers + if (public_key == NULL) + { + return ATCA_BAD_PARAM; + } + // Check the value of the slot + if (slot < 8 || slot > 0xF) + { + return ATCA_BAD_PARAM; + } + + do + { + // The 64 byte P256 public key gets written to a 72 byte slot in the following pattern + // | Block 1 | Block 2 | Block 3 | + // | Pad: 4 Bytes | PubKey[0:27] | PubKey[28:31] | Pad: 4 Bytes | PubKey[32:55] | PubKey[56:63] | + + // Read the block + block = 0; + if ((ret = atcab_read_zone(ATCA_ZONE_DATA, slot, block, offset, read_buf, ATCA_BLOCK_SIZE)) != ATCA_SUCCESS) + { + break; + } + + // Copy. Account for 4 byte pad + cpy_size = ATCA_BLOCK_SIZE - ATCA_PUB_KEY_PAD; + read_index = ATCA_PUB_KEY_PAD; + memcpy(&public_key[cpy_index], &read_buf[read_index], cpy_size); + cpy_index += cpy_size; + + // Read the next block + block = 1; + if ((ret = atcab_read_zone(ATCA_ZONE_DATA, slot, block, offset, read_buf, ATCA_BLOCK_SIZE)) != ATCA_SUCCESS) + { + break; + } + + // Copy. First four bytes + cpy_size = ATCA_PUB_KEY_PAD; + read_index = 0; + memcpy(&public_key[cpy_index], &read_buf[read_index], cpy_size); + cpy_index += cpy_size; + // Copy. Skip four bytes + read_index = ATCA_PUB_KEY_PAD + ATCA_PUB_KEY_PAD; + cpy_size = ATCA_BLOCK_SIZE - read_index; + memcpy(&public_key[cpy_index], &read_buf[read_index], cpy_size); + cpy_index += cpy_size; + + // Read the next block + block = 2; + if ((ret = atcab_read_zone(ATCA_ZONE_DATA, slot, block, offset, read_buf, ATCA_BLOCK_SIZE)) != ATCA_SUCCESS) + { + break; + } + + // Copy. The remaining 8 bytes + cpy_size = ATCA_PUB_KEY_PAD + ATCA_PUB_KEY_PAD; + read_index = 0; + memcpy(&public_key[cpy_index], &read_buf[read_index], cpy_size); + + } + while (0); + + return ret; +} + +/** \brief Used to read an arbitrary number of bytes from any zone configured + * for clear reads. + * + * This function will issue the Read command as many times as is required to + * read the requested data. + * + * \param[in] zone Zone to read data from. Option are ATCA_ZONE_CONFIG(0), + * ATCA_ZONE_OTP(1), or ATCA_ZONE_DATA(2). + * \param[in] slot Slot number to read from if zone is ATCA_ZONE_DATA(2). + * Ignored for all other zones. + * \param[in] offset Byte offset within the zone to read from. + * \param[out] data Read data is returned here. + * \param[in] length Number of bytes to read starting from the offset. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_read_bytes_zone(uint8_t zone, uint16_t slot, size_t offset, uint8_t *data, size_t length) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + size_t zone_size = 0; + uint8_t read_buf[32]; + size_t data_idx = 0; + size_t cur_block = 0; + size_t cur_offset = 0; + uint8_t read_size = ATCA_BLOCK_SIZE; + size_t read_buf_idx = 0; + size_t copy_length = 0; + size_t read_offset = 0; + + if (zone != ATCA_ZONE_CONFIG && zone != ATCA_ZONE_OTP && zone != ATCA_ZONE_DATA) + { + return ATCA_BAD_PARAM; + } + if (zone == ATCA_ZONE_DATA && slot > 15) + { + return ATCA_BAD_PARAM; + } + if (length == 0) + { + return ATCA_SUCCESS; // Always succeed reading 0 bytes + } + if (data == NULL) + { + return ATCA_BAD_PARAM; + } + + do + { + status = atcab_get_zone_size(zone, slot, &zone_size); + if (status != ATCA_SUCCESS) + { + break; + } + if (offset + length > zone_size) + { + return ATCA_BAD_PARAM; // Can't read past the end of a zone + + } + cur_block = offset / ATCA_BLOCK_SIZE; + + while (data_idx < length) + { + if (read_size == ATCA_BLOCK_SIZE && zone_size - cur_block * ATCA_BLOCK_SIZE < ATCA_BLOCK_SIZE) + { + // We have less than a block to read and can't read past the end of the zone, switch to word reads + read_size = ATCA_WORD_SIZE; + cur_offset = ((data_idx + offset) / ATCA_WORD_SIZE) % (ATCA_BLOCK_SIZE / ATCA_WORD_SIZE); + } + + // Read next chunk of data + status = atcab_read_zone( + zone, + slot, + (uint8_t)cur_block, + (uint8_t)cur_offset, + read_buf, + read_size); + if (status != ATCA_SUCCESS) + { + break; + } + + // Calculate where in the read buffer we need data from + read_offset = cur_block * ATCA_BLOCK_SIZE + cur_offset * ATCA_WORD_SIZE; + if (read_offset < offset) + { + read_buf_idx = offset - read_offset; // Read data starts before the requested chunk + } + else + { + read_buf_idx = 0; // Read data is within the requested chunk + + } + // Calculate how much data from the read buffer we want to copy + if (length - data_idx < read_size - read_buf_idx) + { + copy_length = length - data_idx; + } + else + { + copy_length = read_size - read_buf_idx; + } + + memcpy(&data[data_idx], &read_buf[read_buf_idx], copy_length); + data_idx += copy_length; + if (read_size == ATCA_BLOCK_SIZE) + { + cur_block += 1; + } + else + { + cur_offset += 1; + } + } + if (status != ATCA_SUCCESS) + { + break; + } + } + while (false); + + return status; +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.c new file mode 100644 index 0000000..5eb1668 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.c @@ -0,0 +1,221 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for SecureBoot command. + * + * The SecureBoot command provides support for secure boot of an external MCU + * or MPU. + * + * \note List of devices that support this command - ATECC608A. Refer to device + * datasheet for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +#include "atca_basic.h" +#include "atca_execution.h" +#include "host/atca_host.h" + +/** \brief Executes Secure Boot command, which provides support for secure + * boot of an external MCU or MPU. + * + * \param[in] mode Mode determines what operations the SecureBoot + * command performs. + * \param[in] param2 Not used, must be 0. + * \param[in] digest Digest of the code to be verified (32 bytes). + * \param[in] signature Signature of the code to be verified (64 bytes). Can + * be NULL when using the FullStore mode. + * \param[out] mac Validating MAC will be returned here (32 bytes). Can + * be NULL if not required. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_secureboot(uint8_t mode, uint16_t param2, const uint8_t* digest, const uint8_t* signature, uint8_t* mac) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + + if (digest == NULL) + { + return ATCA_BAD_PARAM; + } + + do + { + packet.param1 = mode; + packet.param2 = param2; + + memcpy(packet.data, digest, SECUREBOOT_DIGEST_SIZE); + + if (signature) + { + memcpy(&packet.data[SECUREBOOT_DIGEST_SIZE], signature, SECUREBOOT_SIGNATURE_SIZE); + } + + if ((status = atSecureBoot(ca_cmd, &packet)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + if ((mac != NULL) && (packet.data[ATCA_COUNT_IDX] >= SECUREBOOT_RSP_SIZE_MAC)) + { + memcpy(mac, &packet.data[ATCA_RSP_DATA_IDX], SECUREBOOT_MAC_SIZE); + } + + } + while (0); + + return status; +} + +/** \brief Executes Secure Boot command with encrypted digest and validated + * MAC response using the IO protection key. + * + * \param[in] mode Mode determines what operations the SecureBoot + * command performs. + * \param[in] digest Digest of the code to be verified (32 bytes). + * This is the plaintext digest (not encrypted). + * \param[in] signature Signature of the code to be verified (64 bytes). Can + * be NULL when using the FullStore mode. + * \param[in] num_in Host nonce (20 bytes). + * \param[in] io_key IO protection key (32 bytes). + * \param[out] is_verified Verify result is returned here. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_secureboot_mac(uint8_t mode, const uint8_t* digest, const uint8_t* signature, const uint8_t* num_in, const uint8_t* io_key, bool* is_verified) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + atca_temp_key_t tempkey; + atca_nonce_in_out_t nonce_params; + atca_secureboot_enc_in_out_t sboot_enc_params; + atca_secureboot_mac_in_out_t sboot_mac_params; + uint8_t rand_out[RANDOM_NUM_SIZE]; + uint8_t key[ATCA_KEY_SIZE]; + uint8_t digest_enc[SECUREBOOT_DIGEST_SIZE]; + uint8_t mac[SECUREBOOT_MAC_SIZE]; + uint8_t host_mac[SECUREBOOT_MAC_SIZE]; + uint8_t buf[2]; + + do + { + if (is_verified == NULL) + { + return ATCA_BAD_PARAM; + } + + *is_verified = false; + + if (digest == NULL || num_in == NULL || io_key == NULL) + { + return ATCA_BAD_PARAM; + } + + // Setup Nonce command to create nonce combining host (num_in) and + // device (RNG) nonces + memset(&tempkey, 0, sizeof(tempkey)); + memset(&nonce_params, 0, sizeof(nonce_params)); + nonce_params.mode = NONCE_MODE_SEED_UPDATE; + nonce_params.zero = 0; + nonce_params.num_in = num_in; + nonce_params.rand_out = rand_out; + nonce_params.temp_key = &tempkey; + + // Initialize TempKey with nonce + status = atcab_nonce_base(nonce_params.mode, nonce_params.zero, nonce_params.num_in, rand_out); + if (status != ATCA_SUCCESS) + { + break; + } + + // Calculate nonce (TempKey) value + status = atcah_nonce(&nonce_params); + if (status != ATCA_SUCCESS) + { + break; + } + + // Encrypt the digest + memset(&sboot_enc_params, 0, sizeof(sboot_enc_params)); + sboot_enc_params.digest = digest; + sboot_enc_params.io_key = io_key; + sboot_enc_params.temp_key = &tempkey; + sboot_enc_params.hashed_key = key; + sboot_enc_params.digest_enc = digest_enc; + status = atcah_secureboot_enc(&sboot_enc_params); + if (status != ATCA_SUCCESS) + { + break; + } + + // Prepare MAC calculator + memset(&sboot_mac_params, 0, sizeof(sboot_mac_params)); + sboot_mac_params.mode = mode | SECUREBOOT_MODE_ENC_MAC_FLAG; + sboot_mac_params.param2 = 0; + sboot_mac_params.hashed_key = sboot_enc_params.hashed_key; + sboot_mac_params.digest = digest; + sboot_mac_params.signature = signature; + sboot_mac_params.mac = host_mac; + + // Run the SecureBoot command + status = atcab_secureboot(sboot_mac_params.mode, sboot_mac_params.param2, digest_enc, signature, mac); + if (status == ATCA_CHECKMAC_VERIFY_FAILED) + { + // Verify failed + *is_verified = false; + status = ATCA_SUCCESS; // Still consider this a command success + break; + } + if (status != ATCA_SUCCESS) + { + break; + } + + // Read the SecureBootConfig field out of the configuration zone, which + // is required to properly calculate the expected MAC + status = atcab_read_bytes_zone(ATCA_ZONE_CONFIG, 0, SECUREBOOTCONFIG_OFFSET, buf, 2); + if (status != ATCA_SUCCESS) + { + break; + } + sboot_mac_params.secure_boot_config = (uint16_t)buf[0] | ((uint16_t)buf[1] << 8); + + // Calculate the expected MAC + status = atcah_secureboot_mac(&sboot_mac_params); + if (status != ATCA_SUCCESS) + { + break; + } + + *is_verified = (memcmp(host_mac, mac, SECUREBOOT_MAC_SIZE) == 0); + } + while (0); + + return status; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.c new file mode 100644 index 0000000..01cd105 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.c @@ -0,0 +1,102 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for SelfTest command. + * + * The SelfTest command performs a test of one or more of the cryptographic + * engines within the device. + * + * \note List of devices that support this command - ATECC608A. Refer to device + * datasheet for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_basic.h" +#include "atca_execution.h" + +/** \brief Executes the SelfTest command, which performs a test of one or more + * of the cryptographic engines within the ATECC608A chip. + * + * \param[in] mode Functions to test. Can be a bit field combining any + * of the following: SELFTEST_MODE_RNG, + * SELFTEST_MODE_ECDSA_VERIFY, SELFTEST_MODE_ECDSA_SIGN, + * SELFTEST_MODE_ECDH, SELFTEST_MODE_AES, + * SELFTEST_MODE_SHA, SELFTEST_MODE_ALL. + * \param[in] param2 Currently unused, should be 0. + * \param[out] result Results are returned here as a bit field. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_selftest(uint8_t mode, uint16_t param2, uint8_t* result) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t response = 0; + + do + { + // build a SelfTest command + packet.param1 = mode; + packet.param2 = param2; + + if ((status = atSelfTest(ca_cmd, &packet)) != ATCA_SUCCESS) + { + break; + } + + status = atca_execute_command(&packet, _gDevice); + + // This command is a little awkward, because it returns its status as + // a single byte, which can be hard to differentiate from an actual + // error code. + + response = packet.data[ATCA_RSP_DATA_IDX]; + + if (response & !mode) + { + // The response has bits set outside of the bit field requested by + // the mode. This indicates an actual error rather than a self test + // failure. + return status; // Return the translated status. + } + else + { + // Here, we have the possibility of ambiguous results, where some + // error codes can't be differentiated from self test failures. + // We assume self-test failures. + if (result) + { + *result = response; + } + + // Self tests might have failed, but we returned success because + // the results are returned in result. + return ATCA_SUCCESS; + } + } + while (0); + + return status; +} + diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.c new file mode 100644 index 0000000..972a166 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.c @@ -0,0 +1,508 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for SHA command. + * + * The SHA command Computes a SHA-256 or HMAC/SHA digest for general purpose + * use by the host system. + * + * \note List of devices that support this command - ATSHA204A, ATECC108A, + * ATECC508A, and ATECC608A. There are differences in the modes that they + * support. Refer to device datasheets for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +#include "atca_basic.h" +#include "atca_execution.h" + +typedef struct +{ + uint32_t total_msg_size; //!< Total number of message bytes processed + uint32_t block_size; //!< Number of bytes in current block + uint8_t block[ATCA_SHA256_BLOCK_SIZE * 2]; //!< Unprocessed message storage +} hw_sha256_ctx; + +/** \brief Executes SHA command, which computes a SHA-256 or HMAC/SHA-256 + * digest for general purpose use by the host system. + * + * Only the Start(0) and Compute(1) modes are available for ATSHA devices. + * + * \param[in] mode SHA command mode Start(0), Update/Compute(1), + * End(2), Public(3), HMACstart(4), HMACend(5), + * Read_Context(6), or Write_Context(7). Also + * message digest target location for the + * ATECC608A. + * \param[in] length Number of bytes in the message parameter or + * KeySlot for the HMAC key if Mode is + * HMACstart(4) or Public(3). + * \param[in] message Message bytes to be hashed or Write_Context if + * restoring a context on the ATECC608A. Can be + * NULL if not required by the mode. + * \param[out] data_out Data returned by the command (digest or + * context). + * \param[inout] data_out_size As input, the size of the data_out buffer. As + * output, the number of bytes returned in + * data_out. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_sha_base(uint8_t mode, uint16_t length, const uint8_t* message, uint8_t* data_out, uint16_t* data_out_size) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t cmd_mode = (mode & SHA_MODE_MASK); + + if (cmd_mode != SHA_MODE_SHA256_PUBLIC && cmd_mode != SHA_MODE_HMAC_START && length > 0 && message == NULL) + { + return ATCA_BAD_PARAM; // message data indicated, but nothing provided + } + if (data_out != NULL && data_out_size == NULL) + { + return ATCA_BAD_PARAM; + } + + do + { + //Build Command + packet.param1 = mode; + packet.param2 = length; + + if (cmd_mode != SHA_MODE_SHA256_PUBLIC && cmd_mode != SHA_MODE_HMAC_START) + { + memcpy(packet.data, message, length); + } + + if ((status = atSHA(ca_cmd, &packet, length)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + if ((data_out != NULL) && (packet.data[ATCA_COUNT_IDX] > 4)) + { + if (packet.data[ATCA_COUNT_IDX] - ATCA_PACKET_OVERHEAD > *data_out_size) + { + status = ATCA_SMALL_BUFFER; + break; + } + *data_out_size = packet.data[ATCA_COUNT_IDX] - ATCA_PACKET_OVERHEAD; + memcpy(data_out, &packet.data[ATCA_RSP_DATA_IDX], *data_out_size); + } + } + while (0); + + return status; +} + +/** \brief Executes SHA command to initialize SHA-256 calculation engine + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_sha_start(void) +{ + return atcab_sha_base(SHA_MODE_SHA256_START, 0, NULL, NULL, NULL); +} + +/** \brief Executes SHA command to add 64 bytes of message data to the current + * context. + * + * \param[in] message 64 bytes of message data to add to add to operation. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_sha_update(const uint8_t *message) +{ + return atcab_sha_base(SHA_MODE_SHA256_UPDATE, 64, message, NULL, NULL); +} + +/** \brief Executes SHA command to complete SHA-256 or HMAC/SHA-256 operation. + * + * \param[out] digest Digest from SHA-256 or HMAC/SHA-256 will be returned + * here (32 bytes). + * \param[in] length Length of any remaining data to include in hash. Max 64 + * bytes. + * \param[in] message Remaining data to include in hash. NULL if length is 0. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_sha_end(uint8_t *digest, uint16_t length, const uint8_t *message) +{ + uint16_t digest_size = 32; + + return atcab_sha_base(SHA_MODE_SHA256_END, length, message, digest, &digest_size); +} + +/** \brief Executes SHA command to read the SHA-256 context back. Only for + * ATECC608A with SHA-256 contexts. HMAC not supported. + * + * \param[out] context Context data is returned here. + * \param[inout] context_size As input, the size of the context buffer in + * bytes. As output, the size of the returned + * context data. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_sha_read_context(uint8_t* context, uint16_t* context_size) +{ + return atcab_sha_base(SHA_MODE_READ_CONTEXT, 0, NULL, context, context_size); +} + +/** \brief Executes SHA command to write (restore) a SHA-256 context into the + * the device. Only supported for ATECC608A with SHA-256 contexts. + * + * \param[in] context Context data to be restored. + * \param[in] context_size Size of the context data in bytes. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_sha_write_context(const uint8_t* context, uint16_t context_size) +{ + return atcab_sha_base(SHA_MODE_WRITE_CONTEXT, context_size, context, NULL, NULL); +} + +/** \brief Use the SHA command to compute a SHA-256 digest. + * + * \param[in] length Size of message parameter in bytes. + * \param[in] message Message data to be hashed. + * \param[out] digest Digest is returned here (32 bytes). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_sha(uint16_t length, const uint8_t *message, uint8_t *digest) +{ + return atcab_hw_sha2_256(message, length, digest); +} + +/** \brief Initialize a SHA context for performing a hardware SHA-256 operation + * on a device. Note that only one SHA operation can be run at a time. + * + * \param[in] ctx SHA256 context + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_hw_sha2_256_init(atca_sha256_ctx_t* ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + return atcab_sha_start(); +} + +/** \brief Add message data to a SHA context for performing a hardware SHA-256 + * operation on a device. + * + * \param[in] ctx SHA256 context + * \param[in] data Message data to be added to hash. + * \param[in] data_size Size of data in bytes. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_hw_sha2_256_update(atca_sha256_ctx_t* ctx, const uint8_t* data, size_t data_size) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint32_t block_count; + uint32_t rem_size = ATCA_SHA256_BLOCK_SIZE - ctx->block_size; + uint32_t copy_size = data_size > rem_size ? rem_size : (uint32_t)data_size; + uint32_t i = 0; + + // Copy data into current block + memcpy(&ctx->block[ctx->block_size], data, copy_size); + + if (ctx->block_size + data_size < ATCA_SHA256_BLOCK_SIZE) + { + // Not enough data to finish off the current block + ctx->block_size += (uint32_t)data_size; + return ATCA_SUCCESS; + } + + // Process the current block + status = atcab_sha_update(ctx->block); + if (status != ATCA_SUCCESS) + { + return status; + } + + // Process any additional blocks + data_size -= copy_size; // Adjust to the remaining message bytes + block_count = (uint32_t)(data_size / ATCA_SHA256_BLOCK_SIZE); + for (i = 0; i < block_count; i++) + { + status = atcab_sha_update(&data[copy_size + i * ATCA_SHA256_BLOCK_SIZE]); + if (status != ATCA_SUCCESS) + { + return status; + } + } + + // Save any remaining data + ctx->total_msg_size += (block_count + 1) * ATCA_SHA256_BLOCK_SIZE; + ctx->block_size = data_size % ATCA_SHA256_BLOCK_SIZE; + memcpy(ctx->block, &data[copy_size + block_count * ATCA_SHA256_BLOCK_SIZE], ctx->block_size); + + return ATCA_SUCCESS; +} + +/** \brief Finish SHA-256 digest for a SHA context for performing a hardware + * SHA-256 operation on a device. + * + * \param[in] ctx SHA256 context + * \param[out] digest SHA256 digest is returned here (32 bytes) + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_hw_sha2_256_finish(atca_sha256_ctx_t* ctx, uint8_t* digest) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint32_t msg_size_bits; + uint32_t pad_zero_count; + uint16_t digest_size; + + if (_gDevice->mIface->mIfaceCFG->devtype == ATSHA204A) + { + // ATSHA204A only implements the raw 64-byte block operation, but + // doesn't add in the final footer information. So we do that manually + // here. + + // Calculate the total message size in bits + ctx->total_msg_size += ctx->block_size; + msg_size_bits = ctx->total_msg_size * 8; + + // Calculate the number of padding zero bytes required between the 1 bit byte and the ATCA_SHA256_BLOCK_SIZEbit message size in bits. + pad_zero_count = (ATCA_SHA256_BLOCK_SIZE - ((ctx->block_size + 9) % ATCA_SHA256_BLOCK_SIZE)) % ATCA_SHA256_BLOCK_SIZE; + + // Append a single 1 bit + ctx->block[ctx->block_size++] = 0x80; + + // Add padding zeros plus upper 4 bytes of total message size in bits (only supporting 32bit message bit counts) + memset(&ctx->block[ctx->block_size], 0, pad_zero_count + 4); + ctx->block_size += pad_zero_count + 4; + + // Add the total message size in bits to the end of the current block. Technically this is + // supposed to be 8 bytes. This shortcut will reduce the max message size to 536,870,911 bytes. + ctx->block[ctx->block_size++] = (uint8_t)(msg_size_bits >> 24); + ctx->block[ctx->block_size++] = (uint8_t)(msg_size_bits >> 16); + ctx->block[ctx->block_size++] = (uint8_t)(msg_size_bits >> 8); + ctx->block[ctx->block_size++] = (uint8_t)(msg_size_bits >> 0); + + digest_size = 32; + status = atcab_sha_base(SHA_MODE_SHA256_UPDATE, ATCA_SHA256_BLOCK_SIZE, ctx->block, digest, &digest_size); + if (status != ATCA_SUCCESS) + { + return status; + } + if (ctx->block_size > ATCA_SHA256_BLOCK_SIZE) + { + digest_size = 32; + status = atcab_sha_base(SHA_MODE_SHA256_UPDATE, ATCA_SHA256_BLOCK_SIZE, &ctx->block[ATCA_SHA256_BLOCK_SIZE], digest, &digest_size); + if (status != ATCA_SUCCESS) + { + return status; + } + } + } + else + { + status = atcab_sha_end(digest, ctx->block_size, ctx->block); + if (status != ATCA_SUCCESS) + { + return status; + } + } + + return ATCA_SUCCESS; +} + +/** \brief Use the SHA command to compute a SHA-256 digest. + * + * \param[in] data Message data to be hashed. + * \param[in] data_size Size of data in bytes. + * \param[out] digest Digest is returned here (32 bytes). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_hw_sha2_256(const uint8_t * data, size_t data_size, uint8_t* digest) +{ + ATCA_STATUS status = ATCA_SUCCESS; + atca_sha256_ctx_t ctx; + + status = atcab_hw_sha2_256_init(&ctx); + if (status != ATCA_SUCCESS) + { + return status; + } + + status = atcab_hw_sha2_256_update(&ctx, data, data_size); + if (status != ATCA_SUCCESS) + { + return status; + } + + status = atcab_hw_sha2_256_finish(&ctx, digest); + if (status != ATCA_SUCCESS) + { + return status; + } + + return ATCA_SUCCESS; +} + +/** \brief Executes SHA command to start an HMAC/SHA-256 operation + * + * \param[in] ctx HMAC/SHA-256 context + * \param[in] key_slot Slot key id to use for the HMAC calculation + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_sha_hmac_init(atca_hmac_sha256_ctx_t* ctx, uint16_t key_slot) +{ + memset(ctx, 0, sizeof(*ctx)); + return atcab_sha_base(SHA_MODE_HMAC_START, key_slot, NULL, NULL, NULL); +} + +/** \brief Executes SHA command to add an arbitrary amount of message data to + * a HMAC/SHA-256 operation. + * + * \param[in] ctx HMAC/SHA-256 context + * \param[in] data Message data to add + * \param[in] data_size Size of message data in bytes + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_sha_hmac_update(atca_hmac_sha256_ctx_t* ctx, const uint8_t* data, size_t data_size) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint32_t block_count; + uint32_t rem_size = ATCA_SHA256_BLOCK_SIZE - ctx->block_size; + uint32_t copy_size = data_size > rem_size ? rem_size : (uint32_t)data_size; + uint32_t i = 0; + + // Copy data into current block + memcpy(&ctx->block[ctx->block_size], data, copy_size); + + if (ctx->block_size + data_size < ATCA_SHA256_BLOCK_SIZE) + { + // Not enough data to finish off the current block + ctx->block_size += (uint32_t)data_size; + return ATCA_SUCCESS; + } + + // Process the current block + status = atcab_sha_base(SHA_MODE_HMAC_UPDATE, ATCA_SHA256_BLOCK_SIZE, ctx->block, NULL, NULL); + if (status != ATCA_SUCCESS) + { + return status; + } + + // Process any additional blocks + data_size -= copy_size; // Adjust to the remaining message bytes + block_count = (uint32_t)(data_size / ATCA_SHA256_BLOCK_SIZE); + for (i = 0; i < block_count; i++) + { + status = atcab_sha_base(SHA_MODE_HMAC_UPDATE, ATCA_SHA256_BLOCK_SIZE, &data[copy_size + i * ATCA_SHA256_BLOCK_SIZE], NULL, NULL); + if (status != ATCA_SUCCESS) + { + return status; + } + } + + // Save any remaining data + ctx->total_msg_size += (block_count + 1) * ATCA_SHA256_BLOCK_SIZE; + ctx->block_size = data_size % ATCA_SHA256_BLOCK_SIZE; + memcpy(ctx->block, &data[copy_size + block_count * ATCA_SHA256_BLOCK_SIZE], ctx->block_size); + + return ATCA_SUCCESS; +} + +/** \brief Executes SHA command to complete a HMAC/SHA-256 operation. + * + * \param[in] ctx HMAC/SHA-256 context + * \param[out] digest HMAC/SHA-256 result is returned here (32 bytes). + * \param[in] target Where to save the digest internal to the device. + * For ATECC608A, can be SHA_MODE_TARGET_TEMPKEY, + * SHA_MODE_TARGET_MSGDIGBUF, or SHA_MODE_TARGET_OUT_ONLY. + * For all other devices, SHA_MODE_TARGET_TEMPKEY is the + * only option. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_sha_hmac_finish(atca_hmac_sha256_ctx_t *ctx, uint8_t* digest, uint8_t target) +{ + uint8_t mode = SHA_MODE_HMAC_END; + uint16_t digest_size = 32; + + if (ATECC608A == _gDevice->mIface->mIfaceCFG->devtype) + { + mode = SHA_MODE_608_HMAC_END; + } + else if (target != SHA_MODE_TARGET_TEMPKEY) + { + return ATCA_BAD_PARAM; + } + + mode |= target; + + return atcab_sha_base(mode, ctx->block_size, ctx->block, digest, &digest_size); +} + +/** \brief Use the SHA command to compute an HMAC/SHA-256 operation. + * + * \param[in] data Message data to be hashed. + * \param[in] data_size Size of data in bytes. + * \param[in] key_slot Slot key id to use for the HMAC calculation + * \param[out] digest Digest is returned here (32 bytes). + * \param[in] target Where to save the digest internal to the device. + * For ATECC608A, can be SHA_MODE_TARGET_TEMPKEY, + * SHA_MODE_TARGET_MSGDIGBUF, or + * SHA_MODE_TARGET_OUT_ONLY. For all other devices, + * SHA_MODE_TARGET_TEMPKEY is the only option. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_sha_hmac(const uint8_t * data, size_t data_size, uint16_t key_slot, uint8_t* digest, uint8_t target) +{ + ATCA_STATUS status = ATCA_SUCCESS; + atca_hmac_sha256_ctx_t ctx; + + status = atcab_sha_hmac_init(&ctx, key_slot); + if (status != ATCA_SUCCESS) + { + return status; + } + + status = atcab_sha_hmac_update(&ctx, data, data_size); + if (status != ATCA_SUCCESS) + { + return status; + } + + status = atcab_sha_hmac_finish(&ctx, digest, target); + if (status != ATCA_SUCCESS) + { + return status; + } + + return ATCA_SUCCESS; +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.c new file mode 100644 index 0000000..914e7fc --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.c @@ -0,0 +1,181 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for Sign command. + * + * The Sign command generates a signature using the private key in slot with + * ECDSA algorithm. + * + * \note List of devices that support this command - ATECC108A, ATECC508A, and + * ATECC608A. There are differences in the modes that they support. Refer + * to device datasheets for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_basic.h" +#include "atca_execution.h" + +/** \brief Executes the Sign command, which generates a signature using the + * ECDSA algorithm. + * + * \param[in] mode Mode determines what the source of the message to be + * signed. + * \param[in] key_id Private key slot used to sign the message. + * \param[out] signature Signature is returned here. Format is R and S + * integers in big-endian format. 64 bytes for P256 + * curve. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_sign_base(uint8_t mode, uint16_t key_id, uint8_t *signature) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + + if (signature == NULL) + { + return ATCA_BAD_PARAM; + } + + do + { + // Build sign command + packet.param1 = mode; + packet.param2 = key_id; + if ((status = atSign(ca_cmd, &packet)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + if (packet.data[ATCA_COUNT_IDX] > 4) + { + memcpy(signature, &packet.data[ATCA_RSP_DATA_IDX], packet.data[ATCA_COUNT_IDX] - ATCA_PACKET_OVERHEAD); + } + + } + while (0); + + return status; +} + +/** \brief Executes Sign command, to sign a 32-byte external message using the + * private key in the specified slot. The message to be signed + * will be loaded into the Message Digest Buffer to the + * ATECC608A device or TempKey for other devices. + * + * \param[in] key_id Slot of the private key to be used to sign the + * message. + * \param[in] msg 32-byte message to be signed. Typically the SHA256 + * hash of the full message. + * \param[out] signature Signature will be returned here. Format is R and S + * integers in big-endian format. 64 bytes for P256 + * curve. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_sign(uint16_t key_id, const uint8_t *msg, uint8_t *signature) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t nonce_target = NONCE_MODE_TARGET_TEMPKEY; + uint8_t sign_source = SIGN_MODE_SOURCE_TEMPKEY; + + do + { + // Make sure RNG has updated its seed + if ((status = atcab_random(NULL)) != ATCA_SUCCESS) + { + break; + } + + // Load message into device + if (_gDevice->mCommands->dt == ATECC608A) + { + // Use the Message Digest Buffer for the ATECC608A + nonce_target = NONCE_MODE_TARGET_MSGDIGBUF; + sign_source = SIGN_MODE_SOURCE_MSGDIGBUF; + } + if ((status = atcab_nonce_load(nonce_target, msg, 32)) != ATCA_SUCCESS) + { + break; + } + + // Sign the message + if ((status = atcab_sign_base(SIGN_MODE_EXTERNAL | sign_source, key_id, signature)) != ATCA_SUCCESS) + { + break; + } + } + while (0); + + return status; +} + +/** \brief Executes Sign command to sign an internally generated message. + * + * \param[in] key_id Slot of the private key to be used to sign the + * message. + * \param[in] is_invalidate Set to true if the signature will be used with + * the Verify(Invalidate) command. false for all + * other cases. + * \param[in] is_full_sn Set to true if the message should incorporate + * the device's full serial number. + * \param[out] signature Signature is returned here. Format is R and S + * integers in big-endian format. 64 bytes for + * P256 curve. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_sign_internal(uint16_t key_id, bool is_invalidate, bool is_full_sn, uint8_t *signature) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t mode = SIGN_MODE_INTERNAL; + + do + { + // Sign the message + if (is_invalidate) + { + mode |= SIGN_MODE_INVALIDATE; + } + + if (is_full_sn) + { + mode |= SIGN_MODE_INCLUDE_SN; + } + + if ((status = atcab_sign_base(mode, key_id, signature)) != ATCA_SUCCESS) + { + break; + } + + } + while (0); + + return status; +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.c new file mode 100644 index 0000000..2d70d8d --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.c @@ -0,0 +1,76 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for UpdateExtra command. + * + * The UpdateExtra command is used to update the values of the two extra bytes + * within the Configuration zone after the Configuration zone has been locked. + * + * \note List of devices that support this command - ATSHA204A, ATECC108A, + * ATECC508A, and ATECC608A. There are differences in the modes that they + * support. Refer to device datasheets for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ +#include "atca_basic.h" +#include "atca_execution.h" + +/** \brief Executes UpdateExtra command to update the values of the two + * extra bytes within the Configuration zone (bytes 84 and 85). + * + * Can also be used to decrement the limited use counter associated with the + * key in slot NewValue. + * + * \param[in] mode Mode determines what operations the UpdateExtra + * command performs. + * \param[in] new_value Value to be written. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_updateextra(uint8_t mode, uint16_t new_value) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + + do + { + // Build command + memset(&packet, 0, sizeof(packet)); + packet.param1 = mode; + packet.param2 = new_value; + + if ((status = atUpdateExtra(ca_cmd, &packet)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + } + while (0); + + return status; +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.c new file mode 100644 index 0000000..b7f73da --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.c @@ -0,0 +1,495 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for Verify command. + * + * The Verify command takes an ECDSA [R,S] signature and verifies that it is + * correctly generated given an input message digest and public key. + * + * \note List of devices that support this command - ATECC108A, ATECC508A, and + * ATECC608A. There are differences in the modes that they support. Refer + * to device datasheet for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ +#include "atca_basic.h" +#include "atca_execution.h" +#include "host/atca_host.h" + + +/** \brief Executes the Verify command, which takes an ECDSA [R,S] signature + * and verifies that it is correctly generated from a given message and + * public key. In all cases, the signature is an input to the command. + * + * For the Stored, External, and ValidateExternal Modes, the contents of + * TempKey (or Message Digest Buffer in some cases for the ATECC608A) should + * contain the 32 byte message. + * + * \param[in] mode Verify command mode and options + * \param[in] key_id Stored mode, the slot containing the public key to + * be used for the verification. + * ValidateExternal mode, the slot containing the + * public key to be validated. + * External mode, KeyID contains the curve type to be + * used to Verify the signature. + * Validate or Invalidate mode, the slot containing + * the public key to be (in)validated. + * \param[in] signature Signature to be verified. R and S integers in + * big-endian format. 64 bytes for P256 curve. + * \param[in] public_key If mode is External, the public key to be used for + * verification. X and Y integers in big-endian format. + * 64 bytes for P256 curve. NULL for all other modes. + * \param[in] other_data If mode is Validate, the bytes used to generate the + * message for the validation (19 bytes). NULL for all + * other modes. + * \param[out] mac If mode indicates a validating MAC, then the MAC will + * will be returned here. Can be NULL otherwise. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_verify(uint8_t mode, uint16_t key_id, const uint8_t* signature, const uint8_t* public_key, const uint8_t* other_data, uint8_t* mac) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t verify_mode = (mode & VERIFY_MODE_MASK); + + do + { + if (signature == NULL) + { + return ATCA_BAD_PARAM; + } + if (verify_mode == VERIFY_MODE_EXTERNAL && public_key == NULL) + { + return ATCA_BAD_PARAM; + } + if ((verify_mode == VERIFY_MODE_VALIDATE || verify_mode == VERIFY_MODE_INVALIDATE) && other_data == NULL) + { + return ATCA_BAD_PARAM; + } + + // Build the verify command + packet.param1 = mode; + packet.param2 = key_id; + memcpy(&packet.data[0], signature, ATCA_SIG_SIZE); + if (verify_mode == VERIFY_MODE_EXTERNAL) + { + memcpy(&packet.data[ATCA_SIG_SIZE], public_key, ATCA_PUB_KEY_SIZE); + } + else if (other_data) + { + memcpy(&packet.data[ATCA_SIG_SIZE], other_data, VERIFY_OTHER_DATA_SIZE); + } + + if ((status = atVerify(ca_cmd, &packet)) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + // The Verify command may return MAC if requested + if ((mac != NULL) && (packet.data[ATCA_COUNT_IDX] >= (ATCA_PACKET_OVERHEAD + MAC_SIZE))) + { + memcpy(mac, &packet.data[ATCA_RSP_DATA_IDX], MAC_SIZE); + } + + } + while (false); + + return status; +} + +/** \brief Executes the Verify command with verification MAC for the External + * or Stored Verify modes.. This function is only available on the + * ATECC608A. + * + * \param[in] mode Verify command mode. Can be VERIFY_MODE_EXTERNAL or + * VERIFY_MODE_STORED. + * \param[in] key_id For VERIFY_MODE_STORED mode, the slot containing the + * public key to be used for the verification. + * For VERIFY_MODE_EXTERNAL mode, KeyID contains the + * curve type to be used to Verify the signature. Only + * VERIFY_KEY_P256 supported. + * \param[in] message 32 byte message to be verified. Typically + * the SHA256 hash of the full message. + * \param[in] signature Signature to be verified. R and S integers in + * big-endian format. 64 bytes for P256 curve. + * \param[in] public_key For VERIFY_MODE_EXTERNAL mode, the public key to be + * used for verification. X and Y integers in + * big-endian format. 64 bytes for P256 curve. Null for + * VERIFY_MODE_STORED mode. + * \param[in] num_in System nonce (32 byte) used for the verification + * MAC. + * \param[in] io_key IO protection key for verifying the validation MAC. + * \param[out] is_verified Boolean whether or not the message, signature, + * public key verified. + * + * \return ATCA_SUCCESS on verification success or failure, because the + * command still completed successfully. + */ +static ATCA_STATUS atcab_verify_extern_stored_mac( + uint8_t mode, + uint16_t key_id, + const uint8_t* message, + const uint8_t* signature, + const uint8_t* public_key, + const uint8_t* num_in, + const uint8_t* io_key, + bool* is_verified) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t msg_dig_buf[64]; + atca_verify_mac_in_out_t verify_mac_params; + uint8_t mac[SECUREBOOT_MAC_SIZE]; + uint8_t host_mac[SECUREBOOT_MAC_SIZE]; + + do + { + if (is_verified == NULL) + { + return ATCA_BAD_PARAM; + } + *is_verified = false; + if (signature == NULL || message == NULL || num_in == NULL || io_key == NULL) + { + return ATCA_BAD_PARAM; + } + if ((mode & VERIFY_MODE_MASK) == VERIFY_MODE_EXTERNAL && public_key == NULL) + { + return ATCA_BAD_PARAM; // Only External mode requires an external public key + + } + // When using the message digest buffer as the message source, the + // second 32 bytes in the buffer will be the MAC system nonce. + memcpy(&msg_dig_buf[0], message, 32); + memcpy(&msg_dig_buf[32], num_in, 32); + if ((status = atcab_nonce_load(NONCE_MODE_TARGET_MSGDIGBUF, msg_dig_buf, 64)) != ATCA_SUCCESS) + { + break; + } + + // Calculate the expected MAC + memset(&verify_mac_params, 0, sizeof(verify_mac_params)); + verify_mac_params.mode = mode | VERIFY_MODE_SOURCE_MSGDIGBUF | VERIFY_MODE_MAC_FLAG; + verify_mac_params.key_id = key_id; + verify_mac_params.signature = signature; + verify_mac_params.msg_dig_buf = msg_dig_buf; + verify_mac_params.io_key = io_key; + verify_mac_params.temp_key = NULL; + verify_mac_params.sn = NULL; + verify_mac_params.mac = host_mac; + status = atcah_verify_mac(&verify_mac_params); + if (status != ATCA_SUCCESS) + { + break; + } + + status = atcab_verify(verify_mac_params.mode, verify_mac_params.key_id, signature, public_key, NULL, mac); + if (status != ATCA_SUCCESS) + { + if (status == ATCA_CHECKMAC_VERIFY_FAILED) + { + status = ATCA_SUCCESS; // Verify failed, but command succeeded + } + break; + } + + *is_verified = (memcmp(host_mac, mac, MAC_SIZE) == 0); + } + while (0); + + return status; +} + +/** \brief Executes the Verify command, which verifies a signature (ECDSA + * verify operation) with all components (message, signature, and + * public key) supplied. The message to be signed will be loaded into + * the Message Digest Buffer to the ATECC608A device or TempKey for + * other devices. + * + * \param[in] message 32 byte message to be verified. Typically + * the SHA256 hash of the full message. + * \param[in] signature Signature to be verified. R and S integers in + * big-endian format. 64 bytes for P256 curve. + * \param[in] public_key The public key to be used for verification. X and + * Y integers in big-endian format. 64 bytes for + * P256 curve. + * \param[out] is_verified Boolean whether or not the message, signature, + * public key verified. + * + * \return ATCA_SUCCESS on verification success or failure, because the + * command still completed successfully. + */ +ATCA_STATUS atcab_verify_extern(const uint8_t *message, const uint8_t *signature, const uint8_t *public_key, bool *is_verified) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t nonce_target = NONCE_MODE_TARGET_TEMPKEY; + uint8_t verify_source = VERIFY_MODE_SOURCE_TEMPKEY; + + if (is_verified == NULL) + { + return ATCA_BAD_PARAM; + } + + *is_verified = false; + + if (signature == NULL || message == NULL || public_key == NULL) + { + return ATCA_BAD_PARAM; + } + + do + { + // Load message into device + if (_gDevice->mCommands->dt == ATECC608A) + { + // Use the Message Digest Buffer for the ATECC608A + nonce_target = NONCE_MODE_TARGET_MSGDIGBUF; + verify_source = VERIFY_MODE_SOURCE_MSGDIGBUF; + } + if ((status = atcab_nonce_load(nonce_target, message, 32)) != ATCA_SUCCESS) + { + break; + } + + status = atcab_verify(VERIFY_MODE_EXTERNAL | verify_source, VERIFY_KEY_P256, signature, public_key, NULL, NULL); + *is_verified = (status == ATCA_SUCCESS); + + if (status == ATCA_CHECKMAC_VERIFY_FAILED) + { + status = ATCA_SUCCESS; // Verify failed, but command succeeded + + } + } + while (0); + + return status; +} + +/** \brief Executes the Verify command with verification MAC, which verifies a + * signature (ECDSA verify operation) with all components (message, + * signature, and public key) supplied. This function is only available + * on the ATECC608A. + * + * \param[in] message 32 byte message to be verified. Typically + * the SHA256 hash of the full message. + * \param[in] signature Signature to be verified. R and S integers in + * big-endian format. 64 bytes for P256 curve. + * \param[in] public_key The public key to be used for verification. X and + * Y integers in big-endian format. 64 bytes for + * P256 curve. + * \param[in] num_in System nonce (32 byte) used for the verification + * MAC. + * \param[in] io_key IO protection key for verifying the validation MAC. + * \param[out] is_verified Boolean whether or not the message, signature, + * public key verified. + * + * \return ATCA_SUCCESS on verification success or failure, because the + * command still completed successfully. + */ +ATCA_STATUS atcab_verify_extern_mac(const uint8_t *message, const uint8_t* signature, const uint8_t* public_key, const uint8_t* num_in, const uint8_t* io_key, bool* is_verified) +{ + return atcab_verify_extern_stored_mac( + VERIFY_MODE_EXTERNAL, + VERIFY_KEY_P256, + message, + signature, + public_key, + num_in, + io_key, + is_verified); +} + +/** \brief Executes the Verify command, which verifies a signature (ECDSA + * verify operation) with a public key stored in the device. The + * message to be signed will be loaded into the Message Digest Buffer + * to the ATECC608A device or TempKey for other devices. + * + * \param[in] message 32 byte message to be verified. Typically + * the SHA256 hash of the full message. + * \param[in] signature Signature to be verified. R and S integers in + * big-endian format. 64 bytes for P256 curve. + * \param[in] key_id Slot containing the public key to be used in the + * verification. + * \param[out] is_verified Boolean whether or not the message, signature, + * public key verified. + * + * \return ATCA_SUCCESS on verification success or failure, because the + * command still completed successfully. + */ +ATCA_STATUS atcab_verify_stored(const uint8_t *message, const uint8_t *signature, uint16_t key_id, bool *is_verified) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t nonce_target = NONCE_MODE_TARGET_TEMPKEY; + uint8_t verify_source = VERIFY_MODE_SOURCE_TEMPKEY; + + if (is_verified == NULL) + { + return ATCA_BAD_PARAM; + } + + *is_verified = false; + + if (signature == NULL || message == NULL) + { + return ATCA_BAD_PARAM; + } + + do + { + // Load message into device + if (_gDevice->mCommands->dt == ATECC608A) + { + // Use the Message Digest Buffer for the ATECC608A + nonce_target = NONCE_MODE_TARGET_MSGDIGBUF; + verify_source = VERIFY_MODE_SOURCE_MSGDIGBUF; + } + if ((status = atcab_nonce_load(nonce_target, message, 32)) != ATCA_SUCCESS) + { + break; + } + + status = atcab_verify(VERIFY_MODE_STORED | verify_source, key_id, signature, NULL, NULL, NULL); + *is_verified = (status == ATCA_SUCCESS); + + if (status == ATCA_CHECKMAC_VERIFY_FAILED) + { + status = ATCA_SUCCESS; // Verify failed, but command succeeded + + } + } + while (0); + + return status; +} + +/** \brief Executes the Verify command with verification MAC, which verifies a + * signature (ECDSA verify operation) with a public key stored in the + * device. This function is only available on the ATECC608A. + * + * \param[in] message 32 byte message to be verified. Typically + * the SHA256 hash of the full message. + * \param[in] signature Signature to be verified. R and S integers in + * big-endian format. 64 bytes for P256 curve. + * \param[in] key_id Slot containing the public key to be used in the + * verification. + * \param[in] num_in System nonce (32 byte) used for the verification + * MAC. + * \param[in] io_key IO protection key for verifying the validation MAC. + * \param[out] is_verified Boolean whether or not the message, signature, + * public key verified. + * + * \return ATCA_SUCCESS on verification success or failure, because the + * command still completed successfully. + */ +ATCA_STATUS atcab_verify_stored_mac(const uint8_t *message, const uint8_t *signature, uint16_t key_id, const uint8_t* num_in, const uint8_t* io_key, bool* is_verified) +{ + return atcab_verify_extern_stored_mac( + VERIFY_MODE_STORED, + key_id, + message, + signature, + NULL, + num_in, + io_key, + is_verified); +} + +/** \brief Executes the Verify command in Validate mode to validate a public + * key stored in a slot. + * + * This command can only be run after GenKey has been used to create a PubKey + * digest of the public key to be validated in TempKey (mode=0x10). + * + * \param[in] key_id Slot containing the public key to be validated. + * \param[in] signature Signature to be verified. R and S integers in + * big-endian format. 64 bytes for P256 curve. + * \param[in] other_data 19 bytes of data used to build the verification + * message. + * \param[out] is_verified Boolean whether or not the message, signature, + * validation public key verified. + * + * \return ATCA_SUCCESS on verification success or failure, because the + * command still completed successfully. + */ +ATCA_STATUS atcab_verify_validate(uint16_t key_id, const uint8_t *signature, const uint8_t *other_data, bool *is_verified) +{ + ATCA_STATUS status = ATCA_SUCCESS; + + if (signature == NULL || other_data == NULL || is_verified == NULL) + { + return ATCA_BAD_PARAM; + } + + status = atcab_verify(VERIFY_MODE_VALIDATE, key_id, signature, NULL, other_data, NULL); + *is_verified = (status == ATCA_SUCCESS); + + if (status == ATCA_CHECKMAC_VERIFY_FAILED) + { + status = ATCA_SUCCESS; // Verify failed, but command succeeded + + } + return status; +} + +/** \brief Executes the Verify command in Invalidate mode which invalidates a + * previously validated public key stored in a slot. + * + * This command can only be run after GenKey has been used to create a PubKey + * digest of the public key to be invalidated in TempKey (mode=0x10). + * + * \param[in] key_id Slot containing the public key to be invalidated. + * \param[in] signature Signature to be verified. R and S integers in + * big-endian format. 64 bytes for P256 curve. + * \param[in] other_data 19 bytes of data used to build the verification + * message. + * \param[out] is_verified Boolean whether or not the message, signature, + * validation public key verified. + * + * \return ATCA_SUCCESS on verification success or failure, because the + * command still completed successfully. + */ +ATCA_STATUS atcab_verify_invalidate(uint16_t key_id, const uint8_t *signature, const uint8_t *other_data, bool *is_verified) +{ + ATCA_STATUS status = ATCA_SUCCESS; + + if (signature == NULL || other_data == NULL || is_verified == NULL) + { + return ATCA_BAD_PARAM; + } + + status = atcab_verify(VERIFY_MODE_INVALIDATE, key_id, signature, NULL, other_data, NULL); + *is_verified = (status == ATCA_SUCCESS); + + if (status == ATCA_CHECKMAC_VERIFY_FAILED) + { + status = ATCA_SUCCESS; // Verify failed, but command succeeded + + } + return status; +} + diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.c new file mode 100644 index 0000000..53a857d --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.c @@ -0,0 +1,535 @@ +/** + * \file + * \brief CryptoAuthLib Basic API methods for Write command. + * + * The Write command writes either one 4-byte word or a 32-byte block to one of + * the EEPROM zones on the device. Depending upon the value of the WriteConfig + * byte for a slot, the data may be required to be encrypted by the system prior + * to being sent to the device + * + * \note List of devices that support this command - ATSHA204A, ATECC108A, + * ATECC508A, and ATECC608A. There are differences in the modes that they + * support. Refer to device datasheets for full details. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ +#include "atca_basic.h" +#include "atca_execution.h" +#include "host/atca_host.h" + + +/** + * \brief Executes the Write command, which writes either one four byte word or + * a 32-byte block to one of the EEPROM zones on the device. Depending + * upon the value of the WriteConfig byte for this slot, the data may be + * required to be encrypted by the system prior to being sent to the + * device. This command cannot be used to write slots configured as ECC + * private keys. + * + * \param[in] zone Zone/Param1 for the write command. + * \param[in] address Address/Param2 for the write command. + * \param[in] value Plain-text data to be written or cipher-text for + * encrypted writes. 32 or 4 bytes depending on bit 7 in the + * zone. + * \param[in] mac MAC required for encrypted writes (32 bytes). Set to NULL + * if not required. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_write(uint8_t zone, uint16_t address, const uint8_t *value, const uint8_t *mac) +{ + ATCAPacket packet; + ATCACommand ca_cmd = _gDevice->mCommands; + ATCA_STATUS status = ATCA_GEN_FAIL; + + if (value == NULL) + { + return ATCA_BAD_PARAM; + } + + do + { + // Build the write command + packet.param1 = zone; + packet.param2 = address; + if (zone & ATCA_ZONE_READWRITE_32) + { + // 32-byte write + memcpy(packet.data, value, 32); + // Only 32-byte writes can have a MAC + if (mac) + { + memcpy(&packet.data[32], mac, 32); + } + } + else + { + // 4-byte write + memcpy(packet.data, value, 4); + } + + if ((status = atWrite(ca_cmd, &packet, mac && (zone & ATCA_ZONE_READWRITE_32))) != ATCA_SUCCESS) + { + break; + } + + if ((status = atca_execute_command(&packet, _gDevice)) != ATCA_SUCCESS) + { + break; + } + + } + while (0); + + return status; +} + +/** \brief Executes the Write command, which writes either 4 or 32 bytes of + * data into a device zone. + * + * \param[in] zone Device zone to write to (0=config, 1=OTP, 2=data). + * \param[in] slot If writing to the data zone, it is the slot to write to, + * otherwise it should be 0. + * \param[in] block 32-byte block to write to. + * \param[in] offset 4-byte word within the specified block to write to. If + * performing a 32-byte write, this should be 0. + * \param[in] data Data to be written. + * \param[in] len Number of bytes to be written. Must be either 4 or 32. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_write_zone(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, const uint8_t *data, uint8_t len) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint16_t addr; + + // Check the input parameters + if (data == NULL) + { + return ATCA_BAD_PARAM; + } + + if (len != 4 && len != 32) + { + return ATCA_BAD_PARAM; + } + + do + { + // The get address function checks the remaining variables + if ((status = atcab_get_addr(zone, slot, block, offset, &addr)) != ATCA_SUCCESS) + { + break; + } + + // If there are 32 bytes to write, then xor the bit into the mode + if (len == ATCA_BLOCK_SIZE) + { + zone = zone | ATCA_ZONE_READWRITE_32; + } + + status = atcab_write(zone, addr, data, NULL); + + } + while (0); + + return status; +} + + +/** \brief Executes the Write command, which performs an encrypted write of + * a 32 byte block into given slot. + * + * The function takes clear text bytes and encrypts them for writing over the + * wire. Data zone must be locked and the slot configuration must be set to + * encrypted write for the block to be successfully written. + * + * \param[in] key_id Slot ID to write to. + * \param[in] block Index of the 32 byte block to write in the slot. + * \param[in] data 32 bytes of clear text data to be written to the slot + * \param[in] enc_key WriteKey to encrypt with for writing + * \param[in] enc_key_id The KeyID of the WriteKey + * + * returns ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_write_enc(uint16_t key_id, uint8_t block, const uint8_t *data, const uint8_t* enc_key, const uint16_t enc_key_id) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t zone = ATCA_ZONE_DATA | ATCA_ZONE_READWRITE_32; + atca_nonce_in_out_t nonce_params; + atca_gen_dig_in_out_t gen_dig_param; + atca_write_mac_in_out_t write_mac_param; + atca_temp_key_t temp_key; + uint8_t serial_num[32]; + uint8_t num_in[NONCE_NUMIN_SIZE] = { 0 }; + uint8_t rand_out[RANDOM_NUM_SIZE] = { 0 }; + uint8_t cipher_text[ATCA_KEY_SIZE] = { 0 }; + uint8_t mac[WRITE_MAC_SIZE] = { 0 }; + uint8_t other_data[4] = { 0 }; + uint16_t addr; + + do + { + // Verify inputs parameters + if (data == NULL || enc_key == NULL) + { + status = ATCA_BAD_PARAM; + break; + } + + // Read the device SN + if ((status = atcab_read_zone(ATCA_ZONE_CONFIG, 0, 0, 0, serial_num, 32)) != ATCA_SUCCESS) + { + break; + } + // Make the SN continuous by moving SN[4:8] right after SN[0:3] + memmove(&serial_num[4], &serial_num[8], 5); + + + // Random Nonce inputs + memset(&temp_key, 0, sizeof(temp_key)); + memset(&nonce_params, 0, sizeof(nonce_params)); + nonce_params.mode = NONCE_MODE_SEED_UPDATE; + nonce_params.zero = 0; + nonce_params.num_in = (uint8_t*)&num_in; + nonce_params.rand_out = (uint8_t*)&rand_out; + nonce_params.temp_key = &temp_key; + + // Send the random Nonce command + if ((status = atcab_nonce_rand(num_in, rand_out)) != ATCA_SUCCESS) + { + BREAK(status, "Nonce failed"); + } + + // Calculate Tempkey + if ((status = atcah_nonce(&nonce_params)) != ATCA_SUCCESS) + { + BREAK(status, "Calc TempKey failed"); + } + + // Supply OtherData so GenDig behavior is the same for keys with SlotConfig.NoMac set + other_data[0] = ATCA_GENDIG; + other_data[1] = GENDIG_ZONE_DATA; + other_data[2] = (uint8_t)(enc_key_id); + other_data[3] = (uint8_t)(enc_key_id >> 8); + + // Send the GenDig command + if ((status = atcab_gendig(GENDIG_ZONE_DATA, enc_key_id, other_data, sizeof(other_data))) != ATCA_SUCCESS) + { + BREAK(status, "GenDig failed"); + } + + // Calculate Tempkey + // NoMac bit isn't being considered here on purpose to remove having to read SlotConfig. + // OtherData is built to get the same result regardless of the NoMac bit. + memset(&gen_dig_param, 0, sizeof(gen_dig_param)); + gen_dig_param.key_id = enc_key_id; + gen_dig_param.is_key_nomac = false; + gen_dig_param.sn = serial_num; + gen_dig_param.stored_value = enc_key; + gen_dig_param.zone = GENDIG_ZONE_DATA; + gen_dig_param.other_data = other_data; + gen_dig_param.temp_key = &temp_key; + if ((status = atcah_gen_dig(&gen_dig_param)) != ATCA_SUCCESS) + { + BREAK(status, "atcah_gen_dig() failed"); + } + + // The get address function checks the remaining variables + if ((status = atcab_get_addr(ATCA_ZONE_DATA, key_id, block, 0, &addr)) != ATCA_SUCCESS) + { + BREAK(status, "Get address failed"); + } + + // Setting bit 6 to indicate input data is encrypted + write_mac_param.zone = zone | ATCA_ZONE_ENCRYPTED; + write_mac_param.key_id = addr; + write_mac_param.sn = serial_num; + write_mac_param.input_data = data; + write_mac_param.encrypted_data = cipher_text; + write_mac_param.auth_mac = mac; + write_mac_param.temp_key = &temp_key; + + if ((status = atcah_write_auth_mac(&write_mac_param)) != ATCA_SUCCESS) + { + BREAK(status, "Calculate Auth MAC failed"); + } + + status = atcab_write(write_mac_param.zone, write_mac_param.key_id, write_mac_param.encrypted_data, write_mac_param.auth_mac); + + } + while (0); + + return status; +} + +/** \brief Executes the Write command, which writes the configuration zone. + * + * First 16 bytes are skipped as they are not writable. LockValue and + * LockConfig are also skipped and can only be changed via the Lock + * command. + * + * This command may fail if UserExtra and/or Selector bytes have + * already been set to non-zero values. + * + * \param[in] config_data Data to the config zone data. This should be 88 + * bytes for SHA devices and 128 bytes for ECC + * devices. + * + * \returns ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_write_config_zone(const uint8_t* config_data) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + size_t config_size = 0; + + if (config_data == NULL) + { + return ATCA_BAD_PARAM; + } + + do + { + // Get config zone size for the device + status = atcab_get_zone_size(ATCA_ZONE_CONFIG, 0, &config_size); + if (status != ATCA_SUCCESS) + { + break; + } + + // Write config zone excluding UserExtra and Selector + status = atcab_write_bytes_zone(ATCA_ZONE_CONFIG, 0, 16, &config_data[16], config_size - 16); + if (status != ATCA_SUCCESS) + { + break; + } + + // Write the UserExtra and Selector. This may fail if either value is already non-zero. + status = atcab_updateextra(UPDATE_MODE_USER_EXTRA, config_data[84]); + if (status != ATCA_SUCCESS) + { + break; + } + status = atcab_updateextra(UPDATE_MODE_SELECTOR, config_data[85]); + + if (status != ATCA_SUCCESS) + { + break; + } + } + while (0); + + return status; +} + +/** \brief Uses the write command to write a public key to a slot in the + * proper format. + * + * \param[in] slot Slot number to write. Only slots 8 to 15 are large + * enough to store a public key. + * \param[in] public_key Public key to write into the slot specified. X and Y + * integers in big-endian format. 64 bytes for P256 + * curve. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_write_pubkey(uint16_t slot, const uint8_t *public_key) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint8_t public_key_formatted[ATCA_BLOCK_SIZE * 3]; + int block; + + // Check the pointers + if (public_key == NULL) + { + return ATCA_BAD_PARAM; + } + + // The 64 byte P256 public key gets written to a 72 byte slot in the following pattern + // | Block 1 | Block 2 | Block 3 | + // | Pad: 4 Bytes | PubKey[0:27] | PubKey[28:31] | Pad: 4 Bytes | PubKey[32:55] | PubKey[56:63] | + + memset(public_key_formatted, 0, sizeof(public_key_formatted)); + memcpy(&public_key_formatted[4], &public_key[0], 32); // Move X to padded position + memcpy(&public_key_formatted[40], &public_key[32], 32); // Move Y to padded position + + // Using this instead of atcab_write_zone_bytes, as that function doesn't work when + // the data zone is unlocked + for (block = 0; block < 3; block++) + { + status = atcab_write_zone(ATCA_ZONE_DATA, slot, block, 0, &public_key_formatted[ATCA_BLOCK_SIZE * block], ATCA_BLOCK_SIZE); + if (status != ATCA_SUCCESS) + { + break; + } + } + + return status; +} + +/** \brief Executes the Write command, which writes data into the + * configuration, otp, or data zones with a given byte offset and + * length. Offset and length must be multiples of a word (4 bytes). + * + * Config zone must be unlocked for writes to that zone. If data zone is + * unlocked, only 32-byte writes are allowed to slots and OTP and the offset + * and length must be multiples of 32 or the write will fail. + * + * \param[in] zone Zone to write data to: ATCA_ZONE_CONFIG(0), + * ATCA_ZONE_OTP(1), or ATCA_ZONE_DATA(2). + * \param[in] slot If zone is ATCA_ZONE_DATA(2), the slot number to + * write to. Ignored for all other zones. + * \param[in] offset_bytes Byte offset within the zone to write to. Must be + * a multiple of a word (4 bytes). + * \param[in] data Data to be written. + * \param[in] length Number of bytes to be written. Must be a multiple + * of a word (4 bytes). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_write_bytes_zone(uint8_t zone, uint16_t slot, size_t offset_bytes, const uint8_t *data, size_t length) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + size_t zone_size = 0; + size_t data_idx = 0; + size_t cur_block = 0; + size_t cur_word = 0; + + if (zone != ATCA_ZONE_CONFIG && zone != ATCA_ZONE_OTP && zone != ATCA_ZONE_DATA) + { + return ATCA_BAD_PARAM; + } + if (zone == ATCA_ZONE_DATA && slot > 15) + { + return ATCA_BAD_PARAM; + } + if (length == 0) + { + return ATCA_SUCCESS; // Always succeed writing 0 bytes + } + if (data == NULL) + { + return ATCA_BAD_PARAM; + } + if (offset_bytes % ATCA_WORD_SIZE != 0 || length % ATCA_WORD_SIZE != 0) + { + return ATCA_BAD_PARAM; + } + + do + { + status = atcab_get_zone_size(zone, slot, &zone_size); + if (status != ATCA_SUCCESS) + { + break; + } + if (offset_bytes + length > zone_size) + { + return ATCA_BAD_PARAM; + } + + cur_block = offset_bytes / ATCA_BLOCK_SIZE; + cur_word = (offset_bytes % ATCA_BLOCK_SIZE) / ATCA_WORD_SIZE; + + while (data_idx < length) + { + // The last item makes sure we handle the selector, user extra, and lock bytes in the config properly + if (cur_word == 0 && length - data_idx >= ATCA_BLOCK_SIZE && !(zone == ATCA_ZONE_CONFIG && cur_block == 2)) + { + status = atcab_write_zone(zone, slot, (uint8_t)cur_block, 0, &data[data_idx], ATCA_BLOCK_SIZE); + if (status != ATCA_SUCCESS) + { + break; + } + data_idx += ATCA_BLOCK_SIZE; + cur_block += 1; + } + else + { + // Skip trying to change UserExtra, Selector, LockValue, and LockConfig which require the UpdateExtra command to change + if (!(zone == ATCA_ZONE_CONFIG && cur_block == 2 && cur_word == 5)) + { + status = atcab_write_zone(zone, slot, (uint8_t)cur_block, (uint8_t)cur_word, &data[data_idx], ATCA_WORD_SIZE); + if (status != ATCA_SUCCESS) + { + break; + } + } + data_idx += ATCA_WORD_SIZE; + cur_word += 1; + if (cur_word == ATCA_BLOCK_SIZE / ATCA_WORD_SIZE) + { + cur_block += 1; + cur_word = 0; + } + } + } + } + while (false); + + return status; +} + +/** \brief Initialize one of the monotonic counters in device with a specific + * value. + * + * The monotonic counters are stored in the configuration zone using a special + * format. This encodes a binary count value into the 8 byte encoded value + * required. Can only be set while the configuration zone is unlocked. + * + * \param[in] counter_id Counter to be written. + * \param[in] counter_value Counter value to set. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_write_config_counter(uint16_t counter_id, uint32_t counter_value) +{ + uint16_t lin_a, lin_b, bin_a, bin_b; + uint8_t bytes[8]; + uint8_t idx = 0; + ATCA_STATUS status = ATCA_GEN_FAIL; + + if (counter_id > 1 || counter_value > COUNTER_MAX_VALUE) + { + return ATCA_BAD_PARAM; + } + + lin_a = 0xFFFF >> (counter_value % 32); + lin_b = 0xFFFF >> ((counter_value >= 16) ? (counter_value - 16) % 32 : 0); + bin_a = counter_value / 32; + bin_b = (counter_value >= 16) ? ((counter_value - 16) / 32) : 0; + + bytes[idx++] = lin_a >> 8; + bytes[idx++] = lin_a & 0xFF; + bytes[idx++] = lin_b >> 8; + bytes[idx++] = lin_b & 0xFF; + + bytes[idx++] = bin_a >> 8; + bytes[idx++] = bin_a & 0xFF; + bytes[idx++] = bin_b >> 8; + bytes[idx++] = bin_b & 0xFF; + + status = atcab_write_bytes_zone(ATCA_ZONE_CONFIG, 0, 52 + counter_id * 8, bytes, sizeof(bytes)); + + return status; +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.c new file mode 100644 index 0000000..28cafc2 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.c @@ -0,0 +1,857 @@ +/** + * \file + * \brief Helpers to support the CryptoAuthLib Basic API methods + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include +#include +#include +#include "cryptoauthlib.h" +#include "atca_helpers.h" + + + +/* Ruleset: + Index - Meaning + 0 - 62 Character + 1 - 63 Character + 2 - Pad Character (none if 0) + 3 - Maximum line length (no limit if 0) */ +uint8_t atcab_b64rules_default[4] = { '+', '/', '=', 64 }; +uint8_t atcab_b64rules_mime[4] = { '+', '/', '=', 76 }; +uint8_t atcab_b64rules_urlsafe[4] = { '-', '_', 0, 0 }; + + +/** \brief Convert a binary buffer to a hex string for easy reading. + * \param[in] bin Input data to convert. + * \param[in] bin_size Size of data to convert. + * \param[out] hex Buffer that receives hex string. + * \param[inout] hex_size As input, the size of the hex buffer. + * As output, the size of the output hex. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_bin2hex(const uint8_t* bin, size_t bin_size, char* hex, size_t* hex_size) +{ + return atcab_bin2hex_(bin, bin_size, hex, hex_size, true, true, true); +} + +static void uint8_to_hex(uint8_t num, char* hex_str) +{ + uint8_t nibble = (num >> 4) & 0x0F; + + if (nibble < 10) + { + *(hex_str++) = '0' + nibble; + } + else + { + *(hex_str++) = 'A' + (nibble - 10); + } + nibble = num & 0x0F; + if (nibble < 10) + { + *(hex_str++) = '0' + nibble; + } + else + { + *(hex_str++) = 'A' + (nibble - 10); + } +} + +static void hex_to_lowercase(char *buffer, size_t length) +{ + size_t index; + + if ((buffer != NULL) && (length > 0)) + { + for (index = 0; index < length; index++) + { + buffer[index] = tolower(buffer[index]); + } + } +} + + +static void hex_to_uppercase(char *buffer, size_t length) +{ + size_t index; + + if ((buffer != NULL) && (length > 0)) + { + for (index = 0; index < length; index++) + { + buffer[index] = toupper(buffer[index]); + } + } +} + +/** \brief To reverse the input data. + * \param[in] bin Input data to reverse. + * \param[in] bin_size Size of data to reverse. + * \param[out] dest Buffer to store reversed binary data. + * \param[in] dest_size The size of the dest buffer. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_reversal(const uint8_t* bin, size_t bin_size, uint8_t* dest, size_t* dest_size) +{ + size_t last, i; + + // Verify the inputs + if ((bin == NULL) || (dest == NULL)) + { + return ATCA_BAD_PARAM; + } + + if (*dest_size < bin_size) + { + return ATCA_SMALL_BUFFER; + } + + last = bin_size - 1; + + for (i = 0; i < bin_size; i++) + { + dest[i] = bin[last]; + last--; + } + *dest_size = bin_size; + return ATCA_SUCCESS; +} + + +/** \brief Function that converts a binary buffer to a hex string suitable for + * easy reading. + * \param[in] bin Input data to convert. + * \param[in] bin_size Size of data to convert. + * \param[out] hex Buffer that receives hex string. + * \param[inout] hex_size As input, the size of the hex buffer. + * As output, the size of the output hex. + * \param[in] is_pretty Indicates whether new lines should be + * added for pretty printing. + * \param[in] is_space Convert the output hex with space between it. + * \param[in] is_upper Convert the output hex to upper case. + + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_bin2hex_(const uint8_t* bin, size_t bin_size, char* hex, size_t* hex_size, bool is_pretty, bool is_space, bool is_upper) +{ + size_t i; + size_t cur_hex_size = 0; + size_t max_hex_size; + + // Verify the inputs + if (bin == NULL || hex == NULL || hex_size == NULL) + { + return ATCA_BAD_PARAM; + } + + max_hex_size = *hex_size; + *hex_size = 0; + + // Convert one byte at a time + for (i = 0; i < bin_size; i++) + { + if (cur_hex_size > max_hex_size) + { + break; + } + if (i != 0) + { + if (is_pretty && (i % 16 == 0)) + { + if (cur_hex_size + 2 > max_hex_size) + { + return ATCA_SMALL_BUFFER; + } + memcpy(&hex[cur_hex_size], "\r\n", 2); + cur_hex_size += 2; + } + else + { + if (is_space) + { + if (cur_hex_size + 1 > max_hex_size) + { + return ATCA_SMALL_BUFFER; + } + hex[cur_hex_size] = ' '; + cur_hex_size += 1; + } + } + } + + if (cur_hex_size + 2 > max_hex_size) + { + return ATCA_SMALL_BUFFER; + } + uint8_to_hex(bin[i], &hex[cur_hex_size]); + cur_hex_size += 2; + } + + if (is_upper) + { + hex_to_uppercase(hex, cur_hex_size); + } + else + { + hex_to_lowercase(hex, cur_hex_size); + } + + *hex_size = cur_hex_size; + if (cur_hex_size < max_hex_size) + { + // Since we have room add NULL as a convenience, but don't add to the + // output size. + hex[cur_hex_size] = 0; + } + + return ATCA_SUCCESS; +} + +inline static uint8_t hex_digit_to_num(char c) +{ + if (c >= '0' && c <= '9') + { + return (uint8_t)(c - '0'); + } + if (c >= 'a' && c <= 'f') + { + return (uint8_t)(c - 'a') + 10; + } + if (c >= 'A' && c <= 'F') + { + return (uint8_t)(c - 'A') + 10; + } + return 16; +} + + +ATCA_STATUS atcab_hex2bin_(const char* hex, size_t hex_size, uint8_t* bin, size_t* bin_size, bool is_space) +{ + size_t hex_index; + size_t bin_index = 0; + bool is_upper_nibble = true; + + for (hex_index = 0; hex_index < hex_size; hex_index++) + { + if (!isHexDigit(hex[hex_index])) + { + if (((hex_index + 1) % 3 == 0) && is_space) + { + if (hex[hex_index] != ' ') + { + return ATCA_BAD_PARAM; + } + } + + continue; // Skip any non-hex character + } + if (bin_index >= *bin_size) + { + return ATCA_SMALL_BUFFER; + } + + if (is_upper_nibble) + { + // Upper nibble + bin[bin_index] = hex_digit_to_num(hex[hex_index]) << 4; + } + else + { + // Lower nibble + bin[bin_index] += hex_digit_to_num(hex[hex_index]); + bin_index++; + } + is_upper_nibble = !is_upper_nibble; + } + if (!is_upper_nibble) + { + // Didn't end with an even number of hex digits. Assume it was malformed. + return ATCA_BAD_PARAM; + } + *bin_size = bin_index; + + return ATCA_SUCCESS; +} + +/** \brief Function that converts a hex string to binary buffer + * \param[in] hex Input buffer to convert + * \param[in] hex_size Length of buffer to convert + * \param[out] bin Buffer that receives binary + * \param[inout] bin_size As input, the size of the bin buffer. + * As output, the size of the bin data. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_hex2bin(const char* hex, size_t hex_size, uint8_t* bin, size_t* bin_size) +{ + return atcab_hex2bin_(hex, hex_size, bin, bin_size, false); +} + +/** + * \brief Checks to see if a character is an ASCII representation of a digit ((c ge '0') and (c le '9')) + * \param[in] c character to check + * \return True if the character is a digit + */ +bool isDigit(char c) +{ + return (c >= '0') && (c <= '9'); +} + +/** + * \brief Checks to see if a character is whitespace + * \param[in] c character to check + * \return True if the character is whitespace + */ +bool isWhiteSpace(char c) +{ + return (c == '\n') || (c == '\r') || (c == '\t') || (c == ' '); +} + +/** + * \brief Checks to see if a character is an ASCII representation of hex ((c >= 'A') and (c <= 'F')) || ((c >= 'a') and (c <= 'f')) + * \param[in] c character to check + * \return True if the character is a hex + */ +bool isAlpha(char c) +{ + return ((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')); +} + +/** + * \brief Checks to see if a character is an ASCII representation of hex ((c >= 'A') and (c <= 'F')) || ((c >= 'a') and (c <= 'f')) + * \param[in] c character to check + * \return True if the character is a hex + */ +bool isHexAlpha(char c) +{ + return ((c >= 'A') && (c <= 'F')) || ((c >= 'a') && (c <= 'f')); +} + +/** + * \brief Returns true if this character is a valid hex character or if this is whitespace (The character can be + * included in a valid hexstring). + * \param[in] c character to check + * \return True if the character can be included in a valid hexstring + */ +bool isHex(char c) +{ + return isHexDigit(c) || isWhiteSpace(c); +} + +/** + * \brief Returns true if this character is a valid hex character. + * \param[in] c character to check + * \return True if the character can be included in a valid hexstring + */ +bool isHexDigit(char c) +{ + return isDigit(c) || isHexAlpha(c); +} + +/** + * \brief Remove white space from a ASCII hex string. + * \param[in] ascii_hex Initial hex string to remove white space from + * \param[in] ascii_hex_len Length of the initial hex string + * \param[in] packed_hex Resulting hex string without white space + * \param[inout] packed_len In: Size to packed_hex buffer + * Out: Number of bytes in the packed hex string + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS packHex(const char* ascii_hex, size_t ascii_hex_len, char* packed_hex, size_t* packed_len) +{ + size_t i = 0; + size_t j = 0; + + // Verify the inputs + if ((ascii_hex == NULL) || (packed_hex == NULL) || (packed_len == NULL)) + { + return ATCA_BAD_PARAM; + } + // Loop through each character and only add the hex characters + for (i = 0; i < ascii_hex_len; i++) + { + if (isHexDigit(ascii_hex[i])) + { + if (j > *packed_len) + { + break; + } + packed_hex[j++] = ascii_hex[i]; + } + } + *packed_len = j; + + return ATCA_SUCCESS; +} + +#ifdef ATCAPRINTF +/** \brief Print each hex character in the binary buffer with spaces between bytes + * \param[in] label label to print + * \param[in] binary input buffer to print + * \param[in] bin_len length of buffer to print + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_printbin_label(const char* label, uint8_t* binary, size_t bin_len) +{ + printf("%s", label); + return atcab_printbin(binary, bin_len, true); +} + +/** \brief Print each hex character in the binary buffer with spaces between bytes + * \param[in] binary input buffer to print + * \param[in] bin_len length of buffer to print + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_printbin_sp(uint8_t* binary, size_t bin_len) +{ + return atcab_printbin(binary, bin_len, true); +} + +/** \brief Print each hex character in the binary buffer + * \param[in] binary input buffer to print + * \param[in] bin_len length of buffer to print + * \param[in] add_space indicates whether spaces and returns should be added for pretty printing + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_printbin(uint8_t* binary, size_t bin_len, bool add_space) +{ + size_t i = 0; + size_t line_len = 16; + + // Verify the inputs + if (binary == NULL) + { + return ATCA_BAD_PARAM; + } + + // Set the line length + line_len = add_space ? 16 : 32; + + // Print the bytes + for (i = 0; i < bin_len; i++) + { + // Print the byte + if (add_space) + { + printf("%02X ", binary[i]); + } + else + { + printf("%02X", binary[i]); + } + + // Break at the line_len + if ((i + 1) % line_len == 0) + { + printf("\r\n"); + } + } + // Print the last carriage return + printf("\r\n"); + + return ATCA_SUCCESS; +} +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Base 64 Encode/Decode + +#define B64_IS_EQUAL (uint8_t)64 +#define B64_IS_INVALID (uint8_t)0xFF + +/** + * \brief Returns true if this character is a valid base 64 character or if this is whitespace (A character can be + * included in a valid base 64 string). + * \param[in] c character to check + * \param[in] rules base64 ruleset to use + * \return True if the character can be included in a valid base 64 string + */ +bool isBase64(char c, const uint8_t * rules) +{ + return isBase64Digit(c, rules) || isWhiteSpace(c); +} + +/** + * \brief Returns true if this character is a valid base 64 character. + * \param[in] c character to check + * \param[in] rules base64 ruleset to use + * \return True if the character can be included in a valid base 64 string + */ +bool isBase64Digit(char c, const uint8_t * rules) +{ + return isDigit(c) || isAlpha(c) || c == rules[0] || c == rules[1] || c == rules[2]; +} + +/** + * \brief Returns the base 64 index of the given character. + * \param[in] c character to check + * \param[in] rules base64 ruleset to use + * \return the base 64 index of the given character + */ +uint8_t base64Index(char c, const uint8_t * rules) +{ + if ((c >= 'A') && (c <= 'Z')) + { + return (uint8_t)(c - 'A'); + } + if ((c >= 'a') && (c <= 'z')) + { + return (uint8_t)(26 + c - 'a'); + } + if ((c >= '0') && (c <= '9')) + { + return (uint8_t)(52 + c - '0'); + } + if (c == rules[0]) + { + return (uint8_t)62; + } + if (c == rules[1]) + { + return (uint8_t)63; + } + if (c == rules[2]) + { + return B64_IS_EQUAL; + } + return B64_IS_INVALID; +} + +/** + * \brief Returns the base 64 character of the given index. + * \param[in] id index to check + * \param[in] rules base64 ruleset to use + * \return the base 64 character of the given index + */ +char base64Char(uint8_t id, const uint8_t * rules) +{ + if (id >= 0 && (id < 26)) + { + return (char)('A' + id); + } + if ((id >= 26) && (id < 52)) + { + return (char)('a' + id - 26); + } + if ((id >= 52) && (id < 62)) + { + return (char)('0' + id - 52); + } + if (id == 62) + { + return rules[0]; + } + if (id == 63) + { + return rules[1]; + } + + if (id == B64_IS_EQUAL) + { + return rules[2]; + } + return B64_IS_INVALID; +} + +static ATCA_STATUS atcab_base64decode_block(const uint8_t id[4], uint8_t* data, size_t* data_size, size_t data_max_size) +{ + ATCA_STATUS status = ATCA_SUCCESS; + size_t new_bytes = 0; + + do + { + // Make sure padding characters can only be the last two + if ((id[0] == B64_IS_EQUAL) || + (id[1] == B64_IS_EQUAL) || + (id[2] == B64_IS_EQUAL && id[3] != B64_IS_EQUAL)) + { + status = ATCA_BAD_PARAM; + BREAK(status, "Base64 chars after end padding"); + } + + // Make sure output buffer has enough space + if (id[2] == B64_IS_EQUAL) + { + new_bytes = 1; + } + else if (id[3] == B64_IS_EQUAL) + { + new_bytes = 2; + } + else + { + new_bytes = 3; + } + if ((*data_size) + new_bytes > data_max_size) + { + status = ATCA_BAD_PARAM; + BREAK(status, "decoded buffer too small"); + } + + // Decode into output buffer + data[(*data_size)++] = ((id[0] << 2) | (id[1] >> 4)); + if (id[2] == B64_IS_EQUAL) + { + break; + } + data[(*data_size)++] = ((id[1] << 4) | (id[2] >> 2)); + if (id[3] == B64_IS_EQUAL) + { + break; + } + data[(*data_size)++] = ((id[2] << 6) | id[3]); + } + while (false); + + return status; +} + +/** + * \brief Decode base64 string to data with ruleset option. + * + * \param[in] encoded Base64 string to be decoded. + * \param[in] encoded_size Size of the base64 string in bytes. + * \param[out] data Decoded data will be returned here. + * \param[inout] data_size As input, the size of the byte_array buffer. + * As output, the length of the decoded data. + * \param[in] rules base64 ruleset to use + */ +ATCA_STATUS atcab_base64decode_(const char* encoded, size_t encoded_size, uint8_t* data, size_t* data_size, const uint8_t * rules) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint8_t id[4]; + int id_index = 0; + size_t enc_index = 0; + size_t data_max_size; + bool is_done = false; + + do + { + // Check the input parameters + if (encoded == NULL || data == NULL || data_size == NULL || rules == NULL) + { + status = ATCA_BAD_PARAM; + BREAK(status, "Null input parameter"); + } + data_max_size = *data_size; + *data_size = 0; + + // Start decoding the input data + for (enc_index = 0; enc_index < encoded_size; enc_index++) + { + if (isWhiteSpace(encoded[enc_index])) + { + continue; // Skip any whitespace characters + } + if (!isBase64Digit(encoded[enc_index], rules)) + { + status = ATCA_BAD_PARAM; + BREAK(status, "Invalid base64 character"); + } + if (is_done) + { + // We found valid base64 characters after end padding (equals) + // characters + status = ATCA_BAD_PARAM; + BREAK(status, "Base64 chars after end padding"); + } + id[id_index++] = base64Index(encoded[enc_index], rules); + // Process data 4 characters at a time + if (id_index >= 4) + { + id_index = 0; + status = atcab_base64decode_block(id, data, data_size, data_max_size); + if (status != ATCA_SUCCESS) + { + break; + } + + is_done = (id[3] == B64_IS_EQUAL); + } + } + if (status != ATCA_SUCCESS) + { + break; + } + if (id_index) + { + if (id_index < 2) + { + status = ATCA_BAD_PARAM; + BREAK(status, "Invalid number of base64 chars"); + } + // End of base64 string, but no padding characters + for (; id_index < 4; id_index++) + { + id[id_index] = B64_IS_EQUAL; + } + status = atcab_base64decode_block(id, data, data_size, data_max_size); + } + } + while (false); + + return status; +} + +/** \brief Encode data as base64 string with ruleset option. */ +ATCA_STATUS atcab_base64encode_( + const uint8_t* data, /**< [in] The input byte array that will be converted to base 64 encoded characters */ + size_t data_size, /**< [in] The length of the byte array */ + char* encoded, /**< [in] The output converted to base 64 encoded characters. */ + size_t* encoded_size, /**< [inout] Input: The size of the encoded buffer, Output: The length of the encoded base 64 character string */ + const uint8_t * rules /**< [in] ruleset to use during encoding */ + ) +{ + ATCA_STATUS status = ATCA_SUCCESS; + size_t data_idx = 0; + size_t b64_idx = 0; + size_t offset = 0; + uint8_t id = 0; + size_t b64_len; + + do + { + // Check the input parameters + if (encoded == NULL || data == NULL || encoded_size == NULL || !rules) + { + status = ATCA_BAD_PARAM; + BREAK(status, "Null input parameter"); + } + + // Calculate output length for buffer size check + b64_len = (data_size / 3 + (data_size % 3 != 0)) * 4; // ceil(size/3)*4 + if (rules[3]) + { + // We add newlines to the output + if (rules[3] % 4 != 0) + { + status = ATCA_BAD_PARAM; + BREAK(status, "newline rules[3] must be multiple of 4"); + } + b64_len += (b64_len / rules[3]) * 2; + } + b64_len += 1; // terminating null + if (*encoded_size < b64_len) + { + status = ATCA_SMALL_BUFFER; + BREAK(status, "Length of encoded buffer too small"); + } + // Initialize the return length to 0 + *encoded_size = 0; + + // Loop through the byte array by 3 then map to 4 base 64 encoded characters + for (data_idx = 0; data_idx < data_size; data_idx += 3) + { + // Add \r\n every n bytes if specified + if (rules[3] && data_idx > 0 && (b64_idx - offset) % rules[3] == 0) + { + // as soon as we do this, we introduce an offset + encoded[b64_idx++] = '\r'; + encoded[b64_idx++] = '\n'; + offset += 2; + } + + id = (data[data_idx] & 0xFC) >> 2; + encoded[b64_idx++] = base64Char(id, rules); + id = (data[data_idx] & 0x03) << 4; + if (data_idx + 1 < data_size) + { + id |= (data[data_idx + 1] & 0xF0) >> 4; + encoded[b64_idx++] = base64Char(id, rules); + id = (data[data_idx + 1] & 0x0F) << 2; + if (data_idx + 2 < data_size) + { + id |= (data[data_idx + 2] & 0xC0) >> 6; + encoded[b64_idx++] = base64Char(id, rules); + id = data[data_idx + 2] & 0x3F; + encoded[b64_idx++] = base64Char(id, rules); + } + else + { + encoded[b64_idx++] = base64Char(id, rules); + encoded[b64_idx++] = base64Char(B64_IS_EQUAL, rules); + } + } + else + { + encoded[b64_idx++] = base64Char(id, rules); + encoded[b64_idx++] = base64Char(B64_IS_EQUAL, rules); + encoded[b64_idx++] = base64Char(B64_IS_EQUAL, rules); + } + } + + // Strip any trailing nulls + while (b64_idx > 1 && encoded[b64_idx - 1] == 0) + { + b64_idx--; + } + + // Null terminate end + encoded[b64_idx++] = 0; + + // Set the final encoded length (excluding terminating null) + *encoded_size = b64_idx - 1; + } + while (false); + return status; +} + + +/** + * \brief Encode data as base64 string + * + * \param[in] byte_array Data to be encode in base64. + * \param[in] array_len Size of byte_array in bytes. + * \param[in] encoded Base64 output is returned here. + * \param[inout] encoded_len As input, the size of the encoded buffer. + * As output, the length of the encoded base64 + * character string. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_base64encode(const uint8_t* byte_array, size_t array_len, char* encoded, size_t* encoded_len) +{ + return atcab_base64encode_(byte_array, array_len, encoded, encoded_len, atcab_b64rules_default); +} + +/** + * \brief Decode base64 string to data + * + * \param[in] encoded Base64 string to be decoded. + * \param[in] encoded_len Size of the base64 string in bytes. + * \param[out] byte_array Decoded data will be returned here. + * \param[inout] array_len As input, the size of the byte_array buffer. + * As output, the length of the decoded data. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_base64decode(const char* encoded, size_t encoded_len, uint8_t* byte_array, size_t* array_len) +{ + return atcab_base64decode_(encoded, encoded_len, byte_array, array_len, atcab_b64rules_default); +} + + + diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.h new file mode 100644 index 0000000..3ab7a0f --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.h @@ -0,0 +1,82 @@ +/** + * \file + * \brief Helpers to support the CryptoAuthLib Basic API methods + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef ATCA_HELPERS_H_ +#define ATCA_HELPERS_H_ + +#include "cryptoauthlib.h" + +/** \ingroup atcab_ + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +ATCA_STATUS atcab_printbin(uint8_t* binary, size_t bin_len, bool add_space); +ATCA_STATUS atcab_bin2hex(const uint8_t* bin, size_t bin_size, char* hex, size_t* hex_size); +ATCA_STATUS atcab_bin2hex_(const uint8_t* bin, size_t bin_size, char* hex, size_t* hex_size, bool is_pretty, bool is_space, bool is_upper); +ATCA_STATUS atcab_hex2bin(const char* ascii_hex, size_t ascii_hex_len, uint8_t* binary, size_t* bin_len); +ATCA_STATUS atcab_hex2bin_(const char* hex, size_t hex_size, uint8_t* bin, size_t* bin_size, bool is_space); +ATCA_STATUS atcab_printbin_sp(uint8_t* binary, size_t bin_len); +ATCA_STATUS atcab_printbin_label(const char* label, uint8_t* binary, size_t bin_len); + + +ATCA_STATUS packHex(const char* ascii_hex, size_t ascii_hex_len, char* packed_hex, size_t* packed_len); +bool isDigit(char c); +bool isWhiteSpace(char c); +bool isAlpha(char c); +bool isHexAlpha(char c); +bool isHex(char c); +bool isHexDigit(char c); + +bool isBase64(char c, const uint8_t * rules); +bool isBase64Digit(char c, const uint8_t * rules); +uint8_t base64Index(char c, const uint8_t * rules); +char base64Char(uint8_t id, const uint8_t * rules); + +extern uint8_t atcab_b64rules_default[4]; +extern uint8_t atcab_b64rules_mime[4]; +extern uint8_t atcab_b64rules_urlsafe[4]; + +ATCA_STATUS atcab_base64decode_(const char* encoded, size_t encoded_size, uint8_t* data, size_t* data_size, const uint8_t * rules); +ATCA_STATUS atcab_base64decode(const char* encoded, size_t encoded_size, uint8_t* data, size_t* data_size); + +ATCA_STATUS atcab_base64encode_(const uint8_t* data, size_t data_size, char* encoded, size_t* encoded_size, const uint8_t * rules); +ATCA_STATUS atcab_base64encode(const uint8_t* data, size_t data_size, char* encoded, size_t* encoded_size); + + +ATCA_STATUS atcab_reversal(const uint8_t* bin, size_t bin_size, uint8_t* dest, size_t* dest_size); + + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* ATCA_HELPERS_H_ */ diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/README.md b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/README.md new file mode 100644 index 0000000..506c7b8 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/README.md @@ -0,0 +1,6 @@ +crypto directory - Purpose +=========================== +This directory contains software implementations of cryptographic functions. +The functions at the base level are wrappers that will point to the final +implementations of the software crypto functions. + diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw.h new file mode 100644 index 0000000..b9e5dc7 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw.h @@ -0,0 +1,33 @@ +/** + * \file + * \brief Common defines for CryptoAuthLib software crypto wrappers. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef ATCA_CRYPTO_SW_H +#define ATCA_CRYPTO_SW_H + +#include "atca_status.h" + +#endif \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.c new file mode 100644 index 0000000..448cf94 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.c @@ -0,0 +1,44 @@ +/** + * \file + * \brief API wrapper for software ECDSA verify. Currently unimplemented but could be + * implemented via a 3rd party library such as MicroECC. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +#include "atca_crypto_sw_ecdsa.h" + +/** \brief return software generated ECDSA verification result and the function is currently not implemented + * \param[in] msg ptr to message or challenge + * \param[in] signature ptr to the signature to verify + * \param[in] public_key ptr to public key of device which signed the challenge + * return ATCA_UNIMPLEMENTED , as the function is currently not implemented + */ + +int atcac_sw_ecdsa_verify_p256(const uint8_t msg[ATCA_ECC_P256_FIELD_SIZE], + const uint8_t signature[ATCA_ECC_P256_SIGNATURE_SIZE], + const uint8_t public_key[ATCA_ECC_P256_PUBLIC_KEY_SIZE]) +{ + return ATCA_UNIMPLEMENTED; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.h new file mode 100644 index 0000000..fb3a781 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.h @@ -0,0 +1,62 @@ +/** + * \file + * \brief + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +#ifndef ATCA_CRYPTO_SW_ECDSA_H +#define ATCA_CRYPTO_SW_ECDSA_H + +#include "atca_crypto_sw.h" +#include +#include + +/** \defgroup atcac_ Software crypto methods (atcac_) + * + * \brief + * These methods provide a software implementation of various crypto + * algorithms + * + @{ */ + +#define ATCA_ECC_P256_FIELD_SIZE (256 / 8) +#define ATCA_ECC_P256_PRIVATE_KEY_SIZE (ATCA_ECC_P256_FIELD_SIZE) +#define ATCA_ECC_P256_PUBLIC_KEY_SIZE (ATCA_ECC_P256_FIELD_SIZE * 2) +#define ATCA_ECC_P256_SIGNATURE_SIZE (ATCA_ECC_P256_FIELD_SIZE * 2) + +#ifdef __cplusplus +extern "C" { +#endif + +int atcac_sw_ecdsa_verify_p256(const uint8_t msg[ATCA_ECC_P256_FIELD_SIZE], + const uint8_t signature[ATCA_ECC_P256_SIGNATURE_SIZE], + const uint8_t public_key[ATCA_ECC_P256_PUBLIC_KEY_SIZE]); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.c new file mode 100644 index 0000000..b3e9866 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.c @@ -0,0 +1,39 @@ +/** + * \file + * \brief API wrapper for software random + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_crypto_sw_rand.h" + +/** \brief return software generated random number and the function is currently not implemented + * \param[out] data ptr to space to receive the random number + * \param[in] data_size size of data buffer + * return ATCA_UNIMPLEMENTED , as the function is not implemented + */ + +int atcac_sw_random(uint8_t* data, size_t data_size) +{ + return ATCA_UNIMPLEMENTED; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.h new file mode 100644 index 0000000..4e3a74c --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.h @@ -0,0 +1,53 @@ +/** + * \file + * \brief + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef ATCA_CRYPTO_SW_RAND_H +#define ATCA_CRYPTO_SW_RAND_H + +#include "atca_crypto_sw.h" +#include +#include + +/** \defgroup atcac_ Software crypto methods (atcac_) + * + * \brief + * These methods provide a software implementation of various crypto + * algorithms + * + @{ */ +#ifdef __cplusplus +extern "C" { +#endif + +int atcac_sw_random(uint8_t* data, size_t data_size); + +#ifdef __cplusplus +} +#endif +/** @} */ + +#endif \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.c new file mode 100644 index 0000000..1165bf5 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.c @@ -0,0 +1,106 @@ +/** + * \file + * \brief Wrapper API for SHA 1 routines + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +#include "atca_crypto_sw_sha1.h" +#include "hashes/sha1_routines.h" + + +/** \brief Initialize context for performing SHA1 hash in software. + * \param[in] ctx Hash context + * \return ATCA_SUCCESS on success, otherwise an error code. + */ + +int atcac_sw_sha1_init(atcac_sha1_ctx* ctx) +{ + if (sizeof(CL_HashContext) > sizeof(atcac_sha1_ctx)) + { + return ATCA_ASSERT_FAILURE; // atcac_sha1_ctx isn't large enough for this implementation + } + CL_hashInit((CL_HashContext*)ctx); + + return ATCA_SUCCESS; +} + + +/** \brief Add arbitrary data to a SHA1 hash. + \param[in] ctx Hash context + \param[in] data Data to be added to the hash + \param[in] data_size Data size in bytes + \return ATCA_SUCCESS + */ +int atcac_sw_sha1_update(atcac_sha1_ctx* ctx, const uint8_t* data, size_t data_size) +{ + CL_hashUpdate((CL_HashContext*)ctx, data, (int)data_size); + + return ATCA_SUCCESS; +} + +/** \brief Complete the SHA1 hash in software and return the digest. + * \param[in] ctx Hash context + * \param[out] digest Digest is returned here (20 bytes) + * \return ATCA_SUCCESS + */ +int atcac_sw_sha1_finish(atcac_sha1_ctx* ctx, uint8_t digest[ATCA_SHA1_DIGEST_SIZE]) +{ + CL_hashFinal((CL_HashContext*)ctx, digest); + + return ATCA_SUCCESS; +} + + +/** \brief Perform SHA1 hash of data in software. + * \param[in] data Data to be hashed + * \param[in] data_size Data size in bytes + * \param[out] digest Digest is returned here (20 bytes) + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +int atcac_sw_sha1(const uint8_t* data, size_t data_size, uint8_t digest[ATCA_SHA1_DIGEST_SIZE]) +{ + int ret; + atcac_sha1_ctx ctx; + + ret = atcac_sw_sha1_init(&ctx); + if (ret != ATCA_SUCCESS) + { + return ret; + } + + ret = atcac_sw_sha1_update(&ctx, data, data_size); + if (ret != ATCA_SUCCESS) + { + return ret; + } + + ret = atcac_sw_sha1_finish(&ctx, digest); + if (ret != ATCA_SUCCESS) + { + return ret; + } + + return ATCA_SUCCESS; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.h new file mode 100644 index 0000000..8097c46 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.h @@ -0,0 +1,64 @@ +/** + * \file + * \brief Wrapper API for SHA 1 routines + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef ATCA_CRYPTO_SW_SHA1_H +#define ATCA_CRYPTO_SW_SHA1_H + +#include "atca_crypto_sw.h" +#include +#include + +/** \defgroup atcac_ Software crypto methods (atcac_) + * + * \brief + * These methods provide a software implementation of various crypto + * algorithms + * + @{ */ + +#define ATCA_SHA1_DIGEST_SIZE (20) + +typedef struct +{ + uint32_t pad[32]; //!< Filler value to make sure the actual implementation has enough room to store its context. uint32_t is used to remove some alignment warnings. +} atcac_sha1_ctx; + +#ifdef __cplusplus +extern "C" { +#endif + +int atcac_sw_sha1_init(atcac_sha1_ctx* ctx); +int atcac_sw_sha1_update(atcac_sha1_ctx* ctx, const uint8_t* data, size_t data_size); +int atcac_sw_sha1_finish(atcac_sha1_ctx * ctx, uint8_t digest[ATCA_SHA1_DIGEST_SIZE]); +int atcac_sw_sha1(const uint8_t * data, size_t data_size, uint8_t digest[ATCA_SHA1_DIGEST_SIZE]); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.c new file mode 100644 index 0000000..bc82c0b --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.c @@ -0,0 +1,107 @@ +/** + * \file + * \brief Wrapper API for software SHA 256 routines + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_crypto_sw_sha2.h" +#include "hashes/sha2_routines.h" + +/** \brief initializes the SHA256 software + * \param[in] ctx ptr to context data structure + * \return ATCA_SUCCESS on success, otherwise an error code. + */ + +int atcac_sw_sha2_256_init(atcac_sha2_256_ctx* ctx) +{ + if (sizeof(sw_sha256_ctx) > sizeof(atcac_sha2_256_ctx)) + { + return ATCA_ASSERT_FAILURE; // atcac_sha1_ctx isn't large enough for this implementation + } + sw_sha256_init((sw_sha256_ctx*)ctx); + + return ATCA_SUCCESS; +} + +/** \brief updates the running hash with the next block of data, called iteratively for the entire + stream of data to be hashed using the SHA256 software + \param[in] ctx ptr to SHA context data structure + \param[in] data ptr to next block of data to hash + \param[in] data_size size amount of data to hash in the given block, in bytes + \return ATCA_SUCCESS + */ + +int atcac_sw_sha2_256_update(atcac_sha2_256_ctx* ctx, const uint8_t* data, size_t data_size) +{ + sw_sha256_update((sw_sha256_ctx*)ctx, data, (uint32_t)data_size); + + return ATCA_SUCCESS; +} + +/** \brief completes the final SHA256 calculation and returns the final digest/hash + * \param[in] ctx ptr to context data structure + * \param[out] digest receives the computed digest of the SHA 256 + * \return ATCA_SUCCESS + */ + +int atcac_sw_sha2_256_finish(atcac_sha2_256_ctx* ctx, uint8_t digest[ATCA_SHA2_256_DIGEST_SIZE]) +{ + sw_sha256_final((sw_sha256_ctx*)ctx, digest); + + return ATCA_SUCCESS; +} + + +/** \brief single call convenience function which computes Hash of given data using SHA256 software + * \param[in] data pointer to stream of data to hash + * \param[in] data_size size of data stream to hash + * \param[out] digest result + * \return ATCA_SUCCESS on success, otherwise an error code. + */ + +int atcac_sw_sha2_256(const uint8_t* data, size_t data_size, uint8_t digest[ATCA_SHA2_256_DIGEST_SIZE]) +{ + int ret; + atcac_sha2_256_ctx ctx; + + ret = atcac_sw_sha2_256_init(&ctx); + if (ret != ATCA_SUCCESS) + { + return ret; + } + + ret = atcac_sw_sha2_256_update(&ctx, data, data_size); + if (ret != ATCA_SUCCESS) + { + return ret; + } + + ret = atcac_sw_sha2_256_finish(&ctx, digest); + if (ret != ATCA_SUCCESS) + { + return ret; + } + + return ATCA_SUCCESS; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.h new file mode 100644 index 0000000..f9d80d4 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.h @@ -0,0 +1,64 @@ +/** + * \file + * \brief Wrapper API for software SHA 256 routines + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef ATCA_CRYPTO_SW_SHA2_H +#define ATCA_CRYPTO_SW_SHA2_H + +#include "atca_crypto_sw.h" +#include +#include + +/** \defgroup atcac_ Software crypto methods (atcac_) + * + * \brief + * These methods provide a software implementation of various crypto + * algorithms + * + @{ */ + +#define ATCA_SHA2_256_DIGEST_SIZE (32) + +typedef struct +{ + uint32_t pad[48]; //!< Filler value to make sure the actual implementation has enough room to store its context. uint32_t is used to remove some alignment warnings. +} atcac_sha2_256_ctx; + +#ifdef __cplusplus +extern "C" { +#endif + +int atcac_sw_sha2_256_init(atcac_sha2_256_ctx* ctx); +int atcac_sw_sha2_256_update(atcac_sha2_256_ctx* ctx, const uint8_t* data, size_t data_size); +int atcac_sw_sha2_256_finish(atcac_sha2_256_ctx * ctx, uint8_t digest[ATCA_SHA2_256_DIGEST_SIZE]); +int atcac_sw_sha2_256(const uint8_t * data, size_t data_size, uint8_t digest[ATCA_SHA2_256_DIGEST_SIZE]); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.c new file mode 100644 index 0000000..19f08ed --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.c @@ -0,0 +1,339 @@ +/** + * \file + * \brief Software implementation of the SHA1 algorithm. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "sha1_routines.h" +#include + + +/** + * \brief Initialize context for performing SHA1 hash in software. + * + * \param[in] ctx Hash context + */ +void CL_hashInit(CL_HashContext *ctx) +{ + static const U32 hashContext_h_init[] = { + 0x67452301, + 0xefcdab89, + 0x98badcfe, + 0x10325476, + 0xc3d2e1f0 + }; + + // Initialize context + memset(ctx, 0, sizeof(*ctx)); + memcpy_P(ctx->h, hashContext_h_init, sizeof(ctx->h)); +} + + + +/** + * \brief Add arbitrary data to a SHA1 hash. + * + * \param[in] ctx Hash context + * \param[in] src Data to be added to the hash + * \param[in] nbytes Data size in bytes + */ + +void CL_hashUpdate(CL_HashContext *ctx, const U8 *src, int nbytes) +{ + + /* + Digest src bytes, updating context. + */ + + U8 i, freeBytes; + U32 temp32; + + typedef struct + { + U8 buf[64]; + } Buf64; + + // We are counting on the fact that Buf64 is 64 bytes long. In + // principle the compiler may make Buf64 bigger 64 bytes, but this + // seems unlikely. Add an assertion check to be sure. Beware that + // assert may not be active in release versions. + // + //assert(sizeof(Buf64) == 64); + + // Get number of free bytes in the buf + freeBytes = (U8)(ctx->byteCount); + freeBytes &= 63; + freeBytes = (U8)(64 - freeBytes); + + while (nbytes > 0) + { + + // Get i, number of bytes to transfer from src + i = freeBytes; + if (nbytes < i) + { + i = (U8)nbytes; + } + + // Copy src bytes to buf + if (i == 64) + { + // This seems to be much faster on IAR than memcpy(). + *(Buf64*)(ctx->buf) = *(Buf64*)src; + } + else + { + // Have to use memcpy, size is other than 64 bytes. + memcpy(((U8*)ctx->buf) + 64 - freeBytes, src, i); + } + + // Adjust for transferred bytes + src += i; + nbytes -= i; + freeBytes -= i; + + // Do SHA crunch if buf is full + if (freeBytes == 0) + { + shaEngine(ctx->buf, ctx->h); + } + + // Update 64-bit byte count + temp32 = (ctx->byteCount += i); + if (temp32 == 0) + { + ++ctx->byteCountHi; + } + + // Set up for next iteration + freeBytes = 64; + } +} + + + +/** \brief Complete the SHA1 hash in software and return the digest. + * \param[in] ctx Hash context + * \param[out] dest Digest is returned here (20 bytes) + */ +void CL_hashFinal(CL_HashContext *ctx, U8 *dest) +{ + + /* + Finish a hash calculation and put result in dest. + */ + + U8 i; + U8 nbytes; + U32 temp; + U8 *ptr; + + /* Append pad byte, clear trailing bytes */ + nbytes = (U8)(ctx->byteCount) & 63; + ((U8*)ctx->buf)[nbytes] = 0x80; + for (i = (nbytes + 1); i < 64; i++) + { + ((U8*)ctx->buf)[i] = 0; + } + + /* + If no room for an 8-byte count at end of buf, digest the buf, + then clear it + */ + if (nbytes > (64 - 9)) + { + shaEngine(ctx->buf, ctx->h); + memset(ctx->buf, 0, 64); + } + + /* + Put the 8-byte bit count at end of buf. We have been tracking + bytes, not bits, so we left-shift our byte count by 3 as we do + this. + */ + temp = ctx->byteCount << 3; // low 4 bytes of bit count + ptr = &((U8*)ctx->buf)[63]; // point to low byte of bit count + for (i = 0; i < 4; i++) + { + *ptr-- = (U8)temp; + temp >>= 8; + } + // + temp = ctx->byteCountHi << 3; + temp |= ctx->byteCount >> (32 - 3); // high 4 bytes of bit count + for (i = 0; i < 4; i++) + { + *ptr-- = (U8)temp; + temp >>= 8; + } + //show("final SHA crunch", ctx->buf, 64); + + /* Final digestion */ + shaEngine(ctx->buf, ctx->h); + + /* Unpack chaining variables to dest bytes. */ + memcpy(dest, ctx->h, 20); + for (i = 0; i < 5; i++) + { + dest[i * 4 + 0] = (ctx->h[i] >> 24) & 0xFF; + dest[i * 4 + 1] = (ctx->h[i] >> 16) & 0xFF; + dest[i * 4 + 2] = (ctx->h[i] >> 8) & 0xFF; + dest[i * 4 + 3] = (ctx->h[i] >> 0) & 0xFF; + } +} + + + +/** \brief Perform SHA1 hash of data in software. + * \param[in] msg Data to be hashed + * \param[in] msgBytes Data size in bytes + * \param[out] dest Digest is returned here (20 bytes) + */ +void CL_hash(U8 *msg, int msgBytes, U8 *dest) +{ + CL_HashContext ctx; + + CL_hashInit(&ctx); + CL_hashUpdate(&ctx, msg, msgBytes); + CL_hashFinal(&ctx, dest); +} + +void shaEngine(U32 *buf, U32 *h) +{ + + /* + SHA-1 Engine. From FIPS 180. + + On entry, buf[64] contains the 64 bytes to digest. These bytes + are destroyed. + + _H[20] contains the 5 chaining variables. They must have the + proper value on entry and are updated on exit. + + The order of bytes in buf[] and _h[] matches that used by the + hardware SHA engine. + */ + + U8 t; + U32 a, b, c, d, e; + U32 temp = 0; + U8 *p; + U32 *w = (U32*)buf; + + /* + Pack first 64 bytes of buf into w[0,...,15]. Within a word, + bytes are big-endian. Do this in place -- buf[0,...,63] + overlays w[0,...,15]. + */ + p = (U8*)w; + for (t = 0; t < 16; t++) + { + temp = (temp << 8) | *p++; + temp = (temp << 8) | *p++; + temp = (temp << 8) | *p++; + temp = (temp << 8) | *p++; + w[t] = temp; + } + + /* + Pack the 20 bytes of _h[] into h[0,...,4]. Do in place using + same convention as for buidling w[]. + */ + //p = (U8*)h; + //for (t = 0; t < 5; t++) { + //temp = (temp << 8) | *p++; + //temp = (temp << 8) | *p++; + //temp = (temp << 8) | *p++; + //temp = (temp << 8) | *p++; + //h[t] = temp; + //} + + /* Copy the chaining variables to a, b, c, d, e */ + a = h[0]; + b = h[1]; + c = h[2]; + d = h[3]; + e = h[4]; + + /* Now do the 80 rounds */ + for (t = 0; t < 80; t++) + { + + temp = a; + leftRotate(temp, 5); + temp += e; + temp += w[t & 0xf]; + + if (t < 20) + { + temp += (b & c) | (~b & d); + temp += 0x5a827999L; + } + else if (t < 40) + { + temp += b ^ c ^ d; + temp += 0x6ed9eba1L; + } + else if (t < 60) + { + temp += (b & c) | (b & d) | (c & d); + temp += 0x8f1bbcdcL; + } + else + { + temp += b ^ c ^ d; + temp += 0xca62c1d6L; + } + + e = d; + d = c; + c = b; leftRotate(c, 30); + b = a; + a = temp; + + temp = w[t & 0xf] ^ w[(t - 3) & 0xf] ^ w[(t - 8) & 0xf] ^ w[(t - 14) & 0xf]; + leftRotate(temp, 1); + w[t & 0xf] = temp; + + } + + /* Update the chaining variables */ + h[0] += a; + h[1] += b; + h[2] += c; + h[3] += d; + h[4] += e; + + /* Unpack the chaining variables into _h[] buffer. */ + //p = (U8*)h; + //for (t = 0; t < 5; t++) { + //temp = h[t]; + //p[3] = (U8)temp; temp >>= 8; + //p[2] = (U8)temp; temp >>= 8; + //p[1] = (U8)temp; temp >>= 8; + //p[0] = (U8)temp; + //p += 4; + //} + +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.h new file mode 100644 index 0000000..6a57f1e --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.h @@ -0,0 +1,94 @@ +/** + * \file + * \brief Software implementation of the SHA1 algorithm. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef __SHA1_ROUTINES_DOT_H__ +#define __SHA1_ROUTINES_DOT_H__ + +#include +#include +#include + +#ifdef WIN32 +#include +#include +#endif + +#include + + +#ifndef U8 +#define U8 uint8_t +#endif + +#ifndef U16 +#define U16 uint16_t +#endif + +#ifndef U32 +#define U32 uint32_t +#endif + + +#ifndef memcpy_P +#define memcpy_P memmove +#endif + +#ifndef strcpy_P +#define strcpy_P strcpy +#endif + +#ifndef _WDRESET +#define _WDRESET() +#define _NOP() +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + U32 h[20 / 4]; // Ensure it's word aligned + U32 buf[64 / 4]; // Ensure it's word aligned + U32 byteCount; + U32 byteCountHi; +} CL_HashContext; + +#define leftRotate(x, n) (x) = (((x) << (n)) | ((x) >> (32 - (n)))) + +void shaEngine(U32 *buf, U32 *h); +void CL_hashInit(CL_HashContext *ctx); +void CL_hashUpdate(CL_HashContext *ctx, const U8 *src, int nbytes); +void CL_hashFinal(CL_HashContext *ctx, U8 *dest); +void CL_hash(U8 *msg, int msgBytes, U8 *dest); + +#ifdef __cplusplus +} +#endif + +#endif // __SHA1_ROUTINES_DOT_H__ + diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.c new file mode 100644 index 0000000..8f0dc1a --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.c @@ -0,0 +1,255 @@ +/** + * \file + * \brief Software implementation of the SHA256 algorithm. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include +#include "sha2_routines.h" + +#define rotate_right(value, places) ((value >> places) | (value << (32 - places))) + +/** + * \brief Processes whole blocks (64 bytes) of data. + * + * \param[in] ctx SHA256 hash context + * \param[in] blocks Raw blocks to be processed + * \param[in] block_count Number of 64-byte blocks to process + */ +static void sw_sha256_process(sw_sha256_ctx* ctx, const uint8_t* blocks, uint32_t block_count) +{ + int i = 0; + uint32_t block = 0; + + union + { + uint32_t w_word[SHA256_BLOCK_SIZE]; + uint8_t w_byte[SHA256_BLOCK_SIZE * sizeof(uint32_t)]; + } w_union; + + static const uint32_t k[] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + }; + + // Loop through all the blocks to process + for (block = 0; block < block_count; block++) + { + uint32_t w_index; + uint32_t word_value; + uint32_t s0, s1; + uint32_t t1, t2; + uint32_t maj, ch; + uint32_t rotate_register[8]; + const uint8_t* cur_msg_block = &blocks[block * SHA256_BLOCK_SIZE]; + + // Swap word bytes + for (i = 0; i < SHA256_BLOCK_SIZE; i += 4) + { + w_union.w_byte[i + 3] = cur_msg_block[i + 0]; + w_union.w_byte[i + 2] = cur_msg_block[i + 1]; + w_union.w_byte[i + 1] = cur_msg_block[i + 2]; + w_union.w_byte[i + 0] = cur_msg_block[i + 3]; + } + + w_index = 16; + while (w_index < SHA256_BLOCK_SIZE) + { + // right rotate for 32-bit variable in C: (value >> places) | (value << 32 - places) + word_value = w_union.w_word[w_index - 15]; + s0 = rotate_right(word_value, 7) ^ rotate_right(word_value, 18) ^ (word_value >> 3); + + word_value = w_union.w_word[w_index - 2]; + s1 = rotate_right(word_value, 17) ^ rotate_right(word_value, 19) ^ (word_value >> 10); + + w_union.w_word[w_index] = w_union.w_word[w_index - 16] + s0 + w_union.w_word[w_index - 7] + s1; + + w_index++; + } + + // Initialize hash value for this chunk. + for (i = 0; i < 8; i++) + { + rotate_register[i] = ctx->hash[i]; + } + + // hash calculation loop + for (i = 0; i < SHA256_BLOCK_SIZE; i++) + { + s0 = rotate_right(rotate_register[0], 2) + ^ rotate_right(rotate_register[0], 13) + ^ rotate_right(rotate_register[0], 22); + maj = (rotate_register[0] & rotate_register[1]) + ^ (rotate_register[0] & rotate_register[2]) + ^ (rotate_register[1] & rotate_register[2]); + t2 = s0 + maj; + s1 = rotate_right(rotate_register[4], 6) + ^ rotate_right(rotate_register[4], 11) + ^ rotate_right(rotate_register[4], 25); + ch = (rotate_register[4] & rotate_register[5]) + ^ (~rotate_register[4] & rotate_register[6]); + t1 = rotate_register[7] + s1 + ch + k[i] + w_union.w_word[i]; + + rotate_register[7] = rotate_register[6]; + rotate_register[6] = rotate_register[5]; + rotate_register[5] = rotate_register[4]; + rotate_register[4] = rotate_register[3] + t1; + rotate_register[3] = rotate_register[2]; + rotate_register[2] = rotate_register[1]; + rotate_register[1] = rotate_register[0]; + rotate_register[0] = t1 + t2; + } + + // Add the hash of this block to current result. + for (i = 0; i < 8; i++) + { + ctx->hash[i] += rotate_register[i]; + } + } +} + +/** + * \brief Intialize the software SHA256. + * + * \param[in] ctx SHA256 hash context + */ + +void sw_sha256_init(sw_sha256_ctx* ctx) +{ + static const uint32_t hash_init[] = { + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 + }; + int i; + + memset(ctx, 0, sizeof(*ctx)); + for (i = 0; i < 8; i++) + { + ctx->hash[i] = hash_init[i]; + } +} + +/** + * \brief updates the running hash with the next block of data, called iteratively for the entire + * stream of data to be hashed using the SHA256 software + * + * \param[in] ctx SHA256 hash context + * \param[in] msg Raw blocks to be processed + * \param[in] msg_size The size of the message passed + */ +void sw_sha256_update(sw_sha256_ctx* ctx, const uint8_t* msg, uint32_t msg_size) +{ + uint32_t block_count; + uint32_t rem_size = SHA256_BLOCK_SIZE - ctx->block_size; + uint32_t copy_size = msg_size > rem_size ? rem_size : msg_size; + + // Copy data into current block + memcpy(&ctx->block[ctx->block_size], msg, copy_size); + + if (ctx->block_size + msg_size < SHA256_BLOCK_SIZE) + { + // Not enough data to finish off the current block + ctx->block_size += msg_size; + return; + } + + // Process the current block + sw_sha256_process(ctx, ctx->block, 1); + + // Process any additional blocks + msg_size -= copy_size; // Adjust to the remaining message bytes + block_count = msg_size / SHA256_BLOCK_SIZE; + sw_sha256_process(ctx, &msg[copy_size], block_count); + + // Save any remaining data + ctx->total_msg_size += (block_count + 1) * SHA256_BLOCK_SIZE; + ctx->block_size = msg_size % SHA256_BLOCK_SIZE; + memcpy(ctx->block, &msg[copy_size + block_count * SHA256_BLOCK_SIZE], ctx->block_size); +} + + +/** \brief completes the final SHA256 calculation and returns the final digest/hash + * \param[in] ctx ptr to context data structure + * \param[out] digest receives the computed digest of the SHA 256 + */ +void sw_sha256_final(sw_sha256_ctx* ctx, uint8_t digest[SHA256_DIGEST_SIZE]) +{ + int i, j; + uint32_t msg_size_bits; + uint32_t pad_zero_count; + + // Calculate the total message size in bits + ctx->total_msg_size += ctx->block_size; + msg_size_bits = ctx->total_msg_size * 8; + + // Calculate the number of padding zero bytes required between the 1 bit byte and the 64 bit message size in bits. + pad_zero_count = (SHA256_BLOCK_SIZE - ((ctx->block_size + 9) % SHA256_BLOCK_SIZE)) % SHA256_BLOCK_SIZE; + + // Append a single 1 bit + ctx->block[ctx->block_size++] = 0x80; + + // Add padding zeros plus upper 4 bytes of total msg size in bits (only supporting 32bit message bit counts) + memset(&ctx->block[ctx->block_size], 0, pad_zero_count + 4); + ctx->block_size += pad_zero_count + 4; + + // Add the total message size in bits to the end of the current block. Technically this is + // supposed to be 8 bytes. This shortcut will reduce the max message size to 536,870,911 bytes. + ctx->block[ctx->block_size++] = (uint8_t)(msg_size_bits >> 24); + ctx->block[ctx->block_size++] = (uint8_t)(msg_size_bits >> 16); + ctx->block[ctx->block_size++] = (uint8_t)(msg_size_bits >> 8); + ctx->block[ctx->block_size++] = (uint8_t)(msg_size_bits >> 0); + + sw_sha256_process(ctx, ctx->block, ctx->block_size / SHA256_BLOCK_SIZE); + + // All blocks have been processed. + // Concatenate the hashes to produce digest, MSB of every hash first. + for (i = 0; i < 8; i++) + { + for (j = sizeof(int32_t) - 1; j >= 0; j--, ctx->hash[i] >>= 8) + { + digest[i * sizeof(int32_t) + j] = ctx->hash[i] & 0xFF; + } + } +} + +/** \brief single call convenience function which computes Hash of given data using SHA256 software + * \param[in] message pointer to stream of data to hash + * \param[in] len size of data stream to hash + * \param[out] digest result + */ + +void sw_sha256(const uint8_t* message, unsigned int len, uint8_t digest[SHA256_DIGEST_SIZE]) +{ + sw_sha256_ctx ctx; + + sw_sha256_init(&ctx); + sw_sha256_update(&ctx, message, len); + sw_sha256_final(&ctx, digest); +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.h new file mode 100644 index 0000000..f024942 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.h @@ -0,0 +1,61 @@ +/** + * \file + * \brief Software implementation of the SHA256 algorithm. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef SHA2_ROUTINES_H +#define SHA2_ROUTINES_H + +#include + +#define SHA256_DIGEST_SIZE (32) +#define SHA256_BLOCK_SIZE (64) + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + uint32_t total_msg_size; //!< Total number of message bytes processed + uint32_t block_size; //!< Number of bytes in current block + uint8_t block[SHA256_BLOCK_SIZE * 2]; //!< Unprocessed message storage + uint32_t hash[8]; //!< Hash state +} sw_sha256_ctx; + +void sw_sha256_init(sw_sha256_ctx* ctx); + +void sw_sha256_update(sw_sha256_ctx* ctx, const uint8_t* message, uint32_t len); + +void sw_sha256_final(sw_sha256_ctx * ctx, uint8_t digest[SHA256_DIGEST_SIZE]); + +void sw_sha256(const uint8_t * message, unsigned int len, uint8_t digest[SHA256_DIGEST_SIZE]); + +#ifdef __cplusplus +} +#endif + +#endif // SHA2_ROUTINES_H + diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/cryptoauthlib.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/cryptoauthlib.h new file mode 100644 index 0000000..4822d45 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/cryptoauthlib.h @@ -0,0 +1,57 @@ +/** + * \file + * \brief Single aggregation point for all CryptoAuthLib header files + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef _ATCA_LIB_H +#define _ATCA_LIB_H + +#include +#include + +#include "hal/atca_hal.h" +#include "atca_status.h" +#include "atca_device.h" +#include "atca_command.h" +#include "atca_cfgs.h" +#include "basic/atca_basic.h" +#include "basic/atca_helpers.h" + +#ifdef ATCAPRINTF + #include +//#define BREAK(status, message) {printf(__FUNCTION__": "message" -- Status: %02X\r\n", status); break;} + #define BREAK(status, message) { printf(": "message " -- Status: %02X\r\n", status); break; } + #define RETURN(status, message) { printf(": "message " -- Status: %02X\r\n", status); return status; } + #define PRINTSTAT(status, message) { printf(": "message " -- Status: %02X\r\n", status); } + #define PRINT(message) { printf(": "message "\r\n"); break; } + #define DBGOUT(message) { printf(": "message "\r\n"); break; } +#else + #define BREAK(status, message) { break; } + #define RETURN(status, message) { return status; } + #define PRINT(message) { break; } + #define DBGOUT(message) { break; } +#endif + +#endif diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/cryptoauthlib_config.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/cryptoauthlib_config.h new file mode 100644 index 0000000..a27d8e1 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/cryptoauthlib_config.h @@ -0,0 +1,62 @@ +/* + + * \file + * \brief CryptoAuthLib Basic API methods - a simple crypto authentication API. + * These methods manage a global ATCADevice object behind the scenes. They also + * manage the wake/idle state transitions so callers don't need to. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. +*/ + +#ifndef CRYPTOAUTHLIB_CONFIG_H +#define CRYPTOAUTHLIB_CONFIG_H + + +#ifndef ATCA_HAL_I2C +#define ATCA_HAL_I2C 1 +#endif + +#ifndef ATCA_NO_HEAP +#define ATCA_NO_HEAP 1 +#endif + +#ifndef ATCA_NO_POLL +#define ATCA_NO_POLL 1 +#endif + +#ifndef ATCAPRINTF +#define ATCAPRINTF 1 +#endif + +#ifndef CONF_CRYPTOAUTHLIB_DEBUG_HELPER +#define CONF_CRYPTOAUTHLIB_DEBUG_HELPER 0 +#endif + +/* Enable debug helper function */ +#if CONF_CRYPTOAUTHLIB_DEBUG_HELPER == 1 +#ifndef ATCAdebug_print +#define ATCAdebug_print 1 +#endif +#endif + +#endif // CRYPTOAUTHLIB_CONFIG_H diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.c new file mode 100644 index 0000000..fd89ee6 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.c @@ -0,0 +1,221 @@ +/** + * \file + * \brief low-level HAL - methods used to setup indirection to physical layer interface. + * this level does the dirty work of abstracting the higher level ATCAIFace methods from the + * low-level physical interfaces. Its main goal is to keep low-level details from bleeding into + * the logical interface implemetation. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +/* when incorporating ATCA HAL into your application, you need to adjust the #defines in atca_hal.h to include + * and exclude appropriate interfaces - this optimizes memory use when not using a specific iface implementation in your application */ + +#include "cryptoauthlib.h" +#include "atca_hal.h" + +/** \brief Standard HAL API for ATCA to initialize a physical interface + * \param[in] cfg pointer to ATCAIfaceCfg object + * \param[in] hal pointer to ATCAHAL_t intermediate data structure + * \return ATCA_SUCCESS on success, otherwise an error code. + */ + +ATCA_STATUS hal_iface_init(ATCAIfaceCfg *cfg, ATCAHAL_t *hal) +{ + // Because C isn't a real object oriented language or dynamically typed, some switch in the overall system is unavoidable + // The key here is to provide the flexibility to include just the types of interfaces you want/need without breaking the + // object model. The former is needed so in an embedded, constrained memory environment, you don't have to pay the price + // (in terms of memory) for interfaces you don't use in your application. + ATCA_STATUS status = ATCA_COMM_FAIL; + + switch (cfg->iface_type) + { + case ATCA_I2C_IFACE: + #ifdef ATCA_HAL_I2C + hal->halinit = &hal_i2c_init; + hal->halpostinit = &hal_i2c_post_init; + hal->halreceive = &hal_i2c_receive; + hal->halsend = &hal_i2c_send; + hal->halsleep = &hal_i2c_sleep; + hal->halwake = &hal_i2c_wake; + hal->halidle = &hal_i2c_idle; + hal->halrelease = &hal_i2c_release; + hal->hal_data = NULL; + + status = ATCA_SUCCESS; + #endif + break; + case ATCA_SWI_IFACE: + #ifdef ATCA_HAL_SWI + hal->halinit = &hal_swi_init; + hal->halpostinit = &hal_swi_post_init; + hal->halreceive = &hal_swi_receive; + hal->halsend = &hal_swi_send; + hal->halsleep = &hal_swi_sleep; + hal->halwake = &hal_swi_wake; + hal->halidle = &hal_swi_idle; + hal->halrelease = &hal_swi_release; + hal->hal_data = NULL; + + status = ATCA_SUCCESS; + #endif + break; + case ATCA_UART_IFACE: + #ifdef ATCA_HAL_UART + // TODO - initialize UART iface + #endif + #ifdef ATCA_HAL_KIT_CDC + hal->halinit = &hal_kit_cdc_init; + hal->halpostinit = &hal_kit_cdc_post_init; + hal->halreceive = &hal_kit_cdc_receive; + hal->halsend = &hal_kit_cdc_send; + hal->halsleep = &hal_kit_cdc_sleep; + hal->halwake = &hal_kit_cdc_wake; + hal->halidle = &hal_kit_cdc_idle; + hal->halrelease = &hal_kit_cdc_release; + hal->hal_data = NULL; + + status = ATCA_SUCCESS; + #endif + break; + case ATCA_SPI_IFACE: + #ifdef ATCA_HAL_SPI + // TODO - initialize SPI iface + #endif + break; + case ATCA_HID_IFACE: + #ifdef ATCA_HAL_KIT_HID + hal->halinit = &hal_kit_hid_init; + hal->halpostinit = &hal_kit_hid_post_init; + hal->halreceive = &hal_kit_hid_receive; + hal->halsend = &hal_kit_hid_send; + hal->halsleep = &hal_kit_hid_sleep; + hal->halwake = &hal_kit_hid_wake; + hal->halidle = &hal_kit_hid_idle; + hal->halrelease = &hal_kit_hid_release; + hal->hal_data = NULL; + + status = ATCA_SUCCESS; + #endif + break; + case ATCA_CUSTOM_IFACE: + #ifdef ATCA_HAL_CUSTOM + hal->halinit = cfg->atcacustom.halinit; + hal->halpostinit = cfg->atcacustom.halpostinit; + hal->halreceive = cfg->atcacustom.halreceive; + hal->halsend = cfg->atcacustom.halsend; + hal->halsleep = cfg->atcacustom.halsleep; + hal->halwake = cfg->atcacustom.halwake; + hal->halidle = cfg->atcacustom.halidle; + hal->halrelease = cfg->atcacustom.halrelease; + hal->hal_data = NULL; + + status = ATCA_SUCCESS; + #endif + break; + default: + break; + } + return status; +} + +/** \brief releases a physical interface, HAL knows how to interpret hal_data + * \param[in] iface_type - the type of physical interface to release + * \param[in] hal_data - pointer to opaque hal data maintained by HAL implementation for this interface type + * \return ATCA_SUCCESS on success, otherwise an error code. + */ + +ATCA_STATUS hal_iface_release(ATCAIfaceType iface_type, void *hal_data) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + + switch (iface_type) + { + case ATCA_I2C_IFACE: +#ifdef ATCA_HAL_I2C + status = hal_i2c_release(hal_data); +#endif + break; + case ATCA_SWI_IFACE: + #ifdef ATCA_HAL_SWI + status = hal_swi_release(hal_data); +#endif + break; + case ATCA_UART_IFACE: + #ifdef ATCA_HAL_UART + // TODO - release HAL UART +#endif +#ifdef ATCA_HAL_KIT_CDC + status = hal_kit_cdc_release(hal_data); +#endif + break; + case ATCA_SPI_IFACE: +#ifdef ATCA_HAL_SPI + // TODO - release HAL SPI +#endif + break; + case ATCA_HID_IFACE: +#ifdef ATCA_HAL_KIT_HID + status = hal_kit_hid_release(hal_data); +#endif + break; + case ATCA_CUSTOM_IFACE: +#ifdef ATCA_HAL_CUSTOM + // Current architecture/API prevents us from accessing the custom + // release function. So we just assume success at this point. + status = ATCA_SUCCESS; +#endif + break; + default: + break; + } + + return status; +} + +/** \brief Utility function for hal_wake to check the reply. + * \param[in] response Wake response to be checked. + * \param[in] response_size Size of the response to check. + * \return ATCA_SUCCESS for expected wake, ATCA_STATUS_SELFTEST_ERROR if the + * power on self test failed, ATCA_WAKE_FAILED for other failures. + */ +ATCA_STATUS hal_check_wake(const uint8_t* response, int response_size) +{ + const uint8_t expected_response[4] = { 0x04, 0x11, 0x33, 0x43 }; + uint8_t selftest_fail_resp[4] = { 0x04, 0x07, 0xC4, 0x40 }; + + if (response_size != 4) + { + return ATCA_WAKE_FAILED; + } + if (memcmp(response, expected_response, 4) == 0) + { + return ATCA_SUCCESS; + } + if (memcmp(response, selftest_fail_resp, 4) == 0) + { + return ATCA_STATUS_SELFTEST_ERROR; + } + return ATCA_WAKE_FAILED; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.h new file mode 100644 index 0000000..9a09509 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.h @@ -0,0 +1,177 @@ +/** + * \file + * \brief low-level HAL - methods used to setup indirection to physical layer interface + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +#ifndef ATCA_HAL_H_ +#define ATCA_HAL_H_ + +#include "atca_status.h" +#include "atca_iface.h" +#include "atca_start_config.h" +#include "atca_start_iface.h" + +/** \defgroup hal_ Hardware abstraction layer (hal_) + * + * \brief + * These methods define the hardware abstraction layer for communicating with a CryptoAuth device + * + @{ */ + +/** \brief an intermediary data structure to allow the HAL layer to point the standard API functions + used by the upper layers to the HAL implementation for the interface. This isolates the upper layers + and loosely couples the ATCAIface object from the physical implementation. + */ + +typedef struct +{ + // interface is a group of function pointers to a specific HAL implementation for this interface type + // so these function pointers are initialized in the HAL layer in order to help keep the ATCAIface object + // from needing to know the low-level details, including global naming of HAL methods and physical implementation. + ATCA_STATUS (*halinit)(void *hal, ATCAIfaceCfg *cfg); + ATCA_STATUS (*halpostinit)(ATCAIface iface); + ATCA_STATUS (*halsend)(ATCAIface iface, uint8_t *txdata, int txlength); + ATCA_STATUS (*halreceive)(ATCAIface iface, uint8_t* rxdata, uint16_t* rxlength); + ATCA_STATUS (*halwake)(ATCAIface iface); + ATCA_STATUS (*halidle)(ATCAIface iface); + ATCA_STATUS (*halsleep)(ATCAIface iface); + ATCA_STATUS (*halrelease)(void* hal_data); + + void *hal_data; // points to whatever the HAL implementation for this interface wants it to, HAL manages. +} ATCAHAL_t; + +#ifdef __cplusplus +extern "C" { +#endif + +extern ATCA_STATUS hal_iface_init(ATCAIfaceCfg *, ATCAHAL_t* hal); +extern ATCA_STATUS hal_iface_release(ATCAIfaceType, void* hal_data); + +ATCA_STATUS hal_check_wake(const uint8_t* response, int response_size); + +// Added one or more of the following defines to your compiler's defines to include add support for +// that particular interface in your application. For example, if you're writing an I2C to SWI +// bridge, add both ATCA_HAL_I2C and ATCA_HAL_SWI defines to your compiler settings and then +// include implementations for both interfaces in the HAL. + +// At least one of these symbols will be defined in the project or makefile for each application +//#define ATCA_HAL_I2C +//#define ATCA_HAL_SWI +//#define ATCA_HAL_SPI +//#define ATCA_HAL_UART +//#define ATCA_HAL_KIT_HID +//#define ATCA_HAL_KIT_CDC + +// forward declare known physical layer APIs that must be implemented by the HAL layer (./hal/xyz) for this interface type + +#ifdef ATCA_HAL_I2C +ATCA_STATUS hal_i2c_init(void *hal, ATCAIfaceCfg *cfg); +ATCA_STATUS hal_i2c_post_init(ATCAIface iface); +ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t *txdata, int txlength); +ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength); +ATCA_STATUS hal_i2c_wake(ATCAIface iface); +ATCA_STATUS hal_i2c_idle(ATCAIface iface); +ATCA_STATUS hal_i2c_sleep(ATCAIface iface); +ATCA_STATUS hal_i2c_release(void *hal_data); +ATCA_STATUS hal_i2c_discover_buses(int i2c_buses[], int max_buses); +ATCA_STATUS hal_i2c_discover_devices(int bus_num, ATCAIfaceCfg *cfg, int *found); +#endif + +#ifdef ATCA_HAL_SWI +ATCA_STATUS hal_swi_init(void *hal, ATCAIfaceCfg *cfg); +ATCA_STATUS hal_swi_post_init(ATCAIface iface); +ATCA_STATUS hal_swi_send(ATCAIface iface, uint8_t *txdata, int txlength); +ATCA_STATUS hal_swi_receive(ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength); +ATCA_STATUS hal_swi_wake(ATCAIface iface); +ATCA_STATUS hal_swi_idle(ATCAIface iface); +ATCA_STATUS hal_swi_sleep(ATCAIface iface); +ATCA_STATUS hal_swi_release(void *hal_data); +ATCA_STATUS hal_swi_discover_buses(int swi_buses[], int max_buses); +ATCA_STATUS hal_swi_discover_devices(int bus_num, ATCAIfaceCfg *cfg, int *found); +#endif + +#ifdef ATCA_HAL_UART +ATCA_STATUS hal_uart_init(void *hal, ATCAIfaceCfg *cfg); +ATCA_STATUS hal_uart_post_init(ATCAIface iface); +ATCA_STATUS hal_uart_send(ATCAIface iface, uint8_t *txdata, int txlength); +ATCA_STATUS hal_uart_receive(ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength); +ATCA_STATUS hal_uart_wake(ATCAIface iface); +ATCA_STATUS hal_uart_idle(ATCAIface iface); +ATCA_STATUS hal_uart_sleep(ATCAIface iface); +ATCA_STATUS hal_uart_release(ATCAIface iface); +ATCA_STATUS hal_uart_discover_buses(int uart_buses[], int max_buses); +ATCA_STATUS hal_uart_discover_devices(int bus_num, ATCAIfaceCfg *cfg, int *found); +#endif + +#ifdef ATCA_HAL_KIT_CDC +ATCA_STATUS hal_kit_cdc_init(void *hal, ATCAIfaceCfg *cfg); +ATCA_STATUS hal_kit_cdc_post_init(ATCAIface iface); +ATCA_STATUS hal_kit_cdc_send(ATCAIface iface, uint8_t *txdata, int txlength); +ATCA_STATUS hal_kit_cdc_receive(ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength); +ATCA_STATUS hal_kit_cdc_wake(ATCAIface iface); +ATCA_STATUS hal_kit_cdc_idle(ATCAIface iface); +ATCA_STATUS hal_kit_cdc_sleep(ATCAIface iface); +ATCA_STATUS hal_kit_cdc_release(void *hal_data); +ATCA_STATUS hal_kit_cdc_discover_buses(int cdc_buses[], int max_buses); +ATCA_STATUS hal_kit_cdc_discover_devices(int bus_num, ATCAIfaceCfg *cfg, int *found); +#endif + +#ifdef ATCA_HAL_KIT_HID +ATCA_STATUS hal_kit_hid_init(void *hal, ATCAIfaceCfg *cfg); +ATCA_STATUS hal_kit_hid_post_init(ATCAIface iface); +ATCA_STATUS hal_kit_hid_send(ATCAIface iface, uint8_t *txdata, int txlength); +ATCA_STATUS hal_kit_hid_receive(ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength); +ATCA_STATUS hal_kit_hid_wake(ATCAIface iface); +ATCA_STATUS hal_kit_hid_idle(ATCAIface iface); +ATCA_STATUS hal_kit_hid_sleep(ATCAIface iface); +ATCA_STATUS hal_kit_hid_release(void *hal_data); +ATCA_STATUS hal_kit_hid_discover_buses(int hid_buses[], int max_buses); +ATCA_STATUS hal_kit_hid_discover_devices(int bus_num, ATCAIfaceCfg *cfg, int *found); +#endif + +/** \brief Timer API implemented at the HAL level */ +void atca_delay_us(uint32_t delay); +void atca_delay_10us(uint32_t delay); +void atca_delay_ms(uint32_t delay); + +/** \brief Optional hal interfaces */ +ATCA_STATUS hal_create_mutex(void ** ppMutex, char* pName); +ATCA_STATUS hal_destroy_mutex(void * pMutex); +ATCA_STATUS hal_lock_mutex(void * pMutex); +ATCA_STATUS hal_unlock_mutex(void * pMutex); + +/** \brief If an RTOS is being use make sure the delay definitions do not conflict */ +#ifdef ATCA_USE_RTOS_TIMER +void atca_delay_ms_internal(uint32_t delay); +#endif + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* ATCA_HAL_H_ */ diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.c new file mode 100644 index 0000000..6a14263 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.c @@ -0,0 +1,179 @@ + + +#include +#include "atca_hal.h" +#include "atca_i2c_hal.h" +#include "../atca_device.h" +#include "../atca_status.h" +#include "../../mcc.h" +#include "../../../mcc_generated_files/include/twi0_master.h" +#include "../../../mcc_generated_files/drivers/i2c_simple_master.h" + + + +/** \brief initialize an I2C interface using given config + * \param[in] hal - opaque ptr to HAL data + * \param[in] cfg - interface configuration + */ +uint8_t i2c_address = 0; + +ATCA_STATUS hal_i2c_init(void *hal, ATCAIfaceCfg *cfg) +{ + i2c_address = (cfg->atcai2c.slave_address) >> 1; + I2C0_Open(i2c_address); + + return ATCA_SUCCESS; +} + + +/** \brief HAL implementation of I2C post init + * \param[in] iface instance + * \return ATCA_SUCCESS + */ +ATCA_STATUS hal_i2c_post_init(ATCAIface iface) +{ + return ATCA_SUCCESS; +} + + +/** \brief HAL implementation of I2C send over ASF + * \param[in] iface instance + * \param[in] txdata pointer to space to bytes to send + * \param[in] txlength number of bytes to send + * \return ATCA_STATUS + */ + +ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t *txdata, int txlength) +{ + txdata[0] = 0x03; // insert the Word Address Value, Command token + txlength++; // account for word address value byte. + + i2c_writeNBytes(i2c_address, txdata, txlength); + + return ATCA_SUCCESS; +} + +/** \brief HAL implementation of I2C receive function for ASF I2C + * \param[in] iface instance + * \param[in] rxdata pointer to space to receive the data + * \param[in] rxlength ptr to expected number of receive bytes to request + * \return ATCA_STATUS + */ + +ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength) +{ + uint16_t rxdata_max_size = *rxlength; + + *rxlength = 0; + if (rxdata_max_size < 1) { + return ATCA_SMALL_BUFFER; + } + + *rxdata = 0; + i2c_readNBytes(i2c_address, rxdata, 1); + + if ((rxdata[0] < ATCA_RSP_SIZE_MIN) || (rxdata[0] > ATCA_RSP_SIZE_MAX)) { + return ATCA_INVALID_SIZE; + } + if (rxdata[0] > rxdata_max_size) { + return ATCA_SMALL_BUFFER; + } + + i2c_readNBytes(i2c_address, &rxdata[1], rxdata[0] - 1); + *rxlength = rxdata[0]; + + return ATCA_SUCCESS; +} + +/** \brief wake up CryptoAuth device using I2C bus + * \param[in] iface interface to logical device to wakeup + */ + +ATCA_STATUS hal_i2c_wake(ATCAIface iface) +{ + ATCAIfaceCfg *cfg = atgetifacecfg(iface); + uint32_t bdrt = cfg->atcai2c.baud; + uint8_t data[4]; + uint8_t zero_byte = 0; + + + i2c_writeNBytes(i2c_address, &zero_byte, 1); + + atca_delay_us(cfg->wake_delay); + + // receive the wake up response + i2c_readNBytes(i2c_address, data, 4); + + return hal_check_wake(data, 4); + +} + +/** \brief idle CryptoAuth device using I2C bus + * \param[in] iface interface to logical device to idle + */ + +ATCA_STATUS hal_i2c_idle(ATCAIface iface) +{ + uint8_t data = 0x02; + + i2c_writeNBytes(i2c_address, &data, 1); + + return ATCA_SUCCESS; +} + +/** \brief sleep CryptoAuth device using I2C bus + * \param[in] iface interface to logical device to sleep + */ + +ATCA_STATUS hal_i2c_sleep(ATCAIface iface) +{ + uint8_t data = 0x01; + + i2c_writeNBytes(i2c_address, &data, 1); + return ATCA_SUCCESS; +} + +/** \brief manages reference count on given bus and releases resource if no more refences exist + * \param[in] hal_data - opaque pointer to hal data structure - known only to the HAL implementation + * return ATCA_SUCCESS + */ + +ATCA_STATUS hal_i2c_release(void *hal_data) +{ + //TODO: For the moment, don't do anything + + return ATCA_SUCCESS; +} + +/** \brief discover i2c buses available for this hardware + * this maintains a list of logical to physical bus mappings freeing the application + * of the a-priori knowledge + * \param[in] i2c_buses - an array of logical bus numbers + * \param[in] max_buses - maximum number of buses the app wants to attempt to discover + * \return ATCA_SUCCESS + */ + +ATCA_STATUS hal_i2c_discover_buses(int i2c_buses[], int max_buses) +{ + + //TODO: For the moment, don't do anything + + return ATCA_SUCCESS; +} + +/** \brief discover any CryptoAuth devices on a given logical bus number + * \param[in] busNum logical bus number on which to look for CryptoAuth devices + * \param[out] cfg pointer to head of an array of interface config structures which get filled in by this method + * \param[out] found number of devices found on this bus + * \return ATCA_SUCCESS + */ + +ATCA_STATUS hal_i2c_discover_devices(int busNum, ATCAIfaceCfg cfg[], int *found) +{ + //TODO: For the moment, don't do anything + + return ATCA_SUCCESS; +} + + +/** @} */ diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.h new file mode 100644 index 0000000..280fef3 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.h @@ -0,0 +1,24 @@ + +#ifndef ATCA_I2C_HAL_H_ +#define ATCA_I2C_HAL_H_ + +/** \defgroup hal_ Hardware abstraction layer (hal_) + * + * \brief + * These methods define the hardware abstraction layer for communicating with a CryptoAuth device + * using I2C driver of ASF. + * + @{ */ + +ATCA_STATUS hal_i2c_init(void *hal, ATCAIfaceCfg *cfg); +ATCA_STATUS hal_i2c_post_init(ATCAIface iface); +ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t *txdata, int txlength); +ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength); +ATCA_STATUS hal_i2c_wake(ATCAIface iface); +ATCA_STATUS hal_i2c_idle(ATCAIface iface); +ATCA_STATUS hal_i2c_sleep(ATCAIface iface); +ATCA_STATUS hal_i2c_release(void *hal_data); + + +/** @} */ +#endif /* ATCA_I2C_HAL_H_ */ diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_start_config.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_start_config.h new file mode 100644 index 0000000..0dd4ce0 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_start_config.h @@ -0,0 +1,6 @@ +/* + this is a placeholder include used to satisfy the include + + when used with Atmel START, this file will be overwritten + with the user configuration generated by Atmel START + */ diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_start_iface.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_start_iface.h new file mode 100644 index 0000000..c290da9 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_start_iface.h @@ -0,0 +1,6 @@ +/* + this is a placeholder include used to satisfy the include + + when used with Atmel START, this file will be overwritten + with the user configuration generated by Atmel START + */ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.c new file mode 100644 index 0000000..1f86b09 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.c @@ -0,0 +1,45 @@ + +#include "../../config/clock_config.h" +#include + +/** \defgroup hal_ Hardware abstraction layer (hal_) + * + * \brief + * These methods define the hardware abstraction layer for communicating with a CryptoAuth device + * + @{ */ + +/** \brief This function delays for a number of microseconds. + * + * You can override this function if you like to do + * something else in your system while delaying. + * \param[in] delay number of microseconds to delay + */ +void atca_delay_us(uint32_t delay) +{ + /*Here you can write your own delay routine*/ + while (delay) { + _delay_us(1); + delay--; + } +} + +/** \brief This function delays for a number of milliseconds. + * + * You can override this function if you like to do + * something else in your system while delaying. + * \param[in] delay number of milliseconds to delay + */ +void atca_delay_ms(uint32_t delay) +{ + /*Here you can write your own delay routine*/ + while (delay) { + _delay_ms(1); + delay--; + } +} + + + + +/** @} */ diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.c new file mode 100644 index 0000000..b465ad3 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.c @@ -0,0 +1,1464 @@ +/** + * \file + * \brief Host side methods to support CryptoAuth computations + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_host.h" +#include "crypto/atca_crypto_sw_sha2.h" + + +/** \brief This function copies otp and sn data into a command buffer. + * + * \param[in, out] param pointer to parameter structure + * \return pointer to command buffer byte that was copied last + */ +uint8_t *atcah_include_data(struct atca_include_data_in_out *param) +{ + if (param->mode & MAC_MODE_INCLUDE_OTP_88) + { + memcpy(param->p_temp, param->otp, 11); // use OTP[0:10], Mode:5 is overridden + param->p_temp += 11; + } + else + { + if (param->mode & MAC_MODE_INCLUDE_OTP_64) + { + memcpy(param->p_temp, param->otp, 8); // use 8 bytes OTP[0:7] for (6) + } + else + { + memset(param->p_temp, 0, 8); // use 8 zeros for (6) + } + param->p_temp += 8; + + memset(param->p_temp, 0, 3); // use 3 zeros for (7) + param->p_temp += 3; + } + + // (8) 1 byte SN[8] + *param->p_temp++ = param->sn[8]; + + // (9) 4 bytes SN[4:7] or zeros + if (param->mode & MAC_MODE_INCLUDE_SN) + { + memcpy(param->p_temp, ¶m->sn[4], 4); //use SN[4:7] for (9) + } + else + { + memset(param->p_temp, 0, 4); //use zeros for (9) + } + param->p_temp += 4; + + // (10) 2 bytes SN[0:1] + *param->p_temp++ = param->sn[0]; + *param->p_temp++ = param->sn[1]; + + // (11) 2 bytes SN[2:3] or zeros + if (param->mode & MAC_MODE_INCLUDE_SN) + { + memcpy(param->p_temp, ¶m->sn[2], 2); //use SN[2:3] for (11) + } + else + { + memset(param->p_temp, 0, 2); //use zeros for (9) + } + param->p_temp += 2; + + return param->p_temp; +} + +/** \brief This function calculates host side nonce with the parameters passed. + * \param[in, out] param pointer to parameter structure + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_nonce(struct atca_nonce_in_out *param) +{ + uint8_t temporary[ATCA_MSG_SIZE_NONCE]; + uint8_t *p_temp; + uint8_t calc_mode = param->mode & NONCE_MODE_MASK; + + // Check parameters + if (param->temp_key == NULL || param->num_in == NULL) + { + return ATCA_BAD_PARAM; + } + + // Calculate or pass-through the nonce to TempKey->Value + if ((calc_mode == NONCE_MODE_SEED_UPDATE) || (calc_mode == NONCE_MODE_NO_SEED_UPDATE)) + { + // RandOut is only required for these modes + if (param->rand_out == NULL) + { + return ATCA_BAD_PARAM; + } + + if ((param->zero & NONCE_ZERO_CALC_MASK) == NONCE_ZERO_CALC_TEMPKEY) + { + // Nonce calculation mode. Actual value of TempKey has been returned in RandOut + memcpy(param->temp_key->value, param->rand_out, 32); + + // TempKey flags aren't changed + } + else + { + // Calculate nonce using SHA-256 (refer to data sheet) + p_temp = temporary; + + memcpy(p_temp, param->rand_out, RANDOM_NUM_SIZE); + p_temp += RANDOM_NUM_SIZE; + + memcpy(p_temp, param->num_in, NONCE_NUMIN_SIZE); + p_temp += NONCE_NUMIN_SIZE; + + *p_temp++ = ATCA_NONCE; + *p_temp++ = param->mode; + *p_temp++ = 0x00; + + // Calculate SHA256 to get the nonce + atcac_sw_sha2_256(temporary, ATCA_MSG_SIZE_NONCE, param->temp_key->value); + + // Update TempKey flags + param->temp_key->source_flag = 0; // Random + param->temp_key->key_id = 0; + param->temp_key->gen_dig_data = 0; + param->temp_key->no_mac_flag = 0; + param->temp_key->valid = 1; + } + + // Update TempKey to only 32 bytes + param->temp_key->is_64 = 0; + } + else if (param->mode == NONCE_MODE_PASSTHROUGH && (param->mode & NONCE_MODE_TARGET_MASK) != NONCE_MODE_TARGET_TEMPKEY) + { + // Pass-through mode for TempKey (other targets have no effect on TempKey) + if ((param->mode & NONCE_MODE_INPUT_LEN_MASK) == NONCE_MODE_INPUT_LEN_64) + { + memcpy(param->temp_key->value, param->num_in, 64); + param->temp_key->is_64 = 1; + } + else + { + memcpy(param->temp_key->value, param->num_in, 32); + param->temp_key->is_64 = 0; + } + + // Update TempKey flags + param->temp_key->source_flag = 1; // Not Random + param->temp_key->key_id = 0; + param->temp_key->gen_dig_data = 0; + param->temp_key->no_mac_flag = 0; + param->temp_key->valid = 1; + } + + return ATCA_SUCCESS; +} + +/** \brief Decrypt data that's been encrypted by the IO protection key. + * The ECDH and KDF commands on the ATECC608A are the only ones that + * support this operation. + * + * \param[inout] param Parameters required to perform the operation. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_io_decrypt(struct atca_io_decrypt_in_out *param) +{ + atcac_sha2_256_ctx ctx; + uint8_t key[ATCA_KEY_SIZE]; + size_t block = 0; + int i; + + if (param == NULL || param->io_key == NULL || param->out_nonce == NULL || param->data == NULL) + { + return ATCA_BAD_PARAM; + } + if (param->data_size % ATCA_BLOCK_SIZE != 0) + { + return ATCA_BAD_PARAM; + } + + for (block = 0; block < param->data_size / ATCA_BLOCK_SIZE; block++) + { + // Calculate key for block + atcac_sw_sha2_256_init(&ctx); + atcac_sw_sha2_256_update(&ctx, param->io_key, 32); + atcac_sw_sha2_256_update(&ctx, ¶m->out_nonce[block * 16], 16); + atcac_sw_sha2_256_finish(&ctx, key); + + // Decrypt block + for (i = 0; i < ATCA_BLOCK_SIZE; i++) + { + param->data[block * ATCA_BLOCK_SIZE + i] ^= key[i]; + } + } + + return ATCA_SUCCESS; +} + + +/** \brief Calculate the expected MAC on the host side for the Verify command. + * + * \param[inout] param Data required to perform the operation. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_verify_mac(atca_verify_mac_in_out_t *param) +{ + uint8_t verify_mode = (param->mode & VERIFY_MODE_MASK); + uint8_t verify_source = (param->mode & VERIFY_MODE_SOURCE_MASK); + atcac_sha2_256_ctx ctx; + uint8_t message[32]; + const uint8_t* nonce = NULL; + uint8_t input_params[4]; + const uint8_t sign_opcode = ATCA_SIGN; + + // Check parameters + if (param->signature == NULL || param->msg_dig_buf == NULL || param->io_key == NULL) + { + return ATCA_BAD_PARAM; + } + + // Get the verify message + if (verify_mode == VERIFY_MODE_VALIDATE || verify_mode == VERIFY_MODE_INVALIDATE) + { + if (param->other_data == NULL || param->temp_key == NULL || param->sn == NULL) + { + return ATCA_BAD_PARAM; + } + + // Message is calculated based on TempKey and OtherData + atcac_sw_sha2_256_init(&ctx); + atcac_sw_sha2_256_update(&ctx, param->temp_key->value, 32); + atcac_sw_sha2_256_update(&ctx, &sign_opcode, 1); + atcac_sw_sha2_256_update(&ctx, ¶m->other_data[0], 10); + atcac_sw_sha2_256_update(&ctx, ¶m->sn[8], 1); + atcac_sw_sha2_256_update(&ctx, ¶m->other_data[10], 4); + atcac_sw_sha2_256_update(&ctx, ¶m->sn[0], 2); + atcac_sw_sha2_256_update(&ctx, ¶m->other_data[14], 5); + atcac_sw_sha2_256_finish(&ctx, message); + } + else if (verify_source == VERIFY_MODE_SOURCE_MSGDIGBUF) + { + // Message source is the first 32 bytes of the message digest buffer + memcpy(message, param->msg_dig_buf, 32); + } + else + { + // Message source is the first 32 bytes of TempKey + if (param->temp_key == NULL) + { + return ATCA_BAD_PARAM; + } + memcpy(message, param->temp_key->value, 32); + } + + // Get the system nonce + if (verify_source == VERIFY_MODE_SOURCE_MSGDIGBUF) + { + nonce = ¶m->msg_dig_buf[32]; // System nonce is the second 32 bytes of the message digest buffer + } + else + { + nonce = ¶m->msg_dig_buf[0]; // System nonce is the first 32 bytes of the message digest buffer + + } + // Calculate MAC + atcac_sw_sha2_256_init(&ctx); + atcac_sw_sha2_256_update(&ctx, param->io_key, ATCA_KEY_SIZE); // IO protection key + atcac_sw_sha2_256_update(&ctx, message, 32); // Verify message + atcac_sw_sha2_256_update(&ctx, nonce, 32); // Host (system) nonce + atcac_sw_sha2_256_update(&ctx, param->signature, 64); // Signature + + // Add Verify input parameters + input_params[0] = ATCA_VERIFY; // Verify Opcode + input_params[1] = param->mode; // Verify Mode (Param1) + input_params[2] = (uint8_t)(param->key_id >> 0); // Verify Param2 (LSB) + input_params[3] = (uint8_t)(param->key_id >> 8); // Verify Param2 (MSB) + atcac_sw_sha2_256_update(&ctx, input_params, sizeof(input_params)); + + // Calculate SHA256 to get mac + atcac_sw_sha2_256_finish(&ctx, param->mac); + + return ATCA_SUCCESS; +} + +/** \brief Encrypts the digest for the SecureBoot command when using the + * encrypted digest / validating mac option. + * + * \param[inout] param Data required to perform the operation. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_secureboot_enc(atca_secureboot_enc_in_out_t* param) +{ + atcac_sha2_256_ctx ctx; + size_t i; + + // Check parameters + if (param->digest == NULL || param->temp_key == NULL || param->hashed_key == NULL || param->io_key == NULL || param->digest_enc == NULL) + { + return ATCA_BAD_PARAM; + } + + // Calculate key for encrypting digest + atcac_sw_sha2_256_init(&ctx); + atcac_sw_sha2_256_update(&ctx, param->io_key, ATCA_KEY_SIZE); + atcac_sw_sha2_256_update(&ctx, param->temp_key->value, ATCA_KEY_SIZE); + atcac_sw_sha2_256_finish(&ctx, param->hashed_key); + + // Encrypt digest (XOR with key) + for (i = 0; i < SECUREBOOT_DIGEST_SIZE; i++) + { + param->digest_enc[i] = param->digest[i] ^ param->hashed_key[i]; + } + + return ATCA_SUCCESS; +} + +/** \brief Calculates the expected MAC returned from the SecureBoot command + * when verification is a success. + * + * The result of this function (param->mac) should be compared with the actual + * MAC returned to validate the response. + * + * \param[inout] param Data required to perform the operation. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_secureboot_mac(atca_secureboot_mac_in_out_t *param) +{ + atcac_sha2_256_ctx ctx; + uint8_t input_params[4]; + + if (param->hashed_key == NULL || param->digest == NULL || param->mac == NULL) + { + return ATCA_BAD_PARAM; + } + + // Calculate MAC + atcac_sw_sha2_256_init(&ctx); + atcac_sw_sha2_256_update(&ctx, param->hashed_key, ATCA_KEY_SIZE); + atcac_sw_sha2_256_update(&ctx, param->digest, SECUREBOOT_DIGEST_SIZE); + + // Signature is only skipped when running the SecureBoot command in + // FullStore mode and SecureBootMode from the configuration zone is set to + // FullDig + if (!((param->mode & SECUREBOOT_MODE_MASK) == SECUREBOOT_MODE_FULL_STORE && + (param->secure_boot_config & SECUREBOOTCONFIG_MODE_MASK) == SECUREBOOTCONFIG_MODE_FULL_DIG)) + { + if (param->signature == NULL) + { + return ATCA_BAD_PARAM; + } + atcac_sw_sha2_256_update(&ctx, param->signature, SECUREBOOT_SIGNATURE_SIZE); + } + + // Add SecureBoot input parameters + input_params[0] = ATCA_SECUREBOOT; // SecureBoot Opcode + input_params[1] = param->mode; // SecureBoot Mode (Param1) + input_params[2] = (uint8_t)(param->param2 >> 0); // SecureBoot Param2 (LSB) + input_params[3] = (uint8_t)(param->param2 >> 8); // SecureBoot Param2 (MSB) + atcac_sw_sha2_256_update(&ctx, input_params, sizeof(input_params)); + + atcac_sw_sha2_256_finish(&ctx, param->mac); + + return ATCA_SUCCESS; +} + + + +/** \brief This function generates an SHA-256 digest (MAC) of a key, challenge, and other information. + + The resulting digest will match with the one generated by the device when executing a MAC command. + The TempKey (if used) should be valid (temp_key.valid = 1) before executing this function. + + * \param[in, out] param pointer to parameter structure + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_mac(struct atca_mac_in_out *param) +{ + uint8_t temporary[ATCA_MSG_SIZE_MAC]; + uint8_t *p_temp; + struct atca_include_data_in_out include_data; + + // Initialize struct + include_data.otp = param->otp; + include_data.sn = param->sn; + include_data.mode = param->mode; + + // Check parameters + if (!param->response + || (param->mode & ~MAC_MODE_MASK) + || (!(param->mode & MAC_MODE_BLOCK1_TEMPKEY) && !param->key) + || (!(param->mode & MAC_MODE_BLOCK2_TEMPKEY) && !param->challenge) + || ((param->mode & MAC_MODE_USE_TEMPKEY_MASK) && !param->temp_key) + || (((param->mode & MAC_MODE_INCLUDE_OTP_64) || (param->mode & MAC_MODE_INCLUDE_OTP_88)) && !param->otp) + || ((param->mode & MAC_MODE_INCLUDE_SN) && !param->sn) + ) + { + return ATCA_BAD_PARAM; + } + + // Check TempKey fields validity if TempKey is used + if (((param->mode & MAC_MODE_USE_TEMPKEY_MASK) != 0) + // TempKey.CheckFlag must be 0 and TempKey.Valid must be 1 + && (param->temp_key->no_mac_flag || (param->temp_key->valid != 1) + // If either mode parameter bit 0 or bit 1 are set, mode parameter bit 2 must match temp_key.source_flag. + // Logical not (!) is used to evaluate the expression to TRUE / FALSE first before comparison (!=). + || (!(param->mode & MAC_MODE_SOURCE_FLAG_MATCH) != !(param->temp_key->source_flag))) + ) + { + // Invalidate TempKey, then return + param->temp_key->valid = 0; + return ATCA_EXECUTION_ERROR; + } + + // Start calculation + p_temp = temporary; + + // (1) first 32 bytes + memcpy(p_temp, param->mode & MAC_MODE_BLOCK1_TEMPKEY ? param->temp_key->value : param->key, ATCA_KEY_SIZE); // use Key[KeyID] + p_temp += ATCA_KEY_SIZE; + + // (2) second 32 bytes + memcpy(p_temp, param->mode & MAC_MODE_BLOCK2_TEMPKEY ? param->temp_key->value : param->challenge, ATCA_KEY_SIZE); // use Key[KeyID] + p_temp += ATCA_KEY_SIZE; + + // (3) 1 byte opcode + *p_temp++ = ATCA_MAC; + + // (4) 1 byte mode parameter + *p_temp++ = param->mode; + + // (5) 2 bytes keyID + *p_temp++ = param->key_id & 0xFF; + *p_temp++ = (param->key_id >> 8) & 0xFF; + + include_data.p_temp = p_temp; + atcah_include_data(&include_data); + + // Calculate SHA256 to get the MAC digest + atcac_sw_sha2_256(temporary, ATCA_MSG_SIZE_MAC, param->response); + + // Update TempKey fields + if (param->temp_key) + { + param->temp_key->valid = 0; + } + + return ATCA_SUCCESS; +} + + + + +/** \brief This function performs the checkmac operation to generate client response on the host side . + * \param[inout] param Input and output parameters + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_check_mac(struct atca_check_mac_in_out *param) +{ + uint8_t msg[ATCA_MSG_SIZE_MAC]; + bool is_temp_key_req = false; + + // Check parameters + if (param == NULL || param->other_data == NULL || param->sn == NULL || param->client_resp == NULL) + { + return ATCA_BAD_PARAM; + } + + if ((param->mode & CHECKMAC_MODE_BLOCK1_TEMPKEY) || (param->mode & CHECKMAC_MODE_BLOCK2_TEMPKEY)) + { + is_temp_key_req = true; // Message uses TempKey + } + else if ((param->mode == 0x01 || param->mode == 0x05) && param->target_key != NULL) + { + is_temp_key_req = true; // CheckMac copy will be performed + + } + if (is_temp_key_req && param->temp_key == NULL) + { + return ATCA_BAD_PARAM; + } + if (!(param->mode & CHECKMAC_MODE_BLOCK1_TEMPKEY) && param->slot_key == NULL) + { + return ATCA_BAD_PARAM; + } + if (!(param->mode & CHECKMAC_MODE_BLOCK2_TEMPKEY) && param->client_chal == NULL) + { + return ATCA_BAD_PARAM; + } + if ((param->mode & CHECKMAC_MODE_INCLUDE_OTP_64) && param->otp == NULL) + { + return ATCA_BAD_PARAM; + } + + if ((param->mode & CHECKMAC_MODE_BLOCK1_TEMPKEY) || (param->mode & CHECKMAC_MODE_BLOCK2_TEMPKEY)) + { + // This will use TempKey in message, check validity + if (!param->temp_key->valid) + { + return ATCA_EXECUTION_ERROR; // TempKey is not valid + } + if (((param->mode >> 2) & 0x01) != param->temp_key->source_flag) + { + return ATCA_EXECUTION_ERROR; // TempKey SourceFlag doesn't match bit 2 of the mode + } + } + + // Build the message + memset(msg, 0, sizeof(msg)); + if (param->mode & CHECKMAC_MODE_BLOCK1_TEMPKEY) + { + memcpy(&msg[0], param->temp_key->value, 32); + } + else + { + memcpy(&msg[0], param->slot_key, 32); + } + if (param->mode & CHECKMAC_MODE_BLOCK2_TEMPKEY) + { + memcpy(&msg[32], param->temp_key->value, 32); + } + else + { + memcpy(&msg[32], param->client_chal, 32); + } + memcpy(&msg[64], ¶m->other_data[0], 4); + if (param->mode & CHECKMAC_MODE_INCLUDE_OTP_64) + { + memcpy(&msg[68], param->otp, 8); + } + memcpy(&msg[76], ¶m->other_data[4], 3); + msg[79] = param->sn[8]; + memcpy(&msg[80], ¶m->other_data[7], 4); + memcpy(&msg[84], ¶m->sn[0], 2); + memcpy(&msg[86], ¶m->other_data[11], 2); + + // Calculate the client response + atcac_sw_sha2_256(msg, sizeof(msg), param->client_resp); + + // Update TempKey fields + if ((param->mode == 0x01 || param->mode == 0x05) && param->target_key != NULL) + { + // CheckMac Copy will be performed + memcpy(param->temp_key->value, param->target_key, ATCA_KEY_SIZE); + param->temp_key->gen_dig_data = 0; + param->temp_key->source_flag = 1; + param->temp_key->valid = 1; + } + + return ATCA_SUCCESS; +} + + +/** \brief This function generates an HMAC / SHA-256 hash of a key and other information. + + The resulting hash will match with the one generated in the device by an HMAC command. + The TempKey has to be valid (temp_key.valid = 1) before executing this function. + + * \param[in, out] param pointer to parameter structure + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_hmac(struct atca_hmac_in_out *param) +{ + // Local Variables + struct atca_include_data_in_out include_data; + uint8_t temporary[HMAC_BLOCK_SIZE + ATCA_MSG_SIZE_HMAC]; + uint8_t i = 0; + uint8_t *p_temp = NULL; + + // Check parameters + if (!param->response || !param->key || !param->temp_key + || (param->mode & ~HMAC_MODE_MASK) + || (((param->mode & MAC_MODE_INCLUDE_OTP_64) || (param->mode & MAC_MODE_INCLUDE_OTP_88)) && !param->otp) + || (!param->sn) + ) + { + return ATCA_BAD_PARAM; + } + + // Check TempKey fields validity (TempKey is always used) + if ( // TempKey.CheckFlag must be 0 and TempKey.Valid must be 1 + param->temp_key->no_mac_flag || (param->temp_key->valid != 1) + // The mode parameter bit 2 must match temp_key.source_flag. + // Logical not (!) is used to evaluate the expression to TRUE / FALSE first before comparison (!=). + || (!(param->mode & MAC_MODE_SOURCE_FLAG_MATCH) != !(param->temp_key->source_flag)) + ) + { + // Invalidate TempKey, then return + param->temp_key->valid = 0; + return ATCA_EXECUTION_ERROR; + } + + // Start first calculation (inner) + p_temp = temporary; + + // XOR key with ipad + for (i = 0; i < ATCA_KEY_SIZE; i++) + { + *p_temp++ = param->key[i] ^ 0x36; + } + + // zero pad key out to block size + // Refer to fips-198 , length Key = 32 bytes, Block size = 512 bits = 64 bytes. + // So the Key must be padded with zeros. + memset(p_temp, 0x36, HMAC_BLOCK_SIZE - ATCA_KEY_SIZE); + p_temp += HMAC_BLOCK_SIZE - ATCA_KEY_SIZE; + + // Next append the stream of data 'text' + memset(p_temp, 0, ATCA_KEY_SIZE); + p_temp += ATCA_KEY_SIZE; + + memcpy(p_temp, param->temp_key->value, ATCA_KEY_SIZE); + p_temp += ATCA_KEY_SIZE; + + *p_temp++ = ATCA_HMAC; + *p_temp++ = param->mode; + *p_temp++ = (uint8_t)(param->key_id >> 0); + *p_temp++ = (uint8_t)(param->key_id >> 8); + + include_data.otp = param->otp; + include_data.sn = param->sn; + include_data.mode = param->mode; + include_data.p_temp = p_temp; + atcah_include_data(&include_data); + + // Calculate SHA256 + // H((K0^ipad):text), use param.response for temporary storage + atcac_sw_sha2_256(temporary, HMAC_BLOCK_SIZE + ATCA_MSG_SIZE_HMAC, param->response); + + + // Start second calculation (outer) + p_temp = temporary; + + // XOR K0 with opad + for (i = 0; i < ATCA_KEY_SIZE; i++) + { + *p_temp++ = param->key[i] ^ 0x5C; + } + + // zero pad key out to block size + // Refer to fips-198 , length Key = 32 bytes, Block size = 512 bits = 64 bytes. + // So the Key must be padded with zeros. + memset(p_temp, 0x5C, HMAC_BLOCK_SIZE - ATCA_KEY_SIZE); + p_temp += HMAC_BLOCK_SIZE - ATCA_KEY_SIZE; + + // Append result from last calculation H((K0 ^ ipad) || text) + memcpy(p_temp, param->response, ATCA_SHA_DIGEST_SIZE); + p_temp += ATCA_SHA_DIGEST_SIZE; + + // Calculate SHA256 to get the resulting HMAC + atcac_sw_sha2_256(temporary, HMAC_BLOCK_SIZE + ATCA_SHA_DIGEST_SIZE, param->response); + + // Update TempKey fields + param->temp_key->valid = 0; + + return ATCA_SUCCESS; +} + + +/** \brief This function combines the current TempKey with a stored value. + + The stored value can be a data slot, OTP page, configuration zone, or hardware transport key. + The TempKey generated by this function will match with the TempKey in the device generated + when executing a GenDig command. + The TempKey should be valid (temp_key.valid = 1) before executing this function. + To use this function, an application first sends a GenDig command with a chosen stored value to the device. + This stored value must be known by the application and is passed to this GenDig calculation function. + The function calculates a new TempKey and returns it. + + * \param[in, out] param pointer to parameter structure + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_gen_dig(struct atca_gen_dig_in_out *param) +{ + uint8_t temporary[ATCA_MSG_SIZE_GEN_DIG]; + uint8_t *p_temp; + + // Check parameters + if (param->sn == NULL || param->temp_key == NULL) + { + return ATCA_BAD_PARAM; + } + if (param->zone != GENDIG_ZONE_SHARED_NONCE && param->stored_value == NULL) + { + return ATCA_BAD_PARAM; // Stored value can only be null with the shared_nonce mode + } + if ((param->zone == GENDIG_ZONE_SHARED_NONCE || (param->zone == GENDIG_ZONE_DATA && param->is_key_nomac)) && param->other_data == NULL) + { + return ATCA_BAD_PARAM; // Other data is required in these cases + } + if (param->zone > 5) + { + return ATCA_BAD_PARAM; // Unknown zone + + } + // Start calculation + p_temp = temporary; + + // (1) 32 bytes inputKey + if (param->zone == GENDIG_ZONE_SHARED_NONCE && param->key_id & 0x8000) + { + memcpy(p_temp, param->other_data, ATCA_KEY_SIZE); + } + else + { + memcpy(p_temp, param->stored_value, ATCA_KEY_SIZE); + } + p_temp += ATCA_KEY_SIZE; + + if (param->zone == GENDIG_ZONE_DATA && param->is_key_nomac) + { + // If a key has the SlotConfig.NoMac bit set, then opcode and parameters come from OtherData + memcpy(p_temp, param->other_data, 4); + p_temp += 4; + } + else + { + // (2) 1 byte Opcode + *p_temp++ = ATCA_GENDIG; + + // (3) 1 byte Param1 (zone) + *p_temp++ = param->zone; + + // (4) 2 bytes Param2 (keyID) + *p_temp++ = (uint8_t)(param->key_id & 0xFF); + *p_temp++ = (uint8_t)(param->key_id >> 8); + } + + // (5) 1 byte SN[8] + *p_temp++ = param->sn[8]; + + // (6) 2 bytes SN[0:1] + *p_temp++ = param->sn[0]; + *p_temp++ = param->sn[1]; + + // (7) 25 zeros + memset(p_temp, 0, ATCA_GENDIG_ZEROS_SIZE); + p_temp += ATCA_GENDIG_ZEROS_SIZE; + + if (param->zone == GENDIG_ZONE_SHARED_NONCE && !(param->key_id & 0x8000)) + { + memcpy(p_temp, param->other_data, ATCA_KEY_SIZE); // (8) 32 bytes OtherData + } + else + { + memcpy(p_temp, param->temp_key->value, ATCA_KEY_SIZE); // (8) 32 bytes TempKey + + } + // Calculate SHA256 to get the new TempKey + atcac_sw_sha2_256(temporary, ATCA_MSG_SIZE_GEN_DIG, param->temp_key->value); + + // Update TempKey fields + param->temp_key->valid = 1; + + if ((param->zone == GENDIG_ZONE_DATA) && (param->key_id <= 15)) + { + param->temp_key->gen_dig_data = 1; + param->temp_key->key_id = (param->key_id & 0xF); // mask lower 4-bit only + } + else + { + param->temp_key->gen_dig_data = 0; + param->temp_key->key_id = 0; + } + + return ATCA_SUCCESS; +} + +/** \brief This function generates mac with session key with a plain text. + * \param[in, out] param pointer to parameter structure + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_gen_mac(struct atca_gen_dig_in_out *param) +{ + uint8_t temporary[ATCA_MSG_SIZE_GEN_DIG]; + uint8_t *p_temp; + + // Check parameters + if (!param->stored_value || !param->temp_key) + { + return ATCA_BAD_PARAM; + } + + // Check TempKey fields validity (TempKey is always used) + if ( // TempKey.CheckFlag must be 0 and TempKey.Valid must be 1 + param->temp_key->no_mac_flag || (param->temp_key->valid != 1) + ) + { + // Invalidate TempKey, then return + param->temp_key->valid = 0; + return ATCA_EXECUTION_ERROR; + } + + // Start calculation + p_temp = temporary; + + // (1) 32 bytes SessionKey + // (Config[KeyID] or OTP[KeyID] or Data.slot[KeyID] or TransportKey[KeyID]) + memcpy(p_temp, param->temp_key->value, ATCA_KEY_SIZE); + p_temp += ATCA_KEY_SIZE; + + // (2) 1 byte Opcode + *p_temp++ = ATCA_WRITE; + + // (3) 1 byte Param1 (zone) + *p_temp++ = param->zone; + + // (4) 2 bytes Param2 (keyID) + *p_temp++ = param->key_id & 0xFF; + *p_temp++ = (param->key_id >> 8) & 0xFF; + + // (5) 1 byte SN[8] + *p_temp++ = param->sn[8]; + + // (6) 2 bytes SN[0:1] + *p_temp++ = param->sn[0]; + *p_temp++ = param->sn[1]; + + // (7) 25 zeros + memset(p_temp, 0, ATCA_GENDIG_ZEROS_SIZE); + p_temp += ATCA_GENDIG_ZEROS_SIZE; + + // (8) 32 bytes PlainText + memcpy(p_temp, param->stored_value, ATCA_KEY_SIZE); + + // Calculate SHA256 to get the new TempKey + atcac_sw_sha2_256(temporary, ATCA_MSG_SIZE_GEN_DIG, param->temp_key->value); + + // Update TempKey fields + param->temp_key->valid = 1; + + if ((param->zone == GENDIG_ZONE_DATA) && (param->key_id <= 15)) + { + param->temp_key->gen_dig_data = 1; + param->temp_key->key_id = (param->key_id & 0xF); // mask lower 4-bit only + } + else + { + param->temp_key->gen_dig_data = 0; + param->temp_key->key_id = 0; + } + + return ATCA_SUCCESS; +} + +/** \brief This function calculates the input MAC for the Write command. + + The Write command will need an input MAC if SlotConfig.WriteConfig.Encrypt is set. + + * \param[in, out] param pointer to parameter structure + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_write_auth_mac(struct atca_write_mac_in_out *param) +{ + uint8_t mac_input[ATCA_MSG_SIZE_ENCRYPT_MAC]; + uint8_t i; + uint8_t *p_temp; + + // Check parameters + if (!param->input_data || !param->temp_key) + { + return ATCA_BAD_PARAM; + } + + // Check TempKey fields validity (TempKey is always used) + if ( // TempKey.CheckFlag must be 0 and TempKey.Valid must be 1 + param->temp_key->no_mac_flag || (param->temp_key->valid != 1) + ) + { + // Invalidate TempKey, then return + param->temp_key->valid = 0; + return ATCA_EXECUTION_ERROR; + } + // Encrypt by XOR-ing Data with the TempKey + for (i = 0; i < 32; i++) + { + param->encrypted_data[i] = param->input_data[i] ^ param->temp_key->value[i]; + } + + // If the pointer *mac is provided by the caller then calculate input MAC + if (param->auth_mac) + { + // Start calculation + p_temp = mac_input; + + // (1) 32 bytes TempKey + memcpy(p_temp, param->temp_key->value, ATCA_KEY_SIZE); + p_temp += ATCA_KEY_SIZE; + + // (2) 1 byte Opcode + *p_temp++ = ATCA_WRITE; + + // (3) 1 byte Param1 (zone) + *p_temp++ = param->zone; + + // (4) 2 bytes Param2 (keyID) + *p_temp++ = param->key_id & 0xFF; + *p_temp++ = (param->key_id >> 8) & 0xFF; + + // (5) 1 byte SN[8] + *p_temp++ = param->sn[8]; + + // (6) 2 bytes SN[0:1] + *p_temp++ = param->sn[0]; + *p_temp++ = param->sn[1]; + + // (7) 25 zeros + memset(p_temp, 0, ATCA_WRITE_MAC_ZEROS_SIZE); + p_temp += ATCA_WRITE_MAC_ZEROS_SIZE; + + // (8) 32 bytes PlainText + memcpy(p_temp, param->input_data, ATCA_KEY_SIZE); + + // Calculate SHA256 to get MAC + atcac_sw_sha2_256(mac_input, sizeof(mac_input), param->auth_mac); + } + + return ATCA_SUCCESS; +} + +/** \brief This function calculates the input MAC for the PrivWrite command. + + The PrivWrite command will need an input MAC if SlotConfig.WriteConfig.Encrypt is set. + + * \param[in, out] param pointer to parameter structure + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_privwrite_auth_mac(struct atca_write_mac_in_out *param) +{ + uint8_t mac_input[ATCA_MSG_SIZE_PRIVWRITE_MAC]; + uint8_t i = 0; + uint8_t *p_temp = NULL; + uint8_t session_key2[32]; + + // Check parameters + if (!param->input_data || !param->temp_key) + { + return ATCA_BAD_PARAM; + } + + // Check TempKey fields validity (TempKey is always used) + if ( // TempKey.CheckFlag must be 0 and TempKey.Valid must be 1 + param->temp_key->no_mac_flag || (param->temp_key->valid != 1) + ) + { + // Invalidate TempKey, then return + param->temp_key->valid = 0; + return ATCA_EXECUTION_ERROR; + } + + + /* Encrypt by XOR-ing Data with the TempKey + */ + + // Encrypt the next 28 bytes of the cipher text, which is the first part of the private key. + for (i = 0; i < 32; i++) + { + param->encrypted_data[i] = param->input_data[i] ^ param->temp_key->value[i]; + } + + // Calculate the new key for the last 4 bytes of the cipher text + atcac_sw_sha2_256(param->temp_key->value, 32, session_key2); + + // Encrypt the last 4 bytes of the cipher text, which is the remaining part of the private key + for (i = 32; i < 36; i++) + { + param->encrypted_data[i] = param->input_data[i] ^ session_key2[i - 32]; + } + + // If the pointer *mac is provided by the caller then calculate input MAC + if (param->auth_mac) + { + // Start calculation + p_temp = mac_input; + + // (1) 32 bytes TempKey + memcpy(p_temp, param->temp_key->value, ATCA_KEY_SIZE); + p_temp += ATCA_KEY_SIZE; + + // (2) 1 byte Opcode + *p_temp++ = ATCA_PRIVWRITE; + + // (3) 1 byte Param1 (zone) + *p_temp++ = param->zone; + + // (4) 2 bytes Param2 (keyID) + *p_temp++ = param->key_id & 0xFF; + *p_temp++ = (param->key_id >> 8) & 0xFF; + + // (5) 1 byte SN[8] + *p_temp++ = param->sn[8]; + + // (6) 2 bytes SN[0:1] + *p_temp++ = param->sn[0]; + *p_temp++ = param->sn[1]; + + // (7) 21 zeros + memset(p_temp, 0, ATCA_PRIVWRITE_MAC_ZEROS_SIZE); + p_temp += ATCA_PRIVWRITE_MAC_ZEROS_SIZE; + + // (8) 36 bytes PlainText (Private Key) + memcpy(p_temp, param->input_data, ATCA_PRIVWRITE_PLAIN_TEXT_SIZE); + + // Calculate SHA256 to get the new TempKey + atcac_sw_sha2_256(mac_input, sizeof(mac_input), param->auth_mac); + } + + return ATCA_SUCCESS; +} + +/** \brief This function derives a key with a key and TempKey. + + Used in conjunction with DeriveKey command, the key derived by this function will match the key in the device. + Two kinds of operation are supported: +
    +
  • Roll Key operation: target_key and parent_key parameters should be set to point to the same location (TargetKey).
  • +
  • Create Key operation: target_key should be set to point to TargetKey, parent_key should be set to point to ParentKey.
  • +
+ After executing this function, the initial value of target_key will be overwritten with the derived key. + The TempKey should be valid (temp_key.valid = 1) before executing this function. + + * \param[in, out] param pointer to parameter structure + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_derive_key(struct atca_derive_key_in_out *param) +{ + uint8_t temporary[ATCA_MSG_SIZE_DERIVE_KEY]; + uint8_t *p_temp; + + // Check parameters + if (!param->parent_key || !param->target_key || !param->temp_key + || (param->mode & ~DERIVE_KEY_RANDOM_FLAG) || (param->target_key_id > ATCA_KEY_ID_MAX)) + { + return ATCA_BAD_PARAM; + } + + + // Check TempKey fields validity (TempKey is always used) + if ( // TempKey.CheckFlag must be 0 and TempKey.Valid must be 1 + param->temp_key->no_mac_flag || (param->temp_key->valid != 1) + // The random parameter bit 2 must match temp_key.source_flag + // Logical not (!) is used to evaluate the expression to TRUE / FALSE first before comparison (!=). + || (!(param->mode & DERIVE_KEY_RANDOM_FLAG) != !(param->temp_key->source_flag)) + ) + { + // Invalidate TempKey, then return + param->temp_key->valid = 0; + return ATCA_EXECUTION_ERROR; + } + + // Start calculation + p_temp = temporary; + + // (1) 32 bytes parent key + memcpy(p_temp, param->parent_key, ATCA_KEY_SIZE); + p_temp += ATCA_KEY_SIZE; + + // (2) 1 byte Opcode + *p_temp++ = ATCA_DERIVE_KEY; + + // (3) 1 byte Param1 (random) + *p_temp++ = param->mode; + + // (4) 2 bytes Param2 (keyID) + *p_temp++ = param->target_key_id & 0xFF; + *p_temp++ = (param->target_key_id >> 8) & 0xFF; + + // (5) 1 byte SN[8] + *p_temp++ = param->sn[8]; + + // (6) 2 bytes SN[0:1] + *p_temp++ = param->sn[0]; + *p_temp++ = param->sn[1]; + + // (7) 25 zeros + memset(p_temp, 0, ATCA_DERIVE_KEY_ZEROS_SIZE); + p_temp += ATCA_DERIVE_KEY_ZEROS_SIZE; + + // (8) 32 bytes TempKey + memcpy(p_temp, param->temp_key->value, ATCA_KEY_SIZE); + p_temp += ATCA_KEY_SIZE; + + // Calculate SHA256 to get the derived key. + atcac_sw_sha2_256(temporary, ATCA_MSG_SIZE_DERIVE_KEY, param->target_key); + + // Update TempKey fields + param->temp_key->valid = 0; + + return ATCA_SUCCESS; +} + + +/** \brief This function calculates the input MAC for a DeriveKey command. + + The DeriveKey command will need an input MAC if SlotConfig[TargetKey].Bit15 is set. + + * \param[in, out] param pointer to parameter structure + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_derive_key_mac(struct atca_derive_key_mac_in_out *param) +{ + uint8_t temporary[ATCA_MSG_SIZE_DERIVE_KEY_MAC]; + uint8_t *p_temp; + + // Check parameters + if (!param->parent_key || !param->mac || (param->mode & ~DERIVE_KEY_RANDOM_FLAG) + || (param->target_key_id > ATCA_KEY_ID_MAX)) + { + return ATCA_BAD_PARAM; + } + + // Start calculation + p_temp = temporary; + + // (1) 32 bytes parent key + memcpy(p_temp, param->parent_key, ATCA_KEY_SIZE); + p_temp += ATCA_KEY_SIZE; + + // (2) 1 byte Opcode + *p_temp++ = ATCA_DERIVE_KEY; + + // (3) 1 byte Param1 (random) + *p_temp++ = param->mode; + + // (4) 2 bytes Param2 (keyID) + *p_temp++ = param->target_key_id & 0xFF; + *p_temp++ = (param->target_key_id >> 8) & 0xFF; + + // (5) 1 byte SN[8] + *p_temp++ = param->sn[8]; + + // (6) 2 bytes SN[0:1] + *p_temp++ = param->sn[0]; + *p_temp++ = param->sn[1]; + + // Calculate SHA256 to get the input MAC for DeriveKey command + atcac_sw_sha2_256(temporary, ATCA_MSG_SIZE_DERIVE_KEY_MAC, param->mac); + + return ATCA_SUCCESS; +} + + +/** \brief This function decrypts 32-byte encrypted data received with the Read command. + + To use this function, first the nonce must be valid and synchronized between device and application. + The application sends a GenDig command to the Device, using a key specified by SlotConfig.ReadKey. + The device updates its TempKey. + The application then updates its own TempKey using the GenDig calculation function, using the same key. + The application sends a Read command to the device for a user zone configured with EncryptRead. + The device encrypts 32-byte zone content, and outputs it to the host. + The application passes these encrypted data to this decryption function. The function decrypts the data and returns them. + TempKey must be updated by GenDig using a ParentKey as specified by SlotConfig.ReadKey before executing this function. + The decryption function does not check whether the TempKey has been generated by a correct ParentKey for the corresponding zone. + Therefore to get a correct result, the application has to make sure that prior GenDig calculation was done using correct ParentKey. + + * \param[in, out] param pointer to parameter structure + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_decrypt(struct atca_decrypt_in_out *param) +{ + uint8_t i; + + // Check parameters + if (!param->crypto_data || !param->temp_key) + { + return ATCA_BAD_PARAM; + } + + // Check TempKey fields validity + // Note that if temp_key.key_id is not checked, + // we cannot make sure if the key used in previous GenDig IS equal to + // the key pointed by SlotConfig.ReadKey in the device. + if ( // TempKey.CheckFlag must be 0 + param->temp_key->no_mac_flag + // TempKey.Valid must be 1 + || (param->temp_key->valid != 1) + // TempKey.GenData must be 1 + || (param->temp_key->gen_dig_data != 1) + // TempKey.SourceFlag must be 0 (random) + || param->temp_key->source_flag + ) + { + // Invalidate TempKey, then return + param->temp_key->valid = 0; + return ATCA_EXECUTION_ERROR; + } + + // Decrypt by XOR-ing Data with the TempKey + for (i = 0; i < ATCA_KEY_SIZE; i++) + { + param->crypto_data[i] ^= param->temp_key->value[i]; + } + + // Update TempKey fields + param->temp_key->valid = 0; + + return ATCA_SUCCESS; +} + +/** \brief This function creates a SHA256 digest on a little-endian system. + * + * \param[in] len byte length of message + * \param[in] message pointer to message + * \param[out] digest SHA256 of message + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_sha256(int32_t len, const uint8_t *message, uint8_t *digest) +{ + return atcac_sw_sha2_256(message, len, digest); +} + +/** \brief Calculate the PubKey digest created by GenKey and saved to TempKey. + * + * \param[inout] param GenKey parameters required to calculate the PubKey + * digest. Digest is return in the temp_key parameter. + * + \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_gen_key_msg(struct atca_gen_key_in_out *param) +{ + uint8_t msg[128]; + + if (param == NULL || param->public_key == NULL || param->sn == NULL || param->temp_key == NULL) + { + return ATCA_BAD_PARAM; + } + if (param->public_key_size == 0 || param->public_key_size > 88) + { + return ATCA_BAD_PARAM; + } + + memset(msg, 0, sizeof(msg)); + memcpy(&msg[0], param->temp_key->value, 32); + msg[32] = ATCA_GENKEY; + + if (param->mode & GENKEY_MODE_PUBKEY_DIGEST) + { + // Calculate PubKey digest of stored public key, takes priority over other bits + if (param->other_data == NULL) + { + return ATCA_BAD_PARAM; + } + memcpy(&msg[33], param->other_data, 3); // OtherData replaces mode and key_id in message + } + else if (param->mode & GENKEY_MODE_DIGEST) + { + msg[33] = param->mode; + msg[34] = (uint8_t)(param->key_id >> 0); + msg[35] = (uint8_t)(param->key_id >> 8); + } + else + { + // Mode indicates no PubKey digest was requested. + // No change to TempKey. + return ATCA_SUCCESS; + } + + msg[36] = param->sn[8]; + memcpy(&msg[37], ¶m->sn[0], 2); + + // Copy public key into end of message + memcpy(&msg[sizeof(msg) - param->public_key_size], param->public_key, param->public_key_size); + + atcac_sw_sha2_256(msg, sizeof(msg), param->temp_key->value); + param->temp_key->gen_dig_data = 0; + param->temp_key->gen_key_data = 1; + param->temp_key->key_id = param->key_id; + + return ATCA_SUCCESS; +} + +/** \brief Populate the slot_config, key_config, and is_slot_locked fields in + * the atca_sign_internal_in_out structure from the provided config + * zone. + * + * The atca_sign_internal_in_out structure has a number of fields + * (slot_config, key_config, is_slot_locked) that can be determined + * automatically from the current state of TempKey and the full config + * zone. + * + * \param[inout] param Sign(Internal) parameters to be filled out. Only + * slot_config, key_config, and is_slot_locked will be + * set. + * \param[in] device_type The type of the device. + * \param[in] config Full 128 byte config zone for the device. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_config_to_sign_internal(ATCADeviceType device_type, struct atca_sign_internal_in_out *param, const uint8_t* config) +{ + const uint8_t* value = NULL; + uint16_t slot_locked = 0; + + if (param == NULL || config == NULL || param->temp_key == NULL) + { + return ATCA_BAD_PARAM; + } + + // SlotConfig[TempKeyFlags.keyId] + value = &config[20 + param->temp_key->key_id * 2]; + param->slot_config = (uint16_t)value[0] | ((uint16_t)value[1] << 8); + + // KeyConfig[TempKeyFlags.keyId] + value = &config[96 + param->temp_key->key_id * 2]; + param->key_config = (uint16_t)value[0] | ((uint16_t)value[1] << 8); + + if (device_type == ATECC108A && param->temp_key->key_id < 8) + { + value = &config[52 + param->temp_key->key_id * 2]; + param->use_flag = value[0]; + param->update_count = value[1]; + } + else + { + param->use_flag = 0x00; + param->update_count = 0x00; + } + + //SlotLocked:TempKeyFlags.keyId + slot_locked = (uint16_t)config[88] | ((uint16_t)config[89] << 8); + param->is_slot_locked = (slot_locked & (1 << param->temp_key->key_id)) ? false : true; + + return ATCA_SUCCESS; +} + +/** \brief Builds the full message that would be signed by the Sign(Internal) + * command. + * + * Additionally, the function will optionally output the OtherData data + * required by the Verify(In/Validate) command as well as the SHA256 digest of + * the full message. + * + * \param[out] device_type Device type to perform the calculation for. + * \param[out] param Input data and output buffers required. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_sign_internal_msg(ATCADeviceType device_type, struct atca_sign_internal_in_out *param) +{ + uint8_t msg[55]; + + if (param == NULL || param->temp_key == NULL || param->sn == NULL) + { + return ATCA_BAD_PARAM; + } + + memset(msg, 0, sizeof(msg)); + memcpy(&msg[0], param->temp_key->value, 32); + msg[32] = ATCA_SIGN; // Sign OpCode + msg[33] = param->mode; // Sign Mode + msg[34] = (uint8_t)(param->key_id >> 0); // Sign KeyID + msg[35] = (uint8_t)(param->key_id >> 8); + msg[36] = (uint8_t)(param->slot_config >> 0); // SlotConfig[TempKeyFlags.keyId] + msg[37] = (uint8_t)(param->slot_config >> 8); + msg[38] = (uint8_t)(param->key_config >> 0); // KeyConfig[TempKeyFlags.keyId] + msg[39] = (uint8_t)(param->key_config >> 8); + + //TempKeyFlags (b0-3: keyId, b4: sourceFlag, b5: GenDigData, b6: GenKeyData, b7: NoMacFlag) + msg[40] |= ((param->temp_key->key_id & 0x0F) << 0); + msg[40] |= ((param->temp_key->source_flag & 0x01) << 4); + msg[40] |= ((param->temp_key->gen_dig_data & 0x01) << 5); + msg[40] |= ((param->temp_key->gen_key_data & 0x01) << 6); + msg[40] |= ((param->temp_key->no_mac_flag & 0x01) << 7); + + if (device_type == ATECC108A && param->temp_key->key_id < 8) + { + msg[41] = param->use_flag; // UseFlag[TempKeyFlags.keyId] + msg[42] = param->update_count; // UpdateCount[TempKeyFlags.keyId] + } + else + { + msg[41] = 0x00; + msg[42] = 0x00; + } + + // Serial Number + msg[43] = param->sn[8]; + memcpy(&msg[48], ¶m->sn[0], 2); + if (param->mode & SIGN_MODE_INCLUDE_SN) + { + memcpy(&msg[44], ¶m->sn[4], 4); + memcpy(&msg[50], ¶m->sn[2], 2); + } + + // The bit within the SlotLocked field corresponding to the last key used in the TempKey computation is in the LSB + msg[52] = param->is_slot_locked ? 0x00 : 0x01; + + // If the slot contains a public key corresponding to a supported curve, and if PubInfo indicates this key must be + // validated before being used by Verify, and if the validity bits have a value of 0x05, then the PubKey Valid byte + // will be 0x01. In all other cases, it will be 0. + msg[53] = param->for_invalidate ? 0x01 : 0x00; + + msg[54] = 0x00; + + if (param->message) + { + memcpy(param->message, msg, sizeof(msg)); + } + if (param->verify_other_data) + { + memcpy(¶m->verify_other_data[0], &msg[33], 10); + memcpy(¶m->verify_other_data[10], &msg[44], 4); + memcpy(¶m->verify_other_data[14], &msg[50], 5); + } + if (param->digest) + { + return atcac_sw_sha2_256(msg, sizeof(msg), param->digest); + } + else + { + return ATCA_SUCCESS; + } +} + +/** \brief Builds the counter match value that needs to be stored in a slot. + * + * \param[in] counter_value Counter value to be used for the counter + * match. This must be a multiple of 32. + * \param[out] counter_match_value Data to be stored in the beginning of a + * counter match slot will be returned here + * (8 bytes). + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_encode_counter_match(uint32_t counter_value, uint8_t * counter_match_value) +{ + if ((counter_value > COUNTER_MAX_VALUE) || (counter_value % 32 != 0) || (counter_match_value == NULL)) + { + return ATCA_BAD_PARAM; + } + + // Counter match value is stored in little-endian unsigned format + counter_match_value[0] = (uint8_t)((counter_value >> 0) & 0xFF); + counter_match_value[1] = (uint8_t)((counter_value >> 8) & 0xFF); + counter_match_value[2] = (uint8_t)((counter_value >> 16) & 0xFF); + counter_match_value[3] = (uint8_t)((counter_value >> 24) & 0xFF); + + // Counter match value should be repeated in the next 4 bytes + memcpy(counter_match_value + 4, counter_match_value, 4); + + return ATCA_SUCCESS; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.h new file mode 100644 index 0000000..64be091 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.h @@ -0,0 +1,443 @@ +/** + * \file + * \brief Definitions and Prototypes for ATCA Utility Functions + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + + +#ifndef ATCA_HOST_H +#define ATCA_HOST_H + +#include +#include "cryptoauthlib.h" // contains definitions used by chip and these routines + +/** \defgroup atcah Host side crypto methods (atcah_) + * + * \brief + * Use these functions if your system does not use an ATCADevice as a host but + * implements the host in firmware. The functions provide host-side cryptographic functionality + * for an ATECC client device. They are intended to accompany the CryptoAuthLib functions. + * They can be called directly from an application, or integrated into an API. + * + * Modern compilers can garbage-collect unused functions. If your compiler does not support this feature, + * you can just discard this module from your project if you do use an ATECC as a host. Or, if you don't, + * delete the functions you do not use. + @{ */ + +/** \name Definitions for ATECC Message Sizes to Calculate a SHA256 Hash + + * \brief "||" is the concatenation operator. + * The number in braces is the length of the hash input value in bytes. + @{ */ + +//! RandOut{32} || NumIn{20} || OpCode{1} || Mode{1} || LSB of Param2{1} +#define ATCA_MSG_SIZE_NONCE (55) + + +/** \brief (Key or TempKey){32} || (Challenge or TempKey){32} || OpCode{1} || Mode{1} || Param2{2} +|| (OTP0_7 or 0){8} || (OTP8_10 or 0){3} || SN8{1} || (SN4_7 or 0){4} || SN0_1{2} || (SN2_3 or 0){2} +*/ +#define ATCA_MSG_SIZE_MAC (88) +#define ATCA_MSG_SIZE_HMAC (88) + +//! KeyId{32} || OpCode{1} || Param1{1} || Param2{2} || SN8{1} || SN0_1{2} || 0{25} || TempKey{32} +#define ATCA_MSG_SIZE_GEN_DIG (96) + + +//! KeyId{32} || OpCode{1} || Param1{1} || Param2{2} || SN8{1} || SN0_1{2} || 0{25} || TempKey{32} +#define ATCA_MSG_SIZE_DERIVE_KEY (96) + + +//! KeyId{32} || OpCode{1} || Param1{1} || Param2{2} || SN8{1} || SN0_1{2} +#define ATCA_MSG_SIZE_DERIVE_KEY_MAC (39) + +//! KeyId{32} || OpCode{1} || Param1{1} || Param2{2}|| SN8{1} || SN0_1{2} || 0{25} || TempKey{32} +#define ATCA_MSG_SIZE_ENCRYPT_MAC (96) + +//! KeyId{32} || OpCode{1} || Param1{1} || Param2{2}|| SN8{1} || SN0_1{2} || 0{21} || PlainText{36} +#define ATCA_MSG_SIZE_PRIVWRITE_MAC (96) + +#define ATCA_COMMAND_HEADER_SIZE ( 4) +#define ATCA_GENDIG_ZEROS_SIZE (25) +#define ATCA_WRITE_MAC_ZEROS_SIZE (25) +#define ATCA_PRIVWRITE_MAC_ZEROS_SIZE (21) +#define ATCA_PRIVWRITE_PLAIN_TEXT_SIZE (36) +#define ATCA_DERIVE_KEY_ZEROS_SIZE (25) +#define HMAC_BLOCK_SIZE (64) +#define ENCRYPTION_KEY_SIZE (64) + +/** @} */ + +/** \name Default Fixed Byte Values of Serial Number (SN[0:1] and SN[8]) + @{ */ +#define ATCA_SN_0_DEF (0x01) +#define ATCA_SN_1_DEF (0x23) +#define ATCA_SN_8_DEF (0xEE) +/** @} */ + + +/** \name Definition for TempKey Mode + @{ */ +//! mode mask for MAC command when using TempKey +#define MAC_MODE_USE_TEMPKEY_MASK ((uint8_t)0x03) +/** @} */ + +/** \brief Structure to hold TempKey fields + */ +typedef struct atca_temp_key +{ + uint8_t value[ATCA_KEY_SIZE * 2]; //!< Value of TempKey (64 bytes for ATECC608A only) + unsigned key_id : 4; //!< If TempKey was derived from a slot or transport key (GenDig or GenKey), that key ID is saved here. + unsigned source_flag : 1; //!< Indicates id TempKey started from a random nonce (0) or not (1). + unsigned gen_dig_data : 1; //!< TempKey was derived from the GenDig command. + unsigned gen_key_data : 1; //!< TempKey was derived from the GenKey command (ATECC devices only). + unsigned no_mac_flag : 1; //!< TempKey was derived from a key that has the NoMac bit set preventing the use of the MAC command. Known as CheckFlag in ATSHA devices). + unsigned valid : 1; //!< TempKey is valid. + uint8_t is_64; //!< TempKey has 64 bytes of valid data +} atca_temp_key_t; + + +/** \struct atca_include_data_in_out + * \brief Input / output parameters for function atca_include_data(). + * \var atca_include_data_in_out::p_temp + * \brief [out] pointer to output buffer + * \var atca_include_data_in_out::otp + * \brief [in] pointer to one-time-programming data + * \var atca_include_data_in_out::sn + * \brief [in] pointer to serial number data + */ +struct atca_include_data_in_out +{ + uint8_t * p_temp; + const uint8_t *otp; + const uint8_t *sn; + uint8_t mode; +}; + + +/** \struct atca_nonce_in_out + * \brief Input/output parameters for function atca_nonce(). + * \var atca_nonce_in_out::mode + * \brief [in] Mode parameter used in Nonce command (Param1). + * \var atca_nonce_in_out::zero + * \brief [in] Zero parameter used in Nonce command (Param2). + * \var atca_nonce_in_out::num_in + * \brief [in] Pointer to 20-byte NumIn data used in Nonce command. + * \var atca_nonce_in_out::rand_out + * \brief [in] Pointer to 32-byte RandOut data from Nonce command. + * \var atca_nonce_in_out::temp_key + * \brief [in,out] Pointer to TempKey structure. + */ +typedef struct atca_nonce_in_out +{ + uint8_t mode; + uint16_t zero; + const uint8_t * num_in; + const uint8_t * rand_out; + struct atca_temp_key *temp_key; +} atca_nonce_in_out_t; + + +typedef struct atca_io_decrypt_in_out +{ + const uint8_t* io_key; //!< IO protection key (32 bytes). + const uint8_t* out_nonce; //!< OutNonce returned from command (32 bytes). + uint8_t* data; //!< As input, encrypted data. As output, decrypted data. + size_t data_size; //!< Size of data in bytes (32 or 64). +} atca_io_decrypt_in_out_t; + +typedef struct atca_verify_mac +{ + uint8_t mode; //!< Mode (Param1) parameter used in Verify command. + uint16_t key_id; //!< KeyID (Param2) used in Verify command. + const uint8_t* signature; //!< Signature used in Verify command (64 bytes). + const uint8_t* other_data; //!< OtherData used in Verify command (19 bytes). + const uint8_t* msg_dig_buf; //!< Message digest buffer (64 bytes). + const uint8_t* io_key; //!< IO protection key value (32 bytes). + const uint8_t* sn; //!< Serial number (9 bytes). + const atca_temp_key_t* temp_key; //!< TempKey + uint8_t* mac; //!< Calculated verification MAC is returned here (32 bytes). +} atca_verify_mac_in_out_t; + + +typedef struct atca_secureboot_enc_in_out +{ + const uint8_t* io_key; //!< IO protection key value (32 bytes) + const struct atca_temp_key* temp_key; //!< Current value of TempKey + const uint8_t* digest; //!< Plaintext digest as input + uint8_t* hashed_key; //!< Calculated key is returned here (32 bytes) + uint8_t* digest_enc; //!< Encrypted (ciphertext) digest is return here (32 bytes) +} atca_secureboot_enc_in_out_t; + + +typedef struct atca_secureboot_mac_in_out +{ + uint8_t mode; //!< SecureBoot mode (param1) + uint16_t param2; //!< SecureBoot param2 + uint16_t secure_boot_config; //!< SecureBootConfig value from configuration zone + const uint8_t* hashed_key; //!< Hashed key. SHA256(IO Protection Key | TempKey) + const uint8_t* digest; //!< Digest (unencrypted) + const uint8_t* signature; //!< Signature (can be NULL if not required) + uint8_t* mac; //!< MAC is returned here +} atca_secureboot_mac_in_out_t; + +/** \struct atca_mac_in_out + * \brief Input/output parameters for function atca_mac(). + * \var atca_mac_in_out::mode + * \brief [in] Mode parameter used in MAC command (Param1). + * \var atca_mac_in_out::key_id + * \brief [in] KeyID parameter used in MAC command (Param2). + * \var atca_mac_in_out::challenge + * \brief [in] Pointer to 32-byte Challenge data used in MAC command, depending on mode. + * \var atca_mac_in_out::key + * \brief [in] Pointer to 32-byte key used to generate MAC digest. + * \var atca_mac_in_out::otp + * \brief [in] Pointer to 11-byte OTP, optionally included in MAC digest, depending on mode. + * \var atca_mac_in_out::sn + * \brief [in] Pointer to 9-byte SN, optionally included in MAC digest, depending on mode. + * \var atca_mac_in_out::response + * \brief [out] Pointer to 32-byte SHA-256 digest (MAC). + * \var atca_mac_in_out::temp_key + * \brief [in,out] Pointer to TempKey structure. + */ + + + +typedef struct atca_mac_in_out +{ + uint8_t mode; + uint16_t key_id; + const uint8_t * challenge; + const uint8_t * key; + const uint8_t * otp; + const uint8_t * sn; + uint8_t * response; + struct atca_temp_key *temp_key; +} atca_mac_in_out_t; + + +/** \struct atca_hmac_in_out + * \brief Input/output parameters for function atca_hmac(). + * \var atca_hmac_in_out::mode + * \brief [in] Mode parameter used in HMAC command (Param1). + * \var atca_hmac_in_out::key_id + * \brief [in] KeyID parameter used in HMAC command (Param2). + * \var atca_hmac_in_out::key + * \brief [in] Pointer to 32-byte key used to generate HMAC digest. + * \var atca_hmac_in_out::otp + * \brief [in] Pointer to 11-byte OTP, optionally included in HMAC digest, depending on mode. + * \var atca_hmac_in_out::sn + * \brief [in] Pointer to 9-byte SN, optionally included in HMAC digest, depending on mode. + * \var atca_hmac_in_out::response + * \brief [out] Pointer to 32-byte SHA-256 HMAC digest. + * \var atca_hmac_in_out::temp_key + * \brief [in,out] Pointer to TempKey structure. + */ +struct atca_hmac_in_out +{ + uint8_t mode; + uint16_t key_id; + const uint8_t * key; + const uint8_t * otp; + const uint8_t * sn; + uint8_t * response; + struct atca_temp_key *temp_key; +}; + + +/** + * \brief Input/output parameters for function atcah_gen_dig(). + */ +typedef struct atca_gen_dig_in_out +{ + uint8_t zone; //!< [in] Zone/Param1 for the GenDig command + uint16_t key_id; //!< [in] KeyId/Param2 for the GenDig command + bool is_key_nomac; //!< [in] Set to true if the slot pointed to be key_id has the SotConfig.NoMac bit set + const uint8_t * sn; //!< [in] Device serial number SN[0:8]. Only SN[0:1] and SN[8] are required though. + const uint8_t * stored_value; //!< [in] 32-byte slot value, config block, OTP block as specified by the Zone/KeyId parameters + const uint8_t * other_data; //!< [in] 32-byte value for shared nonce zone, 4-byte value if is_key_nomac is true, ignored and/or NULL otherwise + struct atca_temp_key *temp_key; //!< [inout] Current state of TempKey +} atca_gen_dig_in_out_t; + +/** + * \brief Input/output parameters for function atcah_write_auth_mac() and atcah_privwrite_auth_mac(). + */ +typedef struct atca_write_mac_in_out +{ + uint8_t zone; //!< Zone/Param1 for the Write or PrivWrite command + uint16_t key_id; //!< KeyID/Param2 for the Write or PrivWrite command + const uint8_t * sn; //!< Device serial number SN[0:8]. Only SN[0:1] and SN[8] are required though. + const uint8_t * input_data; //!< Data to be encrypted. 32 bytes for Write command, 36 bytes for PrivWrite command. + uint8_t * encrypted_data; //!< Encrypted version of input_data will be returned here. 32 bytes for Write command, 36 bytes for PrivWrite command. + uint8_t * auth_mac; //!< Write MAC will be returned here. 32 bytes. + struct atca_temp_key *temp_key; //!< Current state of TempKey. +} atca_write_mac_in_out_t; + +/** + * \brief Input/output parameters for function atcah_derive_key(). + */ +struct atca_derive_key_in_out +{ + uint8_t mode; //!< Mode (param 1) of the derive key command + uint16_t target_key_id; //!< Key ID (param 2) of the target slot to run the command on + const uint8_t * sn; //!< Device serial number SN[0:8]. Only SN[0:1] and SN[8] are required though. + const uint8_t * parent_key; //!< Parent key to be used in the derive key calculation (32 bytes). + uint8_t * target_key; //!< Derived key will be returned here (32 bytes). + struct atca_temp_key *temp_key; //!< Current state of TempKey. +}; + + +/** + * \brief Input/output parameters for function atcah_derive_key_mac(). + */ +struct atca_derive_key_mac_in_out +{ + uint8_t mode; //!< Mode (param 1) of the derive key command + uint16_t target_key_id; //!< Key ID (param 2) of the target slot to run the command on + const uint8_t *sn; //!< Device serial number SN[0:8]. Only SN[0:1] and SN[8] are required though. + const uint8_t *parent_key; //!< Parent key to be used in the derive key calculation (32 bytes). + uint8_t * mac; //!< DeriveKey MAC will be returned here. +}; + + +/** \struct atca_decrypt_in_out + * \brief Input/output parameters for function atca_decrypt(). + * \var atca_decrypt_in_out::crypto_data + * \brief [in,out] Pointer to 32-byte data. Input encrypted data from Read command (Contents field), output decrypted. + * \var atca_decrypt_in_out::temp_key + * \brief [in,out] Pointer to TempKey structure. + */ +struct atca_decrypt_in_out +{ + uint8_t * crypto_data; + struct atca_temp_key *temp_key; +}; + + +/** \brief Input/output parameters for function atcah_check_mac(). + */ +typedef struct atca_check_mac_in_out +{ + uint8_t mode; //!< [in] CheckMac command Mode + uint16_t key_id; //!< [in] CheckMac command KeyID + const uint8_t *sn; //!< [in] Device serial number SN[0:8]. Only SN[0:1] and SN[8] are required though. + const uint8_t *client_chal; //!< [in] ClientChal data, 32 bytes. Can be NULL if mode[0] is 1. + uint8_t * client_resp; //!< [out] Calculated ClientResp will be returned here. + const uint8_t *other_data; //!< [in] OtherData, 13 bytes + const uint8_t *otp; //!< [in] First 8 bytes of the OTP zone data. Can be NULL is mode[5] is 0. + const uint8_t *slot_key; //!< [in] 32 byte key value in the slot specified by slot_id. Can be NULL if mode[1] is 1. + /// [in] If this is not NULL, it assumes CheckMac copy is enabled for the specified key_id (ReadKey=0). If key_id + /// is even, this should be the 32-byte key value for the slot key_id+1, otherwise this should be set to slot_key. + const uint8_t * target_key; + struct atca_temp_key *temp_key; //!< [in,out] Current state of TempKey. Required if mode[0] or mode[1] are 1. +} atca_check_mac_in_out_t; + + +/** \struct atca_verify_in_out + * \brief Input/output parameters for function atcah_verify(). + * \var atca_verify_in_out::curve_type + * \brief [in] Curve type used in Verify command (Param2). + * \var atca_verify_in_out::signature + * \brief [in] Pointer to ECDSA signature to be verified + * \var atca_verify_in_out::public_key + * \brief [in] Pointer to the public key to be used for verification + * \var atca_verify_in_out::temp_key + * \brief [in,out] Pointer to TempKey structure. + */ +typedef struct atca_verify_in_out +{ + uint16_t curve_type; + const uint8_t * signature; + const uint8_t * public_key; + struct atca_temp_key *temp_key; +} atca_verify_in_out_t; + +/** \brief Input/output parameters for calculating the PubKey digest put into + * TempKey by the GenKey command with the + * atcah_gen_key_msg() function. + */ +typedef struct atca_gen_key_in_out +{ + uint8_t mode; //!< [in] GenKey Mode + uint16_t key_id; //!< [in] GenKey KeyID + const uint8_t * public_key; //!< [in] Public key to be used in the PubKey digest. X and Y integers in big-endian format. 64 bytes for P256 curve. + size_t public_key_size; //!< [in] Total number of bytes in the public key. 64 bytes for P256 curve. + const uint8_t * other_data; //!< [in] 3 bytes required when bit 4 of the mode is set. Can be NULL otherwise. + const uint8_t * sn; //!< [in] Device serial number SN[0:8] (9 bytes). Only SN[0:1] and SN[8] are required though. + struct atca_temp_key *temp_key; //!< [in,out] As input the current state of TempKey. As output, the resulting PubKEy digest. +} atca_gen_key_in_out_t; + +/** \brief Input/output parameters for calculating the message and digest used + * by the Sign(internal) command. Used with the + * atcah_sign_internal_msg() function. + */ +typedef struct atca_sign_internal_in_out +{ + uint8_t mode; //!< [in] Sign Mode + uint16_t key_id; //!< [in] Sign KeyID + uint16_t slot_config; //!< [in] SlotConfig[TempKeyFlags.keyId] + uint16_t key_config; //!< [in] KeyConfig[TempKeyFlags.keyId] + uint8_t use_flag; //!< [in] UseFlag[TempKeyFlags.keyId], 0x00 for slots 8 and above and for ATECC508A + uint8_t update_count; //!< [in] UpdateCount[TempKeyFlags.keyId], 0x00 for slots 8 and above and for ATECC508A + bool is_slot_locked; //!< [in] Is TempKeyFlags.keyId slot locked. + bool for_invalidate; //!< [in] Set to true if this will be used for the Verify(Invalidate) command. + const uint8_t * sn; //!< [in] Device serial number SN[0:8] (9 bytes) + const struct atca_temp_key *temp_key; //!< [in] The current state of TempKey. + uint8_t* message; //!< [out] Full 55 byte message the Sign(internal) command will build. Can be NULL if not required. + uint8_t* verify_other_data; //!< [out] The 19 byte OtherData bytes to be used with the Verify(In/Validate) command. Can be NULL if not required. + uint8_t* digest; //!< [out] SHA256 digest of the full 55 byte message. Can be NULL if not required. +} atca_sign_internal_in_out_t; + +#ifdef __cplusplus +extern "C" { +#endif + +ATCA_STATUS atcah_nonce(struct atca_nonce_in_out *param); +ATCA_STATUS atcah_mac(struct atca_mac_in_out *param); +ATCA_STATUS atcah_check_mac(struct atca_check_mac_in_out *param); +ATCA_STATUS atcah_hmac(struct atca_hmac_in_out *param); +ATCA_STATUS atcah_gen_dig(struct atca_gen_dig_in_out *param); +ATCA_STATUS atcah_gen_mac(struct atca_gen_dig_in_out *param); +ATCA_STATUS atcah_write_auth_mac(struct atca_write_mac_in_out *param); +ATCA_STATUS atcah_privwrite_auth_mac(struct atca_write_mac_in_out *param); +ATCA_STATUS atcah_derive_key(struct atca_derive_key_in_out *param); +ATCA_STATUS atcah_derive_key_mac(struct atca_derive_key_mac_in_out *param); +ATCA_STATUS atcah_decrypt(struct atca_decrypt_in_out *param); +ATCA_STATUS atcah_sha256(int32_t len, const uint8_t *message, uint8_t *digest); +uint8_t *atcah_include_data(struct atca_include_data_in_out *param); +ATCA_STATUS atcah_gen_key_msg(struct atca_gen_key_in_out *param); +ATCA_STATUS atcah_config_to_sign_internal(ATCADeviceType device_type, struct atca_sign_internal_in_out *param, const uint8_t* config); +ATCA_STATUS atcah_sign_internal_msg(ATCADeviceType device_type, struct atca_sign_internal_in_out *param); +ATCA_STATUS atcah_verify_mac(atca_verify_mac_in_out_t *param); +ATCA_STATUS atcah_secureboot_enc(atca_secureboot_enc_in_out_t* param); +ATCA_STATUS atcah_secureboot_mac(atca_secureboot_mac_in_out_t *param); +ATCA_STATUS atcah_encode_counter_match(uint32_t counter, uint8_t * counter_match); +ATCA_STATUS atcah_io_decrypt(struct atca_io_decrypt_in_out *param); +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif //ATCA_HOST_H diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.c b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.c new file mode 100644 index 0000000..bd08d98 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.c @@ -0,0 +1,348 @@ +/** + * \file + * \brief Utilities to create and verify a JSON Web Token (JWT) + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "cryptoauthlib.h" +#include "basic/atca_helpers.h" +#include "crypto/atca_crypto_sw_sha2.h" +#include "jwt/atca_jwt.h" +#include + +/** \brief The only supported JWT format for this library */ +static const char g_jwt_header[] = "{\"alg\":\"ES256\",\"typ\":\"JWT\"}"; + +/** + * \brief Check the provided context to see what character needs to be added in + * order to append a claim + */ +void atca_jwt_check_payload_start( + atca_jwt_t* jwt /**< [in] JWT Context to use */ + ) +{ + /* Rationality checks: a) must be valid, b) buf must be valid, c) must not be at the start, d) must have room */ + if (jwt && jwt->buf && jwt->cur && (jwt->cur < jwt->buflen - 1)) + { + /* Check the previous */ + char c = jwt->buf[jwt->cur - 1]; + if ('.' == c) + { + jwt->buf[jwt->cur++] = '{'; + } + else if ('{' != c) + { + jwt->buf[jwt->cur++] = ','; + } + } +} + +/** + * \brief Initialize a JWT structure + */ +ATCA_STATUS atca_jwt_init( + atca_jwt_t* jwt, /**< [in] JWT Context to initialize */ + char* buf, /**< [inout] Pointer to a buffer to store the token */ + uint16_t buflen /**< [in] Length of the buffer */ + ) +{ + ATCA_STATUS ret = ATCA_BAD_PARAM; + size_t tSize; + + if (jwt && buf && buflen) + { + jwt->buf = buf; + jwt->buflen = buflen; + jwt->cur = 0; + + /* Encode the header into the buffer */ + tSize = jwt->buflen; + ret = atcab_base64encode_((const uint8_t*)g_jwt_header, strlen(g_jwt_header), jwt->buf, + &tSize, atcab_b64rules_urlsafe); + if (ATCA_SUCCESS == ret) + { + jwt->cur += (uint16_t)tSize; + + /* Check length */ + if (jwt->cur < jwt->buflen - 1) + { + /* Add the separator */ + jwt->buf[jwt->cur++] = '.'; + } + else + { + ret = ATCA_INVALID_SIZE; + } + } + } + return ret; +} + +/** + * \brief Close the claims of a token, encode them, then sign the result + */ +ATCA_STATUS atca_jwt_finalize( + atca_jwt_t* jwt, /**< [in] JWT Context to use */ + uint16_t key_id /**< [in] Key Id (Slot number) used to sign */ + ) +{ + ATCA_STATUS status; + uint16_t i; + size_t rem; + size_t tSize; + + if (!jwt || !jwt->buf || !jwt->buflen || !jwt->cur) + { + return ATCA_BAD_PARAM; + } + + /* Verify the payload is closed */ + if ('}' != jwt->buf[jwt->cur - 1]) + { + jwt->buf[jwt->cur++] = '}'; + } + + /* Find the start of the "claims" portion of the token - header should + already be encoded */ + for (i = 0; i < jwt->cur; i++) + { + if ('.' == jwt->buf[i]) + { + i++; + break; + } + } + + /* Make sure there is enough remaining buffer given base64 4/3 expansion */ + rem = (jwt->cur - i + ATCA_SIG_SIZE) * 4; + rem /= 3; + + /* Increase Count to accomodate: 1 for the '.', 1 for the null terminator, + and 1 for padding */ + rem += 3; + + if (rem > (size_t)(jwt->buflen - jwt->cur)) + { + return ATCA_INVALID_SIZE; + } + + /* Calculate the payload length */ + rem = jwt->cur - i; + /* Move the payload to make room for the encoding */ + memmove(jwt->buf + jwt->buflen - jwt->cur, &jwt->buf[i], rem); + + /* Encode the payload into the buffer */ + tSize = jwt->buflen; + status = atcab_base64encode_((uint8_t*)(jwt->buf + jwt->buflen - jwt->cur), rem, + &jwt->buf[i], &tSize, atcab_b64rules_urlsafe); + if (ATCA_SUCCESS != status) + { + return status; + } + + jwt->cur = (uint16_t)(i + tSize); + + /* Make sure there room to add the signature + ECDSA(P256) -> 64 bytes -> base64 -> 86.3 (87) -> 88 including null */ + if (jwt->cur >= jwt->buflen - 88) + { + /* Something broke */ + return ATCA_INVALID_SIZE; + } + + /* Create digest of the message store and store in the buffer */ + status = atcac_sw_sha2_256((const uint8_t*)jwt->buf, jwt->cur, (uint8_t*)(jwt->buf + jwt->buflen - 32)); + if (ATCA_SUCCESS != status) + { + return status; + } + + /* Create ECSDA signature of the digest and store it back in the buffer */ + status = atcab_sign(key_id, (const uint8_t*)(jwt->buf + jwt->buflen - ATCA_SHA_DIGEST_SIZE), + (uint8_t*)(jwt->buf + jwt->buflen - 64)); + if (ATCA_SUCCESS != status) + { + return status; + } + + /* Add the separator */ + jwt->buf[jwt->cur++] = '.'; + + /* Encode the signature and store it in the buffer */ + tSize = jwt->buflen - jwt->cur; + atcab_base64encode_((const uint8_t*)(jwt->buf + jwt->buflen - ATCA_SIG_SIZE), ATCA_SIG_SIZE, + &jwt->buf[jwt->cur], &tSize, atcab_b64rules_urlsafe); + jwt->cur += (uint16_t)tSize; + + if (jwt->cur >= jwt->buflen) + { + /* Something broke */ + return ATCA_INVALID_SIZE; + } + + /* Make sure resulting buffer is null terminated */ + jwt->buf[jwt->cur] = 0; + + return status; +} + +/** + * \brief Add a string claim to a token + * \note This function does not escape strings so the user has to ensure they + * are valid for use in a JSON string first + */ +ATCA_STATUS atca_jwt_add_claim_string( + atca_jwt_t* jwt, /**< [in] JWT Context to use */ + const char* claim, /**< [in] Name of the claim to be inserted */ + const char* value /**< [in] Null terminated string to be insterted */ + ) +{ + int32_t written; + int32_t remaining; + + if (jwt && jwt->buf && jwt->buflen && claim && value) + { + atca_jwt_check_payload_start(jwt); + + remaining = jwt->buflen - jwt->cur; + written = snprintf(&jwt->buf[jwt->cur], remaining, "\"%s\":\"%s\"", claim, value); + if (0 < written && written < remaining) + { + jwt->cur += written; + return ATCA_SUCCESS; + } + else + { + return ATCA_GEN_FAIL; + } + } + else + { + return ATCA_BAD_PARAM; + } +} + +/** + * \brief Add a numeric claim to a token + * \note This function does not escape strings so the user has to ensure the + * claim is valid first + */ +ATCA_STATUS atca_jwt_add_claim_numeric( + atca_jwt_t* jwt, /**< [in] JWT Context to use */ + const char* claim, /**< [in] Name of the claim to be inserted */ + int32_t value /**< [in] integer value to be inserted */ + ) +{ + int32_t written; + int32_t remaining; + + if (jwt && jwt->buf && jwt->buflen && claim) + { + atca_jwt_check_payload_start(jwt); + + remaining = jwt->buflen - jwt->cur; + written = snprintf(&jwt->buf[jwt->cur], remaining, "\"%s\":%ld", claim, (long)value); + if (0 < written && written < remaining) + { + jwt->cur += written; + return 0; + } + else + { + return ATCA_GEN_FAIL; + } + } + else + { + return ATCA_BAD_PARAM; + } +} + +/** + * \brief Verifies the signature of a jwt using the provided public key + */ +ATCA_STATUS atca_jwt_verify( + const char* buf, /**< [in] Buffer holding an encoded jwt */ + uint16_t buflen, /**< [in] Length of the buffer/jwt */ + const uint8_t* pubkey /**< [in] Public key (raw byte format) */ + ) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t digest[ATCA_KEY_SIZE]; + uint8_t signature[ATCA_SIG_SIZE]; + size_t sig_len = sizeof(signature); + const char* pStr = buf; + + bool verified = false; + + if (!buf || !buflen || !pubkey) + { + return ATCA_BAD_PARAM; + } + + do + { + /* Payload */ + pStr = strchr(pStr, '.') + 1; + if (!pStr) + { + break; + } + + /* Signature */ + pStr = strchr(pStr, '.') + 1; + if (!pStr) + { + break; + } + + /* Extract the signature */ + if (ATCA_SUCCESS != (status = atcab_base64decode_(pStr, strlen(pStr), + signature, &sig_len, atcab_b64rules_urlsafe))) + { + break; + } + + /* Digest the token */ + if (ATCA_SUCCESS != (status = atcac_sw_sha2_256((const uint8_t*)buf, pStr - buf - 1, digest))) + { + break; + } + + /* Do a signature verification using the device */ + if (ATCA_SUCCESS != (status = atcab_verify_extern(digest, signature, + pubkey, &verified))) + { + break; + } + + if (!verified) + { + status = ATCA_CHECKMAC_VERIFY_FAILED; + } + } + while (0); + + return status; +} diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.h b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.h new file mode 100644 index 0000000..2118a57 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.h @@ -0,0 +1,61 @@ +/** + * \file + * \brief Utilities to create and verify a JSON Web Token (JWT) + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef ATCA_JWT_H_ +#define ATCA_JWT_H_ + +/** \defgroup jwt JSON Web Token (JWT) methods (atca_jwt_) + * \brief Methods for signing and verifying JSON Web Token (JWT) tokens. + @{ */ + +#include "cryptoauthlib.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \brief Structure to hold metadata information about the jwt being built */ +typedef struct +{ + char* buf; /* Input buffer */ + uint16_t buflen; /* Total buffer size */ + uint16_t cur; /* Current location in the buffer */ +} atca_jwt_t; + +ATCA_STATUS atca_jwt_init(atca_jwt_t* jwt, char* buf, uint16_t buflen); +ATCA_STATUS atca_jwt_add_claim_string(atca_jwt_t* jwt, const char* claim, const char* value); +ATCA_STATUS atca_jwt_add_claim_numeric(atca_jwt_t* jwt, const char* claim, int32_t value); +ATCA_STATUS atca_jwt_finalize(atca_jwt_t* jwt, uint16_t key_id); +void atca_jwt_check_payload_start(atca_jwt_t* jwt); +ATCA_STATUS atca_jwt_verify(const char* buf, uint16_t buflen, const uint8_t* pubkey); + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* ATCA_JWT_H_ */ diff --git a/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/readme.md b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/readme.md new file mode 100644 index 0000000..13c49df --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/CryptoAuthenticationLibrary/readme.md @@ -0,0 +1 @@ +## This folder will contain the source and header files generated using the cryptoAuthenticationLibrary ftl files. \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/application_manager.c b/AVRIoT.X/mcc_generated_files/application_manager.c new file mode 100644 index 0000000..74e32ca --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/application_manager.c @@ -0,0 +1,399 @@ +/* +\file application_manager.c + +\brief Application Manager source file. + +(c) 2018 Microchip Technology Inc. and its subsidiaries. + +Subject to your compliance with these terms, you may use Microchip software and any +derivatives exclusively with Microchip products. It is your responsibility to comply with third party +license terms applicable to your use of third party software (including open source software) that +may accompany Microchip software. + +THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER +EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY +IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS +FOR A PARTICULAR PURPOSE. + +IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, +INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND +WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP +HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO +THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL +CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT +OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS +SOFTWARE. +*/ + +#include +#include +#include +#include "utils/atomic.h" +#include +#include "include/pin_manager.h" +#include "application_manager.h" +#include "mcc.h" +#include "config/IoT_Sensor_Node_config.h" +#include "config/conf_winc.h" +#include "config/mqtt_config.h" +#include "cloud/cloud_service.h" +#include "cloud/mqtt_service.h" +#include "cloud/crypto_client/crypto_client.h" +#include "cloud/wifi_service.h" +#include "CryptoAuthenticationLibrary/CryptoAuth_init.h" +#include "../mcc_generated_files/sensors_handling.h" +#include "credentials_storage/credentials_storage.h" +#include "led.h" +#include "debug_print.h" +#include "time_service.h" +#if CFG_ENABLE_CLI +#include "cli/cli.h" +#endif + + +#define MAIN_DATATASK_INTERVAL 100L +// The debounce time is currently close to 2 Seconds. +#define SW_DEBOUNCE_INTERVAL 1460000L +#define SW0_TOGGLE_STATE SW0_GetValue() +#define SW1_TOGGLE_STATE SW1_GetValue() +#define TOGGLE_ON 1 +#define TOGGLE_OFF 0 +#define DEVICE_SHADOW_INIT_INTERVAL 1000L +#define UPDATE_DEVICE_SHADOW_BUFFER_TIME (2) +static uint8_t toggleState = 0; + +// This will contain the device ID, before we have it this dummy value is the init value which is non-0 +char attDeviceID[20] = "BAAAAADD1DBAAADD1D"; +char mqttSubscribeTopic[SUBSCRIBE_TOPIC_SIZE]; +ATCA_STATUS retValCryptoClientSerialNumber; +static uint8_t holdCount = 0; + +uint32_t MAIN_dataTask(void *payload); +timerStruct_t MAIN_dataTasksTimer = {MAIN_dataTask}; + +static void wifiConnectionStateChanged(uint8_t status); +static void sendToCloud(void); +static void updateDeviceShadow(void); +static void subscribeToCloud(void); +static void receivedFromCloud(uint8_t *topic, uint8_t *payload); +static void setToggleState(uint8_t passedToggleState); +static uint8_t getToggleState(void); +uint32_t initDeviceShadow(void *payload); +timerStruct_t initDeviceShadowTimer = {initDeviceShadow}; + +// This will get called every 1 second only while we have a valid Cloud connection +static void sendToCloud(void) +{ + static char json[PAYLOAD_SIZE]; + static char publishMqttTopic[PUBLISH_TOPIC_SIZE]; + ledTickState_t ledState; + int rawTemperature = 0; + int light = 0; + int len = 0; + memset((void*)publishMqttTopic, 0, sizeof(publishMqttTopic)); + sprintf(publishMqttTopic, "%s/sensors", cid); + // This part runs every CFG_SEND_INTERVAL seconds + if (shared_networking_params.haveAPConnection) + { + rawTemperature = SENSORS_getTempValue(); + light = SENSORS_getLightValue(); + len = sprintf(json,"{\"Light\":%d,\"Temp\":%d.%02d}", light,rawTemperature/100,abs(rawTemperature)%100); + } + if (len >0) + { + CLOUD_publishData((uint8_t*)publishMqttTopic ,(uint8_t*)json, len); + if (holdCount) + { + holdCount--; + } + else + { + ledState.Full2Sec = LED_BLIP; + LED_modeYellow(ledState); + } + + } +} + +//This handles messages published from the MQTT server when subscribed +static void receivedFromCloud(uint8_t *topic, uint8_t *payload) +{ + char *toggleToken = "\"toggle\":"; + char *subString; + ledTickState_t ledState; + sprintf(mqttSubscribeTopic, "$aws/things/%s/shadow/update/delta", cid); + if (strncmp((void*) mqttSubscribeTopic, (void*) topic, strlen(mqttSubscribeTopic)) == 0) + { + if ((subString = strstr((char*)payload, toggleToken))) + { + if (subString[strlen(toggleToken)] == '1') + { + setToggleState(TOGGLE_ON); + ledState.Full2Sec = LED_ON_STATIC; + LED_modeYellow(ledState); + } + else + { + setToggleState(TOGGLE_OFF); + ledState.Full2Sec = LED_OFF_STATIC; + LED_modeYellow(ledState); + } + holdCount = 2; + } + } + debug_printer(SEVERITY_NONE, LEVEL_NORMAL, "topic: %s", topic); + debug_printer(SEVERITY_NONE, LEVEL_NORMAL, "payload: %s", payload); + updateDeviceShadow(); +} + +void application_init() +{ + uint8_t mode = WIFI_DEFAULT; + uint32_t sw0CurrentVal = 0; + uint32_t sw1CurrentVal = 0; + uint32_t i = 0; + ledTickState_t ledState; + + // Initialization of modules before interrupts are enabled + SYSTEM_Initialize(); + LED_test(); +#if CFG_ENABLE_CLI + CLI_init(); + CLI_setdeviceId(attDeviceID); +#endif + debug_init(attDeviceID); + + // Initialization of modules where the init needs interrupts to be enabled + if(!CryptoAuth_Initialize()) + { + debug_printError("APP: CryptoAuthInit failed"); + shared_networking_params.haveError = 1; + } + // Get serial number from the ECC608 chip + retValCryptoClientSerialNumber = CRYPTO_CLIENT_printSerialNumber(attDeviceID); + if( retValCryptoClientSerialNumber != ATCA_SUCCESS ) + { + shared_networking_params.haveError = 1; + switch(retValCryptoClientSerialNumber) + { + case ATCA_GEN_FAIL: + debug_printError("APP: DeviceID generation failed, unspecified error"); + break; + case ATCA_BAD_PARAM: + debug_printError("APP: DeviceID generation failed, bad argument"); + default: + debug_printError("APP: DeviceID generation failed"); + break; + } + + } +#if CFG_ENABLE_CLI + CLI_setdeviceId(attDeviceID); +#endif + debug_setPrefix(attDeviceID); + wifi_readThingIdFromWinc(); + wifi_readAWSEndpointFromWinc(); + timeout_create(&initDeviceShadowTimer, DEVICE_SHADOW_INIT_INTERVAL ); + // Blocking debounce + for(i = 0; i < SW_DEBOUNCE_INTERVAL; i++) + { + sw0CurrentVal += SW0_TOGGLE_STATE; + sw1CurrentVal += SW1_TOGGLE_STATE; + } + if(sw0CurrentVal < (SW_DEBOUNCE_INTERVAL/2)) + { + if(sw1CurrentVal < (SW_DEBOUNCE_INTERVAL/2)) + { + // Default Credentials + Connect to AP + strcpy(ssid, CFG_MAIN_WLAN_SSID); + strcpy(pass, CFG_MAIN_WLAN_PSK); + sprintf((char*)authType, "%d", CFG_MAIN_WLAN_AUTH); + + ledState.Full2Sec = LED_BLINK; + LED_modeGreen(ledState); + LED_modeBlue(ledState); + ledState.Full2Sec = LED_OFF_STATIC; + LED_modeYellow(ledState); + LED_modeRed(ledState); + + shared_networking_params.amConnectingAP = 1; + shared_networking_params.amSoftAP = 0; + shared_networking_params.amDefaultCred = 1; + } + else + { + // Host as SOFT AP + ledState.Full2Sec = LED_BLIP; + LED_modeBlue(ledState); + ledState.Full2Sec = LED_OFF_STATIC; + LED_modeGreen(ledState); + LED_modeYellow(ledState); + LED_modeRed(ledState); + mode = WIFI_SOFT_AP; + shared_networking_params.amConnectingAP = 0; + shared_networking_params.amSoftAP = 1; + shared_networking_params.amDefaultCred = 0; + } + } + else + { + // Connect to AP + ledState.Full2Sec = LED_BLINK; + LED_modeBlue(ledState); + ledState.Full2Sec = LED_OFF_STATIC; + LED_modeGreen(ledState); + LED_modeYellow(ledState); + LED_modeRed(ledState); + shared_networking_params.amConnectingAP = 1; + shared_networking_params.amSoftAP = 0; + shared_networking_params.amDefaultCred = 0; + } + wifi_init(wifiConnectionStateChanged, mode); + + if (mode == WIFI_DEFAULT) + { + CLOUD_setupTask(attDeviceID); + timeout_create(&MAIN_dataTasksTimer, MAIN_DATATASK_INTERVAL); + } + + LED_test(); + LED_serviceInit(); + subscribeToCloud(); +} + +static void subscribeToCloud(void) +{ + sprintf(mqttSubscribeTopic, "$aws/things/%s/shadow/update/delta", cid); + CLOUD_registerSubscription((uint8_t*)mqttSubscribeTopic,receivedFromCloud); +} + +static void setToggleState(uint8_t passedToggleState) +{ + toggleState = passedToggleState; +} + +static uint8_t getToggleState(void) +{ + return toggleState; +} + +uint32_t initDeviceShadow(void *payload) +{ + static uint32_t previousTime = 0; + if(CLOUD_checkIsConnected()) + { + // Get the current time. This uses the C standard library time functions + uint32_t timeNow = TIME_getCurrent(); + if(previousTime == 0) + { + previousTime = timeNow; + } + else if((TIME_getDiffTime(timeNow, previousTime)) >= UPDATE_DEVICE_SHADOW_BUFFER_TIME) + { + updateDeviceShadow(); + return 0; + } + } + return DEVICE_SHADOW_INIT_INTERVAL; +} + +static void updateDeviceShadow(void) +{ + static char payload[PAYLOAD_SIZE]; + static char topic[PUBLISH_TOPIC_SIZE]; + int payloadLength = 0; + + memset((void*)topic, 0, sizeof(topic)); + sprintf(topic, "$aws/things/%s/shadow/update", cid); + if (shared_networking_params.haveAPConnection) + { + payloadLength = sprintf(payload,"{\"state\":{\"reported\":{\"toggle\":%d}}}", getToggleState()); + } + if (payloadLength >0) + { + CLOUD_publishData((uint8_t*)topic,(uint8_t*)payload, payloadLength); + } +} + +// This scheduler will check all tasks and timers that are due and service them +void runScheduler(void) +{ + timeout_callNextCallback(); +} + +// This gets called by the scheduler approximately every 100ms +uint32_t MAIN_dataTask(void *payload) +{ + ledTickState_t ledState; + static uint32_t previousTransmissionTime = 0; + + // Get the current time. This uses the C standard library time functions + uint32_t timeNow = TIME_getCurrent(); + + // Example of how to send data when MQTT is connected every 1 second based on the system clock + if(CLOUD_checkIsConnected()) + { + // How many seconds since the last time this loop ran? + int32_t delta = TIME_getDiffTime(timeNow, previousTransmissionTime); + + if (delta >= CFG_SEND_INTERVAL) + { + previousTransmissionTime = timeNow; + // Call the data task in main.c + sendToCloud(); + } + } + + // Blue LED + if (!shared_networking_params.amConnectingAP) + { + if (shared_networking_params.haveAPConnection) + { + ledState.Full2Sec = LED_ON_STATIC; + LED_modeBlue(ledState); + } + + // Green LED if we are in Access Point + if (!shared_networking_params.amConnectingSocket) + { + if(CLOUD_checkIsConnected()) + { + ledState.Full2Sec = LED_ON_STATIC; + LED_modeGreen(ledState); + } + } + } + + // RED LED + if (shared_networking_params.haveError) + { + ledState.Full2Sec = LED_ON_STATIC; + LED_modeRed(ledState); + } + else + { + ledState.Full2Sec = LED_OFF_STATIC; + LED_modeRed(ledState); + } + + // This is milliseconds managed by the RTC and the scheduler, this return + // makes the timer run another time, returning 0 will make it stop + return MAIN_DATATASK_INTERVAL; +} + +void application_post_provisioning(void) +{ + CLOUD_setupTask(attDeviceID); + timeout_create(&MAIN_dataTasksTimer, MAIN_DATATASK_INTERVAL); +} + +// React to the WIFI state change here. Status of 1 means connected, Status of 0 means disconnected +static void wifiConnectionStateChanged(uint8_t status) +{ + // If we have no AP access we want to retry + if (status != 1) + { + // Restart the WIFI module if we get disconnected from the WiFi Access Point (AP) + CLOUD_setInitFlag(); + } +} diff --git a/AVRIoT.X/mcc_generated_files/application_manager.h b/AVRIoT.X/mcc_generated_files/application_manager.h new file mode 100644 index 0000000..33e219d --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/application_manager.h @@ -0,0 +1,35 @@ +/* +\file application_manager.h + +\brief Application Manager header file. + +(c) 2018 Microchip Technology Inc. and its subsidiaries. + +Subject to your compliance with these terms, you may use Microchip software and any +derivatives exclusively with Microchip products. It is your responsibility to comply with third party +license terms applicable to your use of third party software (including open source software) that +may accompany Microchip software. + +THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER +EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY +IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS +FOR A PARTICULAR PURPOSE. + +IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, +INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND +WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP +HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO +THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL +CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT +OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS +SOFTWARE. +*/ + +#ifndef APPLICATION_MANAGER_H_ +#define APPLICATION_MANAGER_H_ + +void application_init(void); +void application_post_provisioning(void); +void runScheduler(void); + +#endif /* APPLICATION_MANAGER_H_ */ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/banner.h b/AVRIoT.X/mcc_generated_files/banner.h new file mode 100644 index 0000000..f395dac --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/banner.h @@ -0,0 +1,106 @@ +/* + \file banner.h + + \brief banner text. + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef BANNER_H +#define BANNER_H + +#ifdef __AVR__ +#define BANNER "\33[34m"\ +" . \r\n"\ +" ;;;;;;. ;;;;;; ;;;;;; `;;;;;;;;;: `., \r\n"\ +" `''''''; `''''', .''''', ;'''''''''''`.`, \r\n"\ +" :''''''' '''''' ;''''; ''''''''''''' ` \r\n"\ +" '''''''': ,'''''` `''''': :''''''''''''': \r\n"\ +" `''''''''' '''''; :''''' ''''': `'''''; \r\n"\ +" ;'''''''''. ;''''' '''''; .'''''` :''''' \r\n"\ +" ''''':''''; `''''': .'''''` ;''''; ,''''' \r\n"\ +" :''''; '''''` ;''''; '''''; `''''', ;''''; \r\n"\ +" '''''` ;''''; .'''''` `'''''. :''''' ;''''': \r\n"\ +" `''''' .''''' '''''; ;''''' '''''';;'''''''' \r\n"\ +" ;''''; ''''': :''''' ''''', .''''''''''''''' \r\n"\ +" '''''` :''''' '''''.,''''' ''''''''''''''; \r\n"\ +" ,''''' `'''''. ;'''';;''''; '''''''''''';, \r\n"\ +" ;''''';;;;;'''''; `''''''''''` ;''''',:''''; \r\n"\ +" `'''''''''''''''''` '''''''''; '''''; ''''' \r\n"\ +" ;''''''''''''''''': ,'''''''', :'''''` ''''': \r\n"\ +" ''''''''''''''''''' '''''''' '''''; ;''''; \r\n"\ +" .''''':,,,,,,,:'''''. ;''''''; .''''', .''''' \r\n"\ +" ;''''' '''''; `'''''' ;''''' `''''': \r\n"\ +" '''''; ,'''''` ;''''; `'''''; '''''; \r\n"\ +",'''''` '''''; `''''` ;'''''` ;'''''` \r\n"\ +" '''' \r\n"\ +" ,'', \r\n"\ +" '' \r\n"\ +" ;: \r\n"\ +" ` \r\n"\ +"\33[0m"\ +" ooooo ooooooooooooo\r\n"\ +" `888' 8' 888 `8\r\n"\ +" 888 .ooooo. 888\r\n"\ +" 888 d88' `88b 888\r\n"\ +" 888 888 888 888\r\n"\ +" 888 888 888 888\r\n"\ +" o888o `Y8bod8P' o888o\r\n" +#else +#define BANNER "\33[31m"\ +"PPPPPPPPPPPPPPPPP IIIIIIIIII CCCCCCCCCCCCC\r\n"\ +"P::::::::::::::::P I::::::::I CCC::::::::::::C\r\n"\ +"P::::::PPPPPP:::::P I::::::::I CC:::::::::::::::C\r\n"\ +"PP:::::P P:::::PII::::::IIC:::::CCCCCCCC::::C\r\n"\ +" P::::P P:::::P I::::I C:::::C CCCCCC\r\n"\ +" P::::P P:::::P I::::IC:::::C \r\n"\ +" P::::PPPPPP:::::P I::::IC:::::C \r\n"\ +" P:::::::::::::PP I::::IC:::::C \r\n"\ +" P::::PPPPPPPPP I::::IC:::::C \r\n"\ +" P::::P I::::IC:::::C \r\n"\ +" P::::P I::::IC:::::C \r\n"\ +" P::::P I::::I C:::::C CCCCCC\r\n"\ +"PP::::::PP II::::::IIC:::::CCCCCCCC::::C\r\n"\ +"P::::::::P I::::::::I CC:::::::::::::::C\r\n"\ +"P::::::::P I::::::::I CCC::::::::::::C\r\n"\ +"PPPPPPPPPP IIIIIIIIII CCCCCCCCCCCCC\r\n"\ +"\33[0m\r\n"\ +" IIIIIIIIII TTTTTTTTTTTTTTTTTTTTTTT\r\n"\ +" I::::::::I T:::::::::::::::::::::T\r\n"\ +" I::::::::I T:::::::::::::::::::::T\r\n"\ +" II::::::II T:::::TT:::::::TT:::::T\r\n"\ +" I::::I oooooooooooTTTTTT T:::::T TTTTTT\r\n"\ +" I::::I oo:::::::::::oo T:::::T \r\n"\ +" I::::I o:::::::::::::::o T:::::T \r\n"\ +" I::::I o:::::ooooo:::::o T:::::T \r\n"\ +" I::::I o::::o o::::o T:::::T \r\n"\ +" I::::I o::::o o::::o T:::::T \r\n"\ +" I::::I o::::o o::::o T:::::T \r\n"\ +" I::::I o::::o o::::o T:::::T \r\n"\ +" II::::::IIo:::::ooooo:::::o TT:::::::TT \r\n"\ +" I::::::::Io:::::::::::::::o T:::::::::T \r\n"\ +" I::::::::I oo:::::::::::oo T:::::::::T \r\n"\ +" IIIIIIIIII ooooooooooo TTTTTTTTTTT \r\n" + +#endif + +#endif //BANNER_H \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/cli/cli.c b/AVRIoT.X/mcc_generated_files/cli/cli.c new file mode 100644 index 0000000..2d71ef0 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/cli/cli.c @@ -0,0 +1,380 @@ +/* + \file cli.c + + \brief Command Line Interpreter source file. + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include +#include +#include +#include + +#include "../drivers/uart.h" +#include +#include "../include/usart2.h" +#include "cli.h" +#include "../cloud/crypto_client/crypto_client.h" +#include "../credentials_storage/credentials_storage.h" +#include "../mqtt/mqtt_core/mqtt_core.h" +#include "../debug_print.h" +#include "../cloud/wifi_service.h" +#include "../mqtt/mqtt_comm_bsd/mqtt_comm_layer.h" +#include "../cloud/cloud_service.h" +#include "led.h" +#include "../cloud/cloud_interface.h" +#include "../cloud/mqtt_service.h" + +#define WIFI_PARAMS_OPEN 1 +#define WIFI_PARAMS_PSK 2 +#define WIFI_PARAMS_WEP 3 +#define MAX_COMMAND_SIZE 100 +#define MAX_PUB_KEY_LEN 200 +#define NEWLINE "\r\n" +#define KEY_OR_THING "thing" +#define UNKNOWN_CMD_MSG "--------------------------------------------" NEWLINE\ + "Unknown command. List of available commands:" NEWLINE\ + "reset"NEWLINE\ + "device"NEWLINE\ + KEY_OR_THING NEWLINE\ + "reconnect" NEWLINE\ + "version" NEWLINE\ + "cli_version" NEWLINE\ + "wifi [,,[authType]]" NEWLINE\ + "debug" NEWLINE\ + "--------------------------------------------"NEWLINE"\4" + +static char command[MAX_COMMAND_SIZE]; +static bool isCommandReceived = false; +static uint8_t index = 0; +static bool commandTooLongFlag = false; + +const char * const cli_version_number = "1.0"; +const char * const firmware_version_number = "2.0.1"; + +static void command_received(char *command_text); +static void reset_cmd(char *pArg); +static void reconnect_cmd(char *pArg); +static void set_wifi_auth(char *ssid_pwd_auth); +static void get_thing_id(char *pArg); +static void get_device_id(char *pArg); +static void get_cli_version(char *pArg); +static void get_firmware_version(char *pArg); +static void set_debug_level(char *pArg); +static bool endOfLineTest(char c); +static void enableUsartRxInterrupts(void); + +#define CLI_TASK_INTERVAL 50 + +uint32_t CLI_task(void*); +timerStruct_t CLI_task_timer = {CLI_task}; + +struct cmd +{ + const char * const command; + void (* const handler)(char *argument); +}; + +const struct cmd commands[] = +{ + { "reset", reset_cmd}, + { "reconnect", reconnect_cmd }, + { "wifi", set_wifi_auth }, + { "thing", get_thing_id }, + { "device", get_device_id }, + { "cli_version", get_cli_version }, + { "version", get_firmware_version }, + { "debug", set_debug_level } +}; + +void CLI_init(void) +{ + enableUsartRxInterrupts(); + timeout_create(&CLI_task_timer, CLI_TASK_INTERVAL); +} + +static bool endOfLineTest(char c) +{ + static char test = 0; + bool retvalue = true; + + if(c == '\n') + { + if(test == '\r') + { + retvalue = false; + } + } + test = c; + return retvalue; +} + +uint32_t CLI_task(void* param) +{ + bool cmd_rcvd = false; + char c = 0; + // read all the EUSART bytes in the queue + while(uart[CLI].DataReady() && !isCommandReceived) + { + c = uart[CLI].Read(); + // read until we get a newline + if(c == '\r' || c == '\n') + { + command[index] = 0; + + if(!commandTooLongFlag) + { + if( endOfLineTest(c) && !cmd_rcvd ) + { + command_received((char*)command); + cmd_rcvd = true; + } + } + if(commandTooLongFlag) + { + printf(NEWLINE"Command too long"NEWLINE); + } + index = 0; + commandTooLongFlag = false; + } + else // otherwise store the character + { + if(index < MAX_COMMAND_SIZE) + { + command[index++] = c; + } + else + { + commandTooLongFlag = true; + } + } + } + + return CLI_TASK_INTERVAL; +} + +static void set_wifi_auth(char *ssid_pwd_auth) +{ + char *credentials[3]; + char *pch; + uint8_t params = 0; + uint8_t i; + ledTickState_t ledState; + + for(i=0;i<=2;i++)credentials[i]='\0'; + + pch = strtok (ssid_pwd_auth, ","); + credentials[0]=pch; + + while (pch != NULL && params <= 2) + { + credentials[params] = pch; + params++; + pch = strtok (NULL, ","); + + } + + if(credentials[0]!=NULL) + { + if(credentials[1]==NULL && credentials[2]==NULL) params=1; + else if(credentials[1]!= NULL && credentials[2]== NULL) + { + params=atoi(credentials[1]);//Resuse the same variable to store the auth type + if (params==2 || params==3)params=5; + else if(params==1); + else params=2; + } + else params = atoi(credentials[2]); + } + + switch (params) + { + case WIFI_PARAMS_OPEN: + strncpy(ssid, credentials[0],MAX_WIFI_CREDENTIALS_LENGTH-1); + strcpy(pass, "\0"); + strcpy(authType, "1"); + break; + + case WIFI_PARAMS_PSK: + case WIFI_PARAMS_WEP: + strncpy(ssid, credentials[0],MAX_WIFI_CREDENTIALS_LENGTH-1); + strncpy(pass, credentials[1],MAX_WIFI_CREDENTIALS_LENGTH-1); + sprintf(authType, "%d", params); + break; + + default: + params = 0; + break; + } + if (params) + { + printf("OK\r\n\4"); + if(CLOUD_checkIsConnected()) + { + MQTT_Close(MQTT_GetClientConnectionInfo()); + } + if (shared_networking_params.haveSocket) + { // Disconnect from Socket if active + shared_networking_params.haveSocket = 0; + MQTT_Disconnect(MQTT_GetClientConnectionInfo()); + } + wifi_disconnectFromAp(); + ledState.Full2Sec = LED_OFF_STATIC; + LED_modeYellow(ledState); + LED_modeRed(ledState); + LED_modeGreen(ledState); + ledState.Full2Sec = LED_BLINK; + LED_modeBlue(ledState); + } + else + { + printf("Error. Wi-Fi command format is wifi [,,[authType]]\r\n\4"); + } +} + +static void reconnect_cmd(char *pArg) +{ + ledTickState_t ledState; + (void)pArg; + ledState.Full2Sec = LED_OFF_STATIC; + LED_modeYellow(ledState); + LED_modeRed(ledState); + ledState.Full2Sec = LED_BLINK; + LED_modeGreen(ledState); + shared_networking_params.haveSocket = 0; + MQTT_Disconnect(MQTT_GetClientConnectionInfo()); + printf("OK\r\n"); +} + +static void reset_cmd(char *pArg) +{ + (void)pArg; + wdt_enable(WDTO_30MS); + while(1) {}; +} + +static void set_debug_level(char *pArg) +{ + debug_severity_t level = SEVERITY_NONE; + if(*pArg >= '0' && *pArg <= '4') + { + level = *pArg - '0'; + debug_setSeverity(level); + printf("OK\r\n"); + } + else + { + printf("debug parameter must be between 0 (Least) and 4 (Most) \r\n"); + } +} + +static void get_thing_id(char *pArg) +{ + (void)pArg; + + if (cid != NULL) + { + printf("%s\r\n\4",cid); + } + else + { + printf("Error getting Thing ID.\r\n\4"); + } +} + +static char *ateccsn = NULL; +void CLI_setdeviceId(char *id) +{ + ateccsn = id; +} + +static void get_device_id(char *pArg) +{ + (void) pArg; + if (ateccsn) + { + printf("%s\r\n\4", ateccsn); + } + else + { + printf("Unknown.\r\n\4"); + } +} + +static void get_cli_version(char *pArg) +{ + (void)pArg; + printf("v%s\r\n\4", cli_version_number); +} + +static void get_firmware_version(char *pArg) +{ + (void)pArg; + printf("v%s\r\n\4", firmware_version_number); +} + +static void command_received(char *command_text) +{ + char *argument = strstr(command_text, " "); + uint8_t cmp; + uint8_t ct_len; + uint8_t cc_len; + uint8_t i = 0; + + if (argument != NULL) + { + /* Replace the delimiter with string terminator */ + *argument = '\0'; + /* Point after the string terminator, to the actual string */ + argument++; + } + + for (i = 0; i < sizeof(commands)/sizeof(*commands); i++) + { + cmp = strcmp(command_text, commands[i].command); + ct_len = strlen(command_text); + cc_len = strlen(commands[i].command); + + if (cmp == 0 && ct_len == cc_len) + { + if (commands[i].handler != NULL) + { + commands[i].handler(argument); + return; + } + } + } + + printf(UNKNOWN_CMD_MSG); +} + +static void enableUsartRxInterrupts(void) +{ + // Empty RX buffer + do { + (void)USART2.RXDATAL; + } while ((USART2.STATUS & USART_RXCIF_bm) != 0); + + // Enable RX interrupt + USART2.CTRLA |= 1 << USART_RXCIE_bp; +} diff --git a/AVRIoT.X/mcc_generated_files/cli/cli.h b/AVRIoT.X/mcc_generated_files/cli/cli.h new file mode 100644 index 0000000..04ebf1e --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/cli/cli.h @@ -0,0 +1,36 @@ +/* + \file cli.h + + \brief Command Line Interpreter header file. + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef CLI_H +#define CLI_H + +#include "../drivers/timeout.h" + +void CLI_init(void); +void CLI_setdeviceId(char *); + +#endif /* CLI_H */ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/cloud/aws_cloud_service.c b/AVRIoT.X/mcc_generated_files/cloud/aws_cloud_service.c new file mode 100644 index 0000000..ae6a4a1 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/cloud/aws_cloud_service.c @@ -0,0 +1,210 @@ +/* + \file aws_cloud_service.c + + \brief Cloud Specific Service + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include +#include +#include +#include +#include "cloud_interface.h" +#include "../config/mqtt_config.h" +#include "../config/cloud_config.h" +#include "../mqtt/mqtt_winc_adapter.h" +#include "../mqtt/mqtt_comm_bsd/mqtt_comm_layer.h" +#include "../mqtt/mqtt_packetTransfer_interface.h" +#include "../mqtt/mqtt_core/mqtt_core.h" +#include "mqtt_service.h" +#include "../time_service.h" +#include "../cloud/crypto_client/crypto_client.h" +#include "../drivers/timeout.h" +#include "../debug_print.h" +#include "../winc/common/winc_defines.h" +#include "../winc/m2m/m2m_ssl.h" +#include "../config/cloud_config.h" + + +publishReceptionHandler_t imqtt_publishReceiveCallBackTable[NUM_TOPICS_SUBSCRIBE]; + +void NETWORK_wifiSslCallback(uint8_t u8MsgType, void *pvMsg) +{ + switch (u8MsgType) + { + case M2M_SSL_REQ_ECC: + { + tstrEccReqInfo *ecc_request = (tstrEccReqInfo*)pvMsg; + CRYPTO_CLIENT_processEccRequest(ecc_request); + + break; + } + + case M2M_SSL_RESP_SET_CS_LIST: + { + tstrSslSetActiveCsList *pstrCsList = (tstrSslSetActiveCsList *)pvMsg; + debug_printInfo("ActiveCS bitmap:%04x", pstrCsList->u32CsBMP); + + break; + } + + default: + break; + } +} + +void CLOUD_init(timerStruct_t* appProtocolTimeoutTaskTimer, timerStruct_t* cloudResetTaskTimer) +{ + atcab_lock_data_zone(); + atcab_lock_config_zone(); + cloudStatus.isResetting = true; + debug_printError("CLOUD: Cloud reset timer is set"); + timeout_delete(appProtocolTimeoutTaskTimer); + timeout_create(cloudResetTaskTimer, CLOUD_RESET_TIMEOUT); + cloudStatus.cloudResetTimerFlag = true; +} + +int8_t CLOUD_connectSocket(uint32_t ipAddress) +{ + int8_t ret = BSD_SUCCESS; + + // Abstract the SSL section into a separate function + int8_t sslInit; + + sslInit = m2m_ssl_init(NETWORK_wifiSslCallback); + if(sslInit != M2M_SUCCESS) + { + debug_printInfo("WiFi SSL Initialization failed"); + } + + sslInit = m2m_ssl_set_active_ciphersuites((uint32_t)SSL_ECC_ONLY_CIPHERS); + if(sslInit != SOCK_ERR_NO_ERROR) + { + debug_printInfo("Set active cipher suites failed"); + } + + if (ipAddress > 0) + { + struct bsd_sockaddr_in addr; + + addr.sin_family = PF_INET; + addr.sin_port = BSD_htons(CFG_MQTT_PORT); + addr.sin_addr.s_addr = ipAddress; + + mqttContext *context = MQTT_GetClientConnectionInfo(); + socketState_t socketState = BSD_GetSocketState(*context->tcpClientSocket); + + // Todo: Check - Are we supposed to call close on the socket here to ensure we do not leak ? + if (socketState == NOT_A_SOCKET) + { + *context->tcpClientSocket = BSD_socket(PF_INET, BSD_SOCK_STREAM, 1); + + if (*context->tcpClientSocket >=0) + { + packetReceptionHandler_t* sockInfo = getSocketInfo(*context->tcpClientSocket); + if (sockInfo != NULL) + { + sockInfo->socketState = SOCKET_CLOSED; + } + } + } + + socketState = BSD_GetSocketState(*context->tcpClientSocket); + if (socketState == SOCKET_CLOSED) + { + debug_print("CLOUD: Connect socket"); + ret = BSD_connect(*context->tcpClientSocket, (struct bsd_sockaddr *)&addr, sizeof(struct bsd_sockaddr_in)); + + if (ret != BSD_SUCCESS) + { + debug_printError("CLOUD connect received %d",ret); + + BSD_close(*context->tcpClientSocket); + } + } + } + return ret; +} + +void CLOUD_connectAppProtocol(void) +{ + uint32_t timeStampReference; + timeStampReference = TIME_getCurrent(); + if (timeStampReference > 0) + { + MQTT_CLIENT_connect(); + debug_print("CLOUD: MQTT Connect"); + } + // MQTT SUBSCRIBE packet will be sent after the MQTT connection is established. + cloudStatus.sendSubscribe = true; +} + +void CLOUD_subscribe(void) +{ + if(MQTT_CLIENT_subscribe()) + { + cloudStatus.sendSubscribe = false; + } +} + +void CLOUD_publish(uint8_t* refToPublishTopic, uint8_t* data, unsigned int len) +{ + MQTT_CLIENT_publish(refToPublishTopic, data, len); +} + +void CLOUD_disconnect(void) +{ + debug_printError("CLOUD: Disconnect"); + if (MQTT_GetConnectionState() == CONNECTED) + { + if (MQTT_Disconnect(MQTT_GetClientConnectionInfo()) == DISCONNECTED) + { + debug_print("MQTT: sendresult (%d)", MQTT_LastSentSize()); + } + } +} + +bool CLOUD_isConnected(void) +{ + if (MQTT_GetConnectionState() == CONNECTED) + { + return true; + } + else + { + return false; + } +} + +bool CLOUD_isDisconnected(void) +{ + if (MQTT_GetConnectionState() == DISCONNECTED) + { + return true; + } + else + { + return false; + } +} + diff --git a/AVRIoT.X/mcc_generated_files/cloud/cloud_interface.h b/AVRIoT.X/mcc_generated_files/cloud/cloud_interface.h new file mode 100644 index 0000000..56c1126 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/cloud/cloud_interface.h @@ -0,0 +1,67 @@ +/* + * cloud_type.h + * + */ + +#ifndef CLOUD_INTERFACE_H +#define CLOUD_INTERFACE_H + +#include +#include +#include "../drivers/timeout.h" +#include "mqtt_service.h" + +#define CLOUD_RESET_TIMEOUT 2000L // 2 seconds + +typedef union +{ + uint8_t allBits; + struct + { + unsigned cloudInitialized :1; + unsigned cloudResetTimerFlag :1; + unsigned isResetting :1; + unsigned waitingForMQTT :1; + unsigned sendSubscribe :1; + unsigned unassigned :3; + }; +}cloudStatus_t; + +extern cloudStatus_t cloudStatus; + +extern publishReceptionHandler_t imqtt_publishReceiveCallBackTable[]; + +/** \brief Function pointer for interaction between the cloud core and user + * application to transition through differet cloud states. + **/ +typedef void (*cloudInitPtr)(timerStruct_t*, timerStruct_t*); +typedef int8_t (*cloudConnectSocketPtr)(uint32_t); +typedef void (*cloudConnectAppProtocolPtr) (void); +typedef void (*cloudSubscribePtr) (void); +typedef void (*cloudPublishPtr) (uint8_t* , uint8_t*, uint16_t); +typedef void (*cloudDisconnectPtr) (void); +typedef bool (*cloudIsConnectedPtr) (void); +typedef bool (*cloudIsDisconnectedPtr) (void); + +typedef struct +{ + cloudInitPtr cloudInit; + cloudConnectSocketPtr cloudConnectSocket; + cloudConnectAppProtocolPtr cloudConnectAppProtocol; + cloudSubscribePtr cloudSubscribe; + cloudPublishPtr cloudPublish; + cloudDisconnectPtr cloudDisconnect; + cloudIsConnectedPtr cloudIsConnected; + cloudIsDisconnectedPtr cloudIsDisconnected; +}cloudContext_t; + +void CLOUD_init(timerStruct_t* appProtocolTimeoutTaskTimer, timerStruct_t* cloudResetTaskTimer); +int8_t CLOUD_connectSocket(uint32_t ipAddress); +void CLOUD_connectAppProtocol(void); +void CLOUD_subscribe(void); +void CLOUD_publish(uint8_t* refToPublishTopic, uint8_t* data, uint16_t len); +void CLOUD_disconnect(void); +bool CLOUD_isConnected(void); +bool CLOUD_isDisconnected(void); + +#endif /* CLOUD_INTERFACE_H */ diff --git a/AVRIoT.X/mcc_generated_files/cloud/cloud_service.c b/AVRIoT.X/mcc_generated_files/cloud/cloud_service.c new file mode 100644 index 0000000..588d5c7 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/cloud/cloud_service.c @@ -0,0 +1,455 @@ +/* + \file cloud_service.c + + \brief Cloud Service Abstraction Layer + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include +#include +#include +#include "../config/clock_config.h" +#include +#include "../utils/atomic.h" +#include "../utils/compiler.h" +#include "../config/conf_winc.h" +#include "cloud_service.h" +#include "../debug_print.h" +#include "../mqtt/mqtt_winc_adapter.h" +#include "../drivers/timeout.h" +#include "mqtt_service.h" +#include "../mqtt/mqtt_core/mqtt_core.h" +#include "wifi_service.h" +#include "../credentials_storage/credentials_storage.h" + +#include "../led.h" +#include "../time_service.h" +#include "cloud_interface.h" + + +// Scheduler Callback functions +uint32_t cloudTask(void *param); +uint32_t mqttTimeoutTask(void *payload); +uint32_t cloudResetTask(void *payload); + +static void dnsHandler(uint8_t * domainName, uint32_t serverIP); +static uint8_t reInit(void); +static int32_t getMQTT_ConnectionAge(void); +static void CLOUD_handleReceptionDebugMessage(void); +static void CLOUD_handleTransmitDebugMessage(void); +static void startMqttConnectionTimeout(); +static bool hasLostWifi(); +static void setMqttStateToDisconnected(); +static bool isTimeAvailable(); +static void setHaveSocketFor(socketState_t socketState, int32_t thisAge); +static void handleSocketConnection(); +static void handleSocketState(socketState_t socketState, int32_t thisAge); + +#define CLOUD_TASK_INTERVAL 500L +#define CLOUD_MQTT_TIMEOUT_COUNT 10000L // 10 seconds max allowed to establish a connection +#define MQTT_CONN_AGE_TIMEOUT 3600L // 3600 seconds = 60minutes + +// Create the timers for scheduler_timeout which runs these tasks +timerStruct_t cloudTaskTimer = {cloudTask}; +timerStruct_t mqttTimeoutTaskTimer = {mqttTimeoutTask}; +timerStruct_t cloudResetTaskTimer = {cloudResetTask}; + +uint32_t mqttBrokerIP; +shared_networking_params_t shared_networking_params; +cloudStatus_t cloudStatus; +packetReceptionHandler_t cloud_packetReceiveCallBackTable[CLOUD_PACKET_RECV_TABLE_SIZE]; + +cloudContext_t cloudContext = +{ + CLOUD_init, + CLOUD_connectSocket, + CLOUD_connectAppProtocol, + CLOUD_subscribe, + CLOUD_publish, + CLOUD_disconnect, + CLOUD_isConnected, + CLOUD_isDisconnected +}; + + +void CLOUD_setInitFlag(void) +{ + debug_printError("CLOUD: Cloud Reset"); + cloudStatus.cloudInitialized = false; +} + +void CLOUD_setupTask(char* attDeviceID) +{ + // Create timers for the application scheduler + timeout_create(&cloudTaskTimer, 500); +} + +void CLOUD_registerSubscription(uint8_t *topic, imqttHandlePublishDataFuncPtr subscriptionCallback) +{ + static uint8_t subscriptionTopicCount = 0; + + if(subscriptionTopicCount < NUM_TOPICS_SUBSCRIBE) + { + imqtt_publishReceiveCallBackTable[subscriptionTopicCount].topic = topic; + imqtt_publishReceiveCallBackTable[subscriptionTopicCount].mqttHandlePublishDataCallBack = subscriptionCallback; + } + subscriptionTopicCount++; + MQTT_SetPublishReceptionHandlerTable(imqtt_publishReceiveCallBackTable); +} + +void CLOUD_publishData(uint8_t* refToPublishTopic, uint8_t* data, uint16_t len) +{ + cloudContext.cloudPublish(refToPublishTopic, data, len); +} + +bool CLOUD_checkIsConnected(void) +{ + return cloudContext.cloudIsConnected(); +} + +uint32_t mqttTimeoutTask(void *payload) +{ + debug_printError("CLOUD: MQTT Connection Timeout"); + CLOUD_setInitFlag(); + + cloudStatus.waitingForMQTT = false; + + return 0; +} + +uint32_t cloudResetTask(void *payload) +{ + debug_printError("CLOUD: Reset task"); + if(reInit()) + { + cloudStatus.cloudInitialized = true; + } + else + { + cloudStatus.cloudInitialized = false; + } + return 0; +} + +uint32_t cloudTask(void *param) +{ + if ((cloudStatus.cloudInitialized == false) && (cloudStatus.isResetting == false)) + { + cloudContext.cloudInit(&mqttTimeoutTaskTimer, &cloudResetTaskTimer); + } + else if ((cloudStatus.waitingForMQTT == false) + && (!cloudContext.cloudIsConnected()) + && (cloudStatus.cloudResetTimerFlag == false)) + { + startMqttConnectionTimeout(); + } + + if(hasLostWifi()) { + setMqttStateToDisconnected(); + } + else + { + handleSocketConnection(); + } + return CLOUD_TASK_INTERVAL; +} + +static void startMqttConnectionTimeout() +{ + debug_printError("MQTT: MQTT reset timer is created"); + timeout_create(&mqttTimeoutTaskTimer, CLOUD_MQTT_TIMEOUT_COUNT); + cloudStatus.waitingForMQTT = true; +} + +static bool hasLostWifi() +{ + return shared_networking_params.haveAPConnection == 0; +} + +static void setMqttStateToDisconnected() +{ + if(cloudContext.cloudIsConnected()) + { + MQTT_initialiseState(); + } +} + +static bool isTimeAvailable() +{ + uint32_t theTime = TIME_getCurrent(); + if(theTime<=0) + { + debug_printError("CLOUD: time not ready"); + return false; + } + return true; +} + +static void setHaveSocketFor(socketState_t socketState, int32_t thisAge) +{ + static int32_t lastAge = -1; + + if(cloudContext.cloudIsConnected()) + { + shared_networking_params.haveSocket = 1; + if(lastAge != thisAge) + { + debug_printInfo("CLOUD: Uptime %lus SocketState (%d) MQTT (%d)", thisAge , socketState, MQTT_GetConnectionState()); + lastAge = thisAge; + } + } +} + +static void handleSocketConnection() +{ + mqttContext* mqttConnnectionInfo = MQTT_GetClientConnectionInfo(); + socketState_t socketState = BSD_GetSocketState(*mqttConnnectionInfo->tcpClientSocket); + + int32_t thisAge = getMQTT_ConnectionAge(); + if(isTimeAvailable()) + { + setHaveSocketFor(socketState, thisAge); + } + + handleSocketState(socketState, thisAge); +} + +static void handleSocketState(socketState_t socketState, int32_t thisAge) +{ + switch(socketState) + { + case NOT_A_SOCKET: + // Intentionally fall into Socket Closed + + case SOCKET_CLOSED: + // Reinitialize MQTT + MQTT_ClientInitialise(); + if(cloudContext.cloudConnectSocket(mqttBrokerIP) == BSD_ERROR) + { + shared_networking_params.haveError = 1; + } + else + { + // ToDo Check LED behavior + shared_networking_params.amConnectingSocket = 1; + } + break; + + case SOCKET_IN_PROGRESS: + // The TCP listen or initiate a connection + // WG Application requires no action + break; + + case SOCKET_CONNECTED: + // If MQTT was disconnected but the socket is up we retry the MQTT connection + if (cloudContext.cloudIsDisconnected()) + { + cloudContext.cloudConnectAppProtocol(); + } + else + { + mqttCurrentState receptionResponse; + mqttContext* mqttConnnectionInfo = MQTT_GetClientConnectionInfo(); + receptionResponse = MQTT_ReceptionHandler(mqttConnnectionInfo); + if (receptionResponse != MQTT_UNKNOWN_RECEIVE_STATE) + { + CLOUD_handleReceptionDebugMessage(); + } + else + { + debug_printError("MQTT: Packet type: %d. MQTT Client does not currently support the received packet type.", receptionResponse); + } + + MQTT_TransmissionHandler(mqttConnnectionInfo); + CLOUD_handleTransmitDebugMessage(); + + // Todo: We already processed the data in place using PEEK, this just flushes the buffer + BSD_recv(*MQTT_GetClientConnectionInfo()->tcpClientSocket, MQTT_GetClientConnectionInfo()->mqttDataExchangeBuffers.rxbuff.start, MQTT_GetClientConnectionInfo()->mqttDataExchangeBuffers.rxbuff.bufferLength, 0); + + if (cloudContext.cloudIsConnected()) + { + shared_networking_params.amConnectingSocket = 0; + shared_networking_params.haveError = 0; + timeout_delete(&mqttTimeoutTaskTimer); + timeout_delete(&cloudResetTaskTimer); + cloudStatus.isResetting = false; + + cloudStatus.waitingForMQTT = false; + + if(cloudStatus.sendSubscribe == true) + { + cloudContext.cloudSubscribe(); + } + + // The Authorization timeout is set to 3600, so we need to re-connect that often + if (getMQTT_ConnectionAge() > MQTT_CONN_AGE_TIMEOUT) + { + debug_printError("MQTT: Connection aged, Uptime %lus SocketState (%d) MQTT (%d)", thisAge , socketState, MQTT_GetConnectionState()); + cloudContext.cloudDisconnect(); + BSD_close(*mqttConnnectionInfo->tcpClientSocket); + } + } + } + break; + + case SOCKET_CLOSING: + // The user initiate the closing procedure for this socket + // WG Application requires no action + break; + + default: + // Unknown State + shared_networking_params.haveError = 1; + break; + } +} + +static void CLOUD_handleReceptionDebugMessage(void) +{ + uint32_t timeStampReference = 0; + mqttHandlerState_t receptionState = MQTT_NO_ERROR; + mqttHeaderFlags lastPacketHeader; + + receptionState = MQTT_GetLastHandlerState(); + + switch (receptionState) + { + case MQTT_CONNACK_TIMEOUT: + debug_printError("MQTT: CONNACK TIMEOUT"); + break; + case MQTT_INCORRECT_RESPONSE: + lastPacketHeader = MQTT_GetLastReceivedPacketHeader(); + debug_printError("MQTT: DISCONNECT (%d) from (%d)", lastPacketHeader.controlPacketType, MQTT_GetLastReceivedLength); + break; + case MQTT_CONNACK_ERROR: + debug_printError("MQTT: CONNACK DISCONNECTED :("); + break; + case MQTT_CONNACK: + timeStampReference = TIME_getCurrent(); + TIME_setStamp(timeStampReference); + debug_printGOOD("MQTT: CONNACK CONNECTED at %s", TIME_GetcTime(TIME_getStamp())); + break; + case MQTT_NO_ERROR: + // Do Nothing + break; + default: + debug_printError("MQTT: STATE ERROR_OCCURED"); + break; + } +} + +static void CLOUD_handleTransmitDebugMessage(void) +{ + mqttHandlerState_t transmitState = MQTT_NO_ERROR; + transmitState = MQTT_GetLastHandlerState(); + + switch (transmitState) + { + case MQTT_SEND_SUCCESS: + debug_print("MQTT: sendresult (%d)", MQTT_LastSentSize()); + break; + case MQTT_SEND_ERROR: + debug_printError("MQTT: Send Error"); + break; + default: + break; + } +} + +bool CLOUD_checkIsDisconnected(void) +{ + return cloudContext.cloudIsDisconnected(); +} + +static void dnsHandler(uint8_t* domainName, uint32_t serverIP) +{ + if(serverIP != 0) + { + mqttBrokerIP = serverIP; + debug_printInfo("CLOUD: mqttBrokerIP = (%lu.%lu.%lu.%lu)",(0x0FF & (serverIP)),(0x0FF & (serverIP>>8)),(0x0FF & (serverIP>>16)),(0x0FF & (serverIP>>24))); + } +} + +static uint8_t reInit(void) +{ + debug_printInfo("CLOUD: reinit"); + + mqttBrokerIP = 0; + shared_networking_params.haveAPConnection = 0; + shared_networking_params.amConnectingAP = 1; + cloudStatus.waitingForMQTT = false; + cloudStatus.isResetting = false; + uint8_t wifi_creds; + + //Re-init the WiFi + wifi_reinit(); + + registerSocketCallback(BSD_SocketHandler, dnsHandler); + + MQTT_ClientInitialise(); + memset(&cloud_packetReceiveCallBackTable, 0, sizeof(cloud_packetReceiveCallBackTable)); + BSD_SetRecvHandlerTable(cloud_packetReceiveCallBackTable); + + cloud_packetReceiveCallBackTable[0].socket = MQTT_GetClientConnectionInfo()->tcpClientSocket; + cloud_packetReceiveCallBackTable[0].recvCallBack = MQTT_CLIENT_receive; + + //When the input comes through cli/.cfg + if((strcmp(ssid,"") != 0) && (strcmp(authType,"") != 0)) + { + wifi_creds = NEW_CREDENTIALS; + debug_printInfo("Connecting to AP with new credentials"); + } + //This works provided the board had connected to the AP successfully + else + { + wifi_creds = DEFAULT_CREDENTIALS; + debug_printInfo("Connecting to AP with the last used credentials"); + } + + if(!wifi_connectToAp(wifi_creds)) + { + return false; + } + + timeout_delete(&cloudResetTaskTimer); + debug_printInfo("CLOUD: Cloud reset timer is deleted"); + timeout_create(&mqttTimeoutTaskTimer, CLOUD_MQTT_TIMEOUT_COUNT); + cloudStatus.cloudResetTimerFlag = false; + cloudStatus.waitingForMQTT = true; + + return true; +} + +static int32_t getMQTT_ConnectionAge(void) +{ + int32_t currentTime = 0; + int32_t age = 0; + int32_t lastConnectionTime = TIME_getStamp(); + if (lastConnectionTime > 0) + { + currentTime = TIME_getCurrent(); + age = TIME_getDiffTime(currentTime, lastConnectionTime); + } + return age; +} + diff --git a/AVRIoT.X/mcc_generated_files/cloud/cloud_service.h b/AVRIoT.X/mcc_generated_files/cloud/cloud_service.h new file mode 100644 index 0000000..63dc29b --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/cloud/cloud_service.h @@ -0,0 +1,44 @@ +/* + * cloud_service.h + * + * Created: 9/27/2018 2:25:12 PM + * Author: C14674 + */ + +#ifndef CLOUD_SERVICE_H_ +#define CLOUD_SERVICE_H_ + +#include +#include +#include "../utils/compiler.h" +#include "../mqtt/mqtt_packetTransfer_interface.h" + + +#define CLOUD_PACKET_RECV_TABLE_SIZE 2 + + +typedef union +{ + uint8_t allBits; + struct + { + unsigned amDisconnecting :1; + unsigned haveAPConnection :1; + unsigned haveError :1; + unsigned amConnectingAP : 1; + unsigned amConnectingSocket : 1; + unsigned amSoftAP: 1; + unsigned amDefaultCred : 1; + unsigned haveSocket : 1; + }; +} shared_networking_params_t; + +extern shared_networking_params_t shared_networking_params; + +void CLOUD_setInitFlag(void); +void CLOUD_setupTask(char* deviceId); +void CLOUD_publishData(uint8_t* refToPublishTopic, uint8_t* data, unsigned int len); +void CLOUD_registerSubscription(uint8_t *topic, imqttHandlePublishDataFuncPtr subscriptionCallback); +bool CLOUD_checkIsConnected(void); +bool CLOUD_checkIsDisconnected(void); +#endif /* CLOUD_SERVICE_H_ */ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/cloud/crypto_client/crypto_client.c b/AVRIoT.X/mcc_generated_files/cloud/crypto_client/crypto_client.c new file mode 100644 index 0000000..bd65dde --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/cloud/crypto_client/crypto_client.c @@ -0,0 +1,352 @@ +/* + \file crypto_client.c + + \brief Crypto Client source file. + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ +#include +#include "../../CryptoAuthenticationLibrary/cryptoauthlib_config.h" +#include "CryptoAuthenticationLibrary/jwt/atca_jwt.h" +#include "CryptoAuthenticationLibrary/basic/atca_basic.h" +#include "crypto_client.h" +#include "../cloud_service.h" +#include "../../CryptoAuthenticationLibrary/CryptoAuth_init.h" + +#include "CryptoAuthenticationLibrary/cryptoauthlib.h" +#include "winc/m2m/m2m_ssl.h" +#include "winc/common/winc_defines.h" +#include "../debug_print.h" + + +#ifndef ATCA_NO_HEAP +#error : This project uses CryptoAuthLibrary V2. Please add "ATCA_NO_HEAP" to toolchain symbols. +#endif + +#ifndef ATCA_NO_POLL +#error : This project uses ATCA_NO_POLL option. Please add "ATCA_NO_POLL" to toolchain symbols. +#endif + +#ifndef ATCA_HAL_I2C +#error : This project uses I2C interface. Please add "ATCA_HAL_I2C" to toolchain symbols. +#endif + +#ifndef ATCAPRINTF +#error : This project uses ATCA_debug_print. Please add "ATCA_PRINTF" to toolchain symbols. +#endif + +#define DEVICE_KEY_SLOT (0) +static uint32_t g_ecdh_key_slot_index = 0; +static uint16_t g_ecdh_key_slot[] = {2}; + +const uint8_t public_key_x509_header[] = { 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, + 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, + 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, +0x42, 0x00, 0x04 }; + +uint8_t g_serial_number[ATCA_SERIAL_NUM_SIZE]; + +/** \brief custom configuration for an ECCx08A device */ +ATCAIfaceCfg cfg_ateccx08a_i2c_custom = { + .iface_type = ATCA_I2C_IFACE, + .devtype = ATECC608A, + .atcai2c.slave_address = 0xB0, + .atcai2c.bus = 2, + .atcai2c.baud = 100000, + .wake_delay = 1500, + .rx_retries = 20 +}; + + +//To do: Move this under Google specific section, once the CLI command "key" is handled +uint8_t CRYPTO_CLIENT_printPublicKey(char *s) +{ + char buf[128]; + uint8_t *tmp; + size_t bufferLen = sizeof(buf); + ATCA_STATUS retVal; + + if (ATCA_SUCCESS != atcab_init(&cfg_ateccx08a_i2c_custom)) + { + return ERROR; + } + + /* Calculate where the raw data will fit into the buffer */ + tmp = (uint8_t*)buf + sizeof(buf) - ATCA_PUB_KEY_SIZE - sizeof(public_key_x509_header); + + /* Copy the header */ + memcpy(tmp, public_key_x509_header, sizeof(public_key_x509_header)); + + /* Get public key without private key generation */ + retVal = atcab_get_pubkey(0, tmp + sizeof(public_key_x509_header)); + + if (ATCA_SUCCESS != retVal ) + { + return ERROR; + } + + /* Convert to base 64 */ + retVal = atcab_base64encode(tmp, ATCA_PUB_KEY_SIZE + sizeof(public_key_x509_header), buf, &bufferLen); + + if(ATCA_SUCCESS != retVal) + { + return ERROR; + } + + /* Add a null terminator */ + buf[bufferLen] = 0; + + /* Print out the key */ + sprintf(s, "-----BEGIN PUBLIC KEY-----\r\n%s\r\n-----END PUBLIC KEY-----\r\n\4", buf); + + return NO_ERROR; +} + +uint8_t CRYPTO_CLIENT_printSerialNumber(char *s) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint8_t i = 0; + + int retVal = atcab_init(&cfg_ateccx08a_i2c_custom); + + if (ATCA_SUCCESS != retVal) + { + return retVal; + } + + status = atcab_read_serial_number(g_serial_number); + if (status == ATCA_SUCCESS) + { + for (i = 0; i < ATCA_SERIAL_NUM_SIZE; i++) + { + sprintf(s, "%02X", g_serial_number[i]); + s += 2; + } + } + else{ + return ERROR; + } + + return NO_ERROR; +} + + +int8_t ecdh_derive_client_shared_secret(tstrECPoint *server_public_key, uint8_t *ecdh_shared_secret, tstrECPoint *client_public_key) +{ + int8_t status = M2M_ERR_FAIL; + uint8_t ecdh_mode; + uint16_t key_id; + + if ((g_ecdh_key_slot_index < 0) || + (g_ecdh_key_slot_index >= (sizeof(g_ecdh_key_slot) / sizeof(g_ecdh_key_slot[0])))) + { + g_ecdh_key_slot_index = 0; + } + + if(_gDevice->mIface->mIfaceCFG->devtype == ATECC608A) + { + //do special ecdh functions for the 608, keep ephemeral keys in SRAM + ecdh_mode = ECDH_MODE_SOURCE_TEMPKEY | ECDH_MODE_COPY_OUTPUT_BUFFER; + key_id = GENKEY_PRIVATE_TO_TEMPKEY; + } + else + { + //specializations for the 508, use an EEPROM key slot + ecdh_mode = ECDH_PREFIX_MODE; + key_id = g_ecdh_key_slot[g_ecdh_key_slot_index]; + g_ecdh_key_slot_index++; + } + + //generate an ephemeral key + if(atcab_genkey(key_id, client_public_key->X) == ATCA_SUCCESS) + { + client_public_key->u16Size = 32; + //do the ecdh from the private key in tempkey, results put in ecdh_shared_secret + if(atcab_ecdh_base(ecdh_mode, key_id, server_public_key->X, ecdh_shared_secret, NULL) == ATCA_SUCCESS) + { + status = M2M_SUCCESS; + } + } + + return status; +} + +int8_t ecdh_derive_key_pair(tstrECPoint *server_public_key) +{ + int8_t status = M2M_ERR_FAIL; + + if ((g_ecdh_key_slot_index < 0) || + (g_ecdh_key_slot_index >= (sizeof(g_ecdh_key_slot) / sizeof(g_ecdh_key_slot[0])))) + { + g_ecdh_key_slot_index = 0; + } + + if( (status = atcab_genkey(g_ecdh_key_slot[g_ecdh_key_slot_index], server_public_key->X) ) == ATCA_SUCCESS) + { + server_public_key->u16Size = 32; + server_public_key->u16PrivKeyID = g_ecdh_key_slot[g_ecdh_key_slot_index]; + + g_ecdh_key_slot_index++; + + status = M2M_SUCCESS; + } + + return status; +} + +int8_t ecdsa_process_sign_verify_request(uint32_t number_of_signatures) +{ + int8_t status = M2M_ERR_FAIL; + tstrECPoint Key; + uint32_t index = 0; + uint8_t signature[80]; + uint8_t hash[80] = {0}; + uint16_t curve_type = 0; + + for(index = 0; index < number_of_signatures; index++) + { + status = m2m_ssl_retrieve_cert(&curve_type, hash, signature, &Key); + + if (status != M2M_SUCCESS) + { + debug_printInfo("m2m_ssl_retrieve_cert() failed with ret=%d", status); + return status; + } + + if(curve_type == EC_SECP256R1) + { + bool is_verified = false; + + status = atcab_verify_extern(hash, signature, Key.X, &is_verified); + if(status == ATCA_SUCCESS) + { + status = (is_verified == true) ? M2M_SUCCESS : M2M_ERR_FAIL; + if(is_verified == false) + { + debug_printInfo("ECDSA SigVerif FAILED"); + } + } + else + { + status = M2M_ERR_FAIL; + } + + if(status != M2M_SUCCESS) + { + m2m_ssl_stop_processing_certs(); + break; + } + } + } + + return status; +} + +int8_t ecdsa_process_sign_gen_request(tstrEcdsaSignReqInfo *sign_request, uint8_t *signature, uint16_t *signature_size) +{ + int8_t status = M2M_ERR_FAIL; + uint8_t hash[32]; + + status = m2m_ssl_retrieve_hash(hash, sign_request->u16HashSz); + if (status != M2M_SUCCESS) + { + debug_printInfo("m2m_ssl_retrieve_hash() failed with ret=%d", status); + return status; + } + + if(sign_request->u16CurveType == EC_SECP256R1) + { + *signature_size = 64; + status = atcab_sign(DEVICE_KEY_SLOT, hash, signature); + } + + return status; +} + +int8_t ecdh_derive_server_shared_secret(uint16_t private_key_id, tstrECPoint *client_public_key, uint8_t *ecdh_shared_secret) +{ + uint16_t key_slot = private_key_id; + int8_t status = M2M_ERR_FAIL; + uint8_t atca_status = ATCA_STATUS_UNKNOWN; + + atca_status = atcab_ecdh(key_slot, client_public_key->X, ecdh_shared_secret); + if(atca_status == ATCA_SUCCESS) + { + status = M2M_SUCCESS; + } + else + { + debug_printInfo("__SLOT = %u, Err = %X", key_slot, atca_status); + } + + return status; +} + +void CRYPTO_CLIENT_processEccRequest(tstrEccReqInfo *ecc_request) +{ + tstrEccReqInfo ecc_response; + uint8_t signature[80]; + uint16_t response_data_size = 0; + uint8_t *response_data_buffer = NULL; + + ecc_response.u16Status = 1; + + switch (ecc_request->u16REQ) + { + case ECC_REQ_CLIENT_ECDH: + ecc_response.u16Status = ecdh_derive_client_shared_secret(&(ecc_request->strEcdhREQ.strPubKey), + ecc_response.strEcdhREQ.au8Key, + &ecc_response.strEcdhREQ.strPubKey); + break; + + case ECC_REQ_GEN_KEY: + ecc_response.u16Status = ecdh_derive_key_pair(&ecc_response.strEcdhREQ.strPubKey); + break; + + case ECC_REQ_SERVER_ECDH: + ecc_response.u16Status = ecdh_derive_server_shared_secret(ecc_request->strEcdhREQ.strPubKey.u16PrivKeyID, + &(ecc_request->strEcdhREQ.strPubKey), + ecc_response.strEcdhREQ.au8Key); + break; + + case ECC_REQ_SIGN_VERIFY: + ecc_response.u16Status = ecdsa_process_sign_verify_request(ecc_request->strEcdsaVerifyREQ.u32nSig); + break; + + case ECC_REQ_SIGN_GEN: + ecc_response.u16Status = ecdsa_process_sign_gen_request(&(ecc_request->strEcdsaSignREQ), signature, + &response_data_size); + response_data_buffer = signature; + break; + + default: + // Do nothing + break; + } + + ecc_response.u16REQ = ecc_request->u16REQ; + ecc_response.u32UserData = ecc_request->u32UserData; + ecc_response.u32SeqNo = ecc_request->u32SeqNo; + + m2m_ssl_ecc_process_done(); + m2m_ssl_handshake_rsp(&ecc_response, response_data_buffer, response_data_size); +} diff --git a/AVRIoT.X/mcc_generated_files/cloud/crypto_client/crypto_client.h b/AVRIoT.X/mcc_generated_files/cloud/crypto_client/crypto_client.h new file mode 100644 index 0000000..d19fa15 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/cloud/crypto_client/crypto_client.h @@ -0,0 +1,51 @@ +/* + \file crypto_client.h + + \brief Crypto Client header file. + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef CRYPTO_CLIENT_H +#define CRYPTO_CLIENT_H + +#define ERROR 1 +#define NO_ERROR 0 + +#include +#include "CryptoAuthenticationLibrary/atca_iface.h" +#include "../../CryptoAuthenticationLibrary/cryptoauthlib.h" + +#include "CryptoAuthenticationLibrary/cryptoauthlib.h" +#include "winc/driver/winc_adapter.h" +#include "winc/common/ecc_types.h" + +uint8_t CRYPTO_CLIENT_printPublicKey(char *s); +uint8_t CRYPTO_CLIENT_printSerialNumber(char *s); +void CRYPTO_CLIENT_processEccRequest(tstrEccReqInfo *ecc_request); +int8_t ecdsa_process_sign_verify_request(uint32_t number_of_signatures); +int8_t ecdh_derive_key_pair(tstrECPoint *server_public_key); +int8_t ecdh_derive_client_shared_secret(tstrECPoint *server_public_key, uint8_t *ecdh_shared_secret, tstrECPoint *client_public_key); +int8_t ecdsa_process_sign_gen_request(tstrEcdsaSignReqInfo *sign_request, uint8_t *signature, uint16_t *signature_size); +int8_t ecdh_derive_server_shared_secret(uint16_t private_key_id, tstrECPoint *client_public_key, uint8_t *ecdh_shared_secret); + +#endif /* CRYPTO_CLIENT_H */ diff --git a/AVRIoT.X/mcc_generated_files/cloud/mqtt_service.c b/AVRIoT.X/mcc_generated_files/cloud/mqtt_service.c new file mode 100644 index 0000000..7729e1b --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/cloud/mqtt_service.c @@ -0,0 +1,152 @@ +/* + \file mqtt_service.c + + \brief Application MQTT Service source file. + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ +#include +#include +#include +#include "mqtt_service.h" +#include "mqtt_core/mqtt_core.h" +#include "../mqtt/mqtt_packetTransfer_interface.h" +#include "../config/IoT_Sensor_Node_config.h" +#include "../debug_print.h" + +char cid[MQTT_CID_LENGTH]; +char awsEndpoint[AWS_ENDPOINT_LEN]; +static publishReceptionHandler_t *publishRecvInfo; + + +static void manageSubscriptionMessage(uint8_t *topic, uint8_t *payload); + +static void manageSubscriptionMessage(uint8_t *topic, uint8_t *payload) +{ + const publishReceptionHandler_t *publishRecvHandlerInfo; + uint8_t subTopicIndex; + const char multiLevelWildcard = '#'; + + // Direct messages published on a topic to the correct callback function. + publishRecvHandlerInfo = MQTT_GetPublishReceptionHandlerTable(); + for (subTopicIndex = 0; subTopicIndex < NUM_TOPICS_SUBSCRIBE; subTopicIndex++) + { + if (publishRecvHandlerInfo) + { + if(strchr((const char*)publishRecvHandlerInfo->topic, multiLevelWildcard)) + { + if(!strncmp(topic, publishRecvHandlerInfo->topic, (strlen(publishRecvHandlerInfo->topic) - 1))) + { + publishRecvHandlerInfo->mqttHandlePublishDataCallBack(topic, payload); + break; + } + } + else if(memcmp((void*) publishRecvHandlerInfo->topic, (void*) topic, strlen(publishRecvHandlerInfo->topic)) == 0) + { + publishRecvHandlerInfo->mqttHandlePublishDataCallBack(topic, payload); + break; + } + } + publishRecvHandlerInfo++; + } +} + +void MQTT_SetPublishReceptionHandlerTable(publishReceptionHandler_t *appPublishReceptionInfo) +{ + publishRecvInfo = appPublishReceptionInfo; +} + +publishReceptionHandler_t *MQTT_GetPublishReceptionHandlerTable() +{ + return publishRecvInfo; +} + + + +void MQTT_CLIENT_publish(uint8_t* refToPublishTopic, uint8_t *data, uint16_t len) +{ + mqttPublishPacket cloudPublishPacket; + + // Fixed header + cloudPublishPacket.publishHeaderFlags.duplicate = 0; + cloudPublishPacket.publishHeaderFlags.qos = 0; + cloudPublishPacket.publishHeaderFlags.retain = 0; + + // Variable header + cloudPublishPacket.topic = (uint8_t*)refToPublishTopic; + + // Payload + cloudPublishPacket.payload = data; + // ToDo Check whether sizeof can be used for integers and strings + cloudPublishPacket.payloadLength = len; + + if(MQTT_CreatePublishPacket(&cloudPublishPacket) != true) + { + debug_printError("MQTT: Connection lost PUBLISH failed"); + } +} + +bool MQTT_CLIENT_subscribe(void) +{ + mqttSubscribePacket cloudSubscribePacket; + uint8_t topicCount = 0; + + publishReceptionHandler_t (*subscriptionTable)[] = MQTT_GetPublishReceptionHandlerTable(); + + // Variable header + cloudSubscribePacket.packetIdentifierLSB = 1; + cloudSubscribePacket.packetIdentifierMSB = 0; + + // Payload + for(topicCount = 0; topicCount < NUM_TOPICS_SUBSCRIBE; topicCount++) + { + cloudSubscribePacket.subscribePayload[topicCount].topic = (*subscriptionTable)[topicCount].topic; + cloudSubscribePacket.subscribePayload[topicCount].topicLength = strlen((*subscriptionTable)[topicCount].topic); + cloudSubscribePacket.subscribePayload[topicCount].requestedQoS = 0; + } + + if(MQTT_CreateSubscribePacket(&cloudSubscribePacket) == true) + { + debug_printInfo("CLOUD: SUBSCRIBE packet created"); + return true; + } + return false; +} + +void MQTT_CLIENT_receive(uint8_t *data, uint8_t len) +{ + MQTT_GetReceivedData(data, len); +} + +void MQTT_CLIENT_connect(void) +{ + mqttConnectPacket cloudConnectPacket; + + memset(&cloudConnectPacket, 0, sizeof(mqttConnectPacket)); + + cloudConnectPacket.connectVariableHeader.connectFlagsByte.All = 0x02; + cloudConnectPacket.connectVariableHeader.keepAliveTimer = 10; + cloudConnectPacket.clientID = (uint8_t*)cid; + // Set the subscription callback handler here + MQTT_SetPublishReceptionCallback(manageSubscriptionMessage); + MQTT_CreateConnectPacket(&cloudConnectPacket); +} diff --git a/AVRIoT.X/mcc_generated_files/cloud/mqtt_service.h b/AVRIoT.X/mcc_generated_files/cloud/mqtt_service.h new file mode 100644 index 0000000..fddcee5 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/cloud/mqtt_service.h @@ -0,0 +1,78 @@ +/* + \file mqtt_service.h + + \brief Application MQTT Service header file. + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ +#ifndef MQTT_SERVICE_H +#define MQTT_SERVICE_H + +#include +#include +#include "../mqtt/mqtt_packetTransfer_interface.h" + + +extern char cid[]; +extern char awsEndpoint[]; + +// The call back table prototype for sending the payload received as part of +// PUBLISH packet to the correct publish reception handler function defined in +// the application manager. An instance of this table needs to be initialised by +// the user application to specify the total number of topics to subscribe to, +// the path of each topic and the call back function for handling the payload +// received as part of the PUBLISH packet. +typedef struct +{ + uint8_t *topic; + imqttHandlePublishDataFuncPtr mqttHandlePublishDataCallBack; +} publishReceptionHandler_t; + + +void MQTT_CLIENT_publish(uint8_t* refToPublishTopic, uint8_t *data, uint16_t len); +bool MQTT_CLIENT_subscribe(void); +void MQTT_CLIENT_receive(uint8_t *data, uint8_t len); +void MQTT_CLIENT_connect(void); + +/** \brief Set the publish reception handler table information. + * + * This function is called by the user application to inform the MQTT core of + * the call back table defined to handler the received PUBLISH messages. + * + * @param appPublishReceptionInfo Instance of publishReceptionHandler_t with + * callback functions to handle PUBLISH messages + * received for each topic + */ +void MQTT_SetPublishReceptionHandlerTable(publishReceptionHandler_t *appPublishReceptionInfo); + +/** \brief Obtain the publishReceptionHandler_t table information defined in the + * user application that the application. + * + * Whenever a PUBLISH baclet is received by the MQTT core, the publish handlers + * returned by this function are called to process the payload of the PUBLISH + * packet. + * + * @return publish reception handler details defined in the user application + */ +publishReceptionHandler_t *MQTT_GetPublishReceptionHandlerTable(); + +#endif /* MQTT_SERVICE_H */ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/cloud/wifi_service.c b/AVRIoT.X/mcc_generated_files/cloud/wifi_service.c new file mode 100644 index 0000000..46d53b6 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/cloud/wifi_service.c @@ -0,0 +1,428 @@ +/* +\file wifi_service.c + +\brief Wifi service source file. + +(c) 2018 Microchip Technology Inc. and its subsidiaries. + +Subject to your compliance with these terms, you may use Microchip software and any +derivatives exclusively with Microchip products. It is your responsibility to comply with third party +license terms applicable to your use of third party software (including open source software) that +may accompany Microchip software. + +THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER +EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY +IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS +FOR A PARTICULAR PURPOSE. + +IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, +INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND +WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP +HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO +THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL +CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT +OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS +SOFTWARE. +*/ + +#include +#include +#include +#include +#include "../time_service.h" +#include "wifi_service.h" +#include "../winc/m2m/m2m_wifi.h" +#include "../winc/common/winc_defines.h" +#include "../winc/driver/winc_adapter.h" +#include "../drivers/timeout.h" +#include "../cloud/cloud_service.h" +#include "../debug_print.h" +#include "../config/IoT_Sensor_Node_config.h" +#include "../config/conf_winc.h" +#include "../config/mqtt_config.h" +#include "../config/cloud_config.h" +#include "../winc/socket/socket.h" +#include "../credentials_storage/credentials_storage.h" +#include "../led.h" +#include "winc/m2m/m2m_types.h" + +#include "cloud/mqtt_service.h" +#include "winc/m2m/m2m_wifi.h" +#include "winc/spi_flash/spi_flash.h" +#include "winc/spi_flash/spi_flash_map.h" +#include "winc/common/winc_defines.h" +#include "config/cloud_config.h" + + +//Flash location to read thing ID from winc +#define THING_NAME_FLASH_OFFSET (M2M_TLS_SERVER_FLASH_OFFSET + M2M_TLS_SERVER_FLASH_SIZE - FLASH_PAGE_SZ) +#define AWS_ENDPOINT_FLASH_OFFSET (THING_NAME_FLASH_OFFSET - FLASH_PAGE_SZ) +#define CLOUD_WIFI_TASK_INTERVAL 50L +#define CLOUD_NTP_TASK_INTERVAL 500L +#define SOFT_AP_CONNECT_RETRY_INTERVAL 1000L + +#define MAX_NTP_SERVER_LENGTH 20 + +char prevNTPServerName[MAX_NTP_SERVER_LENGTH]; + +// Scheduler +uint32_t ntpTimeFetchTask(void *payload); +uint32_t wifiHandlerTask(void * param); +uint32_t softApConnectTask(void* param); + +timerStruct_t softApConnectTimer = {softApConnectTask}; +timerStruct_t ntpTimeFetchTimer = {ntpTimeFetchTask}; +timerStruct_t wifiHandlerTimer = {wifiHandlerTask}; + +uint32_t checkBackTask(void * param); +timerStruct_t checkBackTimer = {checkBackTask}; + +static bool responseFromProvisionConnect = false; + +void (*callback_funcPtr)(uint8_t); + +void enable_provision_ap(void); + +// Callback function pointer for indicating status updates upwards +void (*wifiConnectionStateChangedCallback)(uint8_t status) = NULL; + +// Function to be called by WifiModule on status updates from below +static void wifiCallback(uint8_t msgType, void *pMsg); + +// This is a workaround to wifi_deinit being broken in the winc, so we can de-init without hanging up +int8_t winc_hif_deinit(void * arg); + +void wifi_reinit() +{ + tstrWifiInitParam param ; + + /* Initialize Wi-Fi parameters structure. */ + memset((uint8_t *)¶m, 0, sizeof(tstrWifiInitParam)); + + param.pfAppWifiCb = wifiCallback; + socketDeinit(); + winc_hif_deinit(NULL); + winc_adapter_deinit(); + + wifiConnectionStateChangedCallback = callback_funcPtr; + + winc_adapter_init(); + + m2m_wifi_init(¶m); + socketInit(); +} + +// funcPtr passed in here will be called indicating AP state changes with the following values +// Wi-Fi state is disconnected == 0 +// Wi-Fi state is connected == 1 +// Wi-Fi state is undefined == 0xff +void wifi_init(void (*funcPtr)(uint8_t), uint8_t mode) { + callback_funcPtr = funcPtr; + + // This uses the global ptr set above + wifi_reinit(); + + // Mode == 0 means AP configuration mode + if(mode == WIFI_SOFT_AP) + { + enable_provision_ap(); + debug_printInfo("ACCESS POINT MODE for provisioning"); + } + else + { + timeout_create(&ntpTimeFetchTimer,CLOUD_NTP_TASK_INTERVAL); + } + + + timeout_create(&wifiHandlerTimer, CLOUD_WIFI_TASK_INTERVAL); +} + +void wifi_readThingIdFromWinc(void) +{ + int8_t status; + status = m2m_wifi_download_mode(); + + if(status != M2M_SUCCESS) + { + debug_printError("WINC download mode failed - Thing ID cannot be obtained"); + } + else + { + debug_printInfo("WINC in download mode"); + + status = spi_flash_read(cid, THING_NAME_FLASH_OFFSET,MQTT_CID_LENGTH); + if(status != M2M_SUCCESS || cid[0] == 0xFF || cid[MQTT_CID_LENGTH-1] == 0xFF) + { + sprintf(cid, "%s", AWS_THING_ID); + debug_printer(SEVERITY_NONE, LEVEL_ERROR, "Thing ID is not present, error type %d, user defined thing ID is used",status); + } + else + { + debug_printer(SEVERITY_NONE, LEVEL_NORMAL,"Thing ID read from the device is %s",cid); + } + } +} + +void wifi_readAWSEndpointFromWinc(void) +{ + int8_t status; + + memset(awsEndpoint, 0, AWS_ENDPOINT_LEN); + status = m2m_wifi_download_mode(); + + if(status != M2M_SUCCESS) + { + debug_printError("WINC download mode failed - AWS Host URL cannot be obtained"); + } + else + { + debug_printInfo("WINC in download mode"); + status = spi_flash_read(awsEndpoint, AWS_ENDPOINT_FLASH_OFFSET, AWS_ENDPOINT_LEN); + if(status != M2M_SUCCESS || awsEndpoint[0] == 0xFF || awsEndpoint[AWS_ENDPOINT_LEN - 1] == 0xFF) + { + sprintf(awsEndpoint, "%s", CFG_MQTT_HOSTURL); + debug_printer(SEVERITY_NONE, LEVEL_NORMAL, "Custom endpoint not present, using the default endpoint which the hardware was pre-provisioned for : %s", awsEndpoint); + } + else + { + #if USE_MCHP_AWS_ENDPOINT + { + sprintf(awsEndpoint, "%s", CFG_MQTT_HOSTURL); + debug_printer(SEVERITY_NONE, LEVEL_NORMAL,"Using the default endpoint which the hardware was pre-provisioned for : %s", awsEndpoint); + } + #else + { + debug_printer(SEVERITY_NONE, LEVEL_NORMAL,"Using the endpoint defined for custom AWS account: %s", awsEndpoint); + } + #endif + } + } +} + + +bool wifi_connectToAp(uint8_t passed_wifi_creds) +{ + int8_t e = 0; + + if(passed_wifi_creds == NEW_CREDENTIALS) + { + e=m2m_wifi_connect((char *)ssid, sizeof(ssid), atoi((char*)authType), (char *)pass, M2M_WIFI_CH_ALL); + } + else + { + e=m2m_wifi_default_connect(); + } + + if(M2M_SUCCESS != e) + { + debug_printError("WIFI: wifi error = %d",e); + shared_networking_params.haveError = 1; + return false; + } + + return true; +} + +uint32_t softApConnectTask(void *param) +{ + if(!wifi_connectToAp((uint8_t)NEW_CREDENTIALS)) + { + debug_printError("WIFI: Soft AP Connect Failure"); + } + else + { + debug_printInfo("SOFT AP: New Connect credentials sent WINC"); + } + return SOFT_AP_CONNECT_RETRY_INTERVAL; +} + +bool wifi_disconnectFromAp(void) +{ + int8_t m2mDisconnectError; + if(shared_networking_params.haveAPConnection == 1) + { + if(M2M_SUCCESS != (m2mDisconnectError=m2m_wifi_disconnect())) + { + debug_printError("WIFI: Disconnect from AP error = %d",m2mDisconnectError); + return false; + } + } + return true; +} + +// Update the system time every CLOUD_NTP_TASK_INTERVAL milliseconds +uint32_t ntpTimeFetchTask(void *payload) +{ + // If the EEPROM is blank we use the default credentials + if (ntpServerName[0] == 0xFF) + { + strcpy(ntpServerName, CFG_NTP_SERVER); + strcpy(prevNTPServerName, CFG_NTP_SERVER); + debug_printInfo("USING default NTP server name : %s", ntpServerName); + m2m_wifi_configure_sntp(ntpServerName, sizeof(ntpServerName), SNTP_ENABLE_DHCP); + } + if(strncmp(ntpServerName, prevNTPServerName, sizeof(ntpServerName)) != 0) + { + strcpy(prevNTPServerName, ntpServerName); + debug_printInfo("Updated NTP server name: %s", ntpServerName); + m2m_wifi_configure_sntp(ntpServerName, sizeof(ntpServerName), SNTP_ENABLE_DHCP); + } + + m2m_wifi_get_system_time(); + return CLOUD_NTP_TASK_INTERVAL; +} + + +uint32_t wifiHandlerTask(void * param) +{ + m2m_wifi_handle_events(NULL); + return CLOUD_WIFI_TASK_INTERVAL; +} + +uint32_t checkBackTask(void * param) +{ + debug_printError("wifi_cb: M2M_WIFI_RESP_CON_STATE_CHANGED: DISCONNECTED"); + shared_networking_params.haveAPConnection = 0; + shared_networking_params.amDisconnecting = 0; + shared_networking_params.amConnectingSocket = 0; + shared_networking_params.amConnectingAP = 1; + return 0; +} + +static void wifiCallback(uint8_t msgType, void *pMsg) +{ + ledTickState_t ledState; + switch (msgType) { + case M2M_WIFI_RESP_CON_STATE_CHANGED: + { + tstrM2mWifiStateChanged *pstrWifiState = (tstrM2mWifiStateChanged *)pMsg; + if (pstrWifiState->u8CurrState == M2M_WIFI_CONNECTED) + { + if (responseFromProvisionConnect) + { + timeout_delete(&softApConnectTimer); + responseFromProvisionConnect = false; + + ledState.Full2Sec = LED_BLINK; + LED_modeBlue(ledState); + + timeout_create(&ntpTimeFetchTimer,CLOUD_NTP_TASK_INTERVAL); + application_post_provisioning(); + } + + if ((shared_networking_params.amConnectingAP) && (!shared_networking_params.haveAPConnection)) + { + ledState.Full2Sec = LED_BLINK; + LED_modeGreen(ledState); + shared_networking_params.haveAPConnection = 1; + shared_networking_params.amConnectingAP = 0; + shared_networking_params.amDefaultCred = 0; + shared_networking_params.amConnectingSocket = 1; + } + + if (shared_networking_params.amSoftAP) + { // Connected to AS A SOFT AP + shared_networking_params.amSoftAP = 0; + ledState.Full2Sec = LED_1_SEC_ON; + LED_modeBlue(ledState); + } + debug_printGOOD("wifi_cb: M2M_WIFI_RESP_CON_STATE_CHANGED: CONNECTED"); + CREDENTIALS_STORAGE_clearWifiCredentials(); + // We need more than AP to have an APConnection, we also need a DHCP IP address! + } + else if (pstrWifiState->u8CurrState == M2M_WIFI_DISCONNECTED) + { // Disconnected from AP + ledState.Full2Sec = LED_OFF_STATIC; + LED_modeYellow(ledState); + LED_modeRed(ledState); + if (shared_networking_params.amDefaultCred == 0) + { + LED_modeGreen(ledState); + ledState.Full2Sec = LED_BLINK; + LED_modeBlue(ledState); + } + shared_networking_params.haveAPConnection = 0; + shared_networking_params.amConnectingSocket = 0; + shared_networking_params.amConnectingAP = 1; + + timeout_create(&checkBackTimer,CLOUD_WIFI_TASK_INTERVAL); + shared_networking_params.amDisconnecting = 1; + } + + if ((wifiConnectionStateChangedCallback != NULL) && (shared_networking_params.amDisconnecting == 0)) + { + wifiConnectionStateChangedCallback(pstrWifiState->u8CurrState); + } + break; + } + + case M2M_WIFI_REQ_DHCP_CONF: + { + // Now we are really connected, we have AP and we have DHCP, start off the MQTT host lookup now, response in dnsHandler + if (gethostbyname((const char*)CFG_MQTT_HOSTURL) == M2M_SUCCESS) + { + if (shared_networking_params.amDisconnecting == 1) + { + timeout_delete(&checkBackTimer); + shared_networking_params.amDisconnecting = 0; + } + shared_networking_params.haveError = 0; + debug_printGOOD("CLOUD: DHCP CONF"); + } + break; + } + + case M2M_WIFI_RESP_GET_SYS_TIME: + { + tstrSystemTime* WINCTime = (tstrSystemTime*)pMsg; + // Convert to UNIX_EPOCH, this mktime uses years since 1900 and months are 0 based so we + // are doing a couple of adjustments here. + if(WINCTime->u16Year > 0) + { + TIME_ntpTimeStamp(WINCTime); + } + break; + } + + + case M2M_WIFI_RESP_PROVISION_INFO: + { + tstrM2MProvisionInfo *pstrProvInfo = (tstrM2MProvisionInfo*)pMsg; + if(pstrProvInfo->u8Status == M2M_SUCCESS) + { + sprintf((char*)authType, "%d", pstrProvInfo->u8SecType); + debug_printInfo("%s",pstrProvInfo->au8SSID); + strcpy(ssid, (char *)pstrProvInfo->au8SSID); + strcpy(pass, (char *)pstrProvInfo->au8Password); + debug_printInfo("SOFT AP: Connect Credentials sent to WINC"); + responseFromProvisionConnect = true; + timeout_create(&softApConnectTimer, 0); + } + break; + } + + default: + { + break; + } + } +} + + +void enable_provision_ap(void) +{ + tstrM2MAPConfig apConfig = { + CFG_WLAN_AP_NAME, // Access Point Name. + 1, // Channel to use. + 0, // Wep key index. + WEP_40_KEY_STRING_SIZE, // Wep key size. + "1234567890", // Wep key. + M2M_WIFI_SEC_OPEN, // Security mode. + SSID_MODE_VISIBLE, // SSID visible. + CFG_WLAN_AP_IP_ADDRESS + }; + static char gacHttpProvDomainName[] = CFG_WLAN_AP_NAME; + m2m_wifi_start_provision_mode(&apConfig, gacHttpProvDomainName, 1); +} + + diff --git a/AVRIoT.X/mcc_generated_files/cloud/wifi_service.h b/AVRIoT.X/mcc_generated_files/cloud/wifi_service.h new file mode 100644 index 0000000..4aecd13 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/cloud/wifi_service.h @@ -0,0 +1,47 @@ +/* +\file wifi_service.h + +\brief Wifi service header file. + +(c) 2018 Microchip Technology Inc. and its subsidiaries. + +Subject to your compliance with these terms, you may use Microchip software and any +derivatives exclusively with Microchip products. It is your responsibility to comply with third party +license terms applicable to your use of third party software (including open source software) that +may accompany Microchip software. + +THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER +EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY +IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS +FOR A PARTICULAR PURPOSE. + +IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, +INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND +WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP +HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO +THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL +CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT +OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS +SOFTWARE. +*/ + +#ifndef WIFI_SERVICE_H_ +#define WIFI_SERVICE_H_ + +#include +#include + +#define MAX_WIFI_CRED_LENGTH 31 +#define DEFAULT_CREDENTIALS 0 +#define NEW_CREDENTIALS 1 +#define WIFI_SOFT_AP 0 +#define WIFI_DEFAULT 1 + +// If you pass a callback function in here it will be called when the AP state changes. Pass NULL if you do not want that. +void wifi_init(void (*funcPtr)(uint8_t), uint8_t mode); +void wifi_reinit(); +bool wifi_connectToAp(uint8_t passed_wifi_creds); +bool wifi_disconnectFromAp(void); +void wifi_readThingIdFromWinc(void); +void wifi_readAWSEndpointFromWinc(void); +#endif /* WIFI_SERVICE_H_ */ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/config/IoT_Sensor_Node_config.h b/AVRIoT.X/mcc_generated_files/config/IoT_Sensor_Node_config.h new file mode 100644 index 0000000..bb90d87 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/config/IoT_Sensor_Node_config.h @@ -0,0 +1,14 @@ +#ifndef IOT_SENSOR_NODE_CONFIG_H +#define IOT_SENSOR_NODE_CONFIG_H + +#define CFG_SEND_INTERVAL 1 + +#define CFG_TIMEOUT 5000 + +#define CFG_DEBUG_MSG (0) + +#define CFG_ENABLE_CLI (1) + +#define CFG_NTP_SERVER ("*.pool.ntp.org") + +#endif // IOT_SENSOR_NODE_CONFIG_H diff --git a/AVRIoT.X/mcc_generated_files/config/clock_config.h b/AVRIoT.X/mcc_generated_files/config/clock_config.h new file mode 100644 index 0000000..5ce57c9 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/config/clock_config.h @@ -0,0 +1,31 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef CLOCK_CONFIG_H +#define CLOCK_CONFIG_H + +#ifndef F_CPU +#define F_CPU 10000000 +#endif + +#endif // CLOCK_CONFIG_H diff --git a/AVRIoT.X/mcc_generated_files/config/cloud_config.h b/AVRIoT.X/mcc_generated_files/config/cloud_config.h new file mode 100644 index 0000000..6958f36 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/config/cloud_config.h @@ -0,0 +1,11 @@ +#ifndef CLOUD_CONFIG_H +#define CLOUD_CONFIG_H + +//Thing ID configuration + +//Use this thing ID in the event of not reading it from WINC +#define AWS_THING_ID "" + + +// +#endif // CLOUD_CONFIG_H diff --git a/AVRIoT.X/mcc_generated_files/config/conf_winc.h b/AVRIoT.X/mcc_generated_files/config/conf_winc.h new file mode 100644 index 0000000..7576e9d --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/config/conf_winc.h @@ -0,0 +1,106 @@ +/** + * + * \file + * + * \brief WINC1500 configuration. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef CONF_WINC_H_INCLUDED +#define CONF_WINC_H_INCLUDED + +/* Define only on MCU little endian architectures */ +#define CONF_WINC_MCU_ARCH_LITTLE_ENDIAN + +/* Define if _Static_assert/static_assert is not supported on this tool chain */ +//#define CONF_WINC_HIF_STRUCT_SIZE_CHECK(STRUCTNAME) + +#include "../winc/include/conf_winc_defaults.h" +#include "../winc/m2m/m2m_wifi.h" +#include "../winc/socket/socket.h" + +/* Debug Options */ +//#define CONF_WINC_DEBUG_LEVEL 3 +//#define CONF_WINC_PRINTF printf +//#define CONF_WINC_ASSERT + +/* Define macro to swap endianness of 32-bit unsigned integer */ +#define CONF_WINC_UINT32_SWAP(U32) ((((U32) & 0x000000FF) << 24) | (((U32) & 0x0000FF00) << 8) | (((U32) & 0x00FF0000) >> 8) | (((U32) & 0xFF000000) >> 24)) + +/* Define macro to swap endianness of 16-bit unsigned integer */ +#define CONF_WINC_UINT16_SWAP(U16) ((((U16) & 0x00FF) << 8) | (((U16) & 0xFF00) >> 8)) + +/* Define to allow legacy definitions of types and preprocessor macros */ +//#define CONF_WINC_LEGACY_DEFINITIONS + +/* Define if the socket API is exposed or not to the application */ +//#define CONF_WINC_DISABLE_SOCKET_API + +// WLAN Configuration + +// SSID +// Target WLAN SSID +// main_wlan_ssid +#define CFG_MAIN_WLAN_SSID "MCHP.IOT" + +// Authentication +// Target WLAN Authentication +// Invalid security type +// Wi-Fi network is not secured +// Wi-Fi network is secured with WPA/WPA2 personal(PSK) +// Security type WEP (40 or 104) OPEN OR SHARED +// Wi-Fi network is secured with WPA/WPA2 Enterprise.IEEE802.1x user-name/password authentication +// main_wlan_auth +#define CFG_MAIN_WLAN_AUTH M2M_WIFI_SEC_WPA_PSK + +// Password +// Target WLAN password +// main_wlan_psk +#define CFG_MAIN_WLAN_PSK "microchip" + +// + +// AP Mode Configuration + +// Name +// AP name +// wlan_ap_name +#define CFG_WLAN_AP_NAME "MCHP.IOT.ACCESSPOINT" + +// IP Address +// AP IP Address +// wlan_ap_ip_address +#define CFG_WLAN_AP_IP_ADDRESS {192, 168, 1, 1} + +// + +#endif /* CONF_WINC_H_INCLUDED */ diff --git a/AVRIoT.X/mcc_generated_files/config/mqtt_config.h b/AVRIoT.X/mcc_generated_files/config/mqtt_config.h new file mode 100644 index 0000000..79a7d5b --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/config/mqtt_config.h @@ -0,0 +1,93 @@ +/* + \file mqtt_config.h + + \brief MQTT Configuration File + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef MQTT_CONFIG_H +#define MQTT_CONFIG_H + + +#include + + +/********************MQTT Client configurations***********************/ +#define SUBSCRIBE_TOPIC_SIZE 100 //Defines the topic length that is supported when we process a published packet from the cloud +#define PAYLOAD_SIZE 200 //Defines the payload size that is supported when we process a published packet +#define PUBLISH_TOPIC_SIZE 80 //Defines the topic length when we send a publish packet +//TODO: Must be configurable from GUI +// USE_MCHP_AWS_ENDPOINT macro needs to be changed to 1 if the endpoint is different than MCHP AWS account endpoint. +// This check is required only if endpoint is updated in MCC and as such can be +// easily handled by MQTT MCC backend. +#define USE_MCHP_AWS_ENDPOINT 0 +// AWS_ENDPOINT_LEN macro should be populated by MCC by dynamically calculating the endpoint length. +#define AWS_ENDPOINT_LEN 45 +#define MQTT_CID_LENGTH 41 +#define NUM_TOPICS_SUBSCRIBE 1 //Defines number of topics which can be subscribed +#define NUM_TOPICS_UNSUBSCRIBE NUM_TOPICS_SUBSCRIBE // The MQTT client can unsubscribe only from those topics to which it has already subscribed + +// MCC generated parameters +#define CFG_MQTT_PORT 8883 +#define CFG_MQTT_HOSTURL "a1gqt8sttiign3.iot.us-east-2.amazonaws.com" +#define CFG_MQTT_CONN_TIMEOUT 10 +#define CFG_MQTT_BROKERIP 0x00000000 +#define CFG_MQTT_TXBUFFER_SIZE 400 +#define CFG_MQTT_RXBUFFER_SIZE 400 +#define CFG_MQTT_USERNAME "mchpUser" +#define CFG_MQTT_PASSWORD "microchip" +#define CFG_QOS 0 +#define CFG_PUBTOPIC "mchp/iot/events" +#define CFG_SUBTOPIC "mchp/iot/config" +#define TCPIP_BSD 1 + + +/********************MQTT Client configurations*(END)***********************/ + + +/********************Timeout Driver for MQTT definitions***********************/ +#ifdef TCPIP_BSD +#include "../drivers/timeout.h" +#define timerstruct_t timerStruct_t +#define htons(a) (uint16_t)((((uint16_t) (a)) << 8) | (((uint16_t) (a)) >> 8)) +#define ntohs(a) (uint16_t)((((uint16_t) (a)) << 8) | (((uint16_t) (a)) >> 8)) // Socket.h remapped to htons + +// Timeout is calculated on the basis of clock frequency. +// This macro needs to be changed in accordance with the clock frequency. +#define SECONDS (uint32_t)1000 +#endif /* TCPIP_BSD */ + +#ifdef TCPIP_LITE +#define absolutetime_t uint32_t +#define timerstruct_t timerStruct_t + +// Timeout is calculated on the basis of clock frequency. +// This macro needs to be changed in accordance with the clock frequency. +#define SECONDS (uint32_t)1000 +#endif /* TCPIP_LITE */ + +/*******************Timeout Driver for MQTT definitions*(END)******************/ + + + +#endif /* MQTT_CONFIG_H */ diff --git a/AVRIoT.X/mcc_generated_files/credentials_storage/credentials_storage.c b/AVRIoT.X/mcc_generated_files/credentials_storage/credentials_storage.c new file mode 100644 index 0000000..a179143 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/credentials_storage/credentials_storage.c @@ -0,0 +1,47 @@ +/* + \file credentials_storage.c + + \brief Credential Storage source file. + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include +#include +#include +#include +#include "credentials_storage.h" + +char ssid[MAX_WIFI_CREDENTIALS_LENGTH]; +char pass[MAX_WIFI_CREDENTIALS_LENGTH]; +char authType[2]; +char ntpServerName[MAX_NTP_SERVER_LENGTH]; + +void CREDENTIALS_STORAGE_clearWifiCredentials(void) +{ + memset(ssid, 0, sizeof(ssid)); + memset(pass, 0, sizeof(pass)); + memset(authType, 0 ,sizeof(authType)); +} + + + diff --git a/AVRIoT.X/mcc_generated_files/credentials_storage/credentials_storage.h b/AVRIoT.X/mcc_generated_files/credentials_storage/credentials_storage.h new file mode 100644 index 0000000..fb0222d --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/credentials_storage/credentials_storage.h @@ -0,0 +1,44 @@ +/* + \file credentials_storage.h + + \brief Credential Storage header file. + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + + +#ifndef CREDENTIALS_STORAGE_H +#define CREDENTIALS_STORAGE_H + +#define MAX_WIFI_CREDENTIALS_LENGTH 31 +#define MAX_NTP_SERVER_LENGTH 20 + +extern char ssid[MAX_WIFI_CREDENTIALS_LENGTH]; +extern char pass[MAX_WIFI_CREDENTIALS_LENGTH]; +extern char authType[2]; +extern char ntpServerName[MAX_NTP_SERVER_LENGTH]; + +void CREDENTIALS_STORAGE_clearWifiCredentials(void); +void CREDENTIALS_STORAGE_readNTPServerName(char *serverNameBuffer); +void CREDENTIALS_STORAGE_writeNTPServerName(char *serverNameBuffer); + +#endif /* CREDENTIALS_STORAGE_H */ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/debug_print.c b/AVRIoT.X/mcc_generated_files/debug_print.c new file mode 100644 index 0000000..9c97bdc --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/debug_print.c @@ -0,0 +1,88 @@ +/* + \file debug_print.c + + \brief debug_console printer + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include +#include +#include +#include "debug_print.h" + + +static const char *severity_strings[] = { + CSI_WHITE " NONE" CSI_WHITE, + CSI_YELLOW "WARNING" CSI_WHITE, + CSI_BLUE " NOTICE" CSI_WHITE, + CSI_MAGENTA " INFO" CSI_WHITE, + CSI_RED " DEBUG" CSI_NORMAL CSI_WHITE +}; + +static const char *level_strings[] = { + CSI_WHITE "NORMAL" CSI_WHITE, + CSI_GREEN " GOOD" CSI_WHITE, + CSI_RED " BAD" CSI_WHITE, + CSI_RED CSI_INVERSE " ERROR" CSI_NORMAL CSI_WHITE +}; + +static debug_severity_t debug_severity_filter = SEVERITY_NONE; +static char debug_message_prefix[20] = ""; + +void debug_init(const char *prefix) +{ + debug_setPrefix(prefix); + debug_setSeverity(SEVERITY_NONE); +} + +void debug_setSeverity(debug_severity_t debug_level) +{ + debug_severity_filter = debug_level; +} + +void debug_setPrefix(const char *prefix) +{ + strncpy(debug_message_prefix,prefix,sizeof(debug_message_prefix)); +} + +void debug_printer(debug_severity_t debug_severity, debug_errorLevel_t error_level, char* format, ...) +{ + if(debug_severity >= SEVERITY_NONE && debug_severity <= SEVERITY_DEBUG) + { + if(debug_severity <= debug_severity_filter) + { + if(error_level < LEVEL_NORMAL) error_level = LEVEL_NORMAL; + if(error_level > LEVEL_ERROR) error_level = LEVEL_ERROR; + + printf("%s\4 %s %s ",debug_message_prefix, severity_strings[debug_severity], level_strings[error_level]); + + va_list argptr; + va_start(argptr, format); + vprintf(format , argptr); + va_end(argptr); + printf(CSI_RESET"\r\n"); + } + } +} + + diff --git a/AVRIoT.X/mcc_generated_files/debug_print.h b/AVRIoT.X/mcc_generated_files/debug_print.h new file mode 100644 index 0000000..99a1f40 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/debug_print.h @@ -0,0 +1,85 @@ +/* + \file debug_print.h + + \brief debug_console printer + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef DEBUG_PRINT_H +#define DEBUG_PRINT_H + +#include "config/IoT_Sensor_Node_config.h" + +#define CSI_RESET "\33[0m" +#define CSI_BLACK "\33[30m" +#define CSI_RED "\33[31m" +#define CSI_GREEN "\33[32m" +#define CSI_YELLOW "\33[33m" +#define CSI_BLUE "\33[34m" +#define CSI_MAGENTA "\33[35m" +#define CSI_CYAN "\33[36m" +#define CSI_WHITE "\33[37m" +#define CSI_INVERSE "\33[7m" +#define CSI_NORMAL "\33[27m" +#define CSI_CLS "\33[2J" +#define CSI_HOME "\33[1;1H" + +typedef enum +{ + SEVERITY_NONE, + SEVERITY_WARNING, + SEVERITY_NOTICE, + SEVERITY_INFO, + SEVERITY_DEBUG +} debug_severity_t; + +typedef enum +{ + LEVEL_NORMAL, + LEVEL_GOOD, + LEVEL_BAD, + LEVEL_ERROR +}debug_errorLevel_t; + +#include "banner.h" + +#define IOT_DEBUG_PRINT CFG_DEBUG_MSG + +void debug_printer(debug_severity_t debug_severity, debug_errorLevel_t error_level, char* format, ...); +void debug_setSeverity(debug_severity_t debug_level); +void debug_setPrefix(const char *prefix); +void debug_init(const char *prefix); + +#define debug_print(fmt, ...) \ +do { if (IOT_DEBUG_PRINT) debug_printer(SEVERITY_DEBUG, LEVEL_NORMAL, fmt CSI_RESET, ##__VA_ARGS__); } while (0) + +#define debug_printGOOD(fmt, ...) \ +do { if (IOT_DEBUG_PRINT) debug_printer(SEVERITY_DEBUG,LEVEL_GOOD, fmt CSI_RESET, ##__VA_ARGS__); } while (0) + +#define debug_printError(fmt, ...) \ +do { if (IOT_DEBUG_PRINT) debug_printer(SEVERITY_DEBUG,LEVEL_ERROR, fmt CSI_RESET, ##__VA_ARGS__); } while (0) + +#define debug_printInfo(fmt, ...) \ +do { if (IOT_DEBUG_PRINT) debug_printer(SEVERITY_INFO,LEVEL_NORMAL, fmt CSI_RESET, ##__VA_ARGS__); } while (0) + +#endif // DEBUG_PRINT_H diff --git a/AVRIoT.X/mcc_generated_files/delay.c b/AVRIoT.X/mcc_generated_files/delay.c new file mode 100644 index 0000000..cfe1a3b --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/delay.c @@ -0,0 +1,44 @@ +/* + (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this + software and any derivatives exclusively with Microchip products. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION + WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + + MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE + TERMS. +*/ + +#include "config/clock_config.h" +#include +#include + +void DELAY_milliseconds(uint16_t milliseconds) { + while(milliseconds--){ + _delay_ms(1); + } +} + +void DELAY_microseconds(uint16_t microseconds) { + while( microseconds >= 32) + { + _delay_us(32); + microseconds -= 32; + } + + while(microseconds--) + { + _delay_us(1); + } +} diff --git a/AVRIoT.X/mcc_generated_files/delay.h b/AVRIoT.X/mcc_generated_files/delay.h new file mode 100644 index 0000000..d985ec1 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/delay.h @@ -0,0 +1,31 @@ +/* + (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this + software and any derivatives exclusively with Microchip products. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION + WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + + MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE + TERMS. +*/ + +#ifndef _DELAY_H +#define _DELAY_H + +#include + +void DELAY_milliseconds(uint16_t milliseconds); +void DELAY_microseconds(uint16_t microseconds); + +#endif // _DELAY_H diff --git a/AVRIoT.X/mcc_generated_files/device_config.c b/AVRIoT.X/mcc_generated_files/device_config.c new file mode 100644 index 0000000..b7fda7a --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/device_config.c @@ -0,0 +1,39 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include + +/** + * \Configures Fuse bits + */ + +FUSES = +{ + .APPEND = 0, + .BODCFG = ACTIVE_DIS_gc | LVL_BODLEVEL0_gc | SAMPFREQ_1KHZ_gc | SLEEP_DIS_gc, + .BOOTEND = 0, + .OSCCFG = FREQSEL_20MHZ_gc, + .SYSCFG0 = CRCSRC_NOCRC_gc | RSTPINCFG_GPIO_gc, + .SYSCFG1 = SUT_64MS_gc, + .WDTCFG = PERIOD_OFF_gc | WINDOW_OFF_gc, +}; \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/docs/mqtt_documentation/MQTT Readme.md b/AVRIoT.X/mcc_generated_files/docs/mqtt_documentation/MQTT Readme.md new file mode 100644 index 0000000..2d6a3b4 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/docs/mqtt_documentation/MQTT Readme.md @@ -0,0 +1,397 @@ +# Microchip MQTT Library APIs + +## Introduction + +MQTT (Message Queuing Telemetry and Transport) is a publish/subscribe messaging transport protocol. It is widely used in many situations, such as communications in Machine to Machine (M2M) or Internet of Things (IoT) applications, especially in bandwidth and/or memory constrained environments. This protocol runs over TCP/IP, or can over other network protocols that provide ordered, lossless, bi-directional connections. In this implementation of MQTT is implemented over TCP. + +This MQTT implementation supports all the required features and message types of this protocol along with some optional features. + +Supported message types: +* CONNECT +* CONNACK +* PUBLISH (QoS level = 0) +* PINGREQ +* PINGRESP +* SUBSCRIBE (QoS level = 0, beta) +* DISCONNECT + +This document describes the structure and the APIs implemented as part of the MQTT library. The public APIs are used by user application for performing all the MQTT specific tasks such as establishing a MQTT connection, publishing data, sending ping requests, etc. The private APIs are used internally by the MQTT library for maintaining its modularity. + +## Core Public APIs + +##### 1. INITIALISE STATE +* MQTT_initialiseState + * **Description:** + * void MQTT_initialiseState(void) + * Returns the mqttState variable to DISCONNECTED. + * **Parameters:** + * None. + * **Return Values:** + * None. + +##### 2. GET STATE +* MQTT_GetConnectionState + * **Description:** + * mqttCurrentState MQTT_GetConnectionState (void) + * Returns the mqttState variable value. + * **Parameters:** + * None. + * **Return Values:** + * mqttState which is a type define of mqttCurrentState. + +##### 3. CREATE CONNECT PACKET +* MQTT_CreateConnectPacket + * **Description:** + * bool MQTT_CreateConnectPacket(mqttConnectPacket *newConnectPacket*) + * MQTT_CreateConnectPacket API creates a CONNECT packet structure, which follows MQTT standard. + * **Parameters:** + * A pointer that points to a MQTT CONNECT packet structure mqttConnectPacket. + * **Return Values:** + * A bool type value indicating whether a connect data packet structure is initialized successfully. A return value of â??trueâ?? implies that CONNECT packet has been successfully created. + +##### 4. CREATE PUBLISH PACKET +* MQTT_CreatePublishPacket + * **Description:** + * bool MQTT_CreatePublishPacket(mqttPublishPacket *newPublishPacket*) + * MQTT_CreatePublishPacket API creates a MQTT publish data packet structure, which follows MQTT standard. + * **Parameters:** + * A pointer that points to a MQTT PUBLISH packet structure mqttPublishPacket. + * **Return Values:** + * A bool value indicating whether a publish data packet structure is created successfully. A return value of â??trueâ?? means that the PUBLISH packet has been created correctly as per the parameters passed by the user application. + +##### 5. CREATE SUBSCRIBE PACKET +* MQTT_CreateSubscribePacket + * **Description:** + * bool MQTT_CreateSubscribePacket(mqttSubscribePacket *newSubscribePacket*) + * MQTT_CreateSubscribePacket API creates a MQTT subscribe data packet structure, which follows MQTT standard. + * **Parameters:** + * A pointer that points to a MQTT SUBSCRIBE packet structure mqttSubscribePacket. + * **Return Values:** + * A bool type value indicating whether a subscribe data packet structure is created successfully. A return value of â??trueâ?? means that the SUBSCRIBE packet has been created correctly as per the parameters passed by the user application. + +##### 6. CREATE UNSUBSCRIBE PACKET +* MQTT_CreateUnsubscribePacket + * **Description:** + * bool MQTT_CreateUnsubscribePacket(mqttUnsubscribePacket *newUnsubscribePacket*) + * MQTT_CreateUnsubscribePacket API creates a MQTT unsubscribe data packet structure, which follows MQTT standard. + * **Parameters:** + * A pointer that points to a MQTT UNSUBSCRIBE packet structure. + * **Return Values:** + * A bool type value indicating whether a subscribe data packet unstructure is created successfully. A return value of â??trueâ?? means that the UNSUBSCRIBE packet has been created correctly as per the parameters passed by the user application. + +##### 7. DISCONNECT +* MQTT_Disconnect + * **Description:** + * void MQTT_Disconnect(void) + * This API sends a MQTT DISCONNECT packet. This disconnects the client cleanly from the MQTT server. + * **Parameters:** + * None. + * **Return Values:** + * None. + +##### 8. LAST HANDLER STATE +* MQTT_GetLastHandlerState + * **Description:** + * mqttHandlerState_t MQTT_GetLastHandlerState (void); + * The function returns the last MQTT Handler State used to detect transitions by observers. + * **Parameters:** + * None. + * **Return Values:** + * Variable value of type mqttHandlerState_t. + +##### 9. LAST RECEIVED PACKET HEADER +* MQTT_GetLastReceivedPacketHeader + * **Description:** + * mqttHeaderFlags MQTT_GetLastReceivedPacketHeader (void); + * The function returns a uint16_t value representing the last received data length. + * **Parameters:** + * None. + * **Return Values:** + * Variable value of a uint16_t type. + +##### 10. TRANSMISSION HANDLER +* MQTT_TransmissionHandler + * **Description:** + * mqttCurrentState MQTT_TransmissionHandler(mqttTxRxInformation *mqttConnectionPtr*) + * MQTT_TransmissionHandler API sends out an MQTT packet based on the settings of MQTT packet transmission flags and the current MQTT state, then set the current MQTT state to a proper state. + * **Parameters:** + * A pointer to the current MQTT connection information, which is essentially a structure with relevant exchange buffer details. + * **Return Values:** + * mqttCurrentState: An enum indicating the current MQTT connection state. Possible valid values: DISCONNECTED, CONNECTING, WAITFORCONNACK, CONNECTED. + +##### 11. RECEPTION HANDLER +* MQTT_ReceptionHandler + * **Description:** + * mqttCurrentState MQTT_ReceptionHandler(mqttTxRxInformation *mqttConnectionPtr*) + * MQTT_ReceptionHandler API handles the received MQTT packet based on the MQTT state and then sets the state to a proper value based on the data received. + * **Parameters:** + * A pointer to the current MQTT connection information, which is essentially a structure with relevant exchange buffer details. + * **Return Values:** + * mqttCurrentState: An enum indicating the current MQTT connection state. Possible valid values: DISCONNECTED, CONNECTING, WAITFORCONNACK, CONNECTED. + +## Private APIs + +##### 1. SEND CONNECT +* mqttSendConnect + * **Description:** + * static bool mqttSendConnect(mqttTxRxInformation *mqttConnectionPtr*) + * mqttSendConnect API sends the MQTT CONNECT packet using the underlying TCP layer. + * **Parameters:** + * A pointer to the MQTT connection structure *mqttConnectionPtr*. + * **Return Values:** + * Boolean value indicating whether the packet has been successfully sent. The value 'true' implies that the packet has been sent successfully to the server. + +##### 2. SEND PUBLISH +* mqttSendPublish + * **Description:** + * static bool mqttSendPublish(mqttTxRxInformation *mqttConnectionPtr*) + * mqttSendPublish API sends the MQTT PUBLISH packet using the underlying TCP layer. + * **Parameters:** + * A pointer to the MQTT connection structure *mqttConnectionPtr*. + * **Return Values:** + * Boolean value indicating whether the packet has been successfully sent. The value 'true' implies that the packet has been sent successfully to the server. + +##### 3. SEND SUBSCRIBE +* mqttSendSubscribe + * **Description:** + * static bool mqttSendSubscribe (mqttContext*mqttConnectionPtr); + * mqttSendSubscribe API sends the MQTT SUBSCRIBE packet using the underlying TCP layer. + * **Parameters:** + * Pointer to the MQTT connection structure *mqttConnectionPtr*. + * **Return Values:** + * Boolean value indicating whether the packet has been successfully sent. The value â??trueâ?? implies that the packet has been sent successfully to the server. + +##### 4. SEND UNSUBSCRIBE +* mqttSendUnubscribe + * **Description:** + * static bool mqttSendUnsubscribe (mqttContext*mqttConnectionPtr); + * mqttSendUnsubscribe API sends the MQTT SUBSCRIBE packet using the underlying TCP layer. + * **Parameters:** + * Pointer to the MQTT connection structure *mqttConnectionPtr*. + * **Return Values:** + * Boolean value indicating whether the packet has been successfully sent. The value â??trueâ?? implies that the packet has been sent successfully to the server. + +##### 5. SEND PINGREQ +* mqttSendPingreq + * **Description:** + * static bool mqttSendPingreq(mqttTxRxInformation *mqttConnectionPtr*) + * mqttSendPingreq API sends the MQTT PINGREQ packet using the underlying TCP layer. + * **Parameters:** + * A pointer to the MQTT connection structure *mqttConnectionPtr*. + * **Return Values:** + * Boolean value indicating whether the packet has been successfully sent. The value 'true' implies that the packet has been sent to the server. + +##### 6. SEND DISCONNECT +* mqttSendDisconnect + * **Description:** + * static bool mqttSendDisconnect(mqttTxRxInformation *mqttConnectionPtr*) + * mqttSendDisconnect API sends the MQTT DISCONNECT packet using the underlying TCP layer. + * **Parameters:** + * A pointer to the MQTT connection structure *mqttConnectionPtr*. + * **Return Values:** + * Boolean value indicating whether the packet has been successfully sent. The value 'true' implies that the packet has been sent to the server. + +##### 7. ENCODING REMAINING LENGTH +* mqttEncodeLength + * **Description:** + * static uint8_t mqttEncodeLength(uint16_t length, uint8_t *output*) + * The function encodes the text fields in MQTT packets as UTF-8 strings. + * **Parameters:** + * uint16_t length: the number of bytes remaining within the current packet, including data in the variable header and the payload. + * uint8_t *output*: a pointer to the encoded bytes. + * **Return Values:** + * The number of bytes encoded. + +##### 8. DECODING REMAINING LENGTH +* mqttDecodeLength + * **Description:** + * static absolutetime_t mqttEncodeLength(uint8_t *encodedData*) + * The function decodes UTF-8 encoded string to text fields as per the requirement of MQTT standard. + * **Parameters:** + * uint8_t *encodedData*: a pointer to the encoded value of remaining length of a MQTT control packet. + * **Return Values:** + * The decoded value of the remaining length of an MQTT control packet header. + +##### 9. PROCESS PINGRESP +* mqttProcessPingresp + * **Description:** + * static mqttCurrentState mqttProcessPingresp(mqttTxRxInformation *mqttConnectionPtr*) + * Processes the PINGRESP packet received from the broker. + * **Parameters:** + * A pointer to the MQTT connection structure *mqttConnectionPtr*. + * **Return Values:** + * None. + +##### 10. PROCESS SUBACK +* mqttProcessSuback + * **Description:** + * static mqttCurrentState mqttProcessSuback(mqttTxRxInformation *mqttConnectionPtr*) + * Processes the PINGRESP packet received from the broker. + * **Parameters:** + * A pointer to the MQTT connection structure *mqttConnectionPtr*. + * **Return Values:** + * Pointer to the MQTT connection structure *mqttConnectionPtr*. + +##### 11. PROCESS UNSUBACK +* mqttProcessUnsuback + * **Description:** + * static mqttCurrentState mqttProcessSuback(mqttTxRxInformation *mqttConnectionPtr*); + * Processes the PINGRESP packet received from the broker. + * **Parameters:** + * Pointer to the MQTT connection structure *mqttConnectionPtr*. + * **Return Values:** + * Current state of the MQTT (CONNECTED if correct SUBACK packet is received correctly and DISCONNECTED if certain parameters in the SUBACK packet indicate that the server has acknowledged the SUBSCRIBE message completely). + +##### 12. PROCESS PUBLISH +* mqttProcessPublish + * **Description:** + * static mqttCurrentState mqttProcessPublish (mqttContext *mqttConnectionPtr*); + * Processes the PUBLISH packet received from the broker. + * **Parameters:** + * Pointer to the MQTT Context structure *mqttConnectionPtr*. + * **Return Values:** + * Current state of the MQTT (CONNECTED if correct SUBACK packet is received correctly and DISCONNECTED if certain parameters in the PUBACK packet indicate that the server has acknowledged the PUBLISH message completely). + +##### 13. PROCESS PUBACK +* mqttProcessPuback + * **Description:** + * static void mqttProcessPuback (mqttContext *mqttConnectionPtr*); + * Processes the PUBLISH ACK packet received from the broker. + * **Parameters:** + * Pointer to the MQTT Context structure *mqttConnectionPtr*. + * **Return Values:** + * None. + +##### 14. PROCESS CONNACK +* mqttProcessConnack + * **Description:** + * static mqttCurrentState mqttProcessConnack(mqttTxRxInformation *mqttConnectionPtr*) + * Processes the CONNACK packet received from the broker. + * **Parameters:** + * A pointer to the MQTT connection structure *mqttConnectionPtr*. + * **Return Values:** + * Current state of the MQTT (CONNECTED if correct CONNACK packet is received and DISCONNECTED if certain parameters in the CONNACK packet indicate that the server has not granted a connection). + +## Core Timeouts + +##### 1. CHECK CONNACK TIMEOUT STATE +* checkConnackTimeoutState + * **Description:** + * static absolutetime_t checkConnackTimeoutState (); + * checkConnackTimeoutState is a call back function that will be called when a timeout (30s) has occurred after sending the CONNECT packet, since a CONNACK packet is expected from the broker within 30s. + * **Parameters:** + * None. + * **Return Values:** + * Number of ticks until the connackTimer expires. In the current implementation it is 0, indicating that the timer function will be executed only once. + +##### 2. CHECK PING REQUEST TIMEOUT STATE +* checkPingreqTimeoutState + * **Description:** + * static absolutetime_t checkPingreqTimeoutState (); + * checkPingreqTimeoutState is a call back function that will be called when a â??keep-alive-timeoutâ?? defined in user application is near after a MQTT connection has been set up to make sure the connection keeps alive. In the current implementation it is 1 second before â??keep-alive-timeoutâ??. + * **Parameters:** + * None. + * **Return Values:** + * Number of ticks until the pingreqTimer expires. + +##### 3. CHECK PING RESPONSE TIMEOUT STATE +* checkPingrespTimeoutState + * **Description:** + * static absolutetime_t checkPingrespTimeoutState (); + * checkPingrespTimeoutState is a call back function that will be called when a timeout (30s) has occurred after sending a PINGREQ packet. In the current MQTT client implementation, the client waits for 30s after transmission of PINGREQ packet to receive a PINGRESP packet. + * **Parameters:** + * None. + * **Return Values:** + * Number of ticks until the pingrespTimer expires. + +##### 4. CHECK SUBSCRIBE ACKNOWLEDGE TIMEOUT STATE +* checkSubackTimeoutState + * **Description:** + * static absolutetime_t checkSubackTimeoutState (); + * When a SUBSCRIBE packet is sent, the ACK is expected within a timeout period. +If the SUBACK is not received in the set time, this timeout will occur; and a flag will be set as a result. Otherwise this timeout will be deleted prior to completion. + * **Parameters:** + * None. + * **Return Values:** + * Zero (0); the timer is not reloaded. + +##### 5. CHECK UNSUBSCRIBE ACKNOWLEDGE TIMEOUT STATE +* checkUnsubackTimeoutState + * **Description:** + * static absolutetime_t checkUnsubackTimeoutState (); + * When a UNSUBSCRIBE packet is sent, the ACK is expected within a timeout period. +If the SUBACK is not received in the set time, this timeout will occur; and a flag will be set as a result. Otherwise this timeout will be deleted prior to completion. + * **Parameters:** + * None. + * **Return Values:** + * Zero (0); the timer is not reloaded. + +## Dependent APIs + +###Exchange Buffers + +##### 1. EXCHANGE BUFFER INIT +* ExchangeBufferInit + * **Description:** + * void MQTT_ExchangeBufferInit(exchangeBuffer *buffer*) + * Sets the current location pointer to the beginning of the buffer and sets the length to zero. + * **Parameters:** + * A pointer to Exchange Buffer structure. + * **Return Values:** + * None. + +##### 2. EXCHANGE BUFFER WRITE +* ExchangeBufferWrite + * **Description:** + * uint16_t MQTT_ExchangeBufferWrite(exchangeBuffer *buffer*, uint8_t *data*, uint16_t length) + * Sets the current location pointer to the beginning of the buffer and sets the length to zero. + * **Parameters:** + * Copies a data buffer to the Exchange Buffer. + * **Return Values:** + * Length. + +##### 3. EXCHANGE BUFFER PEEK +* ExchangeBufferPeek + * **Description:** + * uint16_t MQTT_ExchangeBufferPeek(exchangeBuffer *buffer*, uint8_t *data*, uint16_t length) + * Copies data out of the Exchange buffer without modifying the data length or current pointer. + * **Parameters:** + * A pointer to Exchange Buffer structure, a pointer to Data Buffer, dataLength. + * **Return Values:** + * Number of bytes copied. + +##### 4. EXCHANGE BUFFER READ +* ExchangeBufferRead + * **Description:** + * uint16_t MQTT_ExchangeBufferRead(exchangeBuffer *buffer*, uint8_t *data*, uint16_t length) + * Copies the Exchange buffer to the data buffer. Exchange buffer is reset in the process. + * **Parameters:** + * Copies a data buffer to the Exchange Buffer. + * **Return Values:** + * Number of bytes copied. + +## Packet Transfer Interface + +##### 1. SET PUBLISH RECEPTION HANDLER TABLE +* MQTT_SetPublishReceptionHandlerTable + * **Description:** + * void MQTT_SetPublishReceptionHandlerTable(publishReceptionHandler_t *appPublishReceptionInfo*) + * MQTT_SetPublishReceptionHandlerTable is called by the user application to inform the MQTT core of the call back table defined to handle the PUBLISH messages received from the MQTT server. + * **Parameters:** + * A publishReceptionHandler_t table information defined in the user application, which involves a call back function pointer of a corresponding MQTT topic. + * **Return Values:** + * None. + +##### 2. GET PUBLISH RECEPTION HANDLER TABLE +* MQTT_GetPublishReceptionHandlerTable + * **Description:** + * publishReceptionHandler_t *MQTT_GetPublishReceptionHandlerTable*() + * MQTT_GetPublishReceptionHandlerTable API returns a publishReceptionHandler_t table information defined in the user application, which involves a call back function pointer of a corresponding MQTT topic. + * **Parameters:** + * None. + * **Return Values:** + * A publishReceptionHandler_t table information defined in the user application, which involves a call back function pointer of a corresponding MQTT topic. + +## References +[MQTT Standard](http://mqtt.org/documentation) +[Click the link](https://guides.github.com/features/mastering-markdown/#examples) diff --git a/AVRIoT.X/mcc_generated_files/docs/mqtt_documentation/Microchip MQTT Client Library.docx b/AVRIoT.X/mcc_generated_files/docs/mqtt_documentation/Microchip MQTT Client Library.docx new file mode 100644 index 0000000..936a771 Binary files /dev/null and b/AVRIoT.X/mcc_generated_files/docs/mqtt_documentation/Microchip MQTT Client Library.docx differ diff --git a/AVRIoT.X/mcc_generated_files/docs/winc_documentation/WINC1500_IoT_SW_APIs.chm b/AVRIoT.X/mcc_generated_files/docs/winc_documentation/WINC1500_IoT_SW_APIs.chm new file mode 100644 index 0000000..f432ed1 Binary files /dev/null and b/AVRIoT.X/mcc_generated_files/docs/winc_documentation/WINC1500_IoT_SW_APIs.chm differ diff --git a/AVRIoT.X/mcc_generated_files/drivers/i2c_simple_master.c b/AVRIoT.X/mcc_generated_files/drivers/i2c_simple_master.c new file mode 100644 index 0000000..d065d6d --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/drivers/i2c_simple_master.c @@ -0,0 +1,162 @@ +/* + (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this + software and any derivatives exclusively with Microchip products. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION + WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + + MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE + TERMS. +*/ + +/* + This file provides some basic blocking helper functions for common operations on the i2c API + */ + +#include "../include/twi0_master.h" +#include "i2c_simple_master.h" + +/****************************************************************/ +static twi0_operations_t wr1RegCompleteHandler(void *p) +{ + I2C0_SetBuffer(p,1); + I2C0_SetDataCompleteCallback(NULL,NULL); + return I2C_CONTINUE; +} + +void i2c_write1ByteRegister(twi0_address_t address, uint8_t reg, uint8_t data) +{ + while(!I2C0_Open(address)); // sit here until we get the bus.. + I2C0_SetDataCompleteCallback(wr1RegCompleteHandler,&data); + I2C0_SetBuffer(®,1); + I2C0_SetAddressNackCallback(I2C0_SetRestartWriteCallback,NULL); //NACK polling? + I2C0_MasterWrite(); + while(I2C_BUSY == I2C0_Close()); // sit here until finished. +} + +void i2c_writeNBytes(twi0_address_t address, void* data, size_t len) +{ + while(!I2C0_Open(address)); // sit here until we get the bus.. + I2C0_SetBuffer(data,len); + I2C0_SetAddressNackCallback(I2C0_SetRestartWriteCallback,NULL); //NACK polling? + I2C0_MasterWrite(); + while(I2C_BUSY == I2C0_Close()); // sit here until finished. +} + +/****************************************************************/ +static twi0_operations_t rd1RegCompleteHandler(void *p) +{ + I2C0_SetBuffer(p,1); + I2C0_SetDataCompleteCallback(NULL,NULL); + return I2C_RESTART_READ; +} + +uint8_t i2c_read1ByteRegister(twi0_address_t address, uint8_t reg) +{ + uint8_t d2=42; + twi0_error_t e; + int x; + + for(x = 2; x != 0; x--) + { + while(!I2C0_Open(address)); // sit here until we get the bus.. + I2C0_SetDataCompleteCallback(rd1RegCompleteHandler,&d2); + I2C0_SetBuffer(®,1); + I2C0_SetAddressNackCallback(I2C0_SetRestartWriteCallback,NULL); //NACK polling? + I2C0_MasterWrite(); + while(I2C_BUSY == (e = I2C0_Close())); // sit here until finished. + if(e==I2C_NOERR) break; + } + + + return d2; +} + +/****************************************************************/ +static twi0_operations_t rd2RegCompleteHandler(void *p) +{ + I2C0_SetBuffer(p,2); + I2C0_SetDataCompleteCallback(NULL,NULL); + return I2C_RESTART_READ; +} + +uint16_t i2c_read2ByteRegister(twi0_address_t address, uint8_t reg) +{ + // result is little endian + uint16_t result; + + while(!I2C0_Open(address)); // sit here until we get the bus.. + I2C0_SetDataCompleteCallback(rd2RegCompleteHandler,&result); + I2C0_SetBuffer(®,1); + I2C0_SetAddressNackCallback(I2C0_SetRestartWriteCallback,NULL); //NACK polling? + I2C0_MasterWrite(); + while(I2C_BUSY == I2C0_Close()); // sit here until finished. + + return (result << 8 | result >> 8); +} + +/****************************************************************/ +static twi0_operations_t wr2RegCompleteHandler(void *p) +{ + I2C0_SetBuffer(p,2); + I2C0_SetDataCompleteCallback(NULL,NULL); + return I2C_CONTINUE; +} + +void i2c_write2ByteRegister(twi0_address_t address, uint8_t reg, uint16_t data) +{ + while(!I2C0_Open(address)); // sit here until we get the bus.. + I2C0_SetDataCompleteCallback(wr2RegCompleteHandler,&data); + I2C0_SetBuffer(®,1); + I2C0_SetAddressNackCallback(I2C0_SetRestartWriteCallback,NULL); //NACK polling? + I2C0_MasterWrite(); + while(I2C_BUSY == I2C0_Close()); // sit here until finished. +} + +/****************************************************************/ +typedef struct +{ + size_t len; + char *data; +}buf_t; + +static twi0_operations_t rdBlkRegCompleteHandler(void *p) +{ + I2C0_SetBuffer(((buf_t *)p)->data,((buf_t*)p)->len); + I2C0_SetDataCompleteCallback(NULL,NULL); + return I2C_RESTART_READ; +} + +void i2c_readDataBlock(twi0_address_t address, uint8_t reg, void *data, size_t len) +{ + // result is little endian + buf_t d; + d.data = data; + d.len = len; + + while(!I2C0_Open(address)); // sit here until we get the bus.. + I2C0_SetDataCompleteCallback(rdBlkRegCompleteHandler,&d); + I2C0_SetBuffer(®,1); + I2C0_SetAddressNackCallback(I2C0_SetRestartWriteCallback,NULL); //NACK polling? + I2C0_MasterWrite(); + while(I2C_BUSY == I2C0_Close()); // sit here until finished. +} + +void i2c_readNBytes(twi0_address_t address, void *data, size_t len) +{ + while(!I2C0_Open(address)); // sit here until we get the bus.. + I2C0_SetBuffer(data,len); + I2C0_MasterRead(); + while(I2C_BUSY == I2C0_Close()); // sit here until finished. +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/drivers/i2c_simple_master.h b/AVRIoT.X/mcc_generated_files/drivers/i2c_simple_master.h new file mode 100644 index 0000000..c660d28 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/drivers/i2c_simple_master.h @@ -0,0 +1,40 @@ +/* + (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this + software and any derivatives exclusively with Microchip products. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION + WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + + MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE + TERMS. +*/ + +#ifndef I2C_SIMPLE_MASTER_H +#define I2C_SIMPLE_MASTER_H + +#include +#include +#include "../include/twi0_master.h" + +uint8_t i2c_read1ByteRegister(twi0_address_t address, uint8_t reg); +uint16_t i2c_read2ByteRegister(twi0_address_t address, uint8_t reg); +void i2c_write1ByteRegister(twi0_address_t address, uint8_t reg, uint8_t data); +void i2c_write2ByteRegister(twi0_address_t address, uint8_t reg, uint16_t data); + +void i2c_writeNBytes(twi0_address_t address, void* data, size_t len); +void i2c_readDataBlock(twi0_address_t address, uint8_t reg, void *data, size_t len); +void i2c_readNBytes(twi0_address_t address, void *data, size_t len); + +#endif /* I2C_SIMPLE_MASTER_H */ + diff --git a/AVRIoT.X/mcc_generated_files/drivers/spi_master.c b/AVRIoT.X/mcc_generated_files/drivers/spi_master.c new file mode 100644 index 0000000..417a884 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/drivers/spi_master.c @@ -0,0 +1,50 @@ +/* + (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this + software and any derivatives exclusively with Microchip products. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION + WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + + MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE + TERMS. +*/ + +/** + Section: Included Files + */ + +#include "spi_master.h" + +bool WINC_open(void); + +const spi_master_functions_t spiMaster[] = { + { SPI0_Close, WINC_open, SPI0_ExchangeByte, SPI0_ExchangeBlock, SPI0_WriteBlock, SPI0_ReadBlock, SPI0_WriteByte, SPI0_ReadByte, NULL, NULL } +}; + +bool WINC_open(void){ + return SPI0_OpenConfiguration(WINC_CONFIG); +} + +//This function serves keep backwards compatibility with older api users +bool spi_master_open(spi_master_configurations_t config){ + switch(config){ + case WINC: + return WINC_open(); + default: + return 0; + } +} +/** + End of File + */ diff --git a/AVRIoT.X/mcc_generated_files/drivers/spi_master.h b/AVRIoT.X/mcc_generated_files/drivers/spi_master.h new file mode 100644 index 0000000..8a12e94 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/drivers/spi_master.h @@ -0,0 +1,53 @@ +/* + (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this + software and any derivatives exclusively with Microchip products. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION + WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + + MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE + TERMS. +*/ + +#ifndef _SPI_MASTER_H +#define _SPI_MASTER_H + +/** + Section: Included Files + */ +#include +#include +#include "../include/spi0.h" + +typedef enum { + WINC +} spi_master_configurations_t; + +typedef struct { void (*spiClose)(void); + bool (*spiOpen)(void); + uint8_t (*exchangeByte)(uint8_t b); + void (*exchangeBlock)(void * block, size_t blockSize); + void (*writeBlock)(void * block, size_t blockSize); + void (*readBlock)(void * block, size_t blockSize); + void (*writeByte)(uint8_t byte); + uint8_t (*readByte)(void); + void (*setSpiISR)(void(*handler)(void)); + void (*spiISR)(void); +} spi_master_functions_t; + +extern const spi_master_functions_t spiMaster[]; + +bool spi_master_open(spi_master_configurations_t config); //for backwards compatibility + +#endif // _SPI_MASTER_H \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/drivers/timeout.c b/AVRIoT.X/mcc_generated_files/drivers/timeout.c new file mode 100644 index 0000000..1c49f52 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/drivers/timeout.c @@ -0,0 +1,384 @@ +/* + (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this + software and any derivatives exclusively with Microchip products. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION + WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + + MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE + TERMS. +*/ + +#ifdef __XC +#include +#endif +#include +#include "timeout.h" +#include "../include/rtc.h" + + +uint32_t dummyHandler(void *payload) {return 0;}; +void startTimerAtHead(void); +INLINE void enqueueCallback(timerStruct_t* timer); +INLINE void setTimerDuration(uint32_t duration); +INLINE uint32_t makeAbsolute(uint32_t timeout); +INLINE uint32_t rebaseList(void); +INLINE void printList(void); + +timerStruct_t *listHead = NULL; +timerStruct_t * volatile executeQueueHead = NULL; + +timerStruct_t dummy = {dummyHandler}; +volatile uint32_t absoluteTimeofLastTimeout = 0; +volatile uint32_t lastTimerLoad = 0; +volatile bool isRunning = false; + +bool timeout_hasPendingTimeouts(void) +{ + return (listHead == NULL); +} + +bool timeout_hasPendingCallbacks(void) +{ + return (executeQueueHead == NULL); +} + +// Disable all the timers without deleting them from any list. Timers can be +// restarted by calling startTimerAtHead +void stopTimeouts(void) +{ + RTC_DisableOVFInterrupt(); + absoluteTimeofLastTimeout = 0; + lastTimerLoad = 0; + isRunning = false; +} + +inline void setTimerDuration(uint32_t duration) +{ + lastTimerLoad = 65535 - duration; + + RTC_WriteCounter(0); + + RTC_ClearOVFInterruptFlag(); + RTC_WriteCounter(lastTimerLoad); +} + +// Convert the time provided from a "relative to now" time to a absolute time which +// means ticks since the last timeout occurred or the timer module was started +inline uint32_t makeAbsolute(uint32_t timeout) +{ + timeout += absoluteTimeofLastTimeout; + if (isRunning) { + uint32_t timerVal = RTC_ReadCounter(); + if (timerVal < lastTimerLoad) // Timer has wrapped while we were busy + { + timerVal = 65535; + } + timeout += timerVal - lastTimerLoad; + } + return timeout; +} + +uint32_t timeout_getTimeRemaining(timerStruct_t *timer) +{ + return timer->absoluteTime - makeAbsolute(0); +} + +// Adjust the time base so that we can never wrap, saving us a lot of complications +inline uint32_t rebaseList(void) +{ + timerStruct_t *basePoint = listHead; + uint32_t baseTime = makeAbsolute(0); + while(basePoint != NULL) + { + basePoint->absoluteTime -= baseTime; + basePoint = basePoint->next; + } + absoluteTimeofLastTimeout -= baseTime; + return baseTime; +} + +inline void printList(void) +{ + timerStruct_t *basePoint = listHead; + while(basePoint != NULL) + { + printf("%ld -> ", (uint32_t)basePoint->absoluteTime); + basePoint = basePoint->next; + } + printf("NULL\n"); +} + +// Returns true if the insert was at the head, false if not +bool sortedInsert(timerStruct_t *timer) +{ + uint32_t timerAbsoluteTime = timer->absoluteTime; + uint8_t atHead = 1; + timerStruct_t *insertPoint = listHead; + timerStruct_t *prevPoint = NULL; + timer->next = NULL; + + if(timerAbsoluteTime < absoluteTimeofLastTimeout) + { + timerAbsoluteTime += 65535 - rebaseList() + 1; + timer->absoluteTime = timerAbsoluteTime; + } + + while(insertPoint != NULL) + { + if(insertPoint->absoluteTime > timerAbsoluteTime) + { + break; // found the spot + } + prevPoint = insertPoint; + insertPoint = insertPoint->next; + atHead = 0; + } + + if(atHead == 1) // the front of the list. Checking the uint8_t saves 7 instructions + { + setTimerDuration(65535); + RTC_ClearOVFInterruptFlag(); + + timer->next = (listHead==&dummy)?dummy.next: listHead; + listHead = timer; + return true; + } + else // middle of the list + { + timer->next = prevPoint->next; + } + + prevPoint->next = timer; + return false; +} + +void startTimerAtHead(void) +{ + // NOTE: listHead must NOT equal NULL at this point. + + RTC_DisableOVFInterrupt(); + + if(listHead==NULL) // no timeouts left + { + stopTimeouts(); + return; + } + + uint32_t period = listHead->absoluteTime - absoluteTimeofLastTimeout; + + // Timer is too far, insert dummy and schedule timer after the dummy + if (period > 65535) + { + dummy.absoluteTime = absoluteTimeofLastTimeout + 65535; + dummy.next = listHead; + listHead = &dummy; + period = 65535; + } + + setTimerDuration(period); + + RTC_EnableOVFInterrupt(); + isRunning = true; +} + +// Cancel and remove all active timers +void timeout_flushAll(void) +{ + stopTimeouts(); + + while (listHead != NULL) + timeout_delete(listHead); + + while (executeQueueHead != NULL) + timeout_delete(executeQueueHead); + +} + + +// Deletes a timer from a list and returns true if the timer was found and +// removed from the list specified +bool timeout_deleteHelper(timerStruct_t * volatile *list, timerStruct_t *timer) +{ + bool retVal = false; + if (*list == NULL) + return retVal; + + // Guard in case we get interrupted, we cannot safely compare/search and get interrupted + RTC_DisableOVFInterrupt(); + + // Special case, the head is the one we are deleting + if (timer == *list) + { + *list = (*list)->next; // Delete the head + retVal = true; + startTimerAtHead(); // Start the new timer at the head + } else + { // More than one timer in the list, search the list. + timerStruct_t *findTimer = *list; + timerStruct_t *prevTimer = NULL; + while(findTimer != NULL) + { + if(findTimer == timer) + { + prevTimer->next = findTimer->next; + retVal = true; + break; + } + prevTimer = findTimer; + findTimer = findTimer->next; + } + RTC_EnableOVFInterrupt(); + } + + return retVal; +} + +// This will cancel/remove a running timer. If the timer is already expired it will +// also remove it from the callback queue +void timeout_delete(timerStruct_t *timer) +{ + if (!timeout_deleteHelper(&listHead, timer)) + { + timeout_deleteHelper(&executeQueueHead, timer); + } + + timer->next = NULL; +} + +// Moves the timer from the active list to the list of timers which are expired and +// needs their callbacks called in callNextCallback +inline void enqueueCallback(timerStruct_t* timer) +{ + timerStruct_t *tmp; + timer->next = NULL; + + // Special case for empty list + if (executeQueueHead == NULL) + { + executeQueueHead = timer; + return; + } + + // Find the end of the list and insert the next expired timer at the back of the queue + tmp = executeQueueHead; + while(tmp->next != NULL) + tmp = tmp->next; + + tmp->next = timer; +} + +// This function checks the list of expired timers and calls the first one in the +// list if the list is not empty. It also reschedules the timer if the callback +// returned a value greater than 0 +// It is recommended this is called from the main superloop (while(1)) in your code +// but by design this can also be called from the timer ISR. If you wish callbacks +// to happen from the ISR context you can call this as the last action in timeout_isr +// instead. +inline void timeout_callNextCallback(void) +{ + if (executeQueueHead == NULL) + return; + + bool tempIE = RTC_IsOVFInterruptEnabled(); + RTC_DisableOVFInterrupt(); + + timerStruct_t *callBackTimer = executeQueueHead; + + // Done, remove from list + executeQueueHead = executeQueueHead->next; + // Mark the timer as not in use + callBackTimer->next = NULL; + + if(tempIE) + { + RTC_EnableOVFInterrupt(); + } + + uint32_t reschedule = callBackTimer->callbackPtr(callBackTimer->payload); + + // Do we have to reschedule it? If yes then add delta to absolute for reschedule + if(reschedule) + { + timeout_create(callBackTimer, reschedule); + } +} + +void timeout_initialize(void) +{ + RTC_SetOVFIsrCallback(timeout_isr); +} + +// This function starts the timer provided with an expiry equal to "timeout". +// If the timer was already active/running it will be replaced by this and the +// old (active) timer will be removed/cancelled first +void timeout_create(timerStruct_t *timer, uint32_t timeout) +{ + // If this timer is already active, replace it + timeout_delete(timer); + + RTC_DisableOVFInterrupt(); + + timer->absoluteTime = makeAbsolute(timeout); + + // We only have to start the timer at head if the insert was at the head + if(sortedInsert(timer)) + { + startTimerAtHead(); + } else { + if (isRunning) + RTC_EnableOVFInterrupt(); + } +} + +// NOTE: assumes the callback completes before the next timer tick +void timeout_isr(void) +{ + timerStruct_t *next = listHead->next; + absoluteTimeofLastTimeout = listHead->absoluteTime; + lastTimerLoad = 0; + + if (listHead != &dummy) { + enqueueCallback(listHead); + } + + listHead = next; + + startTimerAtHead(); +} + + +// These methods are for calculating the elapsed time in stopwatch mode. +// startTimer will start a timer with (maximum range)/2. You cannot time more than +// this and the timer will stop after this time elapses +void timeout_startTimer(timerStruct_t *timer) +{ + uint32_t i = -1; + timeout_create(timer, i>>1); +} + +// This function stops the "stopwatch" and returns the elapsed time. +uint32_t timeout_stopTimer(timerStruct_t *timer) +{ + uint32_t now = makeAbsolute(0); // Do this as fast as possible for accuracy + uint32_t i = -1; + i>>=1; + + timeout_delete(timer); + + uint32_t diff = timer->absoluteTime - now; + + // This calculates the (max range)/2 minus (remaining time) which = elapsed time + return (i - diff); +} diff --git a/AVRIoT.X/mcc_generated_files/drivers/timeout.h b/AVRIoT.X/mcc_generated_files/drivers/timeout.h new file mode 100644 index 0000000..7fcc379 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/drivers/timeout.h @@ -0,0 +1,66 @@ +/* + (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this + software and any derivatives exclusively with Microchip products. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION + WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + + MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE + TERMS. +*/ + +#ifndef __TIMEOUTDRIVER_H +#define __TIMEOUTDRIVER_H + +#include +#include + +/* +* Please note that the timer tick is different from the timer period. +* A tick occurs each time the peripheral timer increases its count +* The timer period is when the number of ticks reaches its specified maximum and +* the timer overflow interrupt occurs. +* This library sets the timer period internally as needed +*/ +#define INLINE + +// mSec to Ticks and Ticks to mSec conversion. These values are based on the minimum period of the TMRx peripheral +// Note that these values have been rounded to the nearest power of two to make the calculations faster at runtime +#define timeout_mSecToTicks(a) ( ((uint32_t)(a)) * 32UL ) +#define timeout_ticksToMsec(a) ( ((uint32_t)(a)) / 32UL ) + +typedef uint32_t (*timercallback_ptr_t)(void *payload); + +typedef struct tmrStruct { + timercallback_ptr_t callbackPtr; + void* payload; + struct tmrStruct* next; + uint32_t absoluteTime; +} timerStruct_t; + +void timeout_initialize(void); +void timeout_create(timerStruct_t *timer, uint32_t timeout); +void timeout_delete(timerStruct_t *timer); +void timeout_flushAll(void); +bool timeout_hasPendingTimeouts(void); +bool timeout_hasPendingCallbacks(void); +INLINE void timeout_callNextCallback(void); +void timeout_isr(void); + +void timeout_startTimer(timerStruct_t *timer); +uint32_t timeout_stopTimer(timerStruct_t *timer); + +uint32_t timeout_getTimeRemaining(timerStruct_t *timer); + +#endif // __TIMEOUTDRIVER_H diff --git a/AVRIoT.X/mcc_generated_files/drivers/uart.c b/AVRIoT.X/mcc_generated_files/drivers/uart.c new file mode 100644 index 0000000..c3bf0b6 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/drivers/uart.c @@ -0,0 +1,36 @@ +/* + (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this + software and any derivatives exclusively with Microchip products. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION + WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + + MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE + TERMS. +*/ + +/** + Section: Included Files + */ + +#include "uart.h" + + +const uart_functions_t uart[] = { + {USART2_Read, USART2_Write, USART2_IsTxReady, USART2_IsRxReady, USART2_SetTXISRCb, USART2_DefaultRxIsrCb, USART2_SetRXISRCb, USART2_IsTxDone, USART2_DefaultTxIsrCb, USART2_Initialize } +}; + +/** + End of File + */ diff --git a/AVRIoT.X/mcc_generated_files/drivers/uart.h b/AVRIoT.X/mcc_generated_files/drivers/uart.h new file mode 100644 index 0000000..ac6b2e5 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/drivers/uart.h @@ -0,0 +1,45 @@ +/* + (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this + software and any derivatives exclusively with Microchip products. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION + WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + + MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE + TERMS. +*/ + +#ifndef _UART_H +#define _UART_H + + +#include +#include +#include "../include/usart2.h" + +/** +\typedef This typdef is a list of all the configuration names added/selected by the user. +*/ +typedef enum { + CLI /** +#include "port.h" + +//get/set PA2 aliases +#define PA2_SetHigh() do { PORTA_OUTSET = 0x4; } while(0) +#define PA2_SetLow() do { PORTA_OUTCLR = 0x4; } while(0) +#define PA2_Toggle() do { PORTA_OUTTGL = 0x4; } while(0) +#define PA2_GetValue() (VPORTA.IN & (0x1 << 2)) +#define PA2_SetDigitalInput() do { PORTA_DIRCLR = 0x4; } while(0) +#define PA2_SetDigitalOutput() do { PORTA_DIRSET = 0x4; } while(0) +#define PA2_SetPullUp() do { PORTA_PIN2CTRL |= PORT_PULLUPEN_bm; } while(0) +#define PA2_ResetPullUp() do { PORTA_PIN2CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define PA2_SetInverted() do { PORTA_PIN2CTRL |= PORT_INVEN_bm; } while(0) +#define PA2_ResetInverted() do { PORTA_PIN2CTRL &= ~PORT_INVEN_bm; } while(0) +#define PA2_DisableInterruptOnChange() do { PORTA.PIN2CTRL = (PORTA.PIN2CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define PA2_EnableInterruptForBothEdges() do { PORTA.PIN2CTRL = (PORTA.PIN2CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define PA2_EnableInterruptForRisingEdge() do { PORTA.PIN2CTRL = (PORTA.PIN2CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define PA2_EnableInterruptForFallingEdge() do { PORTA.PIN2CTRL = (PORTA.PIN2CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define PA2_DisableDigitalInputBuffer() do { PORTA.PIN2CTRL = (PORTA.PIN2CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define PA2_EnableInterruptForLowLevelSensing() do { PORTA.PIN2CTRL = (PORTA.PIN2CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +//get/set PD5 aliases +#define PD5_SetHigh() do { PORTD_OUTSET = 0x20; } while(0) +#define PD5_SetLow() do { PORTD_OUTCLR = 0x20; } while(0) +#define PD5_Toggle() do { PORTD_OUTTGL = 0x20; } while(0) +#define PD5_GetValue() (VPORTD.IN & (0x1 << 5)) +#define PD5_SetDigitalInput() do { PORTD_DIRCLR = 0x20; } while(0) +#define PD5_SetDigitalOutput() do { PORTD_DIRSET = 0x20; } while(0) +#define PD5_SetPullUp() do { PORTD_PIN5CTRL |= PORT_PULLUPEN_bm; } while(0) +#define PD5_ResetPullUp() do { PORTD_PIN5CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define PD5_SetInverted() do { PORTD_PIN5CTRL |= PORT_INVEN_bm; } while(0) +#define PD5_ResetInverted() do { PORTD_PIN5CTRL &= ~PORT_INVEN_bm; } while(0) +#define PD5_DisableInterruptOnChange() do { PORTD.PIN5CTRL = (PORTD.PIN5CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define PD5_EnableInterruptForBothEdges() do { PORTD.PIN5CTRL = (PORTD.PIN5CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define PD5_EnableInterruptForRisingEdge() do { PORTD.PIN5CTRL = (PORTD.PIN5CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define PD5_EnableInterruptForFallingEdge() do { PORTD.PIN5CTRL = (PORTD.PIN5CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define PD5_DisableDigitalInputBuffer() do { PORTD.PIN5CTRL = (PORTD.PIN5CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define PD5_EnableInterruptForLowLevelSensing() do { PORTD.PIN5CTRL = (PORTD.PIN5CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +//get/set SW0 aliases +#define SW0_SetHigh() do { PORTF_OUTSET = 0x40; } while(0) +#define SW0_SetLow() do { PORTF_OUTCLR = 0x40; } while(0) +#define SW0_Toggle() do { PORTF_OUTTGL = 0x40; } while(0) +#define SW0_GetValue() (VPORTF.IN & (0x1 << 6)) +#define SW0_SetDigitalInput() do { PORTF_DIRCLR = 0x40; } while(0) +#define SW0_SetDigitalOutput() do { PORTF_DIRSET = 0x40; } while(0) +#define SW0_SetPullUp() do { PORTF_PIN6CTRL |= PORT_PULLUPEN_bm; } while(0) +#define SW0_ResetPullUp() do { PORTF_PIN6CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define SW0_SetInverted() do { PORTF_PIN6CTRL |= PORT_INVEN_bm; } while(0) +#define SW0_ResetInverted() do { PORTF_PIN6CTRL &= ~PORT_INVEN_bm; } while(0) +#define SW0_DisableInterruptOnChange() do { PORTF.PIN6CTRL = (PORTF.PIN6CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define SW0_EnableInterruptForBothEdges() do { PORTF.PIN6CTRL = (PORTF.PIN6CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define SW0_EnableInterruptForRisingEdge() do { PORTF.PIN6CTRL = (PORTF.PIN6CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define SW0_EnableInterruptForFallingEdge() do { PORTF.PIN6CTRL = (PORTF.PIN6CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define SW0_DisableDigitalInputBuffer() do { PORTF.PIN6CTRL = (PORTF.PIN6CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define SW0_EnableInterruptForLowLevelSensing() do { PORTF.PIN6CTRL = (PORTF.PIN6CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +//get/set RST aliases +#define RST_SetHigh() do { PORTA_OUTSET = 0x2; } while(0) +#define RST_SetLow() do { PORTA_OUTCLR = 0x2; } while(0) +#define RST_Toggle() do { PORTA_OUTTGL = 0x2; } while(0) +#define RST_GetValue() (VPORTA.IN & (0x1 << 1)) +#define RST_SetDigitalInput() do { PORTA_DIRCLR = 0x2; } while(0) +#define RST_SetDigitalOutput() do { PORTA_DIRSET = 0x2; } while(0) +#define RST_SetPullUp() do { PORTA_PIN1CTRL |= PORT_PULLUPEN_bm; } while(0) +#define RST_ResetPullUp() do { PORTA_PIN1CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define RST_SetInverted() do { PORTA_PIN1CTRL |= PORT_INVEN_bm; } while(0) +#define RST_ResetInverted() do { PORTA_PIN1CTRL &= ~PORT_INVEN_bm; } while(0) +#define RST_DisableInterruptOnChange() do { PORTA.PIN1CTRL = (PORTA.PIN1CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define RST_EnableInterruptForBothEdges() do { PORTA.PIN1CTRL = (PORTA.PIN1CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define RST_EnableInterruptForRisingEdge() do { PORTA.PIN1CTRL = (PORTA.PIN1CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define RST_EnableInterruptForFallingEdge() do { PORTA.PIN1CTRL = (PORTA.PIN1CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define RST_DisableDigitalInputBuffer() do { PORTA.PIN1CTRL = (PORTA.PIN1CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define RST_EnableInterruptForLowLevelSensing() do { PORTA.PIN1CTRL = (PORTA.PIN1CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +//get/set PA4 aliases +#define PA4_SetHigh() do { PORTA_OUTSET = 0x10; } while(0) +#define PA4_SetLow() do { PORTA_OUTCLR = 0x10; } while(0) +#define PA4_Toggle() do { PORTA_OUTTGL = 0x10; } while(0) +#define PA4_GetValue() (VPORTA.IN & (0x1 << 4)) +#define PA4_SetDigitalInput() do { PORTA_DIRCLR = 0x10; } while(0) +#define PA4_SetDigitalOutput() do { PORTA_DIRSET = 0x10; } while(0) +#define PA4_SetPullUp() do { PORTA_PIN4CTRL |= PORT_PULLUPEN_bm; } while(0) +#define PA4_ResetPullUp() do { PORTA_PIN4CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define PA4_SetInverted() do { PORTA_PIN4CTRL |= PORT_INVEN_bm; } while(0) +#define PA4_ResetInverted() do { PORTA_PIN4CTRL &= ~PORT_INVEN_bm; } while(0) +#define PA4_DisableInterruptOnChange() do { PORTA.PIN4CTRL = (PORTA.PIN4CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define PA4_EnableInterruptForBothEdges() do { PORTA.PIN4CTRL = (PORTA.PIN4CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define PA4_EnableInterruptForRisingEdge() do { PORTA.PIN4CTRL = (PORTA.PIN4CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define PA4_EnableInterruptForFallingEdge() do { PORTA.PIN4CTRL = (PORTA.PIN4CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define PA4_DisableDigitalInputBuffer() do { PORTA.PIN4CTRL = (PORTA.PIN4CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define PA4_EnableInterruptForLowLevelSensing() do { PORTA.PIN4CTRL = (PORTA.PIN4CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +//get/set PA3 aliases +#define PA3_SetHigh() do { PORTA_OUTSET = 0x8; } while(0) +#define PA3_SetLow() do { PORTA_OUTCLR = 0x8; } while(0) +#define PA3_Toggle() do { PORTA_OUTTGL = 0x8; } while(0) +#define PA3_GetValue() (VPORTA.IN & (0x1 << 3)) +#define PA3_SetDigitalInput() do { PORTA_DIRCLR = 0x8; } while(0) +#define PA3_SetDigitalOutput() do { PORTA_DIRSET = 0x8; } while(0) +#define PA3_SetPullUp() do { PORTA_PIN3CTRL |= PORT_PULLUPEN_bm; } while(0) +#define PA3_ResetPullUp() do { PORTA_PIN3CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define PA3_SetInverted() do { PORTA_PIN3CTRL |= PORT_INVEN_bm; } while(0) +#define PA3_ResetInverted() do { PORTA_PIN3CTRL &= ~PORT_INVEN_bm; } while(0) +#define PA3_DisableInterruptOnChange() do { PORTA.PIN3CTRL = (PORTA.PIN3CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define PA3_EnableInterruptForBothEdges() do { PORTA.PIN3CTRL = (PORTA.PIN3CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define PA3_EnableInterruptForRisingEdge() do { PORTA.PIN3CTRL = (PORTA.PIN3CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define PA3_EnableInterruptForFallingEdge() do { PORTA.PIN3CTRL = (PORTA.PIN3CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define PA3_DisableDigitalInputBuffer() do { PORTA.PIN3CTRL = (PORTA.PIN3CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define PA3_EnableInterruptForLowLevelSensing() do { PORTA.PIN3CTRL = (PORTA.PIN3CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +//get/set PA6 aliases +#define PA6_SetHigh() do { PORTA_OUTSET = 0x40; } while(0) +#define PA6_SetLow() do { PORTA_OUTCLR = 0x40; } while(0) +#define PA6_Toggle() do { PORTA_OUTTGL = 0x40; } while(0) +#define PA6_GetValue() (VPORTA.IN & (0x1 << 6)) +#define PA6_SetDigitalInput() do { PORTA_DIRCLR = 0x40; } while(0) +#define PA6_SetDigitalOutput() do { PORTA_DIRSET = 0x40; } while(0) +#define PA6_SetPullUp() do { PORTA_PIN6CTRL |= PORT_PULLUPEN_bm; } while(0) +#define PA6_ResetPullUp() do { PORTA_PIN6CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define PA6_SetInverted() do { PORTA_PIN6CTRL |= PORT_INVEN_bm; } while(0) +#define PA6_ResetInverted() do { PORTA_PIN6CTRL &= ~PORT_INVEN_bm; } while(0) +#define PA6_DisableInterruptOnChange() do { PORTA.PIN6CTRL = (PORTA.PIN6CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define PA6_EnableInterruptForBothEdges() do { PORTA.PIN6CTRL = (PORTA.PIN6CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define PA6_EnableInterruptForRisingEdge() do { PORTA.PIN6CTRL = (PORTA.PIN6CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define PA6_EnableInterruptForFallingEdge() do { PORTA.PIN6CTRL = (PORTA.PIN6CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define PA6_DisableDigitalInputBuffer() do { PORTA.PIN6CTRL = (PORTA.PIN6CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define PA6_EnableInterruptForLowLevelSensing() do { PORTA.PIN6CTRL = (PORTA.PIN6CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +//get/set PA5 aliases +#define PA5_SetHigh() do { PORTA_OUTSET = 0x20; } while(0) +#define PA5_SetLow() do { PORTA_OUTCLR = 0x20; } while(0) +#define PA5_Toggle() do { PORTA_OUTTGL = 0x20; } while(0) +#define PA5_GetValue() (VPORTA.IN & (0x1 << 5)) +#define PA5_SetDigitalInput() do { PORTA_DIRCLR = 0x20; } while(0) +#define PA5_SetDigitalOutput() do { PORTA_DIRSET = 0x20; } while(0) +#define PA5_SetPullUp() do { PORTA_PIN5CTRL |= PORT_PULLUPEN_bm; } while(0) +#define PA5_ResetPullUp() do { PORTA_PIN5CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define PA5_SetInverted() do { PORTA_PIN5CTRL |= PORT_INVEN_bm; } while(0) +#define PA5_ResetInverted() do { PORTA_PIN5CTRL &= ~PORT_INVEN_bm; } while(0) +#define PA5_DisableInterruptOnChange() do { PORTA.PIN5CTRL = (PORTA.PIN5CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define PA5_EnableInterruptForBothEdges() do { PORTA.PIN5CTRL = (PORTA.PIN5CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define PA5_EnableInterruptForRisingEdge() do { PORTA.PIN5CTRL = (PORTA.PIN5CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define PA5_EnableInterruptForFallingEdge() do { PORTA.PIN5CTRL = (PORTA.PIN5CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define PA5_DisableDigitalInputBuffer() do { PORTA.PIN5CTRL = (PORTA.PIN5CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define PA5_EnableInterruptForLowLevelSensing() do { PORTA.PIN5CTRL = (PORTA.PIN5CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +//get/set nCS aliases +#define nCS_SetHigh() do { PORTA_OUTSET = 0x80; } while(0) +#define nCS_SetLow() do { PORTA_OUTCLR = 0x80; } while(0) +#define nCS_Toggle() do { PORTA_OUTTGL = 0x80; } while(0) +#define nCS_GetValue() (VPORTA.IN & (0x1 << 7)) +#define nCS_SetDigitalInput() do { PORTA_DIRCLR = 0x80; } while(0) +#define nCS_SetDigitalOutput() do { PORTA_DIRSET = 0x80; } while(0) +#define nCS_SetPullUp() do { PORTA_PIN7CTRL |= PORT_PULLUPEN_bm; } while(0) +#define nCS_ResetPullUp() do { PORTA_PIN7CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define nCS_SetInverted() do { PORTA_PIN7CTRL |= PORT_INVEN_bm; } while(0) +#define nCS_ResetInverted() do { PORTA_PIN7CTRL &= ~PORT_INVEN_bm; } while(0) +#define nCS_DisableInterruptOnChange() do { PORTA.PIN7CTRL = (PORTA.PIN7CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define nCS_EnableInterruptForBothEdges() do { PORTA.PIN7CTRL = (PORTA.PIN7CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define nCS_EnableInterruptForRisingEdge() do { PORTA.PIN7CTRL = (PORTA.PIN7CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define nCS_EnableInterruptForFallingEdge() do { PORTA.PIN7CTRL = (PORTA.PIN7CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define nCS_DisableDigitalInputBuffer() do { PORTA.PIN7CTRL = (PORTA.PIN7CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define nCS_EnableInterruptForLowLevelSensing() do { PORTA.PIN7CTRL = (PORTA.PIN7CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +//get/set PF1 aliases +#define PF1_SetHigh() do { PORTF_OUTSET = 0x2; } while(0) +#define PF1_SetLow() do { PORTF_OUTCLR = 0x2; } while(0) +#define PF1_Toggle() do { PORTF_OUTTGL = 0x2; } while(0) +#define PF1_GetValue() (VPORTF.IN & (0x1 << 1)) +#define PF1_SetDigitalInput() do { PORTF_DIRCLR = 0x2; } while(0) +#define PF1_SetDigitalOutput() do { PORTF_DIRSET = 0x2; } while(0) +#define PF1_SetPullUp() do { PORTF_PIN1CTRL |= PORT_PULLUPEN_bm; } while(0) +#define PF1_ResetPullUp() do { PORTF_PIN1CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define PF1_SetInverted() do { PORTF_PIN1CTRL |= PORT_INVEN_bm; } while(0) +#define PF1_ResetInverted() do { PORTF_PIN1CTRL &= ~PORT_INVEN_bm; } while(0) +#define PF1_DisableInterruptOnChange() do { PORTF.PIN1CTRL = (PORTF.PIN1CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define PF1_EnableInterruptForBothEdges() do { PORTF.PIN1CTRL = (PORTF.PIN1CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define PF1_EnableInterruptForRisingEdge() do { PORTF.PIN1CTRL = (PORTF.PIN1CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define PF1_EnableInterruptForFallingEdge() do { PORTF.PIN1CTRL = (PORTF.PIN1CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define PF1_DisableDigitalInputBuffer() do { PORTF.PIN1CTRL = (PORTF.PIN1CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define PF1_EnableInterruptForLowLevelSensing() do { PORTF.PIN1CTRL = (PORTF.PIN1CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +//get/set PF0 aliases +#define PF0_SetHigh() do { PORTF_OUTSET = 0x1; } while(0) +#define PF0_SetLow() do { PORTF_OUTCLR = 0x1; } while(0) +#define PF0_Toggle() do { PORTF_OUTTGL = 0x1; } while(0) +#define PF0_GetValue() (VPORTF.IN & (0x1 << 0)) +#define PF0_SetDigitalInput() do { PORTF_DIRCLR = 0x1; } while(0) +#define PF0_SetDigitalOutput() do { PORTF_DIRSET = 0x1; } while(0) +#define PF0_SetPullUp() do { PORTF_PIN0CTRL |= PORT_PULLUPEN_bm; } while(0) +#define PF0_ResetPullUp() do { PORTF_PIN0CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define PF0_SetInverted() do { PORTF_PIN0CTRL |= PORT_INVEN_bm; } while(0) +#define PF0_ResetInverted() do { PORTF_PIN0CTRL &= ~PORT_INVEN_bm; } while(0) +#define PF0_DisableInterruptOnChange() do { PORTF.PIN0CTRL = (PORTF.PIN0CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define PF0_EnableInterruptForBothEdges() do { PORTF.PIN0CTRL = (PORTF.PIN0CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define PF0_EnableInterruptForRisingEdge() do { PORTF.PIN0CTRL = (PORTF.PIN0CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define PF0_EnableInterruptForFallingEdge() do { PORTF.PIN0CTRL = (PORTF.PIN0CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define PF0_DisableDigitalInputBuffer() do { PORTF.PIN0CTRL = (PORTF.PIN0CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define PF0_EnableInterruptForLowLevelSensing() do { PORTF.PIN0CTRL = (PORTF.PIN0CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +//get/set LED_YELLOW aliases +#define LED_YELLOW_SetHigh() do { PORTD_OUTSET = 0x2; } while(0) +#define LED_YELLOW_SetLow() do { PORTD_OUTCLR = 0x2; } while(0) +#define LED_YELLOW_Toggle() do { PORTD_OUTTGL = 0x2; } while(0) +#define LED_YELLOW_GetValue() (VPORTD.IN & (0x1 << 1)) +#define LED_YELLOW_SetDigitalInput() do { PORTD_DIRCLR = 0x2; } while(0) +#define LED_YELLOW_SetDigitalOutput() do { PORTD_DIRSET = 0x2; } while(0) +#define LED_YELLOW_SetPullUp() do { PORTD_PIN1CTRL |= PORT_PULLUPEN_bm; } while(0) +#define LED_YELLOW_ResetPullUp() do { PORTD_PIN1CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define LED_YELLOW_SetInverted() do { PORTD_PIN1CTRL |= PORT_INVEN_bm; } while(0) +#define LED_YELLOW_ResetInverted() do { PORTD_PIN1CTRL &= ~PORT_INVEN_bm; } while(0) +#define LED_YELLOW_DisableInterruptOnChange() do { PORTD.PIN1CTRL = (PORTD.PIN1CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define LED_YELLOW_EnableInterruptForBothEdges() do { PORTD.PIN1CTRL = (PORTD.PIN1CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define LED_YELLOW_EnableInterruptForRisingEdge() do { PORTD.PIN1CTRL = (PORTD.PIN1CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define LED_YELLOW_EnableInterruptForFallingEdge() do { PORTD.PIN1CTRL = (PORTD.PIN1CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define LED_YELLOW_DisableDigitalInputBuffer() do { PORTD.PIN1CTRL = (PORTD.PIN1CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define LED_YELLOW_EnableInterruptForLowLevelSensing() do { PORTD.PIN1CTRL = (PORTD.PIN1CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +//get/set CE aliases +#define CE_SetHigh() do { PORTF_OUTSET = 0x8; } while(0) +#define CE_SetLow() do { PORTF_OUTCLR = 0x8; } while(0) +#define CE_Toggle() do { PORTF_OUTTGL = 0x8; } while(0) +#define CE_GetValue() (VPORTF.IN & (0x1 << 3)) +#define CE_SetDigitalInput() do { PORTF_DIRCLR = 0x8; } while(0) +#define CE_SetDigitalOutput() do { PORTF_DIRSET = 0x8; } while(0) +#define CE_SetPullUp() do { PORTF_PIN3CTRL |= PORT_PULLUPEN_bm; } while(0) +#define CE_ResetPullUp() do { PORTF_PIN3CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define CE_SetInverted() do { PORTF_PIN3CTRL |= PORT_INVEN_bm; } while(0) +#define CE_ResetInverted() do { PORTF_PIN3CTRL &= ~PORT_INVEN_bm; } while(0) +#define CE_DisableInterruptOnChange() do { PORTF.PIN3CTRL = (PORTF.PIN3CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define CE_EnableInterruptForBothEdges() do { PORTF.PIN3CTRL = (PORTF.PIN3CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define CE_EnableInterruptForRisingEdge() do { PORTF.PIN3CTRL = (PORTF.PIN3CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define CE_EnableInterruptForFallingEdge() do { PORTF.PIN3CTRL = (PORTF.PIN3CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define CE_DisableDigitalInputBuffer() do { PORTF.PIN3CTRL = (PORTF.PIN3CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define CE_EnableInterruptForLowLevelSensing() do { PORTF.PIN3CTRL = (PORTF.PIN3CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +//get/set LED_RED aliases +#define LED_RED_SetHigh() do { PORTD_OUTSET = 0x1; } while(0) +#define LED_RED_SetLow() do { PORTD_OUTCLR = 0x1; } while(0) +#define LED_RED_Toggle() do { PORTD_OUTTGL = 0x1; } while(0) +#define LED_RED_GetValue() (VPORTD.IN & (0x1 << 0)) +#define LED_RED_SetDigitalInput() do { PORTD_DIRCLR = 0x1; } while(0) +#define LED_RED_SetDigitalOutput() do { PORTD_DIRSET = 0x1; } while(0) +#define LED_RED_SetPullUp() do { PORTD_PIN0CTRL |= PORT_PULLUPEN_bm; } while(0) +#define LED_RED_ResetPullUp() do { PORTD_PIN0CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define LED_RED_SetInverted() do { PORTD_PIN0CTRL |= PORT_INVEN_bm; } while(0) +#define LED_RED_ResetInverted() do { PORTD_PIN0CTRL &= ~PORT_INVEN_bm; } while(0) +#define LED_RED_DisableInterruptOnChange() do { PORTD.PIN0CTRL = (PORTD.PIN0CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define LED_RED_EnableInterruptForBothEdges() do { PORTD.PIN0CTRL = (PORTD.PIN0CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define LED_RED_EnableInterruptForRisingEdge() do { PORTD.PIN0CTRL = (PORTD.PIN0CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define LED_RED_EnableInterruptForFallingEdge() do { PORTD.PIN0CTRL = (PORTD.PIN0CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define LED_RED_DisableDigitalInputBuffer() do { PORTD.PIN0CTRL = (PORTD.PIN0CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define LED_RED_EnableInterruptForLowLevelSensing() do { PORTD.PIN0CTRL = (PORTD.PIN0CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +//get/set INT aliases +#define INT_SetHigh() do { PORTF_OUTSET = 0x4; } while(0) +#define INT_SetLow() do { PORTF_OUTCLR = 0x4; } while(0) +#define INT_Toggle() do { PORTF_OUTTGL = 0x4; } while(0) +#define INT_GetValue() (VPORTF.IN & (0x1 << 2)) +#define INT_SetDigitalInput() do { PORTF_DIRCLR = 0x4; } while(0) +#define INT_SetDigitalOutput() do { PORTF_DIRSET = 0x4; } while(0) +#define INT_SetPullUp() do { PORTF_PIN2CTRL |= PORT_PULLUPEN_bm; } while(0) +#define INT_ResetPullUp() do { PORTF_PIN2CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define INT_SetInverted() do { PORTF_PIN2CTRL |= PORT_INVEN_bm; } while(0) +#define INT_ResetInverted() do { PORTF_PIN2CTRL &= ~PORT_INVEN_bm; } while(0) +#define INT_DisableInterruptOnChange() do { PORTF.PIN2CTRL = (PORTF.PIN2CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define INT_EnableInterruptForBothEdges() do { PORTF.PIN2CTRL = (PORTF.PIN2CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define INT_EnableInterruptForRisingEdge() do { PORTF.PIN2CTRL = (PORTF.PIN2CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define INT_EnableInterruptForFallingEdge() do { PORTF.PIN2CTRL = (PORTF.PIN2CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define INT_DisableDigitalInputBuffer() do { PORTF.PIN2CTRL = (PORTF.PIN2CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define INT_EnableInterruptForLowLevelSensing() do { PORTF.PIN2CTRL = (PORTF.PIN2CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +//get/set SW1 aliases +#define SW1_SetHigh() do { PORTF_OUTSET = 0x20; } while(0) +#define SW1_SetLow() do { PORTF_OUTCLR = 0x20; } while(0) +#define SW1_Toggle() do { PORTF_OUTTGL = 0x20; } while(0) +#define SW1_GetValue() (VPORTF.IN & (0x1 << 5)) +#define SW1_SetDigitalInput() do { PORTF_DIRCLR = 0x20; } while(0) +#define SW1_SetDigitalOutput() do { PORTF_DIRSET = 0x20; } while(0) +#define SW1_SetPullUp() do { PORTF_PIN5CTRL |= PORT_PULLUPEN_bm; } while(0) +#define SW1_ResetPullUp() do { PORTF_PIN5CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define SW1_SetInverted() do { PORTF_PIN5CTRL |= PORT_INVEN_bm; } while(0) +#define SW1_ResetInverted() do { PORTF_PIN5CTRL &= ~PORT_INVEN_bm; } while(0) +#define SW1_DisableInterruptOnChange() do { PORTF.PIN5CTRL = (PORTF.PIN5CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define SW1_EnableInterruptForBothEdges() do { PORTF.PIN5CTRL = (PORTF.PIN5CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define SW1_EnableInterruptForRisingEdge() do { PORTF.PIN5CTRL = (PORTF.PIN5CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define SW1_EnableInterruptForFallingEdge() do { PORTF.PIN5CTRL = (PORTF.PIN5CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define SW1_DisableDigitalInputBuffer() do { PORTF.PIN5CTRL = (PORTF.PIN5CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define SW1_EnableInterruptForLowLevelSensing() do { PORTF.PIN5CTRL = (PORTF.PIN5CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +//get/set LED_BLUE aliases +#define LED_BLUE_SetHigh() do { PORTD_OUTSET = 0x8; } while(0) +#define LED_BLUE_SetLow() do { PORTD_OUTCLR = 0x8; } while(0) +#define LED_BLUE_Toggle() do { PORTD_OUTTGL = 0x8; } while(0) +#define LED_BLUE_GetValue() (VPORTD.IN & (0x1 << 3)) +#define LED_BLUE_SetDigitalInput() do { PORTD_DIRCLR = 0x8; } while(0) +#define LED_BLUE_SetDigitalOutput() do { PORTD_DIRSET = 0x8; } while(0) +#define LED_BLUE_SetPullUp() do { PORTD_PIN3CTRL |= PORT_PULLUPEN_bm; } while(0) +#define LED_BLUE_ResetPullUp() do { PORTD_PIN3CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define LED_BLUE_SetInverted() do { PORTD_PIN3CTRL |= PORT_INVEN_bm; } while(0) +#define LED_BLUE_ResetInverted() do { PORTD_PIN3CTRL &= ~PORT_INVEN_bm; } while(0) +#define LED_BLUE_DisableInterruptOnChange() do { PORTD.PIN3CTRL = (PORTD.PIN3CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define LED_BLUE_EnableInterruptForBothEdges() do { PORTD.PIN3CTRL = (PORTD.PIN3CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define LED_BLUE_EnableInterruptForRisingEdge() do { PORTD.PIN3CTRL = (PORTD.PIN3CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define LED_BLUE_EnableInterruptForFallingEdge() do { PORTD.PIN3CTRL = (PORTD.PIN3CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define LED_BLUE_DisableDigitalInputBuffer() do { PORTD.PIN3CTRL = (PORTD.PIN3CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define LED_BLUE_EnableInterruptForLowLevelSensing() do { PORTD.PIN3CTRL = (PORTD.PIN3CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +//get/set LED_GREEN aliases +#define LED_GREEN_SetHigh() do { PORTD_OUTSET = 0x4; } while(0) +#define LED_GREEN_SetLow() do { PORTD_OUTCLR = 0x4; } while(0) +#define LED_GREEN_Toggle() do { PORTD_OUTTGL = 0x4; } while(0) +#define LED_GREEN_GetValue() (VPORTD.IN & (0x1 << 2)) +#define LED_GREEN_SetDigitalInput() do { PORTD_DIRCLR = 0x4; } while(0) +#define LED_GREEN_SetDigitalOutput() do { PORTD_DIRSET = 0x4; } while(0) +#define LED_GREEN_SetPullUp() do { PORTD_PIN2CTRL |= PORT_PULLUPEN_bm; } while(0) +#define LED_GREEN_ResetPullUp() do { PORTD_PIN2CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define LED_GREEN_SetInverted() do { PORTD_PIN2CTRL |= PORT_INVEN_bm; } while(0) +#define LED_GREEN_ResetInverted() do { PORTD_PIN2CTRL &= ~PORT_INVEN_bm; } while(0) +#define LED_GREEN_DisableInterruptOnChange() do { PORTD.PIN2CTRL = (PORTD.PIN2CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define LED_GREEN_EnableInterruptForBothEdges() do { PORTD.PIN2CTRL = (PORTD.PIN2CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define LED_GREEN_EnableInterruptForRisingEdge() do { PORTD.PIN2CTRL = (PORTD.PIN2CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define LED_GREEN_EnableInterruptForFallingEdge() do { PORTD.PIN2CTRL = (PORTD.PIN2CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define LED_GREEN_DisableDigitalInputBuffer() do { PORTD.PIN2CTRL = (PORTD.PIN2CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define LED_GREEN_EnableInterruptForLowLevelSensing() do { PORTD.PIN2CTRL = (PORTD.PIN2CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +//get/set WAKE aliases +#define WAKE_SetHigh() do { PORTF_OUTSET = 0x10; } while(0) +#define WAKE_SetLow() do { PORTF_OUTCLR = 0x10; } while(0) +#define WAKE_Toggle() do { PORTF_OUTTGL = 0x10; } while(0) +#define WAKE_GetValue() (VPORTF.IN & (0x1 << 4)) +#define WAKE_SetDigitalInput() do { PORTF_DIRCLR = 0x10; } while(0) +#define WAKE_SetDigitalOutput() do { PORTF_DIRSET = 0x10; } while(0) +#define WAKE_SetPullUp() do { PORTF_PIN4CTRL |= PORT_PULLUPEN_bm; } while(0) +#define WAKE_ResetPullUp() do { PORTF_PIN4CTRL &= ~PORT_PULLUPEN_bm; } while(0) +#define WAKE_SetInverted() do { PORTF_PIN4CTRL |= PORT_INVEN_bm; } while(0) +#define WAKE_ResetInverted() do { PORTF_PIN4CTRL &= ~PORT_INVEN_bm; } while(0) +#define WAKE_DisableInterruptOnChange() do { PORTF.PIN4CTRL = (PORTF.PIN4CTRL & ~PORT_ISC_gm) | 0x0 ; } while(0) +#define WAKE_EnableInterruptForBothEdges() do { PORTF.PIN4CTRL = (PORTF.PIN4CTRL & ~PORT_ISC_gm) | 0x1 ; } while(0) +#define WAKE_EnableInterruptForRisingEdge() do { PORTF.PIN4CTRL = (PORTF.PIN4CTRL & ~PORT_ISC_gm) | 0x2 ; } while(0) +#define WAKE_EnableInterruptForFallingEdge() do { PORTF.PIN4CTRL = (PORTF.PIN4CTRL & ~PORT_ISC_gm) | 0x3 ; } while(0) +#define WAKE_DisableDigitalInputBuffer() do { PORTF.PIN4CTRL = (PORTF.PIN4CTRL & ~PORT_ISC_gm) | 0x4 ; } while(0) +#define WAKE_EnableInterruptForLowLevelSensing() do { PORTF.PIN4CTRL = (PORTF.PIN4CTRL & ~PORT_ISC_gm) | 0x5 ; } while(0) + +void PIN_MANAGER_Initialize(); +void PORTA_PA2_DefaultInterruptHandler(void); +void PORTA_PA2_SetInterruptHandler(void (* interruptHandler)(void)) ; +void PORTD_PD5_DefaultInterruptHandler(void); +void PORTD_PD5_SetInterruptHandler(void (* interruptHandler)(void)) ; +void PORTF_SW0_DefaultInterruptHandler(void); +void PORTF_SW0_SetInterruptHandler(void (* interruptHandler)(void)) ; +void PORTA_RST_DefaultInterruptHandler(void); +void PORTA_RST_SetInterruptHandler(void (* interruptHandler)(void)) ; +void PORTA_PA4_DefaultInterruptHandler(void); +void PORTA_PA4_SetInterruptHandler(void (* interruptHandler)(void)) ; +void PORTA_PA3_DefaultInterruptHandler(void); +void PORTA_PA3_SetInterruptHandler(void (* interruptHandler)(void)) ; +void PORTA_PA6_DefaultInterruptHandler(void); +void PORTA_PA6_SetInterruptHandler(void (* interruptHandler)(void)) ; +void PORTA_PA5_DefaultInterruptHandler(void); +void PORTA_PA5_SetInterruptHandler(void (* interruptHandler)(void)) ; +void PORTA_nCS_DefaultInterruptHandler(void); +void PORTA_nCS_SetInterruptHandler(void (* interruptHandler)(void)) ; +void PORTF_PF1_DefaultInterruptHandler(void); +void PORTF_PF1_SetInterruptHandler(void (* interruptHandler)(void)) ; +void PORTF_PF0_DefaultInterruptHandler(void); +void PORTF_PF0_SetInterruptHandler(void (* interruptHandler)(void)) ; +void PORTD_LED_YELLOW_DefaultInterruptHandler(void); +void PORTD_LED_YELLOW_SetInterruptHandler(void (* interruptHandler)(void)) ; +void PORTF_CE_DefaultInterruptHandler(void); +void PORTF_CE_SetInterruptHandler(void (* interruptHandler)(void)) ; +void PORTD_LED_RED_DefaultInterruptHandler(void); +void PORTD_LED_RED_SetInterruptHandler(void (* interruptHandler)(void)) ; +void PORTF_INT_DefaultInterruptHandler(void); +void PORTF_INT_SetInterruptHandler(void (* interruptHandler)(void)) ; +void PORTF_SW1_DefaultInterruptHandler(void); +void PORTF_SW1_SetInterruptHandler(void (* interruptHandler)(void)) ; +void PORTD_LED_BLUE_DefaultInterruptHandler(void); +void PORTD_LED_BLUE_SetInterruptHandler(void (* interruptHandler)(void)) ; +void PORTD_LED_GREEN_DefaultInterruptHandler(void); +void PORTD_LED_GREEN_SetInterruptHandler(void (* interruptHandler)(void)) ; +void PORTF_WAKE_DefaultInterruptHandler(void); +void PORTF_WAKE_SetInterruptHandler(void (* interruptHandler)(void)) ; +#endif /* PINS_H_INCLUDED */ diff --git a/AVRIoT.X/mcc_generated_files/include/port.h b/AVRIoT.X/mcc_generated_files/include/port.h new file mode 100644 index 0000000..dccb4ba --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/include/port.h @@ -0,0 +1,1373 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef PORT_INCLUDED +#define PORT_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../utils/compiler.h" + +enum port_pull_mode { + PORT_PULL_OFF, + PORT_PULL_UP, +}; + +enum port_dir { + PORT_DIR_IN, + PORT_DIR_OUT, + PORT_DIR_OFF, +}; +/** + * \brief Set port pin pull mode + * + * Configure pin to pull up, down or disable pull mode, supported pull modes are defined by device used + * + * \param[in] pin The pin number within port + * \param[in] pull_mode Pin pull mode + */ +static inline void PORTE_set_pin_pull_mode(const uint8_t pin, const enum port_pull_mode pull_mode) +{ + volatile uint8_t *port_pin_ctrl = ((uint8_t *)&PORTE + 0x10 + pin); + + if (pull_mode == PORT_PULL_UP) { + *port_pin_ctrl |= PORT_PULLUPEN_bm; + } else if (pull_mode == PORT_PULL_OFF) { + *port_pin_ctrl &= ~PORT_PULLUPEN_bm; + } +} + +/** + * \brief Set port pin inverted mode + * + * Configure pin invert I/O or not + * + * \param[in] pin The pin number within port + * \param[in] inverted Pin inverted mode + */ +static inline void PORTE_pin_set_inverted(const uint8_t pin, const bool inverted) +{ + volatile uint8_t *port_pin_ctrl = ((uint8_t *)&PORTE + 0x10 + pin); + + if (inverted) { + *port_pin_ctrl |= PORT_INVEN_bm; + } else { + *port_pin_ctrl &= ~PORT_INVEN_bm; + } +} + +/** + * \brief Set port pin input/sense configuration + * + * Enable/disable digital input buffer and pin change interrupt, + * select pin interrupt edge/level sensing mode + * + * \param[in] pin pin number within port + * \param[in] isc PORT_ISC_INTDISABLE_gc = Interrupt disabled but input buffer enabled + * PORT_ISC_BOTHEDGES_gc = Sense Both Edges + * PORT_ISC_RISING_gc = Sense Rising Edge + * PORT_ISC_FALLING_gc = Sense Falling Edge + * PORT_ISC_INPUT_DISABLE_gc = Digital Input Buffer disabled + * PORT_ISC_LEVEL_gc = Sense low Level + * + */ +static inline void PORTE_pin_set_isc(const uint8_t pin, const PORT_ISC_t isc) +{ + volatile uint8_t *port_pin_ctrl = ((uint8_t *)&PORTE + 0x10 + pin); + + *port_pin_ctrl = (*port_pin_ctrl & ~PORT_ISC_gm) | isc; +} + +/** + * \brief Set port data direction + * + * Select if the pin data direction is input, output or disabled. + * If disabled state is not possible, this function throws an assert. + * + * \param[in] mask Bit mask where 1 means apply direction setting to the + * corresponding pin + * \param[in] dir PORT_DIR_IN = Data direction in + * PORT_DIR_OUT = Data direction out + * PORT_DIR_OFF = Disables the pin + * (low power state) + */ +static inline void PORTE_set_port_dir(const uint8_t mask, const enum port_dir dir) +{ + switch (dir) { + case PORT_DIR_IN: + VPORTE.DIR &= ~mask; + break; + case PORT_DIR_OUT: + VPORTE.DIR |= mask; + break; + case PORT_DIR_OFF: + /*/ should activate the pullup for power saving + but a bit costly to do it here */ + { + for (uint8_t i = 0; i < 8; i++) { + if (mask & 1 << i) { + *((uint8_t *)&PORTE + 0x10 + i) |= 1 << PORT_PULLUPEN_bp; + } + } + } + break; + default: + break; + } +} + +/** + * \brief Set port pin data direction + * + * Select if the pin data direction is input, output or disabled. + * If disabled state is not possible, this function throws an assert. + * + * \param[in] pin The pin number within port + * \param[in] dir PORT_DIR_IN = Data direction in + * PORT_DIR_OUT = Data direction out + * PORT_DIR_OFF = Disables the pin + * (low power state) + */ +static inline void PORTE_set_pin_dir(const uint8_t pin, const enum port_dir dir) +{ + switch (dir) { + case PORT_DIR_IN: + VPORTE.DIR &= ~(1 << pin); + break; + case PORT_DIR_OUT: + VPORTE.DIR |= (1 << pin); + break; + case PORT_DIR_OFF: + *((uint8_t *)&PORTE + 0x10 + pin) |= 1 << PORT_PULLUPEN_bp; + break; + default: + break; + } +} + +/** + * \brief Set port level + * + * Sets output level on the pins defined by the bit mask + * + * \param[in] mask Bit mask where 1 means apply port level to the corresponding + * pin + * \param[in] level true = Pin levels set to "high" state + * false = Pin levels set to "low" state + */ +static inline void PORTE_set_port_level(const uint8_t mask, const bool level) +{ + if (level == true) { + VPORTE.OUT |= mask; + } else { + VPORTE.OUT &= ~mask; + } +} + +/** + * \brief Set port level + * + * Sets output level on a pin + * + * \param[in] pin The pin number within port + * \param[in] level true = Pin level set to "high" state + * false = Pin level set to "low" state + */ +static inline void PORTE_set_pin_level(const uint8_t pin, const bool level) +{ + if (level == true) { + VPORTE.OUT |= (1 << pin); + } else { + VPORTE.OUT &= ~(1 << pin); + } +} + +/** + * \brief Toggle out level on pins + * + * Toggle the pin levels on pins defined by bit mask + * + * \param[in] mask Bit mask where 1 means toggle pin level to the corresponding + * pin + */ +static inline void PORTE_toggle_port_level(const uint8_t mask) +{ + PORTE.OUTTGL = mask; +} + +/** + * \brief Toggle output level on pin + * + * Toggle the pin levels on pins defined by bit mask + * + * \param[in] pin The pin number within port + */ +static inline void PORTE_toggle_pin_level(const uint8_t pin) +{ + PORTE.OUTTGL = 1 << pin; +} + +/** + * \brief Get input level on pins + * + * Read the input level on pins connected to a port + * + */ +static inline uint8_t PORTE_get_port_level() +{ + return VPORTE.IN; +} + +/** + * \brief Get level on pin + * + * Reads the level on pins connected to a port + */ +static inline bool PORTE_get_pin_level(const uint8_t pin) +{ + return VPORTE.IN & (1 << pin); +} + +/** + * \brief Write value to Port + * + * Write directly to the port OUT register + * + * \param[in] value Value to write to the port register + */ +static inline void PORTE_write_port(const uint8_t value) +{ + VPORTE.OUT = value; +} +/** + * \brief Set port pin pull mode + * + * Configure pin to pull up, down or disable pull mode, supported pull modes are defined by device used + * + * \param[in] pin The pin number within port + * \param[in] pull_mode Pin pull mode + */ +static inline void PORTF_set_pin_pull_mode(const uint8_t pin, const enum port_pull_mode pull_mode) +{ + volatile uint8_t *port_pin_ctrl = ((uint8_t *)&PORTF + 0x10 + pin); + + if (pull_mode == PORT_PULL_UP) { + *port_pin_ctrl |= PORT_PULLUPEN_bm; + } else if (pull_mode == PORT_PULL_OFF) { + *port_pin_ctrl &= ~PORT_PULLUPEN_bm; + } +} + +/** + * \brief Set port pin inverted mode + * + * Configure pin invert I/O or not + * + * \param[in] pin The pin number within port + * \param[in] inverted Pin inverted mode + */ +static inline void PORTF_pin_set_inverted(const uint8_t pin, const bool inverted) +{ + volatile uint8_t *port_pin_ctrl = ((uint8_t *)&PORTF + 0x10 + pin); + + if (inverted) { + *port_pin_ctrl |= PORT_INVEN_bm; + } else { + *port_pin_ctrl &= ~PORT_INVEN_bm; + } +} + +/** + * \brief Set port pin input/sense configuration + * + * Enable/disable digital input buffer and pin change interrupt, + * select pin interrupt edge/level sensing mode + * + * \param[in] pin pin number within port + * \param[in] isc PORT_ISC_INTDISABLE_gc = Interrupt disabled but input buffer enabled + * PORT_ISC_BOTHEDGES_gc = Sense Both Edges + * PORT_ISC_RISING_gc = Sense Rising Edge + * PORT_ISC_FALLING_gc = Sense Falling Edge + * PORT_ISC_INPUT_DISABLE_gc = Digital Input Buffer disabled + * PORT_ISC_LEVEL_gc = Sense low Level + * + */ +static inline void PORTF_pin_set_isc(const uint8_t pin, const PORT_ISC_t isc) +{ + volatile uint8_t *port_pin_ctrl = ((uint8_t *)&PORTF + 0x10 + pin); + + *port_pin_ctrl = (*port_pin_ctrl & ~PORT_ISC_gm) | isc; +} + +/** + * \brief Set port data direction + * + * Select if the pin data direction is input, output or disabled. + * If disabled state is not possible, this function throws an assert. + * + * \param[in] mask Bit mask where 1 means apply direction setting to the + * corresponding pin + * \param[in] dir PORT_DIR_IN = Data direction in + * PORT_DIR_OUT = Data direction out + * PORT_DIR_OFF = Disables the pin + * (low power state) + */ +static inline void PORTF_set_port_dir(const uint8_t mask, const enum port_dir dir) +{ + switch (dir) { + case PORT_DIR_IN: + VPORTF.DIR &= ~mask; + break; + case PORT_DIR_OUT: + VPORTF.DIR |= mask; + break; + case PORT_DIR_OFF: + /*/ should activate the pullup for power saving + but a bit costly to do it here */ + { + for (uint8_t i = 0; i < 8; i++) { + if (mask & 1 << i) { + *((uint8_t *)&PORTF + 0x10 + i) |= 1 << PORT_PULLUPEN_bp; + } + } + } + break; + default: + break; + } +} + +/** + * \brief Set port pin data direction + * + * Select if the pin data direction is input, output or disabled. + * If disabled state is not possible, this function throws an assert. + * + * \param[in] pin The pin number within port + * \param[in] dir PORT_DIR_IN = Data direction in + * PORT_DIR_OUT = Data direction out + * PORT_DIR_OFF = Disables the pin + * (low power state) + */ +static inline void PORTF_set_pin_dir(const uint8_t pin, const enum port_dir dir) +{ + switch (dir) { + case PORT_DIR_IN: + VPORTF.DIR &= ~(1 << pin); + break; + case PORT_DIR_OUT: + VPORTF.DIR |= (1 << pin); + break; + case PORT_DIR_OFF: + *((uint8_t *)&PORTF + 0x10 + pin) |= 1 << PORT_PULLUPEN_bp; + break; + default: + break; + } +} + +/** + * \brief Set port level + * + * Sets output level on the pins defined by the bit mask + * + * \param[in] mask Bit mask where 1 means apply port level to the corresponding + * pin + * \param[in] level true = Pin levels set to "high" state + * false = Pin levels set to "low" state + */ +static inline void PORTF_set_port_level(const uint8_t mask, const bool level) +{ + if (level == true) { + VPORTF.OUT |= mask; + } else { + VPORTF.OUT &= ~mask; + } +} + +/** + * \brief Set port level + * + * Sets output level on a pin + * + * \param[in] pin The pin number within port + * \param[in] level true = Pin level set to "high" state + * false = Pin level set to "low" state + */ +static inline void PORTF_set_pin_level(const uint8_t pin, const bool level) +{ + if (level == true) { + VPORTF.OUT |= (1 << pin); + } else { + VPORTF.OUT &= ~(1 << pin); + } +} + +/** + * \brief Toggle out level on pins + * + * Toggle the pin levels on pins defined by bit mask + * + * \param[in] mask Bit mask where 1 means toggle pin level to the corresponding + * pin + */ +static inline void PORTF_toggle_port_level(const uint8_t mask) +{ + PORTF.OUTTGL = mask; +} + +/** + * \brief Toggle output level on pin + * + * Toggle the pin levels on pins defined by bit mask + * + * \param[in] pin The pin number within port + */ +static inline void PORTF_toggle_pin_level(const uint8_t pin) +{ + PORTF.OUTTGL = 1 << pin; +} + +/** + * \brief Get input level on pins + * + * Read the input level on pins connected to a port + * + */ +static inline uint8_t PORTF_get_port_level() +{ + return VPORTF.IN; +} + +/** + * \brief Get level on pin + * + * Reads the level on pins connected to a port + */ +static inline bool PORTF_get_pin_level(const uint8_t pin) +{ + return VPORTF.IN & (1 << pin); +} + +/** + * \brief Write value to Port + * + * Write directly to the port OUT register + * + * \param[in] value Value to write to the port register + */ +static inline void PORTF_write_port(const uint8_t value) +{ + VPORTF.OUT = value; +} +/** + * \brief Set port pin pull mode + * + * Configure pin to pull up, down or disable pull mode, supported pull modes are defined by device used + * + * \param[in] pin The pin number within port + * \param[in] pull_mode Pin pull mode + */ +static inline void PORTA_set_pin_pull_mode(const uint8_t pin, const enum port_pull_mode pull_mode) +{ + volatile uint8_t *port_pin_ctrl = ((uint8_t *)&PORTA + 0x10 + pin); + + if (pull_mode == PORT_PULL_UP) { + *port_pin_ctrl |= PORT_PULLUPEN_bm; + } else if (pull_mode == PORT_PULL_OFF) { + *port_pin_ctrl &= ~PORT_PULLUPEN_bm; + } +} + +/** + * \brief Set port pin inverted mode + * + * Configure pin invert I/O or not + * + * \param[in] pin The pin number within port + * \param[in] inverted Pin inverted mode + */ +static inline void PORTA_pin_set_inverted(const uint8_t pin, const bool inverted) +{ + volatile uint8_t *port_pin_ctrl = ((uint8_t *)&PORTA + 0x10 + pin); + + if (inverted) { + *port_pin_ctrl |= PORT_INVEN_bm; + } else { + *port_pin_ctrl &= ~PORT_INVEN_bm; + } +} + +/** + * \brief Set port pin input/sense configuration + * + * Enable/disable digital input buffer and pin change interrupt, + * select pin interrupt edge/level sensing mode + * + * \param[in] pin pin number within port + * \param[in] isc PORT_ISC_INTDISABLE_gc = Interrupt disabled but input buffer enabled + * PORT_ISC_BOTHEDGES_gc = Sense Both Edges + * PORT_ISC_RISING_gc = Sense Rising Edge + * PORT_ISC_FALLING_gc = Sense Falling Edge + * PORT_ISC_INPUT_DISABLE_gc = Digital Input Buffer disabled + * PORT_ISC_LEVEL_gc = Sense low Level + * + */ +static inline void PORTA_pin_set_isc(const uint8_t pin, const PORT_ISC_t isc) +{ + volatile uint8_t *port_pin_ctrl = ((uint8_t *)&PORTA + 0x10 + pin); + + *port_pin_ctrl = (*port_pin_ctrl & ~PORT_ISC_gm) | isc; +} + +/** + * \brief Set port data direction + * + * Select if the pin data direction is input, output or disabled. + * If disabled state is not possible, this function throws an assert. + * + * \param[in] mask Bit mask where 1 means apply direction setting to the + * corresponding pin + * \param[in] dir PORT_DIR_IN = Data direction in + * PORT_DIR_OUT = Data direction out + * PORT_DIR_OFF = Disables the pin + * (low power state) + */ +static inline void PORTA_set_port_dir(const uint8_t mask, const enum port_dir dir) +{ + switch (dir) { + case PORT_DIR_IN: + VPORTA.DIR &= ~mask; + break; + case PORT_DIR_OUT: + VPORTA.DIR |= mask; + break; + case PORT_DIR_OFF: + /*/ should activate the pullup for power saving + but a bit costly to do it here */ + { + for (uint8_t i = 0; i < 8; i++) { + if (mask & 1 << i) { + *((uint8_t *)&PORTA + 0x10 + i) |= 1 << PORT_PULLUPEN_bp; + } + } + } + break; + default: + break; + } +} + +/** + * \brief Set port pin data direction + * + * Select if the pin data direction is input, output or disabled. + * If disabled state is not possible, this function throws an assert. + * + * \param[in] pin The pin number within port + * \param[in] dir PORT_DIR_IN = Data direction in + * PORT_DIR_OUT = Data direction out + * PORT_DIR_OFF = Disables the pin + * (low power state) + */ +static inline void PORTA_set_pin_dir(const uint8_t pin, const enum port_dir dir) +{ + switch (dir) { + case PORT_DIR_IN: + VPORTA.DIR &= ~(1 << pin); + break; + case PORT_DIR_OUT: + VPORTA.DIR |= (1 << pin); + break; + case PORT_DIR_OFF: + *((uint8_t *)&PORTA + 0x10 + pin) |= 1 << PORT_PULLUPEN_bp; + break; + default: + break; + } +} + +/** + * \brief Set port level + * + * Sets output level on the pins defined by the bit mask + * + * \param[in] mask Bit mask where 1 means apply port level to the corresponding + * pin + * \param[in] level true = Pin levels set to "high" state + * false = Pin levels set to "low" state + */ +static inline void PORTA_set_port_level(const uint8_t mask, const bool level) +{ + if (level == true) { + VPORTA.OUT |= mask; + } else { + VPORTA.OUT &= ~mask; + } +} + +/** + * \brief Set port level + * + * Sets output level on a pin + * + * \param[in] pin The pin number within port + * \param[in] level true = Pin level set to "high" state + * false = Pin level set to "low" state + */ +static inline void PORTA_set_pin_level(const uint8_t pin, const bool level) +{ + if (level == true) { + VPORTA.OUT |= (1 << pin); + } else { + VPORTA.OUT &= ~(1 << pin); + } +} + +/** + * \brief Toggle out level on pins + * + * Toggle the pin levels on pins defined by bit mask + * + * \param[in] mask Bit mask where 1 means toggle pin level to the corresponding + * pin + */ +static inline void PORTA_toggle_port_level(const uint8_t mask) +{ + PORTA.OUTTGL = mask; +} + +/** + * \brief Toggle output level on pin + * + * Toggle the pin levels on pins defined by bit mask + * + * \param[in] pin The pin number within port + */ +static inline void PORTA_toggle_pin_level(const uint8_t pin) +{ + PORTA.OUTTGL = 1 << pin; +} + +/** + * \brief Get input level on pins + * + * Read the input level on pins connected to a port + * + */ +static inline uint8_t PORTA_get_port_level() +{ + return VPORTA.IN; +} + +/** + * \brief Get level on pin + * + * Reads the level on pins connected to a port + */ +static inline bool PORTA_get_pin_level(const uint8_t pin) +{ + return VPORTA.IN & (1 << pin); +} + +/** + * \brief Write value to Port + * + * Write directly to the port OUT register + * + * \param[in] value Value to write to the port register + */ +static inline void PORTA_write_port(const uint8_t value) +{ + VPORTA.OUT = value; +} +/** + * \brief Set port pin pull mode + * + * Configure pin to pull up, down or disable pull mode, supported pull modes are defined by device used + * + * \param[in] pin The pin number within port + * \param[in] pull_mode Pin pull mode + */ +static inline void PORTB_set_pin_pull_mode(const uint8_t pin, const enum port_pull_mode pull_mode) +{ + volatile uint8_t *port_pin_ctrl = ((uint8_t *)&PORTB + 0x10 + pin); + + if (pull_mode == PORT_PULL_UP) { + *port_pin_ctrl |= PORT_PULLUPEN_bm; + } else if (pull_mode == PORT_PULL_OFF) { + *port_pin_ctrl &= ~PORT_PULLUPEN_bm; + } +} + +/** + * \brief Set port pin inverted mode + * + * Configure pin invert I/O or not + * + * \param[in] pin The pin number within port + * \param[in] inverted Pin inverted mode + */ +static inline void PORTB_pin_set_inverted(const uint8_t pin, const bool inverted) +{ + volatile uint8_t *port_pin_ctrl = ((uint8_t *)&PORTB + 0x10 + pin); + + if (inverted) { + *port_pin_ctrl |= PORT_INVEN_bm; + } else { + *port_pin_ctrl &= ~PORT_INVEN_bm; + } +} + +/** + * \brief Set port pin input/sense configuration + * + * Enable/disable digital input buffer and pin change interrupt, + * select pin interrupt edge/level sensing mode + * + * \param[in] pin pin number within port + * \param[in] isc PORT_ISC_INTDISABLE_gc = Interrupt disabled but input buffer enabled + * PORT_ISC_BOTHEDGES_gc = Sense Both Edges + * PORT_ISC_RISING_gc = Sense Rising Edge + * PORT_ISC_FALLING_gc = Sense Falling Edge + * PORT_ISC_INPUT_DISABLE_gc = Digital Input Buffer disabled + * PORT_ISC_LEVEL_gc = Sense low Level + * + */ +static inline void PORTB_pin_set_isc(const uint8_t pin, const PORT_ISC_t isc) +{ + volatile uint8_t *port_pin_ctrl = ((uint8_t *)&PORTB + 0x10 + pin); + + *port_pin_ctrl = (*port_pin_ctrl & ~PORT_ISC_gm) | isc; +} + +/** + * \brief Set port data direction + * + * Select if the pin data direction is input, output or disabled. + * If disabled state is not possible, this function throws an assert. + * + * \param[in] mask Bit mask where 1 means apply direction setting to the + * corresponding pin + * \param[in] dir PORT_DIR_IN = Data direction in + * PORT_DIR_OUT = Data direction out + * PORT_DIR_OFF = Disables the pin + * (low power state) + */ +static inline void PORTB_set_port_dir(const uint8_t mask, const enum port_dir dir) +{ + switch (dir) { + case PORT_DIR_IN: + VPORTB.DIR &= ~mask; + break; + case PORT_DIR_OUT: + VPORTB.DIR |= mask; + break; + case PORT_DIR_OFF: + /*/ should activate the pullup for power saving + but a bit costly to do it here */ + { + for (uint8_t i = 0; i < 8; i++) { + if (mask & 1 << i) { + *((uint8_t *)&PORTB + 0x10 + i) |= 1 << PORT_PULLUPEN_bp; + } + } + } + break; + default: + break; + } +} + +/** + * \brief Set port pin data direction + * + * Select if the pin data direction is input, output or disabled. + * If disabled state is not possible, this function throws an assert. + * + * \param[in] pin The pin number within port + * \param[in] dir PORT_DIR_IN = Data direction in + * PORT_DIR_OUT = Data direction out + * PORT_DIR_OFF = Disables the pin + * (low power state) + */ +static inline void PORTB_set_pin_dir(const uint8_t pin, const enum port_dir dir) +{ + switch (dir) { + case PORT_DIR_IN: + VPORTB.DIR &= ~(1 << pin); + break; + case PORT_DIR_OUT: + VPORTB.DIR |= (1 << pin); + break; + case PORT_DIR_OFF: + *((uint8_t *)&PORTB + 0x10 + pin) |= 1 << PORT_PULLUPEN_bp; + break; + default: + break; + } +} + +/** + * \brief Set port level + * + * Sets output level on the pins defined by the bit mask + * + * \param[in] mask Bit mask where 1 means apply port level to the corresponding + * pin + * \param[in] level true = Pin levels set to "high" state + * false = Pin levels set to "low" state + */ +static inline void PORTB_set_port_level(const uint8_t mask, const bool level) +{ + if (level == true) { + VPORTB.OUT |= mask; + } else { + VPORTB.OUT &= ~mask; + } +} + +/** + * \brief Set port level + * + * Sets output level on a pin + * + * \param[in] pin The pin number within port + * \param[in] level true = Pin level set to "high" state + * false = Pin level set to "low" state + */ +static inline void PORTB_set_pin_level(const uint8_t pin, const bool level) +{ + if (level == true) { + VPORTB.OUT |= (1 << pin); + } else { + VPORTB.OUT &= ~(1 << pin); + } +} + +/** + * \brief Toggle out level on pins + * + * Toggle the pin levels on pins defined by bit mask + * + * \param[in] mask Bit mask where 1 means toggle pin level to the corresponding + * pin + */ +static inline void PORTB_toggle_port_level(const uint8_t mask) +{ + PORTB.OUTTGL = mask; +} + +/** + * \brief Toggle output level on pin + * + * Toggle the pin levels on pins defined by bit mask + * + * \param[in] pin The pin number within port + */ +static inline void PORTB_toggle_pin_level(const uint8_t pin) +{ + PORTB.OUTTGL = 1 << pin; +} + +/** + * \brief Get input level on pins + * + * Read the input level on pins connected to a port + * + */ +static inline uint8_t PORTB_get_port_level() +{ + return VPORTB.IN; +} + +/** + * \brief Get level on pin + * + * Reads the level on pins connected to a port + */ +static inline bool PORTB_get_pin_level(const uint8_t pin) +{ + return VPORTB.IN & (1 << pin); +} + +/** + * \brief Write value to Port + * + * Write directly to the port OUT register + * + * \param[in] value Value to write to the port register + */ +static inline void PORTB_write_port(const uint8_t value) +{ + VPORTB.OUT = value; +} +/** + * \brief Set port pin pull mode + * + * Configure pin to pull up, down or disable pull mode, supported pull modes are defined by device used + * + * \param[in] pin The pin number within port + * \param[in] pull_mode Pin pull mode + */ +static inline void PORTC_set_pin_pull_mode(const uint8_t pin, const enum port_pull_mode pull_mode) +{ + volatile uint8_t *port_pin_ctrl = ((uint8_t *)&PORTC + 0x10 + pin); + + if (pull_mode == PORT_PULL_UP) { + *port_pin_ctrl |= PORT_PULLUPEN_bm; + } else if (pull_mode == PORT_PULL_OFF) { + *port_pin_ctrl &= ~PORT_PULLUPEN_bm; + } +} + +/** + * \brief Set port pin inverted mode + * + * Configure pin invert I/O or not + * + * \param[in] pin The pin number within port + * \param[in] inverted Pin inverted mode + */ +static inline void PORTC_pin_set_inverted(const uint8_t pin, const bool inverted) +{ + volatile uint8_t *port_pin_ctrl = ((uint8_t *)&PORTC + 0x10 + pin); + + if (inverted) { + *port_pin_ctrl |= PORT_INVEN_bm; + } else { + *port_pin_ctrl &= ~PORT_INVEN_bm; + } +} + +/** + * \brief Set port pin input/sense configuration + * + * Enable/disable digital input buffer and pin change interrupt, + * select pin interrupt edge/level sensing mode + * + * \param[in] pin pin number within port + * \param[in] isc PORT_ISC_INTDISABLE_gc = Interrupt disabled but input buffer enabled + * PORT_ISC_BOTHEDGES_gc = Sense Both Edges + * PORT_ISC_RISING_gc = Sense Rising Edge + * PORT_ISC_FALLING_gc = Sense Falling Edge + * PORT_ISC_INPUT_DISABLE_gc = Digital Input Buffer disabled + * PORT_ISC_LEVEL_gc = Sense low Level + * + */ +static inline void PORTC_pin_set_isc(const uint8_t pin, const PORT_ISC_t isc) +{ + volatile uint8_t *port_pin_ctrl = ((uint8_t *)&PORTC + 0x10 + pin); + + *port_pin_ctrl = (*port_pin_ctrl & ~PORT_ISC_gm) | isc; +} + +/** + * \brief Set port data direction + * + * Select if the pin data direction is input, output or disabled. + * If disabled state is not possible, this function throws an assert. + * + * \param[in] mask Bit mask where 1 means apply direction setting to the + * corresponding pin + * \param[in] dir PORT_DIR_IN = Data direction in + * PORT_DIR_OUT = Data direction out + * PORT_DIR_OFF = Disables the pin + * (low power state) + */ +static inline void PORTC_set_port_dir(const uint8_t mask, const enum port_dir dir) +{ + switch (dir) { + case PORT_DIR_IN: + VPORTC.DIR &= ~mask; + break; + case PORT_DIR_OUT: + VPORTC.DIR |= mask; + break; + case PORT_DIR_OFF: + /*/ should activate the pullup for power saving + but a bit costly to do it here */ + { + for (uint8_t i = 0; i < 8; i++) { + if (mask & 1 << i) { + *((uint8_t *)&PORTC + 0x10 + i) |= 1 << PORT_PULLUPEN_bp; + } + } + } + break; + default: + break; + } +} + +/** + * \brief Set port pin data direction + * + * Select if the pin data direction is input, output or disabled. + * If disabled state is not possible, this function throws an assert. + * + * \param[in] pin The pin number within port + * \param[in] dir PORT_DIR_IN = Data direction in + * PORT_DIR_OUT = Data direction out + * PORT_DIR_OFF = Disables the pin + * (low power state) + */ +static inline void PORTC_set_pin_dir(const uint8_t pin, const enum port_dir dir) +{ + switch (dir) { + case PORT_DIR_IN: + VPORTC.DIR &= ~(1 << pin); + break; + case PORT_DIR_OUT: + VPORTC.DIR |= (1 << pin); + break; + case PORT_DIR_OFF: + *((uint8_t *)&PORTC + 0x10 + pin) |= 1 << PORT_PULLUPEN_bp; + break; + default: + break; + } +} + +/** + * \brief Set port level + * + * Sets output level on the pins defined by the bit mask + * + * \param[in] mask Bit mask where 1 means apply port level to the corresponding + * pin + * \param[in] level true = Pin levels set to "high" state + * false = Pin levels set to "low" state + */ +static inline void PORTC_set_port_level(const uint8_t mask, const bool level) +{ + if (level == true) { + VPORTC.OUT |= mask; + } else { + VPORTC.OUT &= ~mask; + } +} + +/** + * \brief Set port level + * + * Sets output level on a pin + * + * \param[in] pin The pin number within port + * \param[in] level true = Pin level set to "high" state + * false = Pin level set to "low" state + */ +static inline void PORTC_set_pin_level(const uint8_t pin, const bool level) +{ + if (level == true) { + VPORTC.OUT |= (1 << pin); + } else { + VPORTC.OUT &= ~(1 << pin); + } +} + +/** + * \brief Toggle out level on pins + * + * Toggle the pin levels on pins defined by bit mask + * + * \param[in] mask Bit mask where 1 means toggle pin level to the corresponding + * pin + */ +static inline void PORTC_toggle_port_level(const uint8_t mask) +{ + PORTC.OUTTGL = mask; +} + +/** + * \brief Toggle output level on pin + * + * Toggle the pin levels on pins defined by bit mask + * + * \param[in] pin The pin number within port + */ +static inline void PORTC_toggle_pin_level(const uint8_t pin) +{ + PORTC.OUTTGL = 1 << pin; +} + +/** + * \brief Get input level on pins + * + * Read the input level on pins connected to a port + * + */ +static inline uint8_t PORTC_get_port_level() +{ + return VPORTC.IN; +} + +/** + * \brief Get level on pin + * + * Reads the level on pins connected to a port + */ +static inline bool PORTC_get_pin_level(const uint8_t pin) +{ + return VPORTC.IN & (1 << pin); +} + +/** + * \brief Write value to Port + * + * Write directly to the port OUT register + * + * \param[in] value Value to write to the port register + */ +static inline void PORTC_write_port(const uint8_t value) +{ + VPORTC.OUT = value; +} +/** + * \brief Set port pin pull mode + * + * Configure pin to pull up, down or disable pull mode, supported pull modes are defined by device used + * + * \param[in] pin The pin number within port + * \param[in] pull_mode Pin pull mode + */ +static inline void PORTD_set_pin_pull_mode(const uint8_t pin, const enum port_pull_mode pull_mode) +{ + volatile uint8_t *port_pin_ctrl = ((uint8_t *)&PORTD + 0x10 + pin); + + if (pull_mode == PORT_PULL_UP) { + *port_pin_ctrl |= PORT_PULLUPEN_bm; + } else if (pull_mode == PORT_PULL_OFF) { + *port_pin_ctrl &= ~PORT_PULLUPEN_bm; + } +} + +/** + * \brief Set port pin inverted mode + * + * Configure pin invert I/O or not + * + * \param[in] pin The pin number within port + * \param[in] inverted Pin inverted mode + */ +static inline void PORTD_pin_set_inverted(const uint8_t pin, const bool inverted) +{ + volatile uint8_t *port_pin_ctrl = ((uint8_t *)&PORTD + 0x10 + pin); + + if (inverted) { + *port_pin_ctrl |= PORT_INVEN_bm; + } else { + *port_pin_ctrl &= ~PORT_INVEN_bm; + } +} + +/** + * \brief Set port pin input/sense configuration + * + * Enable/disable digital input buffer and pin change interrupt, + * select pin interrupt edge/level sensing mode + * + * \param[in] pin pin number within port + * \param[in] isc PORT_ISC_INTDISABLE_gc = Interrupt disabled but input buffer enabled + * PORT_ISC_BOTHEDGES_gc = Sense Both Edges + * PORT_ISC_RISING_gc = Sense Rising Edge + * PORT_ISC_FALLING_gc = Sense Falling Edge + * PORT_ISC_INPUT_DISABLE_gc = Digital Input Buffer disabled + * PORT_ISC_LEVEL_gc = Sense low Level + * + */ +static inline void PORTD_pin_set_isc(const uint8_t pin, const PORT_ISC_t isc) +{ + volatile uint8_t *port_pin_ctrl = ((uint8_t *)&PORTD + 0x10 + pin); + + *port_pin_ctrl = (*port_pin_ctrl & ~PORT_ISC_gm) | isc; +} + +/** + * \brief Set port data direction + * + * Select if the pin data direction is input, output or disabled. + * If disabled state is not possible, this function throws an assert. + * + * \param[in] mask Bit mask where 1 means apply direction setting to the + * corresponding pin + * \param[in] dir PORT_DIR_IN = Data direction in + * PORT_DIR_OUT = Data direction out + * PORT_DIR_OFF = Disables the pin + * (low power state) + */ +static inline void PORTD_set_port_dir(const uint8_t mask, const enum port_dir dir) +{ + switch (dir) { + case PORT_DIR_IN: + VPORTD.DIR &= ~mask; + break; + case PORT_DIR_OUT: + VPORTD.DIR |= mask; + break; + case PORT_DIR_OFF: + /*/ should activate the pullup for power saving + but a bit costly to do it here */ + { + for (uint8_t i = 0; i < 8; i++) { + if (mask & 1 << i) { + *((uint8_t *)&PORTD + 0x10 + i) |= 1 << PORT_PULLUPEN_bp; + } + } + } + break; + default: + break; + } +} + +/** + * \brief Set port pin data direction + * + * Select if the pin data direction is input, output or disabled. + * If disabled state is not possible, this function throws an assert. + * + * \param[in] pin The pin number within port + * \param[in] dir PORT_DIR_IN = Data direction in + * PORT_DIR_OUT = Data direction out + * PORT_DIR_OFF = Disables the pin + * (low power state) + */ +static inline void PORTD_set_pin_dir(const uint8_t pin, const enum port_dir dir) +{ + switch (dir) { + case PORT_DIR_IN: + VPORTD.DIR &= ~(1 << pin); + break; + case PORT_DIR_OUT: + VPORTD.DIR |= (1 << pin); + break; + case PORT_DIR_OFF: + *((uint8_t *)&PORTD + 0x10 + pin) |= 1 << PORT_PULLUPEN_bp; + break; + default: + break; + } +} + +/** + * \brief Set port level + * + * Sets output level on the pins defined by the bit mask + * + * \param[in] mask Bit mask where 1 means apply port level to the corresponding + * pin + * \param[in] level true = Pin levels set to "high" state + * false = Pin levels set to "low" state + */ +static inline void PORTD_set_port_level(const uint8_t mask, const bool level) +{ + if (level == true) { + VPORTD.OUT |= mask; + } else { + VPORTD.OUT &= ~mask; + } +} + +/** + * \brief Set port level + * + * Sets output level on a pin + * + * \param[in] pin The pin number within port + * \param[in] level true = Pin level set to "high" state + * false = Pin level set to "low" state + */ +static inline void PORTD_set_pin_level(const uint8_t pin, const bool level) +{ + if (level == true) { + VPORTD.OUT |= (1 << pin); + } else { + VPORTD.OUT &= ~(1 << pin); + } +} + +/** + * \brief Toggle out level on pins + * + * Toggle the pin levels on pins defined by bit mask + * + * \param[in] mask Bit mask where 1 means toggle pin level to the corresponding + * pin + */ +static inline void PORTD_toggle_port_level(const uint8_t mask) +{ + PORTD.OUTTGL = mask; +} + +/** + * \brief Toggle output level on pin + * + * Toggle the pin levels on pins defined by bit mask + * + * \param[in] pin The pin number within port + */ +static inline void PORTD_toggle_pin_level(const uint8_t pin) +{ + PORTD.OUTTGL = 1 << pin; +} + +/** + * \brief Get input level on pins + * + * Read the input level on pins connected to a port + * + */ +static inline uint8_t PORTD_get_port_level() +{ + return VPORTD.IN; +} + +/** + * \brief Get level on pin + * + * Reads the level on pins connected to a port + */ +static inline bool PORTD_get_pin_level(const uint8_t pin) +{ + return VPORTD.IN & (1 << pin); +} + +/** + * \brief Write value to Port + * + * Write directly to the port OUT register + * + * \param[in] value Value to write to the port register + */ +static inline void PORTD_write_port(const uint8_t value) +{ + VPORTD.OUT = value; +} +#ifdef __cplusplus +} +#endif + +#endif /* PORT_INCLUDED */ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/include/protected_io.h b/AVRIoT.X/mcc_generated_files/include/protected_io.h new file mode 100644 index 0000000..891631c --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/include/protected_io.h @@ -0,0 +1,85 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +/** + * \defgroup doc_driver_system_protected_io Protected IO + * \ingroup doc_driver_system + * + * \section doc_driver_protected_io_rev Revision History + * - v0.0.0.1 Initial Commit + * + *@{ + */ + +#ifndef PROTECTED_IO_H +#define PROTECTED_IO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__DOXYGEN__) +//! \name IAR Memory Model defines. +//@{ + +/** + * \def CONFIG_MEMORY_MODEL_TINY + * \brief Configuration symbol to enable 8 bit pointers. + * + */ +#define CONFIG_MEMORY_MODEL_TINY + +/** + * \def CONFIG_MEMORY_MODEL_SMALL + * \brief Configuration symbol to enable 16 bit pointers. + * \note If no memory model is defined, SMALL is default. + * + */ +#define CONFIG_MEMORY_MODEL_SMALL + +/** + * \def CONFIG_MEMORY_MODEL_LARGE + * \brief Configuration symbol to enable 24 bit pointers. + * + */ +#define CONFIG_MEMORY_MODEL_LARGE + +//@} +#endif + +/** + * \brief Write to am 8-bit I/O register protected by CCP or a protection bit + * + * \param addr Address of the I/O register + * \param magic CCP magic value or Mask for protection bit + * \param value Value to be written + * + * \note Using IAR Embedded workbench, the choice of memory model has an impact + * on calling convention. The memory model is not visible to the + * preprocessor, so it must be defined in the Assembler preprocessor directives. + */ +extern void protected_write_io(void *addr, uint8_t magic, uint8_t value); + +/** @} */ + +#endif /* PROTECTED_IO_H */ diff --git a/AVRIoT.X/mcc_generated_files/include/rstctrl.h b/AVRIoT.X/mcc_generated_files/include/rstctrl.h new file mode 100644 index 0000000..66e805f --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/include/rstctrl.h @@ -0,0 +1,54 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef RSTCTRL_INCLUDED +#define RSTCTRL_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ccp.h" + +static inline void RSTCTRL_reset(void) +{ + /* SWRR is protected with CCP */ +// ccp_write_io((void *)&RSTCTRL.SWRR, 0x1); +} + +static inline uint8_t RSTCTRL_get_reset_cause(void) +{ + return RSTCTRL.RSTFR; +} + +static inline void RSTCTRL_clear_reset_cause(void) +{ + RSTCTRL.RSTFR + = RSTCTRL_UPDIRF_bm | RSTCTRL_SWRF_bm | RSTCTRL_WDRF_bm | RSTCTRL_EXTRF_bm | RSTCTRL_BORF_bm | RSTCTRL_PORF_bm; +} + +#ifdef __cplusplus +} +#endif + +#endif /* RSTCTRL_INCLUDED */ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/include/rtc.h b/AVRIoT.X/mcc_generated_files/include/rtc.h new file mode 100644 index 0000000..1911d2d --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/include/rtc.h @@ -0,0 +1,53 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef RTCDRIVER_H +#define RTCDRIVER_H + +#include "../utils/compiler.h" +#include +#include + +/** Datatype used to hold the number of ticks until a timer expires */ + +typedef void (*RTC_cb_t)(void); +void RTC_SetOVFIsrCallback(RTC_cb_t cb); +void RTC_SetCMPIsrCallback(RTC_cb_t cb); +int8_t RTC_Initialize(); +void RTC_WriteCounter(uint16_t timerVal); +void RTC_WritePeroid(uint16_t timerVal); +uint16_t RTC_ReadCounter(); +uint16_t RTC_ReadPeriod(); +void RTC_EnableCMPInterrupt(); +void RTC_DisableCMPInterrupt(); +void RTC_EnableOVFInterrupt(); +void RTC_DisableOVFInterrupt(); +void RTC_EnablePITInterrupt(); +void RTC_DisablePITInterrupt(); +void RTC_ClearOVFInterruptFlag(); +bool RTC_IsOVFInterruptEnabled(); + + +#endif /* RTCDRIVER_H */ + +/** @}*/ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/include/spi0.h b/AVRIoT.X/mcc_generated_files/include/spi0.h new file mode 100644 index 0000000..b476aaf --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/include/spi0.h @@ -0,0 +1,228 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef SPI_BASIC_H_INCLUDED +#define SPI_BASIC_H_INCLUDED + +#include "../utils/compiler.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Function pointer to callback function called by SPI IRQ. + NULL=default value: No callback function is to be used. +*/ +typedef void (*spi0_TRANSFER_DONE_CB)(void); + +typedef struct { + // hardware stuff that controls SPI mode + // hardware stuff that controls SPI baud rate + uint8_t CTRLAvalue; + uint8_t CTRLBvalue; +} spi0_configuration_t; + +/** Specify whether the SPI transfer is to be uni- or bidirectional. + A bidirectional transfer (=SPI_EXCHANGE) causes the received data + to overwrite the buffer with the data to transmit. +*/ +typedef enum spi_transfer_type { + SPI_EXCHANGE, ///< SPI transfer is bidirectional + SPI_READ, ///< SPI transfer reads, writes only 0s + SPI_WRITE ///< SPI transfer writes, discards read data +} spi0_transfer_type_t; + +/** Status of the SPI hardware and SPI bus.*/ +typedef enum spi_transfer_status { + SPI_FREE, ///< SPI hardware is not open, bus is free. + SPI_IDLE, ///< SPI hardware has been opened, no transfer ongoing. + SPI_BUSY, ///< SPI hardware has been opened, transfer ongoing. + SPI_DONE ///< SPI hardware has been opened, transfer complete. +} spi0_transfer_status_t; + +/** Enumeration of the different configurations supported by the driver. + A configuration is specified as parameter to SPI0_open(), + and is used by the function to set SPI parameters as specified by the + configuration. A user may specify a configuration, e.g. SLAVE_A, used when + communication over SPI with SLAVE_A, and another configuration, SLAVE_B, + used when communication with SLAVE_B. The configurations may use different + SPI configuration such as polarity or SCK frequency. +*/ +typedef enum { + WINC_CONFIG, + SPI0_DEFAULT +} SPI0_configuration_name_t; + +/** + * \brief Initialize SPI interface + * If module is configured to disabled state, the clock to the SPI is disabled + * if this is supported by the device's clock system. + * + * \return Initialization status. + * \retval 0 the SPI init was successful + * \retval 1 the SPI init was not successful + */ +uint8_t SPI0_Initialize(void); + +/** + * \brief Enable SPI0 + * 1. If supported by the clock system, enables the clock to the SPI + * 2. Enables the SPI module by setting the enable-bit in the SPI control register + * + * \return Nothing + */ +void SPI0_Enable(); + +/** + * \brief Disable SPI0 + * 1. Disables the SPI module by clearing the enable-bit in the SPI control register + * 2. If supported by the clock system, disables the clock to the SPI + * + * \return Nothing + */ +void SPI0_Disable(); + +/** + * \brief Open the SPI SPI0 for communication + * + * \param[in] spiUniqueconfiguration The configuration to use in the transfer + * + * \return Initialization status. + * \retval false The SPI open was successful + * \retval true The SPI open was successful + */ +bool SPI0_Open(spi0_configuration_t spiUniqueConfiguration); + +/** + * \brief Sets the index of Configuration to use in the transfer + * + * \param[in] spiUniqueconfiguration The configuration index + * + * \return Setting status. + */ + +bool SPI0_OpenConfiguration(uint8_t spiUniqueConfiguration); + + +/** + * \brief Close the SPI SPI0 for communication + * + * \return Nothing + */ +void SPI0_Close(void); + +/** + * \brief Exchange one byte over SPI SPI0. Blocks until done. + * + * \param[in] data The byte to transfer + * + * \return Received data byte. + */ +uint8_t SPI0_ExchangeByte(uint8_t data); + +/** + * \brief Exchange a buffer over SPI SPI0. Blocks if using polled driver. + * + * \param[inout] block The buffer to transfer. Received data is returned here. + * \param[in] size The size of buffer to transfer + * + * \return Nothing. + */ +void SPI0_ExchangeBlock(void *block, size_t size); + +/** + * \brief Write a buffer over SPI SPI0. Blocks if using polled driver. + * + * \param[in] block The buffer to transfer + * \param[in] size The size of buffer to transfer + * + * \return Nothing. + */ +void SPI0_WriteBlock(void *block, size_t size); + +/** + * \brief Read a buffer over SPI SPI0. Blocks if using polled driver. + * + * Zeros are transmitted out of the SPI. + * + * \param[out] block Received data is written here. + * \param[in] size The size of buffer to transfer + * + * \return Nothing. + */ +void SPI0_ReadBlock(void *block, size_t size); + +/** + * \brief Write a buffer over SPI SPI0. Blocks if using polled driver. + * + * \param[in] data The byte to transfer + * + * \return Nothing. + */ +void SPI0_WriteByte(uint8_t data); + +/** + * \brief Read a buffer over SPI SPI0. Blocks if using polled driver. + * + * \return The received data. + */ +uint8_t SPI0_ReadByte(); + +/** + * \brief Check if SPI slave is selected, i.e. its SS has been asserted. + * + * \return SPI SS status + * \retval true SPI is selected + * \retval false SPI is not selected + */ +bool SPI0_Selected(void); + +/** + * \brief Get received data byte from SPI + * + * \return Received data byte + */ +uint8_t SPI0_GetRxData(void); + +/** + * \brief Write data byte to SPI + * + * \param[in] data The data to transfer + * + * \return Nothing + */ +void SPI0_WriteTxData(uint8_t data); + +/** + * \brief Wait until SPI has recaived a data byte + * + * \return Nothing + */ +void SPI0_WaitDataready(void); + +#ifdef __cplusplus +} +#endif + +#endif /* SPI_BASIC_H_INCLUDED */ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/include/twi0_master.h b/AVRIoT.X/mcc_generated_files/include/twi0_master.h new file mode 100644 index 0000000..8d02c73 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/include/twi0_master.h @@ -0,0 +1,210 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef TWI0_MASTER_H +#define TWI0_MASTER_H + +#include +#include +#include +#include "../utils/compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TWI0_BAUD(F_SCL, T_RISE) \ + ((((((float)10000000 / (float)F_SCL)) - 10 - ((float)10000000 * T_RISE / 1000000))) / 2) + + +typedef enum { + I2C_NOERR, // The message was sent. + I2C_BUSY, // Message was NOT sent, bus was busy. + I2C_FAIL // Message was NOT sent, bus failure + // If you are interested in the failure reason, + // Sit on the event call-backs. +} twi0_error_t; + +typedef enum { I2C_STOP = 1, I2C_RESTART_READ, I2C_RESTART_WRITE, I2C_CONTINUE, I2C_RESET_LINK } twi0_operations_t; + +typedef twi0_operations_t (*twi0_callback_t)(void *funPtr); + +typedef uint8_t twi0_address_t; +typedef twi0_address_t i2c_address_t; +// common callback responses +twi0_operations_t I2C0_SetReturnStopCallback(void *funPtr); +twi0_operations_t I2C0_SetReturnResetCallback(void *funPtr); +twi0_operations_t I2C0_SetRestartWriteCallback(void *funPtr); +twi0_operations_t I2C0_SetRestartReadCallback(void *funPtr); + +/** + * \brief Initialize I2C interface + * If module is configured to disabled state, the clock to the I2C is disabled + * if this is supported by the device's clock system. + * + * \return Initialization status. + * \retval 0 the init was successful + * \retval 1 the init was not successful + */ +uint8_t I2C0_Initialize(void); + +/** + * \brief Open the I2C for communication + * + * \param[in] address The slave address to use in the transfer + * + * \return Initialization status. + * \retval I2C_NOERR The I2C open was successful + * \retval I2C_BUSY The I2C open failed because the interface is busy + * \retval I2C_FAIL The I2C open failed with an error + */ +twi0_error_t I2C0_Open(twi0_address_t address); + +/** + * \brief Close the I2C interface + * + * \return Status of close operation. + * \retval I2C_NOERR The I2C open was successful + * \retval I2C_BUSY The I2C open failed because the interface is busy + * \retval I2C_FAIL The I2C open failed with an error + */ +twi0_error_t I2C0_Close(void); + +/** + * \brief Start an operation on an opened I2C interface + * + * \param[in] read Set to true for read, false for write + * + * \return Status of operation + * \retval I2C_NOERR The I2C open was successful + * \retval I2C_BUSY The I2C open failed because the interface is busy + * \retval I2C_FAIL The I2C open failed with an error + */ +twi0_error_t I2C0_MasterOperation(bool read); + +/** + * \brief Identical to I2C0_MasterOperation(false); + */ + +twi0_error_t I2C0_MasterWrite(void); // to be depreciated + + +/** + * \brief Identical to I2C0_MasterOperation(true); + */ + + +twi0_error_t I2C0_MasterRead(void); // to be depreciated + +/** + * \brief Set timeout to be used for I2C operations. Uses the Timeout driver. + * + * \param[in] to Timeout in ticks + * + * \return Nothing + */ +void I2C0_SetTimeout(uint8_t to); + +/** + * \brief Sets up the data buffer to use, and number of bytes to transfer + * + * \param[in] buffer Pointer to data buffer to use for read or write data + * \param[in] bufferSize Number of bytes to read or write from slave + * + * \return Nothing + */ +void I2C0_SetBuffer(void *buffer, size_t bufferSize); + +// Event Callback functions. + +/** + * \brief Set callback to be called when all specifed data has been transferred. + * + * \param[in] cb Pointer to callback function + * \param[in] p Pointer to the callback function's parameters + * + * \return Nothing + */ +void I2C0_SetDataCompleteCallback(twi0_callback_t cb, void *funPtr); + +/** + * \brief Set callback to be called when there has been a bus collision and arbitration was lost. + * + * \param[in] cb Pointer to callback function + * \param[in] p Pointer to the callback function's parameters + * + * \return Nothing + */ +void I2C0_SetWriteCollisionCallback(twi0_callback_t cb, void *funPtr); + +/** + * \brief Set callback to be called when the transmitted address was NACK'ed. + * + * \param[in] cb Pointer to callback function + * \param[in] p Pointer to the callback function's parameters + * + * \return Nothing + */ +void I2C0_SetAddressNackCallback(twi0_callback_t cb, void *funPtr); + +/** + * \brief Set callback to be called when the transmitted data was NACK'ed. + * + * \param[in] cb Pointer to callback function + * \param[in] p Pointer to the callback function's parameters + * + * \return Nothing + */ +void I2C0_SetDataNackCallback(twi0_callback_t cb, void *funPtr); + +/** + * \brief Set callback to be called when there was a bus timeout. + * + * \param[in] cb Pointer to callback function + * \param[in] p Pointer to the callback function's parameters + * + * \return Nothing + */ +void I2C0_SetTimeoutCallback(twi0_callback_t cb, void *funPtr); + +/** + * \brief In a polled implementation, call this function in a loop to execute the FSM + * + * \return Nothing + */ +void I2C0_Poller(void); + +/** + * \brief Set Address to be called when there was aa address reception. + * + * \param[in] address Loads the address of the master + * + * \return Nothing + */ +void I2C0_SetAddress(twi0_address_t address); + +#ifdef __cplusplus +} +#endif + +#endif /* TWI0_MASTER_H */ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/include/usart2.h b/AVRIoT.X/mcc_generated_files/include/usart2.h new file mode 100644 index 0000000..86eefe2 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/include/usart2.h @@ -0,0 +1,178 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef USART2_H_INCLUDED +#define USART2_H_INCLUDED + +#include +#include +#include "../utils/compiler.h" +#include "../utils/atomic.h" +#include "../config/clock_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Normal Mode, Baud register value */ +#define USART2_BAUD_RATE(BAUD_RATE) (((float)10000000 * 64 / (16 * (float)BAUD_RATE)) + 0.5) + +/* USART2 Ringbuffer */ + +#define USART2_RX_BUFFER_SIZE 64 +#define USART2_TX_BUFFER_SIZE 64 +#define USART2_RX_BUFFER_MASK (USART2_RX_BUFFER_SIZE - 1) +#define USART2_TX_BUFFER_MASK (USART2_TX_BUFFER_SIZE - 1) + +typedef enum { USART2_RX_CB = 1, USART2_TX_CB } usart2_cb_t; +typedef void (*usart_callback)(void); + +/** + * \brief Initialize USART interface + * If module is configured to disabled state, the clock to the USART is disabled + * if this is supported by the device's clock system. + * + * \return Initialization status. + * \retval 0 the USART init was successful + * \retval 1 the USART init was not successful + */ +void USART2_Initialize(); + +/** + * \brief Enable RX and TX in USART2 + * 1. If supported by the clock system, enables the clock to the USART + * 2. Enables the USART module by setting the RX and TX enable-bits in the USART control register + * + * \return Nothing + */ +void USART2_Enable(); + +/** + * \brief Enable RX in USART2 + * 1. If supported by the clock system, enables the clock to the USART + * 2. Enables the USART module by setting the RX enable-bit in the USART control register + * + * \return Nothing + */ +void USART2_EnableRx(); + +/** + * \brief Enable TX in USART2 + * 1. If supported by the clock system, enables the clock to the USART + * 2. Enables the USART module by setting the TX enable-bit in the USART control register + * + * \return Nothing + */ +void USART2_EnableTx(); + +/** + * \brief Disable USART2 + * 1. Disables the USART module by clearing the enable-bit(s) in the USART control register + * 2. If supported by the clock system, disables the clock to the USART + * + * \return Nothing + */ +void USART2_Disable(); + +/** + * \brief Get recieved data from USART2 + * + * \return Data register from USART2 module + */ +uint8_t USART2_GetData(); + +/** + * \brief Check if the usart can accept data to be transmitted + * + * \return The status of USART TX data ready check + * \retval false The USART can not receive data to be transmitted + * \retval true The USART can receive data to be transmitted + */ +bool USART2_IsTxReady(); + +/** + * \brief Check if the USART has received data + * + * \return The status of USART RX data ready check + * \retval true The USART has received data + * \retval false The USART has not received data + */ +bool USART2_IsRxReady(); + +/** + * \brief Check if USART2 data is transmitted + * + * \return Receiver ready status + * \retval true Data is not completely shifted out of the shift register + * \retval false Data completely shifted out if the USART shift register + */ +bool USART2_IsTxBusy(); + + + +bool USART2_IsTxDone(); +/** + * \brief Read one character from USART2 + * + * Function will block if a character is not available. + * + * \return Data read from the USART2 module + */ +uint8_t USART2_Read(void); + +/** + * \brief Write one character to USART2 + * + * Function will block until a character can be accepted. + * + * \param[in] data The character to write to the USART + * + * \return Nothing + */ +void USART2_Write(const uint8_t data); + +/** + * \brief Set call back function for USART2 + * + * \param[in] cb The call back function to set + * + * \param[in] type The type of ISR to be set + * + * \return Nothing + */ + +void USART2_DefaultRxIsrCb(void); + +void USART2_DefaultTxIsrCb(void); + +void USART2_SetISRCb(usart_callback cb, usart2_cb_t type); + +void USART2_SetRXISRCb(usart_callback cb); + +void USART2_SetTXISRCb(usart_callback cb); + +#ifdef __cplusplus +} +#endif + +#endif /* USART2_H_INCLUDED */ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/led.c b/AVRIoT.X/mcc_generated_files/led.c new file mode 100644 index 0000000..b3ee716 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/led.c @@ -0,0 +1,341 @@ +/* + \file led.c + + \brief Manage board LED's + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include +#include "mcc.h" +#include "config/clock_config.h" +#include +#include "led.h" +#include "drivers/timeout.h" +#include "config/mqtt_config.h" + +#define LED_ON false +#define LED_OFF true +#define LEDS_TEST_INTERVAL 50L +#define LED_SERVICE_INTERVAL 250L + +static ledTickState_t redLed_2SecLoop; +static ledTickState_t yellowLed_2SecLoop; +static ledTickState_t greenLed_2SecLoop; +static ledTickState_t blueLed_2SecLoop; + +static uint8_t redTicker = 0; +static uint8_t yellowTicker = 0; +static uint8_t greenTicker = 0; +static uint8_t blueTicker = 0; + +static uint32_t LED_service(void *payload); +static timerstruct_t LED_service_timer = {LED_service}; + + + +void LED_modeRed(ledTickState_t configLed_2SecLoop) +{ + redLed_2SecLoop.Full2Sec = configLed_2SecLoop.Full2Sec; + redTicker = 0; + } + +void LED_modeBlue(ledTickState_t configLed_2SecLoop) +{ + blueLed_2SecLoop.Full2Sec = configLed_2SecLoop.Full2Sec; + blueTicker = 0; +} + +void LED_modeGreen(ledTickState_t configLed_2SecLoop) +{ + greenLed_2SecLoop.Full2Sec = configLed_2SecLoop.Full2Sec; + greenTicker = 0; +} + +void LED_modeYellow(ledTickState_t configLed_2SecLoop) +{ + yellowLed_2SecLoop.Full2Sec = configLed_2SecLoop.Full2Sec; + yellowTicker = 0; +} + +static void LED_redService(void) +{ + static bool ledStatus = LED_OFF; + switch(redTicker) + { + case 0: + ledStatus = redLed_2SecLoop.tick0; + break; + case 1: + ledStatus = redLed_2SecLoop.tick1; + break; + case 2: + ledStatus = redLed_2SecLoop.tick2; + break; + case 3: + ledStatus = redLed_2SecLoop.tick3; + break; + case 4: + ledStatus = redLed_2SecLoop.tick4; + break; + case 5: + ledStatus = redLed_2SecLoop.tick5; + break; + case 6: + ledStatus = redLed_2SecLoop.tick6; + break; + case 7: + ledStatus = redLed_2SecLoop.tick7; + break; + default: + // This should never be true + break; +} + + // Manage LED State + if (ledStatus == LED_ON) +{ + LED_RED_SetLow(); +} + else + { + LED_RED_SetHigh(); + } + + // Reset Ticker + if (redTicker >= 7) +{ + redTicker = 0; + } + else + { + redTicker++; + } +} + +static void LED_yellowService(void) +{ + static bool ledStatus = LED_OFF; + switch(yellowTicker) + { + case 0: + ledStatus = yellowLed_2SecLoop.tick0; + break; + case 1: + ledStatus = yellowLed_2SecLoop.tick1; + break; + case 2: + ledStatus = yellowLed_2SecLoop.tick2; + break; + case 3: + ledStatus = yellowLed_2SecLoop.tick3; + break; + case 4: + ledStatus = yellowLed_2SecLoop.tick4; + break; + case 5: + ledStatus = yellowLed_2SecLoop.tick5; + break; + case 6: + ledStatus = yellowLed_2SecLoop.tick6; + break; + case 7: + ledStatus = yellowLed_2SecLoop.tick7; + break; + default: + // This should never be true + break; +} + + // Manage LED State + if (ledStatus == LED_ON) +{ + LED_YELLOW_SetLow(); + } + else + { + LED_YELLOW_SetHigh(); + } + + // Reset Ticker + if (yellowTicker >= 7) + { + yellowTicker = 0; +} + else + { + yellowTicker++; + } +} + +static void LED_greenService(void) +{ + static bool ledStatus = LED_OFF; + switch(greenTicker) + { + case 0: + ledStatus = greenLed_2SecLoop.tick0; + break; + case 1: + ledStatus = greenLed_2SecLoop.tick1; + break; + case 2: + ledStatus = greenLed_2SecLoop.tick2; + break; + case 3: + ledStatus = greenLed_2SecLoop.tick3; + break; + case 4: + ledStatus = greenLed_2SecLoop.tick4; + break; + case 5: + ledStatus = greenLed_2SecLoop.tick5; + break; + case 6: + ledStatus = greenLed_2SecLoop.tick6; + break; + case 7: + ledStatus = greenLed_2SecLoop.tick7; + break; + default: + // This should never be true + break; +} + + // Manage LED State + if (ledStatus == LED_ON) +{ + LED_GREEN_SetLow(); + } + else + { + LED_GREEN_SetHigh(); + } + + // Reset Ticker + if (greenTicker >= 7) + { + greenTicker = 0; + } + else + { + greenTicker++; + } +} + +static void LED_blueService(void) +{ + static bool ledStatus = LED_OFF; + switch(blueTicker) + { + case 0: + ledStatus = blueLed_2SecLoop.tick0; + break; + case 1: + ledStatus = blueLed_2SecLoop.tick1; + break; + case 2: + ledStatus = blueLed_2SecLoop.tick2; + break; + case 3: + ledStatus = blueLed_2SecLoop.tick3; + break; + case 4: + ledStatus = blueLed_2SecLoop.tick4; + break; + case 5: + ledStatus = blueLed_2SecLoop.tick5; + break; + case 6: + ledStatus = blueLed_2SecLoop.tick6; + break; + case 7: + ledStatus = blueLed_2SecLoop.tick7; + break; + default: + // This should never be true + break; +} + + // Manage LED State + if (ledStatus == LED_ON) +{ + LED_BLUE_SetLow(); + } + else + { + LED_BLUE_SetHigh(); + } + + // Reset Ticker + if (blueTicker >= 7) + { + blueTicker = 0; +} + else + { + blueTicker++; + } +} + +static uint32_t LED_service(void *payload) +{ + LED_redService(); + LED_blueService(); + LED_greenService(); + LED_yellowService(); + return LED_SERVICE_INTERVAL; +} + +static void testSequence (uint8_t ledState) +{ + if(LED_OFF == ledState){ + LED_BLUE_SetHigh(); + _delay_ms(LEDS_TEST_INTERVAL); + LED_GREEN_SetHigh(); + _delay_ms(LEDS_TEST_INTERVAL); + LED_YELLOW_SetHigh(); + _delay_ms(LEDS_TEST_INTERVAL); + LED_RED_SetHigh(); + _delay_ms(LEDS_TEST_INTERVAL); + } else { + LED_BLUE_SetLow(); + _delay_ms(LEDS_TEST_INTERVAL); + LED_GREEN_SetLow(); + _delay_ms(LEDS_TEST_INTERVAL); + LED_YELLOW_SetLow(); + _delay_ms(LEDS_TEST_INTERVAL); + LED_RED_SetLow(); + _delay_ms(LEDS_TEST_INTERVAL); + } +} + +void LED_test(void) +{ + testSequence(LED_ON); + testSequence(LED_OFF); +} + +void LED_serviceInit(void) +{ + timeout_create(&LED_service_timer, LED_SERVICE_INTERVAL); +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/led.h b/AVRIoT.X/mcc_generated_files/led.h new file mode 100644 index 0000000..dfe8708 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/led.h @@ -0,0 +1,63 @@ +/* + \file led.h + + \brief led header file. + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + + +#ifndef LED_H_ +#define LED_H_ +#include +#include + +#define LED_ON_STATIC 0x00 // OFF +#define LED_BLINK 0x55 // On-Off @ 250 mSec Interval +#define LED_BLIP 0x33 // On 500 @ mSec mSec Interval +#define LED_1_SEC_ON 0x0F // On 1 Sec, Off Remaining +#define LED_OFF_STATIC 0xFF + +typedef union +{ + uint8_t Full2Sec; + struct + { + unsigned tick0 : 1; + unsigned tick1 : 1; + unsigned tick2 : 1; + unsigned tick3 : 1; + unsigned tick4 : 1; + unsigned tick5 : 1; + unsigned tick6 : 1; + unsigned tick7 : 1; + }; +} ledTickState_t; + +void LED_serviceInit(); +void LED_test(void); + +void LED_modeRed(ledTickState_t configLed_2SecLoop); +void LED_modeBlue(ledTickState_t configLed_2SecLoop); +void LED_modeGreen(ledTickState_t configLed_2SecLoop); +void LED_modeYellow(ledTickState_t configLed_2SecLoop); +#endif /* LED_H_ */ diff --git a/AVRIoT.X/mcc_generated_files/mcc.c b/AVRIoT.X/mcc_generated_files/mcc.c new file mode 100644 index 0000000..96ffc94 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mcc.c @@ -0,0 +1,118 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include "mcc.h" + +/** + * Initializes MCU, drivers and middleware in the project +**/ +void SYSTEM_Initialize(void) +{ + PIN_MANAGER_Initialize(); + BOD_Initialize(); + WDT_Initialize(); + SLPCTRL_Initialize(); + CLKCTRL_Initialize(); + I2C0_Initialize(); + ADC0_Initialize(); + RTC_Initialize(); + SPI0_Initialize(); + USART2_Initialize(); + CPUINT_Initialize(); + CryptoAuth_Initialize(); + timeout_initialize(); +} + +/** + * \brief Initialize bod interface + */ +int8_t BOD_Initialize() +{ + //SLEEP DIS; + ccp_write_io((void*)&(BOD.CTRLA),0x00); + + //VLMCFG BELOW; VLMIE disabled; + BOD.INTCTRL = 0x00; + + //VLMLVL 5ABOVE; + BOD.VLMCTRLA = 0x00; + + return 0; +} + +ISR(BOD_VLM_vect) +{ + /* Insert your AC interrupt handling code here */ + + /* The interrupt flag has to be cleared manually */ + BOD.INTFLAGS = BOD_VLMIE_bm; +} + +/** + * \brief Initialize clkctrl interface + */ +int8_t CLKCTRL_Initialize() +{ + //RUNSTDBY disabled; + ccp_write_io((void*)&(CLKCTRL.OSC32KCTRLA),0x00); + + //CSUT 1K; SEL disabled; RUNSTDBY disabled; ENABLE disabled; + ccp_write_io((void*)&(CLKCTRL.XOSC32KCTRLA),0x00); + + //RUNSTDBY disabled; + ccp_write_io((void*)&(CLKCTRL.OSC20MCTRLA),0x00); + + //PDIV 2X; PEN enabled; + ccp_write_io((void*)&(CLKCTRL.MCLKCTRLB),0x01); + + //CLKOUT disabled; CLKSEL OSC20M; + ccp_write_io((void*)&(CLKCTRL.MCLKCTRLA),0x00); + + //LOCKEN disabled; + ccp_write_io((void*)&(CLKCTRL.MCLKLOCK),0x00); + + return 0; +} + +/** + * \brief Initialize slpctrl interface + */ +int8_t SLPCTRL_Initialize() +{ + //SMODE IDLE; SEN disabled; + ccp_write_io((void*)&(SLPCTRL.CTRLA),0x00); + + return 0; +} + +/** + * \brief Initialize wdt interface + */ + +int8_t WDT_Initialize() +{ + //WINDOW OFF; PERIOD OFF; + ccp_write_io((void*)&(WDT.CTRLA),0x00); + + return 0; +} diff --git a/AVRIoT.X/mcc_generated_files/mcc.h b/AVRIoT.X/mcc_generated_files/mcc.h new file mode 100644 index 0000000..96f72f6 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mcc.h @@ -0,0 +1,58 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef MCC_H +#define MCC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "utils/compiler.h" +#include "include/pin_manager.h" +#include "CryptoAuth_init.h" +#include "drivers/i2c_simple_master.h" +#include "delay.h" +#include "include/twi0_master.h" +#include "include/spi0.h" +#include "include/rtc.h" +#include "include/cpuint.h" +#include "include/usart2.h" +#include "include/adc0.h" +#include "drivers/spi_master.h" +#include "drivers/timeout.h" +#include "config/clock_config.h" + +/** + * Initializes MCU, drivers and middleware in the project +**/ +void SYSTEM_Initialize(void); +int8_t BOD_Initialize(); +int8_t CLKCTRL_Initialize(); +int8_t SLPCTRL_Initialize(); +int8_t WDT_Initialize(); + +#ifdef __cplusplus +} +#endif +#endif /* MCC_H */ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.c b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.c new file mode 100644 index 0000000..eded5df --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.c @@ -0,0 +1,92 @@ +/* + \file mqtt_comm_layer.c + + \brief MQTT Communication layer source file. + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ +#include +#include +#include "mqtt_comm_layer.h" +#include "../mqtt_core/mqtt_core.h" +#include "../mqtt_winc_adapter.h" + +static mqttContext mqttConn; +static uint8_t mqttTxBuff[CFG_MQTT_TXBUFFER_SIZE]; +static uint8_t mqttRxBuff[CFG_MQTT_RXBUFFER_SIZE]; +static int8_t mqqtSocket = -1; + +static int lastSentSize; + +void MQTT_ClientInitialise(void) +{ + MQTT_initialiseState(); + memset(mqttTxBuff, 0 , sizeof(CFG_MQTT_TXBUFFER_SIZE)); + memset(mqttRxBuff, 0 , sizeof(CFG_MQTT_RXBUFFER_SIZE)); + mqttConn.mqttDataExchangeBuffers.txbuff.start = mqttTxBuff; + mqttConn.mqttDataExchangeBuffers.txbuff.bufferLength = CFG_MQTT_TXBUFFER_SIZE; + mqttConn.mqttDataExchangeBuffers.txbuff.currentLocation = mqttConn.mqttDataExchangeBuffers.txbuff.start; + mqttConn.mqttDataExchangeBuffers.txbuff.dataLength = 0; + mqttConn.mqttDataExchangeBuffers.rxbuff.start = mqttRxBuff; + mqttConn.mqttDataExchangeBuffers.rxbuff.bufferLength = CFG_MQTT_RXBUFFER_SIZE; + mqttConn.mqttDataExchangeBuffers.rxbuff.currentLocation = mqttConn.mqttDataExchangeBuffers.rxbuff.start; + mqttConn.mqttDataExchangeBuffers.rxbuff.dataLength = 0; + + mqttConn.tcpClientSocket = &mqqtSocket; +} + +mqttContext* MQTT_GetClientConnectionInfo() +{ + return &mqttConn; +} + + +bool MQTT_Send(mqttContext *connectionPtr) +{ + bool ret = false; + if((lastSentSize = BSD_send(*connectionPtr->tcpClientSocket, connectionPtr->mqttDataExchangeBuffers.txbuff.start, connectionPtr->mqttDataExchangeBuffers.txbuff.dataLength, 0)) > BSD_SUCCESS) + { + ret = true; + } + return ret; +} + +int MQTT_LastSentSize (void) +{ + return lastSentSize; +} + +bool MQTT_Close(mqttContext *connectionPtr) +{ + bool ret = false; + if(BSD_close(*connectionPtr->tcpClientSocket) == BSD_SUCCESS) + { + ret = true; + } + return ret; +} + +void MQTT_GetReceivedData(uint8_t *pData, uint8_t len) +{ + MQTT_ExchangeBufferInit(&mqttConn.mqttDataExchangeBuffers.rxbuff); + MQTT_ExchangeBufferWrite(&mqttConn.mqttDataExchangeBuffers.rxbuff, pData, len); +} diff --git a/AVRIoT.X/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.h b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.h new file mode 100644 index 0000000..1f6fa92 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.h @@ -0,0 +1,59 @@ +/* + \file mqtt_comm_layer.h + + \brief MQTT Communication layer header file. + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef MQTT_COMM_LAYER_H +#define MQTT_COMM_LAYER_H + +#include +#include +#include "../mqtt_exchange_buffer/mqtt_exchange_buffer.h" + +/** \brief MQTT connection information + * + * This is used by the application to store TCB, transmit buffer and receive + * buffer information. + */ +typedef struct +{ + // Todo: The MQTTSTATE variable should be in the context. We have one state in the lib now with many buffer contexts. +#ifdef TCPIP_LITE + tcpTCB_t tcbInfo; +#endif /* TCPIP_LITE */ + mqttBuffers mqttDataExchangeBuffers; + int8_t* tcpClientSocket; +} mqttContext; + + +void MQTT_ClientInitialise(void); +mqttContext* MQTT_GetClientConnectionInfo(); + +bool MQTT_Send(mqttContext *connectionPtr); +bool MQTT_Close(mqttContext *connectionPtr); +void MQTT_GetReceivedData(uint8_t *pData, uint8_t len); + +int MQTT_LastSentSize (void); +#endif /* MQTT_COMM_LAYER_H */ diff --git a/AVRIoT.X/mcc_generated_files/mqtt/mqtt_comm_tcpipLite/mqtt_comm_layer.c b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_comm_tcpipLite/mqtt_comm_layer.c new file mode 100644 index 0000000..10d58d8 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_comm_tcpipLite/mqtt_comm_layer.c @@ -0,0 +1,132 @@ +/******************************************************************** + * + © [2018] Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR + * PURPOSE. + * + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + * WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + * BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + * FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + * ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + ************************************************************************* + * + * mqtt_comm_layer.c + * + * About: + * MQTT communication layer to abstract the TCP function calls. Intermediate + * layer linking the core of the MQTT Client to the MQTT TCP Connection + * handler. It is this layer that provides the abstracted APIs for sending and + * receiving TCP packets to the MQTT Client on one side, and for establishing + * TCP communication to the MQTT Connection Handler on the other. If a + * different TCP library usage than the one being currently used (TCPIP Lite + * library) is required, this is the only layer which will need changes thus + * keeping the MQTT Client core independent of the underlying TCP library being + * used. + * + * + ******************************************************************************/ + +#include +#include +#include +#include "mqtt_comm_layer.h" + + +/**********************Function implementations********************************/ + +socketState_t MQTT_SocketPoll(mqttContext *connectionPtr) +{ + socketState_t ret; + + ret = TCP_SocketPoll(&connectionPtr->tcbInfo); + + return ret; +} + + +error_msg MQTT_SocketInit(mqttContext *connectionPtr) +{ + error_msg ret = ERROR; + + ret = TCP_SocketInit(&connectionPtr->tcbInfo); + + return ret; +} + + +error_msg MQTT_InsertRxBuffer(mqttContext *connectionPtr) +{ + error_msg ret = ERROR; + + ret = TCP_InsertRxBuffer(&connectionPtr->tcbInfo, connectionPtr->mqttDataExchangeBuffers.rxbuff.start, connectionPtr->mqttDataExchangeBuffers.rxbuff.bufferLength); + + return ret; +} + + +error_msg MQTT_SocketConnect(mqttContext *connectionPtr, sockaddr_in4_t *srvaddr) +{ + error_msg ret = ERROR; + + ret = TCP_Connect(&connectionPtr->tcbInfo, srvaddr); + + return ret; +} + + +error_msg MQTT_Close(mqttContext *connectionPtr) +{ + error_msg ret = ERROR; + + ret = TCP_Close(&connectionPtr->tcbInfo); + + return ret; +} + + +int16_t MQTT_GetReceivedData(mqttContext *connectionPtr) +{ + int16_t length = 0; + + length = TCP_GetReceivedData(&connectionPtr->tcbInfo); + + return length; +} + + + +bool MQTT_Send(mqttContext *connectionPtr) +{ + bool ret = false; + + if(TCP_Send(&connectionPtr->tcbInfo, connectionPtr->mqttDataExchangeBuffers.txbuff.start, connectionPtr->mqttDataExchangeBuffers.txbuff.dataLength) == SUCCESS) + { + ret = true; + } + return ret; +} + + +error_msg MQTT_SocketRemove(mqttContext *connectionPtr) +{ + error_msg ret = ERROR; + + ret = TCP_SocketRemove(&connectionPtr->tcbInfo); + + return ret; +} + + + +/**********************Function implementations*(END)**************************/ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/mqtt/mqtt_comm_tcpipLite/mqtt_comm_layer.h b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_comm_tcpipLite/mqtt_comm_layer.h new file mode 100644 index 0000000..4765e58 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_comm_tcpipLite/mqtt_comm_layer.h @@ -0,0 +1,175 @@ +/******************************************************************** + * + © [2018] Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR + * PURPOSE. + * + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + * WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + * BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + * FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + * ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + ************************************************************************* + * + * mqtt_comm_layer.h + * + * About: + * Definition of the MQTT Communication Layer which provides abstraction of TCP + * communication APIs for MQTT client. + * + * + ******************************************************************************/ + +#ifndef MQTT_CONNECTION_LAYER_H +#define MQTT_CONNECTION_LAYER_H + +#include +#include +#include "tcpv4.h" +#include "tcpip_types.h" +#include "mac_address.h" +#include "../mqtt_exchange_buffer/mqtt_exchange_buffer.h" + +/** \brief MQTT connection information + * + * This is used by the application to store TCB, transmit buffer and receive + * buffer information. + */ +typedef struct +{ + tcpTCB_t tcbInfo; + mqttBuffers mqttDataExchangeBuffers; +} mqttContext; + + +/** The function will provide an interface to read the status of the socket. + * This function internally calls the TCP_SocketPoll() from the TCPIP Lite + * library. + * + * @param connectionPtr + * pointer to MQTT connection information + * + * @return + * the socket state + */ +socketState_t MQTT_SocketPoll(mqttContext *connectionPtr); + + +/** Initialize the TCB for MQTT communication. This function internally calls + * the TCP_SocketInit() from TCPIP Lite library which in turn puts the socket + * in the CLOSED state. + * + * The user is responsible to manage allocation and releasing of the memory. + * + * @param connectionPtr + * pointer to MQTT connection information + * + * @return + * ERROR if socket is not initialised for MQTT TCP connection + * @return + * SUCCESS if the socket initialisation for MQTT was successful + */ +error_msg MQTT_SocketInit(mqttContext *connectionPtr); + + +/** Add the RX buffer to the socket for receiving MQTT packets. This function + * internally calls the TCP_InsertRxBuffer() function from the TCPIP Lite + * library + * + * @param connectionPtr + * pointer to MQTT connection information + * + * @return + * SUCCESS - The RX buffer was passed to socket successfully + * @return + * ERROR - passing of the RX buffer to the socket failed. + */ +error_msg MQTT_InsertRxBuffer(mqttContext *connectionPtr); + + +/** Start the MQTT client for a specific socket. This function internally calls + * TCP_Connect() from the TCPIP Lite library. + * + * @param connectionPtr + * pointer to MQTT connection information + * + * @param srvaddr + * port number and address used for establishing MQTT connection. + * + * @return + * SUCCESS - The server was started successfully + * @return + * ERROR - The starting of the server fails + */ +error_msg MQTT_SocketConnect(mqttContext *connectionPtr, sockaddr_in4_t *srvaddr); + + +/** Close the MQTT connection. This function internally calls + * TCP_Close() from the TCPIP Lite library. This will initiate the closing + * sequence for the TCP connection being used for MQTT. + * + * @param connectionPtr + * pointer to MQTT connection information + * + * @return + * SUCCESS - The close procedure was started successfully + * @return + * ERROR - The close procedure failed + */ +error_msg MQTT_Close(mqttContext *connectionPtr); + + +/** This function reads the available data from the MQTT socket. This function + * internally calls TCP_GetReceivedData() from the TCPIP Lite library. + * + * @param connectionPtr + * pointer to MQTT connection information + * + * @return + * Number of bytes received in the MQTT packet + * + */ +int16_t MQTT_GetReceivedData(mqttContext *connectionPtr); + + +/** Send a data to MQTT server using TCP connection.This function + * internally calls TCP_Send() from the TCPIP Lite library. + * + * @param connectionPtr + * pointer to MQTT connection information + * + * @return + * true - The data buffer was added to the socket/TCB successfully + * @return + * false - Adding the data buffer to the socket failed + */ +bool MQTT_Send(mqttContext *connectionPtr); + + +/** Remove the socket pointer being used for MQTT connection from the TCP Stack. + * This function internally calls TCP_SocketRemove() from the TCPIP Lite + * library. + * + * @param connectionPtr + * pointer to MQTT connection information + * + * @return + * ERROR if there was any problems + * @return + * SUCCESS if the socket removal was successful + */ +error_msg MQTT_SocketRemove(mqttContext *connectionPtr); + + +#endif /* MQTT_CONNECTION_LAYER_H */ + diff --git a/AVRIoT.X/mcc_generated_files/mqtt/mqtt_comm_tcpipLite/mqtt_connection_handler.c b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_comm_tcpipLite/mqtt_connection_handler.c new file mode 100644 index 0000000..6baec92 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_comm_tcpipLite/mqtt_connection_handler.c @@ -0,0 +1,144 @@ +/******************************************************************** + * + © [2018] Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR + * PURPOSE. + * + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + * WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + * BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + * FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + * ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + ************************************************************************* + * + * mqtt_connection_handler.c + * + * About: + * MQTT Connection Handler to maintain TCP connection for MQTT communication. + * + * + ******************************************************************************/ +#include +#include "mqtt_connection_handler.h" +#include "../mqtt_core/mqtt_core.h" +#include "../mqtt_comm_tcpipLite/mqtt_comm_layer.h" +#include "tcpip_config.h" + + +/********************MQTT Connection Handler definitions**********************/ +//Consider enough time for both broker to send an SYNACK after client sends out +// a SYN packet, and client to send an ACK to broder, we take 60 seconds as +// timeout +#define MQTT_SOCKETCONNECT_TIMEOUT 60 + +/*****************MQTT Connection Handler definitions*(END)********************/ + + +/******************MQTT Connection Handler variables***************************/ +// Create the socket for the TCP Client +volatile sockaddr_in4_t mqttSocket; + + +mqttContext mqttConn; + + +/*****************MQTT Connection Handler variables*(END)**********************/ + + +/**********************Function implementations********************************/ +void MQTT_ClientInitialise(mqttConnectionInfo *mqttClientInfo) +{ + mqttSocket.addr.s_addr = MAKE_IPV4_ADDRESS(mqttClientInfo->ipAddress[0], mqttClientInfo->ipAddress[1], mqttClientInfo->ipAddress[2], mqttClientInfo->ipAddress[3]); + mqttSocket.port = mqttClientInfo->mqttTCPCommunicationPortNumber; + mqttConn.mqttDataExchangeBuffers.txbuff.start = mqttClientInfo->txDataBuffer; + mqttConn.mqttDataExchangeBuffers.txbuff.bufferLength = mqttClientInfo->txDataBufferLength; + mqttConn.mqttDataExchangeBuffers.rxbuff.start = mqttClientInfo->rxDataBuffer; + mqttConn.mqttDataExchangeBuffers.rxbuff.bufferLength = mqttClientInfo->rxDataBufferLength; +} + + +// ToDo Maintain prevState and currState of MQTT_Handler() to close the TCP +// connection in the event of MQTT DISCONNECT. +void MQTT_Manage(void) +{ + static time_t t_client; + static time_t socketTimeout; + static bool mqtt_conn_sent = false; + uint16_t rxLength; + socketState_t socketState; + rxLength = 0; + + socketState = MQTT_SocketPoll(&mqttConn); + + time(&t_client); + + switch(socketState) + { + case NOT_A_SOCKET: + //Try to send out MQTT connect request after MQTT_SOCKETCONNECT_TIMEOUT + socketTimeout = t_client + MQTT_SOCKETCONNECT_TIMEOUT; + MQTT_SocketInit(&mqttConn); + break; + case SOCKET_CLOSED: + // If the socket is closed we will try to connect again + MQTT_InsertRxBuffer(&mqttConn); + if (!mqtt_conn_sent) + { + MQTT_initialiseState(); + MQTT_SocketConnect(&mqttConn, &mqttSocket); + mqtt_conn_sent = true; + } + else + { + if(t_client > socketTimeout) + { + socketTimeout = t_client + MQTT_SOCKETCONNECT_TIMEOUT; + MQTT_SocketConnect(&mqttConn, &mqttSocket); + } + } + + // ToDo Update the MQTT handler state here + // If the MQTT state is DISCONNECTED, the TCP connection needs to be + // closed. + break; + case SOCKET_IN_PROGRESS: + // If the socket is closed try to connect again + // ToDo This might require some modifications + if(t_client >= socketTimeout) + { + MQTT_Close(&mqttConn); + } + break; + case SOCKET_CONNECTED: + // ToDo Maintain prevState and currState of MQTT_Handler() to + // close the TCP connection in the event of MQTT DISCONNECT. + rxLength = MQTT_GetReceivedData(&mqttConn); + if(rxLength > 0) + { + MQTT_ExchangeBufferWrite(&mqttConn.mqttDataExchangeBuffers.rxbuff, mqttConn.tcbInfo.rxBufferStart, rxLength); + MQTT_ReceptionHandler(&mqttConn); + MQTT_InsertRxBuffer(&mqttConn); + } + MQTT_TransmissionHandler(&mqttConn); + break; + case SOCKET_CLOSING: + MQTT_SocketRemove(&mqttConn); + mqtt_conn_sent = false; + break; + default: + break; + } +} + +/**********************Function implementations********************************/ + diff --git a/AVRIoT.X/mcc_generated_files/mqtt/mqtt_comm_tcpipLite/mqtt_connection_handler.h b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_comm_tcpipLite/mqtt_connection_handler.h new file mode 100644 index 0000000..dcadc14 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_comm_tcpipLite/mqtt_connection_handler.h @@ -0,0 +1,71 @@ +/******************************************************************** + * + * Copyright (C) 2014 Microchip Technology Inc. and its subsidiaries + * (Microchip). All rights reserved. + * + * You are permitted to use the software and its derivatives with Microchip + * products. See the license agreement accompanying this software, if any, for + * more info about your rights and obligations. + * + * SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF + * MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR + * PURPOSE. IN NO EVENT SHALL MICROCHIP, SMSC, OR ITS LICENSORS BE LIABLE OR + * OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH + * OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY FOR ANY DIRECT OR INDIRECT + * DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR OTHER SIMILAR COSTS. To the fullest + * extend allowed by law, Microchip and its licensors liability will not exceed + * the amount of fees, if any, that you paid directly to Microchip to use this + * software. + ************************************************************************* + * + * mqtt_connection_handler.h + * + * About: + * Definition of the MQTT TCP Connection + * + * + ******************************************************************************/ +#ifndef MQTT_CONNECTION_HANDLER_H +#define MQTT_CONNECTION_HANDLER_H + +#include + + +typedef struct +{ + uint8_t *ipAddress; + uint16_t mqttTCPCommunicationPortNumber; + uint8_t *txDataBuffer; + uint8_t txDataBufferLength; + uint8_t *rxDataBuffer; + uint8_t rxDataBufferLength; +} mqttConnectionInfo; + + +// ToDo Add description of APIs +void MQTT_ClientInitialise(mqttConnectionInfo *mqttClientInfo); + + +void MQTT_SetBrokerIPAddr(uint8_t *ipAddress); + + +void MQTT_SetTCPConnectionPort(uint16_t mqttTCPCommunicationPort); + + +void MQTT_SetTxDataBuffer(uint8_t *txDataBuffer, uint8_t txDataBufferLength); + + +void MQTT_SetRxDataBuffer(uint8_t *rxDataBuffer, uint8_t rxDataBufferLength); + + +void MQTT_Manage(void); + + +void DEMO_TCP_Client(void); + + +void TCP_Client_Initialize(); + +#endif /* MQTT_CONNECTION_HANDLER_H */ diff --git a/AVRIoT.X/mcc_generated_files/mqtt/mqtt_core/mqtt_core.c b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_core/mqtt_core.c new file mode 100644 index 0000000..5b40d27 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_core/mqtt_core.c @@ -0,0 +1,1436 @@ +/******************************************************************** + * + * (c) [2018] Microchip Technology Inc. and its subsidiaries. + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR + * PURPOSE. + * + * IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + * WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + * BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + * FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + * ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + ************************************************************************* + * + * mqtt_core.c + * + * About: + * MQTT client implementation. This is the core of the MQTT client protocol + * implementation. The aim of this file is to implement a hardware-independent + * subsystem that complies with [mqtt-v3.1.1-plus-errata01]. + * + * + ******************************************************************************/ +#include +#include +#include +#include +#include +#include "../../drivers/timeout.h" +#include "mqtt_core.h" +#include "../mqtt_packetTransfer_interface.h" +#include "../../config/mqtt_config.h" + +/***********************MQTT Client definitions********************************/ + +#define MQTT_TX_PACKET_DECISION_CONSTANT 0x01 +#define KEEP_ALIVE_CALCULATION_CONSTANT 0x01 +#define CONNECT_CLEAN_SESSION_MASK 0x02 + +// MQTT packet transmission flags. The creation and transmission processes of +// MQTT control packets uses a set of flags to indicate that a new packet is +// created and available for transmission. These flags are defined here. + +typedef union +{ + uint8_t All; + struct + { + unsigned newTxConnectPacket : 1; // Indicates new CONNECT packet available for transmission + unsigned newTxDisconnectPacket : 1; // Indicates new DISCONNECT packet available for transmission + unsigned newTxPublishPacket : 1; // Indicates new PUBLISH packet available for transmission + unsigned newTxSubscribePacket : 1; // Indicates new SUBSCRIBE packet available for transmission + unsigned newTxUnsubscribePacket : 1; // Indicates new UNSUBSCRIBE packet available for transmission + unsigned newTxPingreqPacket : 1; // Indicates new PINGREQ packet available for transmission + unsigned : 2; // Reserved + }; +} newTxDataFlags; + + +// MQTT packet reception flags. The reception processes of MQTT control packets +// uses a set of flags to identify the received packet type in order to +// correctly process it. These flags are defined here. +typedef union +{ + uint8_t All; + struct + { + unsigned newRxConnackPacket : 1; // Indicates new CONNACK packet has been received + unsigned newRxPublishPacket : 1; // Indicates new PUBLISH packet has been received + unsigned newRxSubackPacket : 1; // Indicates new SUBACK packet has been received + unsigned newRxUnsubackPacket : 1; // Indicates new UNSUBACK packet has been received + unsigned newRxPingrespPacket : 1; // Indicates new PINGRESP packet has been received + unsigned newRxPubackPacket : 1; // Indicates new PUBACK packet has been received + unsigned : 2; // Reserved + }; +} newRxDataFlags; + + +// MQTT packet transmission states. The transmission of MQTT control packets is +// performed inside the CONNECTED state. The Tx state machine states are defined +// here. These need to correspond to the respective flags in the union +// newTxDataFlags. +typedef enum +{ + SENDDISCONNECT = 2, + SENDPUBLISH = 4, + SENDSUBSCRIBE = 8, + SENDUNSUBSCRIBE = 16, + SENDPINGREQ = 32, +} mqttConnectCurrentTxSubstate; + + +// Function pointer for handling QoS levels. +typedef void (*qosLevelHandler)(uint8_t); + + +// The QoS levels in PUBLISH message are 0, 1 and 2 with quality of service +// increasing from QoS level 0 to 2. QoS level processing needs information +// about the QoS level and the appropriate callback function. The call back +// table type for determining whether the correct callback function for the QoS +// level under consideration is defined here. +typedef struct +{ + uint8_t qosLevel; + qosLevelHandler qosLevelHandlerFunction; +} qosLevelHandler_t; + + +/** \brief mqttTimeouts holds the flags to indicate timeouts for various MQTT packets. */ +typedef union +{ + uint8_t All; + struct + { + unsigned connackTimeOutOccured : 1; + unsigned pingreqTimeoutOccured : 1; + unsigned pingrespTimeoutOccured : 1; + unsigned subackTimeoutOccured : 1; + unsigned unsubackTimeoutOccured : 1; + unsigned unassigned : 3; + }; +}mqttTimeouts_t; + +/***********************MQTT Client definitions*(END)**************************/ + + +/***********************MQTT Client variables**********************************/ + +/** \brief MQTT packet transmission flags. */ +static newTxDataFlags mqttTxFlags; + + +/** \brief MQTT packet reception flags. */ +static newRxDataFlags mqttRxFlags; + + +/** \brief CONNECT packet to be transmitted. */ +static mqttConnectPacket txConnectPacket; + + +/** \brief PUBLISH packet to be transmitted. */ +static mqttPublishPacket txPublishPacket; + + +/** \brief SUBSCRIBE packet to be transmitted. */ +static mqttSubscribePacket txSubscribePacket; + + +/** \brief UNSUBSCRIBE packet to be transmitted. */ +static mqttUnsubscribePacket txUnsubscribePacket; + + +static volatile mqttTimeouts_t mqttTimeouts = {0}; + + +/** \brief Informs later up what the last State we changed from was*/ +static mqttHandlerState_t lastMQTTHandlerState = MQTT_NO_ERROR; + + +/** \brief Allows reference to be pased layer up what last receieve Header type was*/ +static mqttHeaderFlags lastReceivedPacketHeader; + + +/** \brief Used to allow reference of packet size layer up */ +static uint16_t lastReceivedLength; + + +/** \brief QoS level call back table. + * + * This callback table lists the callback functions for 3 different QoS levels + * of the MQTT PUBLISH message. For each QoS level there needs to be a + * corresponding callback function. + * Currently only QoS level 0 is supported. + * + */ +static const qosLevelHandler_t mqtt_qosLevelCallBackTable[] = +{ + // {0x00, handleQoSLevel0} +}; + + +/** \brief Current state of MQTT Client state machine. */ +static mqttCurrentState mqttState = DISCONNECTED; + + +/** \brief Tx substate for the state machine inside the CONNECTED state. */ +static mqttConnectCurrentTxSubstate mqttConnectTxSubstate; + +/***********************MQTT Client variables*(END)****************************/ + + +/**********************Local function definitions******************************/ + +/** \brief Encode the MQTT packet length. + * + * This function encodes the MQTT packet length. + * + * @param length + * @param *output + * + * @return + * - The number of bytes encoded + */ +static uint8_t mqttEncodeLength(uint16_t length, uint8_t *output); + + +/** \brief Decode the MQTT packet length. + * + * This function decodes the MQTT packet length available in the remainingLength + * field of the received packet. + * + * @param *data + * + * @return + * - The number of bytes decoded + */ +static uint32_t mqttDecodeLength(uint8_t *encodedData); + + +/** \brief Send the MQTT CONNECT packet. + * + * This function sends the MQTT CONNECT packet using the underlying +TCP layer. + * + * @param mqttConnectionPtr + * + * @return + * - The return code indicating success/failure of CONNECT packet +transmission. + */ +static bool mqttSendConnect(mqttContext *mqttConnectionPtr); + + +/** \brief Send the MQTT PUBLISH packet. + * + * This function sends the MQTT PUBLISH packet using the underlying +TCP layer. + * + * @param mqttConnectionPtr + * + * @return + * - The return code indicating success/failure of PUBLISH packet +transmission. + */ +static bool mqttSendPublish(mqttContext *mqttConnectionPtr); + + +/** \brief Send the MQTT SUBSCRIBE packet. + * + * This function sends the MQTT SUBSCRIBE packet using the underlying +TCP layer. + * + * @param mqttConnectionPtr + * + * @return + * - The return code indicating success/failure of SUBSCRIBE packet +transmission. + */ +static bool mqttSendSubscribe(mqttContext *mqttConnectionPtr); + + +/** \brief Send the MQTT UNSUBSCRIBE packet. + * + * This function sends the MQTT UNSUBSCRIBE packet using the underlying +TCP layer. + * + * @param mqttConnectionPtr + * + * @return + * - The return code indicating success/failure of UNSUBSCRIBE packet +transmission. + */ +static bool mqttSendUnsubscribe(mqttContext *mqttConnectionPtr); + + +/** \brief Send the MQTT PINGREQ packet. + * + * This function sends the MQTT PINGREQ packet using the underlying +TCP layer. + * + * @param mqttConnectionPtr + * + * @return + * - The return code indicating success/failure of PINGREQ packet +transmission. + */ +static bool mqttSendPingreq(mqttContext *mqttConnectionPtr); + + +/** \brief Send the MQTT DISCONNECT packet. + * + * This function sends the MQTT DISCONNECT packet using the underlying +TCP layer. + * + * @param mqttConnectionPtr + * + * @return + * - The return code indicating success/failure of DISCONNECT packet +transmission. + */ +static bool mqttSendDisconnect(mqttContext *mqttConnectionPtr); + + +/** \brief Process the MQTT CONNACK packet. + * + * This function processes the CONNACK packet received from the +broker. + * + * @param mqttConnectionPtr + * + * @return + * - The state of MQTT Tx and Rx handlers depending on whether the CONNACK +packet was received and processed correctly. + */ +static mqttCurrentState mqttProcessConnack(mqttContext *mqttConnectionPtr); + + +/** \brief Process the MQTT PINGRESP packet. + * + * This function processes the PINGRESP packet received from the +broker. + * + * @param mqttConnectionPtr + * + */ +static void mqttProcessPingresp(mqttContext *mqttConnectionPtr); + + +/** \brief Process the MQTT SUBACK packet. + * + * This function processes the SUBACK packet received from the +broker. + * + * @param mqttConnectionPtr + * + * @return + * - The state of MQTT Tx and Rx handlers depending on whether the mqttProcessSuback +packet was received and processed correctly. + */ +static mqttCurrentState mqttProcessSuback(mqttContext *mqttConnectionPtr); + + +/** \brief Process the MQTT UNSUBACK packet. + * + * This function processes the UNSUBACK packet received from the +broker. + * + * @param mqttConnectionPtr + * + * @return + * - The state of MQTT Tx and Rx handlers depending on whether the mqttProcessUnsuback +packet was received and processed correctly. + */ +static mqttCurrentState mqttProcessUnsuback(mqttContext *mqttConnectionPtr); + + +/** \brief Process the MQTT PUBLISH packet. + * + * This function processes the PUBLISH packet received from the +broker. + * + * @param mqttConnectionPtr + * + */ +static mqttCurrentState mqttProcessPublish(mqttContext *mqttConnectionPtr); + + +/** \brief Check whether timeout has occurred after sending CONNECT +packet. + * + * This function checks whether a timeout (30s) has occurred after sending +CONNECT packet, since a CONNACK packet is expected from the broker +within 30s. + * + * @param none + * + * @return + * - The number of ticks till the connackTimer expires. + */ +static uint32_t checkConnackTimeoutState(); +timerstruct_t connackTimer = {checkConnackTimeoutState, NULL}; + + +/** \brief Check whether timeout has occurred after receiving CONNACK +or PINGRESP packet. + * + * This function checks whether a timeout of (keepAliveTime)s has occurred after +receiving CONNACK or PINGRESP packet, since a client is expected to send some +packet to the broker within (keepAliveTime)s time period. + * + * @param none + * + * @return + * - The number of ticks till the connackTimer or pingrespTimer expires. + */ +static uint32_t checkPingreqTimeoutState(); +timerstruct_t pingreqTimer = {checkPingreqTimeoutState, NULL}; + + +/** \brief Check whether timeout has occurred after sending PINGREQ +packet. + * + * This function checks whether a timeout (30s) has occurred after sending +PINGREQ packet. In the current MQTT client implementation, the client +waits for 30s after transmission of PINGREQ packet to receive a PINGRESP +packet. + * + * @param none + * + * @return + * - The number of ticks till the pingreq expires. + */ +static uint32_t checkPingrespTimeoutState(); +timerstruct_t pingrespTimer = {checkPingrespTimeoutState, NULL}; + + +/** \brief Check whether timeout has occurred after sending SUBSCRIBE +packet. + * + * This function checks whether a timeout (30s) has occurred after sending +SUBSCRIBE packet. In the current MQTT client implementation, the client +waits for 30s after transmission of SUBSCRIBE packet to receive a SUBACK +packet. +* If the client does not receive a SUBACK packet from the server in a +reasonable period of time (currently set to 30s), it is treated as a +protocol violation. The client therefore will close the Network +Connection by checking subackTimeoutOccured flag (MQTT RFC, section 4.8). + * + * @param none + * + * @return + * - The number of ticks till the suback expires. + */ +static uint32_t checkSubackTimeoutState(); +timerstruct_t subackTimer = {checkSubackTimeoutState, NULL}; + + +/** \brief Check whether timeout has occurred after sending UNSUBSCRIBE +packet. + * + * This function checks whether a timeout (30s) has occurred after sending +UNSUBSCRIBE packet. In the current MQTT client implementation, the client +waits for 30s after transmission of UNSUBSCRIBE packet to receive a UNSUBACK +packet. +* If the client does not receive a UNSUBACK packet from the server in a +reasonable period of time (currently set to 30s), it is treated as a +protocol violation. The client therefore will close the Network +Connection by checking unsubackTimeoutOccured flag (MQTT RFC, section 4.8). + * + * @param none + * + * @return + * - The number of ticks till the unsuback expires. + */ +static uint32_t checkUnsubackTimeoutState(); +timerstruct_t unsubackTimer = {checkUnsubackTimeoutState, NULL}; + +/**********************Local function definitions*(END)************************/ + +/**********************Function implementations********************************/ +static uint32_t checkConnackTimeoutState() +{ + mqttTimeouts.connackTimeOutOccured = 1; // Mark that timer has executed + return 0; // Stop the timer +} + +static uint32_t checkPingreqTimeoutState() +{ + mqttTimeouts.pingreqTimeoutOccured = 1; // Mark that timer has executed + return ((ntohs(txConnectPacket.connectVariableHeader.keepAliveTimer) - KEEP_ALIVE_CALCULATION_CONSTANT) * SECONDS); +} + + +static uint32_t checkPingrespTimeoutState() +{ + mqttTimeouts.pingrespTimeoutOccured = 1; // Mark that timer has executed + return (WAITFORPINGRESP_TIMEOUT); +} + + +static uint32_t checkSubackTimeoutState() +{ + mqttTimeouts.subackTimeoutOccured = 1; // Mark that timer has executed + return 0; // Stop the timer +} + + +static uint32_t checkUnsubackTimeoutState() +{ + mqttTimeouts.unsubackTimeoutOccured = 1; // Mark that timer has executed + return 0; // Stop the timer +} + + +void MQTT_initialiseState(void) +{ + mqttState = DISCONNECTED; +} + + +mqttCurrentState MQTT_GetConnectionState(void) +{ + return mqttState; +} + + +bool MQTT_CreateConnectPacket(mqttConnectPacket *newConnectPacket) +{ + uint16_t payloadLength = 0; + memset(&txConnectPacket, 0, sizeof (txConnectPacket)); + + // Fixed header + txConnectPacket.connectFixedHeaderFlags.controlPacketType = CONNECT; + txConnectPacket.connectFixedHeaderFlags.duplicate = 0; + txConnectPacket.connectFixedHeaderFlags.qos = 0; + txConnectPacket.connectFixedHeaderFlags.retain = 0; + + // Variable header + txConnectPacket.connectVariableHeader.protocolName[0] = 0x00; + txConnectPacket.connectVariableHeader.protocolName[1] = 0x04; + txConnectPacket.connectVariableHeader.protocolName[2] = 'M'; + txConnectPacket.connectVariableHeader.protocolName[3] = 'Q'; + txConnectPacket.connectVariableHeader.protocolName[4] = 'T'; + txConnectPacket.connectVariableHeader.protocolName[5] = 'T'; + txConnectPacket.connectVariableHeader.protocolLevel = 0x04; + if ((newConnectPacket->passwordLength > 0) || (newConnectPacket->usernameLength > 0)) + { + txConnectPacket.connectVariableHeader.connectFlagsByte.All = 0xC2; + } + else + { + txConnectPacket.connectVariableHeader.connectFlagsByte.All = 0x02; + } + txConnectPacket.connectVariableHeader.keepAliveTimer = htons(newConnectPacket->connectVariableHeader.keepAliveTimer); + + // Payload + txConnectPacket.clientID = newConnectPacket->clientID; + txConnectPacket.clientIDLength = strlen((char*) txConnectPacket.clientID); + if (txConnectPacket.connectVariableHeader.connectFlagsByte.passwordFlag == 1) + { + txConnectPacket.password = newConnectPacket->password; + txConnectPacket.passwordLength = newConnectPacket->passwordLength; + } + if (txConnectPacket.connectVariableHeader.connectFlagsByte.usernameFlag == 1) + { + txConnectPacket.username = newConnectPacket->username; + txConnectPacket.usernameLength = newConnectPacket->usernameLength; + } + if (txConnectPacket.connectVariableHeader.connectFlagsByte.usernameFlag == 0) + { + payloadLength = txConnectPacket.clientIDLength; + } + else + { + payloadLength = txConnectPacket.clientIDLength + txConnectPacket.passwordLength + txConnectPacket.usernameLength + 4; + } + txConnectPacket.totalLength = sizeof (txConnectPacket.connectVariableHeader) + sizeof (payloadLength) + payloadLength; + if (txConnectPacket.connectVariableHeader.connectFlagsByte.usernameFlag == 1 || txConnectPacket.connectVariableHeader.connectFlagsByte.passwordFlag == 1) + { + txConnectPacket.passwordLength = htons(txConnectPacket.passwordLength); + txConnectPacket.usernameLength = htons(txConnectPacket.usernameLength); + } + txConnectPacket.clientIDLength = htons(txConnectPacket.clientIDLength); + + // Clear all pending transmissions first + mqttTxFlags.All = 0; + + // Now mark the Connect for sending + mqttTxFlags.newTxConnectPacket = 1; + mqttState = CONNECTING; + + return true; +} + + +bool MQTT_CreatePublishPacket(mqttPublishPacket *newPublishPacket) +{ + bool ret; + + ret = false; + + memset(&txPublishPacket, 0, sizeof (txPublishPacket)); + + if (mqttState == CONNECTED) + { + // Fixed header + txPublishPacket.publishHeaderFlags.controlPacketType = PUBLISH; + txPublishPacket.publishHeaderFlags.duplicate = newPublishPacket->publishHeaderFlags.duplicate; + txPublishPacket.publishHeaderFlags.qos = newPublishPacket->publishHeaderFlags.qos; + if ((txPublishPacket.publishHeaderFlags.qos == 0) && (txPublishPacket.publishHeaderFlags.duplicate != 0)) + { + txPublishPacket.publishHeaderFlags.duplicate = 0; + } + txPublishPacket.publishHeaderFlags.retain = newPublishPacket->publishHeaderFlags.retain; + + // Variable header + txPublishPacket.topic = newPublishPacket->topic; + txPublishPacket.topicLength = strlen((char*) newPublishPacket->topic); + if (newPublishPacket->publishHeaderFlags.qos > 0) + { + txPublishPacket.packetIdentifierLSB = newPublishPacket->packetIdentifierLSB; + txPublishPacket.packetIdentifierMSB = newPublishPacket->packetIdentifierMSB; + txPublishPacket.totalLength += sizeof (txPublishPacket.packetIdentifierLSB) + sizeof (txPublishPacket.packetIdentifierMSB); + } + + // Payload + txPublishPacket.payload = newPublishPacket->payload; + txPublishPacket.payloadLength = newPublishPacket->payloadLength; + txPublishPacket.totalLength += sizeof (txPublishPacket.topicLength) + txPublishPacket.topicLength + txPublishPacket.payloadLength; + txPublishPacket.topicLength = htons(txPublishPacket.topicLength); + + mqttTxFlags.newTxPublishPacket = 1; + ret = true; + } + return ret; +} + + +bool MQTT_CreateSubscribePacket(mqttSubscribePacket *newSubscribePacket) +{ + bool ret; + uint8_t topicCount = 0; + + ret = false; + + // The library is capable of handling only one SUBSCRIBE request at a time. + // A new SUBSCRIBE packet can be created only after reception of SUBACK for + // the previous SUBSCRIBE packet has been received. This condition is + // checked by checking the value of newRxSubackPacket flag. + if (mqttState == CONNECTED && mqttRxFlags.newRxSubackPacket == 0) + { + memset(&txSubscribePacket, 0, sizeof (txSubscribePacket)); + + // Fixed header + // MQTT-3.8.1-1: Bits 3,2,1,0 of fixed header MUST be set as 0010, else Server MUST treat as malformed + txSubscribePacket.subscribeHeaderFlags.controlPacketType = SUBSCRIBE; + txSubscribePacket.subscribeHeaderFlags.duplicate = 0; + txSubscribePacket.subscribeHeaderFlags.qos = 1; + txSubscribePacket.subscribeHeaderFlags.retain = 0; + + // Variable header + txSubscribePacket.packetIdentifierLSB = newSubscribePacket->packetIdentifierLSB; + txSubscribePacket.packetIdentifierMSB = newSubscribePacket->packetIdentifierMSB; + + // Payload + for (topicCount = 0; topicCount < NUM_TOPICS_SUBSCRIBE; topicCount++) + { + txSubscribePacket.subscribePayload[topicCount].topicLength = htons(newSubscribePacket->subscribePayload[topicCount].topicLength); + txSubscribePacket.subscribePayload[topicCount].topic = newSubscribePacket->subscribePayload[topicCount].topic; + txSubscribePacket.subscribePayload[topicCount].requestedQoS = newSubscribePacket->subscribePayload[topicCount].requestedQoS; + txSubscribePacket.totalLength += sizeof (txSubscribePacket.subscribePayload[topicCount].topicLength) + ntohs(txSubscribePacket.subscribePayload[topicCount].topicLength) + + sizeof (txSubscribePacket.subscribePayload[topicCount].requestedQoS); + } + + // The totalLength field is not essentially a part of the SUBSCRIBE + // packet. It is used for calculation of the remaining length field. + txSubscribePacket.totalLength += sizeof (txSubscribePacket.packetIdentifierLSB) + sizeof (txSubscribePacket.packetIdentifierMSB); + + mqttTxFlags.newTxSubscribePacket = 1; + ret = true; + } + return ret; +} + +bool MQTT_CreateUnsubscribePacket(mqttUnsubscribePacket *newUnsubscribePacket) +{ + bool ret; + uint8_t topicCount = 0; + + ret = false; + + // The library is capable of handling only one UNSUBSCRIBE request at a time. + // A new UNSUBSCRIBE packet can be created only after reception of UNSUBACK for + // the previous UNSUBSCRIBE packet has been received. This condition is + // checked by checking the value of newRxUnubackPacket flag. + if (mqttState == CONNECTED && mqttRxFlags.newRxUnsubackPacket == 0) + { + memset(&txUnsubscribePacket, 0, sizeof (txUnsubscribePacket)); + + // Fixed header + // MQTT-3.8.1-1: Bits 3,2,1,0 of fixed header MUST be set as 0010, else Server MUST treat as malformed + txUnsubscribePacket.unsubscribeHeaderFlags.controlPacketType = UNSUBSCRIBE; + txUnsubscribePacket.unsubscribeHeaderFlags.duplicate = 0; + txUnsubscribePacket.unsubscribeHeaderFlags.qos = 1; + txUnsubscribePacket.unsubscribeHeaderFlags.retain = 0; + + // Variable header + txUnsubscribePacket.packetIdentifierLSB = newUnsubscribePacket->packetIdentifierLSB; + txUnsubscribePacket.packetIdentifierMSB = newUnsubscribePacket->packetIdentifierMSB; + + // Payload + for (topicCount = 0; topicCount < NUM_TOPICS_UNSUBSCRIBE; topicCount++) + { + txUnsubscribePacket.unsubscribePayload[topicCount].topicLength = htons(newUnsubscribePacket->unsubscribePayload[topicCount].topicLength); + txUnsubscribePacket.unsubscribePayload[topicCount].topic = newUnsubscribePacket->unsubscribePayload[topicCount].topic; + txUnsubscribePacket.totalLength += sizeof (txUnsubscribePacket.unsubscribePayload[topicCount].topicLength) + ntohs(txUnsubscribePacket.unsubscribePayload[topicCount].topicLength); + } + + // The totalLength field is not essentially a part of the UNSUBSCRIBE + // packet. It is used for calculation of the remaining length field. + txUnsubscribePacket.totalLength += sizeof (txUnsubscribePacket.packetIdentifierLSB) + sizeof (txUnsubscribePacket.packetIdentifierMSB); + + mqttTxFlags.newTxUnsubscribePacket = 1; + ret = true; + } + return ret; +} + + +static bool mqttSendConnect(mqttContext *mqttConnectionPtr) +{ + bool ret = false; + + MQTT_ExchangeBufferInit(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff); + MQTT_ExchangeBufferInit(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff); + + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, (uint8_t*) & txConnectPacket.connectFixedHeaderFlags.All, sizeof (txConnectPacket.connectFixedHeaderFlags.All)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, (uint8_t*) txConnectPacket.remainingLength, mqttEncodeLength(txConnectPacket.totalLength, txConnectPacket.remainingLength)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, (uint8_t*) & txConnectPacket.connectVariableHeader, sizeof (txConnectPacket.connectVariableHeader)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, (uint8_t*) & txConnectPacket.clientIDLength, sizeof (txConnectPacket.clientIDLength)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, (uint8_t*) txConnectPacket.clientID, strlen((char*) txConnectPacket.clientID)); + + if ((txConnectPacket.passwordLength > 0) || (txConnectPacket.usernameLength > 0)) + { + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, (uint8_t*) & txConnectPacket.usernameLength, sizeof (txConnectPacket.usernameLength)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, (uint8_t*) txConnectPacket.username, ntohs(txConnectPacket.usernameLength)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, (uint8_t*) & txConnectPacket.passwordLength, sizeof (txConnectPacket.passwordLength)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, (uint8_t*) txConnectPacket.password, ntohs(txConnectPacket.passwordLength)); + } + + ret = MQTT_Send(mqttConnectionPtr); + + if (ret == true) + { + mqttTxFlags.newTxConnectPacket = 0; + } + return ret; +} + + +static bool mqttSendPublish(mqttContext *mqttConnectionPtr) +{ + bool ret = false; + + MQTT_ExchangeBufferInit(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff); + MQTT_ExchangeBufferInit(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff); + + // Copy the txPublishPacket data in TCP Tx buffer + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, &txPublishPacket.publishHeaderFlags.All, sizeof (txPublishPacket.publishHeaderFlags.All)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, txPublishPacket.remainingLength, mqttEncodeLength(txPublishPacket.totalLength, txPublishPacket.remainingLength)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, (uint8_t*) & txPublishPacket.topicLength, sizeof (txPublishPacket.topicLength)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, txPublishPacket.topic, ntohs(txPublishPacket.topicLength)); + + if (txPublishPacket.publishHeaderFlags.qos == 1) + { + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, &txPublishPacket.packetIdentifierMSB, sizeof (txPublishPacket.packetIdentifierMSB)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, &txPublishPacket.packetIdentifierLSB, sizeof (txPublishPacket.packetIdentifierLSB)); + } + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, txPublishPacket.payload, txPublishPacket.payloadLength); + + // Function call to TCP_Send() is abstracted + if (mqttTxFlags.newTxPublishPacket == 1 || txPublishPacket.publishHeaderFlags.duplicate == 1) + { + ret = MQTT_Send(mqttConnectionPtr); + + if (ret == true) + { + mqttTxFlags.newTxPublishPacket = 0; + if (txPublishPacket.publishHeaderFlags.qos == 1) + { + mqttRxFlags.newRxPubackPacket = 1; + } + } + } + return ret; +} + + +static uint8_t mqttEncodeLength(uint16_t length, uint8_t *output) +{ + uint8_t encodedByte; + uint8_t i = 0; + + do + { + encodedByte = length % 128; + length /= 128; + // if there are more data to encode, set the top bit of this byte + if (length > 0) + { + encodedByte |= 0x80; + } + output[i] = encodedByte; + i++; + } while (length); + + return i; /* Return the amount of bytes used */ +} + + +static uint32_t mqttDecodeLength(uint8_t *encodedData) +{ + uint32_t multiplier; + uint32_t value; + uint32_t i; + + multiplier = 1; + value = 0; + + for (i = 0; i == 0 || (encodedData[i - 1] & 0x80); i++) + { + value += (encodedData[i] & 0x7f) * multiplier; + multiplier *= 0x80; + } + + return value; +} + + +mqttCurrentState MQTT_Disconnect(mqttContext* connectionInfo) +{ + if ((mqttState == CONNECTED) || (mqttState == WAITFORCONNACK)) + { + timeout_delete(&pingreqTimer); + mqttSendDisconnect(connectionInfo); + mqttState = DISCONNECTED; + } + + return mqttState; +} + +static void mqttProcessPingresp(mqttContext *mqttConnectionPtr) +{ + mqttPingPacket txPingrespPacket; + + memset(&txPingrespPacket, 0, sizeof (txPingrespPacket)); + + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &txPingrespPacket.pingFixedHeader.All, sizeof (txPingrespPacket.pingFixedHeader.All)); + // Reload timeout for keepAliveTimer + // The timeout should be reloaded only if the keepAliveTimer is set + // to a non-zero value. + if (ntohs(txConnectPacket.connectVariableHeader.keepAliveTimer) != 0) + { + mqttTxFlags.newTxPingreqPacket = 1; + } + // Re-initialise the RX exchange buffer to be able to process the + // next incoming MQTT packet + MQTT_ExchangeBufferInit(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff); +} + + +static mqttCurrentState mqttProcessSuback(mqttContext *mqttConnectionPtr) +{ + mqttCurrentState ret; + mqttSubackPacket rxSubackPacket; + uint8_t topicNumbers = 0; + uint8_t topicCount = 0; + + memset(&rxSubackPacket, 0, sizeof (rxSubackPacket)); + + ret = CONNECTED; + + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &rxSubackPacket.subscribeAckHeaderFlags.All, sizeof (rxSubackPacket.subscribeAckHeaderFlags.All)); + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &rxSubackPacket.remainingLength[0], sizeof (rxSubackPacket.remainingLength[0])); + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &rxSubackPacket.packetIdentifierMSB, sizeof (rxSubackPacket.packetIdentifierMSB)); + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &rxSubackPacket.packetIdentifierLSB, sizeof (rxSubackPacket.packetIdentifierLSB)); + // The packetIdentifier of the SUBACK packet must match the + // packetIdentifier of the SUBSCRIBE packet. Since the library allows + // the application to create only one SUBSCRIBE packet at a time, + // checking this condition becomes simple. + if ((rxSubackPacket.packetIdentifierLSB != txSubscribePacket.packetIdentifierLSB) || (rxSubackPacket.packetIdentifierMSB != txSubscribePacket.packetIdentifierMSB)) { + // Change state appropriately + ret = DISCONNECTED; + } + else + { + // ToDo remove hardcoding + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, rxSubackPacket.returnCode, 1); + // ToDo This calculation needs to be modified after removing + // hardcoding + topicNumbers = (sizeof (rxSubackPacket.returnCode) / sizeof (rxSubackPacket.returnCode[0])); + for (topicCount = 0; topicCount < topicNumbers; topicCount++) + { + if (rxSubackPacket.returnCode[topicCount] == SUBSCRIBE_FAILURE) + { + // Change state appropriately + ret = DISCONNECTED; + break; + } + } + } + + mqttRxFlags.newRxSubackPacket = 0; + // Re-initialize the RX exchange buffer to be able to process the + // next incoming MQTT packet + MQTT_ExchangeBufferInit(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff); + return ret; +} + + +static mqttCurrentState mqttProcessUnsuback(mqttContext *mqttConnectionPtr) +{ + mqttCurrentState ret; + mqttUnsubackPacket rxUnsubackPacket; + + memset(&rxUnsubackPacket, 0, sizeof (rxUnsubackPacket)); + + ret = CONNECTED; + + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &rxUnsubackPacket.unsubAckHeaderFlags.All, sizeof (rxUnsubackPacket.unsubAckHeaderFlags.All)); + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &rxUnsubackPacket.remainingLength, sizeof (rxUnsubackPacket.remainingLength)); + if(rxUnsubackPacket.remainingLength != 2) + { + // The length of the variable header for UNSUBACK Packet has to be 2 + // according to MQTT RFC, section 3.11.1. + ret = DISCONNECTED; + } + else + { + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &rxUnsubackPacket.packetIdentifierMSB, sizeof (rxUnsubackPacket.packetIdentifierMSB)); + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &rxUnsubackPacket.packetIdentifierLSB, sizeof (rxUnsubackPacket.packetIdentifierLSB)); + // The packetIdentifier of the UNSUBACK packet must match the + // packetIdentifier of the UNSUBSCRIBE packet. Since the library allows + // the application to create only one UNSUBSCRIBE packet at a time, + // checking this condition becomes simple. + if ((rxUnsubackPacket.packetIdentifierLSB != txUnsubscribePacket.packetIdentifierLSB) || (rxUnsubackPacket.packetIdentifierMSB != txUnsubscribePacket.packetIdentifierMSB)) + { + // Change state appropriately + ret = DISCONNECTED; + } + } + + mqttRxFlags.newRxUnsubackPacket = 0; + // Re-initialize the RX exchange buffer to be able to process the + // next incoming MQTT packet + MQTT_ExchangeBufferInit(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff); + return ret; +} + + +static mqttCurrentState mqttProcessPublish(mqttContext *mqttConnectionPtr) +{ + mqttCurrentState ret; + uint32_t decodedLength; + mqttPublishPacket rxPublishPacket; + imqttHandlePublishDataFuncPtr publishRecvHandler; + uint8_t remainingLengthIndex; + + uint8_t mqttTopic[SUBSCRIBE_TOPIC_SIZE]; + uint8_t mqttPayload[PAYLOAD_SIZE]; + + decodedLength = 0; + + memset(&rxPublishPacket, 0, sizeof (rxPublishPacket)); + memset(mqttTopic, 0, sizeof (mqttTopic)); + memset(mqttPayload, 0, sizeof (mqttPayload)); + + // Fixed header + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &rxPublishPacket.publishHeaderFlags.All, sizeof (rxPublishPacket.publishHeaderFlags.All)); + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &rxPublishPacket.remainingLength[0], sizeof (rxPublishPacket.remainingLength[0])); + for (remainingLengthIndex = 1; rxPublishPacket.remainingLength[remainingLengthIndex - 1] & 0x80 && remainingLengthIndex < sizeof (rxPublishPacket.remainingLength); remainingLengthIndex++) + { + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &rxPublishPacket.remainingLength[remainingLengthIndex], 1); + } + decodedLength = mqttDecodeLength(&rxPublishPacket.remainingLength[0]); + + // Variable header + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, (uint8_t*) & rxPublishPacket.topicLength, sizeof (rxPublishPacket.topicLength)); + decodedLength -= sizeof (rxPublishPacket.topicLength); + rxPublishPacket.topic = (uint8_t*) mqttTopic; + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, rxPublishPacket.topic, ntohs(rxPublishPacket.topicLength)); + decodedLength -= ntohs(rxPublishPacket.topicLength); + + // Payload + rxPublishPacket.payload = (uint8_t*) mqttPayload; + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, rxPublishPacket.payload, decodedLength); + + // Send publish packet information to the application + publishRecvHandler = MQTT_GetPublishReceptionCallback(); + if(publishRecvHandler) + { + publishRecvHandler(rxPublishPacket.topic, rxPublishPacket.payload); + } + + // Re-initialize the RX exchange buffer to be able to process the + // next incoming MQTT packet + MQTT_ExchangeBufferInit(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff); + ret = CONNECTED; + return ret; +} + + +static void mqttProcessPuback(mqttContext *mqttConnectionPtr) +{ + mqttPubackPacket rxPubackPacket; + memset(&rxPubackPacket, 0, sizeof (rxPubackPacket)); + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, (uint8_t*) & rxPubackPacket.pubackFixedHeader, sizeof (rxPubackPacket.pubackFixedHeader)); + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &rxPubackPacket.remainingLength, sizeof (rxPubackPacket.remainingLength)); + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &rxPubackPacket.packetIdentifierMSB, sizeof (rxPubackPacket.packetIdentifierMSB)); + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &rxPubackPacket.packetIdentifierLSB, sizeof (rxPubackPacket.packetIdentifierLSB)); + + if (rxPubackPacket.packetIdentifierLSB == txPublishPacket.packetIdentifierLSB && rxPubackPacket.packetIdentifierMSB == txPublishPacket.packetIdentifierMSB) + { + mqttRxFlags.newRxPubackPacket = 0; + } +} + + +mqttHandlerState_t MQTT_GetLastHandlerState(void) +{ + return lastMQTTHandlerState; +} + + +mqttHeaderFlags MQTT_GetLastReceivedPacketHeader(void) +{ + return lastReceivedPacketHeader; +} + + +uint16_t MQTT_GetLastReceivedLength(void) +{ + return lastReceivedLength; +} + + +mqttCurrentState MQTT_TransmissionHandler(mqttContext *mqttConnectionPtr) +{ + bool packetSent = false; + uint8_t getSetFlag = 0; + uint16_t keepAliveTimeout = 0; + lastMQTTHandlerState = MQTT_NO_ERROR; + + switch (mqttState) + { + case CONNECTING: + case DISCONNECTED: + if (mqttTxFlags.newTxConnectPacket == 1) + { + packetSent = mqttSendConnect(mqttConnectionPtr); + + if (packetSent == true) + { + lastMQTTHandlerState = MQTT_SEND_SUCCESS; + } + else + { + lastMQTTHandlerState = MQTT_SEND_ERROR; + } + } + if (packetSent == true) + { + // The timeout API names are different in MCC foundation + // services timeout driver and START timeout driver + timeout_create(&connackTimer, WAITFORCONNACK_TIMEOUT); + mqttState = WAITFORCONNACK; + mqttTimeouts.connackTimeOutOccured = 0; + } + break; + + case CONNECTED: + // ToDo Find out ways to improve this logic + if (mqttTxFlags.All > 0) + { + while ((mqttTxFlags.All & (MQTT_TX_PACKET_DECISION_CONSTANT << getSetFlag)) == 0) + { + getSetFlag++; + } + mqttConnectTxSubstate = (MQTT_TX_PACKET_DECISION_CONSTANT << getSetFlag); + switch (mqttConnectTxSubstate) + { + case SENDPINGREQ: + if (mqttTimeouts.pingreqTimeoutOccured == 1) + { + // Change state for the next timeout to occur correctly + mqttTimeouts.pingreqTimeoutOccured = 0; + // Periodic sending of PINGREQ packet + if (mqttSendPingreq(mqttConnectionPtr)) + { + lastMQTTHandlerState = MQTT_SEND_SUCCESS; + } + } + break; + case SENDPUBLISH: + timeout_delete(&pingreqTimer); + packetSent = mqttSendPublish(mqttConnectionPtr); + if (packetSent == true) + { + lastMQTTHandlerState = MQTT_SEND_SUCCESS; + keepAliveTimeout = ntohs(txConnectPacket.connectVariableHeader.keepAliveTimer); + if (txConnectPacket.connectVariableHeader.keepAliveTimer > 0) + { + timeout_create(&pingreqTimer, ((keepAliveTimeout - KEEP_ALIVE_CALCULATION_CONSTANT) * SECONDS)); + } + } + else + { + mqttState = DISCONNECTED; + } + break; + case SENDSUBSCRIBE: + if (mqttSendSubscribe(mqttConnectionPtr)) + { + lastMQTTHandlerState = MQTT_SEND_SUCCESS; + } + keepAliveTimeout = ntohs(txConnectPacket.connectVariableHeader.keepAliveTimer); + if (txConnectPacket.connectVariableHeader.keepAliveTimer > 0) + { + timeout_create(&pingreqTimer, ((keepAliveTimeout - KEEP_ALIVE_CALCULATION_CONSTANT) * SECONDS)); + } + break; + case SENDUNSUBSCRIBE: + if (mqttSendUnsubscribe(mqttConnectionPtr)) + { + lastMQTTHandlerState = MQTT_SEND_SUCCESS; + } + keepAliveTimeout = ntohs(txConnectPacket.connectVariableHeader.keepAliveTimer); + if (txConnectPacket.connectVariableHeader.keepAliveTimer > 0) + { + timeout_create(&pingreqTimer, ((keepAliveTimeout - KEEP_ALIVE_CALCULATION_CONSTANT) * SECONDS)); + } + break; + default: + break; + } + } + break; + default: + // Go to DISCONNECTED? + break; + } + return mqttState; +} + + +mqttCurrentState MQTT_ReceptionHandler(mqttContext *mqttConnectionPtr) +{ + uint16_t keepAliveTimeout; + mqttHeaderFlags receivedPacketHeader; + lastMQTTHandlerState = MQTT_NO_ERROR; + + keepAliveTimeout = 0; + receivedPacketHeader.All = 0; + + if(mqttTimeouts.pingrespTimeoutOccured == 1 || mqttTimeouts.subackTimeoutOccured == 1 || mqttTimeouts.unsubackTimeoutOccured == 1) + { + // This implies that expected response has not been received from + // the server in a reasonable period of time (currently set to 30s). + // This is treated as a protocol violation. The client therefore + // will close the Network Connection (MQTT RFC, section 4.8). + mqttState = DISCONNECTED; + MQTT_Close(mqttConnectionPtr); + } + // If nothing to process + if (mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff.dataLength == 0) + return mqttState; + + switch (mqttState) + { + case WAITFORCONNACK: + keepAliveTimeout = ntohs(txConnectPacket.connectVariableHeader.keepAliveTimer); + if (mqttTimeouts.connackTimeOutOccured == 0) + { + // The timeout API names are different in MCC foundation + // services timeout driver and START timeout driver + timeout_delete(&connackTimer); + // Check the type of packet + uint16_t len = MQTT_ExchangeBufferPeek(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &receivedPacketHeader.All, sizeof (receivedPacketHeader.All)); + + if (receivedPacketHeader.controlPacketType == CONNACK) + { + mqttState = mqttProcessConnack(mqttConnectionPtr); + if (mqttState == CONNECTED) + { + if (keepAliveTimeout != 0) + { + // Send a PINGREQ packet after (keepAliveTimer - KEEP_ALIVE_CALCULATION_CONSTANT)s + // if keepAliveTime is non-zero + mqttTxFlags.newTxPingreqPacket = 1; + // The timeout API names are different in MCC foundation + // services timeout driver and START timeout driver + timeout_create(&pingreqTimer, ((keepAliveTimeout - KEEP_ALIVE_CALCULATION_CONSTANT) * SECONDS)); + } + lastMQTTHandlerState = MQTT_CONNACK; + } + else + { + lastMQTTHandlerState = MQTT_CONNACK_ERROR; + } + } + else + { + lastMQTTHandlerState = MQTT_INCORRECT_RESPONSE; + lastReceivedPacketHeader = receivedPacketHeader; + lastReceivedLength = len; + + //If the Client does not receive a CONNACK Packet from the Server within a reasonable amount of time, + //the Client SHOULD close the Network Connection. + mqttState = DISCONNECTED; + MQTT_Close(mqttConnectionPtr); + } + } + else + { + mqttState = DISCONNECTED; + MQTT_Close(mqttConnectionPtr); + + lastMQTTHandlerState = MQTT_CONNACK_TIMEOUT; + } + break; + + case CONNECTED: + // Check the type of packet + MQTT_ExchangeBufferPeek(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &receivedPacketHeader.All, sizeof (receivedPacketHeader.All)); + + switch (receivedPacketHeader.controlPacketType) + { + case PINGRESP: + // PINGRESP received + if ((mqttRxFlags.newRxPingrespPacket == 1) && (mqttTimeouts.pingrespTimeoutOccured == 0)) + { + timeout_delete(&pingrespTimer); + mqttProcessPingresp(mqttConnectionPtr); + } + break; + case SUBACK: + // SUBACK received + if ((mqttRxFlags.newRxSubackPacket == 1) && (mqttTimeouts.subackTimeoutOccured == 0)) + { + timeout_delete(&subackTimer); + mqttState = mqttProcessSuback(mqttConnectionPtr); + } + break; + case UNSUBACK: + // UNSUBACK received + if ((mqttRxFlags.newRxUnsubackPacket == 1) && (mqttTimeouts.unsubackTimeoutOccured == 0)) + { + timeout_delete(&unsubackTimer); + mqttState = mqttProcessUnsuback(mqttConnectionPtr); + } + break; + case PUBLISH: + // PUBLISH received + mqttProcessPublish(mqttConnectionPtr); + break; + case PUBACK: + mqttProcessPuback(mqttConnectionPtr); + break; + default: + break; + } + break; + + case CONNECTING: + break; + + default: + mqttState = MQTT_UNKNOWN_RECEIVE_STATE; + break; + } + + return mqttState; +} + + +static bool mqttSendSubscribe(mqttContext *mqttConnectionPtr) +{ + bool ret = false; + uint8_t topicCount = 0; + + MQTT_ExchangeBufferInit(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff); + MQTT_ExchangeBufferInit(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff); + + // Copy the txSubscribePacket data in TCP Tx buffer + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, &txSubscribePacket.subscribeHeaderFlags.All, sizeof (txSubscribePacket.subscribeHeaderFlags.All)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, txSubscribePacket.remainingLength, mqttEncodeLength(txSubscribePacket.totalLength, txSubscribePacket.remainingLength)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, &txSubscribePacket.packetIdentifierMSB, sizeof (txSubscribePacket.packetIdentifierMSB)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, &txSubscribePacket.packetIdentifierLSB, sizeof (txSubscribePacket.packetIdentifierLSB)); + + for (topicCount = 0; topicCount < NUM_TOPICS_SUBSCRIBE; topicCount++) + { + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, (uint8_t*) & txSubscribePacket.subscribePayload[topicCount].topicLength, sizeof (txSubscribePacket.subscribePayload[topicCount].topicLength)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, txSubscribePacket.subscribePayload[topicCount].topic, ntohs(txSubscribePacket.subscribePayload[topicCount].topicLength)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, &txSubscribePacket.subscribePayload[topicCount].requestedQoS, sizeof (txSubscribePacket.subscribePayload[topicCount].requestedQoS)); + } + + ret = MQTT_Send(mqttConnectionPtr); + + if (ret == true) + { + mqttTxFlags.newTxSubscribePacket = 0; + mqttRxFlags.newRxSubackPacket = 1; + + //The timeout API names are different in MCC foundation + //services timeout driver and START timeout driver + mqttTimeouts.subackTimeoutOccured = 0; + timeout_create(&subackTimer, (WAITFORSUBACK_TIMEOUT)); + } + + return ret; +} + + +static bool mqttSendUnsubscribe(mqttContext *mqttConnectionPtr) +{ + bool ret = false; + uint8_t topicCount = 0; + + MQTT_ExchangeBufferInit(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff); + MQTT_ExchangeBufferInit(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff); + + // Copy the txUnsubscribePacket data in TCP Tx buffer + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, &txUnsubscribePacket.unsubscribeHeaderFlags.All, sizeof(txUnsubscribePacket.unsubscribeHeaderFlags.All)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, txUnsubscribePacket.remainingLength, mqttEncodeLength(txUnsubscribePacket.totalLength, txUnsubscribePacket.remainingLength)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, &txUnsubscribePacket.packetIdentifierMSB, sizeof(txUnsubscribePacket.packetIdentifierMSB)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, &txUnsubscribePacket.packetIdentifierLSB, sizeof(txUnsubscribePacket.packetIdentifierLSB)); + + for (topicCount = 0; topicCount < NUM_TOPICS_UNSUBSCRIBE; topicCount++) + { + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, (uint8_t*)&txUnsubscribePacket.unsubscribePayload[topicCount].topicLength, sizeof(txUnsubscribePacket.unsubscribePayload[topicCount].topicLength)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, txUnsubscribePacket.unsubscribePayload[topicCount].topic, ntohs(txUnsubscribePacket.unsubscribePayload[topicCount].topicLength)); + } + + ret = MQTT_Send(mqttConnectionPtr); + + if (ret == true) + { + mqttTxFlags.newTxUnsubscribePacket = 0; + mqttRxFlags.newRxUnsubackPacket = 1; + + //The timeout API names are different in MCC foundation + //services timeout driver and START timeout driver + mqttTimeouts.unsubackTimeoutOccured = 0; + timeout_create(&unsubackTimer, (WAITFORUNSUBACK_TIMEOUT)); + } + + return ret; +} + + +static bool mqttSendPingreq(mqttContext *mqttConnectionPtr) +{ + bool ret; + mqttPingPacket txPingreqPacket; + + ret = false; + memset(&txPingreqPacket, 0, sizeof (txPingreqPacket)); + MQTT_ExchangeBufferInit(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff); + MQTT_ExchangeBufferInit(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff); + + // Send a PINGREQ packet here + txPingreqPacket.pingFixedHeader.controlPacketType = PINGREQ; + txPingreqPacket.pingFixedHeader.duplicate = 0; + txPingreqPacket.pingFixedHeader.qos = 0; + txPingreqPacket.pingFixedHeader.retain = 0; + txPingreqPacket.remainingLength = 0; + + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, &txPingreqPacket.pingFixedHeader.All, sizeof (txPingreqPacket.pingFixedHeader.All)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, &txPingreqPacket.remainingLength, sizeof (txPingreqPacket.remainingLength)); + + ret = MQTT_Send(mqttConnectionPtr); + + if (ret == true) + { + mqttTxFlags.newTxPingreqPacket = 0; + // Expect a PINGRESP packet + mqttRxFlags.newRxPingrespPacket = 1; + // The client expects the server to send a PINGRESP within + // keepAliveTimer value. + + //The timeout API names are different in MCC foundation + //services timeout driver and START timeout driver + timeout_create(&pingrespTimer, (WAITFORPINGRESP_TIMEOUT)); + } + + return ret; +} + + +static bool mqttSendDisconnect(mqttContext *mqttConnectionPtr) +{ + bool ret = false; + mqttDisconnectPacket txDisconnectPacket; + + memset(&txDisconnectPacket, 0, sizeof (txDisconnectPacket)); + MQTT_ExchangeBufferInit(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff); + MQTT_ExchangeBufferInit(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff); + + txDisconnectPacket.disconnectFixedHeader.controlPacketType = DISCONNECT; + txDisconnectPacket.disconnectFixedHeader.retain = 0; + txDisconnectPacket.disconnectFixedHeader.qos = 0; + txDisconnectPacket.disconnectFixedHeader.duplicate = 0; + + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, &txDisconnectPacket.disconnectFixedHeader.All, sizeof (txDisconnectPacket.disconnectFixedHeader.All)); + MQTT_ExchangeBufferWrite(&mqttConnectionPtr->mqttDataExchangeBuffers.txbuff, &txDisconnectPacket.remainingLength, sizeof (txDisconnectPacket.remainingLength)); + + ret = MQTT_Send(mqttConnectionPtr); + + if (ret == true) + { + mqttTxFlags.All = 0; + } + return ret; +} + + +static mqttCurrentState mqttProcessConnack(mqttContext *mqttConnectionPtr) +{ + mqttConnackPacket_t mqttConnackPacket; + + memset(&mqttConnackPacket, 0, sizeof (mqttConnackPacket)); + + // Check 1st (4) bytes in Rx MQTT Packet + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &mqttConnackPacket.connackFixedHeader.All, sizeof (mqttConnackPacket.connackFixedHeader.All)); + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &mqttConnackPacket.remainingLength, sizeof (mqttConnackPacket.remainingLength)); + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &mqttConnackPacket.connackVariableHeader.connackAcknowledgeFlags.All, sizeof (mqttConnackPacket.connackVariableHeader.connackAcknowledgeFlags.All)); + MQTT_ExchangeBufferRead(&mqttConnectionPtr->mqttDataExchangeBuffers.rxbuff, &mqttConnackPacket.connackVariableHeader.connackReturnCode, sizeof (mqttConnackPacket.connackVariableHeader.connackReturnCode)); + + if (mqttConnackPacket.connackVariableHeader.connackReturnCode == CONN_ACCEPTED) + { + return CONNECTED; + } + else + { + return DISCONNECTED; + } +} diff --git a/AVRIoT.X/mcc_generated_files/mqtt/mqtt_core/mqtt_core.h b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_core/mqtt_core.h new file mode 100644 index 0000000..311b1fb --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_core/mqtt_core.h @@ -0,0 +1,409 @@ +/* + \file mqtt_core.h + + \brief MQTT CORE source file. + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef MQTT_CORE_H +#define MQTT_CORE_H + +#include "../../config/mqtt_config.h" + +#if !defined(TCPIP_BSD) && !defined(TCPIP_LITE) +#error : This project uses TCPIP BSD / LITE. Please add "TCPIP_BSD" or "TCPIP_LITE" to toolchain symbols. +#endif + +#include +#include +#ifdef TCPIP_BSD +#include "../mqtt_comm_bsd/mqtt_comm_layer.h" +#include "../winc/socket/socket.h" +#elif TCPIP_LITE +#include "../mqtt_comm_tcpipLite/mqtt_comm_layer.h" +#include "network.h" +#endif + + +/********************Timeout for MQTT packets***********************/ + +#define WAITFORCONNACK_TIMEOUT (30 * SECONDS) +#define WAITFORPINGRESP_TIMEOUT (30 * SECONDS) +#define WAITFORSUBACK_TIMEOUT (30 * SECONDS) +#define WAITFORUNSUBACK_TIMEOUT (30 * SECONDS) + +/*******************Timeout for MQTT packets*(END)******************/ + +#pragma pack(push,1) + +/** \brief Basic MQTT states + * + * The application uses these states to manage state transitions in the MQTT Tx + * and Rx handlers. + */ +typedef enum +{ + DISCONNECTED = 0, + CONNECTING = 1, + WAITFORCONNACK = 2, + CONNECTED = 3, +} mqttCurrentState; + +/** \brief MQTT Control Packet types, as dictated by the MQTT standard + * + * The application uses these to determine the packet type of MQTT message. + */ +typedef enum +{ + RESERVED = 0, + CONNECT = 1, + CONNACK = 2, + PUBLISH = 3, + PUBACK = 4, + SUBSCRIBE = 8, + SUBACK = 9, + UNSUBSCRIBE = 10, + UNSUBACK = 11, + PINGREQ = 12, + PINGRESP = 13, + DISCONNECT = 14 +} mqttControlPacketType_t; + +// MQTT packet CONNACK return codes. These are defined in the MQTT documentation +// and indicate the success/ failure of establishing a connection with the +// broker. +typedef enum +{ + CONN_ACCEPTED = 0, + CONN_REFUSED_PROTOCOL_VER = 1, + CONN_REFUSED_ID_REJECTED = 2, + CONN_REFUSED_SERV_UNAVAILABLE = 3, + CONN_REFUSED_USERNAME_OR_PASSWORD = 4, + CONN_REFUSED_NOT_AUTHORIZED = 5 +} connectReturnCode; + +// MQTT SUBACK return codes are defined in MQTT documentation. The return code indicates the success/failure +// and QoS level in case of success. The order of return codes must match the order of Topic Filters. +typedef enum +{ + SUBSCRIBE_SUCCESS_QoS0 = 0x00, + SUBSCRIBE_SUCCESS_QoS1 = 0x01, + SUBSCRIBE_SUCCESS_QoS2 = 0x02, + SUBSCRIBE_FAILURE = 0x80, +} subscribeAckReturnCode; + +// MQTT handler return codes. Use to inform layer of current state of MQTT operation. +typedef enum +{ + MQTT_NO_ERROR = 0, + MQTT_CONNACK_TIMEOUT = 1, + MQTT_INCORRECT_RESPONSE = 2, + MQTT_CONNACK_ERROR = 3, + MQTT_CONNACK = 4, + MQTT_SEND_SUCCESS = 5, + MQTT_SEND_ERROR = 6, + MQTT_UNKNOWN_RECEIVE_STATE = 7, +}mqttHandlerState_t; +/** \brief MQTT Fixed header format + * + * These are used by the application to handle the fixed header section of MQTT + * control packet. + */ +typedef union +{ + uint8_t All; + struct + { + unsigned retain : 1; // Retain flag // byte0, bit0 + unsigned qos : 2; // Quality of Service flag // byte0, bits 1, 2 + unsigned duplicate : 1; // Duplicate delivery flag // byte0, bit3 + unsigned controlPacketType : 4; // MQTT Control Packet type // byte0, bits 4, 5, 6, 7 + }; +} mqttHeaderFlags; + + +/** \brief MQTT CONNECT packet + * + * This is used by the application to form a CONNECT packet. + */ +typedef struct +{ + // Fixed header + mqttHeaderFlags connectFixedHeaderFlags; + uint8_t remainingLength[4]; // Remaining length a part of fixed header + + struct + { + // Variable header + uint8_t protocolName[6]; + uint8_t protocolLevel; + union + { + uint8_t All; + struct + { + unsigned reserved : 1; // Reserved // bit0 + unsigned cleanSession : 1; // "0" = Store session, "1" = Start new session // bit1 + unsigned willFlag : 1; // "0" = Will message absent, "1" = Will message present // bit2 + unsigned willQoS : 2; // "00" = Will flag reset (0), QoS = 0 or Will flag set (1), QoS = 0 + // "01" = Will flag set (1), QoS = 1 + // "10" = Will flag set (1), QoS = 2 //bits 3, 4 + unsigned willRetain : 1; // Retain flag // bit5 + unsigned passwordFlag : 1; // "0" = Username absent, "1" = Username present // bit6 + unsigned usernameFlag : 1; // "0" = Password absent, "1" = Password present // bit7 + }; + } connectFlagsByte; + uint16_t keepAliveTimer; + } connectVariableHeader; + + // Payload + uint16_t clientIDLength; + uint8_t *clientID; +// uint16_t willTopicLength; +// uint8_t *willTopic; +// uint16_t willMessageLength; +// uint8_t *willMessage; + uint16_t usernameLength; + uint8_t *username; + uint16_t passwordLength; + uint8_t *password; + + // The variables defined in this section are not defined in the MQTT RFC as + // members of CONNECT packet but are required nevertheless for correct + // formatting of the CONNECT packet. + uint16_t totalLength; +} mqttConnectPacket; + +/** \brief MQTT CONNACK packet + * + * This is used by the application to process a CONNACK packet. + */ +typedef struct +{ + // Fixed header + mqttHeaderFlags connackFixedHeader; + uint8_t remainingLength; + + // Variable header + struct + { + union + { + uint8_t All; + struct + { + unsigned sessionPresent : 1; // "0" = Store session, "1" = Start new session // bit0 + unsigned reserved : 7; // Reserved // bits 1-7 + }connackFlagBits; + }connackAcknowledgeFlags; + connectReturnCode connackReturnCode; + } connackVariableHeader; + +} mqttConnackPacket_t; + +/** \brief MQTT PUBLISH packet + * + * This is used by the application to form and process a PUBLISH packet. + */ +typedef struct +{ + // Fixed header + mqttHeaderFlags publishHeaderFlags; + uint8_t remainingLength[4]; + + // Variable header + // Topic name + uint16_t topicLength; + uint8_t *topic; + // Packet identifier present only when QoS level = 1 or QoS level = 2 + uint8_t packetIdentifierLSB; + uint8_t packetIdentifierMSB; + + // Payload + uint8_t payloadLength; + uint8_t *payload; + + uint16_t totalLength; +} mqttPublishPacket; + +/** \brief MQTT PUBACK packet + * + * This is used by the application to process a PUBACK packet. + */ +typedef struct +{ + mqttHeaderFlags pubackFixedHeader; + uint8_t remainingLength; + uint8_t packetIdentifierLSB; + uint8_t packetIdentifierMSB; +}mqttPubackPacket; + + +/** \brief MQTT PING packet + * + * This is used by the application to form and process a PINGREQ/PINGRESP packet. + */ +typedef struct +{ + // Fixed header + mqttHeaderFlags pingFixedHeader; + uint8_t remainingLength; +} mqttPingPacket; + +/** \brief MQTT DISCONNECT packet + * + * This is used by the application to form and send a DISCONNECT packet. + */ + +typedef struct +{ + // Fixed Header + mqttHeaderFlags disconnectFixedHeader; + uint8_t remainingLength; +} mqttDisconnectPacket; + + +/** \brief MQTT SUBSCRIBE Payload format + * + * These are used by the application to handle the payload section of MQTT + * subscribe packet. + */ +typedef struct +{ + // Topic name + uint16_t topicLength; + uint8_t *topic; + // A valid SUBSCRIBE Packet should contain QoS level = 0 or QoS level = 1 or QoS level = 2 + uint8_t requestedQoS; +} mqttSubscribePayload; + +/** \brief MQTT SUBSCRIBE packet + * + * This is used by the application to form and send a SUBSCRIBE packet. + */ +typedef struct +{ + // Fixed header + mqttHeaderFlags subscribeHeaderFlags; + uint8_t remainingLength[4]; + + // Variable header + uint8_t packetIdentifierLSB; + uint8_t packetIdentifierMSB; + + // Payload + // The payload of a SUBSCRIBE packet MUST contain at least one Topic Filter / QoS pair. + mqttSubscribePayload subscribePayload[NUM_TOPICS_SUBSCRIBE]; + + uint16_t totalLength; +} mqttSubscribePacket; + +/** \brief MQTT SUBACK packet + * + * This is used by the application to process a SUBACK packet. + */ +typedef struct +{ + // Fixed header + mqttHeaderFlags subscribeAckHeaderFlags; + uint8_t remainingLength[4]; + + //variable header + uint8_t packetIdentifierMSB; + uint8_t packetIdentifierLSB; + + //payload + subscribeAckReturnCode returnCode[NUM_TOPICS_SUBSCRIBE]; +} mqttSubackPacket; + + + +/** \brief MQTT UNSUBSCRIBE Payload format + * + * These are used by the application to handle the payload section of MQTT + * unsubscribe packet. + */ +typedef struct +{ + // Topic name + uint16_t topicLength; + uint8_t *topic; +} mqttUnsubscribePayload; + + +/** \brief MQTT UNSUBSCRIBE packet + * + * This is used by the application to form and send an UNSUBSCRIBE packet. + */ +typedef struct +{ + // Fixed header + mqttHeaderFlags unsubscribeHeaderFlags; + uint8_t remainingLength[4]; + + // Variable header + uint8_t packetIdentifierLSB; + uint8_t packetIdentifierMSB; + + // Payload + // The payload of a UNSUBSCRIBE packet MUST contain at least one Topic Filter / QoS pair. + mqttUnsubscribePayload unsubscribePayload[NUM_TOPICS_UNSUBSCRIBE]; + + uint16_t totalLength; +} mqttUnsubscribePacket; + + +/** \brief MQTT UNSUBACK packet + * + * This is used by the application to process a UNSUBACK packet. + */ +typedef struct +{ + // Fixed header + mqttHeaderFlags unsubAckHeaderFlags; + uint8_t remainingLength; + + //variable header + uint8_t packetIdentifierMSB; + uint8_t packetIdentifierLSB; + +} mqttUnsubackPacket; + +#pragma pack(pop) + + +/***********************MQTT Client definitions*(END)**************************/ +bool MQTT_CreateConnectPacket(mqttConnectPacket *newConnectPacket); +bool MQTT_CreatePublishPacket(mqttPublishPacket *newPublishPacket); +bool MQTT_CreateSubscribePacket(mqttSubscribePacket *newSubscribePacket); +bool MQTT_CreateUnsubscribePacket(mqttUnsubscribePacket *newUnsubscribePacket); +void MQTT_initialiseState(void); +mqttCurrentState MQTT_Disconnect(mqttContext *mqttContextPtr); +mqttCurrentState MQTT_TransmissionHandler(mqttContext *mqttContextPtr); +mqttCurrentState MQTT_ReceptionHandler(mqttContext *mqttContextPtr); +mqttCurrentState MQTT_GetConnectionState(void); +mqttHandlerState_t MQTT_GetLastHandlerState(void); +mqttHeaderFlags MQTT_GetLastReceivedPacketHeader(void); +uint16_t MQTT_GetLastReceivedLength(void); +#endif /* MQTT_CORE_H */ + diff --git a/AVRIoT.X/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.c b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.c new file mode 100644 index 0000000..7b80144 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.c @@ -0,0 +1,94 @@ +/* + \file mqtt_exchange_buffer.c + + \brief MQTT buffer handling source file. + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ +#include "mqtt_exchange_buffer.h" + +void MQTT_ExchangeBufferInit(exchangeBuffer *buffer) +{ + buffer->currentLocation = buffer->start; + buffer->dataLength = 0; +} + +uint16_t MQTT_ExchangeBufferWrite(exchangeBuffer *buffer, uint8_t *data, uint16_t length) +{ + uint8_t *bend = buffer->start + buffer->bufferLength - 1; + uint8_t *dend = (buffer->currentLocation - buffer->start + buffer->dataLength) % buffer->bufferLength + buffer->start; + uint16_t i = 0; + + for (i = length; i > 0; i--) + { + if (dend > bend) + { + dend = buffer->start; + } + if (buffer->dataLength != 0 && dend == buffer->currentLocation) + { + break; + } + *dend = *data; + dend++; + data++; + buffer->dataLength++; + } + + return length; +} + +uint16_t MQTT_ExchangeBufferPeek(exchangeBuffer *buffer, uint8_t *data, uint16_t length) +{ + uint8_t *ptr = buffer->currentLocation; + uint8_t *bend = buffer->start + buffer->bufferLength - 1; + uint16_t i = 0; + + for (i = 0; i < length && i < buffer->dataLength; i++) + { + data[i] = ptr[i]; + if (ptr > bend) + { + ptr = buffer->start; + } + } + + return i; +} + +uint16_t MQTT_ExchangeBufferRead(exchangeBuffer *buffer, uint8_t *data, uint16_t length) +{ + uint8_t *bend = buffer->start + buffer->bufferLength - 1; + uint16_t i = 0; + + for (i = 0; i < length && buffer->dataLength > 0; i++) + { + data[i] = *buffer->currentLocation; + buffer->currentLocation++; + buffer->dataLength--; + if (buffer->currentLocation > bend) + { + buffer->currentLocation = buffer->start; + } + } + return i; +} diff --git a/AVRIoT.X/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.h b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.h new file mode 100644 index 0000000..ee81531 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.h @@ -0,0 +1,50 @@ + +/* + \file mqtt_exchange_buffer.h + + \brief MQTT buffer handling header file. + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include + +typedef struct +{ + uint8_t *start; + uint8_t *currentLocation; + uint16_t bufferLength; + uint16_t dataLength; +} exchangeBuffer; + + +typedef struct +{ + exchangeBuffer txbuff; + exchangeBuffer rxbuff; +} mqttBuffers; + + +void MQTT_ExchangeBufferInit(exchangeBuffer *buffer); +uint16_t MQTT_ExchangeBufferPeek(exchangeBuffer *buffer, uint8_t *data, uint16_t length); +uint16_t MQTT_ExchangeBufferWrite(exchangeBuffer *buffer, uint8_t *data, uint16_t length); +uint16_t MQTT_ExchangeBufferRead(exchangeBuffer *buffer, uint8_t *data, uint16_t length); diff --git a/AVRIoT.X/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.c b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.c new file mode 100644 index 0000000..b8a5e8b --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.c @@ -0,0 +1,61 @@ +/******************************************************************** + * + (c) [2018] Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR + * PURPOSE. + * + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + * WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + * BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + * FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + * ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + ************************************************************************* + * + * mqtt_packetTransfer_interface.c + * + * About: + * Interface layer between MQTT core and application. The aim of this file is + * provide information about the user application to the MQTT core while + * keeping the MQTT core independent of the details specified in the user + * application. + * + * + ******************************************************************************/ +#include +#include +#include "mqtt_packetTransfer_interface.h" + +/**********************MQTT Interface layer variables**************************/ + +/** \brief Publish handler function pointer instance. + * + * This information obtained is used by the MQTT core to send the PUBLISH message + * received for a particular subscribed topic to the application for further + * processing. + */imqttHandlePublishDataFuncPtr publishRecvCallback; +/*******************MQTT Interface layer variables*(END)***********************/ + +/**********************Function implementations********************************/ + +void MQTT_SetPublishReceptionCallback(imqttHandlePublishDataFuncPtr appPublishReceptionCallback) +{ + publishRecvCallback = appPublishReceptionCallback; +} + +imqttHandlePublishDataFuncPtr MQTT_GetPublishReceptionCallback(void) +{ + return publishRecvCallback; +} + + +/**********************Function implementations*(END)**************************/ diff --git a/AVRIoT.X/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.h b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.h new file mode 100644 index 0000000..bd64c70 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.h @@ -0,0 +1,64 @@ +/* + \file mqtt_packetTransfer_interface.h + + \brief MQTT Packet Transfer Interface header file. + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ +#ifndef MQTT_PACKET_TRANSFER_INTERFACE_H +#define MQTT_PACKET_TRANSFER_INTERFACE_H + +#include + +/*********************MQTT Interface layer definitions*************************/ +/** \brief Function pointer for interaction between the MQTT core and user + * application to transfer the information received as part of the published + * packet to the application. + **/ +typedef void (*imqttHandlePublishDataFuncPtr)(uint8_t *topic, uint8_t *payload); + +/*******************MQTT Interface layer definitions*(END)*********************/ + +/** \brief Set the publish reception handler information. + * + * This function is called by the user application to inform the MQTT core of + * the call back table defined to handle the received PUBLISH messages. + * + * @param appPublishReceptionCallback Instance of imqttHandlePublishDataFuncPtr + * to handle PUBLISH messages received for + * each topic. + */ +void MQTT_SetPublishReceptionCallback(imqttHandlePublishDataFuncPtr appPublishReceptionCallback); + +/** \brief Obtain the imqttHandlePublishDataFuncPtr callback information defined + * in the user application for processing messages received over the subscribed + * topic. + * + * Whenever a PUBLISH packet is received by the MQTT core, the publish handler + * returned by this function is called to process the PUBLISH packet. + * + * @return generic publish reception handler defined in the user application + */ +imqttHandlePublishDataFuncPtr MQTT_GetPublishReceptionCallback(void); + +#endif /* MQTT_PACKET_TRANSFER_INTERFACE_H */ + diff --git a/AVRIoT.X/mcc_generated_files/mqtt/mqtt_winc_adapter.c b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_winc_adapter.c new file mode 100644 index 0000000..2ac39eb --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_winc_adapter.c @@ -0,0 +1,847 @@ +/******************************************************************** + * + (c) [2018] Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR + * PURPOSE. + * + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + * WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + * BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + * FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + * ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + ************************************************************************* + * + * bsdWinc.c + * + * About: + * + * + ******************************************************************************/ +#include +#include +#include +#include +#include "mqtt_winc_adapter.h" + +#define MAX_SUPPORTED_SOCKETS 2 +/**********************BSD (WINC) Enumerator Translators ********************************/ +typedef enum +{ + WINC_AF_INET = 2, +}wincSupportedDomains_t; + +typedef enum +{ + WINC_STREAM = 1, + WINC_DGRAM = 2, +}wincSupportedTypes_t; + +typedef enum +{ + WINC_NON_TLS = 0, + WINC_TLS = 0x01, +}wincSupportedProtocol_t; + +typedef enum +{ + WINC_SOCK_ERR_NO_ERROR = 0, + WINC_SOCK_ERR_INVALID_ADDRESS = -1, + WINC_SOCK_ERR_ADDR_ALREADY_IN_USE = -2, + WINC_SOCK_ERR_MAX_TCP_SOCK = -3, + WINC_SOCK_ERR_MAX_UDP_SOCK = -4, + WINC_SOCK_ERR_INVALID_ARG = -6, + WINC_SOCK_ERR_MAX_LISTEN_SOCK = -7, + WINC_SOCK_ERR_INVALID = -9, + WINC_SOCK_ERR_ADDR_IS_REQUIRED = -11, + WINC_SOCK_ERR_CONN_ABORTED = -12, + WINC_SOCK_ERR_TIMEOUT = -13, + WINC_SOCK_ERR_BUFFER_FULL = -14, +}wincSocketResponses_t; + +typedef enum +{ + WINC_SO_SSL_BYPASS_X509_VERIF = 1, + WINC_SO_SSL_SNI = 2, + WINC_SO_SSL_ENABLE_SESSION_CACHING = 3, + WINC_SO_SSL_ENABLE_SNI_VALIDATION = 4, +}wincSupportedSockOptions; + +typedef enum +{ + WINC_SOL_SOCKET = 1, + WINC_SOL_SSL_SOCKET = 2, +}wincSupportedSockLevel; + +/*******************WINC specific socket address structure***************************/ +typedef struct { + uint16_t sa_family; //Socket address + uint8_t sa_data[14]; // Maximum size of all the different socket address structures. +}wincSupported_sockaddr; + +/**********************BSD (Private) Global Variables ********************************/ +static bsdErrno_t bsdErrorNumber; + +static packetReceptionHandler_t *packetRecvInfo; + +/**********************BSD (Private) Function Prototypes *****************************/ +static void bsd_setErrNo (bsdErrno_t errorNumber); + +/**********************BSD (Private) Function Implementations ************************/ +static void bsd_setErrNo (bsdErrno_t errorNumber) +{ + bsdErrorNumber = errorNumber; +} + +/**********************BSD (Public) Function Implementations **************************/ +bsdErrno_t BSD_GetErrNo(void) +{ + return bsdErrorNumber; +} + +packetReceptionHandler_t* getSocketInfo(uint8_t sock) +{ + uint8_t i = 0; + if (sock >= 0) + { + packetReceptionHandler_t *bsdSocketInfo = BSD_GetRecvHandlerTable(); + for(i = 0; i < MAX_SUPPORTED_SOCKETS; i++) + { + if(bsdSocketInfo) + { + if(*(bsdSocketInfo->socket) == sock) + { + return bsdSocketInfo; + } + } + bsdSocketInfo++; + } + } + return NULL; +} + +int BSD_socket(int domain, int type, int protocol) +{ + wincSupportedDomains_t wincDomain; + wincSupportedTypes_t wincType; + wincSupportedProtocol_t wincProtocol; + int8_t wincSocketReturn; + + switch ((bsdDomain_t)domain) + { + case PF_INET: + wincDomain = WINC_AF_INET; + break; + default: // Domain Not Implemented by WINC + bsd_setErrNo(EAFNOSUPPORT); + return BSD_ERROR; + } + + switch ((bsdTypes_t)type) + { + case BSD_SOCK_STREAM: + wincType = WINC_STREAM; + break; + case BSD_SOCK_DGRAM: + wincType = WINC_DGRAM; + break; + default: // Type Not Implemented by WINC + bsd_setErrNo(EAFNOSUPPORT); + return BSD_ERROR; + } + + switch ((wincSupportedProtocol_t)protocol) + { + case WINC_NON_TLS: + case WINC_TLS: + wincProtocol = protocol; + break; + default: // Protocol Not Implemented by WINC + bsd_setErrNo(EINVAL); + return BSD_ERROR; + } + + wincSocketReturn = socket((uint16_t)wincDomain, (uint8_t)wincType, (uint8_t)wincProtocol); + if (wincSocketReturn < 0) // WINC Socket Access Denied always returns -1 for failure to get socket + { + bsd_setErrNo(EACCES); + return BSD_ERROR; + } + + return wincSocketReturn; // >= 0 represents SUCCESS +} + +int BSD_connect(int socket, const struct bsd_sockaddr *name, socklen_t namelen) +{ + int returnValue = BSD_ERROR; + wincSocketResponses_t wincConnectReturn = WINC_SOCK_ERR_INVALID; + wincSupported_sockaddr winc_sockaddr; + + packetReceptionHandler_t *bsdSocket = getSocketInfo(socket); + if(!bsdSocket) + { + + } + else + { + winc_sockaddr.sa_family = name->sa_family; + memcpy(winc_sockaddr.sa_data, name->sa_data, sizeof(winc_sockaddr.sa_data)); + + if(winc_sockaddr.sa_family == PF_INET) + { + winc_sockaddr.sa_family = AF_INET; + wincConnectReturn = connect(socket, (struct sockaddr*)&winc_sockaddr, (uint8_t)namelen); + if(wincConnectReturn != WINC_SOCK_ERR_NO_ERROR) + { + + switch(wincConnectReturn) + { + case WINC_SOCK_ERR_INVALID_ARG: + if(socket < 0) + { + bsd_setErrNo(ENOTSOCK); + } + else if(name == NULL) + { + bsd_setErrNo(EADDRNOTAVAIL); + } + else if(namelen == 0) + { + bsd_setErrNo(EINVAL); + } else + { + bsd_setErrNo(ENOTSOCK); + } + break; + case WINC_SOCK_ERR_INVALID: + bsd_setErrNo(EIO); + break; + default: + break; + } + } + else + { + + bsdSocket->socketState = SOCKET_IN_PROGRESS; + returnValue = BSD_SUCCESS; + } + } + else + { + bsd_setErrNo(EAFNOSUPPORT); + } + } + return returnValue; +} + +void BSD_SetRecvHandlerTable(packetReceptionHandler_t *appRecvInfo) +{ + packetRecvInfo = appRecvInfo; +} + +packetReceptionHandler_t *BSD_GetRecvHandlerTable() +{ + return packetRecvInfo; +} + +int BSD_recv(int socket, const void *buf, size_t len, int flags) +{ + wincSocketResponses_t wincRecvReturn; + + if (flags != 0) + { // Flag Not Support by WINC implementation + bsd_setErrNo(EINVAL); + return BSD_ERROR; + } + + wincRecvReturn = recv((SOCKET)socket, (void*)buf, (uint16_t)len, (uint32_t)flags); + if(wincRecvReturn != WINC_SOCK_ERR_NO_ERROR) + { + switch(wincRecvReturn) + { + case WINC_SOCK_ERR_INVALID_ARG: + if(socket < 0) + { + + bsd_setErrNo(ENOTSOCK); + } + else if(buf == NULL) + { + + bsd_setErrNo(EFAULT); + } + else if(len == 0) + { + + bsd_setErrNo(EMSGSIZE); + } + else + { + + bsd_setErrNo(EINVAL); + } + break; + case WINC_SOCK_ERR_BUFFER_FULL: + + bsd_setErrNo(ENOBUFS); + break; + default: + + break; + } + return BSD_ERROR; + } + else + { + // The socket.c send() API only returns (0) to indicate No Error + // Current WINC implementation doesn't use returned value per BSD. + // debug_printGOOD("BSD: Recv Success"); + + // TODO: Number of Bytes received should be returned in correct implementation. + return BSD_SUCCESS; + } +} + +int BSD_close(int socket) +{ + wincSocketResponses_t wincCloseReturn; + + packetReceptionHandler_t* sock = getSocketInfo(socket); + if (sock != NULL) + { + sock->socketState = NOT_A_SOCKET; + } + + wincCloseReturn = close((SOCKET)socket); + + if (wincCloseReturn!= WINC_SOCK_ERR_NO_ERROR) + { + switch(wincCloseReturn) + { + case WINC_SOCK_ERR_INVALID_ARG: + bsd_setErrNo(EBADF); + break; + case WINC_SOCK_ERR_INVALID: + bsd_setErrNo(EIO); + break; + default: + break; + } + return BSD_ERROR; + } + else + { + return BSD_SUCCESS; + } +} + +uint32_t BSD_htonl(uint32_t hostlong) +{ + return _htonl(hostlong); +} + +uint16_t BSD_htons(uint16_t hostshort) +{ + return _htons(hostshort); +} + +uint32_t BSD_ntohl(uint32_t netlong) +{ + return _ntohl(netlong); +} + +uint16_t BSD_ntohs(uint16_t netshort) +{ + return _ntohs(netshort); +} + +int BSD_bind(int socket, const struct bsd_sockaddr *addr, socklen_t addrlen) +{ + wincSocketResponses_t wincBindReturn; + static wincSupported_sockaddr winc_sockaddr; + + winc_sockaddr.sa_family = addr->sa_family; + memcpy((void*)winc_sockaddr.sa_data, (const void *)addr->sa_data, sizeof(winc_sockaddr.sa_data)); + + switch(winc_sockaddr.sa_family) + { + case PF_INET: + winc_sockaddr.sa_family = AF_INET; + wincBindReturn = bind((int8_t)socket, (struct sockaddr*)&winc_sockaddr, (uint8_t)addrlen); + break; + default: //Address family not supported by WINC + bsd_setErrNo(EAFNOSUPPORT); + return BSD_ERROR; + } + + if (wincBindReturn != WINC_SOCK_ERR_NO_ERROR) + { + switch(wincBindReturn) + { + case WINC_SOCK_ERR_INVALID_ARG: + if(socket < 0) + { + bsd_setErrNo(ENOTSOCK); + } + else if(addr != NULL) + { + bsd_setErrNo(EFAULT); + } + else if(addrlen == 0) + { + bsd_setErrNo(EINVAL); + } + break; + case WINC_SOCK_ERR_INVALID: + bsd_setErrNo(EIO); + break; + default: + break; + } + return BSD_ERROR; + } + else + { + return BSD_SUCCESS; + } +} + +int BSD_recvfrom(int socket, void *buf, size_t len, int flags, struct bsd_sockaddr *from, socklen_t *fromlen) +{ + wincSocketResponses_t wincRecvFromReturn; + wincSupported_sockaddr winc_sockaddr; + + if (flags != 0) + { // Flag Not Support by WINC implementation + bsd_setErrNo(EINVAL); + return BSD_ERROR; + } + + winc_sockaddr.sa_family = from->sa_family; + memcpy((void*)winc_sockaddr.sa_data, (const void *)from->sa_data, sizeof(winc_sockaddr.sa_data)); + + switch(winc_sockaddr.sa_family) + { + case PF_INET: + winc_sockaddr.sa_family = AF_INET; + wincRecvFromReturn = recvfrom((SOCKET)socket, buf, (uint16_t)len, (uint32_t)flags); + break; + default: //Address family not supported by WINC + bsd_setErrNo(EAFNOSUPPORT); + return BSD_ERROR; + } + + if(wincRecvFromReturn != WINC_SOCK_ERR_NO_ERROR) + { + switch(wincRecvFromReturn) + { + case WINC_SOCK_ERR_INVALID_ARG: + if(socket < 0) + { + bsd_setErrNo(ENOTSOCK); + } + else if(buf == NULL) + { + bsd_setErrNo(EFAULT); + } + else if(len == 0) + { + bsd_setErrNo(EMSGSIZE); + } + else + { + bsd_setErrNo(EINVAL); + } + break; + case WINC_SOCK_ERR_BUFFER_FULL: + bsd_setErrNo(ENOBUFS); + break; + default: + break; + } + return BSD_ERROR; + } + else + { + // The socket.c send() API only returns (0) to indicate No Error + // Current WINC implementation doesn't use returned value per BSD. + + // TODO: Number of Bytes received should be returned in correct implementation. + return BSD_SUCCESS; + } +} + +int BSD_listen(int socket, int backlog) +{ + wincSocketResponses_t wincListenResponse; + + wincListenResponse = listen ((SOCKET)socket, (uint8_t)backlog); + + if (wincListenResponse != WINC_SOCK_ERR_NO_ERROR) + { + switch(wincListenResponse) + { + case SOCK_ERR_INVALID_ARG: + if (socket < 0) + { + bsd_setErrNo(ENOTSOCK); + } + else + { + bsd_setErrNo(EINVAL); + } + break; + case SOCK_ERR_INVALID: + bsd_setErrNo(EIO); + break; + default: + break; + } + return BSD_ERROR; + } + else + { + return BSD_SUCCESS; + } +} + +int BSD_accept(int socket, struct bsd_sockaddr * addr, socklen_t * addrlen) +{ + wincSocketResponses_t wincAcceptReturn; + wincSupported_sockaddr winc_sockaddr; + + winc_sockaddr.sa_family = addr->sa_family; + memcpy((void*)winc_sockaddr.sa_data, (const void *)addr->sa_data, sizeof(winc_sockaddr.sa_data)); + + switch(winc_sockaddr.sa_family) + { + case PF_INET: + winc_sockaddr.sa_family = AF_INET; + wincAcceptReturn = accept((SOCKET)socket, (struct sockaddr*)&winc_sockaddr, (uint8_t *)addrlen); + break; + default: //Address family not supported by WINC + bsd_setErrNo(EAFNOSUPPORT); + return BSD_ERROR; + } + + if (wincAcceptReturn != WINC_SOCK_ERR_NO_ERROR) + { + if (socket < 0) + { + bsd_setErrNo(ENOTSOCK); + } + else + { + bsd_setErrNo(EINVAL); + } + return BSD_ERROR; + } + else + { + return BSD_SUCCESS; + } +} + +int BSD_getsockopt(int socket, int level, int optname, void * optval, socklen_t * optlen) +{ + bsd_setErrNo(ENOSYS); + return BSD_ERROR; +} + +int BSD_setsockopt(int socket, int level, int optname, const void *optval, socklen_t optlen) +{ + wincSocketResponses_t wincSockOptResponse; + wincSupportedSockLevel wincSockLevel; + wincSupportedSockOptions wincSockOptions; + + switch((wincSupportedSockLevel)level) + { + case WINC_SOL_SOCKET: + case WINC_SOL_SSL_SOCKET: + wincSockLevel = level; + break; + default: + bsd_setErrNo(EIO); + return BSD_ERROR; + + } + switch((wincSupportedSockOptions)optname) + { + case WINC_SO_SSL_BYPASS_X509_VERIF: + case WINC_SO_SSL_SNI: + case WINC_SO_SSL_ENABLE_SESSION_CACHING: + case WINC_SO_SSL_ENABLE_SNI_VALIDATION: + wincSockOptions = optname; + break; + default: + bsd_setErrNo(EIO); + return BSD_ERROR; + } + wincSockOptResponse = setsockopt((SOCKET)socket, (uint8_t) wincSockLevel, (uint8_t) wincSockOptions, optval, (uint16_t)optlen); + if (wincSockOptResponse != WINC_SOCK_ERR_NO_ERROR) + { + switch(wincSockOptResponse) + { + case SOCK_ERR_INVALID_ARG: + if (socket < 0) + { + bsd_setErrNo(ENOTSOCK); + } + else if (optval == NULL) + { + bsd_setErrNo(EFAULT); + } + else + { + bsd_setErrNo(EINVAL); + } + break; + case SOCK_ERR_INVALID: + bsd_setErrNo(EIO); + break; + default: + break; + } + return BSD_ERROR; + } + else + { + return BSD_SUCCESS; + } +} + +int BSD_write(int fd, const void *buf, size_t nbytes) +{ + bsd_setErrNo(ENOSYS); + return BSD_ERROR; +} + +int BSD_read(int fd, void *buf, size_t nbytes) +{ + bsd_setErrNo(ENOSYS); + return BSD_ERROR; +} + +int BSD_poll(struct pollfd *ufds, unsigned int nfds, int timeout) +{ + bsd_setErrNo(ENOSYS); + return BSD_ERROR; +} + +socketState_t BSD_GetSocketState(int sock) +{ + socketState_t sockState; + packetReceptionHandler_t *bsdSocketInfo; + + sockState = NOT_A_SOCKET; + bsdSocketInfo = getSocketInfo(sock); + + if(bsdSocketInfo) + { + sockState = bsdSocketInfo->socketState; + } + + return sockState; +} + +int BSD_send(int socket, const void *msg, size_t len, int flags) +{ + wincSocketResponses_t wincSendReturn; + + if (flags != 0) + { // Flag Not Support by WINC implementation + bsd_setErrNo(EINVAL); + return BSD_ERROR; + } + + wincSendReturn = send((SOCKET)socket, (void*)msg, (uint16_t)len, (uint16_t)flags); + if(wincSendReturn != WINC_SOCK_ERR_NO_ERROR) + { + + // Most likely in this case we HAVE to update the socket state, especially if we get ENOTSOCK !!! + switch(wincSendReturn) + { + case WINC_SOCK_ERR_INVALID_ARG: + if(socket < 0) + { + bsd_setErrNo(ENOTSOCK); + } + else if(msg == NULL) + { + bsd_setErrNo(EFAULT); + } + else if(len > SOCKET_BUFFER_MAX_LENGTH) + { + bsd_setErrNo(EMSGSIZE); + } + else + { + bsd_setErrNo(EINVAL); + } + break; + case WINC_SOCK_ERR_BUFFER_FULL: + bsd_setErrNo(ENOBUFS); + break; + default: + break; + } + return BSD_ERROR; + } + else + { + // The socket.c send() API either sends the entire packet or + // does not send the packet at all. Therefore, if it does + // successfully send the packet, 'len' number of bytes will + // be transmitted. In this case, it is safe to return the + // value of 'len' as the number of bytes sent. + return len; + } +} + +int BSD_sendto(int socket, const void *msg, size_t len, int flags, const struct bsd_sockaddr *to, socklen_t tolen) +{ + wincSocketResponses_t wincSendToResponse; + wincSupported_sockaddr winc_sockaddr; + + if (flags != 0) + { // Flag Not Support by WINC implementation + bsd_setErrNo(EINVAL); + return BSD_ERROR; + } + + winc_sockaddr.sa_family = to->sa_family; + memcpy((void*)winc_sockaddr.sa_data, (const void *)to->sa_data, sizeof(winc_sockaddr.sa_data)); + + switch(winc_sockaddr.sa_family) + { + case PF_INET: + winc_sockaddr.sa_family = AF_INET; + + wincSendToResponse = sendto((SOCKET)socket, (void *)msg, (uint16_t)(len), (uint16_t)flags, (struct sockaddr *)&winc_sockaddr, (uint8_t)tolen); + break; + default: //Address family not supported by WINC + bsd_setErrNo(EAFNOSUPPORT); + return BSD_ERROR; + } + + if (wincSendToResponse != WINC_SOCK_ERR_NO_ERROR) + { + switch(wincSendToResponse) + { + case SOCK_ERR_INVALID_ARG: + if(socket < 0) + { + bsd_setErrNo(ENOTSOCK); + } + else if(msg == NULL) + { + bsd_setErrNo(EFAULT); + } + else if(len > SOCKET_BUFFER_MAX_LENGTH) + { + bsd_setErrNo(EMSGSIZE); + } + else + { + bsd_setErrNo(EINVAL); + } + break; + case SOCK_ERR_BUFFER_FULL: + bsd_setErrNo(ENOBUFS); + break; + default: + break; + } + return BSD_ERROR; + } + else + { + // The socket.c send() API either sends the entire packet or + // does not send the packet at all. Therefore, if it does + // successfully send the packet, 'len' number of bytes will + // be transmitted. In this case, it is safe to return the + // value of 'len' as the number of bytes sent. + return len; + } +} + +void BSD_SocketHandler(int8_t sock, uint8_t msgType, void *pMsg) +{ + packetReceptionHandler_t *bsdSocketInfo; + + bsdSocketInfo = getSocketInfo(sock); + if(bsdSocketInfo == NULL) { + + return; + } + switch (msgType) + { + case SOCKET_MSG_CONNECT: + if(pMsg) + { + tstrSocketConnectMsg *pstrConnect = (tstrSocketConnectMsg *)pMsg; + if (pstrConnect->s8Error >= 0) + { + + bsdSocketInfo->socketState = SOCKET_CONNECTED; + } + else + { + + BSD_close(sock); + } + } + break; + + case SOCKET_MSG_SEND: + bsdSocketInfo->socketState = SOCKET_CONNECTED; + break; + + case SOCKET_MSG_RECV: + if(pMsg) + { + tstrSocketRecvMsg *pstrRecv = (tstrSocketRecvMsg *)pMsg; + if (pstrRecv->s16BufferSize > 0) + { + bsdSocketInfo->recvCallBack(pstrRecv->pu8Buffer, pstrRecv->s16BufferSize); + bsdSocketInfo->socketState = SOCKET_CONNECTED; + + } else { + + BSD_close(sock); + } + } + break; + + case SOCKET_MSG_RECVFROM: + { + if(pMsg) + { + tstrSocketRecvMsg *pstrRecv = (tstrSocketRecvMsg *)pMsg; + if (pstrRecv->pu8Buffer && pstrRecv->s16BufferSize) + { + bsdSocketInfo->recvCallBack(pstrRecv->pu8Buffer, pstrRecv->s16BufferSize); + bsdSocketInfo->socketState = SOCKET_CONNECTED; + } else { + BSD_close(sock); + } + } + } + break; + + default: + + break; + } + +} diff --git a/AVRIoT.X/mcc_generated_files/mqtt/mqtt_winc_adapter.h b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_winc_adapter.h new file mode 100644 index 0000000..4d7706f --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mqtt/mqtt_winc_adapter.h @@ -0,0 +1,294 @@ +/******************************************************************** + * + (c) [2018] Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR + * PURPOSE. + * + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + * WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + * BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + * FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + * ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + ************************************************************************* + * + * bsdWINC.h + * + * About: + * + * + ******************************************************************************/ +#ifndef BSD_WINC_H +#define BSD_WINC_H + +#include +#include +#include +#include "../winc/socket/socket.h" + +/***************** BSD Generic Defines **********************/ +#define BSD_SUCCESS 0 +#define BSD_ERROR -1 + +/************* (END) BSD Generic Defines (END) *****************/ + +/***************** BSD Type Defined Enumerators **********************/ +// ToDo Check whether this enum can be moved to some other appropriate location +// This enum currently uses the same values as the TCPIPLite stack +typedef enum +{ + NOT_A_SOCKET = 0, // This is not a socket + SOCKET_CLOSED, // Socket closed + SOCKET_IN_PROGRESS, // The TCP listen or initiate a connection + SOCKET_CONNECTED, // The TCP is in established state user can send/receive data + SOCKET_CLOSING // The user initiate the closing procedure for this socket +} socketState_t; + +typedef enum +{ + PF_UNIX = 0, + PF_LOCAL, + PF_INET, // IPv4 + PF_INET6, + PF_IPX, + PF_NETLINK, // Kernel UI + PF_X25, + PF_AX25, + PF_ATMPVC, + PF_APPLETALK, + PF_PACKET, +}bsdDomain_t; + +typedef enum +{ + BSD_SOCK_STREAM = 1, + BSD_SOCK_DGRAM, + BSD_SOCK_SEQPACKET, + BSD_SOCK_RAW, + BSD_SOCK_RDM, + BSD_SOCK_PACKET, +}bsdTypes_t; + +/************** (END) BSD Type Defined Enumerators (END) *******************/ + +/***************** Error Number Defined Enumerators **********************/ +typedef enum +{ + ERROR0 = 0, + EPERM, + ENOENT, + ESRCH, + EINTR, + EIO, + ENXIO, + E2BIG, + ENOEXEC, + EBADF, + ECHILD, + EDEADLK, + ENOMEM, + EACCES, + EFAULT, + ENOTBLK, + EBUSY, + EEXIST, + EXDEV, + ENODEV, + ENOTDIR, + EISDIR, + EINVAL, + ENFILE, + EMFILE, + ENOTTY, + ETXTBSY, + EFBIG, + ENOSPC, + ESPIPE, + EROFS, + EMLINK, + EPIPE, + EDOM, // C99 + ERANGE, // C99 + EAGAIN, + EINPROGRESS, + EALREADY, + ENOTSOCK, + EDESTADDRREQ, + EMSGSIZE, + EPROTOTYPE, + ENOPROTOOPT, + EPROTONOSUPPORT, + ESOCKTNOSUPPORT, + EOPNOTSUPP, + EPFNOSUPPORT, + EAFNOSUPPORT, + EADDRINUSE, + EADDRNOTAVAIL, + ENETDOWN, + ENETUNREACH, + ENETRESET, + ECONNABORTED, + ECONNRESET, + ENOBUFS, + EISCONN, + ENOTCONN, + ESHUTDOWN, + ETIMEDOUT, + ECONNREFUSED, + ELOOP, + ENAMETOOLONG, + EHOSTDOWN, + EHOSTUNREACH, + ENOTEMPTY, + EPROCLIM, + EUSERS, + EDQUOT, + ESTALE, + EBADRPC, + ERPCMISMATCH, + EPROGUNAVAIL, + EPROGMISMATCH, + EPROCUNAVAIL, + ENOLCK, + ENOSYS, + EFTYPE, + EAUTH, + ENEEDAUTH, + EIDRM, + ENOMSG, + EOVERFLOW, + ECANCELED, + EILSEQ, // C99 + ENOATTR, + EDOOFUS, + EBADMSG, + EMULTIHOP, + ENOLINK, + EPROTO, + ENOTCAPABLE, + ECAPMODE, + ENOTRECOVERABLE, + EOWNERDEAD, +}bsdErrno_t; + +/***************** (END) BSD Type Defined Enumerators (END) **********************/ + +/***************** BSD Typedefs and Structures **********************/ + +typedef int socklen_t; + +typedef uint16_t sa_family_t; + +typedef uint16_t in_port_t; + +struct bsd_in_addr{ + in_addr_t s_addr; +}; + +struct bsd_sockaddr{ /* Socket address structure */ + sa_family_t sa_family; /* address family */ + char sa_data[14]; /* actually longer; address value */ +}; + +struct bsd_sockaddr_in{ /* Socket address internet style */ + sa_family_t sin_family; + in_port_t sin_port; + struct bsd_in_addr sin_addr; + char sin_zero[8]; +}; + +struct pollfd { + int fd; /* file descriptor */ + short events; /* events to look for */ + short revents; /* events returned */ +}; + +/***************** (END) BSD Typedefs and Structures (END) **************************************/ + +/*********************** BSD Adapter Definitions ********************************/ +/** \brief Function pointer for interaction between the WINC1500 BSD library + * and user application to transfer the information received over a socket to + * the application. + **/ +typedef void (*bsdRecvFuncPtr)(uint8_t *data, uint8_t length); + +// The call back table prototype for sending the packet received over a socket +// to the correct reception handler function defined in the user application. +// An instance of this table needs to be initialized by the user application to +// to specify the recv callback function for each socket. +typedef struct +{ + int8_t *socket; + bsdRecvFuncPtr recvCallBack; + socketState_t socketState; +} packetReceptionHandler_t; + + +/*********************** (END) BSD Adapter definitions (END) **************************/ + +/***************** BSD Public Functions **************************************/ +void BSD_SetRecvHandlerTable(packetReceptionHandler_t *appRecvInfo); + +packetReceptionHandler_t *BSD_GetRecvHandlerTable(); + +bsdErrno_t BSD_GetErrNo(void); + +int BSD_socket(int domain, int type, int protocol); + +int BSD_connect(int socket, const struct bsd_sockaddr *name, socklen_t namelen); + +int BSD_send(int socket, const void *msg, size_t len, int flags); + +int BSD_recv(int socket, const void *msg, size_t len, int flags); + +int BSD_close(int socket); + +uint32_t BSD_htonl(uint32_t hostlong); + +uint16_t BSD_htons(uint16_t hostshort); + +uint32_t BSD_ntohl(uint32_t netlong); + +uint16_t BSD_ntohs(uint16_t netshort); + +int BSD_bind(int socket, const struct bsd_sockaddr *addr, socklen_t addrlen); + +int BSD_recvfrom(int socket, void *buf, size_t len, int flags, struct bsd_sockaddr *from, socklen_t *fromlen); + +int BSD_listen(int socket, int backlog); + +int BSD_accept(int socket, struct bsd_sockaddr * addr, socklen_t * addrlen); + +int BSD_getsockopt(int socket, int level, int optname, void * optval, socklen_t * optlen); + +int BSD_setsockopt(int socket, int level, int optname, const void *optval, socklen_t optlen); + +int BSD_write(int fd, const void *buf, size_t nbytes); + +int BSD_read(int fd, void *buf, size_t nbytes); + +int BSD_poll(struct pollfd *ufds, unsigned int nfds, int timeout); + +int BSD_sendto(int socket, const void *msg, size_t len, int flags, const struct bsd_sockaddr *to, socklen_t tolen); + +void BSD_SocketHandler(int8_t sock, uint8_t msgType, void *pMsg); + +// ToDo This is not a true BSD_poll(). The actual BSD_poll() requires a +// structures and returns values which are not currently supported by WINC1500. +socketState_t BSD_GetSocketState(int sock); + +packetReceptionHandler_t* getSocketInfo(uint8_t sock); + +/************ (END) BSD Public Functions (END) *********************************/ + +#endif /* BSD_WINC */ + diff --git a/AVRIoT.X/mcc_generated_files/mqtt/nvmem_abstractionLayer/nvmem_hwLibInteraction.c b/AVRIoT.X/mcc_generated_files/mqtt/nvmem_abstractionLayer/nvmem_hwLibInteraction.c new file mode 100644 index 0000000..edaf841 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mqtt/nvmem_abstractionLayer/nvmem_hwLibInteraction.c @@ -0,0 +1,84 @@ +/******************************************************************** + * + ? [2018] Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR + * PURPOSE. + * + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + * WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + * BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + * FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + * ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + ************************************************************************* + * + * nvmem_hwLibInteraction.c + * + * About: + * MQTT hardware abstraction layer implementation. This file implements the + * APIs for handling the hardware dependent sections of the library. The + * function calls inside these APIs need to be replaced with hardware specific + * function calls depending on the device being used. + * + * + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include "nvmem_hwLibInteraction.h" +#include "memory.h" + +/**********************Function implementations********************************/ + +uint8_t nvmem_readByte(uint32_t location) +{ + return DATAEE_ReadByte(location); +} + + +void nvmem_writeByte(uint32_t location, uint8_t value) +{ + DATAEE_WriteByte(location, value); +} + + +void nvmem_readBlock(uint32_t location, uint8_t *data, uint8_t numOfBytes) +{ + uint8_t i; + + for(i = 0; i < numOfBytes; i++) + { + data[i] = nvmem_readByte(location); + location++; + } +} + + +void nvmem_writeBlock(uint32_t location, uint8_t *data, uint8_t numOfBytes) +{ + uint8_t i; + + for(i = 0; i < numOfBytes; i++) + { + nvmem_writeByte(location, data[i]); + location++; + } +} + + + +/**********************Function implementations*(END)**************************/ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/mqtt/nvmem_abstractionLayer/nvmem_hwLibInteraction.h b/AVRIoT.X/mcc_generated_files/mqtt/nvmem_abstractionLayer/nvmem_hwLibInteraction.h new file mode 100644 index 0000000..7b2c65f --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mqtt/nvmem_abstractionLayer/nvmem_hwLibInteraction.h @@ -0,0 +1,81 @@ +/******************************************************************** + * + ? [2018] Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR + * PURPOSE. + * + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + * WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + * BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + * FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN + * ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + ************************************************************************* + * + * nvmem_hwLibInteraction.h + * + * About: + * Abstraction layer for non-volatile memory usage between MQTT client and the + * hardware platform being used. + * + ******************************************************************************/ + +#ifndef MQTT_HW_LIB_INTERACTION_H +#define MQTT_HW_LIB_INTERACTION_H + +#include + + +/***********************MQTT Client definitions********************************/ + +#define MQTT_VALIDITY_CHECK_ADDR 0x00 +#define MQTT_CLIENT_ID_ADDR 0x01 +#define MQTT_CLIENT_ID_CREATED 0xAA + +/** \brief Read a byte from non-volatile memory. + * + * @param location Location of the byte, in the range [0..(last memory location in device EEPROM/ external EEPROM)-1]. + * @return Value read from non-volatile memory. + */ +uint8_t nvmem_readByte(uint32_t location); + + +/** \brief Write a byte to non-volatile memory. + * + * @param location Location of the byte, in the range [0..(last memory location in device EEPROM/ external EEPROM)-1]. + * @param value Value that needs to be written to non-volatile memory. + */ +void nvmem_writeByte(uint32_t location, uint8_t value); + + +/** \brief Read a block of data from non-volatile memory. + * + * @param location Location of the byte, in the range [0..(last memory location in device EEPROM/ external EEPROM)-1]. + * @param data Pointer to the buffer location created for storing the read data. + * @param numOfBytes Total number of bytes to read from non-volatile memory. + */ +void nvmem_readBlock(uint32_t location, uint8_t *data, uint8_t numOfBytes); + + +/** \brief Write a block of data to non-volatile memory. + * + * @param location Location of the byte, in the range [0..(last memory location in device EEPROM/ external EEPROM)-1]. + * @param data Pointer to the buffer location created for storing the data to be written. + * @param numOfBytes Total number of bytes to be written to non-volatile memory. + */ +void nvmem_writeBlock(uint32_t location, uint8_t *data, uint8_t numOfBytes); + + + + +#endif /* MQTT_HW_LIB_INTERACTION_H */ + diff --git a/AVRIoT.X/mcc_generated_files/mqtt/readme.md b/AVRIoT.X/mcc_generated_files/mqtt/readme.md new file mode 100644 index 0000000..8e44be6 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/mqtt/readme.md @@ -0,0 +1 @@ +## This folder will contain the source and header files generated using the MQTT library ftl files. \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/sensors_handling.c b/AVRIoT.X/mcc_generated_files/sensors_handling.c new file mode 100644 index 0000000..17f4f45 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/sensors_handling.c @@ -0,0 +1,55 @@ +/* + \file sensors_handling.c + + \brief Sensors handling handler source file. + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include +#include "sensors_handling.h" +#include "include/adc0.h" +#include "drivers/i2c_simple_master.h" + +#define MCP9809_ADDR 0x18 +#define MCP9808_REG_TA 0x05 +#define LIGHT_SENSOR_ADC_CHANNEL 5 + +uint16_t SENSORS_getLightValue(void) +{ + return ADC0_GetConversion(LIGHT_SENSOR_ADC_CHANNEL); +} + +int16_t SENSORS_getTempValue (void) +{ + int32_t temperature; + + temperature = i2c_read2ByteRegister(MCP9809_ADDR, MCP9808_REG_TA); + + temperature = temperature << 19; + temperature = temperature >> 19; + + temperature *= 100; + temperature /= 16; + + return temperature; +} diff --git a/AVRIoT.X/mcc_generated_files/sensors_handling.h b/AVRIoT.X/mcc_generated_files/sensors_handling.h new file mode 100644 index 0000000..0bbc950 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/sensors_handling.h @@ -0,0 +1,34 @@ +/* + \file sensors_handling.h + + \brief Sensors handler header file. + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef SENSORS_HANDLING_H +#define SENSORS_HANDLING_H + +uint16_t SENSORS_getLightValue(void); +int16_t SENSORS_getTempValue (void); + +#endif /* SENSORS_HANDLING_H*/ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/src/adc0.c b/AVRIoT.X/mcc_generated_files/src/adc0.c new file mode 100644 index 0000000..2525bdd --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/src/adc0.c @@ -0,0 +1,178 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include "../include/adc0.h" + +adc_irq_cb_t ADC0_window_cb = NULL; + +/** + * \brief Initialize ADC interface + */ +int8_t ADC0_Initialize() +{ + + //DUTYCYC DUTY25; + ADC0.CALIB = 0x01; + + //SAMPNUM ACC1; + ADC0.CTRLB = 0x00; + + //SAMPCAP disabled; REFSEL VDDREF; PRESC DIV16; + ADC0.CTRLC = 0x13; + + //INITDLY DLY0; ASDV ASVOFF; SAMPDLY 0; + ADC0.CTRLD = 0x00; + + //WINCM NONE; + ADC0.CTRLE = 0x00; + + //DBGRUN disabled; + ADC0.DBGCTRL = 0x00; + + //STARTEI disabled; + ADC0.EVCTRL = 0x00; + + //WCMP disabled; RESRDY disabled; + ADC0.INTCTRL = 0x00; + + //MUXPOS AIN5; + ADC0.MUXPOS = 0x05; + + //SAMPLEN 0; + ADC0.SAMPCTRL = 0x00; + + // Window comparator high threshold + ADC0.WINHT = 0x00; + + // Window comparator low threshold + ADC0.WINLT = 0x00; + + //RUNSTBY disabled; RESSEL 10BIT; FREERUN disabled; ENABLE enabled; + ADC0.CTRLA = 0x01; + + + return 0; +} + +void ADC0_Enable() +{ + ADC0.CTRLA |= ADC_ENABLE_bm; +} + +void ADC0_Disable() +{ + ADC0.CTRLA &= ~ADC_ENABLE_bm; +} + +void ADC0_EnableAutoTrigger() +{ + ADC0.EVCTRL |= ADC_STARTEI_bm; +} + +void ADC0_DisableAutoTrigger() +{ + ADC0.EVCTRL &= ~ADC_STARTEI_bm; +} + +void ADC0_SetWindowHigh(adc_result_t high) +{ + ADC0.WINHT = high; +} + +void ADC0_SetWindowLow(adc_result_t low) +{ + ADC0.WINLT = low; +} + +void ADC0_SetWindowMode(adc0_window_mode_t mode) +{ + ADC0.CTRLE = mode; +} + +void ADC0_SetWindowChannel(adc_0_channel_t channel) +{ + ADC0.MUXPOS = channel; +} + +void ADC0_StartConversion(adc_0_channel_t channel) +{ + ADC0.MUXPOS = channel; + ADC0.COMMAND = ADC_STCONV_bm; +} + +bool ADC0_IsConversionDone() +{ + return (ADC0.INTFLAGS & ADC_RESRDY_bm); +} + +adc_result_t ADC0_GetConversionResult(void) +{ + return (ADC0.RES); +} + +bool ADC0_GetWindowResult(void) +{ + bool temp = (ADC0.INTFLAGS & ADC_WCMP_bm); + ADC0.INTFLAGS = ADC_WCMP_bm; // Clear intflag if set + return temp; +} + +adc_result_t ADC0_GetConversion(adc_0_channel_t channel) +{ + adc_result_t res; + + ADC0_StartConversion(channel); + while (!ADC0_IsConversionDone()); + res = ADC0_GetConversionResult(); + ADC0.INTFLAGS = ADC_RESRDY_bm; + return res; +} + +uint8_t ADC0_GetResolution() +{ + return (ADC0.CTRLA & ADC_RESSEL_bm) ? 8 : 10; +} + +void ADC0_RegisterWindowCallback(adc_irq_cb_t f) +{ + ADC0_window_cb = f; +} + +ISR(ADC0_WCOMP_vect) +{ + + if (ADC0_window_cb != NULL) { + ADC0_window_cb(); + } + + // Clear the interrupt flag + ADC0.INTFLAGS = ADC_WCMP_bm; +} + +ISR(ADC0_RESRDY_vect) +{ + /* Insert your ADC result ready interrupt handling code here */ + + /* The interrupt flag has to be cleared manually */ + ADC0.INTFLAGS = ADC_RESRDY_bm; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/src/cpuint.c b/AVRIoT.X/mcc_generated_files/src/cpuint.c new file mode 100644 index 0000000..f733275 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/src/cpuint.c @@ -0,0 +1,45 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include "../include/cpuint.h" + +/** + * \brief Initialize cpuint interface + */ +int8_t CPUINT_Initialize() +{ + /* IVSEL and CVT are Configuration Change Protected */ + + //IVSEL disabled; CVT disabled; LVL0RR disabled; + ccp_write_io((void*)&(CPUINT.CTRLA),0x00); + + //LVL0PRI 0; + CPUINT.LVL0PRI = 0x00; + + //USART2 RX Interrupt vector number provided to give it the highest priority + CPUINT.LVL1VEC = 0x1F; + + ENABLE_INTERRUPTS(); + + return 0; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/src/pin_manager.c b/AVRIoT.X/mcc_generated_files/src/pin_manager.c new file mode 100644 index 0000000..9a25ad0 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/src/pin_manager.c @@ -0,0 +1,462 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include "../include/pin_manager.h" +static void (*PORTA_PA2_InterruptHandler)(void); +static void (*PORTD_PD5_InterruptHandler)(void); +static void (*PORTF_SW0_InterruptHandler)(void); +static void (*PORTA_RST_InterruptHandler)(void); +static void (*PORTA_PA4_InterruptHandler)(void); +static void (*PORTA_PA3_InterruptHandler)(void); +static void (*PORTA_PA6_InterruptHandler)(void); +static void (*PORTA_PA5_InterruptHandler)(void); +static void (*PORTA_nCS_InterruptHandler)(void); +static void (*PORTF_PF1_InterruptHandler)(void); +static void (*PORTF_PF0_InterruptHandler)(void); +static void (*PORTD_LED_YELLOW_InterruptHandler)(void); +static void (*PORTF_CE_InterruptHandler)(void); +static void (*PORTD_LED_RED_InterruptHandler)(void); +static void (*PORTF_INT_InterruptHandler)(void); +static void (*PORTF_SW1_InterruptHandler)(void); +static void (*PORTD_LED_BLUE_InterruptHandler)(void); +static void (*PORTD_LED_GREEN_InterruptHandler)(void); +static void (*PORTF_WAKE_InterruptHandler)(void); + +void PORT_Initialize(void); + +void PIN_MANAGER_Initialize() +{ + PORT_Initialize(); + + /* DIR Registers Initialization */ + PORTA.DIR = 0xD2; + PORTB.DIR = 0x00; + PORTC.DIR = 0x00; + PORTD.DIR = 0x0F; + PORTE.DIR = 0x00; + PORTF.DIR = 0x19; + + /* OUT Registers Initialization */ + PORTA.OUT = 0x80; + PORTB.OUT = 0x00; + PORTC.OUT = 0x00; + PORTD.OUT = 0x0F; + PORTE.OUT = 0x00; + PORTF.OUT = 0x00; + + /* PINxCTRL registers Initialization */ + PORTA.PIN0CTRL = 0x00; + PORTA.PIN1CTRL = 0x00; + PORTA.PIN2CTRL = 0x00; + PORTA.PIN3CTRL = 0x00; + PORTA.PIN4CTRL = 0x00; + PORTA.PIN5CTRL = 0x00; + PORTA.PIN6CTRL = 0x00; + PORTA.PIN7CTRL = 0x00; + PORTB.PIN0CTRL = 0x00; + PORTB.PIN1CTRL = 0x00; + PORTB.PIN2CTRL = 0x00; + PORTB.PIN3CTRL = 0x00; + PORTB.PIN4CTRL = 0x00; + PORTB.PIN5CTRL = 0x00; + PORTB.PIN6CTRL = 0x00; + PORTB.PIN7CTRL = 0x00; + PORTC.PIN0CTRL = 0x00; + PORTC.PIN1CTRL = 0x00; + PORTC.PIN2CTRL = 0x00; + PORTC.PIN3CTRL = 0x00; + PORTC.PIN4CTRL = 0x00; + PORTC.PIN5CTRL = 0x00; + PORTC.PIN6CTRL = 0x00; + PORTC.PIN7CTRL = 0x00; + PORTD.PIN0CTRL = 0x00; + PORTD.PIN1CTRL = 0x00; + PORTD.PIN2CTRL = 0x00; + PORTD.PIN3CTRL = 0x00; + PORTD.PIN4CTRL = 0x00; + PORTD.PIN5CTRL = 0x00; + PORTD.PIN6CTRL = 0x00; + PORTD.PIN7CTRL = 0x00; + PORTE.PIN0CTRL = 0x00; + PORTE.PIN1CTRL = 0x00; + PORTE.PIN2CTRL = 0x00; + PORTE.PIN3CTRL = 0x00; + PORTE.PIN4CTRL = 0x00; + PORTE.PIN5CTRL = 0x00; + PORTE.PIN6CTRL = 0x00; + PORTE.PIN7CTRL = 0x00; + PORTF.PIN0CTRL = 0x00; + PORTF.PIN1CTRL = 0x00; + PORTF.PIN2CTRL = 0x0B; + PORTF.PIN3CTRL = 0x00; + PORTF.PIN4CTRL = 0x00; + PORTF.PIN5CTRL = 0x08; + PORTF.PIN6CTRL = 0x08; + PORTF.PIN7CTRL = 0x00; + + /* PORTMUX Initialization */ + PORTMUX.CCLROUTEA = 0x00; + PORTMUX.EVSYSROUTEA = 0x00; + PORTMUX.TCAROUTEA = 0x00; + PORTMUX.TCBROUTEA = 0x00; + PORTMUX.TWISPIROUTEA = 0x00; + PORTMUX.USARTROUTEA = 0x00; + + // register default ISC callback functions at runtime; use these methods to register a custom function + PORTA_PA2_SetInterruptHandler(PORTA_PA2_DefaultInterruptHandler); + PORTD_PD5_SetInterruptHandler(PORTD_PD5_DefaultInterruptHandler); + PORTF_SW0_SetInterruptHandler(PORTF_SW0_DefaultInterruptHandler); + PORTA_RST_SetInterruptHandler(PORTA_RST_DefaultInterruptHandler); + PORTA_PA4_SetInterruptHandler(PORTA_PA4_DefaultInterruptHandler); + PORTA_PA3_SetInterruptHandler(PORTA_PA3_DefaultInterruptHandler); + PORTA_PA6_SetInterruptHandler(PORTA_PA6_DefaultInterruptHandler); + PORTA_PA5_SetInterruptHandler(PORTA_PA5_DefaultInterruptHandler); + PORTA_nCS_SetInterruptHandler(PORTA_nCS_DefaultInterruptHandler); + PORTF_PF1_SetInterruptHandler(PORTF_PF1_DefaultInterruptHandler); + PORTF_PF0_SetInterruptHandler(PORTF_PF0_DefaultInterruptHandler); + PORTD_LED_YELLOW_SetInterruptHandler(PORTD_LED_YELLOW_DefaultInterruptHandler); + PORTF_CE_SetInterruptHandler(PORTF_CE_DefaultInterruptHandler); + PORTD_LED_RED_SetInterruptHandler(PORTD_LED_RED_DefaultInterruptHandler); + PORTF_INT_SetInterruptHandler(PORTF_INT_DefaultInterruptHandler); + PORTF_SW1_SetInterruptHandler(PORTF_SW1_DefaultInterruptHandler); + PORTD_LED_BLUE_SetInterruptHandler(PORTD_LED_BLUE_DefaultInterruptHandler); + PORTD_LED_GREEN_SetInterruptHandler(PORTD_LED_GREEN_DefaultInterruptHandler); + PORTF_WAKE_SetInterruptHandler(PORTF_WAKE_DefaultInterruptHandler); +} + +void PORT_Initialize(void) +{ + /* On AVR devices all peripherals are enable from power on reset, this + * disables all peripherals to save power. Driver shall enable + * peripheral if used */ + + /* Set all pins to low power mode */ + for (uint8_t i = 0; i < 8; i++) { + *((uint8_t *)&PORTE + 0x10 + i) |= 1 << PORT_PULLUPEN_bp; + } + + for (uint8_t i = 0; i < 8; i++) { + *((uint8_t *)&PORTF + 0x10 + i) |= 1 << PORT_PULLUPEN_bp; + } + + for (uint8_t i = 0; i < 8; i++) { + *((uint8_t *)&PORTA + 0x10 + i) |= 1 << PORT_PULLUPEN_bp; + } + + for (uint8_t i = 0; i < 8; i++) { + *((uint8_t *)&PORTB + 0x10 + i) |= 1 << PORT_PULLUPEN_bp; + } + + for (uint8_t i = 0; i < 8; i++) { + *((uint8_t *)&PORTC + 0x10 + i) |= 1 << PORT_PULLUPEN_bp; + } + + for (uint8_t i = 0; i < 8; i++) { + *((uint8_t *)&PORTD + 0x10 + i) |= 1 << PORT_PULLUPEN_bp; + } + +} + +/** + Allows selecting an interrupt handler for PORTA_PA2 at application runtime +*/ +void PORTA_PA2_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTA_PA2_InterruptHandler = interruptHandler; +} + +void PORTA_PA2_DefaultInterruptHandler(void) +{ + // add your PORTA_PA2 interrupt custom code + // or set custom function using PORTA_PA2_SetInterruptHandler() +} +/** + Allows selecting an interrupt handler for PORTD_PD5 at application runtime +*/ +void PORTD_PD5_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTD_PD5_InterruptHandler = interruptHandler; +} + +void PORTD_PD5_DefaultInterruptHandler(void) +{ + // add your PORTD_PD5 interrupt custom code + // or set custom function using PORTD_PD5_SetInterruptHandler() +} +/** + Allows selecting an interrupt handler for PORTF_SW0 at application runtime +*/ +void PORTF_SW0_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTF_SW0_InterruptHandler = interruptHandler; +} + +void PORTF_SW0_DefaultInterruptHandler(void) +{ + // add your PORTF_SW0 interrupt custom code + // or set custom function using PORTF_SW0_SetInterruptHandler() +} +/** + Allows selecting an interrupt handler for PORTA_RST at application runtime +*/ +void PORTA_RST_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTA_RST_InterruptHandler = interruptHandler; +} + +void PORTA_RST_DefaultInterruptHandler(void) +{ + // add your PORTA_RST interrupt custom code + // or set custom function using PORTA_RST_SetInterruptHandler() +} +/** + Allows selecting an interrupt handler for PORTA_PA4 at application runtime +*/ +void PORTA_PA4_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTA_PA4_InterruptHandler = interruptHandler; +} + +void PORTA_PA4_DefaultInterruptHandler(void) +{ + // add your PORTA_PA4 interrupt custom code + // or set custom function using PORTA_PA4_SetInterruptHandler() +} +/** + Allows selecting an interrupt handler for PORTA_PA3 at application runtime +*/ +void PORTA_PA3_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTA_PA3_InterruptHandler = interruptHandler; +} + +void PORTA_PA3_DefaultInterruptHandler(void) +{ + // add your PORTA_PA3 interrupt custom code + // or set custom function using PORTA_PA3_SetInterruptHandler() +} +/** + Allows selecting an interrupt handler for PORTA_PA6 at application runtime +*/ +void PORTA_PA6_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTA_PA6_InterruptHandler = interruptHandler; +} + +void PORTA_PA6_DefaultInterruptHandler(void) +{ + // add your PORTA_PA6 interrupt custom code + // or set custom function using PORTA_PA6_SetInterruptHandler() +} +/** + Allows selecting an interrupt handler for PORTA_PA5 at application runtime +*/ +void PORTA_PA5_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTA_PA5_InterruptHandler = interruptHandler; +} + +void PORTA_PA5_DefaultInterruptHandler(void) +{ + // add your PORTA_PA5 interrupt custom code + // or set custom function using PORTA_PA5_SetInterruptHandler() +} +/** + Allows selecting an interrupt handler for PORTA_nCS at application runtime +*/ +void PORTA_nCS_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTA_nCS_InterruptHandler = interruptHandler; +} + +void PORTA_nCS_DefaultInterruptHandler(void) +{ + // add your PORTA_nCS interrupt custom code + // or set custom function using PORTA_nCS_SetInterruptHandler() +} +/** + Allows selecting an interrupt handler for PORTF_PF1 at application runtime +*/ +void PORTF_PF1_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTF_PF1_InterruptHandler = interruptHandler; +} + +void PORTF_PF1_DefaultInterruptHandler(void) +{ + // add your PORTF_PF1 interrupt custom code + // or set custom function using PORTF_PF1_SetInterruptHandler() +} +/** + Allows selecting an interrupt handler for PORTF_PF0 at application runtime +*/ +void PORTF_PF0_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTF_PF0_InterruptHandler = interruptHandler; +} + +void PORTF_PF0_DefaultInterruptHandler(void) +{ + // add your PORTF_PF0 interrupt custom code + // or set custom function using PORTF_PF0_SetInterruptHandler() +} +/** + Allows selecting an interrupt handler for PORTD_LED_YELLOW at application runtime +*/ +void PORTD_LED_YELLOW_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTD_LED_YELLOW_InterruptHandler = interruptHandler; +} + +void PORTD_LED_YELLOW_DefaultInterruptHandler(void) +{ + // add your PORTD_LED_YELLOW interrupt custom code + // or set custom function using PORTD_LED_YELLOW_SetInterruptHandler() +} +/** + Allows selecting an interrupt handler for PORTF_CE at application runtime +*/ +void PORTF_CE_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTF_CE_InterruptHandler = interruptHandler; +} + +void PORTF_CE_DefaultInterruptHandler(void) +{ + // add your PORTF_CE interrupt custom code + // or set custom function using PORTF_CE_SetInterruptHandler() +} +/** + Allows selecting an interrupt handler for PORTD_LED_RED at application runtime +*/ +void PORTD_LED_RED_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTD_LED_RED_InterruptHandler = interruptHandler; +} + +void PORTD_LED_RED_DefaultInterruptHandler(void) +{ + // add your PORTD_LED_RED interrupt custom code + // or set custom function using PORTD_LED_RED_SetInterruptHandler() +} +/** + Allows selecting an interrupt handler for PORTF_INT at application runtime +*/ +void PORTF_INT_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTF_INT_InterruptHandler = interruptHandler; +} + +void PORTF_INT_DefaultInterruptHandler(void) +{ + // add your PORTF_INT interrupt custom code + // or set custom function using PORTF_INT_SetInterruptHandler() +} +/** + Allows selecting an interrupt handler for PORTF_SW1 at application runtime +*/ +void PORTF_SW1_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTF_SW1_InterruptHandler = interruptHandler; +} + +void PORTF_SW1_DefaultInterruptHandler(void) +{ + // add your PORTF_SW1 interrupt custom code + // or set custom function using PORTF_SW1_SetInterruptHandler() +} +/** + Allows selecting an interrupt handler for PORTD_LED_BLUE at application runtime +*/ +void PORTD_LED_BLUE_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTD_LED_BLUE_InterruptHandler = interruptHandler; +} + +void PORTD_LED_BLUE_DefaultInterruptHandler(void) +{ + // add your PORTD_LED_BLUE interrupt custom code + // or set custom function using PORTD_LED_BLUE_SetInterruptHandler() +} +/** + Allows selecting an interrupt handler for PORTD_LED_GREEN at application runtime +*/ +void PORTD_LED_GREEN_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTD_LED_GREEN_InterruptHandler = interruptHandler; +} + +void PORTD_LED_GREEN_DefaultInterruptHandler(void) +{ + // add your PORTD_LED_GREEN interrupt custom code + // or set custom function using PORTD_LED_GREEN_SetInterruptHandler() +} +/** + Allows selecting an interrupt handler for PORTF_WAKE at application runtime +*/ +void PORTF_WAKE_SetInterruptHandler(void (* interruptHandler)(void)) +{ + PORTF_WAKE_InterruptHandler = interruptHandler; +} + +void PORTF_WAKE_DefaultInterruptHandler(void) +{ + // add your PORTF_WAKE interrupt custom code + // or set custom function using PORTF_WAKE_SetInterruptHandler() +} +ISR(PORTF_PORT_vect) +{ + // Call the interrupt handler for the callback registered at runtime + if(VPORTF.INTFLAGS & PORT_INT6_bm) + { + PORTF_SW0_InterruptHandler(); + } + if(VPORTF.INTFLAGS & PORT_INT1_bm) + { + PORTF_PF1_InterruptHandler(); + } + if(VPORTF.INTFLAGS & PORT_INT0_bm) + { + PORTF_PF0_InterruptHandler(); + } + if(VPORTF.INTFLAGS & PORT_INT3_bm) + { + PORTF_CE_InterruptHandler(); + } + if(VPORTF.INTFLAGS & PORT_INT2_bm) + { + PORTF_INT_InterruptHandler(); + } + if(VPORTF.INTFLAGS & PORT_INT5_bm) + { + PORTF_SW1_InterruptHandler(); + } + if(VPORTF.INTFLAGS & PORT_INT4_bm) + { + PORTF_WAKE_InterruptHandler(); + } + + /* Clear interrupt flags */ + VPORTF.INTFLAGS = 0xff; +} + diff --git a/AVRIoT.X/mcc_generated_files/src/protected_io.S b/AVRIoT.X/mcc_generated_files/src/protected_io.S new file mode 100644 index 0000000..705b7da --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/src/protected_io.S @@ -0,0 +1,80 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include "../utils/assembler.h" + +/* + * GNU and IAR use different calling conventions. Since this is + * a very small and simple function to begin with, it's easier + * to implement it twice than to deal with the differences + * within a single implementation. + */ + + PUBLIC_FUNCTION(protected_write_io) + +#if defined(__GNUC__) + +#ifdef RAMPZ + out _SFR_IO_ADDR(RAMPZ), r1 // Clear bits 23:16 of Z +#endif + movw r30, r24 // Load addr into Z + out CCP, r22 // Start CCP handshake + st Z, r20 // Write value to I/O register + ret // Return to caller + +#elif defined(__IAR_SYSTEMS_ASM__) + +# if !defined(CONFIG_MEMORY_MODEL_TINY) && !defined(CONFIG_MEMORY_MODEL_SMALL) \ + && !defined(CONFIG_MEMORY_MODEL_LARGE) +# define CONFIG_MEMORY_MODEL_SMALL +# endif +# if defined(CONFIG_MEMORY_MODEL_LARGE) + ldi r20, 0 + out RAMPZ, r20 // Reset bits 23:16 of Z + movw r30, r16 // Load addr into Z +# elif defined(CONFIG_MEMORY_MODEL_TINY) + ldi r31, 0 // Reset bits 8:15 of Z + mov r30, r16 // Load addr into Z +# else + movw r30, r16 // Load addr into Z +# endif +# if defined(CONFIG_MEMORY_MODEL_TINY) + out CCP, r17 // Start CCP handshake + st Z, r18 // Write value to I/O register +# elif defined(CONFIG_MEMORY_MODEL_SMALL) + out CCP, r18 // Start CCP handshake + st Z, r19 // Write value to I/O register +# elif defined(CONFIG_MEMORY_MODEL_LARGE) + out CCP, r19 // Start CCP handshake + st Z, r20 // Write value to I/O register +# else +# error Unknown memory model in use, no idea how registers should be accessed +# endif + ret +#else +# error Unknown assembler +#endif + + END_FUNC(protected_write_io) + END_FILE() + diff --git a/AVRIoT.X/mcc_generated_files/src/rtc.c b/AVRIoT.X/mcc_generated_files/src/rtc.c new file mode 100644 index 0000000..4e29483 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/src/rtc.c @@ -0,0 +1,175 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include "../include/rtc.h" + +/** + * \brief Initialize rtc interface + * + * \return Initialization status. + */ + +void (*RTC_OVF_isr_cb)(void) = NULL; +void (*RTC_CMP_isr_cb)(void) = NULL; +void (*RTC_PIT_isr_cb)(void) = NULL; + +/** + * \brief Initialize RTC interface + */ +int8_t RTC_Initialize() +{ + while (RTC.STATUS > 0) { /* Wait for all register to be synchronized */ + } + //Compare + RTC.CMP = 0x00; + + //Count + RTC.CNT = 0x00; + + //Period + RTC.PER = 0xFFFF; + + //Clock selection + RTC.CLKSEL = 0x01; + + //DBGRUN disabled; + RTC.DBGCTRL = 0x00; + + //CMP disabled; OVF enabled; + RTC.INTCTRL = 0x01; + + //PERIOD OFF; PITEN disabled; + RTC.PITCTRLA = 0x00; + + //DBGRUN disabled; + RTC.PITDBGCTRL = 0x00; + + //PI disabled; + RTC.PITINTCTRL = 0x00; + + //RUNSTDBY disabled; PRESCALER DIV1; CORREN disabled; RTCEN enabled; + RTC.CTRLA = 0x01; + + return 0; +} + +void RTC_SetOVFIsrCallback(RTC_cb_t cb) +{ + RTC_OVF_isr_cb = cb; +} + +void RTC_SetCMPIsrCallback(RTC_cb_t cb) +{ + RTC_CMP_isr_cb = cb; +} + +ISR(RTC_CNT_vect) +{ + if (RTC.INTFLAGS & RTC_OVF_bm ) + { + if (RTC_OVF_isr_cb != NULL) + { + (*RTC_OVF_isr_cb)(); + } + } + + if (RTC.INTFLAGS & RTC_CMP_bm ) + { + if (RTC_CMP_isr_cb != NULL) + { + (*RTC_CMP_isr_cb)(); + } + } + RTC.INTFLAGS = (RTC_OVF_bm | RTC_CMP_bm); +} + +ISR(RTC_PIT_vect) +{ + if (RTC_PIT_isr_cb != NULL) + { + (*RTC_PIT_isr_cb)(); + } + RTC.INTFLAGS = RTC_PI_bm; +} + +inline void RTC_WriteCounter(uint16_t timerVal) +{ + while (RTC.STATUS & RTC_CNTBUSY_bm); + RTC.CNT = timerVal; +} + +inline uint16_t RTC_ReadCounter(void) +{ + return RTC.CNT; +} + +inline void RTC_WritePeroid(uint16_t timerVal) +{ + while (RTC.STATUS & RTC_PERBUSY_bm); + RTC.PER = timerVal; +} + +inline uint16_t RTC_ReadPeriod(void) +{ + return RTC.PER; +} + +inline void RTC_EnableCMPInterrupt(void) +{ + RTC.INTCTRL |= RTC_CMP_bm; +} + +inline void RTC_DisableCMPInterrupt(void) +{ + RTC.INTCTRL &= ~RTC_CMP_bm; +} + +inline void RTC_EnableOVFInterrupt(void) +{ + RTC.INTCTRL |= RTC_OVF_bm; +} + +inline void RTC_DisableOVFInterrupt(void) +{ + RTC.INTCTRL &= ~RTC_OVF_bm; +} + +inline void RTC_EnablePITInterrupt(void) +{ + RTC.INTCTRL |= RTC_PI_bm; +} + +inline void RTC_DisablePITInterrupt(void) +{ + RTC.INTCTRL &= ~RTC_PI_bm; +} + +inline void RTC_ClearOVFInterruptFlag(void) +{ + RTC.INTFLAGS &= ~RTC_OVF_bm; +} + +inline bool RTC_IsOVFInterruptEnabled(void) +{ + return ((RTC.INTCTRL & RTC_OVF_bm) > 0); +} diff --git a/AVRIoT.X/mcc_generated_files/src/spi0.c b/AVRIoT.X/mcc_generated_files/src/spi0.c new file mode 100644 index 0000000..d7b95ed --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/src/spi0.c @@ -0,0 +1,168 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include "../include/spi0.h" +#include "../include/pin_manager.h" + +typedef struct spi0_descriptor_s { + spi0_transfer_status_t status; +} spi0_descriptor_t; + +spi0_configuration_t spi0_configurations[] = { + { 0x23, 0x0 }, + { 0x31, 0x0 } +}; + +static spi0_descriptor_t spi0_desc; + +uint8_t SPI0_Initialize() +{ + //DORD disabled; MASTER enabled; CLK2X enabled; PRESC DIV64; ENABLE enabled; + SPI0.CTRLA = 0x35; + + //BUFEN disabled; BUFWR disabled; SSD disabled; MODE 0; + SPI0.CTRLB = 0x00; + + //RXCIE disabled; TXCIE disabled; DREIE disabled; SSIE disabled; IE disabled; + SPI0.INTCTRL = 0x00; + + spi0_desc.status = SPI_FREE; + + //RXCIF disabled; IF disabled; TXCIF disabled; WRCOL disabled; DREIF disabled; SSIF disabled; BUFOVF disabled; + SPI0.INTFLAGS = 0x00; + + return 0; +} + +void SPI0_Enable() +{ + SPI0.CTRLA |= SPI_ENABLE_bm; +} + +void SPI0_Disable() +{ + SPI0.CTRLA &= ~SPI_ENABLE_bm; +} + +bool SPI0_OpenConfiguration(uint8_t spiUniqueConfiguration){ + return SPI0_Open(spi0_configurations[spiUniqueConfiguration]); +} + +bool SPI0_Open(spi0_configuration_t spiUniqueConfiguration) +{ + if (spi0_desc.status == SPI_FREE) { + spi0_desc.status = SPI_IDLE; + SPI0.CTRLA = spiUniqueConfiguration.CTRLAvalue; + SPI0.CTRLB = spiUniqueConfiguration.CTRLBvalue; + return true; + } else { + return false; + } +} + +void SPI0_Close(void) +{ + spi0_desc.status = SPI_FREE; +} + +uint8_t SPI0_ExchangeByte(uint8_t data) +{ + SPI0.DATA = data; + while (!(SPI0.INTFLAGS & SPI_RXCIF_bm)) + ; + return SPI0.DATA; +} + +bool SPI0_Selected() +{ +/** + * \brief returns true if SS pin is selected + * TODO: Place your code + */ +return true; +} + +uint8_t SPI0_GetRxData() +{ + return SPI0.DATA; +} + +void SPI0_WriteTxData(uint8_t data) +{ + SPI0.DATA = data; +} + +void SPI0_WaitDataready() +{ + while (!(SPI0.INTFLAGS & SPI_RXCIF_bm)) + ; +} + +void SPI0_ExchangeBlock(void *block, size_t size) +{ + uint8_t *b = (uint8_t *)block; + while (size--) { + SPI0.DATA = *b; + while (!(SPI0.INTFLAGS & SPI_RXCIF_bm)) + ; + *b = SPI0.DATA; + b++; + } +} + +void SPI0_WriteBlock(void *block, size_t size) +{ + uint8_t *b = (uint8_t *)block; + uint8_t rdata; + while (size--) { + SPI0.DATA = *b; + while (!(SPI0.INTFLAGS & SPI_RXCIF_bm)) + ; + rdata = SPI0.DATA; + (void)(rdata); // Silence compiler warning + b++; + } +} + +void SPI0_ReadBlock(void *block, size_t size) +{ + uint8_t *b = (uint8_t *)block; + while (size--) { + SPI0.DATA = 0; + while (!(SPI0.INTFLAGS & SPI_RXCIF_bm)) + ; + *b = SPI0.DATA; + b++; + } +} + +void SPI0_WriteByte(uint8_t data) +{ + + SPI0.DATA = data; +} + +uint8_t SPI0_ReadByte() +{ + return SPI0.DATA; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/src/twi0_master.c b/AVRIoT.X/mcc_generated_files/src/twi0_master.c new file mode 100644 index 0000000..06a6a1b --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/src/twi0_master.c @@ -0,0 +1,696 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include "../include/twi0_master.h" +#include +#include + +/***************************************************************************/ +// I2C STATES +typedef enum { + I2C_IDLE = 0, + I2C_SEND_ADR_READ, + I2C_SEND_ADR_WRITE, + I2C_TX, + I2C_RX, + I2C_TX_EMPTY, + I2C_SEND_RESTART_READ, + I2C_SEND_RESTART_WRITE, + I2C_SEND_RESTART, + I2C_SEND_STOP, + I2C_RX_DO_ACK, + I2C_TX_DO_ACK, + I2C_RX_DO_NACK_STOP, + I2C_RX_DO_NACK_RESTART, + I2C_RESET, + I2C_ADDRESS_NACK, + I2C_BUS_COLLISION, + I2C_BUS_ERROR +} twi0_fsm_states_t; + +// I2C Event Callback List +typedef enum { + I2C_DATA_COMPLETE = 0, + I2C_WRITE_COLLISION, + I2C_ADDRESSNACK, + I2C_DATA_NACK, + I2C_TIMEOUT, + I2C_NULL +} I2C0_callbackIndex_t; + +// I2C Status Structure +typedef struct { + twi0_callback_t callbackTable[6]; + void * callbackPayload[6]; + uint16_t timeout; + uint16_t timeout_value; + twi0_address_t address; + uint8_t * data_ptr; + size_t data_length; + twi0_fsm_states_t state; + twi0_error_t error; + unsigned addressNACKCheck : 1; + unsigned busy : 1; + unsigned inUse : 1; + unsigned bufferFree : 1; + /*if timeoutDriverEnabled + timerStruct_t timeout; + */ +} I2C0_status_t; +I2C0_status_t I2C0_status = {0}; +typedef twi0_fsm_states_t(stateHandlerFunction)(void); + +/* I2C Interfaces */ +void I2C0_Poller(void); + +/* I2C Internal API's */ +/* Master */ +void I2C0_MasterOpen(void); +void I2C0_MasterClose(void); +char I2C0_MasterGetRxData(void); +void I2C0_MasterTxData(char d); +void I2C0_MasterTxAddr(char d); +void I2C0_MasterResetBus(void); +void I2C0_MasterIsRxOrTx(void); +void I2C0_MasterStop(void); +bool I2C0_MasterIsNack(void); +void I2C0_MasterSendAck(void); +void I2C0_MasterSendNack(void); +void I2C0_MasterClearBusCollision(void); +bool I2C0_MasterBusErrorOverride(); +bool I2C0_MasterArbitrationlostOverride(void); +void I2C0_MasterEnableIrq(void); +bool I2C0_MasterIsIrqEnabled(void); +void I2C0_MasterDisableIrq(void); +void I2C0_MasterClearIrq(void); +void I2C0_MasterWaitForEvent(void); +static void I2C0_set_callback(I2C0_callbackIndex_t idx, twi0_callback_t cb, void *funPtr); +static twi0_operations_t I2C0_RETURN_STOP(void *funPtr); +static twi0_operations_t I2C0_RETURN_RESET(void *funPtr); +static void I2C0_MasterIsr(void); + +/* Helper Functions */ +static twi0_fsm_states_t I2C0_DO_IDLE(void); +static twi0_fsm_states_t I2C0_DO_SEND_ADR_READ(void); +static twi0_fsm_states_t I2C0_DO_SEND_ADR_WRITE(void); +static twi0_fsm_states_t I2C0_DO_TX(void); +static twi0_fsm_states_t I2C0_DO_RX(void); +static twi0_fsm_states_t I2C0_DO_TX_EMPTY(void); +static twi0_fsm_states_t I2C0_DO_SEND_RESTART_READ(void); +static twi0_fsm_states_t I2C0_DO_SEND_RESTART_WRITE(void); +static twi0_fsm_states_t I2C0_DO_SEND_RESTART(void); +static twi0_fsm_states_t I2C0_DO_SEND_STOP(void); +static twi0_fsm_states_t I2C0_DO_RX_ACK(void); +static twi0_fsm_states_t I2C0_DO_TX_ACK(void); +static twi0_fsm_states_t I2C0_DO_RX_NACK_STOP(void); +static twi0_fsm_states_t I2C0_DO_RX_NACK_RESTART(void); +static twi0_fsm_states_t I2C0_DO_RESET(void); +static twi0_fsm_states_t I2C0_DO_ADDRESS_NACK(void); +static twi0_fsm_states_t I2C0_DO_BUS_COLLISION(void); +static twi0_fsm_states_t I2C0_DO_BUS_ERROR(void); + +typedef twi0_fsm_states_t(stateHandlerFunction)(void); +stateHandlerFunction *I2C0_fsmStateTable[] = { + I2C0_DO_IDLE, // I2C_IDLE + I2C0_DO_SEND_ADR_READ, // I2C_SEND_ADR_READ + I2C0_DO_SEND_ADR_WRITE, // I2C_SEND_ADR_WRITE + I2C0_DO_TX, // I2C_TX + I2C0_DO_RX, // I2C_RX + I2C0_DO_TX_EMPTY, // I2C_TX_EMPTY + I2C0_DO_SEND_RESTART_READ, // I2C_SEND_RESTART_READ + I2C0_DO_SEND_RESTART_WRITE, // I2C_SEND_RESTART_WRITE + I2C0_DO_SEND_RESTART, // I2C_SEND_RESTART + I2C0_DO_SEND_STOP, // I2C_SEND_STOP + I2C0_DO_RX_ACK, // I2C_RX_DO_ACK + I2C0_DO_TX_ACK, // I2C_TX_DO_ACK + I2C0_DO_RX_NACK_STOP, // I2C_RX_DO_NACK_STOP + I2C0_DO_RX_NACK_RESTART, // I2C_RX_DO_NACK_RESTART + I2C0_DO_RESET, // I2C_RESET + I2C0_DO_ADDRESS_NACK, // I2C_ADDRESS_NACK + I2C0_DO_BUS_COLLISION, // I2C_BUS_COLLISION + I2C0_DO_BUS_ERROR // I2C_BUS_ERROR +}; + +void I2C0_SetDataCompleteCallback(twi0_callback_t cb, void *funPtr) +{ + I2C0_set_callback(I2C_DATA_COMPLETE, cb, funPtr); +} + +void I2C0_SetWriteCollisionCallback(twi0_callback_t cb, void *funPtr) +{ + I2C0_set_callback(I2C_WRITE_COLLISION, cb, funPtr); +} + +void I2C0_SetAddressNackCallback(twi0_callback_t cb, void *funPtr) +{ + I2C0_set_callback(I2C_ADDRESSNACK, cb, funPtr); +} + +void I2C0_SetDataNackCallback(twi0_callback_t cb, void *funPtr) +{ + I2C0_set_callback(I2C_DATA_NACK, cb, funPtr); +} + +void I2C0_SetTimeoutCallback(twi0_callback_t cb, void *funPtr) +{ + I2C0_set_callback(I2C_TIMEOUT, cb, funPtr); +} + +uint8_t I2C0_Initialize() +{ + //SDASETUP 4CYC; SDAHOLD OFF; FMPEN disabled; + TWI0.CTRLA = 0x00; + + //Debug Run + TWI0.DBGCTRL = 0x00; + + //Master Baud Rate Control + TWI0.MBAUD = (uint8_t)TWI0_BAUD(100000, 0); + + //RIEN disabled; WIEN disabled; QCEN disabled; TIMEOUT DISABLED; SMEN disabled; ENABLE enabled; + TWI0.MCTRLA = 0x01; + + //RIF disabled; WIF disabled; CLKHOLD disabled; ARBLOST disabled; BUSERR disabled; BUSSTATE UNKNOWN; + TWI0.MSTATUS = 0x00; + + //Master Address + TWI0.MADDR = 0x00; + + //FLUSH disabled; ACKACT ACK; MCMD NOACT; + TWI0.MCTRLB = 0x00; + + //Master Data + TWI0.MDATA = 0x00; + + return 0; +} + +// when you call open, you supply a device address. +// if you get the bus, the function returns true +twi0_error_t I2C0_Open(twi0_address_t address) +{ + twi0_error_t ret = I2C_BUSY; + + if (!I2C0_status.inUse) { + I2C0_status.address = address; + I2C0_status.busy = 0; + I2C0_status.inUse = 1; + I2C0_status.addressNACKCheck = 0; + I2C0_status.state = I2C_RESET; + I2C0_status.timeout_value = 500; // MCC should determine a reasonable starting value here. + I2C0_status.bufferFree = 1; + + // set all the call backs to a default of sending stop + I2C0_status.callbackTable[I2C_DATA_COMPLETE] = I2C0_RETURN_STOP; + I2C0_status.callbackPayload[I2C_DATA_COMPLETE] = NULL; + I2C0_status.callbackTable[I2C_WRITE_COLLISION] = I2C0_RETURN_STOP; + I2C0_status.callbackPayload[I2C_WRITE_COLLISION] = NULL; + I2C0_status.callbackTable[I2C_ADDRESSNACK] = I2C0_RETURN_STOP; + I2C0_status.callbackPayload[I2C_ADDRESSNACK] = NULL; + I2C0_status.callbackTable[I2C_DATA_NACK] = I2C0_RETURN_STOP; + I2C0_status.callbackPayload[I2C_DATA_NACK] = NULL; + I2C0_status.callbackTable[I2C_TIMEOUT] = I2C0_RETURN_RESET; + I2C0_status.callbackPayload[I2C_TIMEOUT] = NULL; + + I2C0_MasterResetBus(); + // Reset module + I2C0_MasterClearIrq(); + + ret = I2C_NOERR; + } + return ret; +} + +void I2C0_SetAddress(twi0_address_t address) +{ + I2C0_status.address = address; +} + +// close the bus if it is not busy +twi0_error_t I2C0_Close(void) +{ + twi0_error_t ret = I2C_BUSY; + // Bus is in error state, reset I2C hardware and report error + if (I2C0_MasterBusErrorOverride()) { + I2C0_status.busy = false; + I2C0_status.error = I2C_FAIL; + } + if (!I2C0_status.busy) { + I2C0_status.inUse = 0; + // close it down + I2C0_status.address = 0xff; // 8-bit address is invalid so this is FREE + I2C0_MasterClearIrq(); + I2C0_MasterDisableIrq(); + ret = I2C0_status.error; + } + return ret; +} + +void I2C0_SetTimeout(uint8_t to) +{ + I2C0_MasterDisableIrq(); + I2C0_status.timeout_value = to; + I2C0_MasterEnableIrq(); +} + +void I2C0_SetBuffer(void *buffer, size_t bufferSize) +{ + if (I2C0_status.bufferFree) { + I2C0_status.data_ptr = buffer; + I2C0_status.data_length = bufferSize; + I2C0_status.bufferFree = false; + } +} +twi0_error_t I2C0_MasterOperation(bool read) +{ + twi0_error_t ret = I2C_BUSY; + if (!I2C0_status.busy) { + I2C0_status.busy = true; + ret = I2C_NOERR; + + if (read) { + I2C0_status.state = I2C_SEND_ADR_READ; + } else { + I2C0_status.state = I2C_SEND_ADR_WRITE; + } + I2C0_MasterIsr(); + + I2C0_Poller(); + } + return ret; +} + +twi0_error_t I2C0_MasterRead(void) + +{ + return I2C0_MasterOperation(true); +} + + + +twi0_error_t I2C0_MasterWrite(void) +{ + return I2C0_MasterOperation(false); +} + +/************************************************************************/ +/* Helper Functions */ +/************************************************************************/ + +void I2C0_Poller(void) +{ + while (I2C0_status.busy) + { + I2C0_MasterWaitForEvent(); + I2C0_MasterIsr(); + } +} + +static twi0_fsm_states_t I2C0_DO_RESET(void) +{ + I2C0_MasterResetBus(); + I2C0_status.busy = false; // Bus Free + I2C0_status.error = I2C_NOERR; + return I2C_RESET; // park the FSM on reset +} + +static twi0_fsm_states_t I2C0_DO_IDLE(void) +{ + I2C0_status.busy = false; // Bus Free + I2C0_status.error = I2C_NOERR; + return I2C_IDLE; // park the FSM on IDLE +} + +static twi0_fsm_states_t I2C0_DO_SEND_RESTART_READ(void) +{ + return I2C0_DO_SEND_ADR_READ(); +} + +static twi0_fsm_states_t I2C0_DO_SEND_RESTART_WRITE(void) +{ + return I2C0_DO_SEND_ADR_WRITE(); +} + +static twi0_fsm_states_t I2C0_DO_SEND_RESTART(void) +{ + return I2C0_DO_SEND_ADR_READ(); +} + +static twi0_fsm_states_t I2C0_DO_SEND_STOP(void) +{ + I2C0_MasterStop(); + return I2C0_DO_IDLE(); +} + +// TODO: probably need 2 addressNACK's one from read and one from write. +// the do NACK before RESTART or STOP is a special case that a new state simplifies. +static twi0_fsm_states_t I2C0_DO_ADDRESS_NACK(void) +{ + I2C0_status.addressNACKCheck = 0; + I2C0_status.error = I2C_FAIL; + switch (I2C0_status.callbackTable[I2C_ADDRESSNACK](I2C0_status.callbackPayload[I2C_ADDRESSNACK])) { + case I2C_RESTART_READ: + return I2C0_DO_SEND_RESTART_READ(); + case I2C_RESTART_WRITE: + return I2C0_DO_SEND_RESTART_WRITE(); + default: + return I2C0_DO_SEND_STOP(); + } +} + +static twi0_fsm_states_t I2C0_DO_SEND_ADR_READ(void) +{ + + I2C0_status.addressNACKCheck = 1; + I2C0_MasterTxAddr(I2C0_status.address << 1 | 1); + return I2C_RX; +} + +static twi0_fsm_states_t I2C0_DO_SEND_ADR_WRITE(void) +{ + + I2C0_status.addressNACKCheck = 1; + I2C0_MasterTxAddr(I2C0_status.address << 1); + return I2C_TX; +} + +static twi0_fsm_states_t I2C0_DO_RX_ACK(void) +{ + I2C0_MasterSendAck(); + return I2C_RX; +} + +static twi0_fsm_states_t I2C0_DO_TX_ACK(void) +{ + I2C0_MasterSendAck(); + return I2C_TX; +} + +static twi0_fsm_states_t I2C0_DO_RX_NACK_STOP(void) +{ + I2C0_MasterSendNack(); + I2C0_MasterStop(); + return I2C0_DO_IDLE(); +} + +static twi0_fsm_states_t I2C0_DO_RX_NACK_RESTART(void) +{ + I2C0_MasterSendNack(); + return I2C_SEND_RESTART; +} + +static twi0_fsm_states_t I2C0_DO_TX(void) +{ + if (I2C0_MasterIsNack()) // Slave replied with NACK + { + switch (I2C0_status.callbackTable[I2C_DATA_NACK](I2C0_status.callbackPayload[I2C_DATA_NACK])) { + case I2C_RESTART_READ: + return I2C0_DO_SEND_RESTART_READ(); + case I2C_RESTART_WRITE: + return I2C0_DO_SEND_RESTART_WRITE(); + default: + case I2C_CONTINUE: + case I2C_STOP: + return I2C0_DO_SEND_STOP(); + } + } else { + I2C0_status.addressNACKCheck = 0; + I2C0_MasterTxData(*I2C0_status.data_ptr++); + return (--I2C0_status.data_length) ? I2C_TX : I2C_TX_EMPTY; + } +} + +static twi0_fsm_states_t I2C0_DO_RX(void) +{ + I2C0_status.addressNACKCheck = 0; + + if (I2C0_status.data_length == 1) + I2C0_MasterSendNack(); // Next byte will be last to be received, setup NACK + else + I2C0_MasterSendAck(); // More bytes to receive, setup ACK + + if (--I2C0_status.data_length) { + *I2C0_status.data_ptr = I2C0_MasterGetRxData(); + I2C0_status.data_ptr++; + I2C0_MasterIsRxOrTx(); + return I2C_RX; + } else { + *I2C0_status.data_ptr = I2C0_MasterGetRxData(); + I2C0_status.data_ptr++; + I2C0_status.bufferFree = true; + switch (I2C0_status.callbackTable[I2C_DATA_COMPLETE](I2C0_status.callbackPayload[I2C_DATA_COMPLETE])) { + case I2C_RESTART_WRITE: + case I2C_RESTART_READ: + return I2C0_DO_RX_NACK_RESTART(); + default: + case I2C_CONTINUE: + case I2C_STOP: + return I2C0_DO_RX_NACK_STOP(); + } + } +} + +static twi0_fsm_states_t I2C0_DO_TX_EMPTY(void) +{ + if (I2C0_MasterIsNack()) // Slave replied with NACK + { + switch (I2C0_status.callbackTable[I2C_DATA_NACK](I2C0_status.callbackPayload[I2C_DATA_NACK])) { + case I2C_RESTART_READ: + return I2C0_DO_SEND_RESTART_READ(); + case I2C_RESTART_WRITE: + return I2C0_DO_SEND_RESTART_WRITE(); + default: + case I2C_CONTINUE: + case I2C_STOP: + return I2C0_DO_SEND_STOP(); + } + } else { + I2C0_status.bufferFree = true; + switch (I2C0_status.callbackTable[I2C_DATA_COMPLETE](I2C0_status.callbackPayload[I2C_DATA_COMPLETE])) { + case I2C_RESTART_READ: + return I2C0_DO_SEND_RESTART_READ(); + case I2C_RESTART_WRITE: + return I2C0_DO_SEND_RESTART_WRITE(); + case I2C_CONTINUE: + return I2C0_DO_TX(); + default: + case I2C_STOP: + return I2C0_DO_SEND_STOP(); + } + } +} + +static twi0_fsm_states_t I2C0_DO_BUS_COLLISION(void) +{ + // Clear bus collision status flag + I2C0_MasterClearBusCollision(); + + I2C0_status.error = I2C_FAIL; + switch (I2C0_status.callbackTable[I2C_WRITE_COLLISION](I2C0_status.callbackPayload[I2C_WRITE_COLLISION])) { + case I2C_RESTART_READ: + return I2C0_DO_SEND_RESTART_READ(); + case I2C_RESTART_WRITE: + return I2C0_DO_SEND_RESTART_WRITE(); + default: + return I2C0_DO_RESET(); + } +} + +static twi0_fsm_states_t I2C0_DO_BUS_ERROR(void) +{ + I2C0_MasterResetBus(); + I2C0_status.busy = false; + I2C0_status.error = I2C_FAIL; + return I2C_RESET; // park the FSM on reset +} + + + +void I2C0_MasterIsr(void) +{ + I2C0_MasterClearIrq(); + + // NOTE: We are ignoring the Write Collision flag. + + // Address phase received NACK from slave, override next state + if (I2C0_status.addressNACKCheck && I2C0_MasterIsNack()) { + I2C0_status.state = I2C_ADDRESS_NACK; // State Override + } + + // Bus arbitration lost to another master, override next state + if (I2C0_MasterArbitrationlostOverride()) { + I2C0_status.state = I2C_BUS_COLLISION; // State Override + } + + // Bus error, override next state + if (I2C0_MasterBusErrorOverride()) { + I2C0_status.state = I2C_BUS_ERROR; // State Override + } + + I2C0_status.state = I2C0_fsmStateTable[I2C0_status.state](); +} + +/************************************************************************/ +/* Helper Functions */ +/************************************************************************/ +static twi0_operations_t I2C0_RETURN_STOP(void *p) +{ + return I2C_STOP; +} + +static twi0_operations_t I2C0_RETURN_RESET(void *p) +{ + return I2C_RESET_LINK; +} + +static void I2C0_set_callback(I2C0_callbackIndex_t idx, twi0_callback_t cb, void *funPtr) +{ + if (cb) { + I2C0_status.callbackTable[idx] = cb; + I2C0_status.callbackPayload[idx] = funPtr; + } else { + I2C0_status.callbackTable[idx] = I2C0_RETURN_STOP; + I2C0_status.callbackPayload[idx] = NULL; + } +} + +/* Master Definitions */ + +void I2C0_MasterOpen(void) +{ + TWI0.MCTRLA = 1 << TWI_ENABLE_bp; +} + +void I2C0_MasterClose(void) +{ + TWI0.MCTRLA = 0 << TWI_ENABLE_bp; +} + +/* Interrupt Control */ +void I2C0_MasterEnableIrq(void) +{ + TWI0.MCTRLA |= (TWI_RIEN_bm | TWI_WIEN_bm); +} + +bool I2C0_MasterIsIrqEnabled(void) +{ + return ((TWI0.MCTRLA & TWI_WIEN_bm) && (TWI0.MCTRLA & TWI_RIEN_bm)); +} + +void I2C0_MasterDisableIrq(void) +{ + TWI0.MCTRLA &= ~(TWI_RIEN_bm | TWI_WIEN_bm); +} + +void I2C0_MasterClearIrq(void) +{ + TWI0.MSTATUS |= (TWI_RIF_bm | TWI_WIF_bm); +} + +bool I2C0_MasterBusErrorOverride(void) +{ + return TWI0.MSTATUS & TWI_BUSERR_bm; +} + +bool I2C0_MasterArbitrationlostOverride(void) +{ + return TWI0.MSTATUS & TWI_ARBLOST_bm; +} + +void I2C0_MasterResetBus(void) +{ + TWI0.MCTRLB |= TWI_FLUSH_bm; + TWI0.MSTATUS |= TWI_BUSSTATE_IDLE_gc; +} + +void I2C0_MasterIsRxOrTx(void) +{ + TWI0.MCTRLB |= TWI_MCMD_RECVTRANS_gc; +} + +void I2C0_MasterClearBusCollision(void) +{ + TWI0.MSTATUS |= TWI_ARBLOST_bm; +} + +void I2C0_MasterWaitForEvent(void) +{ + while (!(TWI0.MSTATUS & TWI_RIF_bm) && !(TWI0.MSTATUS & TWI_WIF_bm)) + { + }; +} + +void I2C0_MasterStop(void) +{ + TWI0.MCTRLB |= TWI_MCMD_STOP_gc; +} + +bool I2C0_MasterIsNack(void) +{ + return TWI0.MSTATUS & TWI_RXACK_bm; +} + +char I2C0_MasterGetRxData(void) +{ + return TWI0.MDATA; +} + +void I2C0_MasterTxData(char d) +{ + TWI0.MDATA = d; +} + +void I2C0_MasterTxAddr(char d) +{ + TWI0.MADDR = d; +} + +void I2C0_MasterSendAck(void) +{ + TWI0.MCTRLB &= ~(1 << TWI_ACKACT_bp); +} + +void I2C0_MasterSendNack(void) +{ + TWI0.MCTRLB |= TWI_ACKACT_NACK_gc; +} + +twi0_operations_t I2C0_SetReturnStopCallback(void *funPtr) +{ + return I2C_STOP; +} + +twi0_operations_t I2C0_SetReturnResetCallback(void *funPtr) +{ + return I2C_RESET_LINK; +} + +twi0_operations_t I2C0_SetRestartWriteCallback(void *funPtr) +{ + return I2C_RESTART_WRITE; +} + +twi0_operations_t I2C0_SetRestartReadCallback(void *funPtr) +{ + return I2C_RESTART_READ; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/src/usart2.c b/AVRIoT.X/mcc_generated_files/src/usart2.c new file mode 100644 index 0000000..7b18b84 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/src/usart2.c @@ -0,0 +1,278 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include "../include/usart2.h" + +#if defined(__GNUC__) + +int USART2_printCHAR(char character, FILE *stream) +{ + USART2_Write(character); + return 0; +} + +FILE USART2_stream = FDEV_SETUP_STREAM(USART2_printCHAR, NULL, _FDEV_SETUP_WRITE); + +#elif defined(__ICCAVR__) + +int putchar(int outChar) +{ + USART2_Write(outChar); + return outChar; +} +#endif + +/* Static Variables holding the ringbuffer used in IRQ mode */ +static uint8_t USART2_rxbuf[USART2_RX_BUFFER_SIZE]; +static volatile uint8_t USART2_rx_head; +static volatile uint8_t USART2_rx_tail; +static volatile uint8_t USART2_rx_elements; +static uint8_t USART2_txbuf[USART2_TX_BUFFER_SIZE]; +static volatile uint8_t USART2_tx_head; +static volatile uint8_t USART2_tx_tail; +static volatile uint8_t USART2_tx_elements; + +void (*USART2_rx_isr_cb)(void) = &USART2_DefaultRxIsrCb; + +void (*USART2_tx_isr_cb)(void) = &USART2_DefaultTxIsrCb; + +void USART2_DefaultRxIsrCb(void) +{ + uint8_t data; + uint8_t tmphead; + + /* Read the received data */ + data = USART2.RXDATAL; + /* Calculate buffer index */ + tmphead = (USART2_rx_head + 1) & USART2_RX_BUFFER_MASK; + + if (tmphead == USART2_rx_tail) { + /* ERROR! Receive buffer overflow */ + }else { + /*Store new index*/ + USART2_rx_head = tmphead; + + /* Store received data in buffer */ + USART2_rxbuf[tmphead] = data; + USART2_rx_elements++; + } +} + +void USART2_DefaultTxIsrCb(void) +{ + uint8_t tmptail; + + /* Check if all data is transmitted */ + if (USART2_tx_elements != 0) { + /* Calculate buffer index */ + tmptail = (USART2_tx_tail + 1) & USART2_TX_BUFFER_MASK; + /* Store new index */ + USART2_tx_tail = tmptail; + /* Start transmission */ + USART2.TXDATAL = USART2_txbuf[tmptail]; + + USART2_tx_elements--; + } + + if (USART2_tx_elements == 0) { + /* Disable Tx interrupt */ + USART2.CTRLA &= ~(1 << USART_DREIE_bp); + } +} + +void USART2_SetISRCb(usart_callback cb, usart2_cb_t type) +{ + switch (type) { + case USART2_RX_CB: + USART2_rx_isr_cb = cb; + break; + case USART2_TX_CB: + USART2_tx_isr_cb = cb; + break; + default: + // do nothing + break; + } +} + +void USART2_SetRXISRCb(usart_callback cb) +{ + USART2_SetISRCb(cb,USART2_RX_CB); +} + +void USART2_SetTXISRCb(usart_callback cb) +{ + USART2_SetISRCb(cb,USART2_TX_CB); +} + +/* Interrupt service routine for RX complete */ +ISR(USART2_RXC_vect) +{ + if (USART2_rx_isr_cb != NULL) + { + (*USART2_rx_isr_cb)(); + } +} + +/* Interrupt service routine for Data Register Empty */ +ISR(USART2_DRE_vect) +{ + if (USART2_tx_isr_cb != NULL) + { + (*USART2_tx_isr_cb)(); + } +} + +ISR(USART2_TXC_vect) +{ + USART2.STATUS |= USART_TXCIF_bm; +} + +bool USART2_IsTxReady() +{ + return (USART2_tx_elements != USART2_TX_BUFFER_SIZE); +} + +bool USART2_IsRxReady() +{ + return (USART2_rx_elements != 0); +} + +bool USART2_IsTxBusy() +{ + return (!(USART2.STATUS & USART_TXCIF_bm)); +} + +bool USART2_IsTxDone() +{ + return (USART2.STATUS & USART_TXCIF_bm); +} + +uint8_t USART2_Read(void) +{ + uint8_t tmptail; + + /* Wait for incoming data */ + while (USART2_rx_elements == 0) + ; + /* Calculate buffer index */ + tmptail = (USART2_rx_tail + 1) & USART2_RX_BUFFER_MASK; + /* Store new index */ + USART2_rx_tail = tmptail; + ENTER_CRITICAL(R); + USART2_rx_elements--; + EXIT_CRITICAL(R); + + /* Return data */ + return USART2_rxbuf[tmptail]; +} + +void USART2_Write(const uint8_t data) +{ + uint8_t tmphead; + + /* Calculate buffer index */ + tmphead = (USART2_tx_head + 1) & USART2_TX_BUFFER_MASK; + /* Wait for free space in buffer */ + while (USART2_tx_elements == USART2_TX_BUFFER_SIZE) + ; + /* Store data in buffer */ + USART2_txbuf[tmphead] = data; + /* Store new index */ + USART2_tx_head = tmphead; + ENTER_CRITICAL(W); + USART2_tx_elements++; + EXIT_CRITICAL(W); + /* Enable Tx interrupt */ + USART2.CTRLA |= (1 << USART_DREIE_bp); +} + +void USART2_Initialize() +{ + //set baud rate register + USART2.BAUD = (uint16_t)USART2_BAUD_RATE(9600); + + //RXCIE enabled; TXCIE enabled; DREIE disabled; RXSIE enabled; LBME disabled; ABEIE disabled; RS485 OFF; + USART2.CTRLA = 0xD0; + + //RXEN enabled; TXEN enabled; SFDEN disabled; ODME disabled; RXMODE NORMAL; MPCM disabled; + USART2.CTRLB = 0xC0; + + //CMODE ASYNCHRONOUS; PMODE DISABLED; SBMODE 1BIT; CHSIZE 8BIT; UDORD disabled; UCPHA disabled; + USART2.CTRLC = 0x03; + + //DBGCTRL_DBGRUN + USART2.DBGCTRL = 0x00; + + //EVCTRL_IREI + USART2.EVCTRL = 0x00; + + //RXPLCTRL_RXPL + USART2.RXPLCTRL = 0x00; + + //TXPLCTRL_TXPL + USART2.TXPLCTRL = 0x00; + + + uint8_t x; + + /* Initialize ringbuffers */ + x = 0; + + USART2_rx_tail = x; + USART2_rx_head = x; + USART2_rx_elements = x; + USART2_tx_tail = x; + USART2_tx_head = x; + USART2_tx_elements = x; + +#if defined(__GNUC__) + stdout = &USART2_stream; +#endif + +} + +void USART2_Enable() +{ + USART2.CTRLB |= USART_RXEN_bm | USART_TXEN_bm; +} + +void USART2_EnableRx() +{ + USART2.CTRLB |= USART_RXEN_bm; +} + +void USART2_EnableTx() +{ + USART2.CTRLB |= USART_TXEN_bm; +} + +void USART2_Disable() +{ + USART2.CTRLB &= ~(USART_RXEN_bm | USART_TXEN_bm); +} + +uint8_t USART2_GetData() +{ + return USART2.RXDATAL; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/time_service.c b/AVRIoT.X/mcc_generated_files/time_service.c new file mode 100644 index 0000000..8fcde54 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/time_service.c @@ -0,0 +1,110 @@ +/* + \file time_service.c + + \brief Manage Application's Time Service Requirements + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ +#include +#include "time_service.h" +//#include "timeout.h" +#include "drivers/timeout.h" + +static uint32_t timeTicker(void *payload); +static timerStruct_t timeTask = {timeTicker}; + +static uint32_t currentTime = 0; +static uint32_t stampTime = 0; + +#define ONE_SECOND_TICKER 1000L +#define TIME_OFFSET UNIX_OFFSET + +void TIME_setCurrent(uint32_t newTime) +{ + currentTime = newTime; +} + +uint32_t TIME_getCurrent(void) +{ + return currentTime; +} + +void TIME_setStamp(uint32_t newStamp) +{ + stampTime = newStamp; +} + +uint32_t TIME_getStamp(void) +{ + return stampTime; +} + +static uint32_t timeTicker(void *payload) +{ + currentTime++; // Increment Reference each Second + return ONE_SECOND_TICKER; // Reload to call self +} + +void TIME_startTask(void) +{ + timeout_create(&timeTask, ONE_SECOND_TICKER); +} + +void TIME_endTask(void) +{ + timeout_delete(&timeTask); +} + +uint32_t TIME_getOffset_UNIX(void) +{ + return TIME_OFFSET; +} + +char *TIME_GetcTime(uint32_t timeToConvert) +{ + return ctime((time_t)&timeToConvert); +} + +int32_t TIME_getDiffTime(int32_t diffTime1, int32_t diffTime0) +{ + return difftime((time_t)diffTime1, (time_t)diffTime0); +} + +uint32_t TIME_ntpTimeStamp(tstrSystemTime* WINCTime) +{ + struct tm theTime; + uint32_t mkTimeResult = 0; +// Convert to UNIX_EPOCH, this mktime uses years since 1900 and months are 0 based so we +// are doing a couple of adjustments here. + theTime.tm_hour = WINCTime->u8Hour; + theTime.tm_min = WINCTime->u8Minute; + theTime.tm_sec = WINCTime->u8Second; + theTime.tm_year = WINCTime->u16Year-1900; + theTime.tm_mon = WINCTime->u8Month-1; + theTime.tm_mday = WINCTime->u8Day; + theTime.tm_isdst = 0; +// Capture and Store + mkTimeResult = mktime(&theTime); + TIME_setCurrent(mkTimeResult); +// AVR set Time(null) value + set_system_time(mkTimeResult); +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/time_service.h b/AVRIoT.X/mcc_generated_files/time_service.h new file mode 100644 index 0000000..8585d7f --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/time_service.h @@ -0,0 +1,44 @@ +/* + \file time_service.h + + \brief Manage Application's Time Service Requirements + + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ +#ifndef TIME_SERVICE_H_ +#define TIME_SERVICE_H_ +#include + +#include "winc/m2m/m2m_types.h" + +void TIME_setCurrent(uint32_t); +uint32_t TIME_getCurrent(void); +void TIME_setStamp(uint32_t); +uint32_t TIME_getStamp(void); +void Time_startTask(void); +void Time_endTask(void); +uint32_t TIME_getOffset_UNIX(void); +char *TIME_GetcTime(uint32_t timeToConvert); +int32_t TIME_getDiffTime(int32_t diffTime1, int32_t diffTime0); +uint32_t TIME_ntpTimeStamp(tstrSystemTime* WINCTime); + +#endif /* TIME_SERVICE_H_ */ diff --git a/AVRIoT.X/mcc_generated_files/utils/assembler.h b/AVRIoT.X/mcc_generated_files/utils/assembler.h new file mode 100644 index 0000000..6a321d5 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/utils/assembler.h @@ -0,0 +1,39 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef ASSEMBLER_H_INCLUDED +#define ASSEMBLER_H_INCLUDED + +#if !defined(__ASSEMBLER__) && !defined(__IAR_SYSTEMS_ASM__) && !defined(__DOXYGEN__) +#error This file may only be included from assembly files +#endif + +#if defined(__ASSEMBLER__) +#include "assembler/gas.h" +#include +#elif defined(__IAR_SYSTEMS_ASM__) +#include "assembler/iar.h" +#include +#endif + +#endif /* ASSEMBLER_H_INCLUDED */ diff --git a/AVRIoT.X/mcc_generated_files/utils/assembler/gas.h b/AVRIoT.X/mcc_generated_files/utils/assembler/gas.h new file mode 100644 index 0000000..9913032 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/utils/assembler/gas.h @@ -0,0 +1,106 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef ASSEMBLER_GAS_H_INCLUDED +#define ASSEMBLER_GAS_H_INCLUDED + +#ifndef __DOXYGEN__ + +/* clang-format off */ + + /* IAR doesn't accept dots in macro names */ + .macro ld_addr, reg, sym + lda.w \reg, \sym + .endm + + /* Define a function \a name that is either globally visible or only + * file-local. + */ + .macro gas_begin_func name, is_public + .if \is_public + .global \name + .endif + .section .text.\name, "ax", @progbits + .type \name, @function + \name : + .endm + + /* Define a function \a name that is either globally visible or only + * file-local in a given segment. + */ + .macro gas_begin_func_segm name, is_public, segment + .if \is_public + .global \name + .endif + .section .\segment, "ax", @progbits + .type \name, @function + \name : + .endm + + /* Define \a name as a weak alias for the function \a strong_name */ + .macro gas_weak_function_alias name, strong_name + .global \name + .weak \name + .type \name, @function + .set \name, \strong_name + .endm + + /* Define a weak function called \a name */ + .macro gas_weak_function name + .weak \name + gas_begin_func \name 1 + .endm + +#define REPEAT(count) .rept count +#define END_REPEAT() .endr +#define FILL_BYTES(count) .fill count +#define SET_LOC(offset) .org offset +#define L(name) .L##name +#define EXTERN_SYMBOL(name) + +#define TEXT_SECTION(name) \ + .section name, "ax", @progbits +#define RODATA_SECTION(name) \ + .section name, "a", @progbits +#define DATA_SECTION(name) \ + .section name, "aw", @progbits +#define BSS_SECTION(name) \ + .section name, "aw", @nobits + +#define FUNCTION(name) gas_begin_func name 0 +#define PUBLIC_FUNCTION(name) gas_begin_func name 1 +#define PUBLIC_FUNCTION_SEGMENT(name, segment) \ + gas_begin_func_segm name 1 segment +#define WEAK_FUNCTION(name) gas_weak_function name +#define WEAK_FUNCTION_ALIAS(name, strong_name) \ + gas_weak_function_alias name strong_name +#define END_FUNC(name) \ + .size name, . - name + +#define END_FILE() + +/* clang-format on */ + +#endif /* __DOXYGEN__ */ + +#endif /* ASSEMBLER_GAS_H_INCLUDED */ diff --git a/AVRIoT.X/mcc_generated_files/utils/assembler/iar.h b/AVRIoT.X/mcc_generated_files/utils/assembler/iar.h new file mode 100644 index 0000000..12a3cee --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/utils/assembler/iar.h @@ -0,0 +1,94 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef ASSEMBLER_IAR_H_INCLUDED +#define ASSEMBLER_IAR_H_INCLUDED + +/* clang-format off */ + +ld_addr MACRO reg, sym + mov reg, LWRD sym + orh reg, HWRD sym + ENDM + +call MACRO sym + rcall sym + ENDM + +iar_begin_func MACRO name, sect, is_public, is_weak + MODULE name + RSEG CODE:CODE:NOROOT(1) + IF is_weak == 1 + PUBWEAK name + ELSEIF is_public + PUBLIC name + ENDIF +name: + ENDM + +iar_begin_func_segm MACRO name, sect, is_public, is_weak, segment + MODULE name + RSEG segment:CODE:NOROOT(1) + IF is_weak == 1 + PUBWEAK name + ELSEIF is_public + PUBLIC name + ENDIF +name: + ENDM + +iar_weak_alias MACRO name, strong_name + PUBWEAK name +name: + rjmp strong_name + ENDM + +#define lo(x) LWRD x +#define hi(x) HWRD x + +#define REPEAT(count) REPT count +#define END_REPEAT() ENDR +#define SET_LOC(offset) ORG offset +#define END_FILE() END + +#define FILL_BYTES(count) DS8 count + +#define L(name) name +#define EXTERN_SYMBOL(name) EXTERN name +#define FUNCTION(name) iar_begin_func name, text_##name, 0, 0 +#define PUBLIC_FUNCTION(name) iar_begin_func name, text_##name, 1, 0 +#define PUBLIC_FUNCTION_SEGMENT(name, segment) \ + iar_begin_func_segm name, text_##name, 1, 0, segment +#define WEAK_FUNCTION(name) iar_begin_func name, text_##name, 1, 1 +#define WEAK_FUNCTION_ALIAS(name, strong_name) \ + iar_weak_alias name, strong_name +#define END_FUNC(name) ENDMOD + +#define TEXT_SECTION(name) RSEG name:CODE:NOROOT +#define RODATA_SECTION(name) RSEG name:CONST:NOROOT +#define DATA_SECTION(name) RSEG name:DATA:NOROOT +#define BSS_SECTION(name) RSEG name:DATA:NOROOT + +/* clang-format on */ + +#endif /* ASSEMBLER_IAR_H_INCLUDED */ diff --git a/AVRIoT.X/mcc_generated_files/utils/atomic.h b/AVRIoT.X/mcc_generated_files/utils/atomic.h new file mode 100644 index 0000000..b3d1526 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/utils/atomic.h @@ -0,0 +1,103 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef ATOMIC_H +#define ATOMIC_H + +/** + * \defgroup doc_driver_utils_atomic Atomic memory access and critical sections + * \ingroup doc_driver_utils + * + * Atomic memory access and critical sections + * + * \{ + */ + +/* clang-format off */ + +#if defined(__GNUC__) || defined (__DOXYGEN__) + +/** + * \brief Enter a critical region + * + * Saves the contents of the status register, including the Global + * Interrupt Enable bit, so that it can be restored upon leaving the + * critical region. Thereafter, clears the Global Interrupt Enable Bit. + * This macro takes a parameter P that is unused for the GCC compiler, + * but necessary for code compatibility with the IAR compiler. The IAR + * compiler declares a variable with the name of the parameter for + * holding the SREG value. Since a variable is declared in the macro, + * this variable must have a name that is unique within the scope + * that the critical region is declared within, otherwise compilation + * will fail. + * + * \param[in] UNUSED(GCC)/P(IAR) Name of variable storing SREG + * + */ + +#define ENTER_CRITICAL(UNUSED) __asm__ __volatile__ ( \ + "in __tmp_reg__, __SREG__" "\n\t" \ + "cli" "\n\t" \ + "push __tmp_reg__" "\n\t" \ + ::: "memory" \ + ) + +/** + * \brief Exit a critical region + * + * Restores the contents of the status register, including the Global + * Interrupt Enable bit, as it was when entering the critical region. + * This macro takes a parameter P that is unused for the GCC compiler, + * but necessary for code compatibility with the IAR compiler. The IAR + * compiler uses this parameter as the name of a variable that holds + * the SREG value. The parameter must be identical to the parameter + * used in the corresponding ENTER_CRITICAL(). + * + * \param[in] UNUSED(GCC)/P(IAR) Name of variable storing SREG + * + */ + +#define EXIT_CRITICAL(UNUSED) __asm__ __volatile__ ( \ + "pop __tmp_reg__" "\n\t" \ + "out __SREG__, __tmp_reg__" "\n\t" \ + ::: "memory" \ + ) + +#define DISABLE_INTERRUPTS() __asm__ __volatile__ ( "cli" ::: "memory") +#define ENABLE_INTERRUPTS() __asm__ __volatile__ ( "sei" ::: "memory") + +#elif defined(__ICCAVR__) + +#define ENTER_CRITICAL(P) unsigned char P = __save_interrupt();__disable_interrupt(); +#define EXIT_CRITICAL(P) __restore_interrupt(P); + +#define DISABLE_INTERRUPTS() __disable_interrupt(); +#define ENABLE_INTERRUPTS() __enable_interrupt(); + +#else +# error Unsupported compiler. +#endif + +/* clang-format on */ + +#endif /* ATOMIC_H */ diff --git a/AVRIoT.X/mcc_generated_files/utils/compiler.h b/AVRIoT.X/mcc_generated_files/utils/compiler.h new file mode 100644 index 0000000..1f5ca8f --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/utils/compiler.h @@ -0,0 +1,70 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef UTILS_COMPILER_H +#define UTILS_COMPILER_H + +/** + * \defgroup doc_driver_utils_compiler Compiler abstraction + * \ingroup doc_driver_utils + * + * Compiler abstraction layer and code utilities for 8-bit AVR. + * This module provides various abstraction layers and utilities + * to make code compatible between different compilers. + * + * \{ + */ + +#if defined(__GNUC__) +#include +#include +#elif defined(__ICCAVR__) +#define ENABLE_BIT_DEFINITIONS 1 +#include +#include + +#ifndef CCP_IOREG_gc +#define CCP_IOREG_gc 0xD8 /* CPU_CCP_IOREG_gc */ +#endif +#ifndef CCP_SPM_gc +#define CCP_SPM_gc 0x9D /* CPU_CCP_SPM_gc */ +#endif + +#else +#error Unsupported compiler. +#endif + +#include +#include +#include +#include + +#include "interrupt_avr8.h" + +/** + * \def UNUSED + * \brief Marking \a v as a unused parameter or value. + */ +#define UNUSED(v) (void)(v) + +#endif /* UTILS_COMPILER_H */ diff --git a/AVRIoT.X/mcc_generated_files/utils/interrupt_avr8.h b/AVRIoT.X/mcc_generated_files/utils/interrupt_avr8.h new file mode 100644 index 0000000..5502ef1 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/utils/interrupt_avr8.h @@ -0,0 +1,90 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +/** + * \defgroup doc_driver_utils_interrupts ISR abstraction + * \ingroup doc_driver_utils + * + * Interrupt-related functionality. + * + * \{ + */ + +#ifndef UTILS_INTERRUPT_AVR8_H +#define UTILS_INTERRUPT_AVR8_H + +/** + * \weakgroup interrupt_group + * + * @{ + */ + +#ifdef ISR_CUSTOM_H +#include ISR_CUSTOM_H +#else + +/** + * \def ISR + * \brief Define service routine for specified interrupt vector + * + * Usage: + * \code + ISR(FOO_vect) + { + ... + } +\endcode + * + * \param vect Interrupt vector name as found in the device header files. + */ +#if defined(__DOXYGEN__) +#define ISR(vect) +#elif defined(__GNUC__) +#include +#elif defined(__ICCAVR__) +#define __ISR(x) _Pragma(#x) +#define ISR(vect) __ISR(vector = vect) __interrupt void handler_##vect(void) +#endif +#endif // ISR_CUSTOM_H + +#ifdef __GNUC__ +#define cpu_irq_enable() sei() +#define cpu_irq_disable() cli() +#else +#define cpu_irq_enable() __enable_interrupt() +#define cpu_irq_disable() __disable_interrupt() +#endif + +//! @} + +/** + * \weakgroup interrupt_deprecated_group + * @{ + */ +// Deprecated definitions. +#define Enable_global_interrupt() cpu_irq_enable() +#define Disable_global_interrupt() cpu_irq_disable() +#define Is_global_interrupt_enabled() cpu_irq_is_enabled() +//! @} + +#endif /* UTILS_INTERRUPT_AVR8_H */ diff --git a/AVRIoT.X/mcc_generated_files/utils/utils.h b/AVRIoT.X/mcc_generated_files/utils/utils.h new file mode 100644 index 0000000..4dd41b5 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/utils/utils.h @@ -0,0 +1,51 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +/** + * \defgroup doc_driver_utils AVR Code utility functions + * + * Compiler abstraction layer and code utilities for AVR. + * This module provides various abstraction layers and utilities + * to make code compatible between different compilers. + * + * \{ + */ + +#ifndef UTILS_H_INCLUDED +#define UTILS_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Retrieve array size + */ +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif /* UTILS_H_INCLUDED */ diff --git a/AVRIoT.X/mcc_generated_files/utils/utils_assert.h b/AVRIoT.X/mcc_generated_files/utils/utils_assert.h new file mode 100644 index 0000000..830b74c --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/utils/utils_assert.h @@ -0,0 +1,62 @@ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +/** + * \defgroup doc_driver_utils_assert Functionality for assert. + * \ingroup doc_driver_utils + * + * \{ + */ + +#ifndef _ASSERT_H_INCLUDED +#define _ASSERT_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * \brief Assert macro + * + * This macro is used to throw asserts. It can be mapped to different function + * based on debug level. + * + * \param[in] condition A condition to be checked; + * assert is thrown if the given condition is false + */ + +#ifdef DEBUG +#define ASSERT(condition) \ + if (!(condition)) \ + while (true) \ + ; +#else +#define ASSERT(condition) ((void)0) +#endif + +#ifdef __cplusplus +} +#endif +#endif /* _ASSERT_H_INCLUDED */ diff --git a/AVRIoT.X/mcc_generated_files/winc/common/ecc_types.h b/AVRIoT.X/mcc_generated_files/winc/common/ecc_types.h new file mode 100644 index 0000000..fda9255 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/common/ecc_types.h @@ -0,0 +1,199 @@ +/** + * + * \file + * + * \brief Elliptic Curve Cryptography Module Interface. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef __ECC_TYPES_H__ +#define __ECC_TYPES_H__ + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +MACROS +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + +#define ECC_LARGEST_CURVE_SIZE (32) +/*!< + The size of the the largest supported EC. For now, assuming + the 256-bit EC is the largest supported curve type. +*/ + + +#define ECC_POINT_MAX_SIZE ECC_LARGEST_CURVE_SIZE +/*!< + Maximum size of one coordinate of an EC point. +*/ + + +#define ECC_POINT_MAX_SIZE_WORDS (ECC_POINT_MAX_SIZE / 4) +/*!< + SIZE in 32-bit words. +*/ + + +#define ECC_NUM_SUPP_CURVES ((sizeof(gastrECCSuppList)) / (sizeof(tstrEllipticCurve))) +/*!< +*/ + + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +DATA TYPES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + +/*! +@enum \ + tenuEcNamedCurve + +@brief EC Named Curves + + Defines a list of supported ECC named curves. +*/ +typedef enum EcNamedCurve{ + EC_SECP192R1 = 19, + /*!< + It is defined by NIST as P192 and by the SEC Group as secp192r1. + */ + EC_SECP256R1 = 23, + /*!< + It is defined by NIST as P256 and by the SEC Group as secp256r1. + */ + EC_SECP384R1 = 24, + /*!< + It is defined by NIST as P384 and by the SEC Group as secp384r1. + */ + EC_SECP521R1 = 25, + /*!< + It is defined by NIST as P521 and by the SEC Group as secp521r1. + */ + EC_UNKNOWN = 255 +}tenuEcNamedCurve; + + +/*! +@struct \ + tstrECPoint + +@brief Elliptic Curve point representation +*/ +typedef struct EcPoint{ + uint8_t X[ECC_POINT_MAX_SIZE]; + /*!< + The X-coordinate of the ec point. + */ + uint8_t Y[ECC_POINT_MAX_SIZE]; + /*!< + The Y-coordinate of the ec point. + */ + uint16_t u16Size; + /*!< + Point size in bytes (for each of the coordinates). + */ + uint16_t u16PrivKeyID; + /*!< + ID for the corresponding private key. + */ +}tstrECPoint; + + +/*! +@struct \ + tstrECDomainParam + +@brief ECC Curve Domain Parameters + + The structure defines the ECC domain parameters for curves defined over prime finite fields. +*/ +typedef struct EcDomainParam{ + uint32_t p[ECC_POINT_MAX_SIZE_WORDS]; + uint32_t a[ECC_POINT_MAX_SIZE_WORDS]; + uint32_t b[ECC_POINT_MAX_SIZE_WORDS]; + tstrECPoint G; +}tstrECDomainParam; + + +/*! +@struct \ + tstrEllipticCurve + +@brief + Definition of an elliptic curve +*/ +typedef struct{ + tenuEcNamedCurve enuType; + tstrECDomainParam strParam; +}tstrEllipticCurve; + + +typedef enum{ + ECC_REQ_NONE, + ECC_REQ_CLIENT_ECDH, + ECC_REQ_SERVER_ECDH, + ECC_REQ_GEN_KEY, + ECC_REQ_SIGN_GEN, + ECC_REQ_SIGN_VERIFY +}tenuEccREQ; + + +typedef struct{ + tstrECPoint strPubKey; + uint8_t au8Key[ECC_POINT_MAX_SIZE]; +}tstrEcdhReqInfo; + + +typedef struct{ + uint32_t u32nSig; +}tstrEcdsaVerifyReqInfo; + + +typedef struct{ + uint16_t u16CurveType; + uint16_t u16HashSz; +}tstrEcdsaSignReqInfo; + + +typedef struct{ + uint16_t u16REQ; + uint16_t u16Status; + uint32_t u32UserData; + uint32_t u32SeqNo; + union{ + tstrEcdhReqInfo strEcdhREQ; + tstrEcdsaSignReqInfo strEcdsaSignREQ; + tstrEcdsaVerifyReqInfo strEcdsaVerifyREQ; + }; +}tstrEccReqInfo; + +#endif /* __ECC_TYPES_H__ */ diff --git a/AVRIoT.X/mcc_generated_files/winc/common/winc_1500_3A0_registers.h b/AVRIoT.X/mcc_generated_files/winc/common/winc_1500_3A0_registers.h new file mode 100644 index 0000000..36b0a02 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/common/winc_1500_3A0_registers.h @@ -0,0 +1,103 @@ +/** + * + * \file + * + * \brief WINC Driver WINC1500 3A0 Hardware Registers. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef _WINC_1500_3A0_REGISTERS_H_ +#define _WINC_1500_3A0_REGISTERS_H_ + +#define NMI_CLOCKLESS_REG_BASE (0x00) +#define NMI_PERIPH_REG_BASE (0x1000) +#define NMI_INTR_REG_BASE (0x1A00) +#define NMI_SPI_REG_BASE (0xE800) +#define SPI_FLASH_BASE (0x10200) + +#define WAKE_CLK_REG (NMI_CLOCKLESS_REG_BASE + 0x01) +#define HOST_CORT_COMM (NMI_CLOCKLESS_REG_BASE + 0x0B) +#define CLOCKS_EN_REG (NMI_CLOCKLESS_REG_BASE + 0x0F) +#define CORT_HOST_COMM (NMI_CLOCKLESS_REG_BASE + 0x10) + +#define NMI_CHIPID (NMI_PERIPH_REG_BASE + 0x000) +#define NMI_EFUSE_0_CONTROL (NMI_PERIPH_REG_BASE + 0x014) +#define NMI_REV_REG_ATE (NMI_PERIPH_REG_BASE + 0x048) /*Revision info register in case of ATE firmware*/ +#define WIFI_HOST_RCV_CTRL_3 (NMI_PERIPH_REG_BASE + 0x06C) +#define WIFI_HOST_RCV_CTRL_0 (NMI_PERIPH_REG_BASE + 0x070) +#define WIFI_HOST_RCV_CTRL_2 (NMI_PERIPH_REG_BASE + 0x078) +#define WIFI_HOST_RCV_CTRL_1 (NMI_PERIPH_REG_BASE + 0x084) +#define DUMMY_REGISTER WIFI_HOST_RCV_CTRL_1 +#define WIFI_HOST_RCV_CTRL_5 (NMI_PERIPH_REG_BASE + 0x088) +#define NMI_STATE_REG (NMI_PERIPH_REG_BASE + 0x08C) +#define NMI_CORTUS_BOOT_RESET_MUXSEL (NMI_PERIPH_REG_BASE + 0x118) +#define NMI_RF_REVID (NMI_PERIPH_REG_BASE + 0x3F4) +#define NMI_GLB_RESET_0 (NMI_PERIPH_REG_BASE + 0x400) +#define NMI_PIN_MUX_0 (NMI_PERIPH_REG_BASE + 0x408) +#define NMI_PIN_MUX_1 (NMI_PERIPH_REG_BASE + 0x410) +#define NMI_PLL_INTERNAL_3 (NMI_PERIPH_REG_BASE + 0x41C) +#define MMI_MISC_CTRL (NMI_PERIPH_REG_BASE + 0x428) +#define NMI_GP_REG_0 (NMI_PERIPH_REG_BASE + 0x49C) +#define NMI_GP_REG_1 (NMI_PERIPH_REG_BASE + 0x4A0) + +#define NMI_INTR_ENABLE (NMI_INTR_REG_BASE + 0x000) + +#define NMI_SPI_CTL (NMI_SPI_REG_BASE + 0x000) +#define NMI_SPI_MASTER_DMA_ADDR (NMI_SPI_REG_BASE + 0x004) +#define NMI_SPI_MASTER_DMA_COUNT (NMI_SPI_REG_BASE + 0x008) +#define NMI_SPI_SLAVE_DMA_ADDR (NMI_SPI_REG_BASE + 0x00C) +#define NMI_SPI_SLAVE_DMA_COUNT (NMI_SPI_REG_BASE + 0x010) +#define NMI_SPI_TX_MODE (NMI_SPI_REG_BASE + 0x020) +#define NMI_SPI_PROTOCOL_CONFIG (NMI_SPI_REG_BASE + 0x024) +#define NMI_SPI_INTR_CTL (NMI_SPI_REG_BASE + 0x02C) +#define NMI_SPI_MISC_CTRL (NMI_SPI_REG_BASE + 0x048) + +#define SPI_FLASH_MODE (SPI_FLASH_BASE + 0x00) +#define SPI_FLASH_CMD_CNT (SPI_FLASH_BASE + 0x04) +#define SPI_FLASH_DATA_CNT (SPI_FLASH_BASE + 0x08) +#define SPI_FLASH_BUF1 (SPI_FLASH_BASE + 0x0C) +#define SPI_FLASH_BUF2 (SPI_FLASH_BASE + 0x10) +#define SPI_FLASH_BUF_DIR (SPI_FLASH_BASE + 0x14) +#define SPI_FLASH_TR_DONE (SPI_FLASH_BASE + 0x18) +#define SPI_FLASH_DMA_ADDR (SPI_FLASH_BASE + 0x1C) +#define SPI_FLASH_MSB_CTL (SPI_FLASH_BASE + 0x20) +#define SPI_FLASH_TX_CTL (SPI_FLASH_BASE + 0x24) + +#define NMI_REV_REG (0x207AC) /*Also, Used to load ATE firmware from SPI Flash and to ensure that it is running too*/ +#define M2M_WAIT_FOR_HOST_REG (0x207BC) + +#define NMI_GP_REG_2 (0xC0008) +#define BOOTROM_REG (0xC000C) + +#define WIFI_HOST_RCV_CTRL_4 (0x150400) + +#endif /* _WINC_1500_3A0_REGISTERS_H_ */ diff --git a/AVRIoT.X/mcc_generated_files/winc/common/winc_debug.h b/AVRIoT.X/mcc_generated_files/winc/common/winc_debug.h new file mode 100644 index 0000000..99f1534 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/common/winc_debug.h @@ -0,0 +1,73 @@ +/** + * + * \file + * + * \brief This module contains debug APIs declarations. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef _WINC_DEBUG_H_ +#define _WINC_DEBUG_H_ + +#define WINC_LOG_LEVEL_NONE 0 +#define WINC_LOG_LEVEL_ERROR 1 +#define WINC_LOG_LEVEL_INFO 2 +#define WINC_LOG_LEVEL_DEBUG 3 + +#define WINC_LOG_ERROR(...) +#define WINC_LOG_INFO(...) +#define WINC_LOG_DEBUG(...) + +#if defined(CONF_WINC_PRINTF) && defined(CONF_WINC_DEBUG_LEVEL) && (CONF_WINC_DEBUG_LEVEL > 0) + +#if (CONF_WINC_DEBUG_LEVEL >= WINC_LOG_LEVEL_ERROR) +#undef WINC_LOG_ERROR +#define WINC_LOG_ERROR(...) do { CONF_WINC_PRINTF("[error][%s][%u]", __FUNCTION__, (uint16_t)__LINE__); CONF_WINC_PRINTF(__VA_ARGS__); CONF_WINC_PRINTF("\r\n"); } while(0) +#if (CONF_WINC_DEBUG_LEVEL >= WINC_LOG_LEVEL_INFO) +#undef WINC_LOG_INFO +#define WINC_LOG_INFO(...) do { CONF_WINC_PRINTF("[info]" __VA_ARGS__); CONF_WINC_PRINTF("\r\n"); } while(0) +#if (CONF_WINC_DEBUG_LEVEL >= WINC_LOG_LEVEL_DEBUG) +#undef WINC_LOG_DEBUG +#define WINC_LOG_DEBUG(...) do { CONF_WINC_PRINTF("[debug]" __VA_ARGS__); CONF_WINC_PRINTF("\r\n"); } while(0) +#endif /* WINC_LOG_LEVEL_DEBUG */ +#endif /* WINC_LOG_LEVEL_INFO */ +#endif /* WINC_LOG_LEVEL_ERROR */ + +#endif + +#ifdef CONF_WINC_ASSERT +#define WINC_ASSERT(condition) CONF_WINC_ASSERT(condition) +#else +#define WINC_ASSERT(condition) +#endif + +#endif /* _WINC_DEBUG_H_ */ diff --git a/AVRIoT.X/mcc_generated_files/winc/common/winc_defines.h b/AVRIoT.X/mcc_generated_files/winc/common/winc_defines.h new file mode 100644 index 0000000..e7c9afd --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/common/winc_defines.h @@ -0,0 +1,126 @@ +/** + * + * \file + * + * \brief WINC Driver Common API Definitions. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +/** @defgroup COMMON Common + @{ + @defgroup COMMONDEF Defines + @} + */ + +#ifndef _WINC_DEFINES_H_ +#define _WINC_DEFINES_H_ + +/**@addtogroup COMMONDEF + * @{ + */ +#define M2M_SUCCESS (0) +#define M2M_ERR_SEND (-1) +#define M2M_ERR_RCV (-2) +#define M2M_ERR_MEM_ALLOC (-3) +#define M2M_ERR_TIME_OUT (-4) +#define M2M_ERR_INIT (-5) +#define M2M_ERR_BUS_FAIL (-6) +#define M2M_NOT_YET (-7) +#define M2M_ERR_FIRMWARE (-8) +#define M2M_SPI_FAIL (-9) +#define M2M_ERR_FIRMWARE_bURN (-10) +#define M2M_ACK (-11) +#define M2M_ERR_FAIL (-12) +#define M2M_ERR_FW_VER_MISMATCH (-13) +#define M2M_ERR_SCAN_IN_PROGRESS (-14) +#define M2M_ERR_INVALID_ARG (-15) + +#define NBIT31 (0x80000000) +#define NBIT30 (0x40000000) +#define NBIT29 (0x20000000) +#define NBIT28 (0x10000000) +#define NBIT27 (0x08000000) +#define NBIT26 (0x04000000) +#define NBIT25 (0x02000000) +#define NBIT24 (0x01000000) +#define NBIT23 (0x00800000) +#define NBIT22 (0x00400000) +#define NBIT21 (0x00200000) +#define NBIT20 (0x00100000) +#define NBIT19 (0x00080000) +#define NBIT18 (0x00040000) +#define NBIT17 (0x00020000) +#define NBIT16 (0x00010000) +#define NBIT15 (0x00008000) +#define NBIT14 (0x00004000) +#define NBIT13 (0x00002000) +#define NBIT12 (0x00001000) +#define NBIT11 (0x00000800) +#define NBIT10 (0x00000400) +#define NBIT9 (0x00000200) +#define NBIT8 (0x00000100) +#define NBIT7 (0x00000080) +#define NBIT6 (0x00000040) +#define NBIT5 (0x00000020) +#define NBIT4 (0x00000010) +#define NBIT3 (0x00000008) +#define NBIT2 (0x00000004) +#define NBIT1 (0x00000002) +#define NBIT0 (0x00000001) + +#ifdef CONF_WINC_MCU_ARCH_LITTLE_ENDIAN +/*! Most significant byte of 32bit word (LE) */ +#define BYTE_0(word) ((uint8_t)(((word) >> 0 ) & 0xFF)) +/*! Second most significant byte of 32bit word (LE) */ +#define BYTE_1(word) ((uint8_t)(((word) >> 8 ) & 0xFF)) +/*! Third most significant byte of 32bit word (LE) */ +#define BYTE_2(word) ((uint8_t)(((word) >> 16) & 0xFF)) +/*! Least significant byte of 32bit word (LE) */ +#define BYTE_3(word) ((uint8_t)(((word) >> 24) & 0xFF)) +#endif + +#ifdef CONF_WINC_MCU_ARCH_BIG_ENDIAN +/*! Most significant byte of 32bit word (BE) */ +#define BYTE_0(word) ((uint8_t)(((word) >> 24) & 0xFF)) +/*! Second most significant byte of 32bit word (BE) */ +#define BYTE_1(word) ((uint8_t)(((word) >> 16) & 0xFF)) +/*! Third most significant byte of 32bit word (BE) */ +#define BYTE_2(word) ((uint8_t)(((word) >> 8 ) & 0xFF)) +/*! Least significant byte of 32bit word (BE) */ +#define BYTE_3(word) ((uint8_t)(((word) >> 0 ) & 0xFF)) +#endif + +#define UNUSED_VAR(VAR) (void)(VAR) + +/**@}*/ + +#endif /*_WINC_DEFINES_H_*/ diff --git a/AVRIoT.X/mcc_generated_files/winc/common/winc_registers.h b/AVRIoT.X/mcc_generated_files/winc/common/winc_registers.h new file mode 100644 index 0000000..a38e29c --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/common/winc_registers.h @@ -0,0 +1,43 @@ +/** + * + * \file + * + * \brief WINC Driver Common Hardware Registers. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef _WINC_REGISTERS_H_ +#define _WINC_REGISTERS_H_ + +#include "winc_1500_3A0_registers.h" + +#endif /* _WINC_REGISTERS_H_ */ diff --git a/AVRIoT.X/mcc_generated_files/winc/driver/winc_adapter.c b/AVRIoT.X/mcc_generated_files/winc/driver/winc_adapter.c new file mode 100644 index 0000000..0f6d5f7 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/driver/winc_adapter.c @@ -0,0 +1,169 @@ +/** + * + * \file + * + * \brief This module contains WINC ADAPTER APIs implementation. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#include "../../mcc.h" +#include "../../delay.h" +#include "winc_adapter.h" + +static int_fast8_t serviceRequest; + +static void winc_interrupt_handler(void) +{ + if (!(INT_GetValue())) + { + serviceRequest++; + } +} + +int_fast8_t winc_adapter_interrupt_request_pending(void) +{ + return serviceRequest ? 1 : 0; +} + +int_fast8_t winc_adapter_interrupt_serviced(bool bEdgeInt) +{ + if (bEdgeInt) + { + INT_DisableInterruptOnChange(); + + if(serviceRequest) + { + serviceRequest--; + } + + INT_EnableInterruptForFallingEdge(); + } + + return 1; +} + +int_fast8_t winc_adapter_init(void) +{ + serviceRequest = 0; + PORTF_INT_SetInterruptHandler(winc_interrupt_handler); + + cpu_irq_enable(); + + + return 1; +} + +int_fast8_t winc_adapter_deinit(void) +{ + return 1; +} + +void winc_adapter_sleep(uint32_t u32TimeMsec) +{ + while (u32TimeMsec--) { + DELAY_milliseconds(1); + } +} + +void winc_adapter_chip_enable_assert(void) +{ + CE_SetHigh(); +} + +void winc_adapter_chip_enable_deassert(void) +{ + CE_SetLow(); +} + +void winc_adapter_reset_assert(void) +{ + RST_SetLow(); +} + +void winc_adapter_reset_deassert(void) +{ + RST_SetHigh(); +} + +int_fast8_t winc_adapter_spi_open(void) +{ + return 1; +} + +int_fast8_t winc_adapter_spi_write(const uint8_t *puBuf, size_t size) +{ + if (puBuf == NULL) + return 0; + + spiMaster[WINC].spiOpen(); + nCS_SetLow(); + + while(size >= 128) + { + spiMaster[WINC].writeBlock((uint8_t *)puBuf, 128); + size -= 128; + puBuf += 128; + } + spiMaster[WINC].writeBlock((uint8_t *)puBuf, size); + + nCS_SetHigh(); + spiMaster[WINC].spiClose(); + + return 1; +} + +int_fast8_t winc_adapter_spi_read(uint8_t *puBuf, size_t size) +{ + if (puBuf == NULL) + return 0; + + spiMaster[WINC].spiOpen(); + nCS_SetLow(); + + while(size >= 128) + { + spiMaster[WINC].readBlock(puBuf, 128); + size -= 128; + puBuf += 128; + } + spiMaster[WINC].readBlock(puBuf, size); + + nCS_SetHigh(); + spiMaster[WINC].spiClose(); + + return 1; +} + +int_fast8_t winc_adapter_spi_close(void) +{ + return 1; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/winc/driver/winc_adapter.h b/AVRIoT.X/mcc_generated_files/winc/driver/winc_adapter.h new file mode 100644 index 0000000..fd9f685 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/driver/winc_adapter.h @@ -0,0 +1,445 @@ +/** + * + * \file + * + * \brief WINC ADAPTER API Declarations. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +/** @defgroup winc_adapter + @brief + The ADAPTER is an architecture specific package implemented to support the common WINC driver. When + porting the driver to a new architecture this package will need to be written to provide the + functionality described here. + @{ + @defgroup ADAPTERDefine Defines + @defgroup ADAPTERInit Initialization and de-initialization functions + @defgroup ADAPTERSleep Sleep/delay functions + @defgroup ADAPTERInt Interrupt handling functions + @defgroup ADAPTERSPI SPI interface functions + @defgroup ADAPTERGPIO GPIO control functions + @defgroup ADAPTERUART UART interface functions + @note + These functions are only required for supporting the serial bridge functionality of the + driver. + @} + */ + +#ifndef _WINC_ADAPTER_H_ +#define _WINC_ADAPTER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include "../../config/conf_winc.h" + +/**@addtogroup ADAPTERDefine + * @{ + */ +#if defined(CONF_WINC_MCU_ARCH_LITTLE_ENDIAN) +#define HOST_TO_WINC_U32(U32) (U32) +#define HOST_TO_WINC_U16(U16) (U16) +#elif defined(CONF_WINC_MCU_ARCH_BIG_ENDIAN) +#define HOST_TO_WINC_U32(U32) CONF_WINC_UINT32_SWAP(U32) +#define HOST_TO_WINC_U16(U16) CONF_WINC_UINT16_SWAP(U16) +#endif + +#define WINC_TO_HOST_U32 HOST_TO_WINC_U32 +#define WINC_TO_HOST_U16 HOST_TO_WINC_U16 +/**@}*/ // ADAPTERDefine + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup ADAPTERInit + * @{ + */ +/*! + @fn \ + int_fast8_t winc_adapter_init(void); + + @brief + This function is used to initialize the ADAPTER in order to prepare the WINC before any + WINC API calls. + + @details + The winc_adapter_init function is the first function that should be called at the beginning of + every application to initialize the ADAPTER and the WINC board. Otherwise, the rest of the ADAPTER + function calls will return with failure. This function should also be called after the WINC + has been switched off with a successful call to @ref winc_adapter_deinit in order to reinitialize + the ADAPTER before the Application can use any of the WINC APIs again. After the function + initializes the WINC. + +@note + Implementation of this function is host dependent. + +@warning + Omitting this function will lead to unavailability of host-chip communication. + +@see winc_adapter_deinit + +@return + The function returns a value of 1 for successful operations and a 0 value otherwise. +*/ +int_fast8_t winc_adapter_init(void); + +/*! +@fn \ + int_fast8_t winc_adapter_deinit(void); + +@brief + This function is used to de-initialize the ADAPTER and turn off the WINC board. + +@details + The winc_adapter_deinit is the last function that should be called after the application has + finished and before the WINC is switched off. Every function call of @ref winc_adapter_init + should be matched with a call to winc_adapter_deinit. Failure to do so may result in the WINC + consuming higher power than expected, since it won't be properly de-initialized. + +@pre + The ADAPTER should be initialized through @ref winc_adapter_init first. + +@note + Implementation of this function is host dependent. + +@warning + Omitting this function may lead to unknown behavior in case of soft reset. + +@see winc_adapter_init + +@return + The function returns a value of 1 for successful operations and a 0 value otherwise. +*/ +int_fast8_t winc_adapter_deinit(void); + +/**@}*/ // ADAPTERInit +/**@addtogroup ADAPTERSleep + * @{ + */ +/*! +@fn \ + void winc_adapter_sleep(uint32_t u32TimeMsec); + +@brief + Used to put the host to sleep for the specified duration (in milliseconds). + Forcing the host to sleep for extended period may lead to host not being able to respond + to WINC board events. It is important to be considerate while choosing the sleep period. + +@param[in] u32TimeMsec + Time unit in milliseconds. + +@pre + Initialize @ref winc_adapter_init first. + +@note + Implementation of this function is host dependent. + +@see winc_adapter_init +*/ +void winc_adapter_sleep(uint32_t u32TimeMsec); + +/**@}*/ // ADAPTERSleep +/**@addtogroup ADAPTERInt + * @{ + */ +/*! +@fn \ + int_fast8_t winc_adapter_interrupt_request_pending(void); + +@brief + Indicates to the WINC driver is an interrupt request has been received. This function will be + called by the WINC driver during @ref m2m_wifi_handle_events to determine if the WINC should be + queried for possible messages. + +@pre + Initialize @ref winc_adapter_init first. + +@note + Implementation of this function is host dependent. + +@see winc_adapter_init + +@return + The functions returns a non-zero value to indicate if an interrupt has been received, otherwise zero. +*/ +int_fast8_t winc_adapter_interrupt_request_pending(void); + +/*! +@fn \ + int_fast8_t winc_adapter_interrupt_serviced(bool bEdgeInt); + +@brief + Indicates to the ADAPTER that a pending interrupt has been processed by the driver. The WINC driver + will call this function to indicate that a message has been received from the WINC. @p bEdgeInt + indicates if an edge interrupt should be serviced (true) or a level interrupt (false). + + If the ADAPTER is managing the WINC devices IRQn line as an edge interrupt then when @p bEdgeInt is true + the ADAPTER should consider a pending interrupt has been serviced. If @p bEdgeInt is false the ADAPTER must + ignore it. This ensures the interrupt is serviced before the WINC re-activates the IRQn line and thus + before another interrupt can be received. + + If the ADAPTER is managing the WINC devices IRQn line as a level interrupt then when @p bEdgeInt is false + the ADAPTER should consider a pending interrupt has been serviced. If @p bEdgeInt is true the ADAPTER must + ignore it. This ensures the interrupt is serviced after the WINC re-activates the IRQn line and thus + ensures any previous interrupt level has been de-asserted by the WINC. + +@pre + Initialize @ref winc_adapter_init first. + +@note + Implementation of this function is host dependent. + +@see winc_adapter_init + +@return + The functions returns a non-zero value to indicate if an interrupt service has been acknowledged by the ADAPTER. +*/ +int_fast8_t winc_adapter_interrupt_serviced(bool bEdgeInt); + +/**@}*/ // ADAPTERInt +/**@addtogroup ADAPTERSPI + * @{ + */ +/*! +@fn \ + int_fast8_t winc_adapter_spi_open(void); + +@brief + Called by the driver to open the SPI bus for use. + +@pre + Initialize @ref winc_adapter_init first. + +@note + Implementation of this function is host dependent. + +@see winc_adapter_init + +@return + The function returns a value of 1 for successful operations and a 0 value otherwise. +*/ +int_fast8_t winc_adapter_spi_open(void); + +/*! +@fn \ + int_fast8_t winc_adapter_spi_close(void); + +@brief + Called by the driver to close the SPI bus. @ref winc_adapter_spi_open should have been called before this. + +@pre + Initialize @ref winc_adapter_init first and @ref winc_adapter_spi_open must have been called. + +@note + Implementation of this function is host dependent. + +@see winc_adapter_init +@see winc_adapter_spi_open + +@return + The function returns a value of 1 for successful operations and a 0 value otherwise. +*/ +int_fast8_t winc_adapter_spi_close(void); + +/*! +@fn \ + int_fast8_t winc_adapter_spi_write(const uint8_t *puBuf, size_t size); + +@brief + Called by the driver to write data to the SPI bus. + +@param[in] puBuf + A pointer to the data to be written to the SPI bus. + +@param[in] size + The number of bytes to be written. + +@pre + Initialize @ref winc_adapter_init first and @ref winc_adapter_spi_open must have been called. + +@note + Implementation of this function is host dependent. + +@see winc_adapter_init +@see winc_adapter_spi_open + +@return + The function returns a value of 1 for successful operations and a 0 value otherwise. +*/ +int_fast8_t winc_adapter_spi_write(const uint8_t *puBuf, size_t size); + +/*! +@fn \ + int_fast8_t winc_adapter_spi_read(uint8_t *puBuf, size_t size); + +@brief + Called by the driver to read data from the SPI bus. + +@param[in] puBuf + A pointer to a buffer to which the data should be written. + +@param[in] size + The number of bytes to be read. + +@pre + Initialize @ref winc_adapter_init first and @ref winc_adapter_spi_open must have been called. + +@note + Implementation of this function is host dependent. + +@see winc_adapter_init +@see winc_adapter_spi_open + +@return + The function returns a value of 1 for successful operations and a 0 value otherwise. +*/ +int_fast8_t winc_adapter_spi_read(uint8_t *puBuf, size_t size); + +/**@}*/ // ADAPTERSPI +/**@addtogroup ADAPTERGPIO + * @{ + */ +/*! +@fn \ + void winc_adapter_chip_enable_assert(void); + +@brief + Called by the driver when the chip enable line should be asserted. +*/ +void winc_adapter_chip_enable_assert(void); + +/*! +@fn \ + void winc_adapter_chip_enable_deassert(void); + +@brief + Called by the driver when the chip enable line should be de-asserted. +*/ +void winc_adapter_chip_enable_deassert(void); + +/*! +@fn \ + void winc_adapter_reset_assert(void); + +@brief + Called by the driver when the WINC reset line should be asserted. +*/ +void winc_adapter_reset_assert(void); + +/*! +@fn \ + void winc_adapter_reset_deassert(void); + +@brief + Called by the driver when the WINC reset line should be de-asserted. +*/ +void winc_adapter_reset_deassert(void); + +/**@}*/ // ADAPTERGPIO +/**@addtogroup ADAPTERUART + * @{ + */ +/*! +@fn \ + int_fast8_t winc_adapter_uart_open(uint32_t u32BaudRate); + +@brief + Called by the driver to open the UART. + +@return + The function returns a value of 1 for successful operations and a 0 value otherwise. +*/ +int_fast8_t winc_adapter_uart_open(uint32_t u32BaudRate); + +/*! +@fn \ + int_fast8_t winc_adapter_uart_close(void); + +@brief + Called by the driver to close the UART. + +@return + The function returns a value of 1 for successful operations and a 0 value otherwise. +*/ +int_fast8_t winc_adapter_uart_close(void); + +/*! +@fn \ + int_fast8_t winc_adapter_uart_set_baudrate(uint32_t u32BaudRate); + +@brief + Called by the driver to set the UART baud rate. + +@return + The function returns a value of 1 for successful operations and a 0 value otherwise. +*/ +int_fast8_t winc_adapter_uart_set_baudrate(uint32_t u32BaudRate); + +/*! +@fn \ + size_t winc_adapter_uart_write(const uint8_t *pu8Buf, size_t szLength); + +@brief + Called by the driver to write data to the UART. + +@note + This function must either indicate all bytes were accepted or an error occurred. + +@return + The number of bytes written to the UART or zero for no data/error. +*/ +size_t winc_adapter_uart_write(const uint8_t *pu8Buf, size_t szLength); + +/*! +@fn \ + size_t winc_adapter_uart_read(uint8_t *pu8Buf, size_t szLength); + +@brief + Called by the driver to read data from the UART. + +@return + The number of bytes read, this may be less than \p szLength +*/ +size_t winc_adapter_uart_read(uint8_t *pu8Buf, size_t szLength); + +/**@}*/ // ADAPTERUART + +#ifdef __cplusplus +} +#endif + +#endif /*_WINC_ADAPTER_H_*/ diff --git a/AVRIoT.X/mcc_generated_files/winc/driver/winc_asic.c b/AVRIoT.X/mcc_generated_files/winc/driver/winc_asic.c new file mode 100644 index 0000000..852f7ab --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/driver/winc_asic.c @@ -0,0 +1,493 @@ +/** + * + * \file + * + * \brief This module contains WINC ASIC specific internal API implementation. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#include "../common/winc_defines.h" +#include "../common/winc_registers.h" +#include "../common/winc_debug.h" +#include "winc_adapter.h" +#include "winc_spi.h" +#include "winc_asic.h" + +#define M2M_FINISH_INIT_STATE 0x02532636UL +#define M2M_FINISH_BOOT_ROM 0x10add09eUL +#define M2M_START_FIRMWARE 0xef522f61UL + +#define TIMEOUT (2000) +#define WAKUP_TRAILS_TIMEOUT (4) + +#define rHAVE_SDIO_IRQ_GPIO_BIT (NBIT0) +#define rHAVE_USE_PMU_BIT (NBIT1) +#define rHAVE_SLEEP_CLK_SRC_RTC_BIT (NBIT2) +#define rHAVE_SLEEP_CLK_SRC_XO_BIT (NBIT3) +#define rHAVE_EXT_PA_INV_TX_RX (NBIT4) +#define rHAVE_LEGACY_RF_SETTINGS (NBIT5) +#define rHAVE_LOGS_DISABLED_BIT (NBIT6) +#define rHAVE_ETHERNET_MODE_BIT (NBIT7) +#define rHAVE_RESERVED1_BIT (NBIT8) +#define rHAVE_RESERVED2_BIT (NBIT9) +#define rHAVE_XO_XTALGM2_DIS_BIT (NBIT10) + +static bool chip_apply_conf(const uint32_t u32Conf) +{ + uint32_t u32Reg; + + do + { + winc_bus_write_reg(NMI_GP_REG_1, u32Conf); + + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(NMI_GP_REG_1, &u32Reg)) + return false; + + if (u32Reg == u32Conf) + return true; + } + while (1); + + return false; +} + +bool winc_chip_interrupts_enable(void) +{ + // interrupt pin mux select + if (WINC_BUS_SUCCESS != winc_bus_set_reg_bits(NMI_PIN_MUX_0, (uint32_t)1 << 8)) + return false; + + // interrupt enable + if (WINC_BUS_SUCCESS != winc_bus_set_reg_bits(NMI_INTR_ENABLE, (uint32_t)1 << 16)) + return false; + + return true; +} + +uint32_t winc_chip_get_id(void) +{ + static uint32_t gu32ChipID = 0; + uint32_t u32RevID; + + if (gu32ChipID) + return gu32ChipID; + + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(NMI_RF_REVID, &u32RevID)) + return 0; + + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(NMI_CHIPID, &gu32ChipID)) + return 0; + + if (gu32ChipID == 0x1002a0) + { + if (u32RevID == 0x1) + { + /* 1002A0 */ + } + else /* if (u32RevID == 0x2) */ + { + /* 1002A1 */ + gu32ChipID = 0x1002a1; + } + } + else if (gu32ChipID == 0x1002b0) + { + if (u32RevID == 3) + { + /* 1002B0 */ + } + else if (u32RevID == 4) + { + /* 1002B1 */ + gu32ChipID = 0x1002b1; + } + else /* if(u32RevID == 5) */ + { + /* 1002B2 */ + gu32ChipID = 0x1002b2; + } + } + else if (gu32ChipID == 0x1000f0) + { +#ifdef BT_CHIP_ID_REG + if ((WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(BT_CHIP_ID_REG, &gu32ChipID))) + { + gu32ChipID = 0; + return 0; + } +#endif + } + + gu32ChipID &= ~(0x0f0000); + gu32ChipID |= 0x050000; + + return gu32ChipID; +} + +bool winc_chip_sleep(void) +{ + uint32_t u32Reg; + + if (winc_bus_error()) + return false; + + do + { + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(CORT_HOST_COMM, &u32Reg)) + return false; + } + while (u32Reg & NBIT0); + + /* Clear bit 1 */ + winc_bus_clear_reg_bits(WAKE_CLK_REG, NBIT1); + winc_bus_clear_reg_bits(HOST_CORT_COMM, NBIT0); + + return !winc_bus_error(); +} + +bool winc_chip_wake(void) +{ + uint32_t u32ClkStatusReg; + int_fast8_t i8Trials; + + /* Use bit 0 to indicate host wakeup*/ + winc_bus_set_reg_bits(HOST_CORT_COMM, NBIT0); + winc_bus_set_reg_bits(WAKE_CLK_REG, NBIT1); + + if (winc_bus_error()) + return false; + + i8Trials = WAKUP_TRAILS_TIMEOUT; + + while(i8Trials--) + { + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(CLOCKS_EN_REG, &u32ClkStatusReg)) + { + WINC_LOG_ERROR("Reading clock status register"); + return false; + } + + if (u32ClkStatusReg & NBIT2) + { + winc_bus_reset(); + + return true; + } + + winc_adapter_sleep(2); + } + + WINC_LOG_ERROR("Failed to wake up the chip"); + + winc_bus_reset(); + + return false; +} + +bool winc_chip_halt(void) +{ + if (WINC_BUS_SUCCESS != winc_bus_set_reg_bits(NMI_CORTUS_BOOT_RESET_MUXSEL, (uint32_t)1 << 0)) + return false; + + if (WINC_BUS_SUCCESS != winc_bus_clear_reg_bits(NMI_GLB_RESET_0, (uint32_t)1 << 10)) + return false; + + return true; +} + +void winc_chip_reset(void) +{ + winc_bus_write_reg_no_rsp(NMI_GLB_RESET_0, 0); + /* Don't check return, write will fail as WINC will not respond for 50ms */ + + winc_adapter_sleep(50); +} + +bool winc_chip_init(bool bBootATE, bool bEthMode, uint32_t u32StateRegVal) +{ + uint32_t u32GpReg1; + uint_fast16_t u16Timeout; + + winc_bus_write_reg(BOOTROM_REG, 0); + winc_bus_write_reg(NMI_STATE_REG, 0); + winc_bus_write_reg(NMI_REV_REG, 0); + + if (WINC_BUS_SUCCESS != winc_bus_set_reg_bits(NMI_CORTUS_BOOT_RESET_MUXSEL, (uint32_t)1 << 0)) + return false; + + /* release cortus CPU from reset */ + if (WINC_BUS_SUCCESS != winc_bus_set_reg_bits(NMI_GLB_RESET_0, (uint32_t)1 << 10)) + return false; + + while(1) + { + /* wait for efuse loading done */ + if (winc_bus_read_reg(NMI_EFUSE_0_CONTROL) & 0x80000000) + break; + } + + /* check if waiting for the host will be skipped or not */ + if(!(winc_bus_read_reg(M2M_WAIT_FOR_HOST_REG) & 1)) + { + u16Timeout = TIMEOUT; + + while(u16Timeout--) + { + winc_adapter_sleep(1); + if (M2M_FINISH_BOOT_ROM == winc_bus_read_reg(BOOTROM_REG)) + break; + } + + if (!u16Timeout) + { + WINC_LOG_DEBUG("failed to load firmware from flash"); + return false; + } + } + + u32GpReg1 = 0 +#if (defined __ENABLE_PMU__) || (defined CONF_WINC_INT_PMU) + | rHAVE_USE_PMU_BIT +#endif +#ifdef __ENABLE_SLEEP_CLK_SRC_RTC__ + | rHAVE_SLEEP_CLK_SRC_RTC_BIT +#elif defined __ENABLE_SLEEP_CLK_SRC_XO__ + | rHAVE_SLEEP_CLK_SRC_XO_BIT +#endif +#ifdef __ENABLE_EXT_PA_INV_TX_RX__ + | rHAVE_EXT_PA_INV_TX_RX +#endif +#ifdef __ENABLE_LEGACY_RF_SETTINGS__ + | rHAVE_LEGACY_RF_SETTINGS +#endif +#ifdef __DISABLE_FIRMWARE_LOGS__ + | rHAVE_LOGS_DISABLED_BIT +#endif +#if defined CONF_WINC_XO_XTALGM2_DIS + | rHAVE_XO_XTALGM2_DIS_BIT +#endif + | rHAVE_RESERVED1_BIT; + + if (bBootATE) + { + winc_bus_write_reg(NMI_REV_REG, M2M_ATE_FW_START_VALUE); + } + else if (bEthMode) + { + u32GpReg1 |= rHAVE_ETHERNET_MODE_BIT; + } + + winc_bus_write_reg(NMI_STATE_REG, u32StateRegVal); + + if (REV(winc_chip_get_id()) >= REV_3A0) + { + u32GpReg1 |= rHAVE_USE_PMU_BIT; + } + + chip_apply_conf(u32GpReg1); + + winc_bus_write_reg(BOOTROM_REG, M2M_START_FIRMWARE); + + u16Timeout = TIMEOUT; + while(u16Timeout--) + { + winc_adapter_sleep(2); + + if (!bBootATE) + { + if (M2M_FINISH_INIT_STATE == winc_bus_read_reg(NMI_STATE_REG)) + { + winc_bus_write_reg(NMI_STATE_REG, 0); + + if (!winc_chip_interrupts_enable()) + { + WINC_LOG_ERROR("failed to enable interrupts.."); + return false; + } + + return true; + } + } + else + { + if (M2M_ATE_FW_IS_UP_VALUE == winc_bus_read_reg(NMI_REV_REG)) + { + return true; + } + } + } + + WINC_LOG_DEBUG("Time out for wait firmware Run"); + + return false; +} + +bool winc_chip_deinit(void) +{ + if (WINC_BUS_SUCCESS != winc_bus_clear_reg_bits(NMI_GLB_RESET_0, (uint32_t)1 << 10)) + { + WINC_LOG_ERROR("Failed to de-initialize"); + return false; + } + + return true; +} + +#ifdef CONF_PERIPH + +bool winc_chip_set_gpio_dir(uint_fast8_t u8GPIO, bool bDirOut) +{ + int_fast8_t i8Ret; + + WINC_ASSERT(u8GPIO < 32); + + if (bDirOut) + { + i8Ret = winc_bus_set_reg_bits(0x20108, 1UL << u8GPIO); + } + else + { + i8Ret = winc_bus_clear_reg_bits(0x20108, 1UL << u8GPIO); + } + + if (WINC_BUS_SUCCESS != i8Ret) + return false; + + return true; +} + +bool winc_chip_set_gpio_val(uint_fast8_t u8GPIO, bool bBitSet) +{ + int_fast8_t i8Ret; + + WINC_ASSERT(u8GPIO < 32); + + if (bBitSet) + { + i8Ret = winc_bus_set_reg_bits(0x20100, 1UL << u8GPIO); + } + else + { + i8Ret = winc_bus_clear_reg_bits(0x20100, 1UL << u8GPIO); + } + + if (WINC_BUS_SUCCESS != i8Ret) + return false; + + return true; +} + +bool winc_chip_get_gpio_val(uint_fast8_t u8GPIO, uint8_t *pu8Val) +{ + uint32_t u32Val; + + WINC_ASSERT(u8GPIO < 32); + WINC_ASSERT(pu8Val != NULL); + + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(0x20104, &u32Val)) + return false; + + *pu8Val = (uint8_t)((u32Val >> u8GPIO) & 1); + + return true; +} + +bool winc_chip_pullup_ctrl(uint32_t u32PinMask, bool bEnable) +{ + int_fast8_t i8Ret; + + if (bEnable) + { + i8Ret = winc_bus_clear_reg_bits(0x142c, u32PinMask); + } + else + { + i8Ret = winc_bus_set_reg_bits(0x142c, u32PinMask); + } + + if (WINC_BUS_SUCCESS != i8Ret) + return false; + + return true; +} + +#endif /* CONF_PERIPH */ + +bool winc_chip_get_otp_mac_address(uint8_t *pu8MacAddr) +{ + uint32_t u32RegValue; + tstrGpRegs strGpRegs; + + WINC_ASSERT(pu8MacAddr != NULL); + + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(NMI_GP_REG_2, &u32RegValue)) + return false; + + if (WINC_BUS_SUCCESS != winc_bus_read_block(u32RegValue|0x30000, (uint8_t*)&strGpRegs, sizeof(tstrGpRegs))) + return false; + + if((strGpRegs.u32Mac_efuse_mib & 0xffff0000) == 0) + { + WINC_LOG_DEBUG("Default MAC"); + memset(pu8MacAddr, 0, 6); + + return false; + } + + WINC_LOG_DEBUG("OTP MAC"); + strGpRegs.u32Mac_efuse_mib >>=16; + if (WINC_BUS_SUCCESS != winc_bus_read_block(strGpRegs.u32Mac_efuse_mib|0x30000, pu8MacAddr, 6)) + return false; + + return true; +} + +bool winc_chip_get_mac_address(uint8_t *pu8MacAddr) +{ + uint32_t u32RegValue; + tstrGpRegs strGpRegs; + + WINC_ASSERT(pu8MacAddr != NULL); + + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(NMI_GP_REG_2, &u32RegValue)) + return false; + + if (WINC_BUS_SUCCESS != winc_bus_read_block(u32RegValue|0x30000, (uint8_t*)&strGpRegs, sizeof(tstrGpRegs))) + return false; + + strGpRegs.u32Mac_efuse_mib &= 0x0000ffff; + + if (WINC_BUS_SUCCESS != winc_bus_read_block(strGpRegs.u32Mac_efuse_mib|0x30000, pu8MacAddr, 6)) + return false; + + return true; +} diff --git a/AVRIoT.X/mcc_generated_files/winc/driver/winc_asic.h b/AVRIoT.X/mcc_generated_files/winc/driver/winc_asic.h new file mode 100644 index 0000000..994741b --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/driver/winc_asic.h @@ -0,0 +1,90 @@ +/** + * + * \file + * + * \brief This module contains WINC ASIC specific internal API declarations. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef _WINC_ASIC_H_ +#define _WINC_ASIC_H_ + +#define M2M_ATE_FW_START_VALUE (0x3C1CD57D) /*Also, Change this value in boot_firmware if it will be changed here*/ +#define M2M_ATE_FW_IS_UP_VALUE (0xD75DC1C3) /*Also, Change this value in ATE (Burst) firmware if it will be changed here*/ + +#define REV_3A0 (0x3A0) + +#define REV(id) ( ((id) & 0x00000fff ) ) + +typedef struct +{ + uint32_t u32Mac_efuse_mib; + uint32_t u32Firmware_Ota_rev; +} tstrGpRegs; + +#ifdef __cplusplus + extern "C" { +#endif + +bool winc_chip_interrupts_enable(void); + +uint32_t winc_chip_get_id(void); + +bool winc_chip_sleep(void); + +bool winc_chip_wake(void); + +bool winc_chip_halt(void); + +void winc_chip_reset(void); + +bool winc_chip_init(bool bBootATE, bool bEthMode, uint32_t u32StateRegVal); + +bool winc_chip_deinit(void); + +bool winc_chip_set_gpio_dir(uint_fast8_t u8GPIO, bool bDirOut); + +bool winc_chip_set_gpio_val(uint_fast8_t u8GPIO, bool bBitSet); + +bool winc_chip_get_gpio_val(uint_fast8_t u8GPIO, uint8_t *pu8Val); + +bool winc_chip_pullup_ctrl(uint32_t u32PinMask, bool bEnable); + +bool winc_chip_get_otp_mac_address(uint8_t *pu8MacAddr); + +bool winc_chip_get_mac_address(uint8_t *pu8MacAddr); + +#ifdef __cplusplus + } +#endif + +#endif /*_WINC_ASIC_H_*/ diff --git a/AVRIoT.X/mcc_generated_files/winc/driver/winc_drv.c b/AVRIoT.X/mcc_generated_files/winc/driver/winc_drv.c new file mode 100644 index 0000000..d8683b4 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/driver/winc_drv.c @@ -0,0 +1,120 @@ +/** + * + * \file + * + * \brief This module contains WINC driver API implementation. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#include "../common/winc_defines.h" +#include "../common/winc_debug.h" +#include "../common/winc_registers.h" +#include "winc_adapter.h" +#include "winc_drv.h" +#include "winc_asic.h" +#include "winc_spi.h" +#include "../spi_flash/spi_flash.h" + +int_fast8_t winc_drv_init(bool bHold) +{ + if (!winc_adapter_spi_open()) + { + WINC_LOG_ERROR("Failed to open bus"); + return WINC_DRV_FAIL; + } + + winc_adapter_chip_enable_deassert(); + winc_adapter_reset_assert(); + winc_adapter_sleep(CONF_WINC_RESET_ASSERT_TIME); + winc_adapter_chip_enable_assert(); + winc_adapter_sleep(10); + winc_adapter_reset_deassert(); + + winc_adapter_sleep(10); + + if (WINC_BUS_SUCCESS != winc_bus_init()) + return WINC_DRV_FAIL; + + WINC_LOG_INFO("Chip ID %" PRIx32, winc_chip_get_id()); + + if (bHold) + { + if (!winc_chip_halt()) + return WINC_DRV_FAIL; + + /*disable all interrupt in ROM (to disable uart) in 2b0 chip*/ + winc_bus_write_reg(0x20300,0); + } + + return WINC_DRV_SUCCESS; +} + +int_fast8_t winc_drv_start(bool bBootATE, bool bEthMode, uint32_t u32StateRegVal) +{ + if (winc_chip_init(bBootATE, bEthMode, u32StateRegVal)) + return WINC_DRV_SUCCESS; + + if (!winc_adapter_spi_close()) + { + WINC_LOG_ERROR("Failed to close bus"); + } + + winc_bus_deinit(); + + return WINC_DRV_FAIL; +} + +int_fast8_t winc_drv_deinit(void) +{ + if (!winc_chip_deinit()) + { + WINC_LOG_ERROR("winc_chip_deinit failed"); + return WINC_DRV_FAIL; + } + + /* Disable SPI flash to save power when the chip is off */ + if (M2M_SUCCESS != spi_flash_enable(0)) + { + WINC_LOG_ERROR("SPI flash disable failed"); + return WINC_DRV_FAIL; + } + + if (!winc_adapter_spi_close()) + { + WINC_LOG_ERROR("Failed to close bus"); + return WINC_DRV_FAIL; + } + + winc_bus_deinit(); + + return WINC_DRV_SUCCESS; +} diff --git a/AVRIoT.X/mcc_generated_files/winc/driver/winc_drv.h b/AVRIoT.X/mcc_generated_files/winc/driver/winc_drv.h new file mode 100644 index 0000000..4c889a3 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/driver/winc_drv.h @@ -0,0 +1,58 @@ +/** + * + * \file + * + * \brief This module contains WINC driver API declarations. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef _WINC_DRV_H_ +#define _WINC_DRV_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define WINC_DRV_SUCCESS 0 +#define WINC_DRV_FAIL 1 + +int_fast8_t winc_drv_init(bool bHold); + +int_fast8_t winc_drv_start(bool bBootATE, bool bEthMode, uint32_t u32StateRegVal); + +int_fast8_t winc_drv_deinit(void); + +#ifdef __cplusplus +} +#endif + +#endif /*_WINC_DRV_H_*/ diff --git a/AVRIoT.X/mcc_generated_files/winc/driver/winc_hif.c b/AVRIoT.X/mcc_generated_files/winc/driver/winc_hif.c new file mode 100644 index 0000000..20b2157 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/driver/winc_hif.c @@ -0,0 +1,364 @@ +/** + * + * \file + * + * \brief This module contains host interface APIs implementation. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#include "../common/winc_defines.h" +#include "../common/winc_registers.h" +#include "../common/winc_debug.h" +#include "winc_adapter.h" +#include "winc_spi.h" +#include "winc_hif.h" +#include "winc_asic.h" + +static uint_fast8_t gu8ChipSleep; +static uint32_t gu32RxAddr; +static uint_fast16_t gu16RxSize; +static bool gbChipPwrSave; + +static void hif_null_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr) +{ + UNUSED_VAR(u8OpCode); + UNUSED_VAR(u16DataSize); + UNUSED_VAR(u32Addr); +} + +static const tpfHifCallBack gHifCallbacks[] = { + CONF_WINC_HIF_CB_WIFI_HANDLER, + CONF_WINC_HIF_CB_IP_HANDLER, + CONF_WINC_HIF_CB_HIF_HANDLER, + CONF_WINC_HIF_CB_OTA_HANDLER, + CONF_WINC_HIF_CB_SSL_HANDLER, + CONF_WINC_HIF_CB_CRYPTO_HANDLER, + CONF_WINC_HIF_CB_SIGMA_HANDLER, +}; + +#define WINC_HIF_CB_HIGHEST_GID (sizeof(gHifCallbacks)/sizeof(tpfHifCallBack)) + +int8_t winc_hif_chip_wake(void) +{ + if (gu8ChipSleep++ == 0) + { + if (gbChipPwrSave) + { + if (!winc_chip_wake()) + return M2M_ERR_FAIL; + } + } + + return M2M_SUCCESS; +} + +void winc_hif_set_power_save(bool bPwrSave) +{ + gbChipPwrSave = bPwrSave; +} + +int8_t winc_hif_chip_sleep(void) +{ + if (gu8ChipSleep) + { + gu8ChipSleep--; + } + + if (gu8ChipSleep == 0) + { + if (gbChipPwrSave) + { + if (!winc_chip_sleep()) + return M2M_ERR_FAIL; + } + } + + return M2M_SUCCESS; +} + +int8_t winc_hif_init(void) +{ + gu8ChipSleep = 0; + gbChipPwrSave = false; + + WINC_CRIT_SEC_HIF_INIT; + + return M2M_SUCCESS; +} + +int8_t winc_hif_deinit(void) +{ + WINC_CRIT_SEC_HIF_DEINIT; + + return winc_hif_chip_wake(); +} + +int8_t winc_hif_send(uint8_t u8Gid, uint8_t u8Opcode, const void *pvCtrlBuf, uint16_t u16CtrlBufSize, + const void *pvDataBuf, uint16_t u16DataSize, uint16_t u16DataOffset) +{ + tstrHifHdr strHif; + uint32_t u32Reg; + uint32_t u32DMAAddr; + uint_fast16_t u16Count; + uint32_t u32CurrAddr; + + strHif.u8Opcode = u8Opcode & (~NBIT7); + strHif.u8Gid = u8Gid; + strHif.u16Length = M2M_HIF_HDR_OFFSET; + + if (pvDataBuf != NULL) + { + strHif.u16Length += u16DataOffset + u16DataSize; + } + else + { + strHif.u16Length += u16CtrlBufSize; + } + + if (strHif.u16Length > M2M_HIF_MAX_PACKET_SIZE) + { + WINC_LOG_ERROR("HIF message length (%u) exceeds max length (%d)", strHif.u16Length, M2M_HIF_MAX_PACKET_SIZE); + return M2M_ERR_SEND; + } + + WINC_CRIT_SEC_HIF_ENTER; + + if (M2M_SUCCESS != winc_hif_chip_wake()) + { + WINC_LOG_ERROR("Failed to wakeup the chip"); + + WINC_CRIT_SEC_HIF_LEAVE; + return M2M_ERR_SEND; + } + + u32Reg = (uint32_t)u8Gid; + u32Reg |= ((uint32_t)u8Opcode<<8); + u32Reg |= ((uint32_t)strHif.u16Length<<16); + winc_bus_write_reg(NMI_STATE_REG,u32Reg); + + winc_bus_write_reg(WIFI_HOST_RCV_CTRL_2, NBIT1); + + u32DMAAddr = 0; + + u16Count = 1000; + while(u16Count--) + { + winc_bus_read_reg_with_ret(WIFI_HOST_RCV_CTRL_2, &u32Reg); + + if (winc_bus_error()) + { + winc_hif_chip_sleep(); + + WINC_CRIT_SEC_HIF_LEAVE; + return M2M_ERR_SEND; + } + + if (!(u32Reg & NBIT1)) + { + winc_bus_read_reg_with_ret(WIFI_HOST_RCV_CTRL_4, &u32DMAAddr); + break; + } + + /* + * If it takes too long to get a response, the slow down to + * avoid back-to-back register read operations. + */ + if (u16Count <= 500) + { + if (u16Count == 500) + { + WINC_LOG_INFO("Slowing down..."); + } + + winc_adapter_sleep(1); + } + } + + if (winc_bus_error() || !u32DMAAddr) + { + winc_hif_chip_sleep(); + WINC_LOG_DEBUG("Failed to receive DMA address"); + + WINC_CRIT_SEC_HIF_LEAVE; + return M2M_ERR_MEM_ALLOC; + } + + u32CurrAddr = u32DMAAddr; + strHif.u16Length = HOST_TO_WINC_U16(strHif.u16Length); + + winc_bus_write_block(u32CurrAddr, (uint8_t*)&strHif, M2M_HIF_HDR_OFFSET); + + u32CurrAddr += M2M_HIF_HDR_OFFSET; + + if (pvCtrlBuf != NULL) + { + winc_bus_write_block(u32CurrAddr, pvCtrlBuf, u16CtrlBufSize); + } + + if (pvDataBuf != NULL) + { + u32CurrAddr += u16DataOffset; + winc_bus_write_block(u32CurrAddr, pvDataBuf, u16DataSize); + } + + winc_bus_write_reg(WIFI_HOST_RCV_CTRL_3, (u32DMAAddr << 2) | NBIT1); + + winc_hif_chip_sleep(); + + WINC_CRIT_SEC_HIF_LEAVE; + + if (winc_bus_error()) + return M2M_ERR_SEND; + + return M2M_SUCCESS; +} + +int8_t winc_hif_send_no_data(uint8_t u8Gid, uint8_t u8Opcode, const void *pvCtrlBuf, uint16_t u16CtrlBufSize) +{ + return winc_hif_send(u8Gid, u8Opcode, pvCtrlBuf, u16CtrlBufSize, NULL, 0, 0); +} + +int8_t winc_hif_handle_isr(void) +{ + uint32_t u32Reg; + tstrHifHdr strHif; + + if (!winc_adapter_interrupt_request_pending()) + return M2M_SUCCESS; + + WINC_CRIT_SEC_HIF_ENTER; + + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0, &u32Reg)) + { + WINC_LOG_ERROR("Failed to read interrupt register"); + + WINC_CRIT_SEC_HIF_LEAVE; + return M2M_ERR_FAIL; + } + + if (!(u32Reg & NBIT0)) + { + WINC_LOG_ERROR("False interrupt %" PRIx32, u32Reg); + + WINC_CRIT_SEC_HIF_LEAVE; + return M2M_ERR_FAIL; + } + + /* New interrupt has been received */ + /*Clearing RX interrupt*/ + u32Reg &= ~NBIT0; + if (WINC_BUS_SUCCESS != winc_bus_write_reg(WIFI_HOST_RCV_CTRL_0, u32Reg)) + { + WINC_CRIT_SEC_HIF_LEAVE; + return M2M_ERR_FAIL; + } + + gu16RxSize = (uint_fast16_t)((u32Reg >> 2) & 0xfff); + + if (!gu16RxSize) + { + WINC_LOG_ERROR("Wrong size"); + WINC_CRIT_SEC_HIF_LEAVE; + return M2M_ERR_RCV; + } + + /** + start bus transfer + **/ + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(WIFI_HOST_RCV_CTRL_1, &gu32RxAddr)) + { + WINC_LOG_ERROR("WIFI_HOST_RCV_CTRL_1 bus fail"); + WINC_CRIT_SEC_HIF_LEAVE; + return M2M_ERR_FAIL; + } + + if (WINC_BUS_SUCCESS != winc_bus_read_block(gu32RxAddr, (uint8_t*)&strHif, sizeof(tstrHifHdr))) + { + WINC_LOG_ERROR("Read HIF header failed"); + WINC_CRIT_SEC_HIF_LEAVE; + return M2M_ERR_FAIL; + } + + WINC_CRIT_SEC_HIF_LEAVE; + + strHif.u16Length = WINC_TO_HOST_U16(strHif.u16Length); + + if ((gu16RxSize - strHif.u16Length) > 4) + { + WINC_LOG_ERROR("Invalid packet Size = %u ", + gu16RxSize, strHif.u16Length, strHif.u8Gid, strHif.u8Opcode); + + return M2M_ERR_BUS_FAIL; + } + + if ((strHif.u8Gid == 0) || (strHif.u8Gid > WINC_HIF_CB_HIGHEST_GID)) + { + WINC_LOG_ERROR("Invalid group ID"); + + return M2M_ERR_FAIL; + } + + gHifCallbacks[strHif.u8Gid-1](strHif.u8Opcode, strHif.u16Length - M2M_HIF_HDR_OFFSET, gu32RxAddr + M2M_HIF_HDR_OFFSET); + + winc_adapter_interrupt_serviced(true); + + /* Set RX Done */ + winc_bus_set_reg_bits(WIFI_HOST_RCV_CTRL_0, NBIT1); + + winc_adapter_interrupt_serviced(false); + + if (winc_bus_error()) + return M2M_ERR_FAIL; + + return M2M_SUCCESS; +} + +int8_t winc_hif_receive(uint32_t u32Addr, const void *pvBuf, uint_fast16_t u16Sz) +{ + if (u16Sz > gu16RxSize) + { + WINC_LOG_ERROR("APP requested size is larger than the received buffer size <%u><%u>", u16Sz, gu16RxSize); + return M2M_ERR_FAIL; + } + + if ((u32Addr < gu32RxAddr) || ((u32Addr + u16Sz) > (gu32RxAddr + gu16RxSize))) + { + WINC_LOG_ERROR("APP requested address beyond the received buffer address and length"); + return M2M_ERR_FAIL; + } + + /* Receive the payload */ + if (WINC_BUS_SUCCESS != winc_bus_read_block(u32Addr, (void*)pvBuf, u16Sz)) + return M2M_ERR_FAIL; + + return M2M_SUCCESS; +} diff --git a/AVRIoT.X/mcc_generated_files/winc/driver/winc_hif.h b/AVRIoT.X/mcc_generated_files/winc/driver/winc_hif.h new file mode 100644 index 0000000..03cdaab --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/driver/winc_hif.h @@ -0,0 +1,185 @@ +/** + * + * \file + * + * \brief This module contains host interface APIs implementation. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef _WINC_HIF_H_ +#define _WINC_HIF_H_ + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +MACROS +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +#define M2M_HIF_MAX_PACKET_SIZE (1600 - 4) +/*!< Maximum size of the buffer could be transferred between Host and Firmware. +*/ + +#define M2M_HIF_HDR_OFFSET (sizeof(tstrHifHdr) + 4) + +/** +* @struct tstrHifHdr +* @brief Structure to hold HIF header +*/ +typedef struct +{ + uint8_t u8Gid; /*!< Group ID */ + uint8_t u8Opcode; /*!< OP code */ + uint16_t u16Length; /*!< Payload length */ +}tstrHifHdr; + +#ifdef __cplusplus + extern "C" { +#endif + +/*! +@typedef typedef void (*tpfHifCallBack)(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr); +@brief used to point to Wi-Fi call back function depend on Arduino project or other projects. +@param [in] u8OpCode + HIF Opcode type. +@param [in] u16DataSize + HIF data length. +@param [in] u32Addr + HIF address. +@param [in] grp + HIF group type. +*/ +typedef void (*tpfHifCallBack)(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr); +/** +* @fn int8_t winc_hif_init(void); +* @brief + To initialize HIF layer. +* @return + The function shall return ZERO for successful operation and a negative value otherwise. +*/ +int8_t winc_hif_init(void); +/** +* @fn int8_t winc_hif_deinit(void); +* @brief + To Deinitialize HIF layer. +* @return + The function shall return ZERO for successful operation and a negative value otherwise. +*/ +int8_t winc_hif_deinit(void); +/** +* @fn int8_t winc_hif_send(uint8_t u8Gid, uint8_t u8Opcode, const void *pvCtrlBuf, uint16_t u16CtrlBufSize, + const void *pvDataBuf, uint16_t u16DataSize, uint16_t u16DataOffset) +* @brief Send packet using host interface. + +* @param [in] u8Gid +* Group ID. +* @param [in] u8Opcode +* Operation ID. +* @param [in] pvCtrlBuf +* Pointer to the Control buffer. +* @param [in] u16CtrlBufSize + Control buffer size. +* @param [in] u16DataOffset + Packet Data offset. +* @param [in] pvDataBuf +* Packet buffer Allocated by the caller. +* @param [in] u16DataSize + Packet buffer size (including the HIF header). +* @return The function shall return ZERO for successful operation and a negative value otherwise. +*/ +int8_t winc_hif_send(uint8_t u8Gid, uint8_t u8Opcode, const void *pvCtrlBuf, uint16_t u16CtrlBufSize, + const void *pvDataBuf, uint16_t u16DataSize, uint16_t u16DataOffset); +/** +* @fn int8_t winc_hif_send_no_data(uint8_t u8Gid, uint8_t u8Opcode, const void *pvCtrlBuf, uint16_t u16CtrlBufSize) +* @brief Send packet using host interface. + +* @param [in] u8Gid +* Group ID. +* @param [in] u8Opcode +* Operation ID. +* @param [in] pvCtrlBuf +* Pointer to the Control buffer. +* @param [in] u16CtrlBufSize + Control buffer size. +* @return The function shall return ZERO for successful operation and a negative value otherwise. +*/ +int8_t winc_hif_send_no_data(uint8_t u8Gid, uint8_t u8Opcode, const void *pvCtrlBuf, uint16_t u16CtrlBufSize); +/* +* @fn winc_hif_receive +* @brief Host interface interrupt service routine +* @param [in] u32Addr +* Receive start address +* @param [out] pvBuf +* Pointer to receive buffer. Allocated by the caller +* @param [in] u16Sz +* Receive buffer size +* @return + The function shall return ZERO for successful operation and a negative value otherwise. +*/ +int8_t winc_hif_receive(uint32_t u32Addr, const void *pvBuf, uint_fast16_t u16Sz); +/** +* @fn int8_t winc_hif_chip_sleep(void); +* @brief + To make the chip sleep. +* @return + The function shall return ZERO for successful operation and a negative value otherwise. +*/ +int8_t winc_hif_chip_sleep(void); +/** +* @fn int8_t winc_hif_chip_wake(void); +* @brief + To Wakeup the chip. +* @return + The function shall return ZERO for successful operation and a negative value otherwise. +*/ +int8_t winc_hif_chip_wake(void); +/*! +@fn \ + void winc_hif_set_power_save(bool bPwrSave); + +@brief + Set the sleep mode of the HIF layer. + +@param [in] bPwrSave + Is power save active. +*/ +void winc_hif_set_power_save(bool bPwrSave); +/** +* @fn winc_hif_handle_isr(void) +* @brief + Handle interrupt received from WINC firmware. +* @return + The function SHALL return 0 for success and a negative value otherwise. +*/ +int8_t winc_hif_handle_isr(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/AVRIoT.X/mcc_generated_files/winc/driver/winc_spi.c b/AVRIoT.X/mcc_generated_files/winc/driver/winc_spi.c new file mode 100644 index 0000000..dc9c426 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/driver/winc_spi.c @@ -0,0 +1,700 @@ +/** + * + * \file + * + * \brief This module contains SPI protocol bus API implementation. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#include "../common/winc_debug.h" +#include "../common/winc_registers.h" +#include "winc_adapter.h" +#include "winc_spi.h" + +#define CMD_INTERNAL_WRITE 0xc3 +#define CMD_INTERNAL_READ 0xc4 +#define CMD_DMA_EXT_WRITE 0xc7 +#define CMD_DMA_EXT_READ 0xc8 +#define CMD_SINGLE_WRITE 0xc9 +#define CMD_SINGLE_READ 0xca +#define CMD_RESET 0xcf + +#define SPI_RESP_RETRY_COUNT (10) +#define DATA_PKT_SZ (8*1024) + +static bool bSPIBusError = true; + +static uint8_t spi_rsp(const uint8_t u8Type) +{ + int_fast8_t i = SPI_RESP_RETRY_COUNT; + uint8_t u8Rsp; + + WINC_ASSERT( ((u8Type & 0xf0) == 0xc0) || (u8Type == 0xf0) ); + + do + { + // Read single byte from SPI + if (!winc_adapter_spi_read(&u8Rsp, 1)) + { + WINC_LOG_ERROR("Failed response type read"); + return 0xff; + } + + if ((0xf0 == u8Type) && ((u8Rsp & 0xf0) == 0xf0)) + { + // If type is 0xf0 this is a data start header + // so just return the packet order in the lower nibble + return u8Rsp & 0xf0; + } + else if (u8Rsp == u8Type) + { + // Command response must match command type requested + // to be valid. Proceed to read the state value + if (!winc_adapter_spi_read(&u8Rsp, 1)) + { + WINC_LOG_ERROR("Failed response state read"); + return 0xff; + } + + return u8Rsp; + } + + // SPI bus must be idle while not receiving valid response + // only wait for number of bytes before failing response + } + while (!u8Rsp && i--); + + return 0xff; +} + +static int_fast8_t spi_cmd_send(const uint8_t *pu8Buf, const uint_fast8_t u8Sz) +{ + WINC_ASSERT(pu8Buf != NULL); + WINC_ASSERT(u8Sz >= 4); + + // Write command buffer to SPI + if (!winc_adapter_spi_write(pu8Buf, u8Sz)) + { + WINC_ASSERT(0); + WINC_LOG_ERROR("Failed command write"); + return WINC_BUS_FAIL; + } + + // Read back command response + if (spi_rsp(pu8Buf[0]) != 0) + { + WINC_ASSERT(0); + WINC_LOG_ERROR("Failed command response"); + return WINC_BUS_FAIL; + } + + // Response was valid and indicated no error condition + + return WINC_BUS_SUCCESS; +} + +static int_fast8_t spi_data_read(uint8_t *pu8Buf, uint_fast16_t u16Sz) +{ + uint_fast16_t u16NumBytes; + + WINC_ASSERT(pu8Buf != NULL); + WINC_ASSERT(u16Sz > 0); + + while (u16Sz) + { + // Limit size of a single transfer to DATA_PKT_SZ bytes + if (u16Sz <= DATA_PKT_SZ) + { + u16NumBytes = u16Sz; + } + else + { + u16NumBytes = DATA_PKT_SZ; + } + + // Get the data start byte and check for error in lower nibble + if (spi_rsp(0xf0) & 0x0c) + { + WINC_ASSERT(0); + WINC_LOG_ERROR("Failed data response read"); + return WINC_BUS_FAIL; + } + + // Read data packet + if (!winc_adapter_spi_read(pu8Buf, u16NumBytes)) + { + WINC_ASSERT(0); + WINC_LOG_ERROR("Failed data block read"); + return WINC_BUS_FAIL; + } + + pu8Buf += u16NumBytes; + u16Sz -= u16NumBytes; + } + + return WINC_BUS_SUCCESS; +} + +static int_fast8_t spi_data_write(const uint8_t *pu8Buf, uint_fast16_t u16Sz) +{ + uint_fast16_t u16NumBytes; + uint8_t u8Cmd; + + WINC_ASSERT(pu8Buf != NULL); + WINC_ASSERT(u16Sz > 0); + + // Default to data start as first packet in sequence + u8Cmd = 0xf1; + + while (u16Sz) + { + // Limit size of a single transfer to DATA_PKT_SZ bytes + if (u16Sz <= DATA_PKT_SZ) + { + u16NumBytes = u16Sz; + } + else + { + u16NumBytes = DATA_PKT_SZ; + } + + // Calculate remaining data size, if there is no more data after + // this packet then change the packet order to last in sequence + + u16Sz -= u16NumBytes; + + if (!u16Sz) + u8Cmd = 0xf3; + + // Write data start and packet order values + if (!winc_adapter_spi_write(&u8Cmd, 1)) + { + WINC_ASSERT(0); + WINC_LOG_ERROR("Failed data block command write"); + return WINC_BUS_FAIL; + } + + // Write data packet to SPI + if (!winc_adapter_spi_write(pu8Buf, u16NumBytes)) + { + WINC_ASSERT(0); + WINC_LOG_ERROR("Failed data block write"); + return WINC_BUS_FAIL; + } + + // Change default packet order to not first or last in sequence + u8Cmd = 0xf2; + + pu8Buf += u16NumBytes; + } + + return WINC_BUS_SUCCESS; +} + +static int_fast8_t spi_read_reg(uint32_t u32Addr, uint32_t *pu32RetVal) +{ + uint8_t u8TmpBuf[4]; + uint8_t u8CmdBuf[4]; + + WINC_ASSERT(pu32RetVal != NULL); + + if (u32Addr <= 0xff) + { + // Read is from clockless registers so setup command for internal read + u8CmdBuf[0] = CMD_INTERNAL_READ; + u8CmdBuf[1] = (1 << 7); + + // Shift register address up so following address buffer store puts the + // address in the right place + u32Addr <<= 8; + } + else + { + // Read is from clocked registers so setup command for normal read + u8CmdBuf[0] = CMD_SINGLE_READ; + + // Store first byte of register address before continuing below + u8CmdBuf[1] = (uint8_t)(u32Addr >> 16); + } + + // For clockless register addresses only the first store here is used which + // undoes the shift done above. For clocked registers the remaining two bytes + // of the address are stored and used. + u8CmdBuf[2] = (uint8_t)(u32Addr >> 8); + u8CmdBuf[3] = (uint8_t)u32Addr; + + // Send command buffer via SPI bus + if (WINC_BUS_SUCCESS != spi_cmd_send(u8CmdBuf, 4)) + { + WINC_ASSERT(0); + WINC_LOG_ERROR("Failed command, read reg (%08" PRIx32 ")", u32Addr); + return WINC_BUS_FAIL; + } + + // Read data, to avoid endianness issue use a temporary buffer to receive the + // bytes in WINC order. + if (WINC_BUS_SUCCESS != spi_data_read(&u8TmpBuf[0], 4)) + { + WINC_ASSERT(0); + WINC_LOG_ERROR("Failed data read"); + return WINC_BUS_FAIL; + } + + // Translate received bytes into 32-bit value + *pu32RetVal = u8TmpBuf[0] | + ((uint32_t)u8TmpBuf[1] << 8) | + ((uint32_t)u8TmpBuf[2] << 16) | + ((uint32_t)u8TmpBuf[3] << 24); + + return WINC_BUS_SUCCESS; +} + +static int_fast8_t spi_write_reg(const uint32_t u32Addr, const uint32_t u32Val, bool bCheckRsp) +{ + uint_fast8_t cmd_sz; + uint8_t u8CmdBuf[8]; + uint8_t *pu8CmdBuf = u8CmdBuf; + + if (u32Addr <= 0x30) + { + // Write is to clockless registers so setup command for internal write + u8CmdBuf[0] = CMD_INTERNAL_WRITE; + + u8CmdBuf[1] = (1 << 7); + + cmd_sz = 7; + pu8CmdBuf += 2; + } + else + { + // Write is to clocked registers so setup command for normal write + u8CmdBuf[0] = CMD_SINGLE_WRITE; + + // Store first two bytes of address, the last is completed below in + // common with clockless write. + u8CmdBuf[1] = (uint8_t)(u32Addr >> 16); + u8CmdBuf[2] = (uint8_t)(u32Addr >> 8); + + cmd_sz = 8; + pu8CmdBuf += 3; + } + + // Store last byte of address (only byte for clockless registers) + pu8CmdBuf[0] = (uint8_t)(u32Addr); + + // Store new register value in WINC order + pu8CmdBuf[1] = (uint8_t)(u32Val >> 24); + pu8CmdBuf[2] = (uint8_t)(u32Val >> 16); + pu8CmdBuf[3] = (uint8_t)(u32Val >> 8); + pu8CmdBuf[4] = (uint8_t)(u32Val); + + if (bCheckRsp) + { + // Send command and check for valid response + if (WINC_BUS_SUCCESS != spi_cmd_send(u8CmdBuf, cmd_sz)) + { + WINC_ASSERT(0); + WINC_LOG_ERROR("Failed command, write reg (%08" PRIx32 ")", u32Addr); + return WINC_BUS_FAIL; + } + } + else + { + // Send command but don't look for a response + if (!winc_adapter_spi_write(u8CmdBuf, cmd_sz)) + { + WINC_ASSERT(0); + WINC_LOG_ERROR("Failed command write"); + return WINC_BUS_FAIL; + } + } + + return WINC_BUS_SUCCESS; +} + +int_fast8_t winc_bus_write_reg(const uint32_t u32Addr, const uint32_t u32Val) +{ + // External API: Don't run if bus error is present, preset error so only + // successful path leads to clearing the error condition + WINC_CRIT_SEC_BUS_ENTER; + if (bSPIBusError) + { + WINC_ASSERT(0); + return WINC_BUS_FAIL; + } + bSPIBusError = true; + + if (WINC_BUS_SUCCESS != spi_write_reg(u32Addr, u32Val, 1)) + { + WINC_ASSERT(0); + return WINC_BUS_FAIL; + } + + // Clear bus error condition as operation was successful + bSPIBusError = false; + WINC_CRIT_SEC_BUS_LEAVE; + return WINC_BUS_SUCCESS; +} + +int_fast8_t winc_bus_write_reg_no_rsp(const uint32_t u32Addr, const uint32_t u32Val) +{ + // External API: Don't run if bus error is present, preset error so only + // successful path leads to clearing the error condition + WINC_CRIT_SEC_BUS_ENTER; + if (bSPIBusError) + { + WINC_ASSERT(0); + return WINC_BUS_FAIL; + } + bSPIBusError = true; + + if (WINC_BUS_SUCCESS != spi_write_reg(u32Addr, u32Val, 0)) + { + WINC_ASSERT(0); + return WINC_BUS_FAIL; + } + + // Clear bus error condition as operation was successful + bSPIBusError = false; + WINC_CRIT_SEC_BUS_LEAVE; + return WINC_BUS_SUCCESS; +} + +int_fast8_t winc_bus_write_block(uint32_t u32Addr, const uint8_t *pu8Buf, uint_fast16_t u16Sz) +{ + uint8_t u8CmdBuf[7] = {CMD_DMA_EXT_WRITE}; + + WINC_ASSERT(pu8Buf != NULL); + WINC_ASSERT(u16Sz > 0); + + // External API: Don't run if bus error is present, preset error so only + // successful path leads to clearing the error condition + WINC_CRIT_SEC_BUS_ENTER; + if (bSPIBusError) + { + WINC_ASSERT(0); + return WINC_BUS_FAIL; + } + bSPIBusError = true; + + //Workaround hardware problem with single byte transfers over SPI bus + if (u16Sz == 1) + u16Sz = 2; + + // Store destination address and transfer size into buffer + u8CmdBuf[1] = (uint8_t)(u32Addr >> 16); + u8CmdBuf[2] = (uint8_t)(u32Addr >> 8); + u8CmdBuf[3] = (uint8_t)u32Addr; + u8CmdBuf[4] = 0; + u8CmdBuf[5] = (uint8_t)(u16Sz >> 8); + u8CmdBuf[6] = (uint8_t)(u16Sz); + + // Send command buffer + if (WINC_BUS_SUCCESS != spi_cmd_send(u8CmdBuf, 7)) + { + WINC_ASSERT(0); + WINC_LOG_ERROR("Failed command, write block (%08" PRIx32 ")", u32Addr); + return WINC_BUS_FAIL; + } + + // Send data packet + if (WINC_BUS_SUCCESS != spi_data_write(pu8Buf, u16Sz)) + { + WINC_ASSERT(0); + WINC_LOG_ERROR("Failed block data write"); + return WINC_BUS_FAIL; + } + + // Check data response + if (spi_rsp(0xc3) != 0) + { + WINC_ASSERT(0); + WINC_LOG_ERROR("Failed block data response"); + return WINC_BUS_FAIL; + } + + // Clear bus error condition as operation was successful + bSPIBusError = false; + WINC_CRIT_SEC_BUS_LEAVE; + return WINC_BUS_SUCCESS; +} + +int_fast8_t winc_bus_read_block(const uint32_t u32Addr, uint8_t *pu8Buf, uint_fast16_t u16Sz) +{ + int_fast8_t i8Result; + uint8_t u8TmpBuf[2]; + uint8_t u8CmdBuf[7] = {CMD_DMA_EXT_READ}; + + WINC_ASSERT(pu8Buf != NULL); + WINC_ASSERT(u16Sz > 0); + + // External API: Don't run if bus error is present, preset error so only + // successful path leads to clearing the error condition + WINC_CRIT_SEC_BUS_ENTER; + if (bSPIBusError) + { + WINC_ASSERT(0); + return WINC_BUS_FAIL; + } + bSPIBusError = true; + + // Store address into buffer + u8CmdBuf[1] = (uint8_t)(u32Addr >> 16); + u8CmdBuf[2] = (uint8_t)(u32Addr >> 8); + u8CmdBuf[3] = (uint8_t)u32Addr; + + // Store first byte of transfer size into buffer + u8CmdBuf[4] = 0; + + if (u16Sz == 1) + { + // Possible issue with single byte transfers, request two bytes instead + u8CmdBuf[5] = 0; + u8CmdBuf[6] = 2; + } + else + { + // Store remaining bytes of transfer size into buffer + u8CmdBuf[5] = (uint8_t)(u16Sz >> 8); + u8CmdBuf[6] = (uint8_t)(u16Sz); + } + + // Send command buffer + if (WINC_BUS_SUCCESS != spi_cmd_send(u8CmdBuf, 7)) + { + WINC_ASSERT(0); + WINC_LOG_ERROR("Failed command, read block (%08" PRIx32 ")", u32Addr); + return WINC_BUS_FAIL; + } + + // Read data packet + if (u16Sz == 1) + { + // For single byte transfer go via a temporary buffer to + // ensure second byte requested doesn't trash memory if caller + // only supplied a single byte buffer + i8Result = spi_data_read(u8TmpBuf, 2); + pu8Buf[0] = u8TmpBuf[0]; + } + else + { + i8Result = spi_data_read(pu8Buf, u16Sz); + } + + if (WINC_BUS_SUCCESS != i8Result) + { + WINC_ASSERT(0); + WINC_LOG_ERROR("Failed block data read"); + return WINC_BUS_FAIL; + } + + // Clear bus error condition as operation was successful + bSPIBusError = false; + WINC_CRIT_SEC_BUS_LEAVE; + return WINC_BUS_SUCCESS; +} + +int_fast8_t winc_bus_init(void) +{ + static const uint8_t u8CmdBuf[9] = + { + CMD_SINGLE_WRITE, + 0x00, + (NMI_SPI_PROTOCOL_CONFIG >> 8) & 0xff, + (NMI_SPI_PROTOCOL_CONFIG) & 0xff, + 0x00, + 0x00, + 0x00, + 0x52, + 0x5c + }; + + WINC_CRIT_SEC_BUS_INIT; + + // Initialize bus error to clear, send SPI protocol configuration + // as first test of SPI bus. + bSPIBusError = false; + + return spi_cmd_send(u8CmdBuf, 9); +} + +int_fast8_t winc_bus_reset(void) +{ + static const uint8_t u8CmdBuf[5] = {CMD_RESET, 0xff, 0xff, 0xff, 0x00/*, 0xaa*/}; + + // Clear bus error condition to allow command send to work + bSPIBusError = false; + +#ifdef WINC_CRIT_SEC_BUS + if (WINC_BUS_SUCCESS != spi_cmd_send(u8CmdBuf, 5)) + { + WINC_ASSERT(0); + return WINC_BUS_FAIL; + } + + WINC_CRIT_SEC_BUS_LEAVE; + + return WINC_BUS_SUCCESS; +#else + // Send command to reset SPI + return spi_cmd_send(u8CmdBuf, 5); +#endif +} + +int_fast8_t winc_bus_deinit(void) +{ + WINC_CRIT_SEC_BUS_DEINIT; + + // Set bus error condition so all external APIs related to actual SPI use + // effectively become NOPs + bSPIBusError = true; + + return WINC_BUS_SUCCESS; +} + +uint32_t winc_bus_read_reg(const uint32_t u32Addr) +{ + uint32_t u32Val; + + // External API: Don't run if bus error is present, preset error so only + // successful path leads to clearing the error condition + WINC_CRIT_SEC_BUS_ENTER; + if (bSPIBusError) + { + WINC_ASSERT(0); + return 0; + } + bSPIBusError = true; + + if (WINC_BUS_SUCCESS != spi_read_reg(u32Addr, &u32Val)) + { + WINC_ASSERT(0); + return 0; + } + + // Clear bus error condition as operation was successful + bSPIBusError = false; + WINC_CRIT_SEC_BUS_LEAVE; + return u32Val; +} + +int_fast8_t winc_bus_read_reg_with_ret(const uint32_t u32Addr, uint32_t *pu32RetVal) +{ + WINC_ASSERT(pu32RetVal != NULL); + + // External API: Don't run if bus error is present, preset error so only + // successful path leads to clearing the error condition + WINC_CRIT_SEC_BUS_ENTER; + if (bSPIBusError) + { + WINC_ASSERT(0); + return WINC_BUS_FAIL; + } + bSPIBusError = true; + + if (WINC_BUS_SUCCESS != spi_read_reg(u32Addr, pu32RetVal)) + { + WINC_ASSERT(0); + return WINC_BUS_FAIL; + } + + // Clear bus error condition as operation was successful + bSPIBusError = false; + WINC_CRIT_SEC_BUS_LEAVE; + return WINC_BUS_SUCCESS; +} + +int_fast8_t winc_bus_set_reg_bits(uint32_t u32Addr, uint32_t u32Bits) +{ + uint32_t u32Reg; + + // External API: Only calls other external APIs so if bus error is present + // this function becomes NOP + + // Read the current value of the register + winc_bus_read_reg_with_ret(u32Addr, &u32Reg); + + if ((u32Reg & u32Bits) != u32Bits) + { + // Only set the bits request if they are not already set + u32Reg |= u32Bits; + + winc_bus_write_reg(u32Addr, u32Reg); + } + + if (winc_bus_error()) + { + return WINC_BUS_FAIL; + } + + return WINC_BUS_SUCCESS; +} + +int_fast8_t winc_bus_clear_reg_bits(uint32_t u32Addr, uint32_t u32Bits) +{ + uint32_t u32Reg; + + // External API: Only calls other external APIs so if bus error is present + // this function becomes NOP + + // Read the current value of the register + winc_bus_read_reg_with_ret(u32Addr, &u32Reg); + + if (u32Reg & u32Bits) + { + // Only clear the bits request if some of them are actually set + u32Reg &= ~u32Bits; + + winc_bus_write_reg(u32Addr, u32Reg); + } + + if (winc_bus_error()) + { + return WINC_BUS_FAIL; + } + + return WINC_BUS_SUCCESS; +} + +bool winc_bus_error(void) +{ + bool bRetErrorStatus; + + WINC_CRIT_SEC_BUS_ENTER; + WINC_ASSERT(bSPIBusError == false); + + bRetErrorStatus = bSPIBusError; + WINC_CRIT_SEC_BUS_LEAVE; + + // Return current bus error condition + return bRetErrorStatus; +} diff --git a/AVRIoT.X/mcc_generated_files/winc/driver/winc_spi.h b/AVRIoT.X/mcc_generated_files/winc/driver/winc_spi.h new file mode 100644 index 0000000..44a43de --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/driver/winc_spi.h @@ -0,0 +1,65 @@ +/** + * + * \file + * + * \brief This module contains SPI protocol bus API declarations. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef _WINC_SPI_H_ +#define _WINC_SPI_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define WINC_BUS_SUCCESS 0 +#define WINC_BUS_FAIL 1 + +int_fast8_t winc_bus_init(void); +int_fast8_t winc_bus_reset(void); +int_fast8_t winc_bus_deinit(void); +uint32_t winc_bus_read_reg(const uint32_t u32Addr); +int_fast8_t winc_bus_read_reg_with_ret(const uint32_t u32Addr, uint32_t *pu32RetVal); +int_fast8_t winc_bus_write_reg(const uint32_t u32Addr, const uint32_t u32Val); +int_fast8_t winc_bus_write_reg_no_rsp(const uint32_t u32Addr, const uint32_t u32Val); +int_fast8_t winc_bus_read_block(const uint32_t u32Addr, uint8_t *pu8Buf, uint_fast16_t u16Sz); +int_fast8_t winc_bus_write_block(uint32_t u32Addr, const uint8_t *pu8Buf, uint_fast16_t u16Sz); +int_fast8_t winc_bus_set_reg_bits(uint32_t u32Addr, uint32_t u32Bits); +int_fast8_t winc_bus_clear_reg_bits(uint32_t u32Addr, uint32_t u32Bits); +bool winc_bus_error(void); + +#ifdef __cplusplus + } +#endif + +#endif /* _WINC_SPI_H_ */ diff --git a/AVRIoT.X/mcc_generated_files/winc/include/conf_winc_defaults.h b/AVRIoT.X/mcc_generated_files/winc/include/conf_winc_defaults.h new file mode 100644 index 0000000..a3544ea --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/include/conf_winc_defaults.h @@ -0,0 +1,123 @@ +/** + * + * \file + * + * \brief Default WINC configuration. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#include + +#ifndef CONF_WINC_DEFAULTS_H_INCLUDED +#define CONF_WINC_DEFAULTS_H_INCLUDED + +#ifndef CONF_WINC_PRINTF +#define CONF_WINC_PRINTF printf +#endif + +#ifndef CONF_WINC_RESET_ASSERT_TIME +#define CONF_WINC_RESET_ASSERT_TIME 50 +#endif + + +/* Define to allow callback macros */ +#define CONF_WINC_HIF_CB_WIFI_HANDLER m2m_wifi_cb +#define CONF_WINC_HIF_CB_IP_HANDLER m2m_ip_cb +#define CONF_WINC_HIF_CB_SSL_HANDLER m2m_ssl_cb + +#ifdef CONF_WINC_HIF_CB_IP_HANDLER +void CONF_WINC_HIF_CB_IP_HANDLER(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr); +#else +#define CONF_WINC_HIF_CB_IP_HANDLER hif_null_cb +#endif + +#ifdef CONF_WINC_HIF_CB_HIF_HANDLER +void CONF_WINC_HIF_CB_HIF_HANDLER(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr); +#else +#define CONF_WINC_HIF_CB_HIF_HANDLER hif_null_cb +#endif + +#ifdef CONF_WINC_HIF_CB_OTA_HANDLER +void CONF_WINC_HIF_CB_OTA_HANDLER(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr); +#else +#define CONF_WINC_HIF_CB_OTA_HANDLER hif_null_cb +#endif + +#ifdef CONF_WINC_HIF_CB_SSL_HANDLER +void CONF_WINC_HIF_CB_SSL_HANDLER(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr); +#else +#define CONF_WINC_HIF_CB_SSL_HANDLER hif_null_cb +#endif + +#ifdef CONF_WINC_HIF_CB_CRYPTO_HANDLER +void CONF_WINC_HIF_CB_CRYPTO_HANDLER(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr); +#else +#define CONF_WINC_HIF_CB_CRYPTO_HANDLER hif_null_cb +#endif + +#ifdef CONF_WINC_HIF_CB_SIGMA_HANDLER +void CONF_WINC_HIF_CB_SIGMA_HANDLER(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr); +#else +#define CONF_WINC_HIF_CB_SIGMA_HANDLER hif_null_cb +#endif + +#if defined(CONF_WINC_MCU_ARCH_LITTLE_ENDIAN) +#elif defined(CONF_WINC_MCU_ARCH_BIG_ENDIAN) +#else +#error Please define MCU endianness +#endif + +#ifndef CONF_WINC_HIF_STRUCT_SIZE_CHECK +#ifdef __GNUC__ +#define CONF_WINC_HIF_STRUCT_SIZE_CHECK(STRUCTNAME) _Static_assert((sizeof(STRUCTNAME)%4)==0, "Structure alignment error"); +#elif !defined(_WIN32) && !defined(_STDC_) +#define CONF_WINC_HIF_STRUCT_SIZE_CHECK(STRUCTNAME) static_assert((sizeof(STRUCTNAME)%4)==0, "Structure alignment error"); +#else +#define CONF_WINC_HIF_STRUCT_SIZE_CHECK(STRUCTNAME) +#endif +#endif + +#ifndef WINC_CRIT_SEC_HIF +#define WINC_CRIT_SEC_HIF_INIT +#define WINC_CRIT_SEC_HIF_DEINIT +#define WINC_CRIT_SEC_HIF_ENTER +#define WINC_CRIT_SEC_HIF_LEAVE +#endif + +#ifndef WINC_CRIT_SEC_BUS +#define WINC_CRIT_SEC_BUS_INIT +#define WINC_CRIT_SEC_BUS_DEINIT +#define WINC_CRIT_SEC_BUS_ENTER +#define WINC_CRIT_SEC_BUS_LEAVE +#endif + +#endif /* CONF_WINC_DEFAULTS_H_INCLUDED */ diff --git a/AVRIoT.X/mcc_generated_files/winc/include/winc.h b/AVRIoT.X/mcc_generated_files/winc/include/winc.h new file mode 100644 index 0000000..3c41471 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/include/winc.h @@ -0,0 +1,64 @@ +/** + * + * \file + * + * \brief Primary include file for applications. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef _WINC_H_ +#define _WINC_H_ + +#include + +#include "../driver/winc_adapter.h" + +#ifdef CONF_WINC_LEGACY_DEFINITIONS +#include "winc_legacy.h" +#endif + +#include "../common/winc_defines.h" +#include "../common/winc_debug.h" +#include "../m2m/m2m_types.h" +#include "../m2m/m2m_wifi.h" +#include "../m2m/m2m_periph.h" +#ifndef CONF_WINC_DISABLE_SOCKET_API +#include "../m2m/m2m_ota.h" +#include "../common/ecc_types.h" +#include "../m2m/m2m_ssl.h" +#include "../socket/socket.h" +#endif +#include "../spi_flash/flexible_flash.h" +#include "../spi_flash/spi_flash_map.h" +#include "../spi_flash/spi_flash.h" + +#endif diff --git a/AVRIoT.X/mcc_generated_files/winc/include/winc_legacy.h b/AVRIoT.X/mcc_generated_files/winc/include/winc_legacy.h new file mode 100644 index 0000000..7c98d95 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/include/winc_legacy.h @@ -0,0 +1,60 @@ +/** + * + * \file + * + * \brief Legacy Adaption Layer. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef _WINC_LEGACY_H_ +#define _WINC_LEGACY_H_ + +#define NMI_API + +#define CONST const + +#define uint8 uint8_t +#define uint16 uint16_t +#define uint32 uint32_t +#define sint8 int8_t +#define sint16 int16_t +#define sint32 int32_t + +#define m2m_strlen strlen +#define m2m_memcpy memcpy +#define m2m_memset memset +#define m2m_memcmp memcmp +#define m2m_strstr strstr + +#define m2m_wifi_yield() + +#endif /* _WINC_LEGACY_H_ */ \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_crypto.c b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_crypto.c new file mode 100644 index 0000000..d26a6d0 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_crypto.c @@ -0,0 +1,1012 @@ +/** + * + * \file + * + * \brief WINC Crypto module. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +INCLUDES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +#include "../driver/winc_adapter.h" +#include "../common/winc_defines.h" +#include "../common/winc_debug.h" +#include "m2m_types.h" +#include "m2m_crypto.h" +#include "../driver/winc_hif.h" +#include "../driver/winc_asic.h" +#include "../driver/winc_spi.h" + +#ifdef CONF_CRYPTO_HW + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +MACROS +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +/*======*======*======*======*======*=======* +* WINC SHA256 HW Engine Register Definition * +*======*======*======*======*======*========*/ + +#define SHA_BLOCK_SIZE (64) + +#define SHARED_MEM_BASE (0xd0000) + + +#define SHA256_MEM_BASE (0x180000UL) +#define SHA256_ENGINE_ADDR (0x180000ul) + +/* SHA256 Registers */ +#define SHA256_CTRL (SHA256_MEM_BASE+0x00) +#define SHA256_CTRL_START_CALC_MASK (NBIT0) +#define SHA256_CTRL_START_CALC_SHIFT (0) +#define SHA256_CTRL_PREPROCESS_MASK (NBIT1) +#define SHA256_CTRL_PREPROCESS_SHIFT (1) +#define SHA256_CTRL_HASH_HASH_MASK (NBIT2) +#define SHA256_CTRL_HASH_HASH_SHIFT (2) +#define SHA256_CTRL_INIT_SHA256_STATE_MASK (NBIT3) +#define SHA256_CTRL_INIT_SHA256_STATE_SHIFT (3) +#define SHA256_CTRL_WR_BACK_HASH_VALUE_MASK (NBIT4) +#define SHA256_CTRL_WR_BACK_HASH_VALUE_SHIFT (4) +#define SHA256_CTRL_FORCE_SHA256_QUIT_MASK (NBIT5) +#define SHA256_CTRL_FORCE_SHA256_QUIT_SHIFT (5) + +#define SHA256_REGS_SHA256_CTRL_AHB_BYTE_REV_EN (NBIT6) +#define SHA256_REGS_SHA256_CTRL_RESERVED (NBIT7) +#define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO (NBIT8+ NBIT9+ NBIT10) +#define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO_MASK (NBIT2+ NBIT1+ NBIT0) +#define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO_SHIFT (8) +#define SHA256_REGS_SHA256_CTRL_RESERVED_11 (NBIT11) +#define SHA256_REGS_SHA256_CTRL_SHA1_CALC (NBIT12) +#define SHA256_REGS_SHA256_CTRL_PBKDF2_SHA1_CALC (NBIT13) + + +#define SHA256_START_RD_ADDR (SHA256_MEM_BASE+0x04UL) +#define SHA256_DATA_LENGTH (SHA256_MEM_BASE+0x08UL) +#define SHA256_START_WR_ADDR (SHA256_MEM_BASE+0x0cUL) +#define SHA256_COND_CHK_CTRL (SHA256_MEM_BASE+0x10) +#define SHA256_COND_CHK_CTRL_HASH_VAL_COND_CHK_MASK (NBIT1 | NBIT0) +#define SHA256_COND_CHK_CTRL_HASH_VAL_COND_CHK_SHIFT (0) +#define SHA256_COND_CHK_CTRL_STEP_VAL_MASK (NBIT6 | NBIT5 | NBIT4 | NBIT3 | NBIT2) +#define SHA256_COND_CHK_CTRL_STEP_VAL_SHIFT (2) +#define SHA256_COND_CHK_CTRL_COND_CHK_RESULT_MASK (NBIT7) +#define SHA256_COND_CHK_CTRL_COND_CHK_RESULT_SHIFT (7) + +#define SHA256_MOD_DATA_RANGE (SHA256_MEM_BASE+0x14) +#define SHA256_MOD_DATA_RANGE_ST_BYTE_2_ADD_STP_MASK (NBIT24-1) +#define SHA256_MOD_DATA_RANGE_ST_BYTE_2_ADD_STP_SHIFT (0) +#define SHA256_MOD_DATA_RANGE_MOD_DATA_LEN_MASK (NBIT24 | NBIT25| NBIT26) +#define SHA256_MOD_DATA_RANGE_MOD_DATA_LEN_SHIFT (24) + + +#define SHA256_COND_CHK_STS_1 (SHA256_MEM_BASE+0x18) +#define SHA256_COND_CHK_STS_2 (SHA256_MEM_BASE+0x1c) +#define SHA256_DONE_INTR_ENABLE (SHA256_MEM_BASE+0x20) +#define SHA256_DONE_INTR_STS (SHA256_MEM_BASE+0x24) +#define SHA256_TARGET_HASH_H1 (SHA256_MEM_BASE+0x28) +#define SHA256_TARGET_HASH_H2 (SHA256_MEM_BASE+0x2c) +#define SHA256_TARGET_HASH_H3 (SHA256_MEM_BASE+0x30) +#define SHA256_TARGET_HASH_H4 (SHA256_MEM_BASE+0x34) +#define SHA256_TARGET_HASH_H5 (SHA256_MEM_BASE+0x38) +#define SHA256_TARGET_HASH_H6 (SHA256_MEM_BASE+0x3c) +#define SHA256_TARGET_HASH_H7 (SHA256_MEM_BASE+0x40) +#define SHA256_TARGET_HASH_H8 (SHA256_MEM_BASE+0x44) + +/*======*======*======*======*======*=======* +* WINC BIGINT HW Engine Register Definition * +*======*======*======*======*======*========*/ + + +#define BIGINT_ENGINE_ADDR (0x180080ul) +#define BIGINT_VERSION (BIGINT_ENGINE_ADDR + 0x00) + +#define BIGINT_MISC_CTRL (BIGINT_ENGINE_ADDR + 0x04) +#define BIGINT_MISC_CTRL_CTL_START (NBIT0) +#define BIGINT_MISC_CTRL_CTL_RESET (NBIT1) +#define BIGINT_MISC_CTRL_CTL_MSW_FIRST (NBIT2) +#define BIGINT_MISC_CTRL_CTL_SWAP_BYTE_ORDER (NBIT3) +#define BIGINT_MISC_CTRL_CTL_FORCE_BARRETT (NBIT4) +#define BIGINT_MISC_CTRL_CTL_M_PRIME_VALID (NBIT5) + +#define BIGINT_M_PRIME (BIGINT_ENGINE_ADDR + 0x08) + +#define BIGINT_STATUS (BIGINT_ENGINE_ADDR + 0x0C) +#define BIGINT_STATUS_STS_DONE (NBIT0) + +#define BIGINT_CLK_COUNT (BIGINT_ENGINE_ADDR + 0x10) +#define BIGINT_ADDR_X (BIGINT_ENGINE_ADDR + 0x14) +#define BIGINT_ADDR_E (BIGINT_ENGINE_ADDR + 0x18) +#define BIGINT_ADDR_M (BIGINT_ENGINE_ADDR + 0x1C) +#define BIGINT_ADDR_R (BIGINT_ENGINE_ADDR + 0x20) +#define BIGINT_LENGTH (BIGINT_ENGINE_ADDR + 0x24) + +#define BIGINT_IRQ_STS (BIGINT_ENGINE_ADDR + 0x28) +#define BIGINT_IRQ_STS_DONE (NBIT0) +#define BIGINT_IRQ_STS_CHOOSE_MONT (NBIT1) +#define BIGINT_IRQ_STS_M_READ (NBIT2) +#define BIGINT_IRQ_STS_X_READ (NBIT3) +#define BIGINT_IRQ_STS_START (NBIT4) +#define BIGINT_IRQ_STS_PRECOMP_FINISH (NBIT5) + +#define BIGINT_IRQ_MASK (BIGINT_ENGINE_ADDR + 0x2C) +#define BIGINT_IRQ_MASK_CTL_IRQ_MASK_START (NBIT4) + +#define ENABLE_FLIPPING 1 + + + + +#define GET_UINT32(BUF,OFFSET) ((((uint32_t)(BUF)[OFFSET])) | ((((uint32_t)(BUF)[OFFSET + 1]) << 8)) | \ +((((uint32_t)(BUF)[OFFSET + 2]) << 16)) | ((((uint32_t)(BUF)[OFFSET + 3]) << 24))) + +#define PUTU32(VAL32,BUF,OFFSET) \ +do \ +{ \ + (BUF)[OFFSET ] = BYTE_3((VAL32)); \ + (BUF)[OFFSET +1 ] = BYTE_2((VAL32)); \ + (BUF)[OFFSET +2 ] = BYTE_1((VAL32)); \ + (BUF)[OFFSET +3 ] = BYTE_0((VAL32)); \ +}while(0) + + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +DATA TYPES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +/*! +@struct \ + tstrHashContext + +@brief +*/ +typedef struct{ + uint32_t au32HashState[M2M_SHA256_DIGEST_LEN/4]; + uint8_t au8CurrentBlock[64]; + uint32_t u32TotalLength; + uint8_t u8InitHashFlag; +}tstrSHA256HashCtxt; + + + +/*======*======*======*======*======*=======* +* SHA256 IMPLEMENTATION * +*======*======*======*======*======*========*/ + +int8_t m2m_crypto_sha256_hash_init(tstrM2mSha256Ctxt *pstrSha256Ctxt) +{ + tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt*)pstrSha256Ctxt; + if(pstrSHA256 != NULL) + { + memset(pstrSha256Ctxt, 0, sizeof(tstrM2mSha256Ctxt)); + pstrSHA256->u8InitHashFlag = 1; + } + return 0; +} + +int8_t m2m_crypto_sha256_hash_update(tstrM2mSha256Ctxt *pstrSha256Ctxt, uint8_t *pu8Data, uint16_t u16DataLength) +{ + int8_t s8Ret = M2M_ERR_FAIL; + tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt*)pstrSha256Ctxt; + if(pstrSHA256 != NULL) + { + uint32_t u32ReadAddr; + uint32_t u32WriteAddr = SHARED_MEM_BASE; + uint32_t u32Addr = u32WriteAddr; + uint32_t u32ResidualBytes; + uint32_t u32NBlocks; + uint32_t u32Offset; + uint32_t u32CurrentBlock = 0; + uint8_t u8IsDone = 0; + + /* Get the remaining bytes from the previous update (if the length is not block aligned). */ + u32ResidualBytes = pstrSHA256->u32TotalLength % SHA_BLOCK_SIZE; + + /* Update the total data length. */ + pstrSHA256->u32TotalLength += u16DataLength; + + if(u32ResidualBytes != 0) + { + if((u32ResidualBytes + u16DataLength) >= SHA_BLOCK_SIZE) + { + u32Offset = SHA_BLOCK_SIZE - u32ResidualBytes; + memcpy(&pstrSHA256->au8CurrentBlock[u32ResidualBytes], pu8Data, u32Offset); + pu8Data += u32Offset; + u16DataLength -= u32Offset; + + winc_bus_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE); + u32Addr += SHA_BLOCK_SIZE; + u32CurrentBlock = 1; + } + else + { + memcpy(&pstrSHA256->au8CurrentBlock[u32ResidualBytes], pu8Data, u16DataLength); + u16DataLength = 0; + } + } + + /* Get the number of HASH BLOCKs and the residual bytes. */ + u32NBlocks = u16DataLength / SHA_BLOCK_SIZE; + u32ResidualBytes = u16DataLength % SHA_BLOCK_SIZE; + + if(u32NBlocks != 0) + { + winc_bus_write_block(u32Addr, pu8Data, (uint16_t)(u32NBlocks * SHA_BLOCK_SIZE)); + pu8Data += (u32NBlocks * SHA_BLOCK_SIZE); + } + + u32NBlocks += u32CurrentBlock; + if(u32NBlocks != 0) + { + uint32_t u32RegVal = 0; + + winc_bus_write_reg(SHA256_CTRL, u32RegVal); + u32RegVal |= SHA256_CTRL_FORCE_SHA256_QUIT_MASK; + winc_bus_write_reg(SHA256_CTRL, u32RegVal); + + if(pstrSHA256->u8InitHashFlag) + { + pstrSHA256->u8InitHashFlag = 0; + u32RegVal |= SHA256_CTRL_INIT_SHA256_STATE_MASK; + } + + u32ReadAddr = u32WriteAddr + (u32NBlocks * SHA_BLOCK_SIZE); + winc_bus_write_reg(SHA256_DATA_LENGTH, (u32NBlocks * SHA_BLOCK_SIZE)); + winc_bus_write_reg(SHA256_START_RD_ADDR, u32WriteAddr); + winc_bus_write_reg(SHA256_START_WR_ADDR, u32ReadAddr); + + u32RegVal |= SHA256_CTRL_START_CALC_MASK; + + u32RegVal &= ~(0x7 << 8); + u32RegVal |= (2 << 8); + + winc_bus_write_reg(SHA256_CTRL, u32RegVal); + + /* 5. Wait for done_intr */ + while(!u8IsDone) + { + u32RegVal = winc_bus_read_reg(SHA256_DONE_INTR_STS); + u8IsDone = u32RegVal & NBIT0; + } + } + if(u32ResidualBytes != 0) + { + memcpy(pstrSHA256->au8CurrentBlock, pu8Data, u32ResidualBytes); + } + s8Ret = M2M_SUCCESS; + } + return s8Ret; +} + + +int8_t m2m_crypto_sha256_hash_finish(tstrM2mSha256Ctxt *pstrSha256Ctxt, uint8_t *pu8Sha256Digest) +{ + int8_t s8Ret = M2M_ERR_FAIL; + tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt*)pstrSha256Ctxt; + if(pstrSHA256 != NULL) + { + uint32_t u32ReadAddr; + uint32_t u32WriteAddr = SHARED_MEM_BASE; + uint32_t u32Addr = u32WriteAddr; + uint16_t u16Offset; + uint16_t u16PaddingLength; + uint16_t u16NBlocks = 1; + uint32_t u32RegVal = 0; + uint32_t u32Idx,u32ByteIdx; + uint32_t au32Digest[M2M_SHA256_DIGEST_LEN / 4]; + uint8_t u8IsDone = 0; + + winc_bus_write_reg(SHA256_CTRL,u32RegVal); + u32RegVal |= SHA256_CTRL_FORCE_SHA256_QUIT_MASK; + winc_bus_write_reg(SHA256_CTRL,u32RegVal); + + if(pstrSHA256->u8InitHashFlag) + { + pstrSHA256->u8InitHashFlag = 0; + u32RegVal |= SHA256_CTRL_INIT_SHA256_STATE_MASK; + } + + /* Calculate the offset of the last data byte in the current block. */ + u16Offset = (uint16_t)(pstrSHA256->u32TotalLength % SHA_BLOCK_SIZE); + + /* Add the padding byte 0x80. */ + pstrSHA256->au8CurrentBlock[u16Offset ++] = 0x80; + + /* Calculate the required padding to complete + one Hash Block Size. + */ + u16PaddingLength = SHA_BLOCK_SIZE - u16Offset; + memset(&pstrSHA256->au8CurrentBlock[u16Offset], 0, u16PaddingLength); + + /* If the padding count is not enough to hold 64-bit representation of + the total input message length, one padding block is required. + */ + if(u16PaddingLength < 8) + { + winc_bus_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE); + u32Addr += SHA_BLOCK_SIZE; + memset(pstrSHA256->au8CurrentBlock, 0, SHA_BLOCK_SIZE); + u16NBlocks ++; + } + + /* pack the length at the end of the padding block */ + PUTU32(pstrSHA256->u32TotalLength << 3, pstrSHA256->au8CurrentBlock, (SHA_BLOCK_SIZE - 4)); + + u32ReadAddr = u32WriteAddr + (u16NBlocks * SHA_BLOCK_SIZE); + winc_bus_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE); + winc_bus_write_reg(SHA256_DATA_LENGTH, (u16NBlocks * SHA_BLOCK_SIZE)); + winc_bus_write_reg(SHA256_START_RD_ADDR, u32WriteAddr); + winc_bus_write_reg(SHA256_START_WR_ADDR, u32ReadAddr); + + u32RegVal |= SHA256_CTRL_START_CALC_MASK; + u32RegVal |= SHA256_CTRL_WR_BACK_HASH_VALUE_MASK; + u32RegVal &= ~(0x7UL << 8); + u32RegVal |= (0x2UL << 8); + + winc_bus_write_reg(SHA256_CTRL,u32RegVal); + + + /* 5. Wait for done_intr */ + while(!u8IsDone) + { + u32RegVal = winc_bus_read_reg(SHA256_DONE_INTR_STS); + u8IsDone = u32RegVal & NBIT0; + } + winc_bus_read_block(u32ReadAddr, (uint8_t*)au32Digest, 32); + + /* Convert the output words to an array of bytes. + */ + u32ByteIdx = 0; + for(u32Idx = 0; u32Idx < (M2M_SHA256_DIGEST_LEN / 4); u32Idx ++) + { + pu8Sha256Digest[u32ByteIdx ++] = BYTE_3(au32Digest[u32Idx]); + pu8Sha256Digest[u32ByteIdx ++] = BYTE_2(au32Digest[u32Idx]); + pu8Sha256Digest[u32ByteIdx ++] = BYTE_1(au32Digest[u32Idx]); + pu8Sha256Digest[u32ByteIdx ++] = BYTE_0(au32Digest[u32Idx]); + } + s8Ret = M2M_SUCCESS; + } + return s8Ret; +} + + +/*======*======*======*======*======*=======* +* RSA IMPLEMENTATION * +*======*======*======*======*======*========*/ + +static void FlipBuffer(uint8_t *pu8InBuffer, uint8_t *pu8OutBuffer, uint16_t u16BufferSize) +{ + uint16_t u16Idx; + for(u16Idx = 0; u16Idx < u16BufferSize; u16Idx ++) + { +#if ENABLE_FLIPPING == 1 + pu8OutBuffer[u16Idx] = pu8InBuffer[u16BufferSize - u16Idx - 1]; +#else + pu8OutBuffer[u16Idx] = pu8InBuffer[u16Idx]; +#endif + } +} + +void BigInt_ModExp +( + uint8_t *pu8X, uint16_t u16XSize, + uint8_t *pu8E, uint16_t u16ESize, + uint8_t *pu8M, uint16_t u16MSize, + uint8_t *pu8R, uint16_t u16RSize + ) +{ + uint32_t u32Reg; + uint8_t au8Tmp[780] = {0}; + uint32_t u32XAddr = SHARED_MEM_BASE; + uint32_t u32MAddr; + uint32_t u32EAddr; + uint32_t u32RAddr; + uint8_t u8EMswBits = 32; + uint32_t u32Mprime = 0x7F; + uint16_t u16XSizeWords,u16ESizeWords; + uint32_t u32Exponent; + + u16XSizeWords = (u16XSize + 3) / 4; + u16ESizeWords = (u16ESize + 3) / 4; + + u32MAddr = u32XAddr + (u16XSizeWords * 4); + u32EAddr = u32MAddr + (u16XSizeWords * 4); + u32RAddr = u32EAddr + (u16ESizeWords * 4); + + /* Reset the core. + */ + u32Reg = 0; + u32Reg |= BIGINT_MISC_CTRL_CTL_RESET; + u32Reg = winc_bus_read_reg(BIGINT_MISC_CTRL); + u32Reg &= ~BIGINT_MISC_CTRL_CTL_RESET; + u32Reg = winc_bus_read_reg(BIGINT_MISC_CTRL); + + winc_bus_write_block(u32RAddr,au8Tmp, u16RSize); + + /* Write Input Operands to Chip Memory. + */ + /*------- X -------*/ + FlipBuffer(pu8X,au8Tmp,u16XSize); + winc_bus_write_block(u32XAddr,au8Tmp,u16XSizeWords * 4); + + /*------- E -------*/ + memset(au8Tmp, 0, sizeof(au8Tmp)); + FlipBuffer(pu8E, au8Tmp, u16ESize); + winc_bus_write_block(u32EAddr, au8Tmp, u16ESizeWords * 4); + u32Exponent = GET_UINT32(au8Tmp, (u16ESizeWords * 4) - 4); + while((u32Exponent & NBIT31)== 0) + { + u32Exponent <<= 1; + u8EMswBits --; + } + + /*------- M -------*/ + memset(au8Tmp, 0, sizeof(au8Tmp)); + FlipBuffer(pu8M, au8Tmp, u16XSize); + winc_bus_write_block(u32MAddr, au8Tmp, u16XSizeWords * 4); + + /* Program the addresses of the input operands. + */ + winc_bus_write_reg(BIGINT_ADDR_X, u32XAddr); + winc_bus_write_reg(BIGINT_ADDR_E, u32EAddr); + winc_bus_write_reg(BIGINT_ADDR_M, u32MAddr); + winc_bus_write_reg(BIGINT_ADDR_R, u32RAddr); + + /* Mprime. + */ + winc_bus_write_reg(BIGINT_M_PRIME,u32Mprime); + + /* Length. + */ + u32Reg = (u16XSizeWords & 0xFF); + u32Reg += ((u16ESizeWords & 0xFF) << 8); + u32Reg += ((uint32_t)u8EMswBits << 16); + winc_bus_write_reg(BIGINT_LENGTH,u32Reg); + + /* CTRL Register. + */ + u32Reg = winc_bus_read_reg(BIGINT_MISC_CTRL); + u32Reg ^= BIGINT_MISC_CTRL_CTL_START; + u32Reg |= BIGINT_MISC_CTRL_CTL_FORCE_BARRETT; + //u32Reg |= BIGINT_MISC_CTRL_CTL_M_PRIME_VALID; +#if ENABLE_FLIPPING == 0 + u32Reg |= BIGINT_MISC_CTRL_CTL_MSW_FIRST; +#endif + winc_bus_write_reg(BIGINT_MISC_CTRL,u32Reg); + + /* Wait for computation to complete. */ + while(1) + { + u32Reg = winc_bus_read_reg(BIGINT_IRQ_STS); + if(u32Reg & BIGINT_IRQ_STS_DONE) + { + break; + } + } + winc_bus_write_reg(BIGINT_IRQ_STS,0); + memset(au8Tmp, 0, sizeof(au8Tmp)); + winc_bus_read_block(u32RAddr, au8Tmp, u16RSize); + FlipBuffer(au8Tmp, pu8R, u16RSize); +} + + + +#define MD5_DIGEST_SIZE (16) +#define SHA1_DIGEST_SIZE (20) + +static const uint8_t au8TEncodingMD5[] = +{ + 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, + 0x04 +}; +/*!< Fixed part of the Encoding T for the MD5 hash algorithm. +*/ + + +static const uint8_t au8TEncodingSHA1[] = +{ + 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, + 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04 +}; +/*!< Fixed part of the Encoding T for the SHA-1 hash algorithm. +*/ + + +static const uint8_t au8TEncodingSHA2[] = +{ + 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, + 0x00, 0x04 +}; +/*!< Fixed part of the Encoding T for the SHA-2 hash algorithm. +*/ + + +int8_t m2m_crypto_rsa_sign_verify(uint8_t *pu8N, uint16_t u16NSize, uint8_t *pu8E, uint16_t u16ESize, uint8_t *pu8SignedMsgHash, + uint16_t u16HashLength, uint8_t *pu8RsaSignature) +{ + int8_t s8Ret = M2M_RSA_SIGN_FAIL; + + if((pu8N != NULL) && (pu8E != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL)) + { + uint16_t u16TLength, u16TEncodingLength; + uint8_t *pu8T; + uint8_t au8EM[512]; + + /* Selection of correct T Encoding based on the hash size. + */ + if(u16HashLength == MD5_DIGEST_SIZE) + { + pu8T = (uint8_t*)au8TEncodingMD5; + u16TEncodingLength = sizeof(au8TEncodingMD5); + } + else if(u16HashLength == SHA1_DIGEST_SIZE) + { + pu8T = (uint8_t*)au8TEncodingSHA1; + u16TEncodingLength = sizeof(au8TEncodingSHA1); + } + else + { + pu8T = (uint8_t*)au8TEncodingSHA2; + u16TEncodingLength = sizeof(au8TEncodingSHA2); + } + u16TLength = u16TEncodingLength + 1 + u16HashLength; + + /* If emLen < tLen + 11. + */ + if(u16NSize >= (u16TLength + 11)) + { + uint32_t u32PSLength,u32Idx = 0; + + /* + RSA verification + */ + BigInt_ModExp(pu8RsaSignature, u16NSize, pu8E, u16ESize, pu8N, u16NSize, au8EM, u16NSize); + + u32PSLength = u16NSize - u16TLength - 3; + + /* + The calculated EM must match the following pattern. + *======*======*======*======*======* + * 0x00 || 0x01 || PS || 0x00 || T * + *======*======*======*======*======* + Where PS is all 0xFF + T is defined based on the hash algorithm. + */ + if((au8EM[0] == 0x00) && (au8EM[1] == 0x01)) + { + for(u32Idx = 2; au8EM[u32Idx] == 0xFF; u32Idx ++); + if(u32Idx == (u32PSLength + 2)) + { + if(au8EM[u32Idx ++] == 0x00) + { + if(!memcmp(&au8EM[u32Idx], pu8T, u16TEncodingLength)) + { + u32Idx += u16TEncodingLength; + if(au8EM[u32Idx ++] == u16HashLength) + s8Ret = memcmp(&au8EM[u32Idx], pu8SignedMsgHash, u16HashLength); + } + } + } + } + } + } + return s8Ret; +} + + +int8_t m2m_crypto_rsa_sign_gen(uint8_t *pu8N, uint16_t u16NSize, uint8_t *pu8d, uint16_t u16dSize, uint8_t *pu8SignedMsgHash, + uint16_t u16HashLength, uint8_t *pu8RsaSignature) +{ + int8_t s8Ret = M2M_RSA_SIGN_FAIL; + + if((pu8N != NULL) && (pu8d != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL)) + { + uint16_t u16TLength, u16TEncodingLength; + uint8_t *pu8T; + uint8_t au8EM[512]; + + /* Selection of correct T Encoding based on the hash size. + */ + if(u16HashLength == MD5_DIGEST_SIZE) + { + pu8T = (uint8_t*)au8TEncodingMD5; + u16TEncodingLength = sizeof(au8TEncodingMD5); + } + else if(u16HashLength == SHA1_DIGEST_SIZE) + { + pu8T = (uint8_t*)au8TEncodingSHA1; + u16TEncodingLength = sizeof(au8TEncodingSHA1); + } + else + { + pu8T = (uint8_t*)au8TEncodingSHA2; + u16TEncodingLength = sizeof(au8TEncodingSHA2); + } + u16TLength = u16TEncodingLength + 1 + u16HashLength; + + /* If emLen < tLen + 11. + */ + if(u16NSize >= (u16TLength + 11)) + { + uint16_t u16PSLength = 0; + uint16_t u16Offset = 0; + + /* + The calculated EM must match the following pattern. + *======*======*======*======*======* + * 0x00 || 0x01 || PS || 0x00 || T * + *======*======*======*======*======* + Where PS is all 0xFF + T is defined based on the hash algorithm. + */ + au8EM[u16Offset ++] = 0; + au8EM[u16Offset ++] = 1; + u16PSLength = u16NSize - u16TLength - 3; + memset(&au8EM[u16Offset], 0xFF, u16PSLength); + u16Offset += u16PSLength; + au8EM[u16Offset ++] = 0; + memcpy(&au8EM[u16Offset], pu8T, u16TEncodingLength); + u16Offset += u16TEncodingLength; + au8EM[u16Offset ++] = u16HashLength; + memcpy(&au8EM[u16Offset], pu8SignedMsgHash, u16HashLength); + + /* + RSA Signature Generation + */ + BigInt_ModExp(au8EM, u16NSize, pu8d, u16dSize, pu8N, u16NSize, pu8RsaSignature, u16NSize); + s8Ret = M2M_RSA_SIGN_OK; + } + } + return s8Ret; +} + +#endif /* CONF_CRYPTO */ + +#ifdef CONF_CRYPTO_SOFT + +typedef struct { + tpfAppCryproCb pfAppCryptoCb; + uint8_t * pu8Digest; + uint8_t * pu8Rsa; + uint8_t u8CryptoBusy; +}tstrCryptoCtxt; + +typedef struct { + uint8_t au8N[M2M_MAX_RSA_LEN]; + uint8_t au8E[M2M_MAX_RSA_LEN]; + uint8_t au8Hash[M2M_SHA256_DIGEST_LEN]; + uint16_t u16Nsz; + uint16_t u16Esz; + uint16_t u16Hsz; + uint8_t _pad16_[2]; +}tstrRsaPayload; + +static tstrCryptoCtxt gstrCryptoCtxt; + + +/** +* @fn m2m_crypto_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr) +* @brief WiFi call back function +* @param [in] u8OpCode +* HIF Opcode type. +* @param [in] u16DataSize +* HIF data length. +* @param [in] u32Addr +* HIF address. +* @author +* @date +* @version 1.0 +*/ +void m2m_crypto_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr) +{ + UNUSED_VAR(u16DataSize); + + gstrCryptoCtxt.u8CryptoBusy = 0; + if(u8OpCode == M2M_CRYPTO_RESP_SHA256_INIT) + { + tstrM2mSha256Ctxt strCtxt; + if (winc_hif_receive(u32Addr, &strCtxt, sizeof(tstrM2mSha256Ctxt)) == M2M_SUCCESS) + { + tstrCyptoResp strResp; + if(winc_hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt), &strResp, sizeof(tstrCyptoResp)) == M2M_SUCCESS) + { + if (gstrCryptoCtxt.pfAppCryptoCb) + gstrCryptoCtxt.pfAppCryptoCb(u8OpCode,&strResp,&strCtxt); + } + } + } + else if(u8OpCode == M2M_CRYPTO_RESP_SHA256_UPDATE) + { + tstrM2mSha256Ctxt strCtxt; + if (winc_hif_receive(u32Addr, &strCtxt, sizeof(tstrM2mSha256Ctxt)) == M2M_SUCCESS) + { + tstrCyptoResp strResp; + if (winc_hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt), &strResp, sizeof(tstrCyptoResp)) == M2M_SUCCESS) + { + if (gstrCryptoCtxt.pfAppCryptoCb) + gstrCryptoCtxt.pfAppCryptoCb(u8OpCode,&strResp,&strCtxt); + } + } + + } + else if(u8OpCode == M2M_CRYPTO_RESP_SHA256_FINISH) + { + tstrCyptoResp strResp; + if (winc_hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt), &strResp, sizeof(tstrCyptoResp)) == M2M_SUCCESS) + { + if (winc_hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt) + sizeof(tstrCyptoResp), gstrCryptoCtxt.pu8Digest, M2M_SHA256_DIGEST_LEN) == M2M_SUCCESS) + { + if (gstrCryptoCtxt.pfAppCryptoCb) + gstrCryptoCtxt.pfAppCryptoCb(u8OpCode,&strResp,gstrCryptoCtxt.pu8Digest); + + } + } + } + else if(u8OpCode == M2M_CRYPTO_RESP_RSA_SIGN_GEN) + { + tstrCyptoResp strResp; + if (winc_hif_receive(u32Addr + sizeof(tstrRsaPayload), &strResp, sizeof(tstrCyptoResp)) == M2M_SUCCESS) + { + if (winc_hif_receive(u32Addr + sizeof(tstrRsaPayload) + sizeof(tstrCyptoResp), gstrCryptoCtxt.pu8Rsa, M2M_MAX_RSA_LEN) == M2M_SUCCESS) + { + if (gstrCryptoCtxt.pfAppCryptoCb) + gstrCryptoCtxt.pfAppCryptoCb(u8OpCode,&strResp,gstrCryptoCtxt.pu8Rsa); + } + } + } + else if(u8OpCode == M2M_CRYPTO_RESP_RSA_SIGN_VERIFY) + { + tstrCyptoResp strResp; + if (winc_hif_receive(u32Addr + sizeof(tstrRsaPayload), &strResp, sizeof(tstrCyptoResp)) == M2M_SUCCESS) + { + if (gstrCryptoCtxt.pfAppCryptoCb) + gstrCryptoCtxt.pfAppCryptoCb(u8OpCode,&strResp,NULL); + } + } + else + { + WINC_LOG_ERROR("u8Code %d ??",u8OpCode); + } + +} +/*! +@fn \ + int8_t m2m_crypto_init(); + +@brief crypto initialization + +@param[in] pfAppCryproCb + +*/ +int8_t m2m_crypto_init(tpfAppCryproCb pfAppCryproCb) +{ + memset(&gstrCryptoCtxt, 0, sizeof(tstrCryptoCtxt)); + + if(pfAppCryproCb != NULL) + { + gstrCryptoCtxt.pfAppCryptoCb = pfAppCryproCb; + } + + return M2M_SUCCESS; +} +/*! +@fn \ + int8_t m2m_sha256_hash_init(tstrM2mSha256Ctxt *psha256Ctxt); + +@brief SHA256 hash initialization + +@param[in] psha256Ctxt + Pointer to a sha256 context allocated by the caller. +*/ +int8_t m2m_crypto_sha256_hash_init(tstrM2mSha256Ctxt *psha256Ctxt) +{ + int8_t ret = M2M_ERR_FAIL; + if((psha256Ctxt != NULL)&&(!gstrCryptoCtxt.u8CryptoBusy)) + { + ret = winc_hif_send_no_data(M2M_REQ_GROUP_CRYPTO, M2M_CRYPTO_REQ_SHA256_INIT|M2M_REQ_DATA_PKT, psha256Ctxt, sizeof(tstrM2mSha256Ctxt)); + } + return ret; +} + + +/*! +@fn \ + int8_t m2m_sha256_hash_update(tstrM2mSha256Ctxt *psha256Ctxt, uint8_t *pu8Data, uint16_t u16DataLength); + +@brief SHA256 hash update + +@param [in] psha256Ctxt + Pointer to the sha256 context. + +@param [in] pu8Data + Buffer holding the data submitted to the hash. + +@param [in] u16DataLength + Size of the data buffer in bytes. +*/ +int8_t m2m_crypto_sha256_hash_update(tstrM2mSha256Ctxt *psha256Ctxt, uint8_t *pu8Data, uint16_t u16DataLength) +{ + int8_t ret = M2M_ERR_FAIL; + if((!gstrCryptoCtxt.u8CryptoBusy) && (psha256Ctxt != NULL) && (pu8Data != NULL) && (u16DataLength < M2M_SHA256_MAX_DATA)) + { + ret = winc_hif_send(M2M_REQ_GROUP_CRYPTO, M2M_CRYPTO_REQ_SHA256_UPDATE|M2M_REQ_DATA_PKT, psha256Ctxt, sizeof(tstrM2mSha256Ctxt), pu8Data, u16DataLength, sizeof(tstrM2mSha256Ctxt) + sizeof(tstrCyptoResp)); + } + return ret; + +} + + +/*! +@fn \ + int8_t m2m_sha256_hash_finish(tstrM2mSha256Ctxt *psha256Ctxt, uint8_t *pu8Sha256Digest); + +@brief SHA256 hash finalization + +@param[in] psha256Ctxt + Pointer to a sha256 context allocated by the caller. + +@param [in] pu8Sha256Digest + Buffer allocated by the caller which will hold the resultant SHA256 Digest. It must be allocated no less than M2M_SHA256_DIGEST_LEN. +*/ +int8_t m2m_crypto_sha256_hash_finish(tstrM2mSha256Ctxt *psha256Ctxt, uint8_t *pu8Sha256Digest) +{ + int8_t ret = M2M_ERR_FAIL; + if((!gstrCryptoCtxt.u8CryptoBusy) && (psha256Ctxt != NULL) && (pu8Sha256Digest != NULL)) + { + gstrCryptoCtxt.pu8Digest = pu8Sha256Digest; + ret = winc_hif_send_no_data(M2M_REQ_GROUP_CRYPTO, M2M_CRYPTO_REQ_SHA256_FINISH|M2M_REQ_DATA_PKT, psha256Ctxt, sizeof(tstrM2mSha256Ctxt)); + } + return ret; +} + + + + +/*! +@fn \ + int8_t m2m_rsa_sign_verify(uint8_t *pu8N, uint16_t u16NSize, uint8_t *pu8E, uint16_t u16ESize, uint8_t *pu8SignedMsgHash, \ + uint16_t u16HashLength, uint8_t *pu8RsaSignature); + +@brief RSA Signature Verification + + The function shall request the RSA Signature verification from the WINC Firmware for the given message. The signed message shall be + compressed to the corresponding hash algorithm before calling this function. + The hash type is identified by the given hash length. For example, if the hash length is 32 bytes, then it is SHA256. + +@param[in] pu8N + RSA Key modulus n. + +@param[in] u16NSize + Size of the RSA modulus n in bytes. + +@param[in] pu8E + RSA public exponent. + +@param[in] u16ESize + Size of the RSA public exponent in bytes. + +@param[in] pu8SignedMsgHash + The hash digest of the signed message. + +@param[in] u16HashLength + The length of the hash digest. + +@param[out] pu8RsaSignature + Signature value to be verified. +*/ + + +int8_t m2m_crypto_rsa_sign_verify(uint8_t *pu8N, uint16_t u16NSize, uint8_t *pu8E, uint16_t u16ESize, uint8_t *pu8SignedMsgHash, + uint16_t u16HashLength, uint8_t *pu8RsaSignature) +{ + int8_t ret = M2M_ERR_FAIL; + if((!gstrCryptoCtxt.u8CryptoBusy) && (pu8N != NULL) && (pu8E != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL) + && (u16NSize != 0) && (u16ESize != 0) && (u16HashLength != 0) && (pu8RsaSignature != NULL) ) + + { + tstrRsaPayload strRsa = {0}; + + memcpy(strRsa.au8N,pu8N,u16NSize); + memcpy(strRsa.au8E,pu8E,u16ESize); + memcpy(strRsa.au8Hash,pu8SignedMsgHash,u16HashLength); + + strRsa.u16Esz = u16ESize; + strRsa.u16Hsz = u16HashLength; + strRsa.u16Nsz = u16NSize; + + ret = winc_hif_send_no_data(M2M_REQ_GROUP_CRYPTO, M2M_CRYPTO_REQ_RSA_SIGN_VERIFY|M2M_REQ_DATA_PKT, &strRsa, sizeof(tstrRsaPayload)); + + } + return ret; +} + + +/*! +@fn \ + int8_t m2m_rsa_sign_gen(uint8_t *pu8N, uint16_t u16NSize, uint8_t *pu8d, uint16_t u16dSize, uint8_t *pu8SignedMsgHash, \ + uint16_t u16HashLength, uint8_t *pu8RsaSignature); + +@brief RSA Signature Generation + + The function shall request the RSA Signature generation from the WINC Firmware for the given message. The signed message shall be + compressed to the corresponding hash algorithm before calling this function. + The hash type is identified by the given hash length. For example, if the hash length is 32 bytes, then it is SHA256. + +@param[in] pu8N + RSA Key modulus n. + +@param[in] u16NSize + Size of the RSA modulus n in bytes. + +@param[in] pu8d + RSA private exponent. + +@param[in] u16dSize + Size of the RSA private exponent in bytes. + +@param[in] pu8SignedMsgHash + The hash digest of the signed message. + +@param[in] u16HashLength + The length of the hash digest. + +@param[out] pu8RsaSignature + Pointer to a user buffer allocated by the caller shall hold the generated signature. +*/ +int8_t m2m_crypto_rsa_sign_gen(uint8_t *pu8N, uint16_t u16NSize, uint8_t *pu8d, uint16_t u16dSize, uint8_t *pu8SignedMsgHash, + uint16_t u16HashLength, uint8_t *pu8RsaSignature) +{ + int8_t ret = M2M_ERR_FAIL; + if((!gstrCryptoCtxt.u8CryptoBusy) && (pu8N != NULL) && (pu8d != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL) + && (u16NSize != 0) && (u16dSize != 0) && (u16HashLength != 0) && (pu8RsaSignature != NULL)) + + { + tstrRsaPayload strRsa = {0}; + + memcpy(strRsa.au8N,pu8N,u16NSize); + memcpy(strRsa.au8E,pu8d,u16dSize); + memcpy(strRsa.au8Hash,pu8SignedMsgHash,u16HashLength); + + strRsa.u16Esz = u16dSize; + strRsa.u16Hsz = u16HashLength; + strRsa.u16Nsz = u16NSize; + + gstrCryptoCtxt.pu8Rsa = pu8RsaSignature; + ret = winc_hif_send_no_data(M2M_REQ_GROUP_CRYPTO, M2M_CRYPTO_REQ_RSA_SIGN_GEN|M2M_REQ_DATA_PKT, &strRsa, sizeof(tstrRsaPayload)); + + } + return ret; +} + +#endif \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_crypto.h b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_crypto.h new file mode 100644 index 0000000..ae0281e --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_crypto.h @@ -0,0 +1,272 @@ +/** + * + * \file + * + * \brief WINC Crypto Application Interface. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef __M2M_CRYPTO_H__ +#define __M2M_CRYPTO_H__ + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +MACROS +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ +#define M2M_MAX_RSA_LEN (256) +#define M2M_SHA256_DIGEST_LEN 32 +#define M2M_SHA256_MAX_DATA (M2M_BUFFER_MAX_SIZE - M2M_SHA256_CONTEXT_BUFF_LEN - M2M_HIF_HDR_OFFSET) +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +DATA TYPES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +/*! +@struct \ + tstrM2mSha256Ctxt + +@brief + SHA256 context data +*/ +typedef struct sha256ctxt{ + uint32_t au32Sha256CtxtBuff[M2M_SHA256_CONTEXT_BUFF_LEN/sizeof(uint32_t)]; +} tstrM2mSha256Ctxt; + + +/*! +@enum \ + tenuRsaSignStatus + +@brief + RSA Signature status: pass or fail. + +@see + m2m_crypto_rsa_sign_gen +*/ +typedef enum { + M2M_RSA_SIGN_OK, + M2M_RSA_SIGN_FAIL +} tenuRsaSignStatus; + +/*! +@typedef \ + tpfAppCryproCb + +@brief Crypto Callback function receiving the crypto related messages +@param [in] u8MsgType + Crypto command about which the notification is received. +@param [in] pvResp + A pointer to the result associated with the notification. +@param [in] pvMsg + A pointer to a buffer containing the notification parameters (if any). It should be + Casted to the correct data type corresponding to the notification type. +@see + m2m_crypto_init + tenuM2mCryptoCmd +*/ +typedef void (*tpfAppCryproCb) (uint8_t u8MsgType,void * pvResp, void * pvMsg); +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +FUNCTION PROTOTYPES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* @fn m2m_crypto_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr) +* @brief WiFi call back function +* @param [in] u8OpCode +* HIF Opcode type. +* @param [in] u16DataSize +* HIF data length. +* @param [in] u32Addr +* HIF address. +* @author +* @date +* @version 1.0 +*/ +void m2m_crypto_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr); + +/*! +@fn \ + int8_t m2m_crypto_init(); + +@brief crypto initialization. + +@param[in] pfAppCryproCb + Pointer to the Crypto Callback function receiving the crypto related messages. +@see + tpfAppCryproCb + +@return + The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise. +*/ +int8_t m2m_crypto_init(tpfAppCryproCb pfAppCryproCb); +/*! +@fn \ + int8_t m2m_sha256_hash_init(tstrM2mSha256Ctxt *psha256Ctxt); + +@brief SHA256 hash initialization + +@param[in] psha256Ctxt + Pointer to a sha256 context allocated by the caller. +@return + The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise. +*/ +int8_t m2m_crypto_sha256_hash_init(tstrM2mSha256Ctxt *psha256Ctxt); + + +/*! +@fn \ + int8_t m2m_sha256_hash_update(tstrM2mSha256Ctxt *psha256Ctxt, uint8_t *pu8Data, uint16_t u16DataLength); + +@brief SHA256 hash update + +@param [in] psha256Ctxt + Pointer to the sha256 context. + +@param [in] pu8Data + Buffer holding the data submitted to the hash. + +@param [in] u16DataLength + Size of the data buffer in bytes. +@pre SHA256 module should be initialized first through m2m_crypto_sha256_hash_init function. + +@see m2m_crypto_sha256_hash_init + +@return + The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise. + +*/ +int8_t m2m_crypto_sha256_hash_update(tstrM2mSha256Ctxt *psha256Ctxt, uint8_t *pu8Data, uint16_t u16DataLength); + + +/*! +@fn \ + int8_t m2m_sha256_hash_finish(tstrM2mSha256Ctxt *psha256Ctxt, uint8_t *pu8Sha256Digest); + +@brief SHA256 hash finalization + +@param[in] psha256Ctxt + Pointer to a sha256 context allocated by the caller. + +@param [in] pu8Sha256Digest + Buffer allocated by the caller which will hold the resultant SHA256 Digest. It must be allocated no less than M2M_SHA256_DIGEST_LEN. + +@return + The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise. +*/ +int8_t m2m_crypto_sha256_hash_finish(tstrM2mSha256Ctxt *psha256Ctxt, uint8_t *pu8Sha256Digest); + + +/*! +@fn \ + int8_t m2m_rsa_sign_verify(uint8_t *pu8N, uint16_t u16NSize, uint8_t *pu8E, uint16_t u16ESize, uint8_t *pu8SignedMsgHash, \ + uint16_t u16HashLength, uint8_t *pu8RsaSignature); + +@brief RSA Signature Verification + + The function shall request the RSA Signature verification from the WINC Firmware for the given message. The signed message shall be + compressed to the corresponding hash algorithm before calling this function. + The hash type is identified by the given hash length. For example, if the hash length is 32 bytes, then it is SHA256. + +@param[in] pu8N + RSA Key modulus n. + +@param[in] u16NSize + Size of the RSA modulus n in bytes. + +@param[in] pu8E + RSA public exponent. + +@param[in] u16ESize + Size of the RSA public exponent in bytes. + +@param[in] pu8SignedMsgHash + The hash digest of the signed message. + +@param[in] u16HashLength + The length of the hash digest. + +@param[out] pu8RsaSignature + Signature value to be verified. + +@return + The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise. +*/ +int8_t m2m_crypto_rsa_sign_verify(uint8_t *pu8N, uint16_t u16NSize, uint8_t *pu8E, uint16_t u16ESize, uint8_t *pu8SignedMsgHash, + uint16_t u16HashLength, uint8_t *pu8RsaSignature); + + +/*! +@fn \ + int8_t m2m_rsa_sign_gen(uint8_t *pu8N, uint16_t u16NSize, uint8_t *pu8d, uint16_t u16dSize, uint8_t *pu8SignedMsgHash, \ + uint16_t u16HashLength, uint8_t *pu8RsaSignature); + +@brief RSA Signature Generation + + The function shall request the RSA Signature generation from the WINC Firmware for the given message. The signed message shall be + compressed to the corresponding hash algorithm before calling this function. + The hash type is identified by the given hash length. For example, if the hash length is 32 bytes, then it is SHA256. + +@param[in] pu8N + RSA Key modulus n. + +@param[in] u16NSize + Size of the RSA modulus n in bytes. + +@param[in] pu8d + RSA private exponent. + +@param[in] u16dSize + Size of the RSA private exponent in bytes. + +@param[in] pu8SignedMsgHash + The hash digest of the signed message. + +@param[in] u16HashLength + The length of the hash digest. + +@param[out] pu8RsaSignature + Pointer to a user buffer allocated by the caller shall hold the generated signature. + +@return + The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise. +*/ +int8_t m2m_crypto_rsa_sign_gen(uint8_t *pu8N, uint16_t u16NSize, uint8_t *pu8d, uint16_t u16dSize, uint8_t *pu8SignedMsgHash, + uint16_t u16HashLength, uint8_t *pu8RsaSignature); +#ifdef __cplusplus +} +#endif + + +#endif /* __M2M_CRYPTO_H__ */ diff --git a/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_fwinfo.c b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_fwinfo.c new file mode 100644 index 0000000..6b3a767 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_fwinfo.c @@ -0,0 +1,133 @@ +/** + * + * \file + * + * \brief This module contains WINC firmware information APIs implementation. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#include "../driver/winc_adapter.h" +#include "../common/winc_defines.h" +#include "../common/winc_debug.h" +#include "../common/winc_registers.h" +#include "m2m_types.h" +#include "m2m_fwinfo.h" +#include "../driver/winc_asic.h" +#include "../driver/winc_spi.h" +#include "../spi_flash/spi_flash.h" + +static uint32_t winc_firmware_version_read_addr(void) +{ + uint32_t u32Reg; + tstrGpRegs strgp; + + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(NMI_GP_REG_2, &u32Reg)) + { + return 0; + } + + if (!u32Reg) + { + return 0; + } + + if (WINC_BUS_SUCCESS != winc_bus_read_block(u32Reg|0x30000, (uint8_t*)&strgp, sizeof(tstrGpRegs))) + { + return 0; + } + + return strgp.u32Firmware_Ota_rev; +} + +int_fast8_t m2m_fwinfo_version_check(tstrM2mRev* pstrRev) +{ + uint16_t curr_drv_ver, min_req_drv_ver, curr_firm_ver; + + if (NULL == pstrRev) + { + return M2M_ERR_INVALID_ARG; + } + + curr_firm_ver = M2M_MAKE_VERSION(pstrRev->u8FirmwareMajor, pstrRev->u8FirmwareMinor,pstrRev->u8FirmwarePatch); + curr_drv_ver = M2M_MAKE_VERSION(M2M_RELEASE_VERSION_MAJOR_NO, M2M_RELEASE_VERSION_MINOR_NO, M2M_RELEASE_VERSION_PATCH_NO); + min_req_drv_ver = M2M_MAKE_VERSION(pstrRev->u8DriverMajor, pstrRev->u8DriverMinor,pstrRev->u8DriverPatch); + + if ((curr_firm_ver == 0) || (min_req_drv_ver == 0)) + { + return M2M_ERR_INVALID_ARG; + } + + if(curr_drv_ver < min_req_drv_ver) + { + /*The current driver version should be larger or equal + than the min driver that the current firmware support */ + return M2M_ERR_FW_VER_MISMATCH; + } + + if(curr_drv_ver > curr_firm_ver) + { + /*The current driver should be equal or less than the firmware version*/ + return M2M_ERR_FW_VER_MISMATCH; + } + + return M2M_SUCCESS; +} + +int_fast8_t m2m_fwinfo_get_firmware_info(bool bMainImage, tstrM2mRev* pstrRev) +{ + uint32_t u32Reg; + + if (NULL == pstrRev) + { + return M2M_ERR_INVALID_ARG; + } + + memset(pstrRev, 0, sizeof(tstrM2mRev)); + + u32Reg = winc_firmware_version_read_addr() & 0xffff; + + if (!u32Reg) + { + return M2M_ERR_FAIL; + } + + if (bMainImage) + u32Reg &= 0xffff; + else u32Reg >>= 16; + + if (WINC_BUS_SUCCESS != winc_bus_read_block(u32Reg|0x30000, (uint8_t*)pstrRev, sizeof(tstrM2mRev))) + { + return M2M_ERR_FAIL; + } + + return M2M_SUCCESS; +} diff --git a/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_fwinfo.h b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_fwinfo.h new file mode 100644 index 0000000..de03bba --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_fwinfo.h @@ -0,0 +1,53 @@ +/** + * + * \file + * + * \brief This module contains WINC firmware information APIs declarations. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + + #ifndef _M2M_FWINFO_H_ + #define _M2M_FWINFO_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +int_fast8_t m2m_fwinfo_version_check(tstrM2mRev* pstrRev); + +int_fast8_t m2m_fwinfo_get_firmware_info(bool bMainImage, tstrM2mRev* pstrRev); + +#ifdef __cplusplus + } +#endif + +#endif /* _WINCVER_H_ */ diff --git a/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_ota.c b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_ota.c new file mode 100644 index 0000000..d0970c4 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_ota.c @@ -0,0 +1,555 @@ +/** + * + * \file + * + * \brief WINC IoT OTA Interface. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +INCLUDES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +#include "../driver/winc_adapter.h" +#include "../common/winc_defines.h" +#include "../common/winc_debug.h" +#include "m2m_types.h" +#include "m2m_wifi.h" +#include "m2m_ota.h" +#include "m2m_fwinfo.h" +#include "../driver/winc_hif.h" +#include "../spi_flash/spi_flash.h" +#include "../spi_flash/spi_flash_map.h" +#include "../spi_flash/flexible_flash.h" + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +MACROS +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +DATA TYPES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ +static tpfOtaUpdateCb gpfOtaUpdateCb = NULL; +static tpfOtaNotifCb gpfOtaNotifCb = NULL; +static tpfFileGetCb gpfHFDGetCb = NULL; +static tpfFileReadCb gpfHFDReadCb = NULL; +static tpfFileEraseCb gpfHFDEraseCb = NULL; + +typedef struct { + uint32_t u32Offset; + uint32_t u32Size; +} FileBlockDescriptor; + +static FileBlockDescriptor FileBlock; + +static uint8_t gu8CurrFileHandlerID = HFD_INVALID_HANDLER; + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +FUNCTION PROTOTYPES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +/** +* @fn m2m_ota_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr) +* @brief OTA call back function +* @param [in] u8OpCode +* HIF Opcode type. +* @param [in] u16DataSize +* HIF data length. +* @param [in] u32Addr +* HIF address. +*/ +void m2m_ota_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr) +{ + UNUSED_VAR(u16DataSize); + + int8_t s8Ret = M2M_SUCCESS; + if(u8OpCode == M2M_OTA_RESP_NOTIF_UPDATE_INFO) + { + tstrOtaUpdateInfo strOtaUpdateInfo; + memset(&strOtaUpdateInfo,0,sizeof(tstrOtaUpdateInfo)); + s8Ret = winc_hif_receive(u32Addr, &strOtaUpdateInfo, sizeof(tstrOtaUpdateInfo)); + if(s8Ret == M2M_SUCCESS) + { + if(gpfOtaNotifCb) + gpfOtaNotifCb(&strOtaUpdateInfo); + } + } + else if (u8OpCode == M2M_OTA_RESP_UPDATE_STATUS) + { + tstrOtaUpdateStatusResp strOtaUpdateStatusResp; + memset(&strOtaUpdateStatusResp,0,sizeof(tstrOtaUpdateStatusResp)); + s8Ret = winc_hif_receive(u32Addr, &strOtaUpdateStatusResp, sizeof(tstrOtaUpdateStatusResp)); + if(s8Ret == M2M_SUCCESS) + { + if(gpfOtaUpdateCb) + gpfOtaUpdateCb(strOtaUpdateStatusResp.u8OtaUpdateStatusType,strOtaUpdateStatusResp.u8OtaUpdateStatus); + } + } + else if (u8OpCode == M2M_OTA_RESP_HOST_FILE_STATUS) + { + tstrOtaHostFileGetStatusResp strOtaHostFileGetStatusResp = {0}; + s8Ret = winc_hif_receive(u32Addr, &strOtaHostFileGetStatusResp, sizeof(tstrOtaHostFileGetStatusResp)); + if(M2M_SUCCESS == s8Ret) + { + if(strOtaHostFileGetStatusResp.u8OtaFileGetStatus == OTA_STATUS_SUCCESS) { + gu8CurrFileHandlerID = strOtaHostFileGetStatusResp.u8CFHandler; + } + } + } + else if (u8OpCode == M2M_OTA_RESP_HOST_FILE_DOWNLOAD) + { + tstrOtaHostFileGetStatusResp strOtaHostFileGetStatusResp = {0}; + s8Ret = winc_hif_receive(u32Addr, &strOtaHostFileGetStatusResp, sizeof(tstrOtaHostFileGetStatusResp)); + if(M2M_SUCCESS == s8Ret) + { + if(strOtaHostFileGetStatusResp.u8OtaFileGetStatus == OTA_STATUS_SUCCESS) { + gu8CurrFileHandlerID = strOtaHostFileGetStatusResp.u8CFHandler; + WINC_LOG_INFO("Generated HostFileHandlerID is %u", gu8CurrFileHandlerID); + } + + if(gpfHFDGetCb) { + gpfHFDGetCb(strOtaHostFileGetStatusResp.u8OtaFileGetStatus, gu8CurrFileHandlerID, strOtaHostFileGetStatusResp.u32OtaFileSize); + gpfHFDGetCb = NULL; + } + } + } + else if (u8OpCode == M2M_OTA_RESP_HOST_FILE_READ) + { + tstrOtaHostFileReadStatusResp strOtaHostFileReadStatusResp; + memset(&strOtaHostFileReadStatusResp, 0, sizeof(tstrOtaHostFileReadStatusResp)); + s8Ret = winc_hif_receive(u32Addr, &strOtaHostFileReadStatusResp, sizeof(tstrOtaHostFileReadStatusResp)); + if(M2M_SUCCESS == s8Ret) + if(gpfHFDReadCb) + gpfHFDReadCb(strOtaHostFileReadStatusResp.u8OtaFileReadStatus, strOtaHostFileReadStatusResp.pFileBuf, strOtaHostFileReadStatusResp.u16FileBlockSz); + } + else if (u8OpCode == M2M_OTA_RESP_HOST_FILE_ERASE) + { + tstrOtaHostFileEraseStatusResp strOtaHostFileEraseStatusResp = {0}; + s8Ret = winc_hif_receive(u32Addr, &strOtaHostFileEraseStatusResp, sizeof(tstrOtaHostFileEraseStatusResp)); + if(M2M_SUCCESS == s8Ret) + { + if(gpfHFDEraseCb) + { + gpfHFDEraseCb(strOtaHostFileEraseStatusResp.u8OtaFileEraseStatus); + gpfHFDEraseCb = NULL; + } + } + } + else + { + WINC_LOG_ERROR("Invalid OTA resp %u",u8OpCode); + } +} +/*! +@fn \ + int8_t m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb); + +@brief + Initialize the OTA layer. + +@param [in] pfOtaUpdateCb + OTA Update callback function + +@param [in] pfOtaNotifCb + OTA Notify callback function + +@return + The function SHALL return 0 for success and a negative value otherwise. +*/ +int8_t m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb) +{ + gpfOtaUpdateCb = pfOtaUpdateCb; + gpfOtaNotifCb = pfOtaNotifCb; + + return winc_hif_send_no_data(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_HOST_FILE_STATUS, NULL, 0); +} +/*! +@fn \ + int8_t m2m_ota_notif_set_url(uint8_t * u8Url); + +@brief + Set the OTA url + +@param [in] u8Url + The url server address + +@return + The function SHALL return 0 for success and a negative value otherwise. +*/ +int8_t m2m_ota_notif_set_url(uint8_t * u8Url) +{ + int8_t ret = M2M_SUCCESS; + uint16_t u16UrlSize = (uint16_t)strlen((const char*)u8Url) + 1; + /*Todo: we may change it to data pkt but we need to give it higher priority + but the priority is not implemented yet in data pkt + */ + ret = winc_hif_send_no_data(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_NOTIF_SET_URL, u8Url, u16UrlSize); + return ret; + +} + +/*! +@fn \ + int8_t m2m_ota_notif_check_for_update(void); + +@brief + check for OTA update + +@return + The function SHALL return 0 for success and a negative value otherwise. +*/ +int8_t m2m_ota_notif_check_for_update(void) +{ + int8_t ret = M2M_SUCCESS; + ret = winc_hif_send_no_data(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_NOTIF_CHECK_FOR_UPDATE, NULL, 0); + return ret; +} + +/*! +@fn \ + int8_t m2m_ota_notif_sched(uint32_t u32Period); + +@brief + Schedule OTA update + +@param [in] u32Period + Period in days + +@return + The function SHALL return 0 for success and a negative value otherwise. +*/ +int8_t m2m_ota_notif_sched(uint32_t u32Period) +{ + UNUSED_VAR(u32Period); + + int8_t ret = M2M_SUCCESS; + ret = winc_hif_send_no_data(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_NOTIF_CHECK_FOR_UPDATE, NULL, 0); + return ret; +} + +/*! +@fn \ + int8_t m2m_ota_start_update(unsigned char * pcDownloadUrl); + +@brief + Request OTA start update using the downloaded url + +@param [in] pcDownloadUrl + The download firmware url, you get it from device info + +@return + The function SHALL return 0 for success and a negative value otherwise. + +*/ +int8_t m2m_ota_start_update(unsigned char * pcDownloadUrl) +{ + int8_t ret = M2M_SUCCESS; + uint16_t u16DurlSize = (uint16_t)strlen((const char*)pcDownloadUrl) + 1; + /*Todo: we may change it to data pkt but we need to give it higher priority + but the priority is not implemented yet in data pkt + */ + ret = winc_hif_send_no_data(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_START_FW_UPDATE, pcDownloadUrl, u16DurlSize); + return ret; +} + +/*! +@fn \ + int8_t m2m_ota_rollback(void); + +@brief + Request OTA Rollback image + +@return + The function SHALL return 0 for success and a negative value otherwise. +*/ +int8_t m2m_ota_rollback(void) +{ + int8_t ret = M2M_SUCCESS; + ret = winc_hif_send_no_data(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_ROLLBACK_FW, NULL, 0); + return ret; +} + +/*! +@fn \ + int8_t m2m_ota_abort(void); + +@brief + Request OTA Abort + +@return + The function SHALL return 0 for success and a negative value otherwise. +*/ +int8_t m2m_ota_abort(void) +{ + int8_t ret = M2M_SUCCESS; + ret = winc_hif_send_no_data(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_ABORT, NULL, 0); + return ret; +} + + +/*! +@fn \ + int8_t m2m_ota_switch_firmware(void); + +@brief + Switch to the upgraded Firmware + +@return + The function SHALL return 0 for success and a negative value otherwise. +*/ +int8_t m2m_ota_switch_firmware(void) +{ + int8_t ret = M2M_SUCCESS; + ret = winc_hif_send_no_data(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_SWITCH_FIRMWARE, NULL, 0); + return ret; +} + +/*! +@fn \ + int8_t m2m_ota_get_firmware_version(tstrM2mRev * pstrRev); + +@brief + Get the OTA Firmware version. + +@return + The function SHALL return 0 for success and a negative value otherwise. +*/ +int8_t m2m_ota_get_firmware_version(tstrM2mRev * pstrRev) +{ + int8_t ret; + + ret = winc_hif_chip_wake(); + if(ret != M2M_SUCCESS) + return ret; + + ret = m2m_fwinfo_get_firmware_info(false, pstrRev); + winc_hif_chip_sleep(); + + if(ret != M2M_SUCCESS) + return ret; + + return m2m_fwinfo_version_check(pstrRev); +} +/*! +@fn \ + m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb); + +@brief + Download a file from a remote location and store it in the WINC's Flash. + +@param[in] pcDownloadUrl + Url pointing to the remote file. HTTP/HTTPS only. + +@param[in] pfHFDGetCb + Pointer to a callback to be executed when the download finishes. + +@return + Status of the get operation + +@warning 1. Providing a callback is mandatory. + 2. This functionality is only supported from WINC release 19.6.0 onwards. +*/ +int8_t m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb) +{ + int8_t s8Ret = M2M_ERR_FAIL; + uint16_t u16DUrlSize = (uint16_t)strlen((const char*)pcDownloadUrl); + + if((NULL == pfHFDGetCb) || (0 == u16DUrlSize)) + { + WINC_LOG_ERROR("Invalid parameters."); + goto EXIT; + } + + if('\0' != pcDownloadUrl[u16DUrlSize]) + pcDownloadUrl[u16DUrlSize] = '\0'; + else + u16DUrlSize++; + + WINC_LOG_INFO("GetHostFile - URL: %s, urlSize: %u", pcDownloadUrl, u16DUrlSize); + + s8Ret = winc_hif_send_no_data(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_HOST_FILE_DOWNLOAD, pcDownloadUrl, u16DUrlSize); + if(s8Ret == M2M_SUCCESS) + { + gpfHFDGetCb = pfHFDGetCb; + gu8CurrFileHandlerID = HFD_INVALID_HANDLER; + } + +EXIT: + return s8Ret; +} + +/*! +@fn \ + m2m_ota_host_file_read_hif(uint8_t u8Handler, uint32_t u32Offset, uint32_t u32Size, tpfFileReadCb pfHFDReadCb); +@brief + Read a certain amount of bytes from a file in WINC's Flash using HIF transfer. + +@param[in] u8Handler + ID of the file we are trying to read from. Must be valid. + +@param[in] u32Offset + Offset from start of the file to read from (in bytes). + +@param[in] u32Size + The amount of data to read (in bytes). + +@param[in] pfHFDReadCb + Callback to be executed when the read operation completes. + +@return + Status of the read operation + +@warning 1. Providing a callback is mandatory. + 2. This functionality is only supported from WINC release 19.6.0 onwards. +*/ +int8_t m2m_ota_host_file_read_hif(uint8_t u8Handler, uint32_t u32Offset, uint32_t u32Size, tpfFileReadCb pfHFDReadCb) +{ + int8_t s8Ret = M2M_ERR_INVALID_ARG; + FileBlock.u32Offset = u32Offset; + FileBlock.u32Size = u32Size; + + if((u8Handler != gu8CurrFileHandlerID) || (HFD_INVALID_HANDLER == gu8CurrFileHandlerID) || (NULL == pfHFDReadCb)) goto EXIT; + s8Ret = winc_hif_send_no_data(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_HOST_FILE_READ, &FileBlock, sizeof(FileBlockDescriptor)); + + if(M2M_SUCCESS == s8Ret) + gpfHFDReadCb = pfHFDReadCb; +EXIT: + return s8Ret; +} + +/*! +@fn \ + m2m_ota_host_file_read_spi(uint8_t u8Handler, uint8_t *pu8Buff, uint32_t u32Offset, uint32_t u32Size); +@brief + Read a certain amount of bytes from a file in WINC's Flash using SPI transfer. + +@param[in] u8Handler + ID of the file we are trying to read from. Must be valid. + +@param[in] pu8Buff + Pointer to a buffer to store the data being read. Must be valid. + +@param[in] u32Offset + Offset from start of the file to read from (in bytes). + +@param[in] u32Size + The amount of data to read (in Bytes). + +@return + Status of the read operation + +@warning 1. Before using m2m_ota_host_file_read_spi, the WINC needs to be put in a special + mode to allow for a safe access to the Flash. This can be done by calling + @ref m2m_wifi_download_mode or @ref m2m_wifi_reinit_hold before trying to read. + + 2. This functionality is only supported from WINC release 19.6.0 onwards. +*/ +int8_t m2m_ota_host_file_read_spi(uint8_t u8Handler, uint8_t *pu8Buff, uint32_t u32Offset, uint32_t u32Size) +{ + static uint32_t u32FlashHFDStart = 0; + static uint32_t u32FlashHFDSize = 0; + int8_t s8Ret = M2M_ERR_INVALID_ARG; + if((u8Handler == HFD_INVALID_HANDLER) || (NULL == pu8Buff)) goto EXIT; + + if(WIFI_STATE_INIT != m2m_wifi_get_state()) + { + s8Ret = M2M_ERR_FAIL; + WINC_LOG_ERROR("WINC is not in an appropriate state for this operation!"); + goto EXIT; + } + + if((u32FlashHFDStart == 0) || (u32FlashHFDSize == 0)) + { + s8Ret = spi_flexible_flash_find_section(ENTRY_ID_HOSTFILE, &u32FlashHFDStart, &u32FlashHFDSize); + if(M2M_SUCCESS != s8Ret) goto EXIT; + } + + s8Ret = spi_flash_read(pu8Buff, u32FlashHFDStart, 4); + + if((M2M_SUCCESS != s8Ret) || (pu8Buff[0] != u8Handler)) goto EXIT; + + if((u32Offset >= u32FlashHFDSize) || + (u32Size > u32FlashHFDSize) || + ((u32Offset + u32Size) >= u32FlashHFDSize)) + { + s8Ret = M2M_ERR_FAIL; + goto EXIT; + } + + s8Ret = spi_flash_read(pu8Buff, u32FlashHFDStart + FLASH_SECTOR_SZ + u32Offset, u32Size); + + if(M2M_SUCCESS != s8Ret) + { + WINC_LOG_ERROR("Unable to read SPI Flash"); + } + +EXIT: + return s8Ret; +} + +/*! +@fn \ + m2m_ota_host_file_erase(uint8_t u8Handler, tpfFileEraseCb pfHFDEraseCb); +@brief + Erase any traces of an existing file, this means from host driver and WINC firmware. + +@param[in] u8Handler + ID of the file we are trying to erase. Must be valid. + +@param[in] pfHFDEraseCb + Pointer to callback to execute when the file erase in the WINC completes. + +@return + Status of the erase operation + +@note Providing a callback is optional. + If the current handler is invalid at this point, it means one of the three: + 1. The file never existed; + 2. The file has already been already deleted; + 3. The request to get the file hasn't fully completed. + For 1. and 2. there is no need to signal the WINC to erase the file in Flash. + For 3. the Flash can't be erased while a file download is ongoing. + +@warning This functionality is only supported from WINC release 19.6.0 onwards. +*/ +int8_t m2m_ota_host_file_erase(uint8_t u8Handler, tpfFileEraseCb pfHFDEraseCb) +{ + int8_t s8Ret = M2M_ERR_INVALID_ARG; + if((u8Handler != gu8CurrFileHandlerID) || (HFD_INVALID_HANDLER == gu8CurrFileHandlerID)) goto EXIT; + + gu8CurrFileHandlerID = HFD_INVALID_HANDLER; + gpfHFDReadCb = NULL; + gpfHFDEraseCb = pfHFDEraseCb; + + s8Ret = winc_hif_send_no_data(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_HOST_FILE_ERASE, NULL, 0); +EXIT: + return s8Ret; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_ota.h b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_ota.h new file mode 100644 index 0000000..449bc7f --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_ota.h @@ -0,0 +1,797 @@ +/** + * + * \file + * + * \brief WINC OTA Upgrade API Interface. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +/**@defgroup OTAAPI OTA + @brief + The WINC supports OTA (Over-The-Air) updates. Using the APIs described in this module, + it is possible to request an ATWINC15x0 to update its firmware, or safely rollback to + the previous firmware version.\n There are also APIs to download files and store them in + the WINC's Flash (supported by ATWINC1510 only), which can be used for Host MCU OTA + updates or accessing information stored remotely. + @{ + @defgroup OTACALLBACKS Callbacks + @brief + Lists the different callbacks that can be used during OTA updates.\n + Callbacks of type @ref tpfOtaNotifCb and @ref tpfOtaUpdateCb should be passed + onto @ref m2m_ota_init at system initialization. Other callbacks are provided + to handle the various steps of Host File Download. + + @defgroup OTADEFINE Defines + @brief + Specifies the macros and defines used by the OTA APIs. + + @defgroup OTATYPEDEF Enumerations and Typedefs + @brief + Specifies the enums and Data Structures used by the OTA APIs. + + @defgroup OTAFUNCTIONS Functions + @brief + Lists the full set of available APIs to manage OTA updates and Host File Downloads. + @{ + @defgroup OTACOMMON Common + @defgroup WINCOTA WINC + @defgroup HFD HFD + @} + @} +*/ + +#ifndef __M2M_OTA_H__ +#define __M2M_OTA_H__ + + +/**@addtogroup OTACALLBACKS + * @{ + */ +/*! +@typedef void (*tpfOtaNotifCb) (tstrOtaUpdateInfo *pstrOtaUpdateInfo); + +@brief + A callback to get notification about a potential OTA update. + +@param[in] pstrOtaUpdateInfo + A structure to provide notification payload. + +@sa + tstrOtaUpdateInfo + +@warning + The notification is not supported (Not implemented yet) +*/ +typedef void (*tpfOtaNotifCb)(tstrOtaUpdateInfo *pstrOtaUpdateInfo); + +/*! +@typedef void (*tpfOtaUpdateCb)(uint8_t u8OtaUpdateStatusType, uint8_t u8OtaUpdateStatus); + +@brief + A callback to get OTA status update, the callback provides the status type and its status.\n + The OTA callback provides the download status, the switch to the downloaded firmware status, + roll-back status and Host File Download status. + +@param[in] u8OtaUpdateStatusType + Possible values are listed in @ref tenuOtaUpdateStatusType. + +@param[in] u8OtaUpdateStatus + Possible values are listed as enumerated by @ref tenuOtaUpdateStatus. + +@note + Executes other callbacks passed to the OTA module. + +@see + tenuOtaUpdateStatusType + tenuOtaUpdateStatus + */ +typedef void (*tpfOtaUpdateCb)(uint8_t u8OtaUpdateStatusType, uint8_t u8OtaUpdateStatus); + +/*! +@typedef void (*tpfFileGetCb) (uint8_t u8Status, uint8_t u8Handler, uint32_t u32Size); + +@brief + A callback to notify the application of the result of the download (success/fail), + the generated handler ID and the size of the file which has just finished + downloading (size expressed in bytes). + +@param[in] u8Status + Status of the operation (see @ref tenuOtaUpdateStatus). + +@param[in] u8Handler + Generated handler ID for the new file. + +@param[in] u32Size + Total size of the downloaded file (in bytes). + +@warning + The file handler passed onto this callback will be the valid file handler generated + by the WINC when the download finished successfully. This handler will be required + for all operations on the file like read and erase. + */ +typedef void (*tpfFileGetCb)(uint8_t u8Status, uint8_t u8Handler, uint32_t u32Size); + +/*! +@typedef void (*tpfFileReadCb) (uint8_t u8Status, void *pBuff, uint32_t u32Size); + +@brief + A callback to handle a buffer of data after requesting a Host File read. + The callback will provide the status of the read operation and if successful, + a pointer to a valid placeholder containing the data read and the amount of + data available. Such callback is required when using Host File read via the HIF. + +@param[in] u8Status + Status of the operation (see @ref tenuOtaUpdateStatus). + +@param[in] pBuff + Pointer to a placeholder where the data can be retrieved from. + +@param[in] u32Size + Amount of data available after reading (in bytes). + +@warning + After the callback is executed, pBuff will be freed. + */ +typedef void (*tpfFileReadCb)(uint8_t u8Status, void *pBuff, uint32_t u32Size); + +/*! +@typedef void (*tpfFileEraseCb) (uint8_t u8Status); + +@brief + A callback executed when the file erase has been completed. + +@param[in] u8Status + Status of the operation (see @ref tenuOtaUpdateStatus). + */ +typedef void (*tpfFileEraseCb)(uint8_t u8Status); +/**@}*/ //OTACALLBACKS + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +FUNCTION PROTOTYPES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* @fn m2m_ota_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr) +* @brief OTA call back function +* @param [in] u8OpCode +* HIF Opcode type. +* @param [in] u16DataSize +* HIF data length. +* @param [in] u32Addr +* HIF address. +*/ +void m2m_ota_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr); + +/*! +@ingroup OTACOMMON +@fn \ + int8_t m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb); + +@brief + Synchronous initialization function for the OTA layer by registering the update callback.\n + The notification callback is not supported at the current version. Calling this API is a + MUST for all the OTA API's. + +@param[in] pfOtaUpdateCb + OTA Update callback function. + +@param[in] pfOtaNotifCb + OTA Notify callback function. + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +*/ +int8_t m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb); + +/*! +@ingroup WINCOTA +@fn \ + int8_t m2m_ota_notif_set_url(uint8_t *u8Url); + +@brief + Set the OTA notification server URL, the function needs to be called before any check for update.\n + This functionality is not supported by WINC firmware. + +@param[in] u8Url + Set the OTA notification server URL, the function needs to be called before any check for update. + +@pre + Prior calling of @ref m2m_ota_init is required. + +@warning + Notification Server is not supported in the current version (function is not implemented). + +@see + m2m_ota_init + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +*/ +int8_t m2m_ota_notif_set_url(uint8_t *u8Url); + +/*! +@ingroup WINCOTA +@fn \ + int8_t m2m_ota_notif_check_for_update(void); + +@brief + Synchronous function to check for the OTA update using the Notification Server URL.\n + Function is not implemented (not supported at the current version). + +@warning + Function is not implemented (not supported at the current version). + +@sa + m2m_ota_init + m2m_ota_notif_set_url + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +*/ +int8_t m2m_ota_notif_check_for_update(void); + +/*! +@ingroup WINCOTA +@fn \ + int8_t m2m_ota_notif_sched(uint32_t u32Period); + +@brief + Schedule OTA notification Server check for update request after specific number of days.\n + Function is not implemented (not supported at the current version). + +@param[in] u32Period + Period in days + +@warning + Function is not implemented (not supported at the current version). + +@sa + m2m_ota_init + m2m_ota_notif_check_for_update + m2m_ota_notif_set_url + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +*/ +int8_t m2m_ota_notif_sched(uint32_t u32Period); + +/*! +@ingroup WINCOTA +@fn \ + int8_t m2m_ota_start_update(unsigned char *pcDownloadUrl); + +@brief + Request OTA start update using the download URL. The OTA module will download the OTA image, ensure integrity of the image + and update the validity of the image in the control structure. On completion, a callback of type @ref tpfOtaUpdateCb is called + (callback previously provided via @ref m2m_ota_init). Switching to the updated image additionally requires completion of + @ref m2m_ota_switch_firmware, followed by a WINC reset. + +@param[in] pcDownloadUrl + The download firmware URL, according to the application server. + +@warning + Calling this API does not guarantee OTA WINC image update, it depends on the connection with the + download server and the validity of the image.\n + Calling this API invalidates any previous valid rollback image, irrespective of the result, but when + the OTA succeeds, the current image will become the rollback image after @ref m2m_ota_switch_firmware. + +@pre + @ref m2m_ota_init is a prerequisite and must have been called before using @ref m2m_ota_start_update.\n + Switching to the newly downloaded image requires calling @ref m2m_ota_switch_firmware API. + +@sa + @ref m2m_ota_init + @ref m2m_ota_switch_firmware + @ref tpfOtaUpdateCb + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. + Note that successful operation in this context means the OTA update request has reached the firmware OTA module. + It does not indicate whether or not the image update succeeded. + +@section OTAExample Example + This example shows how an OTA image update and switch is carried out. + It demonstrates use of the following OTA APIs: + - @ref m2m_ota_init + - @ref tpfOtaUpdateCb + - @ref m2m_ota_start_update + - @ref m2m_ota_switch_firmware + - @ref m2m_ota_rollback + +@code +static void OtaUpdateCb(uint8_t u8OtaUpdateStatusType, uint8_t u8OtaUpdateStatus) +{ + WINC_LOG_INFO("%d %d", u8OtaUpdateStatusType, u8OtaUpdateStatus); + switch(u8OtaUpdateStatusType) + { + case DL_STATUS: + if(u8OtaUpdateStatus == OTA_STATUS_SUCCESS) + { + WINC_LOG_INFO("OTA download succeeded"); + + // In this case the application MAY WANT TO update the host driver before calling + // @ref m2m_ota_switch_firmware(). Switching firmware image and resetting without + // updating host driver may lead to suboptimal functionality. + + // Switch to the upgraded firmware + WINC_LOG_INFO("Now switching active partition..."); + m2m_ota_switch_firmware(); + } + break; + case SW_STATUS: + case RB_STATUS: + if(u8OtaUpdateStatus == OTA_STATUS_SUCCESS) + { + WINC_LOG_INFO("Switch/Rollback succeeded"); + + // Start the host SW upgrade if required, then system reset is required (Reinitialize the driver) + + WINC_LOG_INFO("Now resetting the system..."); + } + break; + } +} + +static void wifi_event_cb(uint8_t u8WiFiEvent, const void *const pvMsg) +{ + // ... + case M2M_WIFI_REQ_DHCP_CONF: + { + // After successful connection, start the OTA upgrade + m2m_ota_start_update(OTA_URL); + } + break; + default: + break; + // ... +} + +int main(void) +{ + tstrWifiInitParam param; + int8_t s8Ret = M2M_SUCCESS; + bool rollback_required = false; + tstr1xAuthCredentials gstrCred1x = AUTH_CREDENTIALS; + + // System init, etc should be here... + + memset(¶m, 0, sizeof(param)); + param.pfAppWifiCb = wifi_event_cb; + + // Initialize the WINC Driver + s8Ret = m2m_wifi_init(¶m); + if(s8Ret == M2M_ERR_FW_VER_MISMATCH) + { + WINC_LOG_ERROR("Firmware version mismatch"); + } + if (M2M_SUCCESS != s8Ret) + { + WINC_LOG_ERROR("Driver Init Failed <%d>", s8Ret); + while(1); + } + // Initialize the OTA module + m2m_ota_init(OtaUpdateCb, NULL); + + // Connect to AP that provides connection to the OTA server + m2m_wifi_default_connect(); + + while(1) + { + // Handle the app state machine plus the WINC event handler + while(m2m_wifi_handle_events(NULL) != M2M_SUCCESS) { + } + } +} +@endcode +*/ +int8_t m2m_ota_start_update(unsigned char *pcDownloadUrl); + +/*! +@ingroup WINCOTA +@fn \ + int8_t m2m_ota_rollback(void); + +@brief + Request OTA Roll-back to the old (inactive) WINC image, the WINC firmware will check the validity of the inactive image + and activate it if valid. On completion, a callback of type @ref tpfOtaUpdateCb is called (application must previously have + provided the callback via @ref m2m_ota_init). If the callback indicates successful activation, the newly-activated image + will start running after next system reset. + +@warning + If rollback requires a host driver update in order to maintain HIF compatibility (HIF + major value change), then it is recommended to update the host driver prior to calling this API.\n + In the event of system reset with incompatible driver/firmware, compatibility can be + recovered by calling @ref m2m_ota_rollback or @ref m2m_ota_switch_firmware. See @ref OTAExample. + +@sa + m2m_ota_init + m2m_ota_start_update + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +*/ +int8_t m2m_ota_rollback(void); + +/*! +@ingroup OTACOMMON +@fn \ + int8_t m2m_ota_abort(void); + +@brief + Request the WINC to abort an OTA or Host File download in progress.\n + If no download is in progress, the API will respond with failure. + +@sa + m2m_ota_init + m2m_ota_start_update + +@return + The function returns @ref M2M_SUCCESS for a successful operation and a negative value otherwise. +*/ +int8_t m2m_ota_abort(void); + +/*! +@ingroup WINCOTA +@fn \ + int8_t m2m_ota_switch_firmware(void); + +@brief + Request switch to the updated WINC image. The WINC firmware will check the validity of the + inactive image and activate it if valid. On completion, a callback of type @ref tpfOtaUpdateCb + is called (application must previously have provided the callback via @ref m2m_ota_init). + If the callback indicates successful activation, the newly-activated image will start running + after next system reset. + +@warning + If switch requires a host driver update in order to maintain HIF compatibility (HIF + major value change), then it is recommended to update the host driver prior to calling this API.\n + In the event of system reset with incompatible driver/firmware, compatibility can be + recovered by calling @ref m2m_ota_rollback or @ref m2m_ota_switch_firmware. See @ref OTAExample. + +@sa + m2m_ota_init + m2m_ota_start_update + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +*/ +int8_t m2m_ota_switch_firmware(void); + +/*! +@ingroup HFD +@fn \ + int8_t m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb); + +@brief + Download a file from a remote location and store it in WINC's Flash. + +@param[in] pcDownloadUrl + Url pointing to the remote file. HTTP/HTTPS only. + +@param[in] pfHFDGetCb + Pointer to a callback (see @ref tpfFileGetCb) to be executed when the download finishes. + +@return + The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise. + +@pre + Requires @ref m2m_ota_init to be called before a download can start. + +@warning + This functionality is only supported from WINC release 19.6.1 onwards. + The maximum file size that can be stored in WINC1510 is 508KB, the + WINC1500 variant is not supported for Host File Download.\n + Concurrent use of Host File Get and WINC OTA is not possible.\n + Providing a callback is mandatory. + +@sa + m2m_ota_init + tpfFileGetCb +*/ +int8_t m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb); + +/*! +@ingroup HFD +@fn \ + int8_t m2m_ota_host_file_read_hif(uint8_t u8Handler, uint32_t u32Offset, uint32_t u32Size, tpfFileReadCb pfHFDReadCb); + +@brief + Read a certain amount of bytes from a file previously stored in WINC's Flash using HIF transfer. + +@param[in] u8Handler + Handler of the file we are trying to read from. Must be valid. + +@param[in] u32Offset + Offset from start of the file to read from (in bytes). + +@param[in] u32Size + The amount of data to read (in bytes). + +@param[in] pfHFDReadCb + Callback (see @ref tpfFileReadCb) to be executed when the read operation completes. + +@return + The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise. + +@pre + Requires @ref m2m_ota_init to be called before a read via HIF can be requested. + +@warning + There is a limitation on how much data can be transferred at a time using HIF read, which is 128 bytes. + The limitation described above can potentially reduce the speed of the read due to extra overhead, but + using the HIF is non-blocking and therefore the Application can continue execution as normal, being + interrupted only when data is available. Another advantage is that it does not require the WINC to be + reset or put in download mode, as it is the case for reading the file via SPI (see @ref m2m_ota_host_file_read_spi).\n + A valid file handler must be provided, this means that it needs to match the handler internally stored + by the WINC and must not be @ref HFD_INVALID_HANDLER.\n + Providing a callback is mandatory. + +@note + When calling this API while specifying a size > 128 bytes, the read will be limited to the first 128 bytes + starting at the read offset. It it recommended that a read for sizes above 128 bytes is performed in + multiple steps, using the callback to advance the offset and request another read of 128 bytes (or less) each time. + +@sa + m2m_ota_init + m2m_ota_host_file_get + tpfFileReadCb +*/ +int8_t m2m_ota_host_file_read_hif(uint8_t u8Handler, uint32_t u32Offset, uint32_t u32Size, tpfFileReadCb pfHFDReadCb); + +/*! +@ingroup HFD +@fn \ + int8_t m2m_ota_host_file_read_spi(uint8_t u8Handler, uint8_t *pu8Buff, uint32_t u32Offset, uint32_t u32Size); + +@brief + Read a certain amount of bytes from a file in WINC's Flash using SPI transfer. + +@param[in] u8Handler + Handler of the file we are trying to read from. Must be valid. + +@param[in] pu8Buff + Pointer to a buffer to store the data being read. Must not be NULL. + +@param[in] u32Offset + Offset from start of the file to read from (in bytes). + +@param[in] u32Size + The amount of data to read (in Bytes). + +@return + The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise. + +@warning + Reading of a file via SPI can be much faster than by reading it via the HIF. However, the read will + be blocking and it will require the WINC to be put into download mode prior to the read, the download + mode means that the WINC will act as Flash device and not as a Wifi device. So, before using + m2m_ota_host_file_read_spi, the Application should call @ref m2m_wifi_download_mode before trying to + read. After the read finishes, the WINC needs to be reset.\n + A valid file handler must be provided, this means that it needs to match the handler internally stored + by the WINC and must not be @ref HFD_INVALID_HANDLER. + +@sa + m2m_ota_init + m2m_ota_host_file_get + +\section Host File Download SPI Read Example +The following is an example of how to perform a read file from the WINC via SPI. +@code +typedef struct { + uint8_t u8Handler; + uint32_t u32Offset; + uint32_t u32Size; + uint8_t au8Buff[200]; +}FileDescriptor; + +tstrWifiInitParam gstrWifiParam; +static FileDescriptor gstrAppFile; + +char *acURL = "http://www.microchip.com/_images/ics/medium-ATWINC1500-MODULE-28.png"; + +static void ReadFileSPI(void); +static void wifi_event_cb(uint8_t u8WiFiEvent, void * pvMsg); +static void FileGetCallback(uint8_t u8Status, uint8_t u8Handler, uint32_t u32Size); +static void OtaUpdateCb(uint8_t u8OtaUpdateStatusType ,uint8_t u8OtaUpdateStatus); + +static void wifi_event_cb(uint8_t u8WiFiEvent, void * pvMsg) +{ + case M2M_WIFI_REQ_DHCP_CONF: + { + // After successfully connection, start the File Download + gstrAppFile.u32Offset = 0; + s8Ret = m2m_ota_host_file_get(acURL, FileGetCallback); + if(s8Ret != M2M_SUCCESS) + { + WINC_LOG_ERROR("File Download Failed!"); + } + } + break; + default: + break; +} + +static void OtaUpdateCb(uint8_t u8OtaUpdateStatusType ,uint8_t u8OtaUpdateStatus) +{ + WINC_LOG_INFO("%d %d",u8OtaUpdateStatusType,u8OtaUpdateStatus); + + if(u8OtaUpdateStatus == OTA_STATUS_SUCCESS) + { + if(u8OtaUpdateStatusType == HFD_STATUS) + { + // Read the file and process it + ReadFileSPI(); + } + } +} + +static void FileGetCallback(uint8_t u8Status, uint8_t u8Handler, uint32_t u32Size) +{ + if(OTA_STATUS_SUCCESS == u8Status) + { + gstrAppFile.u8Handler = u8Handler; + gstrAppFile.u32Size = u32Size; + // File Get Successful + } + else + { + WINC_LOG_ERROR("File Get Failed!"); + // File Get Failed + } +} + +static void ReadFileSPI(void) +{ + int8_t s8Ret = M2M_ERR_FAIL; + + if(WIFI_STATE_DEINIT != m2m_wifi_get_state()) + m2m_wifi_deinit(NULL); + + s8Ret = m2m_wifi_download_mode(); + if(M2M_SUCCESS != s8Ret) goto EXIT; + + // gstrAppFile.u32Offset can be changed to define a starting point for the read, + // in which case the size of the requested read should be adjusted to accommodate for this. + // This call assumes that m2m_ota_host_file_get was called earlier, in this example it is fine + // since ReadFileSPI is only called from the within OtaUpdateCb + // This example simply reads the first 200 bytes of the file. + uint32_t u32AmountToRead = 200; + s8Ret = m2m_ota_host_file_read_spi(gstrAppFile.u8Handler, gstrAppFile.au8Buff, gstrAppFile.u32Offset, u32AmountToRead); + + if(M2M_SUCCESS == s8Ret) + WINC_LOG_INFO("\nFile Read completed, Offset: %lu, Size of Read: %lu.", gstrAppFile.u32Offset, u32AmountToRead); + + // *** Do something with the contents of gstrAppFile.au8Buff *** + + s8Ret = m2m_wifi_deinit(NULL); + if(M2M_SUCCESS != s8Ret) goto EXIT; + + s8Ret = m2m_wifi_init_hold(); + if(M2M_SUCCESS != s8Ret) goto EXIT; + + s8Ret = m2m_wifi_init_start(&gstrWifiParam); + if(M2M_SUCCESS != s8Ret) goto EXIT; + + // Initialize the OTA again and reconnect to the previously connected SSID + m2m_ota_init(OtaUpdateCb, NULL); + m2m_wifi_default_connect(); + +EXIT: + return; +} + +void main(void) +{ + winc_adapter_init(); + + memset(&gstrWifiParam, 0, sizeof(gstrWifiParam)); + gstrWifiParam.pfAppWifiCb = wifi_event_cb; + + // Initialize the WINC Driver + int8_t s8Ret = m2m_wifi_init(&gstrWifiParam); + if (M2M_SUCCESS != s8Ret) + { + WINC_LOG_ERROR("Driver Init Failed <%d>",s8Ret); + while(1); + } + + // Initialize the OTA module + m2m_ota_init(OtaUpdateCb, NULL); + + // *** Connect to a wifi network by calling m2m_wifi_connect() *** + + while(1) m2m_wifi_handle_events(NULL); +} +@endcode +*/ +int8_t m2m_ota_host_file_read_spi(uint8_t u8Handler, uint8_t *pu8Buff, uint32_t u32Offset, uint32_t u32Size); + +/*! +@ingroup HFD +@fn \ + int8_t m2m_ota_host_file_erase(uint8_t u8Handler, tpfFileEraseCb pfHFDEraseCb); + +@brief + Erase any traces of file stored in WINC's Flash. + +@param[in] u8Handler + Handler of the file we are trying to erase. Must be valid. + +@param[in] pfHFDEraseCb + Pointer to callback (see @ref tpfFileEraseCb) to execute when the file erase is completed by the WINC. + +@return + The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise. + +@pre + In order to execute the callback, @ref m2m_ota_init must be called before requesting the erase. + +@note + Providing a callback is optional. + If the current handler is invalid at this point, it means one of the three: + 1. The file never existed; + 2. The file has already been already deleted; + 3. The request to get the file hasn't fully completed. + \par + For 1. and 2. there is no need to signal the WINC to erase the file in Flash.\n + For 3. the Flash can't be erased while a file download is ongoing. + +@warning + A valid file handler must be provided, this means that it needs to match the handler internally stored + by the WINC and must not be @ref HFD_INVALID_HANDLER.\n + The handlers will be destroyed regardless of the call returning success or not. + +@sa + m2m_ota_init + m2m_ota_host_file_get +*/ +int8_t m2m_ota_host_file_erase(uint8_t u8Handler, tpfFileEraseCb pfHFDEraseCb); + +/*! +@ingroup VERSIONAPI +@fn int8_t m2m_ota_get_firmware_version(tstrM2mRev* pstrRev); +@brief Get the OTA Firmware version. +@details Get OTA Firmware version info from the inactive partition, as defined in the structure tstrM2mRev. +@param[out] pstrRev + Pointer to the structure tstrM2mRev that contains the firmware version parameters. +@return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +*/ +int8_t m2m_ota_get_firmware_version(tstrM2mRev *pstrRev); + +#ifdef __cplusplus +} +#endif +#endif /* __M2M_OTA_H__ */ diff --git a/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_periph.c b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_periph.c new file mode 100644 index 0000000..c5caeda --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_periph.c @@ -0,0 +1,123 @@ +/** + * + * \file + * + * \brief WINC Peripherals Application Interface. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +INCLUDES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +#include "../driver/winc_adapter.h" +#include "../common/winc_defines.h" +#include "m2m_periph.h" +#include "../driver/winc_hif.h" +#include "../driver/winc_asic.h" + +#ifdef CONF_PERIPH + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +MACROS +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ +#define GPIO_OP_DIR 0 +#define GPIO_OP_SET 1 +#define GPIO_OP_GET 2 +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +DATA TYPES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +STATIC FUNCTIONS +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ +/* + * GPIO read/write skeleton with wakeup/sleep capability. + */ +static int8_t gpio_ioctl(uint8_t op, uint8_t u8GpioNum, uint8_t u8InVal, uint8_t *pu8OutVal) +{ + int8_t i8Ret; + + i8Ret = winc_hif_chip_wake(); + if (i8Ret != M2M_SUCCESS) goto _EXIT; + + if (u8GpioNum >= M2M_PERIPH_GPIO_MAX) goto _EXIT1; + + if (op == GPIO_OP_DIR) + { + if (!winc_chip_set_gpio_dir((uint_fast8_t)u8GpioNum, u8InVal)) + i8Ret = M2M_ERR_FAIL; + } + else if (op == GPIO_OP_SET) + { + if (!winc_chip_set_gpio_val((uint_fast8_t)u8GpioNum, u8InVal)) + i8Ret = M2M_ERR_FAIL; + } + else if (op == GPIO_OP_GET) + { + if (!winc_chip_get_gpio_val((uint_fast8_t)u8GpioNum, pu8OutVal)) + i8Ret = M2M_ERR_FAIL; + } + +_EXIT1: + i8Ret = winc_hif_chip_sleep(); +_EXIT: + return i8Ret; +} +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +FUNCTION IMPLEMENTATION +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +int8_t m2m_periph_gpio_set_dir(uint8_t u8GpioNum, uint8_t u8GpioDir) +{ + return gpio_ioctl(GPIO_OP_DIR, u8GpioNum, u8GpioDir, NULL); +} + +int8_t m2m_periph_gpio_set_val(uint8_t u8GpioNum, uint8_t u8GpioVal) +{ + return gpio_ioctl(GPIO_OP_SET, u8GpioNum, u8GpioVal, NULL); +} + +int8_t m2m_periph_gpio_get_val(uint8_t u8GpioNum, uint8_t * pu8GpioVal) +{ + return gpio_ioctl(GPIO_OP_GET, u8GpioNum, 0, pu8GpioVal); +} + +int8_t m2m_periph_pullup_ctrl(uint32_t pinmask, uint8_t enable) +{ + if (!winc_chip_pullup_ctrl(pinmask, enable)) + return M2M_ERR_FAIL; + + return M2M_SUCCESS; +} + +#endif /* CONF_PERIPH */ diff --git a/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_periph.h b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_periph.h new file mode 100644 index 0000000..7ceea33 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_periph.h @@ -0,0 +1,195 @@ +/** + * + * \file + * + * \brief WINC Peripherals Application Interface. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef _M2M_PERIPH_H_ +#define _M2M_PERIPH_H_ + + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +MACROS +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +DATA TYPES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +/*! +@enum \ + tenuGpioNum + +@brief + A list of GPIO numbers configurable through the m2m_periph module. +*/ +typedef enum { + M2M_PERIPH_GPIO0 = 0, /*!< GPIO0 pad */ + M2M_PERIPH_GPIO1 = 1, /*!< GPIO1 pad */ + M2M_PERIPH_GPIO2 = 2, /*!< GPIO2 pad */ + M2M_PERIPH_GPIO3 = 3, /*!< GPIO3 pad */ + M2M_PERIPH_GPIO4 = 4, /*!< GPIO4 pad */ + M2M_PERIPH_GPIO5 = 5, /*!< GPIO5 pad */ + M2M_PERIPH_GPIO6 = 6, /*!< GPIO6 pad */ + M2M_PERIPH_GPIO_MAX +} tenuGpioNum; + +#define M2M_PERIPH_PULLUP_DIS_HOST_WAKEUP (1ul << 0) +#define M2M_PERIPH_PULLUP_DIS_RTC_CLK (1ul << 1) +#define M2M_PERIPH_PULLUP_DIS_IRQN (1ul << 2) +#define M2M_PERIPH_PULLUP_DIS_GPIO_3 (1ul << 3) +#define M2M_PERIPH_PULLUP_DIS_GPIO_4 (1ul << 4) +#define M2M_PERIPH_PULLUP_DIS_GPIO_5 (1ul << 5) +#define M2M_PERIPH_PULLUP_DIS_SD_DAT3 (1ul << 6) +#define M2M_PERIPH_PULLUP_DIS_SD_DAT2_SPI_RXD (1ul << 7) +#define M2M_PERIPH_PULLUP_DIS_SD_DAT1_SPI_SSN (1ul << 9) +#define M2M_PERIPH_PULLUP_DIS_SD_CMD_SPI_SCK (1ul << 10) +#define M2M_PERIPH_PULLUP_DIS_SD_DAT0_SPI_TXD (1ul << 11) +#define M2M_PERIPH_PULLUP_DIS_GPIO_6 (1ul << 12) +#define M2M_PERIPH_PULLUP_DIS_SD_CLK (1ul << 13) +#define M2M_PERIPH_PULLUP_DIS_I2C_SCL (1ul << 14) +#define M2M_PERIPH_PULLUP_DIS_I2C_SDA (1ul << 15) +#define M2M_PERIPH_PULLUP_DIS_GPIO_11 (1ul << 16) +#define M2M_PERIPH_PULLUP_DIS_GPIO_12 (1ul << 17) +#define M2M_PERIPH_PULLUP_DIS_GPIO_13 (1ul << 18) +#define M2M_PERIPH_PULLUP_DIS_GPIO_14 (1ul << 19) +#define M2M_PERIPH_PULLUP_DIS_GPIO_15 (1ul << 20) +#define M2M_PERIPH_PULLUP_DIS_GPIO_16 (1ul << 21) +#define M2M_PERIPH_PULLUP_DIS_GPIO_17 (1ul << 22) +#define M2M_PERIPH_PULLUP_DIS_GPIO_18 (1ul << 23) +#define M2M_PERIPH_PULLUP_DIS_GPIO_19 (1ul << 24) +#define M2M_PERIPH_PULLUP_DIS_GPIO_20 (1ul << 25) +#define M2M_PERIPH_PULLUP_DIS_GPIO_21 (1ul << 26) +#define M2M_PERIPH_PULLUP_DIS_GPIO_22 (1ul << 27) +#define M2M_PERIPH_PULLUP_DIS_GPIO_23 (1ul << 28) +#define M2M_PERIPH_PULLUP_DIS_GPIO_24 (1ul << 29) + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +FUNCTION PROTOTYPES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +/*! +@fn \ + int8_t m2m_periph_gpio_set_dir(uint8_t u8GpioNum, uint8_t u8GpioDir); + +@brief + Configure a specific WINC pad as a GPIO and sets its direction (input or output). + +@param[in] u8GpioNum + GPIO number. Allowed values are defined in @ref tenuGpioNum. + +@param[in] u8GpioDir + GPIO direction: Zero = input. Non-zero = output. + +@return + The function returns 0 for success and a negative value otherwise. + +@sa + tenuGpioNum +*/ +int8_t m2m_periph_gpio_set_dir(uint8_t u8GpioNum, uint8_t u8GpioDir); + +/*! +@fn \ + int8_t m2m_periph_gpio_set_val(uint8_t u8GpioNum, uint8_t u8GpioVal); + +@brief + Set an WINC GPIO output level high or low. + +@param[in] u8GpioNum + GPIO number. Allowed values are defined in @ref tenuGpioNum. + +@param[in] u8GpioVal + GPIO output value. Zero = low, non-zero = high. + +@return + The function returns 0 for success and a negative value otherwise. + +@sa + tenuGpioNum +*/ +int8_t m2m_periph_gpio_set_val(uint8_t u8GpioNum, uint8_t u8GpioVal); + +/*! +@fn \ + int8_t m2m_periph_gpio_get_val(uint8_t u8GpioNum, uint8_t * pu8GpioVal); + +@brief + Read an WINC GPIO input level. + +@param[in] u8GpioNum + GPIO number. Allowed values are defined in @ref tenuGpioNum. + +@param [out] pu8GpioVal + GPIO input value. Zero = low, non-zero = high. + +@return + The function returns 0 for success and a negative value otherwise. + +@sa + tenuGpioNum +*/ +int8_t m2m_periph_gpio_get_val(uint8_t u8GpioNum, uint8_t * pu8GpioVal); + +/*! +@fn \ + int8_t m2m_periph_pullup_ctrl(uint32_t pinmask, uint8_t enable); + +@brief + Control the programmable pull-up resistor on the chip pads . + +@param[in] pinmask + Write operation bitwise-ORed mask for which pads to control. Allowed values are defined in @ref tenuPullupMask. + +@param[in] enable + Set to 0 to disable pull-up resistor. Non-zero will enable the pull-up. + +@return + The function returns 0 for success and a negative value otherwise. + +@sa + tenuPullupMask +*/ +int8_t m2m_periph_pullup_ctrl(uint32_t pinmask, uint8_t enable); + +#ifdef __cplusplus +} +#endif + +#endif /* _M2M_PERIPH_H_ */ diff --git a/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_socket_host_if.h b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_socket_host_if.h new file mode 100644 index 0000000..a623841 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_socket_host_if.h @@ -0,0 +1,430 @@ +/** + * + * \file + * + * \brief Socket interface internal types. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef __M2M_SOCKET_HOST_IF_H__ +#define __M2M_SOCKET_HOST_IF_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +MACROS +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +#define SSL_MAX_OPT_LEN HOSTNAME_MAX_SIZE + + + +#define SOCKET_CMD_INVALID 0x00 +/*!< + Invalid Socket command value. +*/ + + +#define SOCKET_CMD_BIND 0x41 +/*!< + Socket Binding command value. +*/ + + +#define SOCKET_CMD_LISTEN 0x42 +/*!< + Socket Listening command value. +*/ + + +#define SOCKET_CMD_ACCEPT 0x43 +/*!< + Socket Accepting command value. +*/ + + +#define SOCKET_CMD_CONNECT 0x44 +/*!< + Socket Connecting command value. +*/ + + +#define SOCKET_CMD_SEND 0x45 +/*!< + Socket send command value. +*/ + + +#define SOCKET_CMD_RECV 0x46 +/*!< + Socket Receive command value. +*/ + + +#define SOCKET_CMD_SENDTO 0x47 +/*!< + Socket sendTo command value. +*/ + + +#define SOCKET_CMD_RECVFROM 0x48 +/*!< + Socket ReceiveFrom command value. +*/ + + +#define SOCKET_CMD_CLOSE 0x49 +/*!< + Socket Close command value. +*/ + + +#define SOCKET_CMD_DNS_RESOLVE 0x4A +/*!< + Socket DNS Resolve command value. +*/ + + +#define SOCKET_CMD_SSL_CONNECT 0x4B +/*!< + SSL-Socket Connect command value. +*/ + + +#define SOCKET_CMD_SSL_SEND 0x4C +/*!< + SSL-Socket Send command value. +*/ + + +#define SOCKET_CMD_SSL_RECV 0x4D +/*!< + SSL-Socket Receive command value. +*/ + + +#define SOCKET_CMD_SSL_CLOSE 0x4E +/*!< + SSL-Socket Close command value. +*/ + + +#define SOCKET_CMD_SET_SOCKET_OPTION 0x4F +/*!< + Set Socket Option command value. +*/ + + +#define SOCKET_CMD_SSL_CREATE 0x50 +/*!< +*/ + + +#define SOCKET_CMD_SSL_SET_SOCK_OPT 0x51 +/*!< +*/ + + +#define SOCKET_CMD_PING 0x52 +/*!< +*/ + + +#define SOCKET_CMD_SSL_SET_CS_LIST 0x53 +/*!< + Recommend instead using @ref M2M_SSL_REQ_SET_CS_LIST and + associated response @ref M2M_SSL_RESP_SET_CS_LIST +*/ + + +#define SOCKET_CMD_SSL_BIND 0x54 +/*!< +*/ + + +#define SOCKET_CMD_SSL_EXP_CHECK 0x55 +/*!< +*/ + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +DATA TYPES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + +/*! +* @brief +*/ +typedef struct{ + uint16_t u16Family; + uint16_t u16Port; + uint32_t u32IPAddr; +}tstrSockAddr; + +typedef tstrSockAddr tstrUIPSockAddr; + + +/*! +@struct \ + tstrDnsReply + +@brief + DNS Reply, contains hostName and HostIP. +*/ +typedef struct { + char acHostName[HOSTNAME_MAX_SIZE]; + uint32_t u32HostIP; +} tstrDnsReply; + + +/*! +@brief +*/ +typedef struct { + tstrSockAddr strAddr; + SOCKET sock; + uint8_t u8Void; + uint16_t u16SessionID; +} tstrBindCmd; + + +/*! +@brief +*/ +typedef struct { + SOCKET sock; + int8_t s8Status; + uint16_t u16SessionID; +} tstrBindReply; + + +/*! +* @brief +*/ +typedef struct { + SOCKET sock; + uint8_t u8BackLog; + uint16_t u16SessionID; +} tstrListenCmd; + + +/*! +@struct \ + tstrSocketRecvMsg + +@brief Socket recv status. + + It is passed to the APPSocketEventHandler with SOCKET_MSG_RECV or SOCKET_MSG_RECVFROM message type + in a response to a user call to the recv or recvfrom. + If the received data from the remote peer is larger than the USER Buffer size (given at recv call), the data is + delivered to the user in a number of consecutive chunks according to the USER Buffer size. +*/ +typedef struct { + SOCKET sock; + int8_t s8Status; + uint16_t u16SessionID; +} tstrListenReply; + + +/*! +* @brief +*/ +typedef struct { + tstrSockAddr strAddr; + SOCKET sListenSock; + SOCKET sConnectedSock; + uint16_t u16AppDataOffset; + /*!< + In further packet send requests the host interface should put the user application + data at this offset in the allocated shared data packet. + */ +} tstrAcceptReply; + + +/*! +* @brief +*/ +typedef struct { + tstrSockAddr strAddr; + SOCKET sock; + uint8_t u8SslFlags; + uint16_t u16SessionID; +} tstrConnectCmd; + + +/*! +@struct \ + tstrConnectReply + +@brief + Connect Reply, contains sock number and error value +*/ +typedef struct { + SOCKET sock; + int8_t s8Error; + uint16_t u16AppDataOffset; + /*!< + In further packet send requests the host interface should put the user application + data at this offset in the allocated shared data packet. + */ +} tstrConnectReply; + + +/*! +@brief +*/ +typedef struct { + SOCKET sock; + uint8_t u8Void; + uint16_t u16DataSize; + tstrSockAddr strAddr; + uint16_t u16SessionID; + uint16_t u16Void; +} tstrSendCmd; + + +/*! +@struct \ + tstrSendReply + +@brief + Send Reply, contains socket number and number of sent bytes. +*/ +typedef struct { + SOCKET sock; + uint8_t u8Void; + int16_t s16SentBytes; + uint16_t u16SessionID; + uint16_t u16Void; +} tstrSendReply; + + +/*! +* @brief +*/ +typedef struct { + uint32_t u32Timeoutmsec; + SOCKET sock; + uint8_t u8Void; + uint16_t u16SessionID; +} tstrRecvCmd; + + +/*! +@struct \ + tstrRecvReply +@brief +*/ +typedef struct { + tstrSockAddr strRemoteAddr; + int16_t s16RecvStatus; + uint16_t u16DataOffset; + SOCKET sock; + uint8_t u8Void; + uint16_t u16SessionID; +} tstrRecvReply; + + +/*! +* @brief +*/ +typedef struct { + uint32_t u32OptionValue; + SOCKET sock; + uint8_t u8Option; + uint16_t u16SessionID; +} tstrSetSocketOptCmd; + + +typedef struct { + SOCKET sslSock; + uint8_t __PAD24__[3]; +} tstrSSLSocketCreateCmd; + + +/*! +* @brief +*/ +typedef struct { + SOCKET sock; + uint8_t u8Option; + uint16_t u16SessionID; + uint32_t u32OptLen; + uint8_t au8OptVal[SSL_MAX_OPT_LEN]; +} tstrSSLSetSockOptCmd; + + +/*! +*/ +typedef struct { + uint32_t u32DestIPAddr; + uint32_t u32CmdPrivate; + uint16_t u16PingCount; + uint8_t u8TTL; + uint8_t __PAD8__; +} tstrPingCmd; + + +typedef struct { + uint32_t u32IPAddr; + uint32_t u32CmdPrivate; + uint32_t u32RTT; + uint16_t u16Success; + uint16_t u16Fail; + uint8_t u8ErrorCode; + uint8_t __PAD24__[3]; +} tstrPingReply; + + +/*! +@struct\ + tstrSslCertExpSettings + +@brief SSL Certificate Expiry Validation Settings + +@sa tenuSslCertExpSettings +*/ +typedef struct{ + uint32_t u32CertExpValidationOpt; + /*!< + See @tenuSslCertExpSettings for possible values. + */ +}tstrSslCertExpSettings; + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __M2M_SOCKET_HOST_IF_H__ */ diff --git a/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_ssl.c b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_ssl.c new file mode 100644 index 0000000..3c6d971 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_ssl.c @@ -0,0 +1,413 @@ +/** + * + * \file + * + * \brief WINC SSL Interface. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +INCLUDES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +#include "../driver/winc_adapter.h" +#include "../common/winc_defines.h" +#include "../common/ecc_types.h" +#include "../common/winc_debug.h" +#include "m2m_types.h" +#include "m2m_ssl.h" +#include "../driver/winc_hif.h" +#include "../driver/winc_asic.h" +#include "../socket/socket.h" + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +MACROS +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +DATA TYPES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ +static tpfAppSSLCb gpfAppSSLCb = NULL; +static uint32_t gu32HIFAddr = 0; +static tenuTlsFlashStatus genuStatus = TLS_FLASH_ERR_UNKNOWN; + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +FUNCTION PROTOTYPES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +/*! +@fn \ void m2m_ssl_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr) +@brief Internal SSL callback function. +@param [in] u8OpCode + HIF Opcode type. +@param [in] u16DataSize + HIF data length. +@param [in] u32Addr + HIF address. +*/ +void m2m_ssl_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr) +{ + UNUSED_VAR(u16DataSize); + + int8_t s8tmp = M2M_SUCCESS; + switch(u8OpCode) + { + case M2M_SSL_REQ_ECC: + { + tstrEccReqInfo strEccREQ; + s8tmp = winc_hif_receive(u32Addr, &strEccREQ, sizeof(tstrEccReqInfo)); + if(s8tmp == M2M_SUCCESS) + { + if (gpfAppSSLCb) + { + gu32HIFAddr = u32Addr + sizeof(tstrEccReqInfo); + gpfAppSSLCb(M2M_SSL_REQ_ECC, &strEccREQ); + } + } + } + break; + case M2M_SSL_RESP_SET_CS_LIST: + { + tstrSslSetActiveCsList strCsList; + s8tmp = winc_hif_receive(u32Addr, &strCsList, sizeof(tstrSslSetActiveCsList)); + if(s8tmp == M2M_SUCCESS) + { + if (gpfAppSSLCb) + gpfAppSSLCb(M2M_SSL_RESP_SET_CS_LIST, &strCsList); + } + } + break; + case M2M_SSL_RESP_WRITE_OWN_CERTS: + { + tstrTlsSrvChunkHdr strTlsSrvChunkRsp; + uint8_t bCallApp = 1; + + s8tmp = winc_hif_receive(u32Addr, &strTlsSrvChunkRsp, sizeof(tstrTlsSrvChunkHdr)); + if(s8tmp == M2M_SUCCESS) + { + uint16_t offset = strTlsSrvChunkRsp.u16Offset32; + uint16_t chunk_size = strTlsSrvChunkRsp.u16Size32; + uint16_t total_size = strTlsSrvChunkRsp.u16TotalSize32; + tenuTlsFlashStatus status = (tenuTlsFlashStatus)(strTlsSrvChunkRsp.u16Sig); + + /* If first chunk, reset status. */ + if (offset == 0) + genuStatus = TLS_FLASH_OK_NO_CHANGE; + /* Only send status to app when processing last chunk. */ + if (offset + chunk_size != total_size) + bCallApp = 0; + + switch (status) + { + case TLS_FLASH_OK: + // Good flash write. Update status if no errors yet. + if (genuStatus == TLS_FLASH_OK_NO_CHANGE) + genuStatus = status; + break; + case TLS_FLASH_OK_NO_CHANGE: + // No change, don't update status. + break; + case TLS_FLASH_ERR_CORRUPT: + // Corrupt. Always update status. + genuStatus = status; + break; + case TLS_FLASH_ERR_NO_CHANGE: + // Failed flash write. Update status if no more serious error. + if ((genuStatus != TLS_FLASH_ERR_CORRUPT) && (genuStatus != TLS_FLASH_ERR_UNKNOWN)) + genuStatus = status; + break; + default: + // Don't expect any other case. Ensure we don't mask a previous corrupt error. + if (genuStatus != TLS_FLASH_ERR_CORRUPT) + genuStatus = TLS_FLASH_ERR_UNKNOWN; + break; + } + } + if (bCallApp && gpfAppSSLCb) + gpfAppSSLCb(M2M_SSL_RESP_WRITE_OWN_CERTS, &genuStatus); + } + break; + } + if(s8tmp != M2M_SUCCESS) + { + WINC_LOG_ERROR("Error receiving SSL from the HIF"); + } +} + +/*! +@fn \ int8_t m2m_ssl_init(tpfAppSslCb pfAppSslCb); +@brief Initializes the SSL layer. +@param [in] pfAppSslCb + Application SSL callback function. +@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise. +*/ +int8_t m2m_ssl_init(tpfAppSSLCb pfAppSSLCb) +{ + gpfAppSSLCb = pfAppSSLCb; + gu32HIFAddr = 0; + genuStatus = TLS_FLASH_ERR_UNKNOWN; + + return M2M_SUCCESS; +} + +/*! +@fn \ int8_t m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8_t* pu8RspDataBuff, uint16_t u16RspDataSz) +@brief Sends ECC responses to the WINC. +@param[in] strECCResp + ECC Response struct. +@param[in] pu8RspDataBuff + Pointer of the response data to be sent. +@param[in] u16RspDataSz + Response data size. +@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise. +*/ +int8_t m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8_t* pu8RspDataBuff, uint16_t u16RspDataSz) +{ + int8_t s8Ret = M2M_SUCCESS; + + s8Ret = winc_hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_RESP_ECC | M2M_REQ_DATA_PKT), strECCResp, sizeof(tstrEccReqInfo), pu8RspDataBuff, u16RspDataSz, sizeof(tstrEccReqInfo)); + + return s8Ret; +} + +/*! +@fn \ int8_t m2m_ssl_send_certs_to_winc(uint8_t* sector_buffer, uint32_t sector_size) +@brief Sends certificates to the WINC +@param[in] pu8Buffer + Pointer to the certificates. +@param[in] u32BufferSz + Size of the certificates. +@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise. +*/ +#define TXLIMIT (256 * 6) +#define CHUNKHDRSZ (sizeof(tstrTlsSrvChunkHdr)) +#define CHUNKSZ (TXLIMIT - 256) // divisible by 4 + +int8_t m2m_ssl_send_certs_to_winc(uint8_t *pu8Buffer, uint32_t u32BufferSz) +{ + tstrTlsSrvChunkHdr strChkHdr; + + strChkHdr.u16Sig = TLS_CERTS_CHUNKED_SIG_VALUE; + strChkHdr.u16TotalSize32 = (uint16_t)((u32BufferSz + 3) >> 2); + strChkHdr.u16Offset32 = 0; + + if(u32BufferSz <= TXLIMIT) + { + // set chunk header for one chunk + + strChkHdr.u16Size32 = strChkHdr.u16TotalSize32; + + memcpy(pu8Buffer, &strChkHdr, CHUNKHDRSZ); + + if (M2M_SUCCESS != winc_hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_REQ_WRITE_OWN_CERTS | M2M_REQ_DATA_PKT), NULL, 0, pu8Buffer, (uint16_t)u32BufferSz, 0)) + return M2M_ERR_FAIL; + + WINC_LOG_INFO("Transferred %" PRIu32 " bytes of cert data NON-CHUNKED", u32BufferSz); + } + else + { + // chunk it + // We are sneaking in a header - tstrTlsSrvChunkHdr + uint8_t u8BackupBufData[CHUNKHDRSZ]; + uint16_t u16ThisChunkSz = CHUNKSZ; + uint32_t u32BufRemain; + + memcpy(u8BackupBufData, pu8Buffer, CHUNKHDRSZ); + + // CHUNKSZ is always less than TXLIMIT, so u32BufferSz is always greater than CHUNKSZ, therefore u16ThisChunkSz = CHUNKSZ + + strChkHdr.u16Size32 = (CHUNKSZ >> 2); + + memcpy(pu8Buffer, &strChkHdr, CHUNKHDRSZ); + + if (M2M_SUCCESS != winc_hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_REQ_WRITE_OWN_CERTS | M2M_REQ_DATA_PKT), NULL, 0, pu8Buffer, CHUNKSZ, 0)) + return M2M_ERR_FAIL; + + WINC_LOG_INFO("Transferred %" PRIu16 " bytes of cert data CHUNKED to offset 0 total %" PRIu32, CHUNKSZ, u32BufferSz); + memcpy(pu8Buffer, u8BackupBufData, CHUNKHDRSZ); + + pu8Buffer += (CHUNKSZ - CHUNKHDRSZ); + strChkHdr.u16Offset32 += (CHUNKSZ >> 2); + + u32BufRemain = u32BufferSz - CHUNKSZ; + + while (u32BufRemain) + { + // pu8Buffer points to next chunk data - CHUNKHDRSZ + + memcpy(u8BackupBufData, pu8Buffer, CHUNKHDRSZ); + + if (u32BufRemain < CHUNKSZ) + { + u16ThisChunkSz = (uint16_t)u32BufRemain; + u16ThisChunkSz = (u16ThisChunkSz + 3) & 0xFFFC; // needs to round up to quad word length + + strChkHdr.u16Size32 = (u16ThisChunkSz >> 2); + } + + memcpy(pu8Buffer, &strChkHdr, CHUNKHDRSZ); + + if (M2M_SUCCESS != winc_hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_REQ_WRITE_OWN_CERTS | M2M_REQ_DATA_PKT), NULL, 0, pu8Buffer, u16ThisChunkSz + CHUNKHDRSZ, 0)) + return M2M_ERR_FAIL; + + WINC_LOG_INFO("Transferred %" PRIu16 " bytes of cert data CHUNKED to offset %d total %" PRIu32, u16ThisChunkSz, (strChkHdr.u16Offset32 << 2), u32BufferSz); + memcpy(pu8Buffer, u8BackupBufData, CHUNKHDRSZ); + + pu8Buffer += CHUNKSZ; + strChkHdr.u16Offset32 += (CHUNKSZ >> 2); + + u32BufRemain -= u16ThisChunkSz; + } + } + + return M2M_SUCCESS; +} + +/*! +@fn \ int8_t m2m_ssl_retrieve_cert(uint32_t u32ReadAddr, uint16_t* pu16CurveType, uint8_t* pu8Hash, uint8_t* pu8Sig, tstrECPoint* pu8Key) +@brief Retrieve the certificate to be verified from the WINC +@param[in] pu16CurveType + Pointer to the certificate curve type. +@param[in] pu8Hash + Pointer to the certificate hash. +@param[in] pu8Sig + Pointer to the certificate signature. +@param[in] pu8Key + Pointer to the certificate Key. +@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise. +*/ +int8_t m2m_ssl_retrieve_cert(uint16_t* pu16CurveType, uint8_t* pu8Hash, uint8_t* pu8Sig, tstrECPoint* pu8Key) +{ + uint16_t u16HashSz, u16SigSz, u16KeySz; + + if (gu32HIFAddr == 0) + return M2M_ERR_FAIL; + + if (winc_hif_receive(gu32HIFAddr, pu16CurveType, 2) != M2M_SUCCESS) + return M2M_ERR_FAIL; + gu32HIFAddr += 2; + + if (winc_hif_receive(gu32HIFAddr, &u16KeySz, 2) != M2M_SUCCESS) + return M2M_ERR_FAIL; + gu32HIFAddr += 2; + + if (winc_hif_receive(gu32HIFAddr, &u16HashSz, 2) != M2M_SUCCESS) + return M2M_ERR_FAIL; + gu32HIFAddr += 2; + + if (winc_hif_receive(gu32HIFAddr, &u16SigSz, 2) != M2M_SUCCESS) + return M2M_ERR_FAIL; + gu32HIFAddr += 2; + + (*pu16CurveType)= _htons((*pu16CurveType)); + pu8Key->u16Size = _htons(u16KeySz); + u16HashSz = _htons(u16HashSz); + u16SigSz = _htons(u16SigSz); + + if (winc_hif_receive(gu32HIFAddr, pu8Key->X, pu8Key->u16Size * 2) != M2M_SUCCESS) + return M2M_ERR_FAIL; + gu32HIFAddr += (pu8Key->u16Size * 2); + + if (winc_hif_receive(gu32HIFAddr, pu8Hash, u16HashSz) != M2M_SUCCESS) + return M2M_ERR_FAIL; + gu32HIFAddr += u16HashSz; + + if (winc_hif_receive(gu32HIFAddr, pu8Sig, u16SigSz) != M2M_SUCCESS) + return M2M_ERR_FAIL; + gu32HIFAddr += u16SigSz; + + return M2M_SUCCESS; +} + +/*! +@fn \ int8_t m2m_ssl_retrieve_hash(uint32_t u32ReadAddr, uint8_t* pu8Hash, uint16_t u16HashSz) +@brief Retrieve the certificate hash. +@param[in] pu8Hash + Pointer to the certificate hash. +@param[in] u16HashSz + Hash size. +@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise. +*/ +int8_t m2m_ssl_retrieve_hash(uint8_t* pu8Hash, uint16_t u16HashSz) +{ + if (gu32HIFAddr == 0) + return M2M_ERR_FAIL; + + if (winc_hif_receive(gu32HIFAddr, pu8Hash, u16HashSz) != M2M_SUCCESS) + return M2M_ERR_FAIL; + + return M2M_SUCCESS; +} + +/*! +@fn \ void m2m_ssl_stop_processing_certs(void) +@brief Stops receiving from the HIF. +*/ +void m2m_ssl_stop_processing_certs(void) +{ +} + +/*! +@fn \ void m2m_ssl_ecc_process_done(void) +@brief Stops receiving from the HIF. +*/ +void m2m_ssl_ecc_process_done(void) +{ + gu32HIFAddr = 0; +} + +/*! +@fn int8_t m2m_ssl_set_active_ciphersuites(uint32_t u32SslCsBMP); +@brief Sets the active cipher suites. + +@param [in] u32SslCsBMP + Bitmap containing the desired ciphers to be enabled for the SSL module. The cipher suites are defined in + @ref SSLCipherSuiteID. + The default cipher suites are all cipher suites supported by the firmware with the exception of ECC cipher suites. + The caller can override the default with any desired combination, except for combinations involving both RSA + and ECC; if any RSA ciphersuite is enabled, then firmware will disable all ECC cipher suites. + If u32SslCsBMP does not contain any cipher suites supported by firmware, then the current active list will not + change. + +@return + - @ref SOCK_ERR_NO_ERROR + - @ref SOCK_ERR_INVALID_ARG +*/ +int8_t m2m_ssl_set_active_ciphersuites(uint32_t u32SslCsBMP) +{ + int8_t s8Ret = M2M_SUCCESS; + tstrSslSetActiveCsList strCsList; + + strCsList.u32CsBMP = u32SslCsBMP; + s8Ret = winc_hif_send_no_data(M2M_REQ_GROUP_SSL, M2M_SSL_REQ_SET_CS_LIST, &strCsList, sizeof(tstrSslSetActiveCsList)); + return s8Ret; +} diff --git a/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_ssl.h b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_ssl.h new file mode 100644 index 0000000..a21a218 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_ssl.h @@ -0,0 +1,357 @@ +/** + * + * \file + * + * \brief WINC SSL Interface. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +/** @defgroup SSLAPI SSL + @brief + Provides a description of the SSL Layer. + @{ + @defgroup SSLCallbacks Callbacks + @brief + Provides detail on the available callbacks for the SSL Layer. + + @defgroup SSLEnums Enumerations and Typedefs + @brief + Specifies the enums and Data Structures used by the SSL APIs. + + @defgroup SSLFUNCTIONS Functions + @brief + Provides detail on the available APIs for the SSL Layer. + + @defgroup TLSDefines TLS Defines + @brief + The following list of macros are used to define constants used in the SSL layer. + @{ + @defgroup SSLSocketOptions TLS Socket Options + @brief + The following list of macros are used to define SSL Socket options. + + @see setsockopt + @} + @} +*/ + +#ifndef __M2M_SSL_H__ +#define __M2M_SSL_H__ + +/**@defgroup LegacySSLCipherSuite Legacy names for TLS Cipher Suite IDs + * @ingroup TLSDefines + * The following list of macros MUST NOT be used. Instead use the new names under SSLCipherSuiteID + * @sa m2m_ssl_set_active_ciphersuites + * @{ + */ + +#define SSL_ENABLE_RSA_SHA_SUITES 0x01 +/*!< + Enable RSA Hmac_SHA based Cipher suites. For example, + TLS_RSA_WITH_AES_128_CBC_SHA +*/ + +#define SSL_ENABLE_RSA_SHA256_SUITES 0x02 +/*!< + Enable RSA Hmac_SHA256 based Cipher suites. For example, + TLS_RSA_WITH_AES_128_CBC_SHA256 +*/ + +#define SSL_ENABLE_DHE_SHA_SUITES 0x04 +/*!< + Enable DHE Hmac_SHA based Cipher suites. For example, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA +*/ + +#define SSL_ENABLE_DHE_SHA256_SUITES 0x08 +/*!< + Enable DHE Hmac_SHA256 based Cipher suites. For example, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 +*/ + +#define SSL_ENABLE_RSA_GCM_SUITES 0x10 +/*!< + Enable RSA AEAD based Cipher suites. For example, + TLS_RSA_WITH_AES_128_GCM_SHA256 +*/ + +#define SSL_ENABLE_DHE_GCM_SUITES 0x20 +/*!< + Enable DHE AEAD based Cipher suites. For example, + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 +*/ + +#define SSL_ENABLE_ALL_SUITES 0x0000003F +/*!< + Enable all possible supported cipher suites. +*/ +/**@}*/ //LegacySSLCipherSuite + +/**@defgroup SSLCipherSuiteID TLS Cipher Suite IDs + * @ingroup TLSDefines + * The following list of macros defined the list of supported TLS Cipher suites. + * Each MACRO defines a single Cipher suite. + * @sa m2m_ssl_set_active_ciphersuites + * @{ + */ + +#define SSL_CIPHER_RSA_WITH_AES_128_CBC_SHA NBIT0 +#define SSL_CIPHER_RSA_WITH_AES_128_CBC_SHA256 NBIT1 +#define SSL_CIPHER_DHE_RSA_WITH_AES_128_CBC_SHA NBIT2 +#define SSL_CIPHER_DHE_RSA_WITH_AES_128_CBC_SHA256 NBIT3 +#define SSL_CIPHER_RSA_WITH_AES_128_GCM_SHA256 NBIT4 +#define SSL_CIPHER_DHE_RSA_WITH_AES_128_GCM_SHA256 NBIT5 +#define SSL_CIPHER_RSA_WITH_AES_256_CBC_SHA NBIT6 +#define SSL_CIPHER_RSA_WITH_AES_256_CBC_SHA256 NBIT7 +#define SSL_CIPHER_DHE_RSA_WITH_AES_256_CBC_SHA NBIT8 +#define SSL_CIPHER_DHE_RSA_WITH_AES_256_CBC_SHA256 NBIT9 +#define SSL_CIPHER_ECDHE_RSA_WITH_AES_128_CBC_SHA NBIT10 +#define SSL_CIPHER_ECDHE_RSA_WITH_AES_256_CBC_SHA NBIT11 +#define SSL_CIPHER_ECDHE_RSA_WITH_AES_128_CBC_SHA256 NBIT12 +#define SSL_CIPHER_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 NBIT13 +#define SSL_CIPHER_ECDHE_RSA_WITH_AES_128_GCM_SHA256 NBIT14 +#define SSL_CIPHER_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 NBIT15 + +#define SSL_ECC_ONLY_CIPHERS \ +(\ + SSL_CIPHER_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | \ + SSL_CIPHER_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 \ +) +/*!< + All ciphers that use ECC crypto only. This excludes ciphers that use RSA. They use ECDSA instead. + These ciphers are turned off by default at startup. + The application may enable them if it has an ECC math engine (like ATECC508). +*/ +#define SSL_ECC_ALL_CIPHERS \ +(\ + SSL_CIPHER_ECDHE_RSA_WITH_AES_128_CBC_SHA | \ + SSL_CIPHER_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | \ + SSL_CIPHER_ECDHE_RSA_WITH_AES_128_GCM_SHA256 | \ + SSL_CIPHER_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | \ + SSL_CIPHER_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 \ +) +/*!< + All supported ECC Ciphers including those ciphers that depend on RSA and ECC. + These ciphers are turned off by default at startup. + The application may enable them if it has an ECC math engine (like ATECC508). +*/ + +#define SSL_NON_ECC_CIPHERS_AES_128 \ +(\ + SSL_CIPHER_RSA_WITH_AES_128_CBC_SHA | \ + SSL_CIPHER_RSA_WITH_AES_128_CBC_SHA256 | \ + SSL_CIPHER_DHE_RSA_WITH_AES_128_CBC_SHA | \ + SSL_CIPHER_DHE_RSA_WITH_AES_128_CBC_SHA256 | \ + SSL_CIPHER_RSA_WITH_AES_128_GCM_SHA256 | \ + SSL_CIPHER_DHE_RSA_WITH_AES_128_GCM_SHA256 \ +) +/*!< + All supported AES-128 Ciphers (ECC ciphers are not counted). This is the default active group after startup. +*/ + +#define SSL_ECC_CIPHERS_AES_256 \ +(\ + SSL_CIPHER_ECDHE_RSA_WITH_AES_256_CBC_SHA \ +) +/*!< + ECC AES-256 supported ciphers. +*/ + +#define SSL_NON_ECC_CIPHERS_AES_256 \ +(\ + SSL_CIPHER_RSA_WITH_AES_256_CBC_SHA | \ + SSL_CIPHER_RSA_WITH_AES_256_CBC_SHA256 | \ + SSL_CIPHER_DHE_RSA_WITH_AES_256_CBC_SHA | \ + SSL_CIPHER_DHE_RSA_WITH_AES_256_CBC_SHA256 \ +) +/*!< + AES-256 Ciphers. + This group is disabled by default at startup because the WINC HW Accelerator + supports only AES-128. If the application needs to force AES-256 cipher support, + it could enable them (or any of them) explicitly by calling m2m_ssl_set_active_ciphersuites. +*/ + +#define SSL_CIPHER_ALL \ +(\ + SSL_CIPHER_RSA_WITH_AES_128_CBC_SHA | \ + SSL_CIPHER_RSA_WITH_AES_128_CBC_SHA256 | \ + SSL_CIPHER_DHE_RSA_WITH_AES_128_CBC_SHA | \ + SSL_CIPHER_DHE_RSA_WITH_AES_128_CBC_SHA256 | \ + SSL_CIPHER_RSA_WITH_AES_128_GCM_SHA256 | \ + SSL_CIPHER_DHE_RSA_WITH_AES_128_GCM_SHA256 | \ + SSL_CIPHER_RSA_WITH_AES_256_CBC_SHA | \ + SSL_CIPHER_RSA_WITH_AES_256_CBC_SHA256 | \ + SSL_CIPHER_DHE_RSA_WITH_AES_256_CBC_SHA | \ + SSL_CIPHER_DHE_RSA_WITH_AES_256_CBC_SHA256 | \ + SSL_CIPHER_ECDHE_RSA_WITH_AES_128_CBC_SHA | \ + SSL_CIPHER_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | \ + SSL_CIPHER_ECDHE_RSA_WITH_AES_128_GCM_SHA256 | \ + SSL_CIPHER_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | \ + SSL_CIPHER_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 | \ + SSL_CIPHER_ECDHE_RSA_WITH_AES_256_CBC_SHA \ +) +/*!< + Turn On All TLS Ciphers. +*/ +/**@}*/ // SSLCipherSuiteID + +/*! +@ingroup SSLCallbacks +@typedef void (*tpfAppSSLCb)(uint8_t u8MsgType, void *pvMsg); +@brief A callback to get SSL notifications. +@param[in] u8MsgType + The type of the message received. +@param[in] pvMsg + A structure to provide notification payload. +*/ +typedef void (*tpfAppSSLCb)(uint8_t u8MsgType, void *pvMsg); + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +FUNCTION PROTOTYPES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +/*! +@fn \ void m2m_ssl_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr) +@brief Internal SSL callback function. +@param [in] u8OpCode + HIF Opcode type. +@param [in] u16DataSize + HIF data length. +@param [in] u32Addr + HIF address. +*/ +void m2m_ssl_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr); + +/*! +@ingroup SSLFUNCTIONS +@fn int8_t m2m_ssl_init(tpfAppSSLCb pfAppSSLCb); +@brief Initializes the SSL layer. +@param[in] pfAppSSLCb + Application SSL callback function. +@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise. +*/ +int8_t m2m_ssl_init(tpfAppSSLCb pfAppSSLCb); + +/*! +@ingroup SSLFUNCTIONS +@fn int8_t m2m_ssl_handshake_rsp(tstrEccReqInfo *pstrECCResp, uint8_t *pu8RspDataBuff, uint16_t u16RspDataSz); +@brief Sends ECC responses to the WINC. +@param[in] pstrECCResp + ECC Response struct. +@param[in] pu8RspDataBuff + Pointer of the response data to be sent. +@param[in] u16RspDataSz + Response data size. +@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise. +*/ +int8_t m2m_ssl_handshake_rsp(tstrEccReqInfo *pstrECCResp, uint8_t *pu8RspDataBuff, uint16_t u16RspDataSz); + +/*! +@ingroup SSLFUNCTIONS +@fn int8_t m2m_ssl_send_certs_to_winc(uint8_t *pu8Buffer, uint32_t u32BufferSz); +@brief Sends certificates to the WINC. +@param[in] pu8Buffer + Pointer to the certificates. The buffer format must match the format of @ref tstrTlsSrvSecHdr. +@param[in] u32BufferSz + Size of the certificates. +@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise. +*/ +int8_t m2m_ssl_send_certs_to_winc(uint8_t *pu8Buffer, uint32_t u32BufferSz); + +/*! +@ingroup SSLFUNCTIONS +@fn int8_t m2m_ssl_retrieve_cert(uint16_t *pu16CurveType, uint8_t *pu8Hash, uint8_t *pu8Sig, tstrECPoint *pu8Key); +@brief Retrieve the certificate to be verified from the WINC. +@param[in] pu16CurveType + Pointer to the certificate curve type. +@param[in] pu8Hash + Pointer to the certificate hash. +@param[in] pu8Sig + Pointer to the certificate signature. +@param[in] pu8Key + Pointer to the certificate Key. +@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise. +*/ +int8_t m2m_ssl_retrieve_cert(uint16_t *pu16CurveType, uint8_t *pu8Hash, uint8_t *pu8Sig, tstrECPoint *pu8Key); + +/*! +@ingroup SSLFUNCTIONS +@fn int8_t m2m_ssl_retrieve_hash(uint8_t *pu8Hash, uint16_t u16HashSz); +@brief Retrieve the certificate hash. +@param[in] pu8Hash + Pointer to the certificate hash. +@param[in] u16HashSz + Hash size. +@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise. +*/ +int8_t m2m_ssl_retrieve_hash(uint8_t *pu8Hash, uint16_t u16HashSz); + +/*! +@ingroup SSLFUNCTIONS +@fn void m2m_ssl_stop_processing_certs(void); +@brief Allow SSL driver to tidy up in case application does not read all available certificates. +@warning This API must only be called if some certificates are left unread. +@return None. +*/ +void m2m_ssl_stop_processing_certs(void); + +/*! +@ingroup SSLFUNCTIONS +@fn void m2m_ssl_ecc_process_done(void); +@brief Allow SSL driver to tidy up after application has finished processing ECC message. +@warning This API must be called after receiving a SSL callback with message type @ref M2M_SSL_REQ_ECC. +@return None. +*/ +void m2m_ssl_ecc_process_done(void); + +/*! +@ingroup SSLFUNCTIONS +@fn int8_t m2m_ssl_set_active_ciphersuites(uint32_t u32SslCsBMP); +@brief Sets the active cipher suites. +@details Override the default Active SSL ciphers in the SSL module with a certain combination selected by + the caller in the form of a bitmap containing the required ciphers to be on.\n + There is no need to call this function if the application will not change the default cipher suites. +@param[in] u32SslCsBMP + Bitmap containing the desired ciphers to be enabled for the SSL module. The cipher suites are defined in + @ref SSLCipherSuiteID. + The default cipher suites are all cipher suites supported by the firmware with the exception of ECC cipher suites. + The caller can override the default with any desired combination, except for combinations involving both RSA + and ECC; if any RSA ciphersuite is enabled, then firmware will disable all ECC cipher suites. + If u32SslCsBMP does not contain any cipher suites supported by firmware, then the current active list will not + change. +@return + - @ref SOCK_ERR_NO_ERROR + - @ref SOCK_ERR_INVALID_ARG +*/ +int8_t m2m_ssl_set_active_ciphersuites(uint32_t u32SslCsBMP); + +#endif /* __M2M_SSL_H__ */ diff --git a/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_types.h b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_types.h new file mode 100644 index 0000000..1b40eba --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_types.h @@ -0,0 +1,2815 @@ +/** + * + * \file + * + * \brief WINC Application Interface Types. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef _M2M_TYPES_H_ +#define _M2M_TYPES_H_ + +#include + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +MACROS +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ +/**@addtogroup VERSIONDEF + */ +/**@{*/ +#define M2M_MAJOR_SHIFT (8) +#define M2M_MINOR_SHIFT (4) +#define M2M_PATCH_SHIFT (0) + +#define M2M_DRV_VERSION_SHIFT (16) +#define M2M_FW_VERSION_SHIFT (0) + +#define M2M_GET_MAJOR(ver_info_hword) ((uint8_t)((ver_info_hword) >> M2M_MAJOR_SHIFT) & 0xff) +#define M2M_GET_MINOR(ver_info_hword) ((uint8_t)((ver_info_hword) >> M2M_MINOR_SHIFT) & 0x0f) +#define M2M_GET_PATCH(ver_info_hword) ((uint8_t)((ver_info_hword) >> M2M_PATCH_SHIFT) & 0x0f) + +#define M2M_GET_FW_VER(ver_info_word) ((uint16_t) ((ver_info_word) >> M2M_FW_VERSION_SHIFT)) +#define M2M_GET_DRV_VER(ver_info_word) ((uint16_t) ((ver_info_word) >> M2M_DRV_VERSION_SHIFT)) + +#define M2M_GET_DRV_MAJOR(ver_info_word) M2M_GET_MAJOR(M2M_GET_DRV_VER(ver_info_word)) +#define M2M_GET_DRV_MINOR(ver_info_word) M2M_GET_MINOR(M2M_GET_DRV_VER(ver_info_word)) +#define M2M_GET_DRV_PATCH(ver_info_word) M2M_GET_PATCH(M2M_GET_DRV_VER(ver_info_word)) + +#define M2M_GET_FW_MAJOR(ver_info_word) M2M_GET_MAJOR(M2M_GET_FW_VER(ver_info_word)) +#define M2M_GET_FW_MINOR(ver_info_word) M2M_GET_MINOR(M2M_GET_FW_VER(ver_info_word)) +#define M2M_GET_FW_PATCH(ver_info_word) M2M_GET_PATCH(M2M_GET_FW_VER(ver_info_word)) + +#define M2M_MAKE_VERSION(major, minor, patch) ( \ + ((uint16_t)((major) & 0xff) << M2M_MAJOR_SHIFT) | \ + ((uint16_t)((minor) & 0x0f) << M2M_MINOR_SHIFT) | \ + ((uint16_t)((patch) & 0x0f) << M2M_PATCH_SHIFT)) + +#define M2M_MAKE_VERSION_INFO(fw_major, fw_minor, fw_patch, drv_major, drv_minor, drv_patch) \ + ( \ + ( ((uint32_t)M2M_MAKE_VERSION((fw_major), (fw_minor), (fw_patch))) << M2M_FW_VERSION_SHIFT) | \ + ( ((uint32_t)M2M_MAKE_VERSION((drv_major), (drv_minor), (drv_patch))) << M2M_DRV_VERSION_SHIFT)) + +/*======*======*======*======* + FIRMWARE VERSION NO INFO + *======*======*======*======*/ + +#define M2M_RELEASE_VERSION_MAJOR_NO (19) +/*!< Firmware Major release version number. +*/ + +#define M2M_RELEASE_VERSION_MINOR_NO (6) +/*!< Firmware Minor release version number. +*/ + +#define M2M_RELEASE_VERSION_PATCH_NO (1) +/*!< Firmware patch release version number. +*/ + +/*======*======*======*======* + SUPPORTED DRIVER VERSION NO INFO + *======*======*======*======*/ + +#define M2M_MIN_REQ_DRV_VERSION_MAJOR_NO (19) +/*!< Driver Major release version number. +*/ + + +#define M2M_MIN_REQ_DRV_VERSION_MINOR_NO (3) +/*!< Driver Minor release version number. +*/ + +#define M2M_MIN_REQ_DRV_VERSION_PATCH_NO (0) +/*!< Driver patch release version number. +*/ + +#if !defined(M2M_RELEASE_VERSION_MAJOR_NO) || !defined(M2M_RELEASE_VERSION_MINOR_NO) +#error Undefined version number +#endif + +/**@}*/ // VERSIONDEF + +/**@addtogroup WLANDefines + * @{ + */ + +#define M2M_BUFFER_MAX_SIZE (1600UL - 4) +/*!< Maximum size for the shared packet buffer. + */ + +#define M2M_MAC_ADDRES_LEN 6 +/*!< The size of the 802 MAC address. + */ + +#define M2M_ETHERNET_HDR_OFFSET 34 +/*!< The offset of the Ethernet header within the WLAN Tx Buffer. + */ + + +#define M2M_ETHERNET_HDR_LEN 14 +/*!< Length of the Ethernet header in bytes. +*/ + + +#define M2M_MAX_SSID_LEN 33 +/*!< 1 more than the max SSID length. + This matches the size of SSID buffers (max SSID length + 1-byte length field). + */ + + +#define M2M_MAX_PSK_LEN 65 +/*!< 1 more than the WPA PSK length (in ASCII format). + This matches the size of the WPA PSK/Passphrase buffer (max ASCII contents + 1-byte length field). + Alternatively it matches the WPA PSK length (in ASCII format) + 1 byte NULL termination. + */ + +#define M2M_MIN_PSK_LEN 9 +/*!< 1 more than the minimum WPA PSK Passphrase length. + It matches the minimum WPA PSK Passphrase length + 1 byte NULL termination. + */ + +#define M2M_DEVICE_NAME_MAX 48 +/*!< Maximum Size for the device name including the NULL termination. + */ + +#define M2M_NTP_MAX_SERVER_NAME_LENGTH 32 +/*!< Maximum NTP server name length +*/ + +#define M2M_LISTEN_INTERVAL 1 +/*!< The STA uses the Listen Interval parameter to indicate to the AP how + many beacon intervals it shall sleep before it retrieves the queued frames + from the AP. +*/ + +#define MAX_HIDDEN_SITES 4 +/*!< + max number of hidden SSID supported by scan request +*/ + +#define M2M_CUST_IE_LEN_MAX 252 +/*!< The maximum size of IE (Information Element). +*/ + +#define M2M_CRED_STORE_FLAG 0x01 +/*!< Flag used in @ref tstrM2mConnCredHdr to indicate that Wi-Fi connection + credentials should be stored in WINC flash. +*/ +#define M2M_CRED_ENCRYPT_FLAG 0x02 +/*!< Flag used in @ref tstrM2mConnCredHdr to indicate that Wi-Fi connection + credentials should be encrypted when stored in WINC flash. +*/ +#define M2M_CRED_IS_STORED_FLAG 0x10 +/*!< Flag used in @ref tstrM2mConnCredHdr to indicate that Wi-Fi connection + credentials are stored in WINC flash. May only be set by WINC firmware. +*/ +#define M2M_CRED_IS_ENCRYPTED_FLAG 0x20 +/*!< Flag used in @ref tstrM2mConnCredHdr to indicate that Wi-Fi connection + credentials are encrypted in WINC flash. May only be set by WINC firmware. +*/ + +#define M2M_WIFI_CONN_BSSID_FLAG 0x01 +/*!< Flag used in @ref tstrM2mConnCredCmn to indicate that Wi-Fi connection + must be restricted to an AP with a certain BSSID. +*/ + +#define M2M_AUTH_1X_USER_LEN_MAX 132 +/*!< The maximum length (in ASCII characters) of domain name + username (including '@' or '\') + for authentication with Enterprise methods. +*/ +#define M2M_AUTH_1X_PASSWORD_LEN_MAX 256 +/*!< The maximum length (in ASCII characters) of password for authentication with Enterprise MSCHAPv2 methods. +*/ +#define M2M_AUTH_1X_PRIVATEKEY_LEN_MAX 256 +/*!< The maximum length (in bytes) of private key modulus for authentication with Enterprise TLS methods. + Private key exponent must be the same length as modulus, pre-padded with 0s if necessary. +*/ +#define M2M_AUTH_1X_CERT_LEN_MAX 1584 +/*!< The maximum length (in bytes) of certificate for authentication with Enterprise TLS methods. +*/ +#define M2M_802_1X_UNENCRYPTED_USERNAME_FLAG 0x80 +/*!< Flag to indicate that the 802.1x user-name should be sent (unencrypted) in the initial EAP + identity response. Intended for use with EAP-TLS only. +*/ +#define M2M_802_1X_PREPEND_DOMAIN_FLAG 0x40 +/*!< Flag to indicate that the 802.1x domain name should be prepended to the user-name: + "Domain\Username". If the flag is not set then domain name is appended to the user-name: + "Username@Domain". (Note that the '@' or '\' must be included in the domain name.) +*/ +#define M2M_802_1X_MSCHAP2_FLAG 0x01 +/*!< Flag to indicate 802.1x MsChapV2 credentials: domain/user-name/password. +*/ +#define M2M_802_1X_TLS_FLAG 0x02 +/*!< Flag to indicate 802.1x TLS credentials: domain/user-name/private-key/certificate. +*/ +#define M2M_802_1X_TLS_CLIENT_CERTIFICATE 1 +/*!< Info type used in @ref tstrM2mWifiAuthInfoHdr to indicate Enterprise TLS client certificate. +*/ + +#define PSK_CALC_LEN 40 +/*!< PSK is 32 bytes generated either: + - from 64 ASCII characters + - by SHA1 operations on up to 63 ASCII characters + 40 byte array is required during SHA1 operations, so we define PSK_CALC_LEN as 40. +*/ + +/********************* + * + * WIFI GROUP requests + */ + +#define M2M_CONFIG_CMD_BASE 1 +/*!< The base value of all the Host configuration commands opcodes. +*/ +#define M2M_STA_CMD_BASE 40 +/*!< The base value of all the Station mode host commands opcodes. +*/ +#define M2M_AP_CMD_BASE 70 +/*!< The base value of all the Access Point mode host commands opcodes. +*/ + +/**@cond P2P_DOC + */ +#define M2M_P2P_CMD_BASE 90 +/*!< The base value of all the P2P mode host commands opcodes. +*/ +/**@endcond*/ //P2P_DOC + +#define M2M_SERVER_CMD_BASE 100 +/*!< The base value of all the power save mode host commands codes. +*/ +#define M2M_GEN_CMD_BASE 105 +/*!< The base value of additional host wifi command opcodes. + * Usage restrictions (eg STA mode only) should always be made clear at the API layer in any case. +*/ +/********************** + * OTA GROUP requests + */ +#define M2M_OTA_CMD_BASE 100 +/*!< The base value of all the OTA mode host commands opcodes. + * The OTA Have special group so can extended from 1-M2M_MAX_GRP_NUM_REQ +*/ +/*********************** + * + * CRYPTO group requests + */ +#define M2M_CRYPTO_CMD_BASE 1 +/*!< The base value of all the crypto mode host commands opcodes. + * The crypto Have special group so can extended from 1-M2M_MAX_GRP_NUM_REQ +*/ + +#define M2M_MAX_GRP_NUM_REQ (127) +/*!< max number of request in one group equal to 127 as the last bit reserved for config or data pkt +*/ + +#define WEP_40_KEY_SIZE (5) +/*!< The size in bytes of a 40-bit wep key. +*/ +#define WEP_104_KEY_SIZE (13) +/*!< The size in bytes of a 104-bit wep key. +*/ + +#define WEP_40_KEY_STRING_SIZE (10) +/*!< The string length of a 40-bit wep key. +*/ +#define WEP_104_KEY_STRING_SIZE (26) +/*!< The string length of a 104-bit wep key. +*/ + +#define WEP_KEY_MAX_INDEX (4) +/*!< WEP key index is in the range 1 to 4 inclusive. (This is decremented to + * result in an index in the range 0 to 3 on air.) +*/ +#define M2M_SHA256_CONTEXT_BUFF_LEN (128) +/*!< sha256 context size +*/ +#define M2M_SCAN_DEFAULT_NUM_SLOTS (2) +/*!< The default number of scan slots used by the WINC board. +*/ +#define M2M_SCAN_DEFAULT_SLOT_TIME (30) +/*!< The default duration in milliseconds of an active scan slot used by the WINC board. +*/ +#define M2M_SCAN_DEFAULT_PASSIVE_SLOT_TIME (300) +/*!< The passive scan slot default duration in ms. +*/ +#define M2M_SCAN_DEFAULT_NUM_PROBE (2) +/*!< The default number of probes per scan slot. +*/ +#define M2M_FASTCONNECT_DEFAULT_RSSI_THRESH (-45) +/*!< The default threshold RSSI for fast reconnection to an AP. +*/ + +/*======*======*======*======* + TLS DEFINITIONS + *======*======*======*======*/ +#define TLS_FILE_NAME_MAX 48 +/*!< Maximum length for each TLS certificate file name including null terminator. +*/ +#define TLS_SRV_SEC_MAX_FILES 8 +/*!< Maximum number of certificates allowed in TLS_SRV section. +*/ +#define TLS_SRV_SEC_START_PATTERN_LEN 8 +/*!< Length of certificate struct start pattern. +*/ + +/*======*======*======*======* + SSL DEFINITIONS + *======*======*======*======*/ + +#define TLS_CRL_DATA_MAX_LEN 64 +/* Every bit have 3dB gain control each. + for example: + 1 ->3db + 3 ->6db + 7 ->9db + */ + uint16_t u8PPAGFor11GN; + /*!< PPA gain for 11GN (as the RF document represented) + PPA_AGC<0:2> Every bit have 3dB gain control each. + for example: + 1 ->3db + 3 ->6db + 7 ->9db + */ +} tstrM2mWifiGainsParams; + +/*! +@struct \ + tstrM2mConnCredHdr + +@brief + Wi-Fi Connect Credentials Header +*/ +typedef struct { + uint16_t u16CredSize; + /*!< Total size of connect credentials, not including tstrM2mConnCredHdr: + tstrM2mConnCredCmn + Auth details (variable size) + */ + uint8_t u8CredStoreFlags; + /*!< Credential storage options represented with flags: + @ref M2M_CRED_STORE_FLAG + @ref M2M_CRED_ENCRYPT_FLAG + @ref M2M_CRED_IS_STORED_FLAG + @ref M2M_CRED_IS_ENCRYPTED_FLAG + */ + uint8_t u8Channel; + /*!< Wi-Fi channel(s) on which to attempt connection. */ +} tstrM2mConnCredHdr; + +/*! +@struct \ + tstrM2mConnCredCmn + +@brief + Wi-Fi Connect Credentials Common section + */ +typedef struct { + uint8_t u8SsidLen; + /*!< SSID length. */ + uint8_t au8Ssid[M2M_MAX_SSID_LEN-1]; + /*!< SSID. */ + uint8_t u8Options; + /*!< Common flags: + @ref M2M_WIFI_CONN_BSSID_FLAG + */ + uint8_t au8Bssid[M2M_MAC_ADDRES_LEN]; + /*!< BSSID to restrict on, or all 0 if M2M_WIFI_CONN_BSSID_FLAG is not set in u8Options. */ + uint8_t u8AuthType; + /*!< Connection auth type. See @ref tenuM2mSecType. */ + uint8_t au8Rsv[3]; + /*!< Reserved for future use. Set to 0. */ +} tstrM2mConnCredCmn; + +/*! +@struct \ + tstrM2mWifiWep + +@brief + WEP security key header. +*/ +typedef struct { + uint8_t u8KeyIndex; + /*!< WEP Key Index. */ + uint8_t u8KeyLen; + /*!< WEP Key Size. */ + uint8_t au8WepKey[WEP_104_KEY_SIZE]; + /*!< WEP Key represented in bytes (padded with 0's if WEP-40). */ + uint8_t u8Rsv; + /*!< Reserved for future use. Set to 0. */ +} tstrM2mWifiWep; + +/*! +@struct \ + tstrM2mWifiPsk + +@brief + Passphrase and PSK for WPA(2) PSK. +*/ +typedef struct { + uint8_t u8PassphraseLen; + /*!< Length of passphrase (8 to 63) or 64 if au8Passphrase contains ASCII representation of PSK. */ + uint8_t au8Passphrase[M2M_MAX_PSK_LEN-1]; + /*!< Passphrase, or ASCII representation of PSK if u8PassphraseLen is 64. */ + uint8_t au8Psk[PSK_CALC_LEN]; + /*!< PSK calculated by firmware. Driver sets this to 0. */ + uint8_t u8PskCalculated; + /*!< Flag used by firmware to avoid unnecessary recalculation of PSK. Driver sets this to 0. */ + uint8_t au8Rsv[2]; + /*!< Reserved for future use. Set to 0. */ +} tstrM2mWifiPsk; + +/*! +@struct \ + tstrM2mWifi1xHdr + +@brief + Wi-Fi Authentication 802.1x header for parameters. + The parameters (Domain, UserName, PrivateKey/Password) are appended to this structure. +*/ +typedef struct { + uint8_t u8Flags; + /*!< 802.1x-specific flags: + @ref M2M_802_1X_MSCHAP2_FLAG + @ref M2M_802_1X_TLS_FLAG + @ref M2M_802_1X_UNENCRYPTED_USERNAME_FLAG + @ref M2M_802_1X_PREPEND_DOMAIN_FLAG + */ + uint8_t u8DomainLength; + /*!< Length of Domain. (Offset of Domain understood to be 0.) */ + uint16_t u16UserNameLength; + /*!< Length of UserName. (Offset of UserName understood to be u8DomainLength.) */ + uint16_t u16PrivateKeyOffset; + /*!< Offset within au81xAuthDetails of PrivateKey/Password. */ + uint16_t u16PrivateKeyLength; + /*!< Length of PrivateKey/Password. In the case of PrivateKey, this is the length of the modulus. */ + uint16_t u16CertificateOffset; + /*!< Offset within au81xAuthDetails of Certificate. */ + uint16_t u16CertificateLength; + /*!< Length of Certificate. */ + uint8_t au81xAuthDetails[]; + /*!< Placeholder for concatenation of Domain, UserName, PrivateKey/Password, Certificate. + Padding (0s) is placed between UserName and PrivateKey/Password so that + PrivateKey/Password begins on a 4-byte boundary. + Certificate (for 1x Tls only) is sent over HIF separately from the other parameters. */ +} tstrM2mWifi1xHdr; + +/*! +@struct \ + tstrM2mWifiAuthInfoHdr + +@brief + Generic Wi-Fi authentication information to be sent in a separate HIF message of type + @ref M2M_WIFI_IND_CONN_PARAM (preceding @ref M2M_WIFI_REQ_CONN). +*/ +typedef struct { + uint8_t u8Type; + /*!< Type of info: + @ref M2M_802_1X_TLS_CLIENT_CERTIFICATE + */ + uint8_t au8Rsv[3]; + /*!< Reserved for future use. Set to 0. */ + uint16_t u16InfoPos; + /*!< Information about positioning of the Info. The interpretation depends on u8Type. */ + uint16_t u16InfoLen; + /*!< Info length (not including this header). */ + uint8_t au8Info[]; + /*!< Placeholder for info. */ +} tstrM2mWifiAuthInfoHdr; + +/*! +@struct \ + tstrM2mWifiConnHdr + +@brief + Wi-Fi Connect Request (new format) for use with @ref M2M_WIFI_REQ_CONN. + This structure is sent across the HIF along with the relevant auth details. One of: + @ref tstrM2mWifiPsk + @ref tstrM2mWifiWep + @ref tstrM2mWifi1xHdr + If further authentication details need to be sent (such as client certificate for 1x TLS), they + are sent with header @ref tstrM2mWifiAuthInfoHdr in a preceding HIF message of type + @ref M2M_WIFI_IND_CONN_PARAM +*/ +typedef struct { + tstrM2mConnCredHdr strConnCredHdr; + /*!< Credentials header. */ + tstrM2mConnCredCmn strConnCredCmn; + /*!< Credentials common section, including auth type and SSID. */ +} tstrM2mWifiConnHdr; + +/*! +@struct \ + tstrM2mWifiApId + +@brief + Specify an access point (by SSID) +*/ +typedef struct { + uint8_t au8SSID[M2M_MAX_SSID_LEN]; + /*!< + SSID of the desired AP, prefixed by length byte. + First byte 0xFF used to mean all access points. + */ + uint8_t __PAD__[3]; + /*!< Padding bytes for forcing 4-byte alignment + */ +} tstrM2mWifiApId; + +/*! +@struct \ + tstrM2MGenericResp + +@brief + Generic success/error response +*/ +typedef struct { + int8_t s8ErrorCode; + /*!< + Generic success/error code. Possible values are: + - @ref M2M_SUCCESS + - @ref M2M_ERR_FAIL + */ + uint8_t __PAD24__[3]; +} tstrM2MGenericResp; + +/*! +@struct \ + tstrM2MWPSConnect + +@brief + This struct stores the WPS configuration parameters. + +@sa + tenuWPSTrigger +*/ +typedef struct { + uint8_t u8TriggerType; + /*!< WPS triggering method (Push button or PIN) */ + char acPinNumber[8]; + /*!< WPS PIN No (for PIN method) */ + uint8_t __PAD24__[3]; + /*!< Padding bytes for forcing 4-byte alignment */ +} tstrM2MWPSConnect; + +/*! +@struct \ + tstrM2MWPSInfo + +@brief WPS Result + + This structure is passed to the application in response to a WPS request. If the WPS session is completed successfully, the + structure will have Non-ZERO authentication type. If the WPS Session fails (due to error or timeout) the authentication type + is set to ZERO. + +@sa + tenuM2mSecType +*/ +typedef struct { + uint8_t u8AuthType; + /*!< Network authentication type. */ + uint8_t u8Ch; + /*!< RF Channel for the AP. */ + uint8_t au8SSID[M2M_MAX_SSID_LEN]; + /*!< SSID obtained from WPS. */ + uint8_t au8PSK[M2M_MAX_PSK_LEN]; + /*!< PSK for the network obtained from WPS. */ + +} tstrM2MWPSInfo; + + +/*! +@struct \ + tstrM2MDefaultConnResp + +@brief + This struct contains the response error of m2m_default_connect. + +@sa + M2M_DEFAULT_CONN_SCAN_MISMATCH + M2M_DEFAULT_CONN_EMPTY_LIST +*/ +typedef struct { + int8_t s8ErrorCode; + /*!< + Default connect error code. possible values are: + - M2M_DEFAULT_CONN_EMPTY_LIST + - M2M_DEFAULT_CONN_SCAN_MISMATCH + */ + uint8_t __PAD24__[3]; +} tstrM2MDefaultConnResp; + +/*! +@struct \ + tstrM2MScanOption + +@brief + This struct contains the configuration options for Wi-Fi scan. + +@sa + tenuM2mScanCh + tstrM2MScan +*/ +typedef struct { + uint8_t u8NumOfSlot; + /*!< The number of scan slots per channel. Refers to both active and passive scan. + Valid settings are in the range 0Microchip Support + */ + +#include "../driver/winc_adapter.h" +#include "../common/winc_defines.h" +#include "../common/winc_debug.h" +#include "m2m_types.h" +#include "m2m_wifi.h" +#include "m2m_fwinfo.h" +#include "../driver/winc_hif.h" +#include "../driver/winc_drv.h" +#include "../driver/winc_asic.h" + +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mPwrMode) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mTxPwrLevel) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mWiFiGainIdx) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mEnableLogs) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mBatteryVoltage) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mWiFiRoaming) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mConnCredHdr) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mConnCredCmn) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mWifiWep) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mWifiPsk) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mWifi1xHdr) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mWifiAuthInfoHdr) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mWifiConnHdr) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mWifiApId) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2MGenericResp) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2MWPSConnect) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2MDefaultConnResp) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2MScanRegion) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrCyptoResp) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mScanDone) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mReqScanResult) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mWifiscanResult) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mWifiStateChanged) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mPsType) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mLsnInt) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2MWifiMonitorModeCtrl) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2MWifiRxPacketInfo) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2MP2PConnect) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2MAPConfig) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2MAPConfigExt) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2MAPModeConfig) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mServerInit) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mClientState) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2Mservercmd) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2mSetMacAddress) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2MProvisionModeConfig) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2MConnInfo) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrTlsCrlEntry) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2MSNTPConfig) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrOtaUpdateStatusResp) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrOtaUpdateInfo) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrOtaHostFileGetStatusResp) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrOtaHostFileReadStatusResp) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrOtaHostFileEraseStatusResp) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrSystemTime) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrM2MMulticastMac) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrPrng) +CONF_WINC_HIF_STRUCT_SIZE_CHECK(tstrConfAutoRate) + +static uint8_t gu8ChNum; +static uint8_t gu8WifiState = WIFI_STATE_DEINIT; +static tpfAppWifiCb gpfAppWifiCb = NULL; +static uint8_t gu8scanInProgress = 0; +static tenuPowerSaveModes genuPsMode = M2M_NO_PS; + +#ifdef ETH_MODE +static tpfAppEthCb gpfAppEthCb = NULL; +static uint8_t *gau8ethRcvBuf = NULL; +static uint16_t gu16ethRcvBufSize; +#endif + +typedef struct +{ + uint_fast8_t u8OpCode; + uint_fast16_t u16DataSize; +} tstrWiFiCbEntry; + +static tstrWiFiCbEntry WiFiCbTable[] = { + {M2M_WIFI_RESP_CON_STATE_CHANGED, sizeof(tstrM2mWifiStateChanged)}, + {M2M_WIFI_RESP_GET_SYS_TIME, sizeof(tstrSystemTime)}, + {M2M_WIFI_RESP_CONN_INFO, sizeof(tstrM2MConnInfo)}, + {M2M_WIFI_REQ_DHCP_CONF, sizeof(tstrM2MIPConfig)}, + {M2M_WIFI_REQ_DHCP_FAILURE, 0}, + {M2M_WIFI_REQ_WPS, sizeof(tstrM2MWPSInfo)}, + {M2M_WIFI_RESP_IP_CONFLICT, sizeof(uint32_t)}, + {M2M_WIFI_RESP_SCAN_DONE, sizeof(tstrM2mScanDone)}, + {M2M_WIFI_RESP_SCAN_RESULT, sizeof(tstrM2mWifiscanResult)}, + {M2M_WIFI_RESP_CURRENT_RSSI, 4}, + {M2M_WIFI_RESP_CLIENT_INFO, 4}, + {M2M_WIFI_RESP_PROVISION_INFO, sizeof(tstrM2MProvisionInfo)}, + {M2M_WIFI_RESP_DEFAULT_CONNECT, sizeof(tstrM2MDefaultConnResp)}, + {M2M_WIFI_REQRSP_DELETE_APID, sizeof(tstrM2MGenericResp)}, +#ifdef ETH_MODE + {M2M_WIFI_RESP_ETHERNET_RX_PACKET, sizeof(tstrM2mIpRsvdPkt)}, +#endif + {M2M_WIFI_MAX_STA_ALL, 0} +}; + +typedef union +{ + tstrM2mWifiStateChanged strStateChanged; + tstrSystemTime strSysTime; + tstrM2MConnInfo strConnInfo; + tstrM2MIPConfig strIpConfig; + tstrM2MWPSInfo strWps; + uint32_t u32ConflictedIP; + tstrM2mScanDone strScanDone; + tstrM2mWifiscanResult strScanResult; + tstrM2MProvisionInfo strProvInfo; + tstrM2MDefaultConnResp strDefaultConnResp; + tstrM2MGenericResp strGenericResp; +#ifdef ETH_MODE + tstrM2mIpRsvdPkt strM2mRsvd; +#endif +} tuWiFiCbMsgs; + +/** +@fn void m2m_wifi_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr) +@brief Internal WiFi callback function. +@param[in] u8OpCode + HIF Opcode type. +@param[in] u16DataSize + HIF data length. +@param[in] u32Addr + HIF address. +*/ +void m2m_wifi_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr) +{ + UNUSED_VAR(u16DataSize); + + tstrWiFiCbEntry *pWiFiCbEntry; + tuWiFiCbMsgs wifiMsg; + + pWiFiCbEntry = WiFiCbTable; + + while(pWiFiCbEntry->u8OpCode != M2M_WIFI_MAX_STA_ALL) + { + if (pWiFiCbEntry->u8OpCode == u8OpCode) + { + if (pWiFiCbEntry->u16DataSize) + { + if (M2M_SUCCESS != winc_hif_receive(u32Addr, &wifiMsg, pWiFiCbEntry->u16DataSize)) + { + return; + } + } + + if (!gpfAppWifiCb) + break; + + if (pWiFiCbEntry->u16DataSize) + { + if (u8OpCode == M2M_WIFI_RESP_IP_CONFLICT) + { + WINC_LOG_INFO("Conflicted IP \" %u.%u.%u.%u \"", + BYTE_0(wifiMsg.u32ConflictedIP), BYTE_1(wifiMsg.u32ConflictedIP), BYTE_2(wifiMsg.u32ConflictedIP), BYTE_3(wifiMsg.u32ConflictedIP)); + } + else if (u8OpCode == M2M_WIFI_RESP_SCAN_DONE) + { + gu8scanInProgress = 0; + gu8ChNum = wifiMsg.strScanDone.u8NumofCh; + } + + gpfAppWifiCb(u8OpCode, &wifiMsg); + } + else + { + gpfAppWifiCb(u8OpCode, NULL); + } + + break; + } + + pWiFiCbEntry++; + } + + if(u8OpCode == M2M_WIFI_RESP_GET_PRNG) + { + tstrPrng strPrng; + if(winc_hif_receive(u32Addr, &strPrng, sizeof(tstrPrng)) == M2M_SUCCESS) + { + if(winc_hif_receive(u32Addr + sizeof(tstrPrng), strPrng.pu8RngBuff, strPrng.u16PrngSize) == M2M_SUCCESS) + { + if(gpfAppWifiCb) + gpfAppWifiCb(M2M_WIFI_RESP_GET_PRNG,&strPrng); + } + } + } +#ifdef ETH_MODE + else if(u8OpCode == M2M_WIFI_RESP_ETHERNET_RX_PACKET) + { + tstrM2mIpCtrlBuf strM2mIpCtrlBuf; + uint16_t u16Offset = wifiMsg.strM2mRsvd.u16PktOffset; + strM2mIpCtrlBuf.u16RemainingDataSize = wifiMsg.strM2mRsvd.u16PktSz; + if((gpfAppEthCb) && (gau8ethRcvBuf) && (gu16ethRcvBufSize > 0)) + { + do + { + if(strM2mIpCtrlBuf.u16RemainingDataSize > gu16ethRcvBufSize) + { + strM2mIpCtrlBuf.u16DataSize = gu16ethRcvBufSize; + } + else + { + strM2mIpCtrlBuf.u16DataSize = strM2mIpCtrlBuf.u16RemainingDataSize; + } + + if(winc_hif_receive(u32Addr + u16Offset, gau8ethRcvBuf, strM2mIpCtrlBuf.u16DataSize) == M2M_SUCCESS) + { + strM2mIpCtrlBuf.u16RemainingDataSize -= strM2mIpCtrlBuf.u16DataSize; + u16Offset += strM2mIpCtrlBuf.u16DataSize; + gpfAppEthCb(M2M_WIFI_RESP_ETHERNET_RX_PACKET, gau8ethRcvBuf, &(strM2mIpCtrlBuf)); + } + else + { + break; + } + } + while (strM2mIpCtrlBuf.u16RemainingDataSize > 0); + } + } +#endif /* ETH_MODE */ +} + +int8_t m2m_wifi_download_mode(void) +{ + if (WINC_DRV_SUCCESS != winc_drv_init(true)) + return M2M_ERR_FAIL; + + winc_chip_interrupts_enable(); + gu8WifiState = WIFI_STATE_INIT; + + return M2M_SUCCESS; +} + +static int8_t m2m_validate_ap_parameters(const tstrM2MAPModeConfig *pstrM2MAPModeConfig) +{ + int8_t s8Ret = M2M_SUCCESS; + /* Check for incoming pointer */ + if(pstrM2MAPModeConfig == NULL) + { + WINC_LOG_ERROR("INVALID POINTER"); + s8Ret = M2M_ERR_FAIL; + goto ERR1; + } + /* Check for SSID */ + if((strlen((const char*)pstrM2MAPModeConfig->strApConfig.au8SSID) <= 0) || (strlen((const char*)pstrM2MAPModeConfig->strApConfig.au8SSID) >= M2M_MAX_SSID_LEN)) + { + WINC_LOG_ERROR("INVALID SSID"); + s8Ret = M2M_ERR_FAIL; + goto ERR1; + } + /* Check for Channel */ + if(pstrM2MAPModeConfig->strApConfig.u8ListenChannel > M2M_WIFI_CH_14 || pstrM2MAPModeConfig->strApConfig.u8ListenChannel < M2M_WIFI_CH_1) + { + WINC_LOG_ERROR("INVALID CH"); + s8Ret = M2M_ERR_FAIL; + goto ERR1; + } + /* Check for DHCP Server IP address */ + if(!(pstrM2MAPModeConfig->strApConfig.au8DHCPServerIP[0] || pstrM2MAPModeConfig->strApConfig.au8DHCPServerIP[1])) + { + if(!(pstrM2MAPModeConfig->strApConfig.au8DHCPServerIP[2])) + { + WINC_LOG_ERROR("INVALID DHCP SERVER IP"); + s8Ret = M2M_ERR_FAIL; + goto ERR1; + } + } + /* Check for Security */ + if(pstrM2MAPModeConfig->strApConfig.u8SecType == M2M_WIFI_SEC_OPEN) + { + goto ERR1; + } + else if(pstrM2MAPModeConfig->strApConfig.u8SecType == M2M_WIFI_SEC_WEP) + { + /* Check for WEP Key index */ + if((pstrM2MAPModeConfig->strApConfig.u8KeyIndx == 0) || (pstrM2MAPModeConfig->strApConfig.u8KeyIndx > WEP_KEY_MAX_INDEX)) + { + WINC_LOG_ERROR("INVALID KEY INDEX"); + s8Ret = M2M_ERR_FAIL; + goto ERR1; + } + /* Check for WEP Key size */ + if( (pstrM2MAPModeConfig->strApConfig.u8KeySz != WEP_40_KEY_STRING_SIZE) && + (pstrM2MAPModeConfig->strApConfig.u8KeySz != WEP_104_KEY_STRING_SIZE) + ) + { + WINC_LOG_ERROR("INVALID KEY STRING SIZE"); + s8Ret = M2M_ERR_FAIL; + goto ERR1; + } + + if((strlen((const char*)pstrM2MAPModeConfig->strApConfig.au8WepKey) <= 0) || (strlen((const char*)pstrM2MAPModeConfig->strApConfig.au8WepKey) > WEP_104_KEY_STRING_SIZE)) + { + WINC_LOG_ERROR("INVALID KEY SIZE"); + s8Ret = M2M_ERR_FAIL; + goto ERR1; + } + } + else if(pstrM2MAPModeConfig->strApConfig.u8SecType == M2M_WIFI_SEC_WPA_PSK) + { + /* Check for WPA Key size */ + if( ((pstrM2MAPModeConfig->strApConfig.u8KeySz + 1) < M2M_MIN_PSK_LEN) || ((pstrM2MAPModeConfig->strApConfig.u8KeySz + 1) > M2M_MAX_PSK_LEN)) + { + WINC_LOG_ERROR("INVALID WPA KEY SIZE"); + s8Ret = M2M_ERR_FAIL; + goto ERR1; + } + } + else + { + WINC_LOG_ERROR("INVALID AUTHENTICATION MODE"); + s8Ret = M2M_ERR_FAIL; + goto ERR1; + } + +ERR1: + return s8Ret; +} + +static int8_t m2m_validate_scan_options(tstrM2MScanOption *ptstrM2MScanOption) +{ + /* Check for incoming pointer */ + if (ptstrM2MScanOption == NULL) + { + WINC_LOG_ERROR("INVALID POINTER"); + return M2M_ERR_FAIL; + } + /* Check for valid No of slots */ + if (ptstrM2MScanOption->u8NumOfSlot == 0) + { + WINC_LOG_ERROR("INVALID No of scan slots! %u", ptstrM2MScanOption->u8NumOfSlot); + return M2M_ERR_FAIL; + } + /* Check for valid time of slots */ + if ((ptstrM2MScanOption->u8SlotTime < 10) || (ptstrM2MScanOption->u8SlotTime > 250)) + { + WINC_LOG_ERROR("INVALID scan slot time! %u", ptstrM2MScanOption->u8SlotTime); + return M2M_ERR_FAIL; + } + /* Check for valid No of probe requests per slot */ + if ((ptstrM2MScanOption->u8ProbesPerSlot == 0) || (ptstrM2MScanOption->u8ProbesPerSlot > M2M_SCAN_DEFAULT_NUM_PROBE)) + { + WINC_LOG_ERROR("INVALID No of probe requests per scan slot %u", ptstrM2MScanOption->u8ProbesPerSlot); + return M2M_ERR_FAIL; + } + /* Check for valid RSSI threshold */ + if (ptstrM2MScanOption->s8RssiThresh >= 0) + { + WINC_LOG_ERROR("INVALID RSSI threshold %d", ptstrM2MScanOption->s8RssiThresh); + return M2M_ERR_FAIL; + } + + return M2M_SUCCESS; +} + +int8_t m2m_wifi_send_crl(tstrTlsCrlInfo *pCRL) +{ + return winc_hif_send(M2M_REQ_GROUP_SSL, M2M_SSL_IND_CRL|M2M_REQ_DATA_PKT, NULL, 0, pCRL, sizeof(tstrTlsCrlInfo), 0); +} + +int8_t m2m_wifi_init_hold(void) +{ + if (WINC_DRV_SUCCESS != winc_drv_init(false)) + return M2M_ERR_FAIL; + + gu8WifiState = WIFI_STATE_INIT; + + return M2M_SUCCESS; +} + +int8_t m2m_wifi_init_start(tstrWifiInitParam *pWifiInitParam) +{ + tstrM2mRev strtmp; + int8_t s8Ret; + uint32_t u32DriverVerInfo = M2M_MAKE_VERSION_INFO(M2M_RELEASE_VERSION_MAJOR_NO,\ + M2M_RELEASE_VERSION_MINOR_NO, M2M_RELEASE_VERSION_PATCH_NO,\ + M2M_MIN_REQ_DRV_VERSION_MAJOR_NO, M2M_MIN_REQ_DRV_VERSION_MINOR_NO,\ + M2M_MIN_REQ_DRV_VERSION_PATCH_NO); + + if(pWifiInitParam == NULL) + return M2M_ERR_INVALID_ARG; + + gpfAppWifiCb = pWifiInitParam->pfAppWifiCb; + +#ifdef ETH_MODE + gpfAppEthCb = pWifiInitParam->strEthInitParam.pfAppEthCb; + gau8ethRcvBuf = pWifiInitParam->strEthInitParam.au8ethRcvBuf; + gu16ethRcvBufSize = pWifiInitParam->strEthInitParam.u16ethRcvBufSize; +#endif /* ETH_MODE */ + + gu8scanInProgress = 0; + /* Apply device specific initialization. */ + + /* u8WifiMode | u8BootATE | u8EthMode | u32StateRegVal + ---------------------------------------------------------------------- + M2M_WIFI_MODE_NORMAL | false | false | u32DriverVerInfo + M2M_WIFI_MODE_ATE_HIGH | true | false | NBIT20 + M2M_WIFI_MODE_ATE_LOW | true | false | 0 + M2M_WIFI_MODE_ETHERNET | false | true | u32DriverVerInfo + */ + +#ifdef ETH_MODE + if (WINC_DRV_SUCCESS != winc_drv_start(false, (pWifiInitParam->strEthInitParam.u8EthernetEnable == M2M_WIFI_MODE_ETHERNET) ? true : false, u32DriverVerInfo)) + return M2M_ERR_INIT; +#else + if (WINC_DRV_SUCCESS != winc_drv_start(false, false, u32DriverVerInfo)) + return M2M_ERR_INIT; +#endif + + WINC_LOG_INFO("DriverVerInfo: 0x%08" PRIx32, u32DriverVerInfo); + + gu8WifiState = WIFI_STATE_START; + + /* Initialize host interface module */ + if (M2M_SUCCESS != winc_hif_init()) + return M2M_ERR_INIT; + + s8Ret = m2m_wifi_get_firmware_version(&strtmp); + + WINC_LOG_INFO("Firmware ver : %u.%u.%u Svnrev %u", strtmp.u8FirmwareMajor, strtmp.u8FirmwareMinor, strtmp.u8FirmwarePatch,strtmp.u16FirmwareSvnNum); + WINC_LOG_INFO("Firmware Build %s Time %s",strtmp.BuildDate, strtmp.BuildTime); + WINC_LOG_INFO("Firmware Min driver ver : %u.%u.%u", strtmp.u8DriverMajor, strtmp.u8DriverMinor, strtmp.u8DriverPatch); + WINC_LOG_INFO("Driver ver: %u.%u.%u", M2M_RELEASE_VERSION_MAJOR_NO, M2M_RELEASE_VERSION_MINOR_NO, M2M_RELEASE_VERSION_PATCH_NO); + WINC_LOG_INFO("Driver built at %s\t%s", __DATE__, __TIME__); + + if(M2M_ERR_FW_VER_MISMATCH == s8Ret) + { + WINC_LOG_ERROR("Mismatch Firmware Version"); + } + + return s8Ret; +} + +int8_t m2m_wifi_init(tstrWifiInitParam *pWifiInitParam) +{ + int8_t ret = M2M_SUCCESS; + + ret = m2m_wifi_init_hold(); + if (ret == M2M_SUCCESS) + { + ret = m2m_wifi_init_start(pWifiInitParam); + } + return ret; +} + +int8_t m2m_wifi_deinit(void *pVArg) +{ + UNUSED_VAR(pVArg); + + gu8WifiState = WIFI_STATE_DEINIT; + winc_hif_deinit(); + + winc_drv_deinit(); + + return M2M_SUCCESS; +} + +int8_t m2m_wifi_handle_events(void *pVArg) +{ + UNUSED_VAR(pVArg); + + return winc_hif_handle_isr(); +} + +int8_t m2m_wifi_delete_sc(char *pcSsid, uint8_t u8SsidLen) +{ + UNUSED_VAR(pcSsid); + UNUSED_VAR(u8SsidLen); + + tstrM2mWifiApId strApId; + memset(&strApId, 0, sizeof(strApId)); + strApId.au8SSID[0] = 0xFF; // Special value used to cause firmware to delete all entries. + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQRSP_DELETE_APID, &strApId, sizeof(tstrM2mWifiApId)); +} + +int8_t m2m_wifi_default_connect(void) +{ + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_DEFAULT_CONNECT, NULL, 0); +} + +/*************************************************************************************************/ +/* WIFI CONNECT INTERNAL FUNCTIONS */ +/*************************************************************************************************/ +static int8_t m2m_wifi_connect_prepare_msg( + tenuCredStoreOption enuCredStoreOption, + tenuM2mSecType enuAuthType, + uint16_t u16AuthSize, + tstrNetworkId *pstrNetworkId, + tstrM2mWifiConnHdr *pstrWifiConn +) +{ + int8_t ret = M2M_ERR_FAIL; + uint16_t u16CredSize = sizeof(tstrM2mConnCredCmn) + u16AuthSize; + + /* Check application params. */ + if ( + (pstrNetworkId == NULL) + || (pstrNetworkId->pu8Ssid == NULL) + || (pstrNetworkId->u8SsidLen >= M2M_MAX_SSID_LEN) + ) + goto INVALID_ARG; + + if (pstrWifiConn != NULL) + { + tstrM2mConnCredHdr *pstrHdr = &pstrWifiConn->strConnCredHdr; + tstrM2mConnCredCmn *pstrCmn = &pstrWifiConn->strConnCredCmn; + + memset(pstrWifiConn, 0, sizeof(tstrM2mWifiConnHdr)); + + pstrHdr->u16CredSize = u16CredSize; + switch (enuCredStoreOption) + { + case WIFI_CRED_SAVE_ENCRYPTED: + pstrHdr->u8CredStoreFlags |= M2M_CRED_ENCRYPT_FLAG; + // intentional fall through... + case WIFI_CRED_SAVE_UNENCRYPTED: + pstrHdr->u8CredStoreFlags |= M2M_CRED_STORE_FLAG; + // intentional fall through... + case WIFI_CRED_DONTSAVE: + break; + default: + goto INVALID_ARG; + } + + if (pstrNetworkId->enuChannel == M2M_WIFI_CH_ALL) + pstrHdr->u8Channel = (uint8_t)(pstrNetworkId->enuChannel); + else if ((pstrNetworkId->enuChannel <= M2M_WIFI_CH_14) && (pstrNetworkId->enuChannel >= M2M_WIFI_CH_1)) + pstrHdr->u8Channel = (uint8_t)(pstrNetworkId->enuChannel) - 1; + else + goto INVALID_ARG; + + if ((enuAuthType == M2M_WIFI_SEC_INVALID) || (enuAuthType >= M2M_WIFI_NUM_AUTH_TYPES)) + goto INVALID_ARG; + pstrCmn->u8AuthType = (uint8_t)enuAuthType; + + pstrCmn->u8SsidLen = pstrNetworkId->u8SsidLen; + memcpy(pstrCmn->au8Ssid, pstrNetworkId->pu8Ssid, pstrNetworkId->u8SsidLen); + if (pstrNetworkId->pu8Bssid != NULL) + { + pstrCmn->u8Options = M2M_WIFI_CONN_BSSID_FLAG; + memcpy(pstrCmn->au8Bssid, pstrNetworkId->pu8Bssid, M2M_MAC_ADDRES_LEN); + } + /* Everything is ok, set return value. */ + ret = M2M_SUCCESS; + } + return ret; +INVALID_ARG: + return M2M_ERR_INVALID_ARG; +} + +/* Convert hexchar to value 0-15 */ +static uint8_t hexchar_2_val(uint8_t ch) +{ + ch -= 0x30; + if (ch <= 9) + return ch; + ch |= 0x20; + ch -= 0x31; + if (ch <= 5) + return ch + 10; + return 0xFF; +} + +/* Convert hexstring to bytes */ +static int8_t hexstr_2_bytes(uint8_t *pu8Out, uint8_t *pu8In, uint8_t u8SizeOut) +{ + while (u8SizeOut--) + { + uint8_t u8Out = hexchar_2_val(*pu8In++); + if (u8Out > 0xF) + return M2M_ERR_INVALID_ARG; + *pu8Out = u8Out * 0x10; + u8Out = hexchar_2_val(*pu8In++); + if (u8Out > 0xF) + return M2M_ERR_INVALID_ARG; + *pu8Out += u8Out; + pu8Out++; + } + return M2M_SUCCESS; +} + +/*************************************************************************************************/ +/* WIFI CONNECT APIS */ +/*************************************************************************************************/ +int8_t m2m_wifi_connect_open(tenuCredStoreOption enuCredStoreOption, tstrNetworkId *pstrNetworkId) +{ + int8_t ret = M2M_ERR_INVALID_ARG; + tstrM2mWifiConnHdr strConnHdr; + + ret = m2m_wifi_connect_prepare_msg(enuCredStoreOption, M2M_WIFI_SEC_OPEN, 0, pstrNetworkId, &strConnHdr); + if (ret == M2M_SUCCESS) + { + ret = winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN, &strConnHdr, sizeof(strConnHdr)); + } + return ret; +} + +int8_t m2m_wifi_connect_wep(tenuCredStoreOption enuCredStoreOption, tstrNetworkId *pstrNetworkId, tstrAuthWep *pstrAuthWep) +{ + int8_t ret = M2M_ERR_INVALID_ARG; + + if ( + (pstrAuthWep != NULL) && (pstrAuthWep->pu8WepKey != NULL) + && (pstrAuthWep->u8KeyIndx > 0) && (pstrAuthWep->u8KeyIndx <= WEP_KEY_MAX_INDEX) + && ((pstrAuthWep->u8KeySz == WEP_104_KEY_STRING_SIZE) || (pstrAuthWep->u8KeySz == WEP_40_KEY_STRING_SIZE)) + ) + { + tstrM2mWifiConnHdr strConnHdr; + + ret = m2m_wifi_connect_prepare_msg( enuCredStoreOption, + M2M_WIFI_SEC_WEP, + sizeof(tstrM2mWifiWep), + pstrNetworkId, + &strConnHdr); + + if (ret == M2M_SUCCESS) + { + tstrM2mWifiWep strWep; + + strWep.u8KeyIndex = pstrAuthWep->u8KeyIndx - 1; + strWep.u8KeyLen = pstrAuthWep->u8KeySz/2; + hexstr_2_bytes(strWep.au8WepKey, (pstrAuthWep->pu8WepKey), strWep.u8KeyLen); + + ret = winc_hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT, + &strConnHdr, sizeof(tstrM2mWifiConnHdr), + &strWep, sizeof(tstrM2mWifiWep), sizeof(tstrM2mWifiConnHdr)); + } + } + + return ret; +} + +int8_t m2m_wifi_connect_psk(tenuCredStoreOption enuCredStoreOption, tstrNetworkId *pstrNetworkId, tstrAuthPsk *pstrAuthPsk) +{ + int8_t ret = M2M_ERR_INVALID_ARG; + + if (pstrAuthPsk != NULL) + { + tstrM2mWifiConnHdr strConnHdr; + + ret = m2m_wifi_connect_prepare_msg( enuCredStoreOption, + M2M_WIFI_SEC_WPA_PSK, + sizeof(tstrM2mWifiPsk), + pstrNetworkId, + &strConnHdr); + + if (ret == M2M_SUCCESS) + { + tstrM2mWifiPsk strPsk; + + memset(&strPsk, 0, sizeof(tstrM2mWifiPsk)); + if (pstrAuthPsk->pu8Psk != NULL) + { + if (pstrAuthPsk->pu8Passphrase != NULL) + ret = M2M_ERR_INVALID_ARG; + else + { + strPsk.u8PassphraseLen = M2M_MAX_PSK_LEN-1; + /* Use hexstr_2_bytes to verify pu8Psk input. */ + if (M2M_SUCCESS != hexstr_2_bytes(strPsk.au8Passphrase, pstrAuthPsk->pu8Psk, strPsk.u8PassphraseLen/2)) + ret = M2M_ERR_INVALID_ARG; + memcpy(strPsk.au8Passphrase, pstrAuthPsk->pu8Psk, strPsk.u8PassphraseLen); + } + } + else if (pstrAuthPsk->pu8Passphrase != NULL) + { + if (pstrAuthPsk->u8PassphraseLen > M2M_MAX_PSK_LEN-1) + ret = M2M_ERR_INVALID_ARG; + else + { + strPsk.u8PassphraseLen = pstrAuthPsk->u8PassphraseLen; + memcpy(strPsk.au8Passphrase, pstrAuthPsk->pu8Passphrase, strPsk.u8PassphraseLen); + } + } + else + ret = M2M_ERR_INVALID_ARG; + if (ret == M2M_SUCCESS) + { + ret = winc_hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT, + &strConnHdr, sizeof(tstrM2mWifiConnHdr), + &strPsk, sizeof(tstrM2mWifiPsk), sizeof(tstrM2mWifiConnHdr)); + } + } + } + + return ret; +} + +int8_t m2m_wifi_connect_1x_mschap2(tenuCredStoreOption enuCredStoreOption, tstrNetworkId *pstrNetworkId, tstrAuth1xMschap2 *pstrAuth1xMschap2) +{ + int8_t ret = M2M_ERR_INVALID_ARG; + if (pstrAuth1xMschap2 != NULL) + { + if (pstrAuth1xMschap2->pu8Domain == NULL) + pstrAuth1xMschap2->u16DomainLen = 0; + if ( + (pstrAuth1xMschap2->pu8UserName != NULL) + && (pstrAuth1xMschap2->pu8Password != NULL) + && ((uint32_t)(pstrAuth1xMschap2->u16DomainLen) + pstrAuth1xMschap2->u16UserNameLen <= M2M_AUTH_1X_USER_LEN_MAX) + && (pstrAuth1xMschap2->u16PasswordLen <= M2M_AUTH_1X_PASSWORD_LEN_MAX) + ) + { + tstrM2mWifiConnHdr strConnHdr; + uint16_t u16AuthSize = sizeof(tstrM2mWifi1xHdr) + + pstrAuth1xMschap2->u16DomainLen + + pstrAuth1xMschap2->u16UserNameLen + + pstrAuth1xMschap2->u16PasswordLen; + + ret = m2m_wifi_connect_prepare_msg( enuCredStoreOption, M2M_WIFI_SEC_802_1X, u16AuthSize, pstrNetworkId, &strConnHdr); + + if (ret == M2M_SUCCESS) + { + tstrM2mWifi1xHdr str1xHdr; + uint8_t *pu8AuthPtr = str1xHdr.au81xAuthDetails; + + memset(&str1xHdr, 0, u16AuthSize); + + str1xHdr.u8Flags = M2M_802_1X_MSCHAP2_FLAG; + if (pstrAuth1xMschap2->bUnencryptedUserName == true) + str1xHdr.u8Flags |= M2M_802_1X_UNENCRYPTED_USERNAME_FLAG; + if (pstrAuth1xMschap2->bPrependDomain == true) + str1xHdr.u8Flags |= M2M_802_1X_PREPEND_DOMAIN_FLAG; + + str1xHdr.u8DomainLength = 0; + if (pstrAuth1xMschap2->pu8Domain != NULL) + { + str1xHdr.u8DomainLength = (uint8_t)(pstrAuth1xMschap2->u16DomainLen); + memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8Domain, str1xHdr.u8DomainLength); + pu8AuthPtr += str1xHdr.u8DomainLength; + } + + str1xHdr.u16UserNameLength = (pstrAuth1xMschap2->u16UserNameLen); + memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8UserName, str1xHdr.u16UserNameLength); + pu8AuthPtr += str1xHdr.u16UserNameLength; + + str1xHdr.u16PrivateKeyOffset = (uint16_t)(pu8AuthPtr - str1xHdr.au81xAuthDetails); + str1xHdr.u16PrivateKeyLength = pstrAuth1xMschap2->u16PasswordLen; + memcpy(pu8AuthPtr, pstrAuth1xMschap2->pu8Password, str1xHdr.u16PrivateKeyLength); + + ret = winc_hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT, + &strConnHdr, sizeof(tstrM2mWifiConnHdr), + &str1xHdr, u16AuthSize, + sizeof(tstrM2mWifiConnHdr)); + } + } + } + return ret; +} + +int8_t m2m_wifi_connect_1x_tls(tenuCredStoreOption enuCredStoreOption, tstrNetworkId *pstrNetworkId, tstrAuth1xTls *pstrAuth1xTls) +{ + int8_t ret = M2M_ERR_INVALID_ARG; + if (pstrAuth1xTls != NULL) + { + if (pstrAuth1xTls->pu8Domain == NULL) + pstrAuth1xTls->u16DomainLen = 0; + if ( + (pstrAuth1xTls->pu8UserName != NULL) + && (pstrAuth1xTls->pu8PrivateKey_Mod != NULL) + && (pstrAuth1xTls->pu8PrivateKey_Exp != NULL) + && (pstrAuth1xTls->pu8Certificate != NULL) + && ((uint32_t)(pstrAuth1xTls->u16DomainLen) + pstrAuth1xTls->u16UserNameLen <= M2M_AUTH_1X_USER_LEN_MAX) + && (pstrAuth1xTls->u16PrivateKeyLen <= M2M_AUTH_1X_PRIVATEKEY_LEN_MAX) + && (pstrAuth1xTls->u16CertificateLen <= M2M_AUTH_1X_CERT_LEN_MAX) + ) + { + tstrM2mWifiConnHdr strConnHdr; + uint16_t u16AuthSize = sizeof(tstrM2mWifi1xHdr) + + pstrAuth1xTls->u16DomainLen + + pstrAuth1xTls->u16UserNameLen + + (2 * pstrAuth1xTls->u16PrivateKeyLen) + + pstrAuth1xTls->u16CertificateLen; + + ret = m2m_wifi_connect_prepare_msg( enuCredStoreOption, + M2M_WIFI_SEC_802_1X, + u16AuthSize, + pstrNetworkId, + &strConnHdr); + + if (ret == M2M_SUCCESS) + { + uint16_t u16Payload1Size = u16AuthSize - pstrAuth1xTls->u16CertificateLen; + tstrM2mWifi1xHdr str1xHdr; + tstrM2mWifiAuthInfoHdr strInfoHdr = {0}; + uint8_t *pu8AuthPtr = str1xHdr.au81xAuthDetails; + + memset(&str1xHdr, 0, u16Payload1Size); + + str1xHdr.u8Flags = M2M_802_1X_TLS_FLAG; + if (pstrAuth1xTls->bUnencryptedUserName == true) + str1xHdr.u8Flags |= M2M_802_1X_UNENCRYPTED_USERNAME_FLAG; + if (pstrAuth1xTls->bPrependDomain == true) + str1xHdr.u8Flags |= M2M_802_1X_PREPEND_DOMAIN_FLAG; + + str1xHdr.u8DomainLength = 0; + if (pstrAuth1xTls->pu8Domain != NULL) + { + str1xHdr.u8DomainLength = (uint8_t)(pstrAuth1xTls->u16DomainLen); + memcpy(pu8AuthPtr, pstrAuth1xTls->pu8Domain, str1xHdr.u8DomainLength); + pu8AuthPtr += str1xHdr.u8DomainLength; + } + + str1xHdr.u16UserNameLength = (pstrAuth1xTls->u16UserNameLen); + memcpy(pu8AuthPtr, pstrAuth1xTls->pu8UserName, str1xHdr.u16UserNameLength); + pu8AuthPtr += str1xHdr.u16UserNameLength; + + str1xHdr.u16PrivateKeyOffset = (uint16_t)(pu8AuthPtr - str1xHdr.au81xAuthDetails); + str1xHdr.u16PrivateKeyLength = pstrAuth1xTls->u16PrivateKeyLen; + memcpy(pu8AuthPtr, pstrAuth1xTls->pu8PrivateKey_Mod, str1xHdr.u16PrivateKeyLength); + pu8AuthPtr += str1xHdr.u16PrivateKeyLength; + memcpy(pu8AuthPtr, pstrAuth1xTls->pu8PrivateKey_Exp, str1xHdr.u16PrivateKeyLength); + pu8AuthPtr += str1xHdr.u16PrivateKeyLength; + + str1xHdr.u16CertificateOffset = (uint16_t)(pu8AuthPtr - str1xHdr.au81xAuthDetails); + str1xHdr.u16CertificateLength = pstrAuth1xTls->u16CertificateLen; + + strInfoHdr.u8Type = M2M_802_1X_TLS_CLIENT_CERTIFICATE; + strInfoHdr.u16InfoPos = str1xHdr.u16CertificateOffset; + strInfoHdr.u16InfoLen = str1xHdr.u16CertificateLength; + ret = winc_hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_IND_CONN_PARAM | M2M_REQ_DATA_PKT, + &strInfoHdr, sizeof(tstrM2mWifiAuthInfoHdr), + pstrAuth1xTls->pu8Certificate, pstrAuth1xTls->u16CertificateLen, + sizeof(tstrM2mWifiAuthInfoHdr)); + + if (ret == M2M_SUCCESS) + { + ret = winc_hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONN | M2M_REQ_DATA_PKT, + &strConnHdr, sizeof(tstrM2mWifiConnHdr), + &str1xHdr, u16Payload1Size, + sizeof(tstrM2mWifiConnHdr)); + } + } + } + } + return ret; +} + +int8_t m2m_wifi_connect(char *pcSsid, uint8_t u8SsidLen, uint8_t u8SecType, void *pvAuthInfo, uint16_t u16Ch) +{ + return m2m_wifi_connect_sc(pcSsid, u8SsidLen, u8SecType, pvAuthInfo, u16Ch, 0); +} + +int8_t m2m_wifi_connect_sc(char *pcSsid, uint8_t u8SsidLen, uint8_t u8SecType, void *pvAuthInfo, uint16_t u16Ch, uint8_t u8NoSaveCred) +{ + int8_t s8Ret = M2M_ERR_INVALID_ARG; + tstrNetworkId strNetworkId = {NULL, (uint8_t*)pcSsid, u8SsidLen, (tenuM2mScanCh)u16Ch}; + tenuCredStoreOption enuCredStoreOption = u8NoSaveCred ? WIFI_CRED_DONTSAVE : WIFI_CRED_SAVE_ENCRYPTED; + + /* This API does not support SSIDs which contain '\0'. If there is a '\0' character within the + * first u8SsidLen characters, then assume that the input u8SsidLen was incorrect - set length + * to strlen(pcSsid) and continue. This is to avoid a change from the behavior of previously + * released drivers. */ + if (u8SsidLen < M2M_MAX_SSID_LEN) + while (u8SsidLen--) + if (strNetworkId.pu8Ssid[u8SsidLen] == 0) + strNetworkId.u8SsidLen = u8SsidLen; + + switch ((tenuM2mSecType)u8SecType) + { + case M2M_WIFI_SEC_OPEN: + s8Ret = m2m_wifi_connect_open(enuCredStoreOption, &strNetworkId); + break; + case M2M_WIFI_SEC_WPA_PSK: + if (pvAuthInfo != NULL) + { + tstrAuthPsk strAuthPsk = {NULL, NULL, 0}; + uint16_t len = (uint16_t)strlen((const char*)pvAuthInfo); + + if (len == M2M_MAX_PSK_LEN-1) + { + strAuthPsk.pu8Psk = (uint8_t*)pvAuthInfo; + } + else + { + strAuthPsk.pu8Passphrase = (uint8_t*)pvAuthInfo; + strAuthPsk.u8PassphraseLen = (uint8_t)len; + } + s8Ret = m2m_wifi_connect_psk(enuCredStoreOption, &strNetworkId, &strAuthPsk); + } + break; + case M2M_WIFI_SEC_WEP: + if (pvAuthInfo != NULL) + { + tstrM2mWifiWepParams *pstrWepParams = (tstrM2mWifiWepParams*)pvAuthInfo; + tstrAuthWep strAuthWep = {pstrWepParams->au8WepKey, pstrWepParams->u8KeySz-1, pstrWepParams->u8KeyIndx}; + + s8Ret = m2m_wifi_connect_wep(enuCredStoreOption, &strNetworkId, &strAuthWep); + } + break; + case M2M_WIFI_SEC_802_1X: + if (pvAuthInfo != NULL) + { + tstr1xAuthCredentials *pstr1xParams = (tstr1xAuthCredentials*)pvAuthInfo; + tstrAuth1xMschap2 strAuth1xMschap2 = {NULL, + pstr1xParams->au8UserName, + pstr1xParams->au8Passwd, + 0, + (uint16_t)strlen((const char*)pstr1xParams->au8UserName), + (uint16_t)strlen((const char*)pstr1xParams->au8Passwd), + false, + false}; + + s8Ret = m2m_wifi_connect_1x_mschap2(enuCredStoreOption, &strNetworkId, &strAuth1xMschap2); + } + break; + default: + break; + } + return s8Ret; +} + +int8_t m2m_wifi_disconnect(void) +{ + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_DISCONNECT, NULL, 0); +} + +int8_t m2m_wifi_set_mac_address(uint8_t au8MacAddress[6]) +{ + tstrM2mSetMacAddress strTmp; + memcpy(strTmp.au8Mac, au8MacAddress, 6); + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_MAC_ADDRESS, &strTmp, sizeof(tstrM2mSetMacAddress)); +} + +int8_t m2m_wifi_set_static_ip(tstrM2MIPConfig *pstrStaticIPConf) +{ + pstrStaticIPConf->u32DNS = HOST_TO_WINC_U32(pstrStaticIPConf->u32DNS); + pstrStaticIPConf->u32Gateway = HOST_TO_WINC_U32(pstrStaticIPConf->u32Gateway); + pstrStaticIPConf->u32StaticIP = HOST_TO_WINC_U32( + pstrStaticIPConf->u32StaticIP); + pstrStaticIPConf->u32SubnetMask = HOST_TO_WINC_U32( + pstrStaticIPConf->u32SubnetMask); + return winc_hif_send_no_data(M2M_REQ_GROUP_IP, M2M_IP_REQ_STATIC_IP_CONF, pstrStaticIPConf, sizeof(tstrM2MIPConfig)); +} + +int8_t m2m_wifi_enable_dhcp(uint8_t u8DhcpEn) +{ + uint8_t u8Req; + u8Req = u8DhcpEn ? M2M_IP_REQ_ENABLE_DHCP : M2M_IP_REQ_DISABLE_DHCP; + return winc_hif_send_no_data(M2M_REQ_GROUP_IP, u8Req, NULL, 0); +} + +int8_t m2m_wifi_set_lsn_int(tstrM2mLsnInt *pstrM2mLsnInt) +{ + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_LSN_INT, pstrM2mLsnInt, sizeof(tstrM2mLsnInt)); +} + +int8_t m2m_wifi_set_cust_InfoElement(uint8_t *pau8M2mCustInfoElement) +{ + int8_t ret = M2M_ERR_FAIL; + if(pau8M2mCustInfoElement != NULL) + { + if((pau8M2mCustInfoElement[0] + 1) < M2M_CUST_IE_LEN_MAX) + { + ret = winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CUST_INFO_ELEMENT|M2M_REQ_DATA_PKT, pau8M2mCustInfoElement, pau8M2mCustInfoElement[0]+1); + } + } + return ret; +} + +int8_t m2m_wifi_set_scan_options(tstrM2MScanOption *ptstrM2MScanOption) +{ + int8_t s8Ret = M2M_ERR_FAIL; + if (m2m_validate_scan_options(ptstrM2MScanOption) == M2M_SUCCESS) + { + s8Ret = winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_SCAN_OPTION, ptstrM2MScanOption, sizeof(tstrM2MScanOption)); + } + return s8Ret; +} + +int8_t m2m_wifi_set_scan_region(uint16_t u16ScanRegion) +{ + tstrM2MScanRegion strScanRegion; + + strScanRegion.u16ScanRegion = u16ScanRegion; + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_SCAN_REGION, &strScanRegion, sizeof(tstrM2MScanRegion)); +} + +int8_t m2m_wifi_request_scan(uint8_t u8Ch) +{ + int8_t s8Ret = M2M_SUCCESS; + + if(!gu8scanInProgress) + { + if(((u8Ch >= M2M_WIFI_CH_1) && (u8Ch <= M2M_WIFI_CH_14)) || (u8Ch == M2M_WIFI_CH_ALL)) + { + tstrM2MScan strtmp; + strtmp.u8ChNum = u8Ch; + s8Ret = winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SCAN, &strtmp, sizeof(tstrM2MScan)); + if(s8Ret == M2M_SUCCESS) + { + gu8scanInProgress = 1; + } + } + else + { + s8Ret = M2M_ERR_INVALID_ARG; + } + } + else + { + s8Ret = M2M_ERR_SCAN_IN_PROGRESS; + } + + return s8Ret; +} + +int8_t m2m_wifi_request_scan_passive(uint8_t u8Ch, uint16_t u16ScanTime) +{ + int8_t s8Ret = M2M_SUCCESS; + + if(!gu8scanInProgress) + { + if(((u8Ch >= M2M_WIFI_CH_1) && (u8Ch <= M2M_WIFI_CH_14)) || (u8Ch == M2M_WIFI_CH_ALL)) + { + tstrM2MScan strtmp; + strtmp.u8ChNum = u8Ch; + + strtmp.u16PassiveScanTime = u16ScanTime; + + s8Ret = winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_PASSIVE_SCAN, &strtmp, sizeof(tstrM2MScan)); + if(s8Ret == M2M_SUCCESS) + { + gu8scanInProgress = 1; + } + } + else + { + s8Ret = M2M_ERR_INVALID_ARG; + } + } + else + { + s8Ret = M2M_ERR_SCAN_IN_PROGRESS; + } + + return s8Ret; +} + +int8_t m2m_wifi_request_scan_ssid_list(uint8_t u8Ch, uint8_t *pu8Ssidlist) +{ + int8_t s8Ret = M2M_ERR_INVALID_ARG; + + if(!gu8scanInProgress) + { + if((((u8Ch >= M2M_WIFI_CH_1) && (u8Ch <= M2M_WIFI_CH_14)) || (u8Ch == M2M_WIFI_CH_ALL))&&(pu8Ssidlist != NULL)) + { + tstrM2MScan strtmp; + uint16_t u16Lsize = 0; + uint8_t u8Apnum = pu8Ssidlist[u16Lsize]; + if(u8Apnum <= MAX_HIDDEN_SITES) + { + u16Lsize++; + while(u8Apnum) + { + if(pu8Ssidlist[u16Lsize] >= M2M_MAX_SSID_LEN){ + goto EXIT; + }else { + u16Lsize += pu8Ssidlist[u16Lsize] + 1; + u8Apnum--; + } + } + strtmp.u8ChNum = u8Ch; + s8Ret = winc_hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SCAN_SSID_LIST|M2M_REQ_DATA_PKT, &strtmp, sizeof(tstrM2MScan), pu8Ssidlist, u16Lsize, sizeof(tstrM2MScan)); + if(s8Ret == M2M_SUCCESS) + { + gu8scanInProgress = 1; + } + } + } + } + else + { + s8Ret = M2M_ERR_SCAN_IN_PROGRESS; + } +EXIT: + return s8Ret; +} + +int8_t m2m_wifi_wps(uint8_t u8TriggerType, const char *pcPinNumber) +{ + tstrM2MWPSConnect strtmp; + + /* Stop Scan if it is ongoing. + */ + gu8scanInProgress = 0; + strtmp.u8TriggerType = u8TriggerType; + + /*If WPS is using PIN METHOD*/ + if (u8TriggerType == WPS_PIN_TRIGGER) + memcpy(strtmp.acPinNumber, pcPinNumber, 8); + + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_WPS, &strtmp, sizeof(tstrM2MWPSConnect)); +} + +int8_t m2m_wifi_wps_disable(void) +{ + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_DISABLE_WPS, NULL, 0); +} + +int8_t m2m_wifi_req_client_ctrl(uint8_t u8Cmd) +{ +#ifdef _PS_SERVER_ + tstrM2Mservercmd strCmd; + + strCmd.u8cmd = u8Cmd; + + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CLIENT_CTRL, &strCmd, sizeof(tstrM2Mservercmd)); +#else + UNUSED_VAR(u8Cmd); + WINC_LOG_ERROR("_PS_SERVER_ is not defined"); + + return M2M_ERR_FAIL; +#endif +} + +int8_t m2m_wifi_req_server_init(uint8_t u8Ch) +{ +#ifdef _PS_SERVER_ + tstrM2mServerInit strServer; + + strServer.u8Channel = u8Ch; + + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SERVER_INIT, &strServer, sizeof(tstrM2mServerInit)); +#else + UNUSED_VAR(u8Ch); + WINC_LOG_ERROR("_PS_SERVER_ is not defined"); + + return M2M_ERR_FAIL; +#endif +} + +int8_t m2m_wifi_p2p(uint8_t u8Channel) +{ + if((u8Channel == M2M_WIFI_CH_1) || (u8Channel == M2M_WIFI_CH_6) || (u8Channel == M2M_WIFI_CH_11)) + { + tstrM2MP2PConnect strtmp; + + strtmp.u8ListenChannel = u8Channel; + + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_ENABLE_P2P, &strtmp, sizeof(tstrM2MP2PConnect)); + } + else + { + WINC_LOG_ERROR("Listen channel should only be M2M_WIFI_CH_1/6/11"); + return M2M_ERR_FAIL; + } +} + +int8_t m2m_wifi_p2p_disconnect(void) +{ + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_DISABLE_P2P, NULL, 0); +} + +int8_t m2m_wifi_enable_ap(const tstrM2MAPConfig *pstrM2MAPConfig) +{ + tstrM2MAPModeConfig strM2MAPModeConfig; + + memcpy(&strM2MAPModeConfig.strApConfig, pstrM2MAPConfig, sizeof(tstrM2MAPConfig)); + + memcpy(strM2MAPModeConfig.strApConfigExt.au8DefRouterIP, pstrM2MAPConfig->au8DHCPServerIP, 4); + memcpy(strM2MAPModeConfig.strApConfigExt.au8DNSServerIP, pstrM2MAPConfig->au8DHCPServerIP, 4); + + strM2MAPModeConfig.strApConfigExt.au8SubnetMask[0] = 0; + + return m2m_wifi_enable_ap_ext(&strM2MAPModeConfig); +} + +int8_t m2m_wifi_enable_ap_ext(const tstrM2MAPModeConfig *pstrM2MAPModeConfig) +{ + int8_t ret = M2M_ERR_FAIL; + if(M2M_SUCCESS == m2m_validate_ap_parameters(pstrM2MAPModeConfig)) + { + ret = winc_hif_send(M2M_REQ_GROUP_WIFI, (M2M_REQ_DATA_PKT|M2M_WIFI_REQ_ENABLE_AP), NULL, 0, pstrM2MAPModeConfig, sizeof(tstrM2MAPModeConfig), 0); + } + return ret; +} + +int8_t m2m_wifi_set_gains(tstrM2mWifiGainsParams *pstrM2mGain) +{ + int8_t ret = M2M_ERR_FAIL; + if(pstrM2mGain != NULL) + { + ret = winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_GAINS, pstrM2mGain, sizeof(tstrM2mWifiGainsParams)); + } + return ret; +} + +int8_t m2m_wifi_disable_ap(void) +{ + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_DISABLE_AP, NULL, 0); +} + +int8_t m2m_wifi_req_curr_rssi(void) +{ + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CURRENT_RSSI, NULL, 0); +} + +int8_t m2m_wifi_send_ethernet_pkt(uint8_t *pu8Packet, uint16_t u16PacketSize) +{ + int8_t s8Ret = -1; + if((pu8Packet != NULL)&&(u16PacketSize>0)) + { + tstrM2MWifiTxPacketInfo strTxPkt; + + strTxPkt.u16PacketSize = u16PacketSize; + strTxPkt.u16HeaderLength = M2M_ETHERNET_HDR_LEN; + s8Ret = winc_hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SEND_ETHERNET_PACKET | M2M_REQ_DATA_PKT, + &strTxPkt, sizeof(tstrM2MWifiTxPacketInfo), pu8Packet, u16PacketSize, M2M_ETHERNET_HDR_OFFSET - M2M_HIF_HDR_OFFSET); + } + return s8Ret; +} + +int8_t m2m_wifi_get_otp_mac_address(uint8_t *pu8MacAddr, uint8_t *pu8IsValid) +{ + uint8_t u8IsValid = 0; + + if (M2M_SUCCESS != winc_hif_chip_wake()) + return M2M_ERR_FAIL; + + if (winc_chip_get_otp_mac_address(pu8MacAddr)) + u8IsValid = 1; + + if (M2M_SUCCESS != winc_hif_chip_sleep()) + return M2M_ERR_FAIL; + + if (pu8IsValid) + *pu8IsValid = u8IsValid; + + return M2M_SUCCESS; +} + +int8_t m2m_wifi_get_mac_address(uint8_t *pu8MacAddr) +{ + if (M2M_SUCCESS != winc_hif_chip_wake()) + return M2M_ERR_FAIL; + + if (!winc_chip_get_mac_address(pu8MacAddr)) + return M2M_ERR_FAIL; + + return winc_hif_chip_sleep(); +} + +int8_t m2m_wifi_req_scan_result(uint8_t u8Index) +{ + tstrM2mReqScanResult strReqScanRlt; + + strReqScanRlt.u8Index = u8Index; + + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SCAN_RESULT, &strReqScanRlt, sizeof(tstrM2mReqScanResult)); +} + +uint8_t m2m_wifi_get_num_ap_found(void) +{ + return gu8ChNum; +} + +uint8_t m2m_wifi_get_sleep_mode(void) +{ + return (uint8_t)genuPsMode; +} + +int8_t m2m_wifi_set_sleep_mode(uint8_t u8PsTyp, uint8_t u8BcastEn) +{ + int8_t ret = M2M_SUCCESS; + tstrM2mPsType strPs; + strPs.u8PsType = u8PsTyp; + strPs.u8BcastEn = u8BcastEn; + ret = winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SLEEP, &strPs, sizeof(tstrM2mPsType)); + WINC_LOG_INFO("POWER SAVE %u", u8PsTyp); + genuPsMode = u8PsTyp; + winc_hif_set_power_save((u8PsTyp != M2M_NO_PS)?true:false); + return ret; +} + +int8_t m2m_wifi_request_sleep(uint32_t u32SlpReqTime) +{ + int8_t ret = M2M_SUCCESS; + + if(genuPsMode == M2M_PS_MANUAL) + { + tstrM2mSlpReqTime strPs; + strPs.u32SleepTime = u32SlpReqTime; + ret = winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_DOZE, &strPs, sizeof(tstrM2mSlpReqTime)); + } + return ret; +} + +int8_t m2m_wifi_set_device_name(uint8_t *pu8DeviceName, uint8_t u8DeviceNameLength) +{ + tstrM2MDeviceNameConfig strDeviceName; + + u8DeviceNameLength++; + + if(u8DeviceNameLength >= M2M_DEVICE_NAME_MAX) + { + u8DeviceNameLength = M2M_DEVICE_NAME_MAX; + } + + memcpy(strDeviceName.au8DeviceName, pu8DeviceName, u8DeviceNameLength); + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_DEVICE_NAME, &strDeviceName, sizeof(tstrM2MDeviceNameConfig)); +} + +int8_t m2m_wifi_configure_sntp(uint8_t *pu8NTPServerName, uint8_t u8NTPServerNameLength, tenuSNTPUseDHCP enuUseDHCP) +{ + tstrM2MSNTPConfig strSNTPConfig; + if(u8NTPServerNameLength > M2M_NTP_MAX_SERVER_NAME_LENGTH) + return M2M_ERR_FAIL; + + memcpy(strSNTPConfig.acNTPServer, pu8NTPServerName, u8NTPServerNameLength); + strSNTPConfig.acNTPServer[u8NTPServerNameLength] = '\0'; + strSNTPConfig.enuUseDHCP = (uint8_t)enuUseDHCP; + + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONFIG_SNTP, &strSNTPConfig, sizeof(tstrM2MSNTPConfig)); +} + +int8_t m2m_wifi_get_firmware_version(tstrM2mRev *pstrRev) +{ + int8_t ret; + + ret = winc_hif_chip_wake(); + if(ret != M2M_SUCCESS) + return ret; + + ret = m2m_fwinfo_get_firmware_info(true, pstrRev); + winc_hif_chip_sleep(); + + if(ret != M2M_SUCCESS) + return ret; + + return m2m_fwinfo_version_check(pstrRev); +} + +int8_t m2m_wifi_start_provision_mode(tstrM2MAPConfig *pstrM2MAPConfig, char *pcHttpServerDomainName, uint8_t bEnableHttpRedirect) +{ + tstrM2MAPModeConfig strM2MAPModeConfig; + + memcpy(&strM2MAPModeConfig.strApConfig, pstrM2MAPConfig, sizeof(tstrM2MAPConfig)); + + memcpy(strM2MAPModeConfig.strApConfigExt.au8DefRouterIP, pstrM2MAPConfig->au8DHCPServerIP, 4); + memcpy(strM2MAPModeConfig.strApConfigExt.au8DNSServerIP, pstrM2MAPConfig->au8DHCPServerIP, 4); + + strM2MAPModeConfig.strApConfigExt.au8SubnetMask[0] = 0; + + return m2m_wifi_start_provision_mode_ext(&strM2MAPModeConfig, pcHttpServerDomainName, bEnableHttpRedirect); +} + +int8_t m2m_wifi_start_provision_mode_ext(tstrM2MAPModeConfig *pstrAPModeConfig, char *pcHttpServerDomainName, uint8_t bEnableHttpRedirect) +{ + int8_t s8Ret = M2M_ERR_FAIL; + + if(pstrAPModeConfig != NULL) + { + tstrM2MProvisionModeConfig strProvConfig; + if(M2M_SUCCESS == m2m_validate_ap_parameters(pstrAPModeConfig)) + { + memcpy(&strProvConfig.strApConfig, &pstrAPModeConfig->strApConfig, sizeof(tstrM2MAPConfig)); + memcpy(&strProvConfig.strApConfigExt, &pstrAPModeConfig->strApConfigExt, sizeof(tstrM2MAPConfigExt)); + if((strlen((const char*)pcHttpServerDomainName) <= 0) || (NULL == pcHttpServerDomainName)) + { + WINC_LOG_ERROR("INVALID DOMAIN NAME"); + goto ERR1; + } + memcpy(strProvConfig.acHttpServerDomainName, pcHttpServerDomainName, 64); + strProvConfig.u8EnableRedirect = bEnableHttpRedirect; + + /* Stop Scan if it is ongoing. + */ + gu8scanInProgress = 0; + s8Ret = winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_START_PROVISION_MODE | M2M_REQ_DATA_PKT, + &strProvConfig, sizeof(tstrM2MProvisionModeConfig)); + } + else + { + /*goto ERR1;*/ + } + } +ERR1: + return s8Ret; +} + +int8_t m2m_wifi_stop_provision_mode(void) +{ + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_STOP_PROVISION_MODE, NULL, 0); +} + +int8_t m2m_wifi_get_connection_info(void) +{ + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_GET_CONN_INFO, NULL, 0); +} + +int8_t m2m_wifi_set_system_time(uint32_t u32UTCSeconds) +{ + /* + The firmware accepts timestamps relative to 1900 like NTP Timestamp. + */ + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_SYS_TIME, &u32UTCSeconds, sizeof(tstrSystemTime)); +} + +int8_t m2m_wifi_get_system_time(void) +{ + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_GET_SYS_TIME, NULL, 0); +} + +int8_t m2m_wifi_enable_sntp(uint8_t u8Enable) +{ + uint8_t u8Req; + + u8Req = u8Enable ? M2M_WIFI_REQ_ENABLE_SNTP_CLIENT : M2M_WIFI_REQ_DISABLE_SNTP_CLIENT; + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, u8Req, NULL, 0); +} + +int8_t m2m_wifi_set_power_profile(uint8_t u8PwrMode) +{ + tstrM2mPwrMode strM2mPwrMode; + + strM2mPwrMode.u8PwrMode = u8PwrMode; + + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_POWER_PROFILE, &strM2mPwrMode, sizeof(tstrM2mPwrMode)); +} + +int8_t m2m_wifi_set_tx_power(uint8_t u8TxPwrLevel) +{ + tstrM2mTxPwrLevel strM2mTxPwrLevel; + + strM2mTxPwrLevel.u8TxPwrLevel = u8TxPwrLevel; + + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_TX_POWER, &strM2mTxPwrLevel, sizeof(tstrM2mTxPwrLevel)); +} + +int8_t m2m_wifi_set_gain_table_idx(uint8_t u8GainTableIdx) +{ + tstrM2mWiFiGainIdx strM2mGainTableIdx; + + strM2mGainTableIdx.u8GainTableIdx = u8GainTableIdx; + + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_GAIN_TABLE_IDX, &strM2mGainTableIdx, sizeof(tstrM2mWiFiGainIdx)); +} + +int8_t m2m_wifi_enable_firmware_logs(uint8_t u8Enable) +{ + tstrM2mEnableLogs strM2mEnableLogs; + + strM2mEnableLogs.u8Enable = u8Enable; + + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_ENABLE_LOGS, &strM2mEnableLogs, sizeof(tstrM2mEnableLogs)); +} + +int8_t m2m_wifi_set_battery_voltage(uint16_t u16BattVoltx100) +{ + tstrM2mBatteryVoltage strM2mBattVol = {0}; + + strM2mBattVol.u16BattVolt = u16BattVoltx100; + + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_BATTERY_VOLTAGE, &strM2mBattVol, sizeof(tstrM2mBatteryVoltage)); +} + +int8_t m2m_wifi_prng_get_random_bytes(uint8_t *pu8PrngBuff, uint16_t u16PrngSize) +{ + tstrPrng strRng = {0}; + + if ((u16PrngSize < (M2M_BUFFER_MAX_SIZE - sizeof(tstrPrng))) && (pu8PrngBuff != NULL)) + { + strRng.u16PrngSize = u16PrngSize; + strRng.pu8RngBuff = pu8PrngBuff; + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_GET_PRNG|M2M_REQ_DATA_PKT, &strRng, sizeof(tstrPrng)); + } + + WINC_LOG_ERROR("PRNG Buffer exceeded maximum size %u or NULL Buffer", u16PrngSize); + + return M2M_ERR_FAIL; +} + +int8_t m2m_wifi_conf_auto_rate(tstrConfAutoRate *pstrConfAutoRate) +{ + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONG_AUTO_RATE, pstrConfAutoRate, sizeof(tstrConfAutoRate)); +} + +#ifdef ETH_MODE +int8_t m2m_wifi_enable_mac_mcast(uint8_t *pu8MulticastMacAddress, uint8_t u8AddRemove) +{ + tstrM2MMulticastMac strMulticastMac; + + if (pu8MulticastMacAddress == NULL) + return M2M_ERR_FAIL; + + strMulticastMac.u8AddRemove = u8AddRemove; + + memcpy(strMulticastMac.au8macaddress, pu8MulticastMacAddress, M2M_MAC_ADDRES_LEN); + + WINC_LOG_DEBUG("mac multicast: %x:%x:%x:%x:%x:%x", strMulticastMac.au8macaddress[0], strMulticastMac.au8macaddress[1], strMulticastMac.au8macaddress[2], + strMulticastMac.au8macaddress[3], strMulticastMac.au8macaddress[4], strMulticastMac.au8macaddress[5]); + + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_MAC_MCAST, &strMulticastMac, sizeof(tstrM2MMulticastMac)); +} + +int8_t m2m_wifi_set_receive_buffer(void *pvBuffer, uint16_t u16BufferLen) +{ + if (pvBuffer == NULL) + { + WINC_LOG_ERROR("Buffer NULL pointer"); + return M2M_ERR_FAIL; + } + + gau8ethRcvBuf = pvBuffer; + gu16ethRcvBufSize= u16BufferLen; + + return M2M_SUCCESS; +} +#endif /* ETH_MODE */ + +uint8_t m2m_wifi_get_state(void) +{ + return gu8WifiState; +} + +int8_t m2m_wifi_enable_roaming(uint8_t u8EnableDhcp) +{ + tstrM2mWiFiRoaming strWiFiRoaming; + strWiFiRoaming.u8EnableRoaming = 1; + + if (u8EnableDhcp > 1) + return M2M_ERR_INVALID_ARG; + + strWiFiRoaming.u8EnableDhcp = u8EnableDhcp; + + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_ROAMING, &strWiFiRoaming, sizeof(tstrM2mWiFiRoaming)); +} + +int8_t m2m_wifi_disable_roaming(void) +{ + tstrM2mWiFiRoaming strWiFiRoaming; + + strWiFiRoaming.u8EnableRoaming = 0; + + return winc_hif_send_no_data(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_ROAMING, &strWiFiRoaming, sizeof(tstrM2mWiFiRoaming)); +} diff --git a/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_wifi.h b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_wifi.h new file mode 100644 index 0000000..4aded7d --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/m2m/m2m_wifi.h @@ -0,0 +1,2883 @@ +/** + * + * \file + * + * \brief WINC WLAN Application Interface. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +/** @defgroup m2m_wifi WLAN + @{ + @defgroup WLANCallbacks Callbacks + @brief + Provides detail on the available callbacks for the WLAN APIs. + + @defgroup WLANDefines Defines + @brief + Specifies the macros and defines used by the WLAN APIs. + + @defgroup WLANEnums Enumerations and Typedefs + @brief + Specifies the enums and Data Structures used by the WLAN APIs. + + @defgroup WLANAPI WLAN Functions + @brief + Here are listed all the functions that implement the WLAN APIs. + @{ + @defgroup WLANINIT Initialization + @brief + Here are listed all the functions that implement the WLAN Initialization APIs. + @defgroup WLANEVTS WLAN Events + @brief + Here are listed all the functions that implement the WLAN Events APIs. + @defgroup WLANCONNECT Connection + @brief + Here are listed all the functions that implement the Wi-Fi Connection APIs. + @defgroup WLANSCAN Scanning + @brief + Here are listed all the functions that implement the Wi-Fi Scanning APIs. + @defgroup WLANAP Hot-Spot (Access-Point) + @brief + Here are listed all the functions that implement the Wi-Fi Hot-Spot (Access-Point) APIs. + @defgroup WLANETH Bypass Mode + @brief + Here are listed all the functions that implement the Bypass Mode APIs. + @defgroup WLANROAMING Roaming + @brief + Here are listed all the functions that implement the Wi-Fi Roaming APIs. + @defgroup WLANPS Power Save + @brief + Here are listed all the functions that implement the Power-Save APIs. + @defgroup WLANCONF Configuration + @brief + Here are listed all the functions that implement the WLAN Configuration APIs. + @defgroup WLANTIME System Time + @brief + Here are listed all the functions that implement the System Time APIs. + @defgroup WLANPROVISION Provisioning + @brief + Here are listed all the functions that implement the Wi-Fi Provisioning APIs. + @defgroup WLANCRYPTO Crypto + @brief + Here are listed all the functions that implement the Wi-Fi Crypto APIs. + @defgroup WLANWPS WPS + @brief + Here are listed all the functions that implement the Wi-Fi WPS APIs. + + @cond P2P_DOC + @defgroup WLANP2P P2P + @brief + Here are listed all the functions that implement the Wi-Fi P2P APIs. + @endcond + @cond MON_DOC + @defgroup WLANMON Monitoring Mode + @brief + Here are listed all the functions that implement the Wi-Fi Monitoring Mode APIs. + @endcond + @} + @} + */ + +#ifndef __M2M_WIFI_H__ +#define __M2M_WIFI_H__ + +#include +#include "m2m_types.h" + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +Callbacks +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +/**@addtogroup WLANCallbacks + * @{ + */ +/*! +@typedef void (*tpfAppWifiCb)(uint8_t u8MsgType, const void *const pvMsg); + +@brief + This is the main callback function for the Wi-Fi driver and is responsible for processing + any M2M_WIFI events that are received on the Wi-Fi interface. + These events (notifications) are usually received in response to earlier Wi-Fi requests such + as @ref m2m_wifi_request_scan, @ref m2m_wifi_connect_open, @ref m2m_wifi_connect_wep, + @ref m2m_wifi_connect_psk, @ref m2m_wifi_connect_1x_mschap2, @ref m2m_wifi_connect_1x_tls, + @ref m2m_wifi_get_connection_info, @ref m2m_wifi_req_curr_rssi, @ref m2m_wifi_get_system_time, etc. + + Most Wi-Fi APIs are implemented in an asynchronous mode and calling them generates information + that is then passed back to the application via this callback. For instance, a set of detected + networks to be passed back as a result to a call to @ref m2m_wifi_request_scan. + + Applications must ensure a callback function is registered with the Wi-Fi driver by + calling @ref m2m_wifi_init. +@param[in] u8MsgType + Type of notification. Possible types are: + - @ref M2M_WIFI_RESP_CON_STATE_CHANGED + - @ref M2M_WIFI_RESP_CONN_INFO + - @ref M2M_WIFI_REQ_DHCP_CONF + - @ref M2M_WIFI_REQ_WPS + - @ref M2M_WIFI_RESP_IP_CONFLICT + - @ref M2M_WIFI_RESP_SCAN_DONE + - @ref M2M_WIFI_RESP_SCAN_RESULT + - @ref M2M_WIFI_RESP_CURRENT_RSSI + - @ref M2M_WIFI_RESP_CLIENT_INFO + - @ref M2M_WIFI_RESP_PROVISION_INFO + - @ref M2M_WIFI_RESP_DEFAULT_CONNECT + - @ref M2M_WIFI_RESP_ETHERNET_RX_PACKET (If Bypass mode is active) + - @ref M2M_WIFI_RESP_WIFI_RX_PACKET (If monitoring mode is active) + +@param[in] pvMsg + A pointer to a buffer containing the notification parameters (if any). + It should be cast to the correct data type corresponding to the notification type. + +@see + tstrM2mWifiStateChanged + tstrM2MWPSInfo + tstrM2mScanDone + tstrM2mWifiscanResult + m2m_wifi_init +*/ +typedef void (*tpfAppWifiCb)(uint8_t u8MsgType, const void *const pvMsg); + +/*! +@typedef void (*tpfAppEthCb) (uint8_t u8MsgType, const void *const pvMsg, const void *const pvCtrlBuf); + +@brief + Ethernet (Bypass mode) notification callback function receiving Bypass mode events as + defined in the Wi-Fi responses enumeration @ref tenuM2mStaCmd. + + If bypass mode is enabled, applications must ensure this callback function is registered + with the Wi-Fi driver by calling @ref m2m_wifi_init. + +@param[in] u8MsgType + Type of notification. Possible types are: + - @ref M2M_WIFI_RESP_ETHERNET_RX_PACKET + +@param[in] pvMsg + A pointer to a buffer containing the notification parameters (if any). + It should be cast to the correct data type corresponding to the notification type. + + For example, it could be a pointer to the buffer holding the received frame in case + a @ref M2M_WIFI_RESP_ETHERNET_RX_PACKET event is received. + +@param[in] pvControlBuf + A pointer to control buffer describing the accompanied message. + This must be cast to the data type @ref tstrM2mIpCtrlBuf in case of @ref M2M_WIFI_RESP_ETHERNET_RX_PACKET event. + +@warning + Make sure that the application defines ETH_MODE. + +@see + m2m_wifi_init +*/ +typedef void (*tpfAppEthCb) (uint8_t u8MsgType, const void *const pvMsg, const void *const pvCtrlBuf); + +/**@}*/ // WLANCallbacks +/**@addtogroup WLANEnums + * @{ + */ +/*! +@enum \ + tenuWifiState +@brief + Enumeration for Wi-Fi state + The following is used to track the state of the Wi-Fi (not initialized, initialized or started) + +@remarks + This is useful when putting the WINC in "download mode" to access the flash via SPI. By using + @ref m2m_wifi_get_state and checking against the desired state, it is possible to validate if + the application should proceed with the SPI Flash access or not. +*/ +typedef enum { + WIFI_STATE_DEINIT, + /*!< Wi-Fi is not initialized */ + WIFI_STATE_INIT, + /*!< Wi-Fi has been initialized */ + WIFI_STATE_START, + /*!< Wi-Fi has started */ +} tenuWifiState; + +typedef enum { + WIFI_CRED_DONTSAVE, + /*!< Credentials will not be stored in WINC flash. */ + WIFI_CRED_SAVE_UNENCRYPTED, + /*!< Credentials will be stored unencrypted in WINC flash. */ + WIFI_CRED_SAVE_ENCRYPTED + /*!< Credentials will be stored encrypted in WINC flash. + The encryption is not secure; it is merely intended to prevent sensitive information + being leaked by an opportunistic read of WINC flash contents. + The encryption keys involve WINC efuse contents, so WINC efuses should not be written + while this option is in use. */ +} tenuCredStoreOption; + +/*! +@struct \ + tstrEthInitParam + +@brief + Structure to hold Ethernet interface parameters. + Structure is to be defined and have its attributes set, based on the application's functionality + before a call is made to initialize the Wi-Fi operations by calling the + @ref m2m_wifi_init function. + Part of the Wi-Fi configuration structure @ref tstrWifiInitParam. + Applications shouldn't need to define this structure, if the bypass mode is not defined. + +@see + tpfAppEthCb + tpfAppWifiCb + m2m_wifi_init + +@warning + Make sure that application defines ETH_MODE before using @ref tstrEthInitParam. +*/ +typedef struct { + tpfAppWifiCb pfAppWifiCb; /*!< Callback for Wi-Fi notifications. */ + tpfAppEthCb pfAppEthCb; /*!< Callback for Ethernet interface. */ + uint8_t *au8ethRcvBuf; /*!< Pointer to Receive Buffer of Ethernet Packet */ + uint16_t u16ethRcvBufSize; /*!< Size of Receive Buffer for Ethernet Packet */ + uint8_t u8EthernetEnable; /*!< Enable Ethernet mode flag */ +} tstrEthInitParam; + +/*! +@struct \ + tstrM2mIpCtrlBuf + +@brief + Structure holding the incoming buffer's data size information, indicating the data size of the + buffer and the remaining buffer's data size. The data of the buffer which holds the packet sent + to the host when in the bypass mode, is placed in the @ref tstrEthInitParam::au8ethRcvBuf attribute. + This following information is retrieved in the host when an event + @ref M2M_WIFI_RESP_ETHERNET_RX_PACKET is received in the Wi-Fi callback function + @ref tpfAppWifiCb. + + The application is expected to use this structure's information to determine if there is still incoming data to be received from the firmware. + +@see + tpfAppWifiCb + tpfAppEthCb + tstrEthInitParam + +@warning + Make sure that ETHERNET/bypass mode is defined before using @ref tstrM2mIpCtrlBuf + + */ +typedef struct { + uint16_t u16DataSize; /*!< Size of the received data in bytes. */ + uint16_t u16RemainingDataSize; /*!< Size of the remaining data bytes to be delivered to host. */ +} tstrM2mIpCtrlBuf; + +/** +@struct \ + tstrWifiInitParam + +@brief + Structure, holding the Wi-fi configuration attributes such as the Wi-Fi callback , monitoring mode callback and Ethernet parameter initialization structure. + Such configuration parameters are required to be set before calling the Wi-Fi initialization function @ref m2m_wifi_init. + @ref pfAppWifiCb attribute must be set to handle the Wi-Fi callback operations. + @ref strEthInitParam structure, is another optional configuration based on whether the bypass mode is set. + + @see + tpfAppEthCb + tstrEthInitParam +*/ +typedef struct { + tpfAppWifiCb pfAppWifiCb; /*!< Callback for Wi-Fi notifications. */ + tstrEthInitParam strEthInitParam; /*!< Structure to hold Ethernet interface parameters. */ +} tstrWifiInitParam; + +typedef struct { + uint8_t *pu8Bssid; + /*!< Pointer to BSSID (6 bytes). Optional (may be NULL). + If present, this restricts the connection attempt to APs that have a matching BSSID. */ + uint8_t *pu8Ssid; + /*!< Pointer to SSID. Required. */ + uint8_t u8SsidLen; + /*!< Length of SSID in bytes. Permitted values are between 0 and 32. */ + tenuM2mScanCh enuChannel; + /*!< Wi-Fi channel to connect on. + If an appropriate AP cannot be found on this channel then connection fails. + @ref M2M_WIFI_CH_ALL may be used to allow scanning of all channels. */ +} tstrNetworkId; + +/* Legacy Wep param structure. */ +typedef struct { + uint8_t u8KeyIndx; + uint8_t u8KeySz; + uint8_t au8WepKey[WEP_104_KEY_STRING_SIZE + 1]; // NULL terminated + uint8_t __PAD24__[3]; +} tstrM2mWifiWepParams; + +/* Legacy 802.1x MsChapv2 param structure. */ +typedef struct { + uint8_t au8UserName[21]; // NULL terminated + uint8_t au8Passwd[41]; // NULL terminated +} tstr1xAuthCredentials; + +typedef struct { + uint8_t *pu8Psk; + /*!< Pointer to PSK, represented as an ASCII string (64 characters, representing 32 bytes). + Must be NULL if Passphrase is provided instead. */ + uint8_t *pu8Passphrase; + /*!< Pointer to Passphrase (Printable ASCII). + Must be NULL if PSK is provided instead. */ + uint8_t u8PassphraseLen; + /*!< Length of Passphrase. Permitted values are between 8 and 63. + This field is ignored if pu8Passphrase == NULL. */ +} tstrAuthPsk; + +typedef struct { + uint8_t *pu8WepKey; + /*!< Pointer to WEP Key, represented as an ASCII string. + (10 or 26 characters, representing 5 or 13 bytes.) */ + uint8_t u8KeySz; + /*!< Size of WEP Key string. + Permitted values are @ref WEP_40_KEY_STRING_SIZE or @ref WEP_104_KEY_STRING_SIZE. */ + uint8_t u8KeyIndx; + /*!< WEP Key Index in the range 1 to 4. */ +} tstrAuthWep; + +typedef struct { + uint8_t *pu8Domain; + /*!< Pointer to Domain of authentication server (printable ASCII), including '@' or '\' + separator character as appropriate. Use NULL if there is no domain information. + The Domain will be either prepended or appended to the UserName, depending on the + setting of field bPrependDomain. \n + Example 1: if [Domain]is "@my_domain" and bPrependDomain is false, then the EAP + identity response is "[UserName]@my_domain". \n + Example 2: if [Domain]is "my_domain\" and bPrependDomain is true, then the EAP + identity response is "my_domain\[UserName]". */ + uint8_t *pu8UserName; + /*!< Pointer to UserName (ASCII). + This will be sent (encrypted) in the tunneled EAP identity response (if applicable) + and used during MSCHAPv2 authentication. If bUnencryptedUserName is true then it will + also be sent (unencrypted) in the initial EAP identity response. */ + uint8_t *pu8Password; + /*!< Pointer to MSCHAPv2 Password (ASCII). + This will be used during MSCHAPv2 authentication. */ + uint16_t u16DomainLen; + /*!< Length of Domain (in ASCII characters), including '@' or '\' separator character as + appropriate. + Permitted values are such that u16DomainLen + u16UserNameLen is between 0 and + @ref M2M_AUTH_1X_USER_LEN_MAX. */ + uint16_t u16UserNameLen; + /*!< Length of UserName (in ASCII characters). + Permitted values are such that u16DomainLen + u16UserNameLen is between 0 and + @ref M2M_AUTH_1X_USER_LEN_MAX. */ + uint16_t u16PasswordLen; + /*!< Length of Password (in ASCII characters). + Permitted values are between 0 and @ref M2M_AUTH_1X_PASSWORD_LEN_MAX. */ + bool bUnencryptedUserName; + /*!< Determines whether UserName or "anonymous" is sent (unencrypted) in the initial EAP + identity response. Domain is sent in both cases. \n + true: UserName is sent in the initial EAP identity response (not recommended). + false: "anonymous" is sent in the initial EAP identity response. This setting is + recommended for tunneled methods. MSCHAPv2 is always a tunneled method. */ + bool bPrependDomain; + /*!< Determines whether Domain is prepended or appended to UserName in EAP identity responses. + true: Domain is prepended to UserName - [Domain][UserName]. + false: Domain is appended to UserName - [UserName][Domain]. */ +} tstrAuth1xMschap2; + +typedef struct { + uint8_t *pu8Domain; + /*!< Pointer to Domain of authentication server (printable ASCII), including '@' or '\' + separator character as appropriate. Use NULL if there is no domain information. + The Domain will be either prepended or appended to the UserName, depending on the + setting of field bPrependDomain. \n + Example 1: if [Domain]is "@my_domain" and bPrependDomain is false, then the EAP + identity response is "[UserName]@my_domain". \n + Example 2: if [Domain]is "my_domain\" and bPrependDomain is true, then the EAP + identity response is "my_domain\[UserName]". */ + uint8_t *pu8UserName; + /*!< Pointer to UserName (ASCII). + This will be sent (encrypted) in the tunneled EAP identity response. + If bUnencryptedUserName is true then it will also be sent (unencrypted) in the initial + EAP identity response. */ + uint8_t *pu8PrivateKey_Mod; + /*!< Pointer to PrivateKey modulus (raw data). + This will be used during TLS client authentication. */ + uint8_t *pu8PrivateKey_Exp; + /*!< Pointer to PrivateKey exponent (raw data). + This will be used during TLS client authentication. */ + uint8_t *pu8Certificate; + /*!< Pointer to TLS client certificate corresponding to PrivateKey. + This will be used during TLS client authentication. */ + uint16_t u16DomainLen; + /*!< Length of Domain (in ASCII characters), including '@' or '\' separator character as + appropriate. + Permitted values are such that u16DomainLen + u16UserNameLen is between 0 and + @ref M2M_AUTH_1X_USER_LEN_MAX. */ + uint16_t u16UserNameLen; + /*!< Length of UserName (in ASCII characters). + Permitted values are such that u16DomainLen + u16UserNameLen is between 0 and + @ref M2M_AUTH_1X_USER_LEN_MAX. */ + uint16_t u16PrivateKeyLen; + /*!< Length of PrivateKey_Mod (in bytes). + Permitted values are between 0 and @ref M2M_AUTH_1X_PRIVATEKEY_LEN_MAX, typically 128 or 256. + PrivateKey_Exp must be the same length as modulus, pre-padded with 0s if necessary. */ + uint16_t u16CertificateLen; + /*!< Length of Certificate (in bytes). + Permitted values are between 0 and @ref M2M_AUTH_1X_CERT_LEN_MAX. */ + bool bUnencryptedUserName; + /*!< Determines whether UserName or "anonymous" is sent (unencrypted) in the initial EAP + identity response. Domain is sent in both cases. \n + true: UserName is sent in the initial EAP identity response (required for EAP-TLS). + false: "anonymous" is sent in the initial EAP identity response. This setting is + recommended for tunneled methods such as EAP-PEAP/TLS. */ + bool bPrependDomain; + /*!< Determines whether Domain is prepended or appended to UserName in EAP identity responses. + true: Domain is prepended to UserName - [Domain][UserName]. + false: Domain is appended to UserName - [UserName][Domain]. */ +} tstrAuth1xTls; +/**@}*/ // WLANEnums + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +FUNCTION PROTOTYPES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* @fn m2m_wifi_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr, uint8_t grp) +* @brief WiFi call back function +* @param [in] u8OpCode +* HIF Opcode type. +* @param [in] u16DataSize +* HIF data length. +* @param [in] u32Addr +* HIF address. +* @param [in] grp +* HIF group type. +* @author +* @date +* @version 1.0 +*/ +void m2m_wifi_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr); + +/*! +@ingroup WLANINIT +@fn \ + int8_t m2m_wifi_download_mode(void); + +@brief + Prepares the WINC before downloading any data (firmware, certificates, etc). + +@details + This function should be called before attempting to download any data to the WINC. + Performs the appropriate WINC driver initialization, this includes bus initialization, + interrupt enabling and it halts the chip to allow for the firmware downloads. Firmware + can be downloaded through a number of interfaces, UART, I2C and SPI. + +@pre + Prior to call m2m_wifi_download_mode, the Application should ensure that the Wi-Fi is not + initialized. This can be done by calling @ref m2m_wifi_get_state and in case the Wi-Fi state + differs from @ref WIFI_STATE_DEINIT, a @ref m2m_wifi_deinit needs to be issued. + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +*/ +int8_t m2m_wifi_download_mode(void); + +/*! +@ingroup WLANINIT +@fn \ + int8_t m2m_wifi_init(tstrWifiInitParam *pWifiInitParam); + +@brief + Synchronous API to initialize the WINC driver. + +@details + This function initializes the WINC driver by registering the callback function for the M2M_WIFI layer + (also the callback function for bypass mode/monitoring mode if defined), initializing the host + interface layer and the bus interfaces. Wi-Fi callback registering is essential to allow the + handling of the events received, in response to the asynchronous Wi-Fi operations. + + The possible Wi-Fi events that are expected to be received through the callback + function (provided by the application) to the M2M_WIFI layer are listed below: + + - @ref M2M_WIFI_RESP_CON_STATE_CHANGED + - @ref M2M_WIFI_RESP_CONN_INFO + - @ref M2M_WIFI_REQ_DHCP_CONF + - @ref M2M_WIFI_REQ_WPS + - @ref M2M_WIFI_RESP_IP_CONFLICT + - @ref M2M_WIFI_RESP_SCAN_DONE + - @ref M2M_WIFI_RESP_SCAN_RESULT + - @ref M2M_WIFI_RESP_CURRENT_RSSI + - @ref M2M_WIFI_RESP_CLIENT_INFO + - @ref M2M_WIFI_RESP_PROVISION_INFO + - @ref M2M_WIFI_RESP_DEFAULT_CONNECT + - @ref M2M_WIFI_RESP_ETHERNET_RX_PACKET (if bypass mode is enabled) + - @ref M2M_WIFI_RESP_WIFI_RX_PACKET (if monitoring mode is enabled) + + Any application using the WINC driver must call this function at the start of its main function. + +@param[in] pWifiInitParam + This is a pointer to a structure of type @ref tstrWifiInitParam which contains pointers to the + application WIFI layer callback function, monitoring mode callback and @ref tstrEthInitParam + structure (which contains initialization settings for bypass mode). + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. + +@pre + Prior to this function call, the application should initialize the ADAPTER using @ref winc_adapter_init. + Also, the application must provide a callback function responsible for receiving all the + Wi-Fi events that are received on the M2M_WIFI layer. + +@warning + Failure to successfully complete indicates that the driver could not be initialized and + a fatal error will prevent the application from proceeding, proper error handling should be + implemented by the application. + +@see + m2m_wifi_deinit + m2m_wifi_init_hold + m2m_wifi_init_start + m2m_wifi_download_mode + tstrWifiInitParam + tenuM2mStaCmd +*/ +int8_t m2m_wifi_init(tstrWifiInitParam *pWifiInitParam); + +/*! +@ingroup WLANINIT +@fn \ + int8_t m2m_wifi_deinit(void *pVArg); + +@brief + Synchronous API to de-initialize the WINC driver and host interface. + +@details + De-initialization function for the WINC driver. + De-initializes the host interface and frees any resources used by the M2M_WIFI layer. + This function must be called in the application closing phase to ensure that all + resources have been correctly released. + +@param[in] pVArg + Opaque argument, not used in current implementation. Application should use null. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC, + and a negative value otherwise. + +@note + This function must be called at the de-initialization stage of the application. + Generally this function should be the last function before switching off the chip + and it should be followed only by @ref winc_adapter_deinit function call. + Every function call of @ref m2m_wifi_init should be matched with a call to m2m_wifi_deinit. + +@see + winc_adapter_deinit + m2m_wifi_init + m2m_wifi_init_hold + m2m_wifi_init_start + m2m_wifi_download_mode + m2m_wifi_download_mode +*/ +int8_t m2m_wifi_deinit(void *pVArg); + +/*! +@ingroup WLANINIT +@fn \ + int8_t m2m_wifi_init_hold(void); + +@brief + First part of @ref m2m_wifi_init, up to the point of initializing SPI for flash access. + +@see + m2m_wifi_init + m2m_wifi_deinit + m2m_wifi_init_start + m2m_wifi_download_mode +*/ +int8_t m2m_wifi_init_hold(void); + +/*! +@ingroup WLANINIT +@fn \ + int8_t m2m_wifi_init_start(tstrWifiInitParam *pWifiInitParam); + +@brief + Second part of @ref m2m_wifi_init, continuing from where @ref m2m_wifi_init_hold left off. + +@param[in] pWifiInitParam + This is a pointer to a variable of type @ref tstrWifiInitParam which contains pointers to the + application WIFI layer callback function (see @ref tpfAppWifiCb), monitoring mode callback + (see @ref tpfAppEthCb) and @ref tstrEthInitParam structure (which contains initialization + settings for bypass mode). + +@see + m2m_wifi_init + m2m_wifi_deinit + m2m_wifi_init_hold + m2m_wifi_download_mode + tstrWifiInitParam +*/ +int8_t m2m_wifi_init_start(tstrWifiInitParam *pWifiInitParam); + +/*! +@ingroup WLANEVTS +@fn \ + int8_t m2m_wifi_handle_events(void *pVArg); + +@brief + Synchronous M2M event handler function. + +@details + This function is responsible for handling interrupts received from the WINC firmware. + Applications should call this function periodically in-order to receive the events that are to + be handled by the callback functions implemented by the application. + + Handle the various events received from the WINC. + Whenever an event happens in the WINC (e.g. Connection, Disconnection, DHCP, etc), + the WINC will interrupt the host to let it know that a new event has occurred. The host driver + will attempt to handle these events whenever the application decides to do so by calling + the m2m_wifi_handle_events function. + It is mandatory to call this function periodically and independently of any other condition. + It is ideal to include this function in the main and the most frequent loop of the + host application. + +@param[in] pVArg + Opaque argument, not used in current implementation. Application should use null. + +@pre + Prior to receiving events, the WINC driver should have been successfully initialized by calling the @ref m2m_wifi_init function. + +@warning + Failure to successfully complete this function indicates bus errors and hence a fatal error that will prevent the application from proceeding. + +@return + The function returns @ref M2M_SUCCESS for successful interrupt handling and a negative value otherwise. +*/ +int8_t m2m_wifi_handle_events(void *pVArg); + +/*! +@fn \ + int8_t m2m_wifi_send_crl(tstrTlsCrlInfo *pCRL); + +@brief + Asynchronous API that notifies the WINC with the Certificate Revocation List. + +@param[in] pCRL + Pointer to the structure containing certificate revocation list details. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. +*/ +int8_t m2m_wifi_send_crl(tstrTlsCrlInfo *pCRL); + +/*! +@ingroup WLANCONNECT +@fn \ + int8_t m2m_wifi_delete_sc(char *pcSsid, uint8_t u8SsidLen); + +@brief + Asynchronous API that deletes connection credentials (PSK, WEP key, 802.1X password) from WINC + flash. Either deletes all credentials, or for a specific SSID. + +@details + Causes WINC to delete connection credentials. If the parameter is NULL, then WINC will delete + all credentials from flash. Otherwise WINC will only delete credentials for matching SSID. + Callback will report the status of the operation (success or not). + +@param[in] pcSsid + SSID to match on when deleting credentials. + SSID must not contain '\0'. + NULL is a valid argument here, in which case all credentials are deleted. + +@param[in] u8SsidLen + Length of SSID provided in pcSsid. Must be less than @ref M2M_MAX_SSID_LEN. + This parameter is ignored if pcSsid is NULL. + +@pre + Prior to deleting credentials, the WINC driver should have been successfully initialized by calling the + @ref m2m_wifi_init function. + +@warning + The option to delete for a specific SSID is currently not supported; all credentials are + deleted regardless of the input parameters. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. +*/ +int8_t m2m_wifi_delete_sc(char *pcSsid, uint8_t u8SsidLen); + +/*! +@ingroup WLANCONNECT +@fn \ + int8_t m2m_wifi_default_connect(void); + +@brief + Asynchronous API that attempts to reconnect to the last-associated access point. + +@details + Asynchronous Wi-Fi connection function. An application calling this function will cause + the firmware to attempt to reconnect to the access point with which it had last successfully connected. + A failure to connect will result in a response of @ref M2M_WIFI_RESP_DEFAULT_CONNECT + indicating a connection error as defined in the structure @ref tstrM2MDefaultConnResp. + + Possible errors are: + @ref M2M_DEFAULT_CONN_EMPTY_LIST indicating that the connection list is empty, or + @ref M2M_DEFAULT_CONN_SCAN_MISMATCH indicating a mismatch for the saved AP name. + +@pre + Prior to connecting, the WINC driver should have been successfully initialized by calling the + @ref m2m_wifi_init function. + +@warning + This function must be called in station mode only. + It is important to note that successful completion of a call to m2m_wifi_default_connect + does not guarantee success of the WIFI connection; a negative return value indicates only + locally-detected errors. + +@see + m2m_wifi_connect + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. +*/ +int8_t m2m_wifi_default_connect(void); + +/*! +@ingroup WLANCONNECT +@fn \ + int8_t m2m_wifi_connect_open(tenuCredStoreOption enuCredStoreOption, tstrNetworkId *pstrNetworkId); + +@brief + Asynchronous API to connect to an access point using open authentication. + +@details + Asynchronous Wi-Fi connection function. An application calling this function will cause the + firmware to attempt to connect to an access point matching the details in pstrNetworkId, with + open authentication. + On successful connection, the connection details may be saved in WINC's flash, according to + the option selected in enuCredStoreOption. + Once connection has been attempted (whether successful or otherwise), a response event + @ref M2M_WIFI_RESP_CON_STATE_CHANGED will be sent to the callback function @ref tpfAppWifiCb + provided during initialization @ref m2m_wifi_init. + + Possible results indicated by the response event are: + - @ref M2M_WIFI_DISCONNECTED if the connection attempt failed. + - @ref M2M_WIFI_CONNECTED if the connection attempt succeeded. + +@pre + Prior to attempting connection, the WINC driver must have been initialized by calling the + @ref m2m_wifi_init function. + +@warning + This function is handled in station mode only. + +@param[in] enuCredStoreOption + Option to specify whether connection details (i.e. the contents + of pstrNetworkId) are stored in WINC's flash and, if so, + whether they are encrypted before storing. + +@param[in] pstrNetworkId + Structure specifying SSID/BSSID and Wi-Fi channel. + +@return + The function returns @ref M2M_SUCCESS if the connect request has been successfully passed to the firmware and a negative value otherwise. +*/ +int8_t m2m_wifi_connect_open(tenuCredStoreOption enuCredStoreOption, tstrNetworkId *pstrNetworkId); + +/*! +@ingroup WLANCONNECT +@fn \ + int8_t m2m_wifi_connect_wep(tenuCredStoreOption enuCredStoreOption, tstrNetworkId *pstrNetworkId, tstrAuthWep *pstrAuthWep); + +@brief + Asynchronous API to connect to an access point using WEP authentication. + +@details + Asynchronous Wi-Fi connection function. An application calling this function will cause the + firmware to attempt to connect to an access point matching the details in pstrNetworkId, with + the WEP key provided in pstrAuthWep. + On successful connection, the connection details may be saved in WINC's flash, according to + the option selected in enuCredStoreOption. + Once connection has been attempted (whether successful or otherwise), a response event + @ref M2M_WIFI_RESP_CON_STATE_CHANGED will be sent to the callback function @ref tpfAppWifiCb + provided during initialization @ref m2m_wifi_init. + + Possible results indicated by the response event are: + - @ref M2M_WIFI_DISCONNECTED if the connection attempt failed. + - @ref M2M_WIFI_CONNECTED if the connection attempt succeeded. + +@pre + Prior to attempting connection, the WINC driver must have been initialized by calling the + @ref m2m_wifi_init function. + +@warning + This function is handled in station mode only. + +@param[in] enuCredStoreOption + Option to specify whether connection details (i.e. the contents + of pstrNetworkId and pstrAuthWep) are stored in WINC's flash + and, if so, whether they are encrypted before storing. + +@param[in] pstrNetworkId + Structure specifying SSID/BSSID and Wi-Fi channel. + +@param[in] pstrAuthWep + Structure specifying the WEP key. + +@return + The function returns @ref M2M_SUCCESS if the connect request has been successfully passed to the firmware and a negative value otherwise. +*/ +int8_t m2m_wifi_connect_wep(tenuCredStoreOption enuCredStoreOption, tstrNetworkId *pstrNetworkId, tstrAuthWep *pstrAuthWep); + +/*! +@ingroup WLANCONNECT +@fn \ + int8_t m2m_wifi_connect_psk(tenuCredStoreOption enuCredStoreOption, tstrNetworkId *pstrNetworkId, tstrAuthPsk *pstrAuthPsk); + +@brief + Asynchronous API to connect to an access point using WPA(2) PSK authentication. + +@details + Asynchronous Wi-Fi connection function. An application calling this function will cause the + firmware to attempt to connect to an access point matching the details in pstrNetworkId, with + the PSK passphrase provided in pstrAuthPsk. + On successful connection, the connection details may be saved in WINC's flash, according to + the option selected in enuCredStoreOption. + Once connection has been attempted (whether successful or otherwise), a response event + @ref M2M_WIFI_RESP_CON_STATE_CHANGED will be sent to the callback function @ref tpfAppWifiCb + provided during initialization @ref m2m_wifi_init. + + Possible results indicated by the response event are: + - @ref M2M_WIFI_DISCONNECTED if the connection attempt failed. + - @ref M2M_WIFI_CONNECTED if the connection attempt succeeded. + +@pre + Prior to attempting connection, the WINC driver must have been initialized by calling the + @ref m2m_wifi_init function. + +@warning + This function is handled in station mode only. + +@param[in] enuCredStoreOption + Option to specify whether connection details (i.e. the contents + of pstrNetworkId and pstrAuthPsk) are stored in WINC's flash + and, if so, whether they are encrypted before storing. + +@param[in] pstrNetworkId + Structure specifying SSID/BSSID and Wi-Fi channel. + +@param[in] pstrAuthPsk + Structure specifying the Passphrase/PSK. + +@return + The function returns @ref M2M_SUCCESS if the connect request has been successfully passed to the firmware and a negative value otherwise. +*/ +int8_t m2m_wifi_connect_psk(tenuCredStoreOption enuCredStoreOption, tstrNetworkId *pstrNetworkId, tstrAuthPsk *pstrAuthPsk); + +/*! +@ingroup WLANCONNECT +@fn \ + int8_t m2m_wifi_connect_1x_mschap2(tenuCredStoreOption enuCredStoreOption, tstrNetworkId *pstrNetworkId, tstrAuth1xMschap2 *pstrAuth1xMschap2); + +@brief + Asynchronous API to connect to an access point using WPA(2) Enterprise authentication with + MS-CHAP-V2 credentials. + +@details + Asynchronous Wi-Fi connection function. An application calling this function will cause the + firmware to attempt to connect to an access point matching the details in pstrNetworkId, with + the Enterprise MS-CHAP-V2 credentials provided in pstrAuth1xMschap2. + On successful connection, the connection details may be saved in WINC's flash, according to + the option selected in enuCredStoreOption. + Once connection has been attempted (whether successful or otherwise), a response event + @ref M2M_WIFI_RESP_CON_STATE_CHANGED will be sent to the callback function tpfAppWifiCb + provided during initialization @ref m2m_wifi_init. + + Possible results indicated by the response event are: + - @ref M2M_WIFI_DISCONNECTED if the connection attempt failed. + - @ref M2M_WIFI_CONNECTED if the connection attempt succeeded. + +@pre + Prior to attempting connection, the WINC driver must have been initialized by calling the + @ref m2m_wifi_init function. + +@warning + This function is handled in station mode only. + +@param[in] enuCredStoreOption + Option to specify whether connection details (i.e. the contents + of pstrNetworkId and pstrAuth1xMschap2) are stored in WINC's + flash and, if so, whether they are encrypted before storing. + +@param[in] pstrNetworkId + Structure specifying SSID/BSSID and Wi-Fi channel. + +@param[in] pstrAuth1xMschap2 + Structure specifying the MS-CHAP-V2 credentials. + +@return + The function returns @ref M2M_SUCCESS if the connect request has been successfully passed to the firmware and a negative value otherwise. +*/ +int8_t m2m_wifi_connect_1x_mschap2(tenuCredStoreOption enuCredStoreOption, tstrNetworkId *pstrNetworkId, tstrAuth1xMschap2 *pstrAuth1xMschap2); + +/*! +@ingroup WLANCONNECT +@fn \ + int8_t m2m_wifi_connect_1x_tls(tenuCredStoreOption enuCredStoreOption, tstrNetworkId *pstrNetworkId, tstrAuth1xTls *pstrAuth1xTls); + +@brief + Asynchronous API to connect to an access point using WPA(2) Enterprise authentication with + MS-CHAP-V2 credentials. + +@details + Asynchronous Wi-Fi connection function. An application calling this function will cause the + firmware to attempt to connect to an access point matching the details in pstrNetworkId, with + the Enterprise TLS credentials provided in pstrAuth1xTls. + On successful connection, the connection details may be saved in WINC's flash, according to + the option selected in enuCredStoreOption. + Once connection has been attempted (whether successful or otherwise), a response event + @ref M2M_WIFI_RESP_CON_STATE_CHANGED will be sent to the callback function @ref tpfAppWifiCb + provided during initialization @ref m2m_wifi_init. + + Possible results indicated by the response event are: + - @ref M2M_WIFI_DISCONNECTED if the connection attempt failed. + - @ref M2M_WIFI_CONNECTED if the connection attempt succeeded. + +@pre + Prior to attempting connection, the WINC driver must have been initialized by calling the + @ref m2m_wifi_init function. + +@warning + This function is handled in station mode only. + +@param[in] enuCredStoreOption + Option to specify whether connection details (i.e. the contents + of pstrNetworkId and pstrAuth1xTls) are stored in WINC's + flash and, if so, whether they are encrypted before storing. + +@param[in] pstrNetworkId + Structure specifying SSID/BSSID and Wi-Fi channel. + +@param[in] pstrAuth1xTls + Structure specifying the EAP-TLS credentials. + +@return + The function returns @ref M2M_SUCCESS if the connect request has been successfully passed to the firmware and a negative value otherwise. +*/ +int8_t m2m_wifi_connect_1x_tls(tenuCredStoreOption enuCredStoreOption, tstrNetworkId *pstrNetworkId, tstrAuth1xTls *pstrAuth1xTls); + +/*! +@ingroup WLANCONNECT +@fn \ + int8_t m2m_wifi_connect(char *pcSsid, uint8_t u8SsidLen, uint8_t u8SecType, void *pvAuthInfo, uint16_t u16Ch); + +@brief + DEPRECATED in v19.6.1 - Kept only for legacy purposes.\n + Legacy asynchronous API to request connection to a specified access point. + +@details + Prior to a successful connection, the application developers must know the SSID, the security + type, and the authentication parameters of the target access point; knowledge of the channel number + is optional. + + The connection status will be indicated to the application via a + @ref M2M_WIFI_RESP_CON_STATE_CHANGED event. The status will be one of those defined in + @ref tenuM2mConnState withe @ref M2M_WIFI_CONNECTED indicating a successful connection. + +@param[in] pcSsid + A buffer holding the SSID corresponding to the requested AP. + SSID must not contain '\0'. + +@param[in] u8SsidLen + Length of the given SSID (not including any NULL termination). + A length greater than or equal to @ref M2M_MAX_SSID_LEN will result in a negative error + @ref M2M_ERR_FAIL. + +@param[in] u8SecType + Wi-Fi security type security for the network. It can be one of the following types: + -@ref M2M_WIFI_SEC_OPEN + -@ref M2M_WIFI_SEC_WEP + -@ref M2M_WIFI_SEC_WPA_PSK + -@ref M2M_WIFI_SEC_802_1X + A value outside these possible values will result in a negative return error @ref M2M_ERR_FAIL. + +@param[in] pvAuthInfo + Authentication parameters required for completing the connection. Its type is based on the + security type. If the authentication parameters are NULL or are greater than the maximum length + of the authentication parameters length as defined by @ref M2M_MAX_PSK_LEN a negative error will + return @ref M2M_ERR_FAIL indicating connection failure. + +@param[in] u16Ch + Wi-Fi channel number as defined in @ref tenuM2mScanCh enumeration. Specifying a channel number + greater than @ref M2M_WIFI_CH_14 returns a negative error @ref M2M_ERR_FAIL, unless + the value is @ref M2M_WIFI_CH_ALL, since this indicates that the firmware should scan all channels + to find the SSID specified in parameter pcSsid. + + Failure to find the connection match will return a negative error + @ref M2M_DEFAULT_CONN_SCAN_MISMATCH. + +@pre + Prior to a successful connection request, the Wi-Fi driver must have been successfully initialized + through the call of the @ref m2m_wifi_init function. + +@warning + If there is a '\0' character within the first u8SsidLen characters, then this function will assume + that the input u8SsidLen was incorrect, set length to strlen(pcSsid) and continue.\n + This function has been deprecated since v19.6.1 and will no longer be supported afterwards. + The following should be used instead: + @ref m2m_wifi_connect_open + @ref m2m_wifi_connect_wep + @ref m2m_wifi_connect_psk + @ref m2m_wifi_connect_1x_mschap2 + @ref m2m_wifi_connect_1x_tls + + Additionally: + - This function must be called in station mode only. + - Successful completion of this function does not guarantee success of the WIFI connection, and + a negative return value indicates only locally-detected errors. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + tstr1xAuthCredentials + tstrM2mWifiWepParams +*/ +int8_t m2m_wifi_connect(char *pcSsid, uint8_t u8SsidLen, uint8_t u8SecType, void *pvAuthInfo, uint16_t u16Ch); + +/*! +@ingroup WLANCONNECT +@fn \ + int8_t m2m_wifi_connect_sc(char *pcSsid, uint8_t u8SsidLen, uint8_t u8SecType, void *pvAuthInfo, uint16_t u16Ch, uint8_t u8NoSaveCred); + +@brief + DEPRECATED in v19.6.1 - Kept only for legacy purposes.\n + Legacy asynchronous API to request connection to a specific AP with the option to save credentials in Flash. + +@details + Prior to a successful connection, the application developers must know the SSID, the security + type, and the authentication parameters of the target access point; knowledge of the channel number + is optional. + + The connection status will be indicated to the application via a + @ref M2M_WIFI_RESP_CON_STATE_CHANGED event. The status will be one of those defined in + @ref tenuM2mConnState withe @ref M2M_WIFI_CONNECTED indicating a successful connection. + + The only difference between this function and @ref m2m_wifi_connect, is the option to save the + acess point info ( SSID, password...etc) into flash. + +@param[in] pcSsid + A buffer holding the SSID corresponding to the requested AP. + SSID must not contain '\0'. + +@param[in] u8SsidLen + Length of the given SSID (not including any NULL termination). + A length greater than or equal to @ref M2M_MAX_SSID_LEN will result in a negative error + @ref M2M_ERR_FAIL. + +@param[in] u8SecType + Wi-Fi security type security for the network (see @ref tenuM2mSecType). It can be one of the following types: + -@ref M2M_WIFI_SEC_OPEN + -@ref M2M_WIFI_SEC_WEP + -@ref M2M_WIFI_SEC_WPA_PSK + -@ref M2M_WIFI_SEC_802_1X + A value outside these possible values will result in a negative return error @ref M2M_ERR_FAIL. + +@param[in] pvAuthInfo + Authentication parameters required for completing the connection. Its type is based on the + security type. If the authentication parameters are NULL or are greater than the maximum length + of the authentication parameters length as defined by @ref M2M_MAX_PSK_LEN a negative error will + return @ref M2M_ERR_FAIL indicating connection failure. + +@param[in] u16Ch + Wi-Fi channel number as defined in @ref tenuM2mScanCh enumeration. Specification of a channel + number greater than @ref M2M_WIFI_CH_14 returns a negative error @ref M2M_ERR_FAIL unless + the value is @ref M2M_WIFI_CH_ALL. A channel number of @ref M2M_WIFI_CH_ALL indicates that the + firmware should scan all channels to find the SSID specified in parameter pcSsid. + + Failure to find the connection match will return a negative error + @ref M2M_DEFAULT_CONN_SCAN_MISMATCH. + +@param[in] u8NoSaveCred + Option to store the access point SSID and password into the WINC flash memory or not. + +@pre + Prior to a successful connection request, the Wi-Fi driver must have been successfully initialized through the call of the @ref m2m_wifi_init function. + +@warning + If there is a '\0' character within the first u8SsidLen characters, then this function will assume + that the input u8SsidLen was incorrect, set length to strlen(pcSsid) and continue.\n + This function has been deprecated since v19.6.1 and will no longer be supported afterwards. + The following should be used instead: + @ref m2m_wifi_connect_open + @ref m2m_wifi_connect_wep + @ref m2m_wifi_connect_psk + @ref m2m_wifi_connect_1x_mschap2 + @ref m2m_wifi_connect_1x_tls + + Additionally: + - This function must be called in station mode only. + - Successful completion of this function does not guarantee success of the WIFI connection, and + a negative return value indicates only locally-detected errors. + +@see + tenuM2mSecType + tstr1xAuthCredentials + tstrM2mWifiWepParams + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. +*/ +int8_t m2m_wifi_connect_sc(char *pcSsid, uint8_t u8SsidLen, uint8_t u8SecType, void *pvAuthInfo, uint16_t u16Ch, uint8_t u8NoSaveCred); + +/*! +@ingroup WLANCONNECT +@fn \ + int8_t m2m_wifi_disconnect(void); + +@brief + Synchronous API to request disconnection from a network. + +@details + Request a Wi-Fi disconnect from the currently connected AP. + The connection status will be indicated to the application via a @ref M2M_WIFI_RESP_CON_STATE_CHANGED event. + The status will be one of those defined in @ref tenuM2mConnState, with @ref M2M_WIFI_DISCONNECTED indicating + a successful disconnection. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@pre + Disconnection request must be made to a successfully connected AP. If the WINC is not in the connected state, a call to this function will hold insignificant. + +@warning + This function must be called in station mode only. + +@see + m2m_wifi_connect_open + m2m_wifi_connect_wep + m2m_wifi_connect_psk + m2m_wifi_connect_1x_mschap2 + m2m_wifi_connect_1x_tls + m2m_wifi_default_connect + +*/ +int8_t m2m_wifi_disconnect(void); + +/*! +@ingroup WLANPROVISION +@fn \ + int8_t m2m_wifi_start_provision_mode(tstrM2MAPConfig *pstrAPConfig, char *pcHttpServerDomainName, uint8_t bEnableHttpRedirect); + +@brief + Asynchronous API for control of Wi-Fi provisioning functionality. + +@details + This function allows the application to start the WINC in 'provisioning mode', a special mode + that triggers the WINC to create a Wi-Fi access point, DHCP server, and HTTP server. + + The HTTP server presents a provisioning page to a connected client which lists the access points + detected in the vicinity of the WINC, and allows one of these to be selected and any appropriate + credentials to be entered. This allows a headless system to be provisioned (configured to + connect with an access point). + + Provisioning status is returned in an event @ref M2M_WIFI_RESP_PROVISION_INFO. + +@param[in] pstrAPConfig + AP configuration parameters as defined in @ref tstrM2MAPConfig configuration structure. + If a NULL value is passed in, the call will result in a negative error @ref M2M_ERR_FAIL. + +@param[in] pcHttpServerDomainName + Domain name of the HTTP Provision WEB server which others will use to load the provisioning Home page. + The domain name can have one of the following 3 forms: + - 1. "wincprov.com" + - 2. "http://wincprov.com" + - 3. "https://wincprov.com" + + Forms 1 and 2 are equivalent, they will both start a plain http server, while form 3 + will start a secure HTTP provisioning Session (HTTP over SSL connection). + +@param[in] bEnableHttpRedirect + A flag to enable/disable the HTTP redirect feature. If Secure provisioning is enabled (i.e. the server + domain name uses "https" prefix) this flag is ignored (no meaning for redirect in HTTPS). + Possible values are: + - Zero: DO NOT use HTTP Redirect. In this case, the associated device could open the provisioning + page ONLY when the HTTP Provision URL of the WINC HTTP Server is correctly written on the browser. + - Non-Zero: Use HTTP Redirect. In this case, all http traffic (http://URL) from the associated + device (Phone, PC, etc) will be redirected to the WINC HTTP Provisioning Home page. + +@pre + - A Wi-Fi notification callback of type @ref tpfAppWifiCb MUST be implemented and registered at startup. + Registering the callback is done through passing it to the initialization @ref m2m_wifi_init function. + - The event @ref M2M_WIFI_RESP_CONN_INFO must be handled in the callback to receive the requested connection info. + +@warning + Do not use ".local" in the pcHttpServerDomainName. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + tpfAppWifiCb + m2m_wifi_init + M2M_WIFI_RESP_PROVISION_INFO + m2m_wifi_stop_provision_mode + tstrM2MAPConfig + +@section WIFIExample1 Example + The example demonstrates a code snippet for how provisioning is triggered and the response event received accordingly. + +@include m2m_wifi_start_provision_mode.c +@example m2m_wifi_start_provision_mode.c +*/ +int8_t m2m_wifi_start_provision_mode(tstrM2MAPConfig *pstrAPConfig, char *pcHttpServerDomainName, uint8_t bEnableHttpRedirect); + +/*! +@ingroup WLANPROVISION +@fn \ + int8_t m2m_wifi_start_provision_mode_ext(tstrM2MAPModeConfig *pstrAPModeConfig, char *pcHttpServerDomainName, uint8_t bEnableHttpRedirect); + +@brief + Asynchronous API for control of Wi-Fi provisioning functionality with extended options. + +@details + Asynchronous Wi-Fi provisioning function, which starts the WINC HTTP PROVISIONING mode. + The function triggers the WINC to activate the Wi-Fi AP (HOTSPOT) mode with the passed + configuration parameters and then starts the HTTP Provision WEB Server. + + Provisioning status is returned in an event @ref M2M_WIFI_RESP_PROVISION_INFO. + +@param[in] pstrAPModeConfig + AP configuration parameters as defined in @ref tstrM2MAPModeConfig configuration structure. + A NULL value passed in, will result in a negative error @ref M2M_ERR_FAIL. + +@param[in] pcHttpServerDomainName + Domain name of the HTTP Provision WEB server which others will use to load the provisioning Home page. + The domain name can have one of the following 3 forms: + - 1. "wincprov.com" + - 2. "http://wincprov.com" + - 3. "https://wincprov.com" + + The forms 1 and 2 are equivalent, they both will start a plain http server, while form 3 + will start a secure HTTP provisioning Session (HTTP over SSL connection). + +@param[in] bEnableHttpRedirect + A flag to enable/disable the HTTP redirect feature. If Secure provisioning is enabled (i.e. the server + domain name uses "https" prefix) this flag is ignored (no meaning for redirect in HTTPS). + Possible values are: + - ZERO value, which means DO NOT use HTTP Redirect. In this case, the associated device could open the provisioning + page ONLY when the HTTP Provision URL of the WINC HTTP Server is correctly written on the browser. + - Non-Zero value, means use HTTP Redirect. In this case, all http traffic (http://URL) from the associated + device (Phone, PC, etc) will be redirected to the WINC HTTP Provisioning Home page. + +@pre + - A Wi-Fi notification callback of type @ref tpfAppWifiCb MUST be implemented and registered at startup. Registering the callback + is done through passing it to the initialization @ref m2m_wifi_init function. + - The event @ref M2M_WIFI_RESP_CONN_INFO must be handled in the callback to receive the requested connection info. + +@warning + DO Not use ".local" in the pcHttpServerDomainName. + +@see + tpfAppWifiCb + m2m_wifi_init + M2M_WIFI_RESP_PROVISION_INFO + m2m_wifi_stop_provision_mode + tstrM2MAPModeConfig + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@section WIFIExample1b Example + The example demonstrates a code snippet for how provisioning is triggered and the response event + received accordingly. + +@include m2m_wifi_start_provision_mode_ext.c +@example m2m_wifi_start_provision_mode_ext.c +*/ +int8_t m2m_wifi_start_provision_mode_ext(tstrM2MAPModeConfig *pstrAPModeConfig, char *pcHttpServerDomainName, uint8_t bEnableHttpRedirect); + +/*! +@ingroup WLANPROVISION +@fn \ + int8_t m2m_wifi_stop_provision_mode(void); + +@brief + Synchronous API for terminating provisioning mode on the WINC. + +@details + This function will terminate any currently active provisioning mode on the WINC, returning the WINC to idle. + +@pre + An active provisioning session must be active before it is terminated through this function. + +@return + The function returns @ref M2M_SUCCESS for success and a negative value otherwise. + +@see + m2m_wifi_start_provision_mode +*/ +int8_t m2m_wifi_stop_provision_mode(void); + +/*! +@ingroup WLANCONNECT +@fn \ + int8_t m2m_wifi_get_connection_info(void); + +@brief + Asynchronous API for retrieving the WINC connection status. + +@details + Requests the connection status from the WINC including information regarding any access + point to which it is currently connected, or any non-AP station that is connected to the WINC. + All information will be returned to the application via the Wi-Fi notification callback through + the event @ref M2M_WIFI_RESP_CONN_INFO. + + The connection info can be retrieved using the structure @ref tstrM2MConnInfo which contains: + - Connection Security + - Connection RSSI + - Remote MAC address + - Remote IP address + - SSID of the network (in cases where the WINC is in non-AP mode) + +@pre + - A Wi-Fi notification callback of type @ref tpfAppWifiCb MUST be implemented and registered at + startup. Registering the callback is done through passing it to the initialization + @ref m2m_wifi_init function. + - The event @ref M2M_WIFI_RESP_CONN_INFO must be handled in the callback to receive the + requested connection info. + +@warning + - In case the WINC is operating in AP mode, the SSID field will be returned as a NULL string. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + M2M_WIFI_RESP_CONN_INFO, + tstrM2MConnInfo +@section WIFIExample2 Example + The code snippet shows an example of how Wi-Fi connection information is retrieved . + +@include m2m_wifi_get_connection_info.c +@example m2m_wifi_get_connection_info.c +*/ +int8_t m2m_wifi_get_connection_info(void); + +/*! +@ingroup WLANCONF +@fn \ + int8_t m2m_wifi_set_mac_address(uint8_t au8MacAddress[6]); + +@brief + Asynchronous API for assigning a MAC address to the WINC. + +@details + This function is intended to allow non-production software to assign a MAC address to the WINC. + +@warning + This function is intended for development use only and not for use in production software. + +@param[in] au8MacAddress + MAC Address to be provisioned to the WINC. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. +*/ +int8_t m2m_wifi_set_mac_address(uint8_t au8MacAddress[6]); + +/*! +@ingroup WLANWPS +@fn \ + int8_t m2m_wifi_wps(uint8_t u8TriggerType, const char *pcPinNumber); + +@brief + Asynchronous API to engage the WINC Wi-Fi Protected Setup (enrollee) function. + +@details + This function can be called to make the WINC enter WPS (Wi-Fi Protected Setup) mode. The result + is passed to the Wi-Fi notification callback with the event @ref M2M_WIFI_REQ_WPS. + +@param[in] u8TriggerType + WPS Trigger method. This may be: + - @ref WPS_PIN_TRIGGER Push button method + - @ref WPS_PBC_TRIGGER Pin method + +@param[in] pcPinNumber + Valid only if the u8TriggerType is @ref WPS_PIN_TRIGGER, this parameter contains the PIN number. + The number must follow the format as given in the WSC1.0 specification. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@warning + This function is not allowed in AP modes. + +@pre + - A Wi-Fi notification callback of type (@ref tpfAppWifiCb MUST be implemented and registered at + startup. Registering the callback is done through passing it to @ref m2m_wifi_init. + - The event @ref M2M_WIFI_REQ_WPS must be handled in the callback to receive the WPS status. + - The WINC device MUST be in IDLE or STA mode. If AP or P2P mode is active, the WPS will not be performed. + - The @ref m2m_wifi_handle_events MUST be called periodically to receive + the responses in the callback. + +@see + tpfAppWifiCb + m2m_wifi_init + M2M_WIFI_REQ_WPS + tenuWPSTrigger + tstrM2MWPSInfo + +@section WIFIExample3 Example + The code snippet shows an example of how Wi-Fi WPS is triggered . + +@include m2m_wifi_wps.c +@example m2m_wifi_wps.c +*/ +int8_t m2m_wifi_wps(uint8_t u8TriggerType, const char *pcPinNumber); + +/*! +@ingroup WLANWPS +@fn \ + int8_t m2m_wifi_wps_disable(void); + +@brief + Asynchronous API that disables Wi-Fi Protected Setup mode in the WINC. + +@pre + WINC should be already in WPS mode using @ref m2m_wifi_wps. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + m2m_wifi_wps +*/ +int8_t m2m_wifi_wps_disable(void); + +/**@cond P2P_DOC + */ +/*! +@ingroup WLANP2P +@fn \ + int8_t m2m_wifi_p2p(uint8_t u8Channel); + +@warning + P2P has been deprecated from version 19.5.3! +*/ +int8_t m2m_wifi_p2p(uint8_t u8Channel); + +/*! +@ingroup WLANP2P +@fn \ + int8_t m2m_wifi_p2p_disconnect(void); + +@warning + P2P has been deprecated from version 19.5.3! +*/ +int8_t m2m_wifi_p2p_disconnect(void); +/**@endcond*/ //P2P_DOC + +/*! +@ingroup WLANAP +@fn \ + int8_t m2m_wifi_enable_ap(const tstrM2MAPConfig *pstrM2MAPConfig); + +@brief + Asynchronous API to enable access point (AKA "hot-spot") mode on the WINC. + +@details + The WINC supports the ability to operate as an access point with the following limitations: + - Only 1 station may be associated at any given time. + - Open system and WEP are the only security suites supported. + +@param[in] pstrM2MAPConfig + A structure holding the AP configurations. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@warning + This function is not allowed in STA modes. + +@pre + - A Wi-Fi notification callback of type @ref tpfAppWifiCb MUST be implemented and registered at initialization. Registering the callback + is done through passing it to the @ref m2m_wifi_init. + - The event @ref M2M_WIFI_REQ_DHCP_CONF must be handled in the callback. + - The @ref m2m_wifi_handle_events MUST be called to receive the responses in the callback. + +@see + tpfAppWifiCb + tenuM2mSecType + m2m_wifi_init + M2M_WIFI_REQ_DHCP_CONF + tstrM2mWifiStateChanged + tstrM2MAPConfig + +@section WIFIExample5 Example + The code snippet demonstrates how the AP mode is enabled after the driver is initialized in the application's main function and the handling + of the event @ref M2M_WIFI_REQ_DHCP_CONF, to indicate successful connection. + +@include m2m_wifi_enable_ap.c +@example m2m_wifi_enable_ap.c +*/ +int8_t m2m_wifi_enable_ap(const tstrM2MAPConfig *pstrM2MAPConfig); + +/*! +@ingroup WLANAP +@fn \ + int8_t m2m_wifi_enable_ap_ext(const tstrM2MAPModeConfig *pstrM2MAPModeConfig); + +@brief + Asynchronous API to enable access point (AKA "hot-spot") mode on the WINC IC with extended options. + +@details + The WINC IC supports the ability to operate as an access point with the following limitations: + - Only 1 station may be associated at any given time. + - Open system and WEP are the only security suites supported. + +@param[in] pstrM2MAPModeConfig + A structure holding the AP configurations. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@pre + - A Wi-Fi notification callback of type @ref tpfAppWifiCb MUST be implemented and registered at initialization. Registering the callback + is done through passing it to the @ref m2m_wifi_init. + - The event @ref M2M_WIFI_REQ_DHCP_CONF must be handled in the callback. + - The @ref m2m_wifi_handle_events MUST be called to receive the responses in the callback. + +@warning + This function is not allowed in STA mode. + +@see + tpfAppWifiCb + tenuM2mSecType + m2m_wifi_init + M2M_WIFI_REQ_DHCP_CONF + tstrM2mWifiStateChanged + tstrM2MAPModeConfig + tstrM2MAPConfigExt + +@section WIFIExample5b Example + The code snippet demonstrates how the AP mode is enabled after the driver is initialized in the application's main function and the handling + of the event @ref M2M_WIFI_REQ_DHCP_CONF, to indicate successful connection. + +@include m2m_wifi_enable_ap_ext.c +@example m2m_wifi_enable_ap_ext.c +*/ +int8_t m2m_wifi_enable_ap_ext(const tstrM2MAPModeConfig *pstrM2MAPModeConfig); + +/*! +@ingroup WLANAP +@fn \ + int8_t m2m_wifi_disable_ap(void); + +@brief + Synchronous API to disable access point mode on the WINC. + +@details + Must be called only when the AP is enabled through the @ref m2m_wifi_enable_ap + function. Otherwise the call to this function will not be useful. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + m2m_wifi_enable_ap +*/ +int8_t m2m_wifi_disable_ap(void); + +/*! +@ingroup WLANCONNECT +@fn \ + int8_t m2m_wifi_set_static_ip(tstrM2MIPConfig *pstrStaticIPConf); + +@brief + Asynchronous API to manually assign a (static) IP address to the WINC. + +@details + Assigns a static IP address to the WINC. + Typically an infrastructure access point will be able to provide an IP address to all clients + after they associate. The WINC will request configuration via DHCP automatically after + successfully connecting to an access point. + This function should only be called in the event that the network has no DHCP server or in case the application + wants to assign a predefined known IP address and the application. + This function can be used to assign a static IP address in case the application knows the specifics of the network. + The user must keep in mind that assigning a static IP address might + result in an IP address conflict. In case of an IP address conflict observed + by the WINC the user will get a response of @ref M2M_WIFI_RESP_IP_CONFLICT + in the Wi-Fi callback. The application is then responsible to either solve the + conflict or assign another IP address. + +@pre + The application must first call @ref m2m_wifi_enable_dhcp to request that DHCP functionality is + disabled prior to calling this function. + +@warning + Exercise caution using this function. + DHCP is the preferred method for configuring IP addresses. + +@param[in] pstrStaticIPConf + Pointer to a structure holding the static IP configuration (IP, Gateway, subnet mask and DNS address). + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + tstrM2MIPConfig +*/ +int8_t m2m_wifi_set_static_ip(tstrM2MIPConfig *pstrStaticIPConf); + +/*! +@ingroup WLANCONNECT +@fn \ + int8_t m2m_wifi_enable_dhcp(uint8_t u8DhcpEn); + +@brief + Asynchronous function to control the DHCP client functionality within the WINC. + +@details + This function allows the application to control the behaviour of the DHCP client function within + the WINC once it has associated with an access point. DHCP client functionality is enabled by + default. + +@param[in] u8DhcpEn + The state of the DHCP client feature after successful association with an access point: + - 1: Enables DHCP client after connection. + - 0: Disables DHCP client after connection. + +@return + The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise. + +@warning + DHCP client is enabled by default. + This Function should be called to disable DHCP client operation before using @ref m2m_wifi_set_static_ip. + +@see + m2m_wifi_set_static_ip +*/ +int8_t m2m_wifi_enable_dhcp(uint8_t u8DhcpEn); + +/*! +@ingroup WLANSCAN +@fn \ + int8_t m2m_wifi_set_scan_options(tstrM2MScanOption *ptstrM2MScanOption); + +@brief + Synchronous API for configuring the behaviour of the WINC network scanning functions. + +@details + This function allows the application to tune the scanning behaviour of the WINC using the + parameters described in @ref tstrM2MScanOption. + +@param[in] ptstrM2MScanOption; + Pointer to the structure holding the Scan Parameters. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + tenuM2mScanCh + m2m_wifi_request_scan + tstrM2MScanOption +*/ +int8_t m2m_wifi_set_scan_options(tstrM2MScanOption *ptstrM2MScanOption); + +/*! +@ingroup WLANSCAN +@fn \ + int8_t m2m_wifi_set_scan_region(uint16_t u16ScanRegion); + +@brief + Synchronous API for configuring the regulatory restrictions that may affect the WINC scanning behaviour. + +@details + This function sets a property called the scan region, a parameter that affects the range of + channels that the WINC may legally scan given a geographic region. + + For 2.4GHz, supported in the current release, the requested scan region cannot exceed the + maximum number of channels (14). + +@param[in] u16ScanRegion + @ref ASIA + @ref EUROPE + @ref NORTH_AMERICA + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + tenuM2mScanRegion + m2m_wifi_request_scan +*/ +int8_t m2m_wifi_set_scan_region(uint16_t u16ScanRegion); + +/*! +@ingroup WLANSCAN +@fn \ + int8_t m2m_wifi_request_scan(uint8_t u8Ch); + +@brief + Asynchronous API to request the WINC to scan for networks. + +@details + Scan statuses are delivered to the application via the Wi-Fi event callback (@ref tpfAppWifiCb) in + three stages. The first step involves the event @ref M2M_WIFI_RESP_SCAN_DONE which, if successful, + provides the number of detected networks (access points). The application must then read the list + of access points via multiple calls to the asynchronous @ref m2m_wifi_req_scan_result API. For + each call to this function, the application will receive (step three) the event + @ref M2M_WIFI_RESP_SCAN_RESULT. + +@param[in] u8Ch + RF Channel ID for SCAN operation. It should be set according to @ref tenuM2mScanCh, with a + value of @ref M2M_WIFI_CH_ALL to scan all channels. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@pre + - A Wi-Fi notification callback of type @ref tpfAppWifiCb MUST be implemented and registered at + initialization. Registration of the callback is done via @ref m2m_wifi_init. + - The events @ref M2M_WIFI_RESP_SCAN_DONE and @ref M2M_WIFI_RESP_SCAN_RESULT must be handled in + the (@ref tpfAppWifiCb) callback. + - The @ref m2m_wifi_handle_events function MUST be called to receive the responses in the + callback. + +@warning + This API is valid only for STA mode, it may be called regardless of connection state (connected or disconnected states). + +@see + M2M_WIFI_RESP_SCAN_DONE + M2M_WIFI_RESP_SCAN_RESULT + tpfAppWifiCb + tstrM2mWifiscanResult + tenuM2mScanCh + m2m_wifi_init + m2m_wifi_handle_events + m2m_wifi_req_scan_result + +@section WIFIExample6 Example + The code snippet demonstrates an example of how the scan request is called from the application's main function and the handling of + the events received in response. + +@include m2m_wifi_request_scan.c +@example m2m_wifi_request_scan.c +*/ +int8_t m2m_wifi_request_scan(uint8_t u8Ch); + +/*! +@ingroup WLANSCAN +@fn \ + int8_t m2m_wifi_request_scan_passive(uint8_t u8Ch, uint16_t u16ScanTime); + +@brief + Similar to @ref m2m_wifi_request_scan but performs passive scanning instead of active scanning. + +@param[in] u8Ch + RF Channel ID for SCAN operation. It should be set according to @ref tenuM2mScanCh. + With a value of @ref M2M_WIFI_CH_ALL, means to scan all channels. + +@param[in] u16ScanTime + The time in ms that passive scan is listening for beacons on each channel per one slot, enter 0 for default setting. + +@warning + This function is not allowed in AP mode. It works only for STA mode (both connected or disconnected states). + +@pre + - A Wi-Fi notification callback of type @ref tpfAppWifiCb MUST be implemented and registered at initialization. Registering the callback + is done through passing it to the @ref m2m_wifi_init. + - The events @ref M2M_WIFI_RESP_SCAN_DONE and @ref M2M_WIFI_RESP_SCAN_RESULT. + must be handled in the callback. + - The @ref m2m_wifi_handle_events function MUST be called to receive the responses in the callback. + +@see + M2M_WIFI_RESP_SCAN_DONE + M2M_WIFI_RESP_SCAN_RESULT + tpfAppWifiCb + tstrM2MScanOption + tstrM2mWifiscanResult + tenuM2mScanCh + m2m_wifi_init + m2m_wifi_request_scan + m2m_wifi_handle_events + m2m_wifi_req_scan_result + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +*/ +int8_t m2m_wifi_request_scan_passive(uint8_t u8Ch, uint16_t u16ScanTime); + +/*! +@ingroup WLANSCAN +@fn \ + int8_t m2m_wifi_request_scan_ssid_list(uint8_t u8Ch, uint8_t *pu8Ssidlist); + +@brief + Asynchronous Wi-Fi scan request on the given channel and the hidden scan list. + +@details + The scan status is delivered in the Wi-Fi event callback and then the application + is to read the scan results sequentially. + The number of APs found (N) is returned in event @ref M2M_WIFI_RESP_SCAN_DONE with the number of found + APs. + The application could read the list of APs by calling the function @ref m2m_wifi_req_scan_result N times. + +@param[in] u8Ch + RF Channel ID for SCAN operation. It should be set according to @ref tenuM2mScanCh. + With a value of @ref M2M_WIFI_CH_ALL, means to scan all channels. + +@param[in] pu8Ssidlist + u8SsidList is a buffer containing a list of hidden SSIDs to + include during the scan. The first byte in the buffer, u8SsidList[0], + is the number of SSIDs encoded in the string. The number of hidden SSIDs + cannot exceed @ref MAX_HIDDEN_SITES. All SSIDs are concatenated in the following + bytes and each SSID is prefixed with a one-byte header containing its length. + The total number of bytes in u8SsidList buffer, including length byte, cannot + exceed 133 bytes (MAX_HIDDEN_SITES SSIDs x 32 bytes each, which is max SSID length). + For instance, encoding the two hidden SSIDs "DEMO_AP" and "TEST" + results in the following buffer content: + +@code + uint8_t u8SsidList[14]; + u8SsidList[0] = 2; // Number of SSIDs is 2 + u8SsidList[1] = 7; // Length of the string "DEMO_AP" without NULL termination + memcpy(&u8SsidList[2], "DEMO_AP", 7); // Bytes index 2-9 containing the string DEMO_AP + u8SsidList[9] = 4; // Length of the string "TEST" without NULL termination + memcpy(&u8SsidList[10], "TEST", 4); // Bytes index 10-13 containing the string TEST +@endcode + +@note + It works with STA/AP mode (connected or disconnected). + +@pre + - A Wi-Fi notification callback of type @ref tpfAppWifiCb MUST be implemented and registered at initialization. Registering the callback + is done through passing it to the @ref m2m_wifi_init. + - The events @ref M2M_WIFI_RESP_SCAN_DONE and @ref M2M_WIFI_RESP_SCAN_RESULT. + must be handled in the callback. + - The @ref m2m_wifi_handle_events function MUST be called to receive the responses in the callback. + +@see + M2M_WIFI_RESP_SCAN_DONE + M2M_WIFI_RESP_SCAN_RESULT + tpfAppWifiCb + tstrM2mWifiscanResult + tenuM2mScanCh + m2m_wifi_init + m2m_wifi_handle_events + m2m_wifi_req_scan_result + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. + +@section WIFIExample6b Example + The code snippet demonstrates an example of how the scan request is called from the application's main function and the handling of + the events received in response. + +@include m2m_wifi_request_scan_ssid_list.c +@example m2m_wifi_request_scan_ssid_list.c +*/ +int8_t m2m_wifi_request_scan_ssid_list(uint8_t u8Ch, uint8_t *pu8Ssidlist); + +/*! +@ingroup WLANSCAN +@fn \ + uint8_t m2m_wifi_get_num_ap_found(void); + +@brief + Synchronous function to retrieve the number of AP's found during the last scan operation. + +@details + The function reads the number of APs from global variable which was updated in the Wi-Fi + callback function through the @ref M2M_WIFI_RESP_SCAN_DONE event. + Function used only in STA mode only. + +@see + m2m_wifi_request_scan + M2M_WIFI_RESP_SCAN_DONE + M2M_WIFI_RESP_SCAN_RESULT + +@pre + m2m_wifi_request_scan must be called first to ensure up to date results are available. + - A Wi-Fi notification callback of type @ref tpfAppWifiCb MUST be implemented and registered at initialization. Registering the callback + is done through passing it to the @ref m2m_wifi_init. + - The event @ref M2M_WIFI_RESP_SCAN_DONE must be handled in the callback to receive the requested scan information. + +@warning + This function must be called only in the Wi-Fi callback function when the events + @ref M2M_WIFI_RESP_SCAN_DONE or @ref M2M_WIFI_RESP_SCAN_RESULT are received. + Calling this function in any other place will result in undefined/outdated numbers. + +@return + Returns the number of AP's found in the last Scan Request. + +@section WIFIExample7 Example + The code snippet demonstrates an example of how the scan request is called from the application's main function and the handling of + the events received in response. + +@include m2m_wifi_get_num_ap_found.c +@example m2m_wifi_get_num_ap_found.c +*/ +uint8_t m2m_wifi_get_num_ap_found(void); + +/*! +@ingroup WLANSCAN +@fn \ + int8_t m2m_wifi_req_scan_result(uint8_t u8Index); + +@brief + Asynchronous API to request the information of an access point discovered via scanning. + +@details + This function allows the information of any discovered access point to be retrieved. When a + scan is completed, the application is informed of the number of networks (access points) + discovered. Calling this function with an index, N, will return the information for the Nth + access point. The information will be returned to the application via a + @ref M2M_WIFI_RESP_SCAN_RESULT event, and the response data may be obtained through casting + the pointer (pvMsg) to @ref tstrM2mWifiscanResult. + +@param[in] u8Index + Index for the requested result, the index range start from 0 till number of AP's found. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + tstrM2mWifiscanResult + m2m_wifi_get_num_ap_found + m2m_wifi_request_scan + +@pre + - @ref m2m_wifi_request_scan must be called first to ensure up to date results are available. + - A Wi-Fi notification callback of type @ref tpfAppWifiCb MUST be implemented and registered + in order to receive scan data after calling this function. Registration of the callback + is done via the @ref m2m_wifi_init function. + - The event @ref M2M_WIFI_RESP_SCAN_RESULT must be handled in the callback to receive the + requested scan information. + +@warning + - This API is valid only for STA mode, it may be called regardless of the connection state (connected or disconnected). + - Calling this function without first issuing a scan request may lead to stale data being recovered. + - Application code should refrain from introducing significant delays between issuing the scan + request and scan result requests. + +@section WIFIExample8 Example + The code snippet demonstrates an example of how the scan request is called from the application's main function and + the handling of the events received in the response. + +@include m2m_wifi_req_scan_result.c +@example m2m_wifi_req_scan_result.c +*/ +int8_t m2m_wifi_req_scan_result(uint8_t u8Index); + +/*! +@ingroup WLANCONNECT +@fn \ + int8_t m2m_wifi_req_curr_rssi(void); + +@brief + Asynchronous API to request the current Receive Signal Strength (RSSI) of the current connection. + +@details + This function will result in the application receiving the RSSI via a + @ref M2M_WIFI_RESP_CURRENT_RSSI event. + +@pre + - A Wi-Fi notification callback of type @ref tpfAppWifiCb MUST be implemented and registered + during initialization. Registration of the callback is done through passing it to @ref m2m_wifi_init + via the @ref tstrWifiInitParam initialization structure. + - The event @ref M2M_WIFI_RESP_CURRENT_RSSI must be handled in the callback to receive the requested Rssi information. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@section WIFIExample9 Example + The code snippet demonstrates how the RSSI request is called in the application's main function and the handling of the event received in the callback. + +@include m2m_wifi_req_curr_rssi.c +@example m2m_wifi_req_curr_rssi.c +*/ +int8_t m2m_wifi_req_curr_rssi(void); + +/*! +@ingroup WLANCONF +@fn \ + int8_t m2m_wifi_get_otp_mac_address(uint8_t *pu8MacAddr, uint8_t *pu8IsValid); + +@brief + Synchronous API to query the MAC address programmed into the WINC OTP memory. + +@details + This function attempts to read the device's MAC address from the One Time Programmable (OTP) + memory on the WINC. The presence (yes or no) of a MAC address in the OTP memory and, in the case + of it being present, its value is returned via RAM pointed to by the input arguments. + + Request the MAC address stored on the One Time Programmable(OTP) memory of the device. + The function is blocking until the response is received. + +@pre + Prior call to @ref m2m_wifi_init is required before any WIFI/socket function. + +@param[out] pu8MacAddr + Output MAC address buffer 6 bytes in size. Valid only if *pu8Valid=1. + +@param[out] pu8IsValid + A boolean value set by the callee to indicate the validity of pu8MacAddr in OTP. If no MAC has + been programmed in the OTP the value of this parameter will be zero; otherwise it will be non-zero. + +@return + The function returns @ref M2M_SUCCESS for success and a negative value otherwise. + +@see + m2m_wifi_get_mac_address +*/ +int8_t m2m_wifi_get_otp_mac_address(uint8_t *pu8MacAddr, uint8_t *pu8IsValid); + +/*! +@ingroup WLANCONF +@fn \ + int8_t m2m_wifi_get_mac_address(uint8_t *pu8MacAddr) + +@brief + Synchronous API to retrieve the MAC address currently in use by the device. + +@details + This function obtains the MAC address that is currently in use by the device. If the function + returns with @ref M2M_SUCCESS then the content of the memory referenced by pu8MacAddr will be + populated with the 6 byte MAC address; otherwise, that memory will be left unchanged. + +@pre + Prior call to @ref m2m_wifi_init is required before any WIFI/socket function. + +@param[out] pu8MacAddr + Pointer to a buffer in memory containing a 6-byte MAC address (provided function returns @ref M2M_SUCCESS). + +@return + The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise. + +@see + m2m_wifi_get_otp_mac_address +*/ +int8_t m2m_wifi_get_mac_address(uint8_t *pu8MacAddr); + +/*! +@ingroup WLANPS +@fn \ + int8_t m2m_wifi_set_sleep_mode(uint8_t u8PsTyp, uint8_t u8BcastEn); + +@brief + Synchronous API to set the power-save mode of the WINC. + +@details + This is one of the two synchronous power-save setting functions that allow the host MCU application + to tweak the system power consumption. Such tweaking can be done through one of two ways: + - 1) Changing the power save mode, to one of the allowed power save modes (see @ref tenuPowerSaveModes). This is done by setting the first parameter. + - 2) Configuring DTIM monitoring: Configuring beacon monitoring parameters by enabling or disabling the reception of broadcast/multicast data. + This is done by setting the second parameter. + +@param[in] u8PsTyp + Desired power saving mode. Supported types are enumerated in @ref tenuPowerSaveModes. + +@param[in] u8BcastEn + Broadcast reception enable flag. + If set to 1, the WINC will wake for each DTIM beacon to ensure broadcast traffic can be received. + If set to 0, the WINC will not wakeup at the DTIM beacon, ignoring broadcast traffic, instead it will + wake every N beacon periods, as per the negotiated Listen Interval. + +@warning + The function called once after initialization. + +@return + The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise. + +@see + tenuPowerSaveModes + m2m_wifi_get_sleep_mode + m2m_wifi_set_lsn_int +*/ +int8_t m2m_wifi_set_sleep_mode(uint8_t u8PsTyp, uint8_t u8BcastEn); + +/*! +@ingroup WLANPS +@fn \ + int8_t m2m_wifi_request_sleep(uint32_t u32SlpReqTime); + +@brief + Asynchronous API to place the WINC into sleep mode for a specified period of time. + +@details + Power-save sleep request function, which requests the WINC device to sleep in the currently configured + power save mode, as set using @ref m2m_wifi_set_sleep_mode, for a specific time as defined by the parameter + u32SlpReqTime (measured in milliseconds). + This function should be used when the WINC is running in @ref M2M_PS_MANUAL power save mode only. + A wake up request is automatically performed by the WINC device when any host driver API function, e.g. Wi-Fi or socket operation is called. + +@param[in] u32SlpReqTime + Request sleep time in ms.\n + The best recommended sleep duration is left to be determined by the application. + Taking into account that if the application sends notifications very rarely, + sleeping for a long time can be a power-efficient decision. + In contrast, applications that are sensitive for long periods of absence can experience + performance degradation in the connection if long sleeping times are used. + +@return + The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise. + +@warning + The function should be called in @ref M2M_PS_MANUAL power save mode only. As enumerated in @ref tenuPowerSaveModes. + It's also important to note that during the sleeping time while in the M2M_PS_MANUAL mode, AP beacon monitoring is + bypassed and the Wi-Fi-connection may drop if the sleep period is elongated. + +@see + tenuPowerSaveModes + m2m_wifi_set_sleep_mode +*/ +int8_t m2m_wifi_request_sleep(uint32_t u32SlpReqTime); + +/*! +@ingroup WLANPS +@fn \ + uint8_t m2m_wifi_get_sleep_mode(void); + +@brief + Synchronous API to retrieve the current power save mode of the WINC. + +@return + The current operating power saving mode. The value will be one of those from the enumerated type @ref tenuPowerSaveModes. + +@see + tenuPowerSaveModes + m2m_wifi_set_sleep_mode +*/ +uint8_t m2m_wifi_get_sleep_mode(void); + +/*! +@fn \ + int8_t m2m_wifi_req_client_ctrl(uint8_t u8Cmd); + +@brief + Asynchronous command sending function to the PS Client. + +@details + Asynchronous command sending function to the PS Client (a WINC board running the ps_firmware) + if the PS client sends any command, it will be received through the @ref M2M_WIFI_RESP_CLIENT_INFO event. + +@param[in] u8Cmd + Control command sent from PS Server to PS Client (command values defined by the application) + +@pre + @ref m2m_wifi_req_server_init should be called first. + +@warning + This mode is not supported in the current release. + +@see + m2m_wifi_req_server_init + M2M_WIFI_RESP_CLIENT_INFO + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +*/ +int8_t m2m_wifi_req_client_ctrl(uint8_t u8Cmd); + +/*! +@fn \ + int8_t m2m_wifi_req_server_init(uint8_t u8Ch); + +@brief + Synchronous function to initialize the PS Server. + +@details + The WINC supports non secure communication with another WINC, + (SERVER/CLIENT) through one byte command (probe request and probe response) without any connection setup. + The server mode can't be used with any other modes (STA/AP) + +@param[in] u8Ch + Server listening channel + +@see + m2m_wifi_req_client_ctrl + +@warning + This mode is not supported in the current release. + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +*/ +int8_t m2m_wifi_req_server_init(uint8_t u8Ch); + +/*! +@ingroup WLANCONF +@fn \ + int8_t m2m_wifi_set_device_name(uint8_t *pu8DeviceName, uint8_t u8DeviceNameLength); + +@brief + Asynchronous API to set the Wi-Fi Direct "Device Name" of the WINC. + +@details + Sets the WINC device name. The name string is used as a device name in DHCP + hostname (option 12). + If a device is not set through this function a default name is assigned. + The default name is WINC-XX-YY, where XX and YY are the last 2 octets of the OTP + MAC address. If OTP (eFuse) is programmed, then the default name is WINC-00-00. + +@warning + The function called once after initialization.\n + Used for DHCP client hostname option (12).\n + Device name shall contain only characters allowed in valid internet host name as + defined in RFC 952 and 1123. + +@param[in] pu8DeviceName + Buffer holding the device name. Device name is a null terminated C string. + +@param[in] u8DeviceNameLength + Length of the device name. Should not exceed the maximum device name's + length @ref M2M_DEVICE_NAME_MAX (including null character). + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. +*/ +int8_t m2m_wifi_set_device_name(uint8_t *pu8DeviceName, uint8_t u8DeviceNameLength); + +/*! +@ingroup WLANTIME +@fn \ + int8_t m2m_wifi_configure_sntp(uint8_t *pu8NTPServerName, uint8_t u8NTPServerNameLength, tenuSNTPUseDHCP enuUseDHCP); + +@brief + Configures what NTP server the SNTP client should use. + +@details + Configures what NTP server the SNTP client should use. Only 1 server name can be provided, if the configured server name begins with an asterisk then it will be treated as a server pool. + The SNTP client can also use the NTP server provided by the DHCP server through option 42. + By default the NTP server provided by DHCP will be tried first, then the built-in default NTP server (time.nist.gov) will be used. + Configuring a server name will overwrite the built-in default server until next reboot. + +@param[in] pu8NTPServerName + Buffer holding the NTP server name. If the first character is an asterisk (*) then it will be treated as a server pool, where the asterisk will + be replaced with an incrementing value from 0 to 3 each time a server fails (example: *.pool.ntp.org). + +@param[in] u8NTPServerNameLength + Length of the NTP server name. Should not exceed the maximum NTP server name length of @ref M2M_NTP_MAX_SERVER_NAME_LENGTH. + +@param[in] enuUseDHCP + Should the NTP server provided by the DHCP server be used. + +@return + The function returns @ref M2M_SUCCESS for success and a negative value otherwise. +*/ +int8_t m2m_wifi_configure_sntp(uint8_t *pu8NTPServerName, uint8_t u8NTPServerNameLength, tenuSNTPUseDHCP enuUseDHCP); + +/*! +@ingroup WLANPS +@fn \ + int8_t m2m_wifi_set_lsn_int(tstrM2mLsnInt *pstrM2mLsnInt); + +@brief + Asynchronous API to set Wi-Fi listen interval for power save operation. + +@details + This is one of the two synchronous power-save setting functions that + allow the host MCU application to tweak the system power consumption. Such tweaking can be done by modifying the + Wi-Fi listen interval. The listen interval is how many beacon periods the station can sleep before it wakes up to receive data buffered in the AP. + It is represented in units of AP beacon periods(100ms). + +@warning + The function should be called once after initialization. + +@param[in] pstrM2mLsnInt + Structure holding the listen interval configuration. + +@pre + The function @ref m2m_wifi_set_sleep_mode shall be called first, to set the power saving mode required. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + tstrM2mLsnInt + m2m_wifi_set_sleep_mode +*/ +int8_t m2m_wifi_set_lsn_int(tstrM2mLsnInt *pstrM2mLsnInt); + +/*! +@ingroup WLANETH +@fn \ + int8_t m2m_wifi_send_ethernet_pkt(uint8_t *pu8Packet, uint16_t u16PacketSize); + +@brief + Asynchronous API to queue an Ethernet packet for transmission by the WINC. + +@details + Transmit a packet directly in ETHERNET/bypass mode where the TCP/IP stack is disabled + and the implementation of this packet is left to the application developer. + The Ethernet packet composition is left to the application developer. + +@note + Packets are the user's responsibility. + +@warning + This function available in ETHERNET/Bypass mode ONLY. Make sure that application defines ETH_MODE. + +@param[in] pu8Packet + Pointer to a buffer holding the whole Ethernet frame. + +@param[in] u16PacketSize + The size of the whole packet in bytes. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + m2m_wifi_enable_mac_mcast + m2m_wifi_set_receive_buffer +*/ +int8_t m2m_wifi_send_ethernet_pkt(uint8_t *pu8Packet, uint16_t u16PacketSize); + +/*! +@ingroup WLANTIME +@fn \ + int8_t m2m_wifi_enable_sntp(uint8_t u8Enable); + +@brief + Asynchronous API to enable or disable the native Simple Network Time Protocol(SNTP) client running on the WINC. + +@details + The SNTP client is enabled by default during chip initialization. This function can be used to + disable or subsequently re-enable the service. + + The service is capable of synchronizing the WINC system clock to the UTC time from a well-known + (and trusted) time server, for example "time.nist.gov". By default the SNTP client will update the + system time once every 24 hours. The ability to track the time accurately is important for various + applications such as checking expiry of X509 certificates during TLS (Transport Layer Security) + session establishment. + + It is highly recommended to leave SNTP enabled if there is no alternative source of timing + information. For systems including an RTC device, SNTP may not be needed and the WINC's time + may be set using the @ref m2m_wifi_set_system_time function. + +@param[in] u8Enable + Enables or disables the SNTP service + '0' :disable SNTP + '1' :enable SNTP + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + m2m_wifi_set_system_time + */ +int8_t m2m_wifi_enable_sntp(uint8_t u8Enable); + +/*! +@ingroup WLANTIME +@fn \ + int8_t m2m_wifi_set_system_time(uint32_t u32UTCSeconds); + +@brief + Asynchronous function for setting the system time within the WINC. + +@details + Function for setting the system time in time/date format (uint32_t). + The @ref tstrSystemTime structure can be used as a reference to the time values that + should be set and pass its value as uint32_t. + +@param[in] u32UTCSeconds + Seconds elapsed since January 1, 1900 (NTP Timestamp). + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + m2m_wifi_enable_sntp + tstrSystemTime + +@note + If there is an RTC on the host MCU, the SNTP may be disabled and the host may set the system + time within the firmware using the API @ref m2m_wifi_set_system_time. + */ +int8_t m2m_wifi_set_system_time(uint32_t u32UTCSeconds); + +/*! +@ingroup WLANTIME +@fn \ + int8_t m2m_wifi_get_system_time(void); + +@brief + Asynchronous API to obtain the system time in use by the WINC. + +@details + This function will request the WINC to report its current system time to the application. The + information will arrive at the application via the @ref tpfAppWifiCb and event @ref M2M_WIFI_RESP_GET_SYS_TIME. + Response time retrieved is parsed into the members defined in the structure @ref tstrSystemTime. + +@note + - A Wi-Fi notification callback of type @ref tpfAppWifiCb MUST be implemented and registered + during initialization. Registration of the callback is done via the @ref m2m_wifi_init API. + - The event @ref M2M_WIFI_RESP_GET_SYS_TIME must be handled in the callback. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + m2m_wifi_enable_sntp + tstrSystemTime + */ +int8_t m2m_wifi_get_system_time(void); + +/*! +@ingroup WLANCONF +@fn \ + int8_t m2m_wifi_set_cust_InfoElement(uint8_t *pau8M2mCustInfoElement); + +@brief + Asynchronous API to add or remove a user-defined Information Element. + +@details + This function allows the application to provide a custom Information Element to the + WINC that will be included in all beacon and probe response frames, while in Access Point mode. + If it is required to delete these IEs, fill the buffer with zeros. + +@param[in] pau8M2mCustInfoElement + Pointer to Buffer containing the IE to be used. It is the application developer's + responsibility to ensure on the correctness of the information element's ordering + passed in. + If the pointer is null, this removes any current custom IE. If non-null, the pointer + must reference data in the following format: + +@verbatim + --------------- ---------- ---------- ------------------- -------- -------- ----------- ----------------------- + | Byte[0] | Byte[1] | Byte[2] | Byte[3:length1+2] | ..... | Byte[n] | Byte[n+1] | Byte[n+2:lengthx+2] | + |---------------|----------|----------|-------------------|-------- --------|-----------|---------------------| + | #of all Bytes | IE1 ID | Length1 | Data1(Hex Coded) | ..... | IEx ID | Lengthx | Datax(Hex Coded) | + --------------- ---------- ---------- ------------------- -------- -------- ----------- ----------------------- +@endverbatim + +@warning + Size of All elements combined must not exceed 255 byte. + Used in Access Point Mode. + +@note + IEs Format will follow the above format. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + m2m_wifi_enable_sntp + +@section WIFIExample11 Example + The example demonstrates how the information elements are set using this function. + +@include m2m_wifi_set_cust_InfoElement.c +@example m2m_wifi_set_cust_InfoElement.c + */ +int8_t m2m_wifi_set_cust_InfoElement(uint8_t *pau8M2mCustInfoElement); + +/*! +@ingroup WLANPS +@fn \ + int8_t m2m_wifi_set_power_profile(uint8_t u8PwrMode); + +@brief + Change the power profile mode. + +@param[in] u8PwrMode + Change the WINC power profile to different mode based on the enumeration @ref tenuM2mPwrMode. + +@warning + May only be called after initialization, before any connection request, and may not be used to change + the power mode thereafter. + +@return + The function returns @ref M2M_SUCCESS for success and a negative value otherwise. + +@see + tenuM2mPwrMode + m2m_wifi_init +*/ +int8_t m2m_wifi_set_power_profile(uint8_t u8PwrMode); + +/*! +@ingroup WLANCONF +@fn \ + int8_t m2m_wifi_set_tx_power(uint8_t u8TxPwrLevel); + +@brief + Set the TX power tenuM2mTxPwrLevel. + +@param[in] u8TxPwrLevel + Change the TX power based on the enumeration @ref tenuM2mTxPwrLevel. + +@pre + Must be called after the initialization and before any connection request and can't be changed in runtime. + +@return + The function returns @ref M2M_SUCCESS for success and a negative value otherwise. + +@see + tenuM2mTxPwrLevel + m2m_wifi_init +*/ +int8_t m2m_wifi_set_tx_power(uint8_t u8TxPwrLevel); + +/*! +@ingroup WLANCONF +@fn \ + int8_t m2m_wifi_set_gain_table_idx(uint8_t u8GainTableIdx); + +@brief + Set the Gain table index corresponding to specific WiFi region. + +@param[in] u8GainTableIdx + Change the gain table index based on the WiFi region it is suppose to be used. + +@pre + Must be called after the initialization and before any connection request. + The corresponding gain tables must be present in the flash. + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. + +@see + m2m_wifi_init +*/ +int8_t m2m_wifi_set_gain_table_idx(uint8_t u8GainTableIdx); + +/*! +@ingroup WLANLOG +@fn \ + int8_t m2m_wifi_enable_firmware_logs(uint8_t u8Enable); + +@brief + Enable or Disable logs in run time. + +@details + Enable or Disable logs in run time (Disable Firmware logs will enhance the firmware start-up time and performance). + +@param[in] u8Enable + Set 1 to enable the logs, 0 for disable. + +@pre + Must be called after initialization through the following function @ref m2m_wifi_init. + +@return + The function returns @ref M2M_SUCCESS for success and a negative value otherwise. + +@see + __DISABLE_FIRMWARE_LOGS__ (build option to disable logs from initializations) + m2m_wifi_init +*/ +int8_t m2m_wifi_enable_firmware_logs(uint8_t u8Enable); + +/*! +@ingroup WLANCONF +@fn \ + int8_t m2m_wifi_set_battery_voltage(uint16_t u16BattVoltx100); + +@brief + Set the battery voltage to update the firmware calculations. + +@pre + Must be called after initialization through the following function @ref m2m_wifi_init. + +@param[in] u16BattVoltx100 + Battery Voltage as double. + +@return + The function returns @ref M2M_SUCCESS for success and a negative value otherwise. + +@see + m2m_wifi_init +*/ +int8_t m2m_wifi_set_battery_voltage(uint16_t u16BattVoltx100); + +/*! +@ingroup WLANCONF +@fn \ + int8_t m2m_wifi_set_gains(tstrM2mWifiGainsParams *pstrM2mGain); + +@brief + Set the chip PPA gain for 11b/11gn. + +@param[in] pstrM2mGain + @ref tstrM2mWifiGainsParams contain gain parameters as implemented in rf document. + +@pre + Must be called after initialization through the following function @ref m2m_wifi_init. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + m2m_wifi_init +*/ +int8_t m2m_wifi_set_gains(tstrM2mWifiGainsParams *pstrM2mGain); + +#ifdef ETH_MODE +/*! +@ingroup WLANETH +@fn \ + int8_t m2m_wifi_enable_mac_mcast(uint8_t *pu8MulticastMacAddress, uint8_t u8AddRemove); + +@brief + Asynchronous API to add or remove MAC addresses to the multicast filter. + +@details + This function will configure the WINC to receive/ignore multicast packets from certain + MAC address groups when operating in bypass mode. + This function requests the given MAC addresses to be added/removed from the multicast filter. + +@param[in] pu8MulticastMacAddress + Pointer to MAC address + +@param[in] u8AddRemove + A flag to add or remove the MAC ADDRESS, based on the following values: + - 0 : remove MAC address + - 1 : add MAC address + +@note + Maximum number of MAC addresses that could be added is 8. + +@warning + This function is available in ETHERNET/bypass mode ONLY. + Make sure that the application defines ETH_MODE. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + m2m_wifi_set_receive_buffer + m2m_wifi_send_ethernet_pkt + */ +int8_t m2m_wifi_enable_mac_mcast(uint8_t *pu8MulticastMacAddress, uint8_t u8AddRemove); + +/*! +@ingroup WLANETH +@fn \ + int8_t m2m_wifi_set_receive_buffer(void *pvBuffer, uint16_t u16BufferLen); + +@brief + Synchronous function for setting or modifying the receiver buffer's length. + +@details + Synchronous function for setting or modifying the receiver buffer's length. + In the ETHERNET/bypass mode the application should define a callback of type + @ref tpfAppEthCb, through which the application handles the received + ethernet frames. It is through this callback function that the user can + dynamically modify the length of the currently used receiver buffer. + +@param[in] pvBuffer + Pointer to Buffer to receive data. + NULL pointer causes a negative error @ref M2M_ERR_FAIL. + +@param[in] u16BufferLen + Length of data to be received. Maximum length of data should not exceed the size defined by TCP/IP + defined as @ref SOCKET_BUFFER_MAX_LENGTH + +@warning + This function is available in the Ethernet/bypass mode ONLY. Make sure that the application defines ETH_MODE. + +@return + The function returns @ref M2M_SUCCESS if the command has been successfully queued to the WINC and a negative value otherwise. + +@see + m2m_wifi_enable_mac_mcast + m2m_wifi_send_ethernet_pkt +*/ +int8_t m2m_wifi_set_receive_buffer(void *pvBuffer, uint16_t u16BufferLen); +#endif /* ETH_MODE */ + +/*! +@ingroup WLANCRYPTO +@fn \ + int8_t m2m_wifi_prng_get_random_bytes(uint8_t *pu8PrngBuff, uint16_t u16PrngSize); + +@brief + Asynchronous function for retrieving from the firmware a pseudo-random set of bytes. + +@details + Asynchronous function for retrieving from the firmware a pseudo-random set of bytes as specified in the size passed in as a parameter. + The registered Wi-Fi-cb function retrieves the random bytes through the response @ref M2M_WIFI_RESP_GET_PRNG + +@param[in] pu8PrngBuff + Pointer to a buffer to receive data. + +@param[in] u16PrngSize + Request size in bytes + +@warning + Size greater than the maximum specified (@ref M2M_BUFFER_MAX_SIZE - sizeof(tstrPrng)) + causes a negative error @ref M2M_ERR_FAIL. + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +*/ +int8_t m2m_wifi_prng_get_random_bytes(uint8_t *pu8PrngBuff, uint16_t u16PrngSize); + +/*! +@ingroup WLANCONF +@fn \ + int8_t m2m_wifi_conf_auto_rate(tstrConfAutoRate *pstrConfAutoRate); + +@brief + Configures WLAN automatic TX rate adaptation algorithm. + +@details + Allow the host MCU app to configure auto TX rate selection algorithm. The application can use this + API to tweak the algorithm performance. Moreover, it allows the application to force a specific WLAN + PHY rate for transmitted data packets to favor range vs. throughput needs. + +@param[in] pstrConfAutoRate + The Auto rate configuration parameters as listed in tstrConfAutoRate. + +@return + The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise. + +@see + tstrConfAutoRate +*/ +int8_t m2m_wifi_conf_auto_rate(tstrConfAutoRate *pstrConfAutoRate); + +/*! +@ingroup WLANROAMING +@fn \ + int8_t m2m_wifi_enable_roaming(uint8_t u8EnableDhcp); + +@brief + Enable WiFi STA roaming. + +@details + m2m_wifi_enable_roaming enables the firmware to trigger the roaming algorithm/steps on link loss with the current AP. + If roaming is successful, + the @ref M2M_WIFI_RESP_CON_STATE_CHANGED message with state as @ref M2M_WIFI_ROAMED is sent to host. + Additionally a @ref M2M_WIFI_REQ_DHCP_CONF message with new DHCP lease details is sent to host (only if u8EnableDhcp=1). + If roaming is unsuccessful, + @ref M2M_WIFI_RESP_CON_STATE_CHANGED message with state as @ref M2M_WIFI_DISCONNECTED is sent to host. + +@param[in] u8EnableDhcp + 0 : Disables DHCP client execution after roaming to new AP + 1 : Enables DHCP client execution after roaming to new AP + +@pre + Must be called after the initialization. + The roaming algorithm/procedure is internal to the firmware. + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. + +@see + m2m_wifi_init +*/ +int8_t m2m_wifi_enable_roaming(uint8_t u8EnableDhcp); +/*! +@ingroup WLANROAMING +@fn \ + int8_t m2m_wifi_disable_roaming(void); + +@brief + Disable WiFi STA roaming. + +@pre + Must be called after the initialization. + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. + +@see + m2m_wifi_init +*/ +int8_t m2m_wifi_disable_roaming(void); + +/*! +@ingroup WLANINIT +@fn \ + uint8_t m2m_wifi_get_state(void); + +@brief + Get the Wi-Fi state. + +@return + The function returns the current Wi-Fi state (see @ref tenuWifiState for the possible states). + +@note + Check the WINC state. See @ref tenuWifiState for possible states.\n + @ref WIFI_STATE_INIT state represents WINC initialized but not started, this is a suitable state + for safe flash access. + +@sa + m2m_wifi_init + m2m_wifi_download_mode +*/ +uint8_t m2m_wifi_get_state(void); + +/** @defgroup VERSION Version + @brief + Describes the APIs for reading the version information of the WINC firmware. + @{ + @defgroup VERSIONDEF Defines + @brief + Specifies the macros and defines used by the version APIs. + + @defgroup VERSIONAPI Functions + @brief + Lists the APIs for reading the version information of the WINC firmware. + @} + */ + +/*! +@ingroup VERSIONAPI +@fn \ + int8_t m2m_wifi_get_firmware_version(tstrM2mRev *pstrRev) + +@brief + Synchronous API to obtain the firmware version currently running on the WINC. + +@details + Get the Firmware version info from the active partition, as defined in the structure @ref tstrM2mRev. + +@param[out] pstrRev + Pointer to a variable of type @ref tstrM2mRev, which contains the firmware version parameters. + +@return + The function returns @ref M2M_SUCCESS for success and a negative value otherwise. + +@pre + Must be called after initialization through the following function @ref m2m_wifi_init. + +@sa + m2m_wifi_init +*/ +int8_t m2m_wifi_get_firmware_version(tstrM2mRev *pstrRev); + +#ifdef __cplusplus +} +#endif +#endif /* __M2M_WIFI_H__ */ + diff --git a/AVRIoT.X/mcc_generated_files/winc/readme.md b/AVRIoT.X/mcc_generated_files/winc/readme.md new file mode 100644 index 0000000..2009d37 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/readme.md @@ -0,0 +1 @@ +## This folder will contain the source and header files generated using the WINC library's ftl files. \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/winc/socket/socket.c b/AVRIoT.X/mcc_generated_files/winc/socket/socket.c new file mode 100644 index 0000000..b6b3141 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/socket/socket.c @@ -0,0 +1,1020 @@ +/** + * + * \file + * + * \brief Socket Interface. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +INCLUDES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +#include "../driver/winc_adapter.h" +#include "../common/winc_defines.h" +#include "../common/winc_debug.h" +#include "../m2m/m2m_types.h" +#include "socket.h" +#include "../m2m/m2m_socket_host_if.h" +#include "../driver/winc_hif.h" + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +MACROS +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + +#define TLS_RECORD_HEADER_LENGTH (5) +#define ETHERNET_HEADER_OFFSET (34) +#define ETHERNET_HEADER_LENGTH (14) +#define TCP_IP_HEADER_LENGTH (40) +#define UDP_IP_HEADER_LENGTH (28) + +#define IP_PACKET_OFFSET (ETHERNET_HEADER_LENGTH + ETHERNET_HEADER_OFFSET - M2M_HIF_HDR_OFFSET) + +#define TCP_TX_PACKET_OFFSET (IP_PACKET_OFFSET + TCP_IP_HEADER_LENGTH) +#define UDP_TX_PACKET_OFFSET (IP_PACKET_OFFSET + UDP_IP_HEADER_LENGTH) +#define SSL_TX_PACKET_OFFSET (TCP_TX_PACKET_OFFSET + TLS_RECORD_HEADER_LENGTH) + +#define SSL_FLAGS_ACTIVE NBIT0 +#define SSL_FLAGS_BYPASS_X509 NBIT1 +#define SSL_FLAGS_2_RESERVD NBIT2 +#define SSL_FLAGS_3_RESERVD NBIT3 +#define SSL_FLAGS_CACHE_SESSION NBIT4 +#define SSL_FLAGS_NO_TX_COPY NBIT5 +#define SSL_FLAGS_CHECK_SNI NBIT6 + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +PRIVATE DATA TYPES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + +/*! +* @brief +*/ +typedef struct{ + SOCKET sock; + uint8_t u8Dummy; + uint16_t u16SessionID; +}tstrCloseCmd; + + +/*! +* @brief +*/ +typedef struct{ + uint8_t *pu8UserBuffer; + uint16_t u16UserBufferSize; + uint16_t u16SessionID; + uint16_t u16DataOffset; + uint8_t bIsUsed; + uint8_t u8SSLFlags; + uint8_t bIsRecvPending; +}tstrSocket; + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +GLOBALS +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +static tstrSocket gastrSockets[MAX_SOCKET]; +static uint16_t gu16SessionID = 0; + +static tpfAppSocketCb gpfAppSocketCb; +static tpfAppResolveCb gpfAppResolveCb; +static uint8_t gbSocketInit = 0; +static tpfPingCb gfpPingCb; +static uint32_t gu32PingId = 0; + +static void Socket_ReadSocketData(SOCKET sock, tstrSocketRecvMsg *pstrRecv,uint8_t u8SocketMsg, + uint32_t u32StartAddress, uint16_t u16ReadCount) +{ + tstrSocket *pstrSocket = &gastrSockets[sock]; + + if((u16ReadCount > 0) && (pstrSocket->pu8UserBuffer != NULL) && (pstrSocket->u16UserBufferSize > 0) && (pstrSocket->bIsUsed == 1)) + { + uint16_t u16Read; + + pstrRecv->u16RemainingSize = u16ReadCount; + do + { + u16Read = u16ReadCount; + if (u16ReadCount > pstrSocket->u16UserBufferSize) + u16Read = pstrSocket->u16UserBufferSize; + + if(winc_hif_receive(u32StartAddress, pstrSocket->pu8UserBuffer, u16Read) == M2M_SUCCESS) + { + pstrRecv->pu8Buffer = pstrSocket->pu8UserBuffer; + pstrRecv->s16BufferSize = u16Read; + pstrRecv->u16RemainingSize -= u16Read; + + if (gpfAppSocketCb) + gpfAppSocketCb(sock, u8SocketMsg, pstrRecv); + + u16ReadCount -= u16Read; + u32StartAddress += u16Read; + + if((!pstrSocket->bIsUsed) && (u16ReadCount)) + { + WINC_LOG_DEBUG("Application Closed Socket While Rx Is not Complete"); + break; + } + } + else + { + WINC_LOG_INFO("(ERRR)Current <%u>", u16ReadCount); + break; + } + } + while(u16ReadCount != 0); + } +} + +void m2m_ip_cb(uint8_t u8OpCode, uint16_t u16BufferSize, uint32_t u32Address) +{ + if((u8OpCode == SOCKET_CMD_BIND) || (u8OpCode == SOCKET_CMD_SSL_BIND)) + { + tstrBindReply strBindReply; + tstrSocketBindMsg strBind; + + if(winc_hif_receive(u32Address, &strBindReply, sizeof(tstrBindReply)) == M2M_SUCCESS) + { + strBind.status = strBindReply.s8Status; + if(gpfAppSocketCb) + gpfAppSocketCb(strBindReply.sock, SOCKET_MSG_BIND, &strBind); + } + } + else if(u8OpCode == SOCKET_CMD_LISTEN) + { + tstrListenReply strListenReply; + tstrSocketListenMsg strListen; + if(winc_hif_receive(u32Address, &strListenReply, sizeof(tstrListenReply)) == M2M_SUCCESS) + { + strListen.status = strListenReply.s8Status; + if(gpfAppSocketCb) + gpfAppSocketCb(strListenReply.sock, SOCKET_MSG_LISTEN, &strListen); + } + } + else if(u8OpCode == SOCKET_CMD_ACCEPT) + { + tstrAcceptReply strAcceptReply; + tstrSocketAcceptMsg strAccept; + if(winc_hif_receive(u32Address, &strAcceptReply, sizeof(tstrAcceptReply)) == M2M_SUCCESS) + { + if(strAcceptReply.sConnectedSock >= 0) + { + gastrSockets[strAcceptReply.sConnectedSock].u8SSLFlags = gastrSockets[strAcceptReply.sListenSock].u8SSLFlags; + gastrSockets[strAcceptReply.sConnectedSock].bIsUsed = 1; + gastrSockets[strAcceptReply.sConnectedSock].u16DataOffset = strAcceptReply.u16AppDataOffset - M2M_HIF_HDR_OFFSET; + + /* The session ID is used to distinguish different socket connections + by comparing the assigned session ID to the one reported by the firmware*/ + ++gu16SessionID; + if(gu16SessionID == 0) + ++gu16SessionID; + + gastrSockets[strAcceptReply.sConnectedSock].u16SessionID = gu16SessionID; + WINC_LOG_DEBUG("Socket %d session ID = %u", strAcceptReply.sConnectedSock, gu16SessionID); + } + strAccept.sock = strAcceptReply.sConnectedSock; + strAccept.strAddr.sin_family = AF_INET; + strAccept.strAddr.sin_port = strAcceptReply.strAddr.u16Port; + strAccept.strAddr.sin_addr.s_addr = strAcceptReply.strAddr.u32IPAddr; + if(gpfAppSocketCb) + gpfAppSocketCb(strAcceptReply.sListenSock, SOCKET_MSG_ACCEPT, &strAccept); + } + } + else if((u8OpCode == SOCKET_CMD_CONNECT) || (u8OpCode == SOCKET_CMD_SSL_CONNECT)) + { + tstrConnectReply strConnectReply; + tstrSocketConnectMsg strConnMsg; + if(winc_hif_receive(u32Address, &strConnectReply, sizeof(tstrConnectReply)) == M2M_SUCCESS) + { + strConnMsg.sock = strConnectReply.sock; + strConnMsg.s8Error = strConnectReply.s8Error; + if(strConnectReply.s8Error == SOCK_ERR_NO_ERROR) + { + gastrSockets[strConnectReply.sock].u16DataOffset = strConnectReply.u16AppDataOffset - M2M_HIF_HDR_OFFSET; + } + if(gpfAppSocketCb) + gpfAppSocketCb(strConnectReply.sock, SOCKET_MSG_CONNECT, &strConnMsg); + } + } + else if(u8OpCode == SOCKET_CMD_DNS_RESOLVE) + { + tstrDnsReply strDnsReply; + if(winc_hif_receive(u32Address, &strDnsReply, sizeof(tstrDnsReply)) == M2M_SUCCESS) + { + if(gpfAppResolveCb) + gpfAppResolveCb((uint8_t*)strDnsReply.acHostName, strDnsReply.u32HostIP); + } + } + else if((u8OpCode == SOCKET_CMD_RECV) || (u8OpCode == SOCKET_CMD_RECVFROM) || (u8OpCode == SOCKET_CMD_SSL_RECV)) + { + SOCKET sock; + int16_t s16RecvStatus; + tstrRecvReply strRecvReply; + uint16_t u16ReadSize; + tstrSocketRecvMsg strRecvMsg; + uint8_t u8CallbackMsgID = SOCKET_MSG_RECV; + uint16_t u16DataOffset; + + if(u8OpCode == SOCKET_CMD_RECVFROM) + u8CallbackMsgID = SOCKET_MSG_RECVFROM; + + /* Read RECV REPLY data structure. + */ + u16ReadSize = sizeof(tstrRecvReply); + if(winc_hif_receive(u32Address, &strRecvReply, u16ReadSize) == M2M_SUCCESS) + { + uint16_t u16SessionID = 0; + + sock = strRecvReply.sock; + u16SessionID = strRecvReply.u16SessionID; + WINC_LOG_DEBUG("recv callback session ID = %u",u16SessionID); + + /* Reset the Socket RX Pending Flag. + */ + gastrSockets[sock].bIsRecvPending = 0; + + s16RecvStatus = WINC_TO_HOST_U16(strRecvReply.s16RecvStatus); + u16DataOffset = WINC_TO_HOST_U16(strRecvReply.u16DataOffset); + strRecvMsg.strRemoteAddr.sin_port = strRecvReply.strRemoteAddr.u16Port; + strRecvMsg.strRemoteAddr.sin_addr.s_addr = strRecvReply.strRemoteAddr.u32IPAddr; + + if(u16SessionID == gastrSockets[sock].u16SessionID) + { + if((s16RecvStatus > 0) && ((uint16_t)s16RecvStatus < u16BufferSize)) + { + /* Skip incoming bytes until reaching the Start of Application Data. + */ + u32Address += u16DataOffset; + + /* Read the Application data and deliver it to the application callback in + the given application buffer. If the buffer is smaller than the received data, + the data is passed to the application in chunks according to its buffer size. + */ + u16ReadSize = (uint16_t)s16RecvStatus; + Socket_ReadSocketData(sock, &strRecvMsg, u8CallbackMsgID, u32Address, u16ReadSize); + } + else + { + /* Don't tidy up here. Application must call close(). + */ + strRecvMsg.s16BufferSize = s16RecvStatus; + strRecvMsg.pu8Buffer = NULL; + if(gpfAppSocketCb) + gpfAppSocketCb(sock, u8CallbackMsgID, &strRecvMsg); + } + } + else + { + WINC_LOG_DEBUG("Discard recv callback %u %u", u16SessionID, gastrSockets[sock].u16SessionID); + } + } + } + else if((u8OpCode == SOCKET_CMD_SEND) || (u8OpCode == SOCKET_CMD_SENDTO) || (u8OpCode == SOCKET_CMD_SSL_SEND)) + { + SOCKET sock; + int16_t s16Rcvd; + tstrSendReply strReply; + uint8_t u8CallbackMsgID = SOCKET_MSG_SEND; + + if(u8OpCode == SOCKET_CMD_SENDTO) + u8CallbackMsgID = SOCKET_MSG_SENDTO; + + if(winc_hif_receive(u32Address, &strReply, sizeof(tstrSendReply)) == M2M_SUCCESS) + { + uint16_t u16SessionID = 0; + + sock = strReply.sock; + u16SessionID = strReply.u16SessionID; + WINC_LOG_DEBUG("send callback session ID = %u", u16SessionID); + + s16Rcvd = WINC_TO_HOST_U16(strReply.s16SentBytes); + + if(u16SessionID == gastrSockets[sock].u16SessionID) + { + if(gpfAppSocketCb) + gpfAppSocketCb(sock, u8CallbackMsgID, &s16Rcvd); + } + else + { + WINC_LOG_DEBUG("Discard send callback %u %u", u16SessionID, gastrSockets[sock].u16SessionID); + } + } + } + else if(u8OpCode == SOCKET_CMD_PING) + { + tstrPingReply strPingReply; + if(winc_hif_receive(u32Address, &strPingReply, sizeof(tstrPingReply)) == M2M_SUCCESS) + { + if((gu32PingId == strPingReply.u32CmdPrivate) && (gfpPingCb != NULL)) + { + gfpPingCb(strPingReply.u32IPAddr, strPingReply.u32RTT, strPingReply.u8ErrorCode); + } + gfpPingCb = NULL; + } + } +} + +void socketInit(void) +{ + if(gbSocketInit == 0) + { + memset(gastrSockets, 0, MAX_SOCKET * sizeof(tstrSocket)); + gbSocketInit = 1; + gu16SessionID = 0; + } +} + +void socketDeinit(void) +{ + memset(gastrSockets, 0, MAX_SOCKET * sizeof(tstrSocket)); + gpfAppSocketCb = NULL; + gpfAppResolveCb = NULL; + gfpPingCb = NULL; + gbSocketInit = 0; +} + +void registerSocketCallback(tpfAppSocketCb pfAppSocketCb, tpfAppResolveCb pfAppResolveCb) +{ + gpfAppSocketCb = pfAppSocketCb; + gpfAppResolveCb = pfAppResolveCb; +} + +void registerSocketEventCallback(tpfAppSocketCb pfAppSocketCb) +{ + gpfAppSocketCb = pfAppSocketCb; +} + +void registerSocketResolveCallback(tpfAppResolveCb pfAppResolveCb) +{ + gpfAppResolveCb = pfAppResolveCb; +} + +SOCKET socket(uint16_t u16Domain, uint8_t u8Type, uint8_t u8Flags) +{ + SOCKET sock = -1; + uint8_t u8SockID; + uint8_t u8Count; + tstrSocket *pstrSock = NULL; + static uint8_t u8NextTcpSock = 0; + static uint8_t u8NextUdpSock = 0; + + /* The only supported family is the AF_INET for UDP and TCP transport layer protocols. */ + if(u16Domain == AF_INET) + { + if(u8Type == SOCK_STREAM) + { + for(u8Count = 0; u8Count < TCP_SOCK_MAX; u8Count ++) + { + u8SockID = u8NextTcpSock; + pstrSock = &gastrSockets[u8NextTcpSock]; + u8NextTcpSock = (u8NextTcpSock + 1) % TCP_SOCK_MAX; + if(!pstrSock->bIsUsed) + { + sock = (SOCKET)u8SockID; + break; + } + } + } + else if(u8Type == SOCK_DGRAM) + { + tstrSocket *pastrUDPSockets = &gastrSockets[TCP_SOCK_MAX]; + for(u8Count = 0; u8Count < UDP_SOCK_MAX; u8Count ++) + { + u8SockID = u8NextUdpSock; + pstrSock = &pastrUDPSockets[u8NextUdpSock]; + u8NextUdpSock = (u8NextUdpSock + 1) % UDP_SOCK_MAX; + if(!pstrSock->bIsUsed) + { + sock = (SOCKET)(u8SockID + TCP_SOCK_MAX); + break; + } + } + } + + if(pstrSock) + { + memset(pstrSock, 0, sizeof(tstrSocket)); + pstrSock->bIsUsed = 1; + + /* The session ID is used to distinguish different socket connections + by comparing the assigned session ID to the one reported by the firmware*/ + ++gu16SessionID; + if(gu16SessionID == 0) + ++gu16SessionID; + + pstrSock->u16SessionID = gu16SessionID; + WINC_LOG_INFO("Socket %d session ID = %u", sock, gu16SessionID ); + + if(u8Flags & SOCKET_FLAGS_SSL) + { + tstrSSLSocketCreateCmd strSSLCreate; + strSSLCreate.sslSock = sock; + pstrSock->u8SSLFlags = SSL_FLAGS_ACTIVE | SSL_FLAGS_NO_TX_COPY; + winc_hif_send_no_data(M2M_REQ_GROUP_IP, SOCKET_CMD_SSL_CREATE, &strSSLCreate, sizeof(tstrSSLSocketCreateCmd)); + } + } + } + return sock; +} + +int8_t bind(SOCKET sock, struct sockaddr *pstrAddr, uint8_t u8AddrLen) +{ + tstrBindCmd strBind; + uint8_t u8CMD = SOCKET_CMD_BIND; + + if((pstrAddr == NULL) || (sock < 0) || (!gastrSockets[sock].bIsUsed) || (!u8AddrLen)) + return SOCK_ERR_INVALID_ARG; + + if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE) + { + u8CMD = SOCKET_CMD_SSL_BIND; + } + + /* Build the bind request. */ + strBind.sock = sock; + memcpy((uint8_t *)&strBind.strAddr, (uint8_t *)pstrAddr, sizeof(tstrSockAddr)); + + strBind.u16SessionID = gastrSockets[sock].u16SessionID; + + /* Send the request. */ + if (M2M_SUCCESS != winc_hif_send_no_data(M2M_REQ_GROUP_IP, u8CMD, &strBind,sizeof(tstrBindCmd))) + return SOCK_ERR_INVALID; + + return SOCK_ERR_NO_ERROR; +} + +int8_t listen(SOCKET sock, uint8_t u8Backlog) +{ + tstrListenCmd strListen; + + if((sock < 0) || (!gastrSockets[sock].bIsUsed)) + return SOCK_ERR_INVALID_ARG; + + strListen.sock = sock; + strListen.u8BackLog = u8Backlog; + strListen.u16SessionID = gastrSockets[sock].u16SessionID; + + if (M2M_SUCCESS != winc_hif_send_no_data(M2M_REQ_GROUP_IP, SOCKET_CMD_LISTEN, &strListen, sizeof(tstrListenCmd))) + return SOCK_ERR_INVALID; + + return SOCK_ERR_NO_ERROR; +} + +int8_t accept(SOCKET sock, struct sockaddr *pstrAddr, uint8_t *pu8AddrLen) +{ + UNUSED_VAR(pstrAddr); + UNUSED_VAR(pu8AddrLen); + + if ((sock < 0) || (!gastrSockets[sock].bIsUsed)) + return SOCK_ERR_INVALID_ARG; + + return SOCK_ERR_NO_ERROR; +} + +int8_t connect(SOCKET sock, struct sockaddr *pstrAddr, uint8_t u8AddrLen) +{ + tstrConnectCmd strConnect; + uint8_t u8Cmd = SOCKET_CMD_CONNECT; + + if((sock < 0) || (pstrAddr == NULL) || (!gastrSockets[sock].bIsUsed) || (!u8AddrLen)) + return SOCK_ERR_INVALID_ARG; + + if((gastrSockets[sock].u8SSLFlags) & SSL_FLAGS_ACTIVE) + { + u8Cmd = SOCKET_CMD_SSL_CONNECT; + strConnect.u8SslFlags = gastrSockets[sock].u8SSLFlags; + } + strConnect.sock = sock; + memcpy((uint8_t *)&strConnect.strAddr, (uint8_t *)pstrAddr, sizeof(tstrSockAddr)); + + strConnect.u16SessionID = gastrSockets[sock].u16SessionID; + if (M2M_SUCCESS != winc_hif_send_no_data(M2M_REQ_GROUP_IP, u8Cmd, &strConnect, sizeof(tstrConnectCmd))) + return SOCK_ERR_INVALID; + + return SOCK_ERR_NO_ERROR; +} + +int8_t send(SOCKET sock, void *pvSendBuffer, uint16_t u16SendLength, uint16_t u16Flags) +{ + UNUSED_VAR(u16Flags); + + uint16_t u16DataOffset; + tstrSendCmd strSend; + uint8_t u8Cmd; + + if((sock < 0) || (pvSendBuffer == NULL) || (u16SendLength > SOCKET_BUFFER_MAX_LENGTH) || (!gastrSockets[sock].bIsUsed)) + return SOCK_ERR_INVALID_ARG; + + u8Cmd = SOCKET_CMD_SEND; + u16DataOffset = TCP_TX_PACKET_OFFSET; + + strSend.sock = sock; + strSend.u16DataSize = HOST_TO_WINC_U16(u16SendLength); + strSend.u16SessionID = gastrSockets[sock].u16SessionID; + + if(sock >= TCP_SOCK_MAX) + { + u16DataOffset = UDP_TX_PACKET_OFFSET; + } + if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE) + { + u8Cmd = SOCKET_CMD_SSL_SEND; + u16DataOffset = gastrSockets[sock].u16DataOffset; + } + + if (M2M_SUCCESS != winc_hif_send(M2M_REQ_GROUP_IP, u8Cmd|M2M_REQ_DATA_PKT, &strSend, sizeof(tstrSendCmd), pvSendBuffer, u16SendLength, u16DataOffset)) + return SOCK_ERR_BUFFER_FULL; + + return SOCK_ERR_NO_ERROR; +} + +int8_t sendto(SOCKET sock, void *pvSendBuffer, uint16_t u16SendLength, uint16_t u16Flags, struct sockaddr *pstrAddr, uint8_t u8AddrLen) +{ + tstrSendCmd strSendTo; + + UNUSED_VAR(u16Flags); + UNUSED_VAR(u8AddrLen); + + if((sock < 0) || (pvSendBuffer == NULL) || (u16SendLength > SOCKET_BUFFER_MAX_LENGTH) || (!gastrSockets[sock].bIsUsed)) + return SOCK_ERR_INVALID_ARG; + + memset(&strSendTo, 0, sizeof(tstrSendCmd)); + + strSendTo.sock = sock; + strSendTo.u16DataSize = HOST_TO_WINC_U16(u16SendLength); + strSendTo.u16SessionID = gastrSockets[sock].u16SessionID; + + if(pstrAddr != NULL) + { + struct sockaddr_in *pstrDestAddr; + pstrDestAddr = (struct sockaddr_in*)pstrAddr; + + strSendTo.strAddr.u16Family = pstrDestAddr->sin_family; + strSendTo.strAddr.u16Port = pstrDestAddr->sin_port; + strSendTo.strAddr.u32IPAddr = pstrDestAddr->sin_addr.s_addr; + } + + if (M2M_SUCCESS != winc_hif_send(M2M_REQ_GROUP_IP, SOCKET_CMD_SENDTO|M2M_REQ_DATA_PKT, &strSendTo, sizeof(tstrSendCmd), + pvSendBuffer, u16SendLength, UDP_TX_PACKET_OFFSET)) + { + return SOCK_ERR_BUFFER_FULL; + } + + return SOCK_ERR_NO_ERROR; +} + +int8_t recv(SOCKET sock, void *pvRecvBuf, uint16_t u16BufLen, uint32_t u32Timeoutmsec) +{ + tstrRecvCmd strRecv; + uint8_t u8Cmd = SOCKET_CMD_RECV; + + if((sock < 0) || (pvRecvBuf == NULL) || (!u16BufLen) || (!gastrSockets[sock].bIsUsed)) + return SOCK_ERR_INVALID_ARG; + + gastrSockets[sock].pu8UserBuffer = (uint8_t*)pvRecvBuf; + gastrSockets[sock].u16UserBufferSize = u16BufLen; + + if (gastrSockets[sock].bIsRecvPending) + { + return SOCK_ERR_NO_ERROR; + } + + gastrSockets[sock].bIsRecvPending = 1; + + if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE) + { + u8Cmd = SOCKET_CMD_SSL_RECV; + } + + /* Check the timeout value. */ + if(u32Timeoutmsec == 0) + strRecv.u32Timeoutmsec = 0xFFFFFFFF; + else + strRecv.u32Timeoutmsec = HOST_TO_WINC_U32(u32Timeoutmsec); + + strRecv.sock = sock; + strRecv.u16SessionID = gastrSockets[sock].u16SessionID; + + if (M2M_SUCCESS != winc_hif_send_no_data(M2M_REQ_GROUP_IP, u8Cmd, &strRecv, sizeof(tstrRecvCmd))) + return SOCK_ERR_BUFFER_FULL; + + return SOCK_ERR_NO_ERROR; +} + +int8_t close(SOCKET sock) +{ + uint8_t u8Cmd = SOCKET_CMD_CLOSE; + tstrCloseCmd strclose; + + WINC_LOG_INFO("Sock to delete <%d>", sock); + + if((sock < 0) || (!gastrSockets[sock].bIsUsed)) + return SOCK_ERR_INVALID_ARG; + + strclose.sock = sock; + strclose.u16SessionID = gastrSockets[sock].u16SessionID; + + if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE) + { + u8Cmd = SOCKET_CMD_SSL_CLOSE; + } + + if (M2M_SUCCESS != winc_hif_send_no_data(M2M_REQ_GROUP_IP, u8Cmd, &strclose, sizeof(tstrCloseCmd))) + return SOCK_ERR_INVALID; + + memset(&gastrSockets[sock], 0, sizeof(tstrSocket)); + + return SOCK_ERR_NO_ERROR; +} + +int16_t recvfrom(SOCKET sock, void *pvRecvBuf, uint16_t u16BufLen, uint32_t u32Timeoutmsec) +{ + tstrRecvCmd strRecv; + + if((sock < 0) || (pvRecvBuf == NULL) || (!u16BufLen) || (!gastrSockets[sock].bIsUsed)) + { + return SOCK_ERR_INVALID_ARG; + } + + gastrSockets[sock].pu8UserBuffer = (uint8_t*)pvRecvBuf; + gastrSockets[sock].u16UserBufferSize = u16BufLen; + + if(gastrSockets[sock].bIsRecvPending) + return SOCK_ERR_NO_ERROR; + + gastrSockets[sock].bIsRecvPending = 1; + + /* Check the timeout value. */ + if(u32Timeoutmsec == 0) + strRecv.u32Timeoutmsec = 0xFFFFFFFF; + else + strRecv.u32Timeoutmsec = HOST_TO_WINC_U32(u32Timeoutmsec); + strRecv.sock = sock; + strRecv.u16SessionID = gastrSockets[sock].u16SessionID; + + if (M2M_SUCCESS != winc_hif_send_no_data(M2M_REQ_GROUP_IP, SOCKET_CMD_RECVFROM, &strRecv, sizeof(tstrRecvCmd))) + { + return SOCK_ERR_BUFFER_FULL; + } + + return SOCK_ERR_NO_ERROR; +} + +in_addr_t inet_addr(const char *cp) +{ + uint8_t i,l; + uint16_t t; + uint32_t ip; + char c; + + ip = 0; + + for (i=0; i<4; i++) + { + t = 0; + ip >>= 8; + + // Count non-delimiter or terminator characters + + for (l=0; l<4; l++) + { + c = cp[l]; + + if (('.' == c) || ('\0' == c)) + { + break; + } + } + + // There must be 1 to 3 characters + + if ((0 == l) || (4 == l)) + { + return 0; + } + + c = *cp++; + + // First digit can't be '0' unless it's the only one + + if ((l > 1) && (c == '0')) + { + return 0; + } + + while(l--) + { + // Each digit must be decimal + + if ((c < '0') || (c > '9')) + { + return 0; + } + + t = (t * 10) + (c - '0'); + + c = *cp++; + } + + // Total accumulated number must be less than 256 + + if (t > 255) + { + return 0; + } + + // Pack number into 32 bit IP address representation + + ip |= ((uint32_t)t << 24); + + // First three numbers must terminate with '.', last one with '\0's + + if ((('\0' == c) && (i != 3)) || (('\0' != c) && (i == 3))) + { + return 0; + } + } + + return ip; +} + +const char *inet_ntop(int af, const void *src, char *dst, size_t size) +{ + uint8_t i, v, t, c, n; + char *rp = dst; + uint32_t ip = ((struct in_addr*)src)->s_addr; + + if ((NULL == src) || (NULL == dst) || (size < INET_ADDRSTRLEN)) + { + return NULL; + } + + for (i=0; i<4; i++) + { + t = ip; + v = 100; + + // Check for zero + + if (t > 0) + { + n = 0; + + do + { + c = '0'; + while (t >= v) + { + c++; + t -= v; + } + v /= 10; + + if (('0' != c) || (n > 0)) + { + *dst++ = c; + + n++; + } + } + while (v > 0); + } + else + { + *dst++ = '0'; + } + + if (3 == i) + { + *dst++ = '\0'; + } + else + { + *dst++ = '.'; + } + + ip >>= 8; + } + + return rp; +} + +int8_t gethostbyname(const char *pcHostName) +{ + uint8_t u8HostNameSize = (uint8_t)strlen(pcHostName); + + if(u8HostNameSize > HOSTNAME_MAX_SIZE) + { + return SOCK_ERR_INVALID_ARG; + } + + if (M2M_SUCCESS != winc_hif_send_no_data(M2M_REQ_GROUP_IP, SOCKET_CMD_DNS_RESOLVE, pcHostName, u8HostNameSize + 1)) + { + return SOCK_ERR_BUFFER_FULL; + } + + return SOCK_ERR_NO_ERROR; +} + +static int8_t sslSetSockOpt(SOCKET sock, uint8_t u8Opt, const void *pvOptVal, uint16_t u16OptLen) +{ + if(sock >= TCP_SOCK_MAX) + return SOCK_ERR_INVALID_ARG; + + if(!(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE)) + { + WINC_LOG_ERROR("Not SSL Socket"); + return SOCK_ERR_INVALID_ARG; + } + + if(u8Opt == SO_SSL_BYPASS_X509_VERIF) + { + int optVal = *((int*)pvOptVal); + if(optVal) + { + gastrSockets[sock].u8SSLFlags |= SSL_FLAGS_BYPASS_X509; + } + else + { + gastrSockets[sock].u8SSLFlags &= ~SSL_FLAGS_BYPASS_X509; + } + + return SOCK_ERR_NO_ERROR; + } + else if(u8Opt == SO_SSL_ENABLE_SESSION_CACHING) + { + int optVal = *((int*)pvOptVal); + if(optVal) + { + gastrSockets[sock].u8SSLFlags |= SSL_FLAGS_CACHE_SESSION; + } + else + { + gastrSockets[sock].u8SSLFlags &= ~SSL_FLAGS_CACHE_SESSION; + } + + return SOCK_ERR_NO_ERROR; + } + else if(u8Opt == SO_SSL_ENABLE_SNI_VALIDATION) + { + int optVal = *((int*)pvOptVal); + if(optVal) + { + gastrSockets[sock].u8SSLFlags |= SSL_FLAGS_CHECK_SNI; + } + else + { + gastrSockets[sock].u8SSLFlags &= ~SSL_FLAGS_CHECK_SNI; + } + + return SOCK_ERR_NO_ERROR; + } + else if(u8Opt == SO_SSL_SNI) + { + if(u16OptLen < HOSTNAME_MAX_SIZE) + { + uint8_t *pu8SNI = (uint8_t*)pvOptVal; + tstrSSLSetSockOptCmd strCmd; + + strCmd.sock = sock; + strCmd.u16SessionID = gastrSockets[sock].u16SessionID; + strCmd.u8Option = u8Opt; + strCmd.u32OptLen = u16OptLen; + memcpy(strCmd.au8OptVal, pu8SNI, HOSTNAME_MAX_SIZE); + + if (M2M_ERR_MEM_ALLOC == winc_hif_send_no_data(M2M_REQ_GROUP_IP, SOCKET_CMD_SSL_SET_SOCK_OPT, &strCmd, sizeof(tstrSSLSetSockOptCmd))) + { + if (M2M_SUCCESS != winc_hif_send_no_data(M2M_REQ_GROUP_IP, SOCKET_CMD_SSL_SET_SOCK_OPT | M2M_REQ_DATA_PKT, + &strCmd, sizeof(tstrSSLSetSockOptCmd))) + { + return SOCK_ERR_BUFFER_FULL; + } + } + + return SOCK_ERR_NO_ERROR; + } + else + { + WINC_LOG_ERROR("SNI Exceeds Max Length"); + } + } + else + { + WINC_LOG_ERROR("Unknown SSL Socket Option %u", u8Opt); + } + + return SOCK_ERR_INVALID_ARG; +} + +int8_t setsockopt(SOCKET sock, uint8_t u8Level, uint8_t option_name, + const void *option_value, uint16_t u16OptionLen) +{ + if((sock < 0) || (option_value == NULL) || (!gastrSockets[sock].bIsUsed)) + { + return SOCK_ERR_INVALID_ARG; + } + + if(u8Level == SOL_SSL_SOCKET) + { + return sslSetSockOpt(sock, option_name, option_value, u16OptionLen); + } + else + { + uint8_t u8Cmd = SOCKET_CMD_SET_SOCKET_OPTION; + tstrSetSocketOptCmd strSetSockOpt; + strSetSockOpt.u8Option=option_name; + strSetSockOpt.sock = sock; + strSetSockOpt.u32OptionValue = *(uint32_t*)option_value; + strSetSockOpt.u16SessionID = gastrSockets[sock].u16SessionID; + + if (M2M_SUCCESS != winc_hif_send_no_data(M2M_REQ_GROUP_IP, u8Cmd, &strSetSockOpt, sizeof(tstrSetSocketOptCmd))) + { + return SOCK_ERR_INVALID; + } + } + + return SOCK_ERR_NO_ERROR; +} + +int8_t getsockopt(SOCKET sock, uint8_t u8Level, uint8_t u8OptName, const void *pvOptValue, uint8_t* pu8OptLen) +{ + UNUSED_VAR(sock); + UNUSED_VAR(u8Level); + UNUSED_VAR(u8OptName); + UNUSED_VAR(pvOptValue); + UNUSED_VAR(pu8OptLen); + + /* TBD */ + return SOCK_ERR_INVALID_ARG; +} + +int8_t m2m_ping_req(uint32_t u32DstIP, uint8_t u8TTL, tpfPingCb fpPingCb) +{ + tstrPingCmd strPingCmd; + + if((!u32DstIP) || (fpPingCb == NULL)) + return M2M_ERR_INVALID_ARG; + + strPingCmd.u16PingCount = 1; + strPingCmd.u32DestIPAddr = u32DstIP; + strPingCmd.u32CmdPrivate = ++gu32PingId; + strPingCmd.u8TTL = u8TTL; + + gfpPingCb = fpPingCb; + + if (M2M_SUCCESS != winc_hif_send_no_data(M2M_REQ_GROUP_IP, SOCKET_CMD_PING, &strPingCmd, sizeof(tstrPingCmd))) + { + return SOCK_ERR_INVALID; + } + + return SOCK_ERR_NO_ERROR; +} + +int8_t sslEnableCertExpirationCheck(tenuSslCertExpSettings enuValidationSetting) +{ + tstrSslCertExpSettings strSettings; + strSettings.u32CertExpValidationOpt = (uint32_t)enuValidationSetting; + + if (M2M_SUCCESS != winc_hif_send_no_data(M2M_REQ_GROUP_IP, SOCKET_CMD_SSL_EXP_CHECK, &strSettings, sizeof(tstrSslCertExpSettings))) + { + return SOCK_ERR_INVALID; + } + + return SOCK_ERR_NO_ERROR; +} + +uint8_t IsSocketReady(void) +{ + return gbSocketInit; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/winc/socket/socket.h b/AVRIoT.X/mcc_generated_files/winc/socket/socket.h new file mode 100644 index 0000000..9d6eb3a --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/socket/socket.h @@ -0,0 +1,1516 @@ +/** + * + * \file + * + * \brief Socket Interface. + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef __SOCKET_H__ +#define __SOCKET_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "../../config/conf_winc.h" + +/** @defgroup SocketModule Socket + @brief + This is an API providing socket functionality similar to BSD sockets. + + The application can use this API to perform socket operations within the WINC firmware. This API allows + the application to: + + - Create and destroy UDP and TCP sockets. + - Connect to remote TCP/UDP servers. + - Act as TCP/UDP servers for remote clients to connect to. + - Use TLS to protect TCP socket traffic. + - Send and receive data. + - Translate domain names into IP addresses. + - Ping a remote IP address. + + @{ + @defgroup SocketDefines Defines + @brief + These are preprocessor macros to define constants used within the socket API. + + @note + These defines should not be changed as they reflect the configuration of the WINC firmware. + Changing these values could result in unexpected behavior. + + @see SSLSocketOptions + + @defgroup SocketByteOrder Byte Order + @brief + These macros are used to convert between host representation and network byte order. + + @defgroup SocketStructures Data Structures + @brief + Specific data structures used by the socket API. + + @defgroup SocketTypes Typedefs + @brief + Specific typedefs used by the socket API. + + @defgroup SocketEnums Enumerations + @brief + Specific Enumerations used by the socket API. + + @defgroup AsyncCallback Asynchronous Events + @brief + Specific data structures and enumerations used for asynchronous operations. + + Asynchronous APIs make use of callback functions to return results once the corresponding socket operation has completed. + + Callbacks allows the application to resume normal execution while the socket operation is performed. + + @defgroup SocketCallbacks Callbacks + @brief + These are callback types used by the socket API when calling back to the application. + + @defgroup SocketAPI Functions + @brief + These functions provide socket functionality to the application. + @} +*/ + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +MACROS +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +/**@addtogroup SocketDefines + @{*/ + +#define HOSTNAME_MAX_SIZE 64 +/*!< Maximum allowed size for a host name passed to the function @ref gethostbyname. Also defines + the maximum size of the option @ref SO_SSL_SNI used with the @ref setsockopt function. + +@see gethostbyname +@see setsockopt +@see SO_SSL_SNI +*/ + +#define SOCKET_BUFFER_MAX_LENGTH 1400 +/*!< Maximum allowed size for a socket data buffer. Used with @ref send and @ref sendto socket + functions to ensure that the buffer sent is within the allowed range. + +@see send +@see sendto +*/ + +#define AF_INET 2 +/*!< The AF_INET is the address family used for IPv4. An IPv4 transport address is specified with the @ref sockaddr_in structure. + +@see sockaddr_in +*/ + +#define INET_ADDRSTRLEN 16 +/*!< Length of the string form for IP. + + @see inet_ntop +*/ + +#define SOCK_STREAM 1 +/*!< Socket type for reliable connection-oriented stream connection. + Passed to the @ref socket function for the socket creation operation. + +@see socket +*/ + +#define SOCK_DGRAM 2 +/*!< Socket type for unreliable connectionless datagram connection. + Passed to the @ref socket function for the socket creation operation. + +@see socket +*/ + +#define SOCKET_FLAGS_SSL 0x01 +/*!< Socket flag passed to @ref socket for the creation of SSL/TLS sockets. + +@see socket +*/ + +#define TCP_SOCK_MAX 7 +/*! Maximum number of simultaneous TCP sockets supported. +*/ + +#define UDP_SOCK_MAX 4 +/*!< Maximum number of simultaneous UDP sockets supported. +*/ + +#define MAX_SOCKET (TCP_SOCK_MAX + UDP_SOCK_MAX) +/*!< Total maximum number of simultaneous sockets supported. +*/ + +#define SOL_SOCKET 1 +/*!< Socket protocol type (non-SSL) used with the @ref setsockopt function. + +@see setsockopt +*/ + +#define SOL_SSL_SOCKET 2 +/*!< Socket protocol type (SSL) used with the @ref setsockopt function. + +@see setsockopt +*/ + +#define SO_SET_UDP_SEND_CALLBACK 0x00 +/*!< Socket option to enable/disable the use of UDP send callbacks. + +@see setsockopt +*/ + +#define IP_ADD_MEMBERSHIP 0x01 +/*!< Socket option to join a multicast group. + +@see setsockopt +*/ + +#define IP_DROP_MEMBERSHIP 0x02 +/*!< Socket option to leave a multicast group. + +@see setsockopt +*/ + +#define SO_KEEPALIVE 0x04 +/*!< Enable or disable TCP keep-alive. + +@see setsockopt +*/ + +#define TCP_KEEPIDLE 0x05 +/*!< Duration between two keepalive transmissions in idle condition (in 500ms increments, so 4 would be 2 seconds). Max 2^32. + +@see setsockopt +*/ + +#define TCP_KEEPINTVL 0x06 +/*!< Duration between two successive keepalive retransmissions, if acknowledgment to the previous keepalive + transmission is not received (in 500ms increments, so 4 would be 2 seconds). Max 255 (127.5 seconds). + +@see setsockopt +*/ + +#define TCP_KEEPCNT 0x07 +/*!< Number of retransmissions to be carried out before declaring that the remote end is not available. Max 255. + +@see setsockopt +*/ +/**@}*/ // IPDefines + +/**@addtogroup SSLSocketOptions + @{*/ +#define SO_SSL_BYPASS_X509_VERIF 0x01 +/*!< Allow an SSL socket to bypass the X509 certificate verification process. + + The option value should be cast to an int32_t (32 bits) and it is handled + as a boolean flag. + +@warning + It is highly recommended @b NOT to use this socket option in production + software applications. It is intended for debugging and testing + purposes only. + +@see setsockopt + +@code +int32_t sslOptionEnable = 1; + +setsockopt(sock, SOL_SSL_SOCKET, SO_SSL_BYPASS_X509_VERIF, &sslOptionEnable, sizeof(int32_t)); +@endcode +*/ + +#define SO_SSL_SNI 0x02 +/*!< Set the Server Name Indicator (SNI) for an SSL socket. + + The SNI is a NULL terminated string containing the server name associated + with the connection. It must not exceed the size of @ref HOSTNAME_MAX_SIZE. + If the SNI is not a null string, then TLS Client Hello messages will include + the SNI extension. + +@see setsockopt + +@code +int32_t sslOptionEnable = 1; + +setsockopt(sock, SOL_SSL_SOCKET, SO_SSL_SNI, acHostName, strlen(acHostName) + 1); +@endcode +*/ + +#define SO_SSL_ENABLE_SESSION_CACHING 0x03 +/*!< Allow the WINC to cache the TLS session information for fast TLS session + establishment in future connections using the TLS Protocol session resume features. + + The option value should be cast to an int32_t (32 bits) and it is handled + as a boolean flag. + +@see setsockopt + +@code +int32_t sslOptionEnable = 1; + +setsockopt(sock, SOL_SSL_SOCKET, SO_SSL_ENABLE_SESSION_CACHING, &sslOptionEnable, sizeof(int32_t)); +@endcode +*/ + +#define SO_SSL_ENABLE_SNI_VALIDATION 0x04 +/*!< Enable internal validation of server name against the server's certificate + subject common name. If there is no server name provided + (via the @ref SO_SSL_SNI option), setting this option does nothing. + + The option value should be cast to an int32_t (32 bits) and it is handled + as a boolean flag. + +@see setsockopt + +@code +int32_t sslOptionEnable = 1; + +setsockopt(sock, SOL_SSL_SOCKET, SO_SSL_ENABLE_SNI_VALIDATION, , &sslOptionEnable, sizeof(int32_t)); +@endcode +*/ +/**@}*/ // SSLSocketOptions + +/**@addtogroup SocketByteOrder + @{*/ + +#if defined(CONF_WINC_MCU_ARCH_LITTLE_ENDIAN) +#define _htonl(l) CONF_WINC_UINT32_SWAP(l) +/*!< Convert a 4-byte integer from the Host representation to Network byte order. +*/ + +#define _htons(s) CONF_WINC_UINT16_SWAP(s) +/*!< Convert a 2-byte integer (short) from Host representation to Network byte order. +*/ + +#elif defined(CONF_WINC_MCU_ARCH_BIG_ENDIAN) +#define _htonl(l) (l) +/*!< Convert a 4-byte integer from Host representation to Network byte order. +*/ + +#define _htons(s) (s) +/*!< Convert a 2-byte integer (short) from Host representation to Network byte order. +*/ +#endif + +#define _ntohl _htonl +/*!< Convert a 4-byte integer from Network byte order to Host representation. +*/ + +#define _ntohs _htons +/*!< Convert a 2-byte integer from Network byte order to Host representation. +*/ +/**@}*/ // SocketByteOrder + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +DATA TYPES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + +/**@addtogroup SocketEnums + @{*/ + +/*! +@enum \ + tenuSocketStatusType + +@brief + Possible success/error status codes returned by the Socket API. +*/ + +typedef enum { + SOCK_ERR_NO_ERROR = 0, + /*!< Successful socket operation. + */ + SOCK_ERR_INVALID_ADDRESS = -1, + /*!< Socket address is invalid. The socket operation cannot be completed successfully without specifying a valid address. + */ + SOCK_ERR_ADDR_ALREADY_IN_USE = -2, + /*!< Socket operation cannot bind on the given address. Only one IP address per socket, and one socket per IP address is permitted - + any attempt for a new socket to bind with an IP address already bound to another open socket will return this error code. + */ + SOCK_ERR_MAX_TCP_SOCK = -3, + /*!< Exceeded the maximum number of TCP sockets. A maximum number of TCP sockets opened simultaneously is defined through TCP_SOCK_MAX. + It is not permitted to exceed that number at socket creation. Identifies that @ref socket operation failed. + */ + SOCK_ERR_MAX_UDP_SOCK = -4, + /*!< Exceeded the maximum number of UDP sockets. A maximum number of UDP sockets opened simultaneously is defined through UDP_SOCK_MAX. + It is not permitted to exceed that number at socket creation. Identifies that @ref socket operation failed. + */ + SOCK_ERR_INVALID_ARG = -6, + /*!< An invalid argument is passed to a socket function. + */ + SOCK_ERR_MAX_LISTEN_SOCK = -7, + /*!< Exceeded the maximum number of TCP passive listening sockets. Identifies that @ref listen operation failed. + */ + SOCK_ERR_INVALID = -9, + /*!< The requested socket operation is not valid in the current socket state. + */ + SOCK_ERR_ADDR_IS_REQUIRED = -11, + /*!< Destination address is required. Failure to provide the socket address required for the socket operation to be completed. + */ + SOCK_ERR_CONN_ABORTED = -12, + /*!< The socket is closed (reset) by the peer. If this error is received, the application should call @ref close. + */ + SOCK_ERR_TIMEOUT = -13, + /*!< The socket pending operation has timed out. The socket remains open. + */ + SOCK_ERR_BUFFER_FULL = -14 + /*!< No buffer space available to be used for the requested socket operation. + */ +} tenuSocketStatusType; + +/**@}*/ // SocketEnums +/**@addtogroup SocketTypes + @{*/ + +/*! +@typedef \ + SOCKET + +@brief + Definition for socket data type. + + Socket ID is used with all socket operations to uniquely identify the socket. + The ID is uniquely assigned at socket creation when calling @ref socket function. +*/ +typedef int8_t SOCKET; + +/*! +@typedef \ + in_addr_t + +@brief + Packed representation of IPv4 address. +*/ +typedef uint32_t in_addr_t; + +/**@}*/ // SocketTypes +/**@addtogroup SocketStructures + @{*/ + +/*! +@struct \ + in_addr + +@brief + IPv4 address representation. + + This structure is used as a placeholder for IPv4 addresses in other structures. + +@see sockaddr_in +*/ +struct in_addr { + in_addr_t s_addr; + /*!< Network Byte Order representation of the IPv4 address. + + For example, the address "192.168.0.10" is represented as 0x0A00A8C0. + */ +}; + +/*! +@struct \ + sockaddr + +@brief + Generic socket address structure. + +@see sockaddr_in +*/ +struct sockaddr { + uint16_t sa_family; + /*!< Socket address family. + */ + uint8_t sa_data[14]; + /*!< Socket address data. + */ +}; + +/*! +@struct \ + sockaddr_in + +@brief + Socket address structure for IPv4 addresses. Used to specify socket address information to connect to. + Can be cast to @ref sockaddr structure. +*/ +struct sockaddr_in { + uint16_t sin_family; + /*!< Specifies the address family(AF). + + @note + The only supported value for this is AF_INET. + */ + uint16_t sin_port; + /*!< Port number of the socket. + + It must be set in the Network Byte Order format, _htons (e.g. _htons(80)). + + @note + Must @b NOT have the value zero. + */ + struct in_addr sin_addr; + /*!< IP Address of the socket. + + The IP address is of type @ref in_addr. + + @note + The IP address can be zero to accept any IP address for server operations. + */ + uint8_t sin_zero[8]; + /*!< Padding to ensure the structure size is the same size as @ref sockaddr. + */ +}; + +/**@}*/ // SocketStructures + +/**@addtogroup AsyncCallback + @{ */ + +/*! +@enum \ + tenuSocketCallbackMsgType + +@brief + This enum identifies the type of events that will be received by the callback function. + + To receive callbacks the application must call @ref m2m_wifi_handle_events periodically to process any returning + event data from the WINC device. + +@see bind +@see listen +@see accept +@see connect +@see send +@see sendto +@see recv +@see recvfrom +@see gethostbyname +*/ +typedef enum { + SOCKET_MSG_BIND = 1, + /*!< Bind socket event. + */ + SOCKET_MSG_LISTEN, + /*!< Listen socket event. + */ + SOCKET_MSG_DNS_RESOLVE, + /*!< DNS Resolution event. + */ + SOCKET_MSG_ACCEPT, + /*!< Accept socket event. + */ + SOCKET_MSG_CONNECT, + /*!< Connect socket event. + */ + SOCKET_MSG_RECV, + /*!< Receive socket event. + */ + SOCKET_MSG_SEND, + /*!< Send socket event. + */ + SOCKET_MSG_SENDTO, + /*!< Sendto socket event. + */ + SOCKET_MSG_RECVFROM + /*!< Recvfrom socket event. + */ +} tenuSocketCallbackMsgType; + +/*! +@enum \ + tenuPingErrorType + +@brief + This enum identifies the success/error codes returned in the ping callback from calling @ref m2m_ping_req. + +*/ +typedef enum { + PING_ERR_SUCCESS = 0, + /*!< The ping operation was successful. + */ + PING_ERR_DEST_UNREACH = 1, + /*!< The ping destination was unreachable. + */ + PING_ERR_TIMEOUT = 2 + /*!< The ping operation timed out. + */ +} tenuPingErrorType; + +/*! +@struct \ + tstrSocketBindMsg + +@brief + Socket @ref bind status message structure. + + An asynchronous call to the @ref bind socket function, returns information through this structure in response. + This structure together with the event @ref SOCKET_MSG_BIND are passed in parameters to the callback function. + +@see + bind +*/ +typedef struct { + int8_t status; + /*!< The result of the bind operation. See @ref tenuSocketStatusType. + */ +} tstrSocketBindMsg; + +/*! +@struct \ + tstrSocketListenMsg + +@brief + Socket @ref listen status message structure. + + Socket listen information is returned through this structure in response to the asynchronous call to the @ref listen function. + This structure together with the event @ref SOCKET_MSG_LISTEN are passed in parameters to the callback function. +@see + listen +*/ +typedef struct { + int8_t status; + /*!< The result of the listen operation. See @ref tenuSocketStatusType. + */ +} tstrSocketListenMsg; + +/*! +@struct \ + tstrSocketAcceptMsg + +@brief + Socket @ref accept status message structure. + + Socket accept information is returned through this structure in response to the asynchronous call to the @ref accept function. + This structure together with the event @ref SOCKET_MSG_ACCEPT are passed in parameters to the callback function. +*/ +typedef struct { + SOCKET sock; + /*!< On a successful @ref accept operation, the returned information is the socket ID for the accepted connection with the remote peer. + Otherwise a negative error code is returned to indicate failure of the accept operation. + */ + struct sockaddr_in strAddr; + /*!< Socket address structure for the remote peer. + */ +} tstrSocketAcceptMsg; + +/*! +@struct \ + tstrSocketConnectMsg + +@brief + Socket @ref connect status message structure. + +@details + Socket connect information is returned through this structure in response to the asynchronous call to the @ref connect function. + This structure together with the event @ref SOCKET_MSG_CONNECT are passed in parameters to the callback function. + If the application receives this structure with a negative value in @p s8Error, the application should call @ref close. +*/ +typedef struct { + SOCKET sock; + /*!< Socket ID referring to the socket passed to the connect function call. + */ + int8_t s8Error; + /*!< Connect error code. See @ref tenuSocketStatusType. + */ +} tstrSocketConnectMsg; + +/*! +@struct \ + tstrSocketRecvMsg + +@brief + Socket @ref recv or @ref recvfrom status message structure. + + Socket receive information is returned through this structure in response to the asynchronous call to the @ref recv or @ref recvfrom functions. + This structure together with the events @ref SOCKET_MSG_RECV or @ref SOCKET_MSG_RECVFROM are passed in parameters to the callback function. + +@remark + In case the received data from the remote peer is larger than the USER buffer size defined during the asynchronous call to the @ref recv function, + only data up to the USER buffer size is delivered to the user. The user must call @ref recv again in order to receive the remaining data. + + A negative or zero buffer size indicates an error with the following values: + + | Value | Description | + |-------------------------------|------------------------------------------------------------------------| + | @ref SOCK_ERR_NO_ERROR | Socket connection closed. The application should now call @ref close. | + | @ref SOCK_ERR_CONN_ABORTED | Socket connection aborted. The application should now call @ref close. | + | @ref SOCK_ERR_TIMEOUT | Socket receive timed out. The socket connection remains open. | +*/ +typedef struct { + uint8_t *pu8Buffer; + /*!< Pointer to the buffer (passed to @ref recv and @ref recvfrom function) containing the received data chunk. + */ + int16_t s16BufferSize; + /*!< The received data chunk size. + + Holds a negative value if there is a receive error or zero on success upon reception of close socket message. + */ + uint16_t u16RemainingSize; + /*!< The number of bytes remaining in the current @ref recv operation. + */ + struct sockaddr_in strRemoteAddr; + /*!< Socket address structure for the remote peer. It is valid for @ref SOCKET_MSG_RECVFROM events. + */ +} tstrSocketRecvMsg; +/**@}*/ // AsyncCallback + +/**@addtogroup SocketCallbacks + @{ */ + +/*! +@typedef \ + tpfAppSocketCb + +@brief + The main socket application callback function. + + Applications register their main socket application callback by calling @ref registerSocketCallback. + In response to events received this callback function is called to handle process the response from the + corresponding asynchronous function called by the application. + +@param [in] sock + Socket ID for the callback. + +@param [in] u8Msg + Socket event type. See @ref tenuSocketCallbackMsgType. + +@param [in] pvMsg + Pointer to message structure. The structure type is dependant on the value of @p u8Msg: + +| Event Type | Structure Type | +|---------------------------|---------------------------| +| @ref SOCKET_MSG_BIND | @ref tstrSocketBindMsg | +| @ref SOCKET_MSG_LISTEN | @ref tstrSocketListenMsg | +| @ref SOCKET_MSG_ACCEPT | @ref tstrSocketAcceptMsg | +| @ref SOCKET_MSG_CONNECT | @ref tstrSocketConnectMsg | +| @ref SOCKET_MSG_RECV | @ref tstrSocketRecvMsg | +| @ref SOCKET_MSG_RECVFROM | @ref tstrSocketRecvMsg | +| @ref SOCKET_MSG_SEND | int16_t | +| @ref SOCKET_MSG_SENDTO | int16_t | + +@see bind +@see listen +@see accept +@see connect +@see send +@see sendto +@see recv +@see recvfrom +*/ +typedef void (*tpfAppSocketCb)(SOCKET sock, uint8_t u8Msg, void *pvMsg); + +/*! +@typedef \ + tpfAppResolveCb + +@brief + DNS resolution callback function. + + Applications requiring DNS resolution should register this callback by calling @ref registerSocketCallback. + The callback is triggered in response to an asynchronous call to the @ref gethostbyname function. + +@param [in] pu8DomainName + Domain name of the host to be resolved. + +@param [in] u32IP + Server IPv4 address encoded in Network Byte Order format. A value of zero indicates the DNS resolution failed. +*/ +typedef void (*tpfAppResolveCb)(uint8_t *pu8DomainName, uint32_t u32IP); + +/*! +@typedef \ + tpfPingCb + +@brief + Ping (ICMP echo request) callback function. + + The function delivers the ping statistics for the sent ping triggered by calling @ref m2m_ping_req. + +@param [in] u32IPAddr + Destination IP. + +@param [in] u32RTT + Round Trip Time. + +@param [in] u8ErrorCode + Ping error code. See @ref tenuPingErrorType +*/ +typedef void (*tpfPingCb)(uint32_t u32IPAddr, uint32_t u32RTT, uint8_t u8ErrorCode); + +/**@}*/ //SocketCallbacks + +/********************************************************************* +Function + m2m_ip_cb + +Description + Callback function used by the NMC1000 driver to deliver messages + for socket layer. + +Return + None. + +Author + Ahmed Ezzat + +Version + 1.0 + +Date + 17 July 2012 +*********************************************************************/ +void m2m_ip_cb(uint8_t u8OpCode, uint16_t u16BufferSize,uint32_t u32Address); + +/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +FUNCTION PROTOTYPES +*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ +/**@addtogroup SocketAPI + @{ */ +/*! +@fn \ + void socketInit(void); + +@brief + This function performs the necessary initialization of the socket library. + +@remarks + This initialization function must be invoked before any socket operation can be performed. +*/ +void socketInit(void); + +/*! +@fn \ + void socketDeinit(void); + +@brief + This function de-initializes the socket library. + + The function performs the necessary cleanup for the socket library static data. + + It must be invoked only after all desired socket operations have been performed on any active sockets. +*/ +void socketDeinit(void); + +/*! +@fn \ + uint8_t IsSocketReady(void); + +@see socketInit + socketDeinit +@return If the socket has been initialized and is ready. + Should return 1 after @ref socketInit and 0 after @ref socketDeinit +*/ +uint8_t IsSocketReady(void); + +/*! +@fn \ + void registerSocketCallback(tpfAppSocketCb pfAppSocketCallback, tpfAppResolveCb pfAppResolveCallback); + +@brief + This function registers two application provided callback functions with the socket library. + One for asynchronous socket events and the second for DNS resolution events. + +@param [in] pfAppSocketCallback + This callback will receive socket events from the socket library. + +@param [in] pfAppResolveCallback + This callback will receive DNS resolution events from the socket library. + +@remarks + If either callback function pointer is NULL then the corresponding events will not be received by the application. + +@pre + Callbacks must be registered after calling @ref socketInit. + +@section SocketExample2 Example + This example demonstrates the use of @ref registerSocketCallback to register a socket callback function with DNS resolution CB set to null + for a simple UDP server example. + +@include registerSocketCallback.c +@example registerSocketCallback.c +*/ +void registerSocketCallback(tpfAppSocketCb pfAppSocketCallback, tpfAppResolveCb pfAppResolveCallback); + +/*! +@fn \ + void registerSocketEventCallback(tpfAppSocketCb pfAppSocketCallback); + +@brief + This function registers an application provided callback function with the socket library for asynchronous socket events. + +@param [in] pfAppSocketCallback + This callback will receive socket events from the socket library. + +@remarks + If the callback function pointer is NULL then the corresponding events will not be received by the application. + +@pre + Callbacks must be registered after calling @ref socketInit. +*/ +void registerSocketEventCallback(tpfAppSocketCb pfAppSocketCallback); + +/*! +@fn \ + void registerSocketResolveCallback(tpfAppResolveCb pfAppResolveCallback); + +@brief + This function registers an application provided callback function with the socket library for DNS resolution events. + +@param [in] pfAppResolveCallback + This callback will receive DNS resolution events from the socket library. + +@remarks + If the callback function pointer is NULL then the corresponding events will not be received by the application. + +@pre + Callbacks must be registered after calling @ref socketInit. +*/ +void registerSocketResolveCallback(tpfAppResolveCb pfAppResolveCallback); + +/*! +@fn \ + SOCKET socket(uint16_t u16Domain, uint8_t u8Type, uint8_t u8Flags); + +@brief + Synchronous socket allocation function based on the specified socket type. Created sockets are non-blocking and their possible types are either TCP or a UDP sockets. + The maximum allowed number of TCP sockets is @ref TCP_SOCK_MAX sockets while the maximum number of UDP sockets that can be created simultaneously is @ref UDP_SOCK_MAX sockets. + +@param[in] u16Domain + Socket family. The only allowed value is @ref AF_INET (IPv4) for TCP/UDP sockets. + +@param[in] u8Type + Socket type. Allowed values are: + - @ref SOCK_STREAM + - @ref SOCK_DGRAM + +@param[in] u8Flags + Socket creation flags. For normal TCP/UDP sockets this value is zero, for SSL TCP socket this + value will be @ref SOCKET_FLAGS_SSL. The use of the flag @ref SOCKET_FLAGS_SSL has no meaning + in case of UDP sockets. + +@pre + The function @ref socketInit must have been called to initialize the socket library. + +@see connect +@see bind +@see setsockopt +@see getsockopt + +@return + On successful socket creation, a non-blocking socket type is created and a socket ID is returned + In case of failure the function returns a negative value, identifying one of the socket error codes, see @ref tenuSocketStatusType. + +@section SocketExample3 Example + This example demonstrates the use of the socket function to allocate the socket, returning the socket handler to be used for other + socket operations. Socket creation is dependent on the socket type. + +@subsection SE3sub1 UDP example +@code + SOCKET UdpServerSocket = -1; + + UdpServerSocket = socket(AF_INET, SOCK_DGRAM, 0); +@endcode + +@subsection SE3sub2 TCP example +@code + SOCKET tcp_client_socket = -1; + + tcp_client_socket = socket(AF_INET, SOCK_STREAM, 0)); +@endcode +@subsection SE3sub3 SSL example + +@code + SOCKET ssl_socket = -1; + + ssl_socket = socket(AF_INET, SOCK_STREAM, SOCK_FLAGS_SSL)); +@endcode +*/ +SOCKET socket(uint16_t u16Domain, uint8_t u8Type, uint8_t u8Flags); + +/*! +@fn \ + int8_t bind(SOCKET sock, struct sockaddr *pstrAddr, uint8_t u8AddrLen); + +@brief + Asynchronous bind function associates the provided local address and port with a socket. + + This function is required to create a server socket capable of receiving connection requests + from a socket client. The function can be used with both TCP and UDP sockets. + Upon socket bind completion, the application will receive a @ref SOCKET_MSG_BIND message via the socket callback. + +@param[in] sock + Socket ID, must hold a valid non negative value obtained from the function @ref socket. + +@param[in] pstrAddr + Pointer to a socket address structure @ref sockaddr_in. + +@param[in] u8AddrLen + Size of the socket address structure pointed to by @p pstrAddr (in bytes). + +@pre + The @ref socket function must have been called to allocate a socket. + +@see socket +@see listen +@see accept + +@return + The function returns @ref SOCK_ERR_NO_ERROR for successful operations and a negative value otherwise, see @ref tenuSocketStatusType. + +@section SocketExample4 Example + This example demonstrates opening a UDP datagram socket and binding it to a local port. + +@include bind.c +@example bind.c +*/ +int8_t bind(SOCKET sock, struct sockaddr *pstrAddr, uint8_t u8AddrLen); + +/*! +@fn \ + int8_t listen(SOCKET sock, uint8_t u8Backlog); + +@brief + Mark a locally bound (via @ref bind) socket as a passive socket that can be used to accept incoming connection requests. + + This asynchronous function will respond via the socket callback using the event @ref SOCKET_MSG_LISTEN. + + Upon completion of the listen operation the socket is available for connection requests, for TCP sockets these requests + are automatically accepted by the WINC and thus require no specific call to @ref accept. Applications are notified of + an accepted socket connection via the socket callback using the event @ref SOCKET_MSG_ACCEPT. + There is no requirement to call the @ref accept function after calling @ref listen. + +@param[in] sock + Socket ID, must hold a valid non negative value obtained from the function @ref socket. + +@param[in] u8Backlog + Not used by the current implementation. + +@pre + The @ref bind function must have been called to associate a local address and port with the socket. + +@see bind +@see accept + +@return + The function returns @ref SOCK_ERR_NO_ERROR for successful operations and a negative value otherwise, see @ref tenuSocketStatusType. + +@section SocketExample5 Example + +@include listen.c +@example listen.c + +*/ +int8_t listen(SOCKET sock, uint8_t u8Backlog); + +/*! +@fn \ + int8_t accept(SOCKET sock, struct sockaddr *pstrAddr, uint8_t *pu8AddrLen); + +@brief + The function has no current implementation. An empty declaration is used to prevent errors when legacy application code is used. + As it has no effect, it can be safely removed from any application using it. + +@param[in] sock + Socket ID, must hold a valid non negative value obtained from the function @ref socket. + +@param[in] pstrAddr + Not used in the current implementation. + +@param[in] pu8AddrLen + Not used in the current implementation. + +@return + The function returns @ref SOCK_ERR_NO_ERROR for successful operations and a negative value otherwise, see @ref tenuSocketStatusType. +*/ +int8_t accept(SOCKET sock, struct sockaddr *pstrAddr, uint8_t *pu8AddrLen); + +/*! +@fn \ + int8_t connect(SOCKET sock, struct sockaddr *pstrAddr, uint8_t u8AddrLen); + +@brief + Establishes a TCP connection with a remote server. + + The application socket callback function is notified of the result of the connection attempt through the event @ref SOCKET_MSG_CONNECT, + along with a structure @ref tstrSocketConnectMsg. + +@param[in] sock + Socket ID, must hold a valid non negative value obtained from the function @ref socket. + +@param[in] pstrAddr + Pointer to socket address structure @ref sockaddr. + +@param[in] u8AddrLen + Size of the socket address structure pointed to by @p pstrAddr (in bytes). + +@pre + The @ref socket function must have been called to allocate a TCP socket. + +@see + socket + +@return + The function returns @ref SOCK_ERR_NO_ERROR for successful operations and a negative value otherwise, see @ref tenuSocketStatusType. + +@section SocketExample6 Example + +@include connect.c +@example connect.c +*/ +int8_t connect(SOCKET sock, struct sockaddr *pstrAddr, uint8_t u8AddrLen); + +/*! +@fn \ + int8_t recv(SOCKET sock, void *pvRecvBuf, uint16_t u16BufLen, uint32_t u32Timeoutmsec); + +@brief + An asynchronous function, used to retrieve data from a TCP stream. + + The application receives data via the socket callback event @ref SOCKET_MSG_RECV. + + When receiving the callback event @ref SOCKET_MSG_RECV the @p s16BufferSize element of the event structure @ref tstrSocketRecvMsg + indicates the status of the @ref recv operation: + + | @p s16BufferSize | Meaning | + |----------------------------|-------------------------------------------------------------------------------------------------| + | @ref SOCK_ERR_NO_ERROR | The socket connection has closed gracefully, the application should now call @ref close. | + | @ref SOCK_ERR_CONN_ABORTED | The socket connection was aborted, the application, the application should now call @ref close. | + | @ref SOCK_ERR_TIMEOUT | The socket receive exceeded the @p u32Timeoutmsec timeout, the socket remains open. | + +@param[in] sock + Socket ID, must hold a valid non negative value obtained from the function @ref socket. + +@param[in] pvRecvBuf + Pointer to a buffer that will hold the received data. The buffer will be used in the socket callback event @ref SOCKET_MSG_RECV + to deliver the received data to the callback. The buffer must remain valid until the socket callback has completed. + +@param[in] u16BufLen + The buffer size in bytes. + +@param[in] u32Timeoutmsec + Timeout for the @ref recv operation in milliseconds. If the value is set to zero, the timeout will be infinite + (the recv function will wait forever). If no data is received during this period the socket callback will + be called with a @p s16BufferSize value of @ref SOCK_ERR_TIMEOUT. + +@pre + The @ref socket function must have been called to allocate a TCP socket. +@pre + The socket must be in the connected state via either of the two socket events @ref SOCKET_MSG_CONNECT or @ref SOCKET_MSG_ACCEPT. + +@see socket +@see connect +@see bind +@see listen +@see close + +@return + The function returns @ref SOCK_ERR_NO_ERROR for successful operations and a negative value otherwise, see @ref tenuSocketStatusType. + +@section SocketExample7 Example + +@include recv.c +@example recv.c +*/ +int8_t recv(SOCKET sock, void *pvRecvBuf, uint16_t u16BufLen, uint32_t u32Timeoutmsec); + +/*! +@fn \ + int16_t recvfrom(SOCKET sock, void *pvRecvBuf, uint16_t u16BufLen, uint32_t u32Timeoutmsec); + +@brief + An asynchronous function, used to retrieve data from a UDP socket. + + The application receives data via the socket callback event @ref SOCKET_MSG_RECVFROM. + + When receiving the callback event @ref SOCKET_MSG_RECVFROM the @p s16BufferSize element of the event structure @ref tstrSocketRecvMsg + indicates the status of the @ref recv operation: + + | @p s16BufferSize | Meaning | + |----------------------------|-------------------------------------------------------------------------------------------------| + | @ref SOCK_ERR_NO_ERROR | The socket connection has closed gracefully, the application should now call @ref close. | + | @ref SOCK_ERR_TIMEOUT | The socket receive exceeded the @p u32Timeoutmsec timeout, the socket remains open. | + + The callback event @ref SOCKET_MSG_RECVFROM event structure @ref tstrSocketRecvMsg also contains the address of the remote peer + sending the data in the element @p strRemoteAddr. + +@param[in] sock + Socket ID, must hold a valid non negative value obtained from the function @ref socket. + +@param[in] pvRecvBuf + Pointer to a buffer that will hold the received data. The buffer will be used in the socket callback event @ref SOCKET_MSG_RECVFROM + to deliver the received data to the callback. The buffer must remain valid until the socket callback has completed. + +@param[in] u16BufLen + The buffer size in bytes. + +@param[in] u32Timeoutmsec + Timeout for the @ref recvfrom operation in milliseconds. If the value is set to zero, the timeout will be infinite + (the recvfrom function will wait forever). If no data is received during this period the socket callback will + be called with a @p s16BufferSize value of @ref SOCK_ERR_TIMEOUT. + +@pre + The @ref socket function must have been called to allocate a UDP socket. + +@see socket +@see connect +@see bind +@see close + +@return + The function returns @ref SOCK_ERR_NO_ERROR for successful operations and a negative value otherwise, see @ref tenuSocketStatusType. + +@section SocketExample8 Example + +@include recvfrom.c +@example recvfrom.c +*/ +int16_t recvfrom(SOCKET sock, void *pvRecvBuf, uint16_t u16BufLen, uint32_t u32Timeoutmsec); + +/*! +@fn \ + int8_t send(SOCKET sock, void *pvSendBuffer, uint16_t u16SendLength, uint16_t u16Flags); + +@brief + Asynchronous function used, to send data via a TCP/UDP socket. + + To send data via a TCP socket the socket must be in the connected state. + + To send data via a UDP socket the application must have previously called @ref sendto with a valid remote address. + + The socket callback will receive the event @ref SOCKET_MSG_SEND with the number of bytes sent once the data has + been sent. + +@param[in] sock + Socket ID, must hold a valid non negative value obtained from the function @ref socket. + +@param[in] pvSendBuffer + Pointer to a buffer of data to be transmitted. + +@param[in] u16SendLength + The buffer size in bytes. + +@param[in] u16Flags + Not used in the current implementation. + +@pre + The @ref socket function must have been called to allocate a socket. + +@pre + TCP sockets: The socket must be in the connected state. For server sockets a successful @ref listen / @ref accept, and + for client sockets a successful @ref connect must have been performed on the socket before trying to send data. + +@pre + UDP socket: At least one successful call must be made to the @ref sendto function before using the @ref send function. + +@see sendto +@see socket +@see connect +@see accept +@see listen + +@warning + @p u16SendLength must not exceed @ref SOCKET_BUFFER_MAX_LENGTH. + +@note + Successful completion of a call to @ref send does not guarantee delivery of the message, + a negative return value indicates only locally-detected errors + +@return + The function returns @ref SOCK_ERR_NO_ERROR for successful operations and a negative value otherwise, see @ref tenuSocketStatusType. + */ +int8_t send(SOCKET sock, void *pvSendBuffer, uint16_t u16SendLength, uint16_t u16Flags); + +/*! +@fn \ + int8_t sendto(SOCKET sock, void *pvSendBuffer, uint16_t u16SendLength, uint16_t u16Flags, struct sockaddr *pstrAddr, uint8_t u8AddrLen); + +@brief + Asynchronous function used, to send data via a UDP socket. + + The socket callback will receive the event @ref SOCKET_MSG_SEND with the number of bytes sent once the data has + been sent. + +@param[in] sock + Socket ID, must hold a valid non negative value obtained from the function @ref socket. + +@param[in] pvSendBuffer + Pointer to a buffer of data to be transmitted. + +@param[in] u16SendLength + The buffer size in bytes. + +@param[in] u16Flags + Not used in the current implementation. + +@param[in] pstrAddr + Pointer to socket address structure @ref sockaddr. + +@param[in] u8AddrLen + Size of the socket address structure pointed to by @p pstrAddr (in bytes). + +@pre + The @ref socket function must have been called to allocate a socket. + +@see socket + +@warning + @p u16SendLength must not exceed @ref SOCKET_BUFFER_MAX_LENGTH. + +@note + Successful completion of a call to @ref sendto does not guarantee delivery of the message, + a negative return value indicates only locally-detected errors + +@return + The function returns @ref SOCK_ERR_NO_ERROR for successful operations and a negative value otherwise, see @ref tenuSocketStatusType. +*/ +int8_t sendto(SOCKET sock, void *pvSendBuffer, uint16_t u16SendLength, uint16_t u16Flags, struct sockaddr *pstrAddr, uint8_t u8AddrLen); + +/*! +@fn \ + int8_t close(SOCKET sock); + +@brief + Synchronous function, closes a socket and releases all the assigned resources. + +@param[in] sock + Socket ID, must hold a valid non negative value obtained from the function @ref socket. + +@pre + The @ref socket function must have been called to allocate a socket. + +@warning + If @ref close is called while there are still outstanding messages (to be sent or received) these will be discarded. + +@see socket + +@return + The function returns @ref SOCK_ERR_NO_ERROR for successful operations and a negative value otherwise, see @ref tenuSocketStatusType. +*/ +int8_t close(SOCKET sock); + +/*! +@fn \ + in_addr_t inet_addr(const char *cp); + +@brief + Synchronous function which returns a BSD socket compliant Internet Protocol (IPv4) socket address. + +@param[in] cp + A NULL terminated string containing the IP address in IPv4 dotted-decimal format. + +@return + Unsigned 32-bit integer representing the IP address in Network byte order + (eg. "192.168.10.1" will be expressed as 0x010AA8C0). +*/ +in_addr_t inet_addr(const char *cp); + +/*! +@fn \ + const char *inet_ntop(int af, const void *src, char *dst, size_t size); + +@brief + Synchronous function which converts an IPv4 address from binary to text form. + +@param[in] af + Address family, must be AF_INET. + +@param[in] src + src points to a struct in_addr (in network byte order) which is to be converted. + +@param[in] dst + dst points to a buffer to receive the dotted-decimal format IP address "ddd.ddd.ddd.ddd". + +@param[in] size + The size of the buffer pointed to by dst. The buffer dst must be at least @ref INET_ADDRSTRLEN bytes long + +@return + On success, inet_ntop() returns a non-null pointer to dst. NULL is returned if there was an error. +*/ +const char *inet_ntop(int af, const void *src, char *dst, size_t size); + +/*! +@fn \ + int8_t gethostbyname(const char *pcHostName); + +@brief + Asynchronous function. This function uses DNS to resolve a domain name to the corresponding IP address. + + A call to this function will cause a DNS request to be sent and the response will be delivered to the DNS callback + function registered using @ref registerSocketCallback. + +@param[in] pcHostName + A NULL terminated string containing the domain name for the remote host. + Its size must not exceed @ref HOSTNAME_MAX_SIZE. + +@warning + Successful completion of a call to gethostbyname() does not guarantee success of the DNS request, + a negative return value indicates only locally-detected errors + +@see registerSocketCallback + +@return + The function returns @ref SOCK_ERR_NO_ERROR for successful operations and a negative value otherwise, see @ref tenuSocketStatusType. +*/ +int8_t gethostbyname(const char *pcHostName); + +/*! +@fn \ + int8_t sslEnableCertExpirationCheck(tenuSslCertExpSettings enuValidationSetting); + +@param[in] enuValidationSetting + See @ref tenuSslCertExpSettings for details. + +@see tenuSslCertExpSettings + +@return + The function returns @ref SOCK_ERR_NO_ERROR for successful operations and a negative value otherwise, see @ref tenuSocketStatusType. +*/ +int8_t sslEnableCertExpirationCheck(tenuSslCertExpSettings enuValidationSetting); + +/*! +@fn \ + int8_t setsockopt(SOCKET socket, uint8_t u8Level, uint8_t option_name, const void *option_value, uint16_t u16OptionLen); + +@brief + The setsockopt function shall set the option specified by the option_name argument, at the protocol level specified + by the level argument, to the value pointed to by the option_value argument for the socket specified by the socket argument. + +@details + Possible options when the protocol level is @ref SOL_SOCKET : + + | Option | Description | + | -------|-------------| + | @ref SO_SET_UDP_SEND_CALLBACK | Enable/Disable callback messages for @ref sendto. Since UDP is unreliable by default the user maybe interested (or not) in receiving a message of @ref SOCKET_MSG_SENDTO for each call of @ref sendto.
Enabled if option_value points to a non-zero value, disabled otherwise. | + | @ref IP_ADD_MEMBERSHIP | Valid for UDP sockets, this option is used to receive frames sent to a multicast group.
option_value shall be a pointer to an unsigned 32 bit integer containing the multicast IPv4 address. | + | @ref IP_DROP_MEMBERSHIP | Valid for UDP sockets, this option is used to stop receiving frames sent to a multicast group.
option_value shall be a pointer to an unsigned 32 bit integer containing the multicast IPv4 address. | + + Possible options when the protocol level is @ref SOL_SSL_SOCKET : + + | Option | Description | + | -------|-------------| + | @ref SO_SSL_BYPASS_X509_VERIF | Allow an opened SSL socket to bypass the X509 certificate verification process. It is highly recommended NOT to use this socket option in production software applications. The option is supported for debugging and testing purposes. The option value should be cast to an int type and it is handled as a boolean flag. | + | @ref SO_SSL_SNI | Set the Server Name Indicator (SNI) for an SSL socket. The SNI is a null terminated string containing the server name associated with the connection. It must not exceed the size of @ref HOSTNAME_MAX_SIZE. | + | @ref SO_SSL_ENABLE_SESSION_CACHING | This option allows the WINC to cache the TLS session information for fast TLS session establishment in future connections using the TLS protocol session resume features. | + +@param[in] socket + Socket ID, must hold a valid non negative value obtained from the function @ref socket. + +@param[in] u8Level + Protocol level. See description above. + +@param[in] option_name + Option to be set. See description above. + +@param[in] option_value + Pointer to the user provided value. + +@param[in] u16OptionLen + Length of the option value in bytes. + +@see SOL_SOCKET +@see SOL_SSL_SOCKET +@see IP_ADD_MEMBERSHIP +@see IP_DROP_MEMBERSHIP + +@return + The function returns @ref SOCK_ERR_NO_ERROR for successful operations and a negative value otherwise, see @ref tenuSocketStatusType. +*/ +int8_t setsockopt(SOCKET socket, uint8_t u8Level, uint8_t option_name, const void *option_value, uint16_t u16OptionLen); + +/*! +@fn \ + int8_t getsockopt(SOCKET sock, uint8_t u8Level, uint8_t u8OptName, const void *pvOptValue, uint8_t *pu8OptLen); + +@brief + Get socket options retrieves. + +@note + This Function isn't implemented yet but this is the form that will be released later. + +@param[in] sock + Socket ID, must hold a valid non negative value obtained from the function @ref socket. + +@param[in] u8Level + The protocol level of the option. + +@param[in] u8OptName + The u8OptName argument specifies a single option to get. + +@param[out] pvOptValue + The pvOptValue argument contains pointer to a buffer containing the option value. + +@param[out] pu8OptLen + Option value buffer length. + +@return + The function returns @ref SOCK_ERR_NO_ERROR for successful operations and a negative value otherwise, see @ref tenuSocketStatusType. +*/ +int8_t getsockopt(SOCKET sock, uint8_t u8Level, uint8_t u8OptName, const void *pvOptValue, uint8_t *pu8OptLen); + +/*! +@fn \ + int8_t m2m_ping_req(uint32_t u32DstIP, uint8_t u8TTL, tpfPingCb fpPingCb); + +@brief + This function requests the WINC send a ping request to the given IP Address. + +@param[in] u32DstIP + Target Destination IP Address for the ping request. It must be represented in Network Byte Order. + The function @ref inet_addr could be used to translate the dotted decimal notation IP + to its Network Byte Order integer representative. + +@param[in] u8TTL + IP TTL value for the ping request. If set to ZERO, the default value will be used. + +@param[in] fpPingCb + Callback will be called to deliver the ping statistics. + +@warning + This function should only be used to request one ping at a time; calling this API invalidates callbacks + for previous ping requests. + +@see inet_addr + +@return + The function returns @ref SOCK_ERR_NO_ERROR for successful operations and a negative value otherwise, see @ref tenuSocketStatusType. +*/ +int8_t m2m_ping_req(uint32_t u32DstIP, uint8_t u8TTL, tpfPingCb fpPingCb); + +/**@}*/ // SocketAPI + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __SOCKET_H__ */ diff --git a/AVRIoT.X/mcc_generated_files/winc/spi_flash/flexible_flash.c b/AVRIoT.X/mcc_generated_files/winc/spi_flash/flexible_flash.c new file mode 100644 index 0000000..5a2c9e1 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/spi_flash/flexible_flash.c @@ -0,0 +1,77 @@ +/** + * \file + * + * \brief This module contains the flexible flash map + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#include "../driver/winc_adapter.h" +#include "../common/winc_defines.h" +#include "../m2m/m2m_types.h" +#include "spi_flash.h" +#include "spi_flash_map.h" +#include "flexible_flash.h" + +#define FLASH_MAP_TABLE_ADDR (FLASH_SECTOR_SZ+sizeof(tstrOtaControlSec)+8) +#define N_ENTRIES_MAX 32 + +int8_t spi_flexible_flash_find_section(uint16_t u16EntryIDToLookFor, uint32_t *pu32StartOffset, uint32_t *pu32Size) +{ + int8_t s8Ret = M2M_ERR_INVALID_ARG; + if((NULL == pu32StartOffset) || (NULL == pu32Size)) goto EXIT; + + uint8_t au8buff[8]; + uint8_t u8CurrEntry = 0; + s8Ret = spi_flash_read(&au8buff[0], FLASH_MAP_TABLE_ADDR, 4); + if(M2M_SUCCESS != s8Ret) goto EXIT; + + uint8_t u8nEntries = au8buff[0]; // Max number is 32, reading one byte will suffice + if(u8nEntries > N_ENTRIES_MAX) + { + s8Ret = M2M_ERR_FAIL; + goto EXIT; + } + + while(u8nEntries > u8CurrEntry) + { + s8Ret = spi_flash_read(&au8buff[0], FLASH_MAP_TABLE_ADDR + 4 + (u8CurrEntry*8), 8); + u8CurrEntry++; + if(M2M_SUCCESS != s8Ret) break; + uint16_t u16EntryID = (au8buff[1] << 8) | au8buff[0]; + if(u16EntryID != u16EntryIDToLookFor) continue; + *pu32StartOffset = au8buff[2] * FLASH_SECTOR_SZ; + *pu32Size = au8buff[3] * FLASH_SECTOR_SZ; + break; + } +EXIT: + return s8Ret; +} \ No newline at end of file diff --git a/AVRIoT.X/mcc_generated_files/winc/spi_flash/flexible_flash.h b/AVRIoT.X/mcc_generated_files/winc/spi_flash/flexible_flash.h new file mode 100644 index 0000000..20ceaa8 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/spi_flash/flexible_flash.h @@ -0,0 +1,89 @@ +/** + * \file + * + * \brief This module contains the flexible flash map + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef __FLEXIBLE_FLASH_H__ +#define __FLEXIBLE_FLASH_H__ + +typedef struct { + uint32_t magic; + uint32_t max_size; +}tstrFlashLUTHeader; + +// NOTE: Don't use enums for id/status here, +// they need to be 16 bit but the enums end up as +// 32 bit even if the __packed__ attribute is used +typedef struct { + uint16_t id; + uint8_t sector; + uint8_t size; + uint32_t reserved; +}tstrFlashLUTEntry; + +#define FLASHMAP_MAGIC_VALUE 0x1ABCDEF9 +#define FLASHMAP_MAX_ENTRIES 32 + +// + 8 is for the number of entries value (uint32_t) and CRC (uint32_t) +// * 2 is for the new lookup table to apply +// + 48 is for the progress monitor +#define FLASHMAP_MAX_SIZE (sizeof(tstrFlashLUTHeader) + (((sizeof(tstrFlashLUTEntry) * FLASHMAP_MAX_ENTRIES) + 8) * 2) + 48) + + +/** @defgroup SPiFlashRead spi_flexible_flash_find_section + * @ingroup SPIFLASHAPI + */ + /**@{*/ +/*! + * @fn int8_t spi_flexible_flash_find_section(uint16_t u16EntryIDToLookFor, uint32_t *pu32StartOffset, uint32_t *pu32Size); + * @brief Read the Flash Map to extract the host file starting offset.\n + * @param [in] u16EntryIDToLookFor + * The ID of the location in Flash we are looking for. See @ref tenuFlashLUTEntryID. + * @param [in] pu32StartOffset + * Pointer to the variable where the Flash section start address should be stored. + * @param [in] pu32Size + * Pointer to the variable where the Flash section size should be stored. + * @warning + * In case there is a running WINC firmware, it is required to pause the firmware + * first before any trial to access SPI flash to avoid any racing between host and + * running firmware on bus. @ref m2m_wifi_download_mode can be used to pause the firmware. + * @sa m2m_wifi_download_mode + * m2m_wifi_init_hold + * @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. + + */ + int8_t spi_flexible_flash_find_section(uint16_t u16EntryIDToLookFor, uint32_t *pu32StartOffset, uint32_t *pu32Size); + /**@}*/ + +#endif /* __FLEXIBLE_FLASH_H__ */ diff --git a/AVRIoT.X/mcc_generated_files/winc/spi_flash/spi_flash.c b/AVRIoT.X/mcc_generated_files/winc/spi_flash/spi_flash.c new file mode 100644 index 0000000..ecf6d18 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/spi_flash/spi_flash.c @@ -0,0 +1,447 @@ +/** + * \file + * + * \brief SPI flash API + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#include "../driver/winc_adapter.h" +#include "../common/winc_defines.h" +#include "../common/winc_registers.h" +#include "../common/winc_debug.h" +#include "../driver/winc_spi.h" +#include "../driver/winc_asic.h" +#include "spi_flash.h" +#include "spi_flash_map.h" + +#define HOST_SHARE_MEM_BASE (0xd0000UL) +/*********************************************************** +SPI Flash DMA +***********************************************************/ + +static uint32_t gu32InternalFlashSize = 0; + +/*********************************************/ +/* STATIC FUNCTIONS */ +/*********************************************/ + +static int8_t spi_flash_read_status_reg(uint8_t *pu8Val) +{ + uint32_t u32Reg; + + winc_bus_write_reg(SPI_FLASH_DATA_CNT, 4); + winc_bus_write_reg(SPI_FLASH_BUF1, 0x05); + winc_bus_write_reg(SPI_FLASH_BUF_DIR, 0x01); + winc_bus_write_reg(SPI_FLASH_DMA_ADDR, DUMMY_REGISTER); + winc_bus_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7)); + do + { + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(SPI_FLASH_TR_DONE, &u32Reg)) + break; + } + while(u32Reg != 1); + + u32Reg = winc_bus_read_reg(DUMMY_REGISTER); + + if (winc_bus_error()) + return M2M_ERR_FAIL; + + *pu8Val = (uint8_t)(u32Reg & 0xff); + + return M2M_SUCCESS; +} + +static int8_t spi_flash_load_to_cortus_mem(uint32_t u32MemAdr, uint32_t u32FlashAdr, uint32_t u32Sz) +{ + uint32_t u32Reg; + + u32FlashAdr = CONF_WINC_UINT32_SWAP(u32FlashAdr); // 24bit address swapped and placed in top 24bits + u32FlashAdr |= 0x0b; + + winc_bus_write_reg(SPI_FLASH_DATA_CNT, u32Sz); + winc_bus_write_reg(SPI_FLASH_BUF1, u32FlashAdr); + winc_bus_write_reg(SPI_FLASH_BUF2, 0xa5); + winc_bus_write_reg(SPI_FLASH_BUF_DIR, 0x1f); + winc_bus_write_reg(SPI_FLASH_DMA_ADDR, u32MemAdr); + winc_bus_write_reg(SPI_FLASH_CMD_CNT, 5 | (1<<7)); + do + { + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(SPI_FLASH_TR_DONE, &u32Reg)) + break; + } + while(u32Reg != 1); + + if (winc_bus_error()) + return M2M_ERR_FAIL; + + return M2M_SUCCESS; +} + +static int8_t spi_flash_sector_erase(uint32_t u32FlashAdr) +{ + uint32_t u32Reg; + + u32FlashAdr = CONF_WINC_UINT32_SWAP(u32FlashAdr); // 24bit address swapped and placed in top 24bits + u32FlashAdr |= 0x20; + + winc_bus_write_reg(SPI_FLASH_DATA_CNT, 0); + winc_bus_write_reg(SPI_FLASH_BUF1, u32FlashAdr); + winc_bus_write_reg(SPI_FLASH_BUF_DIR, 0x0f); + winc_bus_write_reg(SPI_FLASH_DMA_ADDR, 0); + winc_bus_write_reg(SPI_FLASH_CMD_CNT, 4 | (1<<7)); + do + { + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(SPI_FLASH_TR_DONE, &u32Reg)) + break; + } + while(u32Reg != 1); + + if (winc_bus_error()) + return M2M_ERR_FAIL; + + return M2M_SUCCESS; +} + +static int8_t spi_flash_write_enable(void) +{ + uint32_t u32Reg; + + winc_bus_write_reg(SPI_FLASH_DATA_CNT, 0); + winc_bus_write_reg(SPI_FLASH_BUF1, 0x06); + winc_bus_write_reg(SPI_FLASH_BUF_DIR, 0x01); + winc_bus_write_reg(SPI_FLASH_DMA_ADDR, 0); + winc_bus_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7)); + do + { + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(SPI_FLASH_TR_DONE, &u32Reg)) + break; + } + while(u32Reg != 1); + + if (winc_bus_error()) + return M2M_ERR_FAIL; + + return M2M_SUCCESS; +} + +static int8_t spi_flash_write_disable(void) +{ + uint32_t u32Reg; + + winc_bus_write_reg(SPI_FLASH_DATA_CNT, 0); + winc_bus_write_reg(SPI_FLASH_BUF1, 0x04); + winc_bus_write_reg(SPI_FLASH_BUF_DIR, 0x01); + winc_bus_write_reg(SPI_FLASH_DMA_ADDR, 0); + winc_bus_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7)); + do + { + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(SPI_FLASH_TR_DONE, &u32Reg)) + break; + } + while(u32Reg != 1); + + if (winc_bus_error()) + return M2M_ERR_FAIL; + + return M2M_SUCCESS; +} + +static int8_t spi_flash_page_program(uint32_t u32MemAdr, uint32_t u32FlashAdr, uint32_t u32Sz) +{ + uint32_t u32Reg; + + u32FlashAdr = CONF_WINC_UINT32_SWAP(u32FlashAdr); // 24bit address swapped and placed in top 24bits + u32FlashAdr |= 0x02; + + winc_bus_write_reg(SPI_FLASH_DATA_CNT, 0); + winc_bus_write_reg(SPI_FLASH_BUF1, u32FlashAdr); + winc_bus_write_reg(SPI_FLASH_BUF_DIR, 0x0f); + winc_bus_write_reg(SPI_FLASH_DMA_ADDR, u32MemAdr); + winc_bus_write_reg(SPI_FLASH_CMD_CNT, 4 | (1<<7) | ((u32Sz & 0xfffff) << 8)); + do + { + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(SPI_FLASH_TR_DONE, &u32Reg)) + break; + } + while(u32Reg != 1); + + if (winc_bus_error()) + return M2M_ERR_FAIL; + + return M2M_SUCCESS; +} + +static int8_t spi_flash_read_internal(uint8_t *pu8Buf, uint32_t u32Addr, uint32_t u32Sz) +{ + /* read size must be < 64KB */ + if (M2M_SUCCESS != spi_flash_load_to_cortus_mem(HOST_SHARE_MEM_BASE, u32Addr, u32Sz)) + return M2M_ERR_FAIL; + + if (WINC_BUS_SUCCESS != winc_bus_read_block(HOST_SHARE_MEM_BASE, pu8Buf, u32Sz)) + return M2M_ERR_FAIL; + + return M2M_SUCCESS; +} + +static int8_t spi_flash_pp(uint32_t u32Offset, uint8_t *pu8Buf, uint_fast16_t u16Sz) +{ + uint8_t u8Reg; + + /* use shared packet memory as temp mem */ + if (WINC_BUS_SUCCESS != winc_bus_write_block(HOST_SHARE_MEM_BASE, pu8Buf, u16Sz)) + return M2M_ERR_FAIL; + + spi_flash_write_enable(); + spi_flash_page_program(HOST_SHARE_MEM_BASE, u32Offset, u16Sz); + spi_flash_read_status_reg(&u8Reg); + + do + { + if (M2M_SUCCESS != spi_flash_read_status_reg(&u8Reg)) + break; + } + while(u8Reg & 0x01); + + spi_flash_write_disable(); + + if (winc_bus_error()) + return M2M_ERR_FAIL; + + return M2M_SUCCESS; +} + +static uint32_t spi_flash_rdid(void) +{ + uint32_t u32Reg; + uint_fast16_t u16Cnt; + + winc_bus_write_reg(SPI_FLASH_DATA_CNT, 4); + winc_bus_write_reg(SPI_FLASH_BUF1, 0x9f); + winc_bus_write_reg(SPI_FLASH_BUF_DIR, 0x1); + winc_bus_write_reg(SPI_FLASH_DMA_ADDR, DUMMY_REGISTER); + winc_bus_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7)); + + u16Cnt = 500; + do + { + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(SPI_FLASH_TR_DONE, &u32Reg)) + break; + } + while((u32Reg != 1) && (u16Cnt--)); + + u32Reg = winc_bus_read_reg(DUMMY_REGISTER); + + if (winc_bus_error()) + return 0; + + WINC_LOG_INFO("Flash ID %" PRIx32, u32Reg); + + return u32Reg; +} + +/*********************************************/ +/* GLOBAL FUNCTIONS */ +/*********************************************/ + +int8_t spi_flash_enable(uint8_t enable) +{ + uint32_t u32Reg; + uint32_t u32Val; + + if(REV(winc_chip_get_id()) >= REV_3A0) + { + /* Enable pinmux to SPI flash. */ + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(NMI_PIN_MUX_1, &u32Val)) + return M2M_ERR_FAIL; + + /* GPIO15/16/17/18 */ + u32Val &= ~((0x7777ul) << 12); + u32Val |= ((0x1111ul) << 12); + + winc_bus_write_reg(NMI_PIN_MUX_1, u32Val); + + winc_bus_write_reg(SPI_FLASH_DATA_CNT, 0); + if(enable) + { + winc_bus_write_reg(SPI_FLASH_BUF1, 0xab); + } + else + { + winc_bus_write_reg(SPI_FLASH_BUF1, 0xb9); + } + winc_bus_write_reg(SPI_FLASH_BUF_DIR, 0x1); + winc_bus_write_reg(SPI_FLASH_DMA_ADDR, 0); + winc_bus_write_reg(SPI_FLASH_CMD_CNT, 1 | (1 << 7)); + + if (winc_bus_error()) + return M2M_ERR_FAIL; + + do + { + if (WINC_BUS_SUCCESS != winc_bus_read_reg_with_ret(SPI_FLASH_TR_DONE, &u32Reg)) + break; + } + while(u32Reg != 1); + + /* Disable pinmux to SPI flash to minimize leakage. */ + u32Val &= ~((0x7777ul) << 12); + u32Val |= ((0x0010ul) << 12); + winc_bus_write_reg(NMI_PIN_MUX_1, u32Val); + } + + return M2M_SUCCESS; +} + +int8_t spi_flash_read(uint8_t *pu8Buf, uint32_t u32offset, uint32_t u32Sz) +{ + if(u32Sz > FLASH_BLOCK_SIZE) + { + do + { + if (M2M_SUCCESS != spi_flash_read_internal(pu8Buf, u32offset, FLASH_BLOCK_SIZE)) + return M2M_ERR_FAIL; + + u32Sz -= FLASH_BLOCK_SIZE; + u32offset += FLASH_BLOCK_SIZE; + pu8Buf += FLASH_BLOCK_SIZE; + } + while(u32Sz > FLASH_BLOCK_SIZE); + } + + return spi_flash_read_internal(pu8Buf, u32offset, u32Sz); +} + +int8_t spi_flash_write(uint8_t* pu8Buf, uint32_t u32Offset, uint32_t u32Sz) +{ + uint_fast16_t u16wsz; + uint32_t u32off; + + if (u32Sz == 0) + { + WINC_LOG_ERROR("Data size = %" PRIu32, u32Sz); + return M2M_ERR_FAIL; + } + + u32off = u32Offset % FLASH_PAGE_SZ; + + if (u32off) /*first part of data in the address page*/ + { + // Calculate remaining space in this sector + u16wsz = FLASH_PAGE_SZ - u32off; + + // Cap write to the requested size if smaller + if (u16wsz > u32Sz) + u16wsz = u32Sz; + + if (spi_flash_pp(u32Offset, pu8Buf, u16wsz) != M2M_SUCCESS) + return M2M_ERR_FAIL; + + pu8Buf += u16wsz; + u32Offset += u16wsz; + u32Sz -= u16wsz; + } + + while (u32Sz > 0) + { + if (u32Sz >= FLASH_PAGE_SZ) + u16wsz = FLASH_PAGE_SZ; + else u16wsz = u32Sz; + + /*write complete page or the remaining data*/ + if (spi_flash_pp(u32Offset, pu8Buf, u16wsz) != M2M_SUCCESS) + return M2M_ERR_FAIL; + + pu8Buf += u16wsz; + u32Offset += u16wsz; + u32Sz -= u16wsz; + } + + return M2M_SUCCESS; +} + +int8_t spi_flash_erase(uint32_t u32Offset, uint32_t u32Sz) +{ + uint32_t i; + uint8_t u8Reg; + + WINC_LOG_INFO("\r\n>Start erasing..."); + + for (i=u32Offset; i<(u32Sz +u32Offset); i += (16*FLASH_PAGE_SZ)) + { + if (M2M_SUCCESS != spi_flash_write_enable()) + return M2M_ERR_FAIL; + if (M2M_SUCCESS != spi_flash_read_status_reg(&u8Reg)) + return M2M_ERR_FAIL; + if (M2M_SUCCESS != spi_flash_sector_erase(i)) + return M2M_ERR_FAIL; + if (M2M_SUCCESS != spi_flash_read_status_reg(&u8Reg)) + return M2M_ERR_FAIL; + do + { + if (M2M_SUCCESS != spi_flash_read_status_reg(&u8Reg)) + return M2M_ERR_FAIL; + } + while(u8Reg & 0x01); + } + + WINC_LOG_INFO("Done"); + + return M2M_SUCCESS; +} + +uint32_t spi_flash_get_size(void) +{ + uint32_t u32FlashId; + uint_fast8_t u8FlashPwr; + + if (gu32InternalFlashSize) + return gu32InternalFlashSize; + + u32FlashId = spi_flash_rdid(); + + if(u32FlashId != 0xffffffff) + { + /*flash size is the third byte from the FLASH RDID*/ + u8FlashPwr = ((u32FlashId>>16) & 0xff) - 0x11; /*2MBIT is the min*/ + + /*That number power 2 to get the flash size*/ + gu32InternalFlashSize = 1 << u8FlashPwr; + + WINC_LOG_INFO("Flash Size %" PRIu32 " Mb", gu32InternalFlashSize); + } + else + { + WINC_LOG_ERROR("Can't detect Flash size"); + } + + return gu32InternalFlashSize; +} diff --git a/AVRIoT.X/mcc_generated_files/winc/spi_flash/spi_flash.h b/AVRIoT.X/mcc_generated_files/winc/spi_flash/spi_flash.h new file mode 100644 index 0000000..addae90 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/spi_flash/spi_flash.h @@ -0,0 +1,188 @@ +/** + * \file + * + * \brief SPI flash API + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +/** @defgroup SPIFLASHAPI SPI Flash + @{ + @defgroup SPIFLASHFUNCTIONS Functions + @{ + @} + @} + */ + + /**@addtogroup SPIFLASHAPI + * @{ +@include spi_flash_example.c +@example spi_flash_example.c + * @} + */ + +#ifndef __SPI_FLASH_H__ +#define __SPI_FLASH_H__ + +/**@addtogroup SPIFLASHFUNCTIONS + * @{ + */ + +/*! +@fn \ + int8_t spi_flash_enable(uint8_t enable); + +@brief + Enable SPI flash operations +*/ +int8_t spi_flash_enable(uint8_t enable); + +/*! +@fn \ + uint32_t spi_flash_get_size(void); + +@brief + Returns size of the flash in megabits. + +@return + SPI flash size in case of success and a zero value in case of failure. +*/ +uint32_t spi_flash_get_size(void); + +/*! +@fn \ + int8_t spi_flash_read(uint8_t *pu8Buf, uint32_t u32Addr, uint32_t u32Sz); + +@brief + Read a specified block of data from the SPI flash. + +@param[out] pu8Buf + Pointer to a data buffer to be filled with data. + +@param[in] u32Addr + Address offset within the SPI flash to read the data from. + +@param[in] u32Sz + Total size of data to be read (in bytes). + +@note + No firmware is required to be loaded on the WINC for the SPI flash to be accessed. + +@warning + The read must not exceed the last address of the flash. + +@warning + If the WINC device has running firmware it must be stopped before interacting with + the SPI flash using @ref m2m_wifi_download_mode. + +@see m2m_wifi_download_mode + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +*/ +int8_t spi_flash_read(uint8_t *pu8Buf, uint32_t u32Addr, uint32_t u32Sz); + +/*! +@fn \ + int8_t spi_flash_write(uint8_t* pu8Buf, uint32_t u32Offset, uint32_t u32Sz); + +@brief + Write a specified block of data to the SPI flash. + +@param[in] pu8Buf + Pointer to a data buffer containing data to be written. + +@param[in] u32Offset + Address offset within the SPI flash to write the data to. + +@param[in] u32Sz + Total size of data to be written (in bytes). + +@note + No firmware is required to be loaded on the WINC for the SPI flash to be accessed. + +@warning + The read must not exceed the last address of the flash. + +@warning + If the WINC device has running firmware it must be stopped before interacting with + the SPI flash using @ref m2m_wifi_download_mode. + +@warning + The flash sector should be erased before writing data using the function @ref spi_flash_erase + otherwise the correct data will not be written. + +@see m2m_wifi_download_mode +@see spi_flash_erase + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +*/ +int8_t spi_flash_write(uint8_t* pu8Buf, uint32_t u32Offset, uint32_t u32Sz); + +/*! +@fn \ + int8_t spi_flash_erase(uint32_t u32Offset, uint32_t u32Sz); + +@brief Erase a specified range of sectors within the SPI flash. + +@param[in] u32Offset + Address offset within the SPI flash to erase from. + +@param[in] u32Sz + Total size of data to be erased (in bytes). + +@note + No firmware is required to be loaded on the WINC for the SPI flash to be accessed. + +@note + The SPI flash is erased in whole sectors, therefore if @p u32Offset is not aligned + with a sector boundary it will rounded down to the nearest sector start address. + If the erase range ends before a sector boundary it will be rounded up to include + a complete sector. + +@warning + The read must not exceed the last address of the flash. + +@warning + If the WINC device has running firmware it must be stopped before interacting with + the SPI flash using @ref m2m_wifi_download_mode. + +@see m2m_wifi_download_mode + +@return + The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise. +*/ +int8_t spi_flash_erase(uint32_t u32Offset, uint32_t u32Sz); + + /**@}*/ + +#endif //__SPI_FLASH_H__ diff --git a/AVRIoT.X/mcc_generated_files/winc/spi_flash/spi_flash_map.h b/AVRIoT.X/mcc_generated_files/winc/spi_flash/spi_flash_map.h new file mode 100644 index 0000000..e5d2d35 --- /dev/null +++ b/AVRIoT.X/mcc_generated_files/winc/spi_flash/spi_flash_map.h @@ -0,0 +1,223 @@ +/** + * \file + * + * \brief This module contains the SPI flash map + * + * Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries. + * + * \asf_license_start + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip + * software and any derivatives exclusively with Microchip products. + * It is your responsibility to comply with third party license terms applicable + * to your use of third party software (including open source software) that + * may accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, + * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, + * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, + * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE + * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE + * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE + * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY + * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, + * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Microchip Support + */ + +#ifndef __SPI_FLASH_MAP_H__ +#define __SPI_FLASH_MAP_H__ + +#define FLASH_MAP_VER_0 (0) +#define FLASH_MAP_VER_1 (1) +#define FLASH_MAP_VER_2 (2) +#define FLASH_MAP_VER_3 (3) +#define FLASH_MAP_VER_4 (4) + +#define FLASH_MAP_VERSION FLASH_MAP_VER_4 + +//#define DOWNLOAD_ROLLBACK +//#define OTA_GEN +#define _PROGRAM_POWER_SAVE_ + +/* =======*=======*=======*=======*======= + * General Sizes for Flash Memory + * =======*=======*=======*=======*======= + */ + +#define FLASH_START_ADDR (0UL) +/*! location :xxxK + * "S:xxxK" -means-> Size is :xxxK + */ + +/* + * Boot Firmware: used to select which firmware to run + */ +#define M2M_BOOT_FIRMWARE_STARTING_ADDR (FLASH_START_ADDR) +#define M2M_BOOT_FIRMWARE_FLASH_SZ (FLASH_SECTOR_SZ) + +/* + * Control Section: used by Boot firmware + */ +#define M2M_CONTROL_FLASH_OFFSET (M2M_BOOT_FIRMWARE_STARTING_ADDR + M2M_BOOT_FIRMWARE_FLASH_SZ) +#define M2M_CONTROL_FLASH_BKP_OFFSET (M2M_CONTROL_FLASH_OFFSET + FLASH_SECTOR_SZ) +#define M2M_CONTROL_FLASH_SEC_SZ (FLASH_SECTOR_SZ) +#define M2M_CONTROL_FLASH_TOTAL_SZ (FLASH_SECTOR_SZ * 2) + +/* + * LUT for PLL and TX Gain settings + */ +#define M2M_PLL_FLASH_OFFSET (M2M_CONTROL_FLASH_OFFSET + M2M_CONTROL_FLASH_TOTAL_SZ) +#define M2M_PLL_FLASH_SZ (1024 * 1) +#define M2M_GAIN_FLASH_OFFSET (M2M_PLL_FLASH_OFFSET + M2M_PLL_FLASH_SZ) +#define M2M_GAIN_FLASH_SZ (M2M_CONFIG_SECT_TOTAL_SZ - M2M_PLL_FLASH_SZ) +#define M2M_CONFIG_SECT_TOTAL_SZ (FLASH_SECTOR_SZ) + +/* + * TLS Certificates + */ +#define M2M_TLS_ROOTCER_FLASH_OFFSET (M2M_PLL_FLASH_OFFSET + M2M_CONFIG_SECT_TOTAL_SZ) +#define M2M_TLS_ROOTCER_FLASH_SIZE (FLASH_SECTOR_SZ * 1) + +/* + * TLS Server Key Files + */ +#define M2M_TLS_SERVER_FLASH_OFFSET (M2M_TLS_ROOTCER_FLASH_OFFSET + M2M_TLS_ROOTCER_FLASH_SIZE) +#define M2M_TLS_SERVER_FLASH_SIZE (FLASH_SECTOR_SZ * 2) + +/* + * HTTP Files + * + */ +#define M2M_HTTP_MEM_FLASH_OFFSET (M2M_TLS_SERVER_FLASH_OFFSET + M2M_TLS_SERVER_FLASH_SIZE) +#define M2M_HTTP_MEM_FLASH_SZ (FLASH_SECTOR_SZ * 2) + +/* + * Saved Connection Parameters + */ +#define M2M_CACHED_CONNS_FLASH_OFFSET (M2M_HTTP_MEM_FLASH_OFFSET + M2M_HTTP_MEM_FLASH_SZ) +#define M2M_CACHED_CONNS_FLASH_SZ (FLASH_SECTOR_SZ * 1) + +/* + * Common section size + */ +#define M2M_COMMON_DATA_SEC \ + (\ + M2M_BOOT_FIRMWARE_FLASH_SZ + \ + M2M_CONTROL_FLASH_TOTAL_SZ + \ + M2M_CONFIG_SECT_TOTAL_SZ + \ + M2M_TLS_ROOTCER_FLASH_SIZE + \ + M2M_TLS_SERVER_FLASH_SIZE + \ + M2M_HTTP_MEM_FLASH_SZ + \ + M2M_CACHED_CONNS_FLASH_SZ \ + ) + +/* + * OTA image1 Offset (Firmware offset) + */ +#define M2M_OTA_IMAGE1_OFFSET (M2M_CACHED_CONNS_FLASH_OFFSET + M2M_CACHED_CONNS_FLASH_SZ) + +#if (defined _FIRMWARE_)||(defined OTA_GEN) +#define M2M_FIRMWARE_FLASH_OFFSET (0UL) +#else +#if (defined DOWNLOAD_ROLLBACK) +#define M2M_FIRMWARE_FLASH_OFFSET (M2M_OTA_IMAGE2_OFFSET) +#else +#define M2M_FIRMWARE_FLASH_OFFSET (M2M_OTA_IMAGE1_OFFSET) +#endif +#endif +/* + * + * Firmware + */ +#define M2M_FIRMWARE_FLASH_SZ (236 * 1024UL) +/** + * + * OTA image Size + */ +#define OTA_IMAGE_SIZE (M2M_FIRMWARE_FLASH_SZ) +/** + * + * Flash Total size + */ +#define FLASH_IMAGE1_CONTENT_SZ (M2M_COMMON_DATA_SEC + OTA_IMAGE_SIZE) + +/** + * + * OTA image 2 offset + */ +#define M2M_OTA_IMAGE2_OFFSET (FLASH_IMAGE1_CONTENT_SZ) + +#define M2M_HFD_8M_MEM_FLASH_OFFSET (M2M_OTA_IMAGE2_OFFSET + OTA_IMAGE_SIZE) + +/* Check if total size of content + * don't exceed total size of memory allowed + **/ +#if (M2M_COMMON_DATA_SEC + (OTA_IMAGE_SIZE *2)> FLASH_4M_TOTAL_SZ) +#error "Exceeds 4M Flash Size" +#endif /* (FLASH_CONTENT_SZ > FLASH_TOTAL_SZ) */ + +/** + * Magic value to differentiate between old HTTP flash section format and newer formats. + * The lowest byte is ignored when checking the value as it contains the + * version number (it should always be 00 here, image_builder will set this value in flash). + **/ +#define HTTP_FLASH_SECTION_MAGIC 0xB00B1500 +#define HTTP_FLASH_SECTION_VERSION 2 + + +#endif /* __SPI_FLASH_MAP_H__ */ diff --git a/AVRIoT.X/nbproject/Makefile-AWS_IOT.mk b/AVRIoT.X/nbproject/Makefile-AWS_IOT.mk new file mode 100644 index 0000000..b182957 --- /dev/null +++ b/AVRIoT.X/nbproject/Makefile-AWS_IOT.mk @@ -0,0 +1,1278 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a -pre and a -post target defined where you can add customized code. +# +# This makefile implements configuration specific macros and targets. + + +# Include project Makefile +ifeq "${IGNORE_LOCAL}" "TRUE" +# do not include local makefile. User is passing all local related variables already +else +include Makefile +# Include makefile containing local settings +ifeq "$(wildcard nbproject/Makefile-local-AWS_IOT.mk)" "nbproject/Makefile-local-AWS_IOT.mk" +include nbproject/Makefile-local-AWS_IOT.mk +endif +endif + +# Environment +MKDIR=mkdir -p +RM=rm -f +MV=mv +CP=cp + +# Macros +CND_CONF=AWS_IOT +ifeq ($(TYPE_IMAGE), DEBUG_RUN) +IMAGE_TYPE=debug +OUTPUT_SUFFIX=elf +DEBUGGABLE_SUFFIX=elf +FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/AVRIoT.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX} +else +IMAGE_TYPE=production +OUTPUT_SUFFIX=hex +DEBUGGABLE_SUFFIX=elf +FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/AVRIoT.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX} +endif + +ifeq ($(COMPARE_BUILD), true) +COMPARISON_BUILD= +else +COMPARISON_BUILD= +endif + +ifdef SUB_IMAGE_ADDRESS + +else +SUB_IMAGE_ADDRESS_COMMAND= +endif + +# Object Directory +OBJECTDIR=build/${CND_CONF}/${IMAGE_TYPE} + +# Distribution Directory +DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE} + +# Source Files Quoted if spaced +SOURCEFILES_QUOTED_IF_SPACED=mcc_generated_files/cli/cli.c mcc_generated_files/cloud/crypto_client/crypto_client.c mcc_generated_files/cloud/cloud_service.c mcc_generated_files/cloud/wifi_service.c mcc_generated_files/cloud/mqtt_service.c mcc_generated_files/cloud/aws_cloud_service.c mcc_generated_files/credentials_storage/credentials_storage.c mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.c mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.c mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.c mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.c mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.c mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.c mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.c mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.c mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.c mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.c mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.c mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.c mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.c mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.c mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.c mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.c mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.c mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.c mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.c mcc_generated_files/CryptoAuthenticationLibrary/atca_command.c mcc_generated_files/CryptoAuthenticationLibrary/atca_device.c mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.c mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.c mcc_generated_files/drivers/spi_master.c mcc_generated_files/drivers/timeout.c mcc_generated_files/drivers/i2c_simple_master.c mcc_generated_files/drivers/uart.c mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.c mcc_generated_files/mqtt/mqtt_core/mqtt_core.c mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.c mcc_generated_files/mqtt/mqtt_packetTransfer_interface.c mcc_generated_files/mqtt/mqtt_winc_adapter.c mcc_generated_files/src/pin_manager.c mcc_generated_files/src/cpuint.c mcc_generated_files/src/spi0.c mcc_generated_files/src/protected_io.S mcc_generated_files/src/rtc.c mcc_generated_files/src/twi0_master.c mcc_generated_files/src/adc0.c mcc_generated_files/src/usart2.c mcc_generated_files/winc/driver/winc_spi.c mcc_generated_files/winc/driver/winc_adapter.c mcc_generated_files/winc/driver/winc_hif.c mcc_generated_files/winc/driver/winc_asic.c mcc_generated_files/winc/driver/winc_drv.c mcc_generated_files/winc/m2m/m2m_ssl.c mcc_generated_files/winc/m2m/m2m_wifi.c mcc_generated_files/winc/m2m/m2m_periph.c mcc_generated_files/winc/m2m/m2m_ota.c mcc_generated_files/winc/m2m/m2m_fwinfo.c mcc_generated_files/winc/m2m/m2m_crypto.c mcc_generated_files/winc/socket/socket.c mcc_generated_files/winc/spi_flash/flexible_flash.c mcc_generated_files/winc/spi_flash/spi_flash.c mcc_generated_files/mcc.c mcc_generated_files/delay.c mcc_generated_files/device_config.c mcc_generated_files/application_manager.c mcc_generated_files/debug_print.c mcc_generated_files/led.c mcc_generated_files/sensors_handling.c mcc_generated_files/time_service.c mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.c main.c + +# Object Files Quoted if spaced +OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/mcc_generated_files/cli/cli.o ${OBJECTDIR}/mcc_generated_files/cloud/crypto_client/crypto_client.o ${OBJECTDIR}/mcc_generated_files/cloud/cloud_service.o ${OBJECTDIR}/mcc_generated_files/cloud/wifi_service.o ${OBJECTDIR}/mcc_generated_files/cloud/mqtt_service.o ${OBJECTDIR}/mcc_generated_files/cloud/aws_cloud_service.o ${OBJECTDIR}/mcc_generated_files/credentials_storage/credentials_storage.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.o ${OBJECTDIR}/mcc_generated_files/drivers/spi_master.o ${OBJECTDIR}/mcc_generated_files/drivers/timeout.o ${OBJECTDIR}/mcc_generated_files/drivers/i2c_simple_master.o ${OBJECTDIR}/mcc_generated_files/drivers/uart.o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core/mqtt_core.o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_winc_adapter.o ${OBJECTDIR}/mcc_generated_files/src/pin_manager.o ${OBJECTDIR}/mcc_generated_files/src/cpuint.o ${OBJECTDIR}/mcc_generated_files/src/spi0.o ${OBJECTDIR}/mcc_generated_files/src/protected_io.o ${OBJECTDIR}/mcc_generated_files/src/rtc.o ${OBJECTDIR}/mcc_generated_files/src/twi0_master.o ${OBJECTDIR}/mcc_generated_files/src/adc0.o ${OBJECTDIR}/mcc_generated_files/src/usart2.o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_spi.o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_adapter.o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_hif.o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_asic.o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_drv.o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ssl.o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_wifi.o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_periph.o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ota.o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_fwinfo.o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_crypto.o ${OBJECTDIR}/mcc_generated_files/winc/socket/socket.o ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/flexible_flash.o ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/spi_flash.o ${OBJECTDIR}/mcc_generated_files/mcc.o ${OBJECTDIR}/mcc_generated_files/delay.o ${OBJECTDIR}/mcc_generated_files/device_config.o ${OBJECTDIR}/mcc_generated_files/application_manager.o ${OBJECTDIR}/mcc_generated_files/debug_print.o ${OBJECTDIR}/mcc_generated_files/led.o ${OBJECTDIR}/mcc_generated_files/sensors_handling.o ${OBJECTDIR}/mcc_generated_files/time_service.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.o ${OBJECTDIR}/main.o +POSSIBLE_DEPFILES=${OBJECTDIR}/mcc_generated_files/cli/cli.o.d ${OBJECTDIR}/mcc_generated_files/cloud/crypto_client/crypto_client.o.d ${OBJECTDIR}/mcc_generated_files/cloud/cloud_service.o.d ${OBJECTDIR}/mcc_generated_files/cloud/wifi_service.o.d ${OBJECTDIR}/mcc_generated_files/cloud/mqtt_service.o.d ${OBJECTDIR}/mcc_generated_files/cloud/aws_cloud_service.o.d ${OBJECTDIR}/mcc_generated_files/credentials_storage/credentials_storage.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.o.d ${OBJECTDIR}/mcc_generated_files/drivers/spi_master.o.d ${OBJECTDIR}/mcc_generated_files/drivers/timeout.o.d ${OBJECTDIR}/mcc_generated_files/drivers/i2c_simple_master.o.d ${OBJECTDIR}/mcc_generated_files/drivers/uart.o.d ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.o.d ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core/mqtt_core.o.d ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.o.d ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.o.d ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_winc_adapter.o.d ${OBJECTDIR}/mcc_generated_files/src/pin_manager.o.d ${OBJECTDIR}/mcc_generated_files/src/cpuint.o.d ${OBJECTDIR}/mcc_generated_files/src/spi0.o.d ${OBJECTDIR}/mcc_generated_files/src/protected_io.o.d ${OBJECTDIR}/mcc_generated_files/src/rtc.o.d ${OBJECTDIR}/mcc_generated_files/src/twi0_master.o.d ${OBJECTDIR}/mcc_generated_files/src/adc0.o.d ${OBJECTDIR}/mcc_generated_files/src/usart2.o.d ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_spi.o.d ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_adapter.o.d ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_hif.o.d ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_asic.o.d ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_drv.o.d ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ssl.o.d ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_wifi.o.d ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_periph.o.d ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ota.o.d ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_fwinfo.o.d ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_crypto.o.d ${OBJECTDIR}/mcc_generated_files/winc/socket/socket.o.d ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/flexible_flash.o.d ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/spi_flash.o.d ${OBJECTDIR}/mcc_generated_files/mcc.o.d ${OBJECTDIR}/mcc_generated_files/delay.o.d ${OBJECTDIR}/mcc_generated_files/device_config.o.d ${OBJECTDIR}/mcc_generated_files/application_manager.o.d ${OBJECTDIR}/mcc_generated_files/debug_print.o.d ${OBJECTDIR}/mcc_generated_files/led.o.d ${OBJECTDIR}/mcc_generated_files/sensors_handling.o.d ${OBJECTDIR}/mcc_generated_files/time_service.o.d ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.o.d ${OBJECTDIR}/main.o.d + +# Object Files +OBJECTFILES=${OBJECTDIR}/mcc_generated_files/cli/cli.o ${OBJECTDIR}/mcc_generated_files/cloud/crypto_client/crypto_client.o ${OBJECTDIR}/mcc_generated_files/cloud/cloud_service.o ${OBJECTDIR}/mcc_generated_files/cloud/wifi_service.o ${OBJECTDIR}/mcc_generated_files/cloud/mqtt_service.o ${OBJECTDIR}/mcc_generated_files/cloud/aws_cloud_service.o ${OBJECTDIR}/mcc_generated_files/credentials_storage/credentials_storage.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.o ${OBJECTDIR}/mcc_generated_files/drivers/spi_master.o ${OBJECTDIR}/mcc_generated_files/drivers/timeout.o ${OBJECTDIR}/mcc_generated_files/drivers/i2c_simple_master.o ${OBJECTDIR}/mcc_generated_files/drivers/uart.o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core/mqtt_core.o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_winc_adapter.o ${OBJECTDIR}/mcc_generated_files/src/pin_manager.o ${OBJECTDIR}/mcc_generated_files/src/cpuint.o ${OBJECTDIR}/mcc_generated_files/src/spi0.o ${OBJECTDIR}/mcc_generated_files/src/protected_io.o ${OBJECTDIR}/mcc_generated_files/src/rtc.o ${OBJECTDIR}/mcc_generated_files/src/twi0_master.o ${OBJECTDIR}/mcc_generated_files/src/adc0.o ${OBJECTDIR}/mcc_generated_files/src/usart2.o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_spi.o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_adapter.o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_hif.o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_asic.o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_drv.o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ssl.o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_wifi.o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_periph.o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ota.o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_fwinfo.o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_crypto.o ${OBJECTDIR}/mcc_generated_files/winc/socket/socket.o ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/flexible_flash.o ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/spi_flash.o ${OBJECTDIR}/mcc_generated_files/mcc.o ${OBJECTDIR}/mcc_generated_files/delay.o ${OBJECTDIR}/mcc_generated_files/device_config.o ${OBJECTDIR}/mcc_generated_files/application_manager.o ${OBJECTDIR}/mcc_generated_files/debug_print.o ${OBJECTDIR}/mcc_generated_files/led.o ${OBJECTDIR}/mcc_generated_files/sensors_handling.o ${OBJECTDIR}/mcc_generated_files/time_service.o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.o ${OBJECTDIR}/main.o + +# Source Files +SOURCEFILES=mcc_generated_files/cli/cli.c mcc_generated_files/cloud/crypto_client/crypto_client.c mcc_generated_files/cloud/cloud_service.c mcc_generated_files/cloud/wifi_service.c mcc_generated_files/cloud/mqtt_service.c mcc_generated_files/cloud/aws_cloud_service.c mcc_generated_files/credentials_storage/credentials_storage.c mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.c mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.c mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.c mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.c mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.c mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.c mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.c mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.c mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.c mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.c mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.c mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.c mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.c mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.c mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.c mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.c mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.c mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.c mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.c mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.c mcc_generated_files/CryptoAuthenticationLibrary/atca_command.c mcc_generated_files/CryptoAuthenticationLibrary/atca_device.c mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.c mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.c mcc_generated_files/drivers/spi_master.c mcc_generated_files/drivers/timeout.c mcc_generated_files/drivers/i2c_simple_master.c mcc_generated_files/drivers/uart.c mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.c mcc_generated_files/mqtt/mqtt_core/mqtt_core.c mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.c mcc_generated_files/mqtt/mqtt_packetTransfer_interface.c mcc_generated_files/mqtt/mqtt_winc_adapter.c mcc_generated_files/src/pin_manager.c mcc_generated_files/src/cpuint.c mcc_generated_files/src/spi0.c mcc_generated_files/src/protected_io.S mcc_generated_files/src/rtc.c mcc_generated_files/src/twi0_master.c mcc_generated_files/src/adc0.c mcc_generated_files/src/usart2.c mcc_generated_files/winc/driver/winc_spi.c mcc_generated_files/winc/driver/winc_adapter.c mcc_generated_files/winc/driver/winc_hif.c mcc_generated_files/winc/driver/winc_asic.c mcc_generated_files/winc/driver/winc_drv.c mcc_generated_files/winc/m2m/m2m_ssl.c mcc_generated_files/winc/m2m/m2m_wifi.c mcc_generated_files/winc/m2m/m2m_periph.c mcc_generated_files/winc/m2m/m2m_ota.c mcc_generated_files/winc/m2m/m2m_fwinfo.c mcc_generated_files/winc/m2m/m2m_crypto.c mcc_generated_files/winc/socket/socket.c mcc_generated_files/winc/spi_flash/flexible_flash.c mcc_generated_files/winc/spi_flash/spi_flash.c mcc_generated_files/mcc.c mcc_generated_files/delay.c mcc_generated_files/device_config.c mcc_generated_files/application_manager.c mcc_generated_files/debug_print.c mcc_generated_files/led.c mcc_generated_files/sensors_handling.c mcc_generated_files/time_service.c mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.c main.c + + + +CFLAGS= +ASFLAGS= +LDLIBSOPTIONS= + +############# Tool locations ########################################## +# If you copy a project from one host to another, the path where the # +# compiler is installed may be different. # +# If you open this project with MPLAB X in the new host, this # +# makefile will be regenerated and the paths will be corrected. # +####################################################################### +# fixDeps replaces a bunch of sed/cat/printf statements that slow down the build +FIXDEPS=fixDeps + +.build-conf: ${BUILD_SUBPROJECTS} +ifneq ($(INFORMATION_MESSAGE), ) + @echo $(INFORMATION_MESSAGE) +endif + ${MAKE} -f nbproject/Makefile-AWS_IOT.mk dist/${CND_CONF}/${IMAGE_TYPE}/AVRIoT.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX} + +MP_PROCESSOR_OPTION=ATmega4808 +# ------------------------------------------------------------------------------------ +# Rules for buildStep: compile +ifeq ($(TYPE_IMAGE), DEBUG_RUN) +${OBJECTDIR}/mcc_generated_files/cli/cli.o: mcc_generated_files/cli/cli.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/cli" + @${RM} ${OBJECTDIR}/mcc_generated_files/cli/cli.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/cli/cli.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/cli/cli.o.d" -MT "${OBJECTDIR}/mcc_generated_files/cli/cli.o.d" -MT ${OBJECTDIR}/mcc_generated_files/cli/cli.o -o ${OBJECTDIR}/mcc_generated_files/cli/cli.o mcc_generated_files/cli/cli.c + +${OBJECTDIR}/mcc_generated_files/cloud/crypto_client/crypto_client.o: mcc_generated_files/cloud/crypto_client/crypto_client.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/cloud/crypto_client" + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/crypto_client/crypto_client.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/crypto_client/crypto_client.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/cloud/crypto_client/crypto_client.o.d" -MT "${OBJECTDIR}/mcc_generated_files/cloud/crypto_client/crypto_client.o.d" -MT ${OBJECTDIR}/mcc_generated_files/cloud/crypto_client/crypto_client.o -o ${OBJECTDIR}/mcc_generated_files/cloud/crypto_client/crypto_client.o mcc_generated_files/cloud/crypto_client/crypto_client.c + +${OBJECTDIR}/mcc_generated_files/cloud/cloud_service.o: mcc_generated_files/cloud/cloud_service.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/cloud" + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/cloud_service.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/cloud_service.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/cloud/cloud_service.o.d" -MT "${OBJECTDIR}/mcc_generated_files/cloud/cloud_service.o.d" -MT ${OBJECTDIR}/mcc_generated_files/cloud/cloud_service.o -o ${OBJECTDIR}/mcc_generated_files/cloud/cloud_service.o mcc_generated_files/cloud/cloud_service.c + +${OBJECTDIR}/mcc_generated_files/cloud/wifi_service.o: mcc_generated_files/cloud/wifi_service.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/cloud" + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/wifi_service.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/wifi_service.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/cloud/wifi_service.o.d" -MT "${OBJECTDIR}/mcc_generated_files/cloud/wifi_service.o.d" -MT ${OBJECTDIR}/mcc_generated_files/cloud/wifi_service.o -o ${OBJECTDIR}/mcc_generated_files/cloud/wifi_service.o mcc_generated_files/cloud/wifi_service.c + +${OBJECTDIR}/mcc_generated_files/cloud/mqtt_service.o: mcc_generated_files/cloud/mqtt_service.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/cloud" + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/mqtt_service.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/mqtt_service.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/cloud/mqtt_service.o.d" -MT "${OBJECTDIR}/mcc_generated_files/cloud/mqtt_service.o.d" -MT ${OBJECTDIR}/mcc_generated_files/cloud/mqtt_service.o -o ${OBJECTDIR}/mcc_generated_files/cloud/mqtt_service.o mcc_generated_files/cloud/mqtt_service.c + +${OBJECTDIR}/mcc_generated_files/cloud/aws_cloud_service.o: mcc_generated_files/cloud/aws_cloud_service.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/cloud" + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/aws_cloud_service.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/aws_cloud_service.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/cloud/aws_cloud_service.o.d" -MT "${OBJECTDIR}/mcc_generated_files/cloud/aws_cloud_service.o.d" -MT ${OBJECTDIR}/mcc_generated_files/cloud/aws_cloud_service.o -o ${OBJECTDIR}/mcc_generated_files/cloud/aws_cloud_service.o mcc_generated_files/cloud/aws_cloud_service.c + +${OBJECTDIR}/mcc_generated_files/credentials_storage/credentials_storage.o: mcc_generated_files/credentials_storage/credentials_storage.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/credentials_storage" + @${RM} ${OBJECTDIR}/mcc_generated_files/credentials_storage/credentials_storage.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/credentials_storage/credentials_storage.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/credentials_storage/credentials_storage.o.d" -MT "${OBJECTDIR}/mcc_generated_files/credentials_storage/credentials_storage.o.d" -MT ${OBJECTDIR}/mcc_generated_files/credentials_storage/credentials_storage.o -o ${OBJECTDIR}/mcc_generated_files/credentials_storage/credentials_storage.o mcc_generated_files/credentials_storage/credentials_storage.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.o: mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.o mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.o: mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.o mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.o: mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.o mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.o: mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.o mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.o: mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.o mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.o: mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.o mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.o: mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.o mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.o: mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.o mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.o: mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.o mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.o: mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.o mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.o: mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.o mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.o: mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.o mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.o: mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.o mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.o: mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.o mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.o: mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.o mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.o: mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.o mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.o: mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.o mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.o: mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.o mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.o: mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.o mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.o: mcc_generated_files/CryptoAuthenticationLibrary/atca_command.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.o mcc_generated_files/CryptoAuthenticationLibrary/atca_command.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.o: mcc_generated_files/CryptoAuthenticationLibrary/atca_device.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.o mcc_generated_files/CryptoAuthenticationLibrary/atca_device.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.o: mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.o mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.o: mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.o mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.c + +${OBJECTDIR}/mcc_generated_files/drivers/spi_master.o: mcc_generated_files/drivers/spi_master.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/drivers" + @${RM} ${OBJECTDIR}/mcc_generated_files/drivers/spi_master.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/drivers/spi_master.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/drivers/spi_master.o.d" -MT "${OBJECTDIR}/mcc_generated_files/drivers/spi_master.o.d" -MT ${OBJECTDIR}/mcc_generated_files/drivers/spi_master.o -o ${OBJECTDIR}/mcc_generated_files/drivers/spi_master.o mcc_generated_files/drivers/spi_master.c + +${OBJECTDIR}/mcc_generated_files/drivers/timeout.o: mcc_generated_files/drivers/timeout.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/drivers" + @${RM} ${OBJECTDIR}/mcc_generated_files/drivers/timeout.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/drivers/timeout.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/drivers/timeout.o.d" -MT "${OBJECTDIR}/mcc_generated_files/drivers/timeout.o.d" -MT ${OBJECTDIR}/mcc_generated_files/drivers/timeout.o -o ${OBJECTDIR}/mcc_generated_files/drivers/timeout.o mcc_generated_files/drivers/timeout.c + +${OBJECTDIR}/mcc_generated_files/drivers/i2c_simple_master.o: mcc_generated_files/drivers/i2c_simple_master.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/drivers" + @${RM} ${OBJECTDIR}/mcc_generated_files/drivers/i2c_simple_master.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/drivers/i2c_simple_master.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/drivers/i2c_simple_master.o.d" -MT "${OBJECTDIR}/mcc_generated_files/drivers/i2c_simple_master.o.d" -MT ${OBJECTDIR}/mcc_generated_files/drivers/i2c_simple_master.o -o ${OBJECTDIR}/mcc_generated_files/drivers/i2c_simple_master.o mcc_generated_files/drivers/i2c_simple_master.c + +${OBJECTDIR}/mcc_generated_files/drivers/uart.o: mcc_generated_files/drivers/uart.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/drivers" + @${RM} ${OBJECTDIR}/mcc_generated_files/drivers/uart.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/drivers/uart.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/drivers/uart.o.d" -MT "${OBJECTDIR}/mcc_generated_files/drivers/uart.o.d" -MT ${OBJECTDIR}/mcc_generated_files/drivers/uart.o -o ${OBJECTDIR}/mcc_generated_files/drivers/uart.o mcc_generated_files/drivers/uart.c + +${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.o: mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd" + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.o.d" -MT "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.o.d" -MT ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.o -o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.o mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.c + +${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core/mqtt_core.o: mcc_generated_files/mqtt/mqtt_core/mqtt_core.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core" + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core/mqtt_core.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core/mqtt_core.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core/mqtt_core.o.d" -MT "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core/mqtt_core.o.d" -MT ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core/mqtt_core.o -o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core/mqtt_core.o mcc_generated_files/mqtt/mqtt_core/mqtt_core.c + +${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.o: mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer" + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.o.d" -MT "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.o.d" -MT ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.o -o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.o mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.c + +${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.o: mcc_generated_files/mqtt/mqtt_packetTransfer_interface.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/mqtt" + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.o.d" -MT "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.o.d" -MT ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.o -o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.o mcc_generated_files/mqtt/mqtt_packetTransfer_interface.c + +${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_winc_adapter.o: mcc_generated_files/mqtt/mqtt_winc_adapter.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/mqtt" + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_winc_adapter.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_winc_adapter.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_winc_adapter.o.d" -MT "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_winc_adapter.o.d" -MT ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_winc_adapter.o -o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_winc_adapter.o mcc_generated_files/mqtt/mqtt_winc_adapter.c + +${OBJECTDIR}/mcc_generated_files/src/pin_manager.o: mcc_generated_files/src/pin_manager.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/src" + @${RM} ${OBJECTDIR}/mcc_generated_files/src/pin_manager.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/src/pin_manager.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/src/pin_manager.o.d" -MT "${OBJECTDIR}/mcc_generated_files/src/pin_manager.o.d" -MT ${OBJECTDIR}/mcc_generated_files/src/pin_manager.o -o ${OBJECTDIR}/mcc_generated_files/src/pin_manager.o mcc_generated_files/src/pin_manager.c + +${OBJECTDIR}/mcc_generated_files/src/cpuint.o: mcc_generated_files/src/cpuint.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/src" + @${RM} ${OBJECTDIR}/mcc_generated_files/src/cpuint.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/src/cpuint.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/src/cpuint.o.d" -MT "${OBJECTDIR}/mcc_generated_files/src/cpuint.o.d" -MT ${OBJECTDIR}/mcc_generated_files/src/cpuint.o -o ${OBJECTDIR}/mcc_generated_files/src/cpuint.o mcc_generated_files/src/cpuint.c + +${OBJECTDIR}/mcc_generated_files/src/spi0.o: mcc_generated_files/src/spi0.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/src" + @${RM} ${OBJECTDIR}/mcc_generated_files/src/spi0.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/src/spi0.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/src/spi0.o.d" -MT "${OBJECTDIR}/mcc_generated_files/src/spi0.o.d" -MT ${OBJECTDIR}/mcc_generated_files/src/spi0.o -o ${OBJECTDIR}/mcc_generated_files/src/spi0.o mcc_generated_files/src/spi0.c + +${OBJECTDIR}/mcc_generated_files/src/rtc.o: mcc_generated_files/src/rtc.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/src" + @${RM} ${OBJECTDIR}/mcc_generated_files/src/rtc.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/src/rtc.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/src/rtc.o.d" -MT "${OBJECTDIR}/mcc_generated_files/src/rtc.o.d" -MT ${OBJECTDIR}/mcc_generated_files/src/rtc.o -o ${OBJECTDIR}/mcc_generated_files/src/rtc.o mcc_generated_files/src/rtc.c + +${OBJECTDIR}/mcc_generated_files/src/twi0_master.o: mcc_generated_files/src/twi0_master.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/src" + @${RM} ${OBJECTDIR}/mcc_generated_files/src/twi0_master.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/src/twi0_master.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/src/twi0_master.o.d" -MT "${OBJECTDIR}/mcc_generated_files/src/twi0_master.o.d" -MT ${OBJECTDIR}/mcc_generated_files/src/twi0_master.o -o ${OBJECTDIR}/mcc_generated_files/src/twi0_master.o mcc_generated_files/src/twi0_master.c + +${OBJECTDIR}/mcc_generated_files/src/adc0.o: mcc_generated_files/src/adc0.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/src" + @${RM} ${OBJECTDIR}/mcc_generated_files/src/adc0.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/src/adc0.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/src/adc0.o.d" -MT "${OBJECTDIR}/mcc_generated_files/src/adc0.o.d" -MT ${OBJECTDIR}/mcc_generated_files/src/adc0.o -o ${OBJECTDIR}/mcc_generated_files/src/adc0.o mcc_generated_files/src/adc0.c + +${OBJECTDIR}/mcc_generated_files/src/usart2.o: mcc_generated_files/src/usart2.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/src" + @${RM} ${OBJECTDIR}/mcc_generated_files/src/usart2.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/src/usart2.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/src/usart2.o.d" -MT "${OBJECTDIR}/mcc_generated_files/src/usart2.o.d" -MT ${OBJECTDIR}/mcc_generated_files/src/usart2.o -o ${OBJECTDIR}/mcc_generated_files/src/usart2.o mcc_generated_files/src/usart2.c + +${OBJECTDIR}/mcc_generated_files/winc/driver/winc_spi.o: mcc_generated_files/winc/driver/winc_spi.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/driver" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_spi.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_spi.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_spi.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_spi.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_spi.o -o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_spi.o mcc_generated_files/winc/driver/winc_spi.c + +${OBJECTDIR}/mcc_generated_files/winc/driver/winc_adapter.o: mcc_generated_files/winc/driver/winc_adapter.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/driver" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_adapter.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_adapter.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_adapter.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_adapter.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_adapter.o -o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_adapter.o mcc_generated_files/winc/driver/winc_adapter.c + +${OBJECTDIR}/mcc_generated_files/winc/driver/winc_hif.o: mcc_generated_files/winc/driver/winc_hif.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/driver" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_hif.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_hif.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_hif.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_hif.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_hif.o -o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_hif.o mcc_generated_files/winc/driver/winc_hif.c + +${OBJECTDIR}/mcc_generated_files/winc/driver/winc_asic.o: mcc_generated_files/winc/driver/winc_asic.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/driver" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_asic.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_asic.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_asic.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_asic.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_asic.o -o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_asic.o mcc_generated_files/winc/driver/winc_asic.c + +${OBJECTDIR}/mcc_generated_files/winc/driver/winc_drv.o: mcc_generated_files/winc/driver/winc_drv.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/driver" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_drv.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_drv.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_drv.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_drv.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_drv.o -o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_drv.o mcc_generated_files/winc/driver/winc_drv.c + +${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ssl.o: mcc_generated_files/winc/m2m/m2m_ssl.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/m2m" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ssl.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ssl.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ssl.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ssl.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ssl.o -o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ssl.o mcc_generated_files/winc/m2m/m2m_ssl.c + +${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_wifi.o: mcc_generated_files/winc/m2m/m2m_wifi.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/m2m" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_wifi.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_wifi.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_wifi.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_wifi.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_wifi.o -o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_wifi.o mcc_generated_files/winc/m2m/m2m_wifi.c + +${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_periph.o: mcc_generated_files/winc/m2m/m2m_periph.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/m2m" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_periph.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_periph.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_periph.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_periph.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_periph.o -o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_periph.o mcc_generated_files/winc/m2m/m2m_periph.c + +${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ota.o: mcc_generated_files/winc/m2m/m2m_ota.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/m2m" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ota.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ota.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ota.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ota.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ota.o -o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ota.o mcc_generated_files/winc/m2m/m2m_ota.c + +${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_fwinfo.o: mcc_generated_files/winc/m2m/m2m_fwinfo.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/m2m" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_fwinfo.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_fwinfo.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_fwinfo.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_fwinfo.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_fwinfo.o -o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_fwinfo.o mcc_generated_files/winc/m2m/m2m_fwinfo.c + +${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_crypto.o: mcc_generated_files/winc/m2m/m2m_crypto.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/m2m" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_crypto.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_crypto.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_crypto.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_crypto.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_crypto.o -o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_crypto.o mcc_generated_files/winc/m2m/m2m_crypto.c + +${OBJECTDIR}/mcc_generated_files/winc/socket/socket.o: mcc_generated_files/winc/socket/socket.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/socket" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/socket/socket.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/socket/socket.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/socket/socket.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/socket/socket.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/socket/socket.o -o ${OBJECTDIR}/mcc_generated_files/winc/socket/socket.o mcc_generated_files/winc/socket/socket.c + +${OBJECTDIR}/mcc_generated_files/winc/spi_flash/flexible_flash.o: mcc_generated_files/winc/spi_flash/flexible_flash.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/spi_flash" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/flexible_flash.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/flexible_flash.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/spi_flash/flexible_flash.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/spi_flash/flexible_flash.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/flexible_flash.o -o ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/flexible_flash.o mcc_generated_files/winc/spi_flash/flexible_flash.c + +${OBJECTDIR}/mcc_generated_files/winc/spi_flash/spi_flash.o: mcc_generated_files/winc/spi_flash/spi_flash.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/spi_flash" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/spi_flash.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/spi_flash.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/spi_flash/spi_flash.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/spi_flash/spi_flash.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/spi_flash.o -o ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/spi_flash.o mcc_generated_files/winc/spi_flash/spi_flash.c + +${OBJECTDIR}/mcc_generated_files/mcc.o: mcc_generated_files/mcc.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files" + @${RM} ${OBJECTDIR}/mcc_generated_files/mcc.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/mcc.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/mcc.o.d" -MT "${OBJECTDIR}/mcc_generated_files/mcc.o.d" -MT ${OBJECTDIR}/mcc_generated_files/mcc.o -o ${OBJECTDIR}/mcc_generated_files/mcc.o mcc_generated_files/mcc.c + +${OBJECTDIR}/mcc_generated_files/delay.o: mcc_generated_files/delay.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files" + @${RM} ${OBJECTDIR}/mcc_generated_files/delay.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/delay.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/delay.o.d" -MT "${OBJECTDIR}/mcc_generated_files/delay.o.d" -MT ${OBJECTDIR}/mcc_generated_files/delay.o -o ${OBJECTDIR}/mcc_generated_files/delay.o mcc_generated_files/delay.c + +${OBJECTDIR}/mcc_generated_files/device_config.o: mcc_generated_files/device_config.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files" + @${RM} ${OBJECTDIR}/mcc_generated_files/device_config.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/device_config.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/device_config.o.d" -MT "${OBJECTDIR}/mcc_generated_files/device_config.o.d" -MT ${OBJECTDIR}/mcc_generated_files/device_config.o -o ${OBJECTDIR}/mcc_generated_files/device_config.o mcc_generated_files/device_config.c + +${OBJECTDIR}/mcc_generated_files/application_manager.o: mcc_generated_files/application_manager.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files" + @${RM} ${OBJECTDIR}/mcc_generated_files/application_manager.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/application_manager.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/application_manager.o.d" -MT "${OBJECTDIR}/mcc_generated_files/application_manager.o.d" -MT ${OBJECTDIR}/mcc_generated_files/application_manager.o -o ${OBJECTDIR}/mcc_generated_files/application_manager.o mcc_generated_files/application_manager.c + +${OBJECTDIR}/mcc_generated_files/debug_print.o: mcc_generated_files/debug_print.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files" + @${RM} ${OBJECTDIR}/mcc_generated_files/debug_print.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/debug_print.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/debug_print.o.d" -MT "${OBJECTDIR}/mcc_generated_files/debug_print.o.d" -MT ${OBJECTDIR}/mcc_generated_files/debug_print.o -o ${OBJECTDIR}/mcc_generated_files/debug_print.o mcc_generated_files/debug_print.c + +${OBJECTDIR}/mcc_generated_files/led.o: mcc_generated_files/led.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files" + @${RM} ${OBJECTDIR}/mcc_generated_files/led.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/led.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/led.o.d" -MT "${OBJECTDIR}/mcc_generated_files/led.o.d" -MT ${OBJECTDIR}/mcc_generated_files/led.o -o ${OBJECTDIR}/mcc_generated_files/led.o mcc_generated_files/led.c + +${OBJECTDIR}/mcc_generated_files/sensors_handling.o: mcc_generated_files/sensors_handling.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files" + @${RM} ${OBJECTDIR}/mcc_generated_files/sensors_handling.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/sensors_handling.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/sensors_handling.o.d" -MT "${OBJECTDIR}/mcc_generated_files/sensors_handling.o.d" -MT ${OBJECTDIR}/mcc_generated_files/sensors_handling.o -o ${OBJECTDIR}/mcc_generated_files/sensors_handling.o mcc_generated_files/sensors_handling.c + +${OBJECTDIR}/mcc_generated_files/time_service.o: mcc_generated_files/time_service.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files" + @${RM} ${OBJECTDIR}/mcc_generated_files/time_service.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/time_service.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/time_service.o.d" -MT "${OBJECTDIR}/mcc_generated_files/time_service.o.d" -MT ${OBJECTDIR}/mcc_generated_files/time_service.o -o ${OBJECTDIR}/mcc_generated_files/time_service.o mcc_generated_files/time_service.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.o: mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.o mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.c + +${OBJECTDIR}/main.o: main.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}" + @${RM} ${OBJECTDIR}/main.o.d + @${RM} ${OBJECTDIR}/main.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/main.o.d" -MT "${OBJECTDIR}/main.o.d" -MT ${OBJECTDIR}/main.o -o ${OBJECTDIR}/main.o main.c + +else +${OBJECTDIR}/mcc_generated_files/cli/cli.o: mcc_generated_files/cli/cli.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/cli" + @${RM} ${OBJECTDIR}/mcc_generated_files/cli/cli.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/cli/cli.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/cli/cli.o.d" -MT "${OBJECTDIR}/mcc_generated_files/cli/cli.o.d" -MT ${OBJECTDIR}/mcc_generated_files/cli/cli.o -o ${OBJECTDIR}/mcc_generated_files/cli/cli.o mcc_generated_files/cli/cli.c + +${OBJECTDIR}/mcc_generated_files/cloud/crypto_client/crypto_client.o: mcc_generated_files/cloud/crypto_client/crypto_client.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/cloud/crypto_client" + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/crypto_client/crypto_client.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/crypto_client/crypto_client.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/cloud/crypto_client/crypto_client.o.d" -MT "${OBJECTDIR}/mcc_generated_files/cloud/crypto_client/crypto_client.o.d" -MT ${OBJECTDIR}/mcc_generated_files/cloud/crypto_client/crypto_client.o -o ${OBJECTDIR}/mcc_generated_files/cloud/crypto_client/crypto_client.o mcc_generated_files/cloud/crypto_client/crypto_client.c + +${OBJECTDIR}/mcc_generated_files/cloud/cloud_service.o: mcc_generated_files/cloud/cloud_service.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/cloud" + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/cloud_service.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/cloud_service.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/cloud/cloud_service.o.d" -MT "${OBJECTDIR}/mcc_generated_files/cloud/cloud_service.o.d" -MT ${OBJECTDIR}/mcc_generated_files/cloud/cloud_service.o -o ${OBJECTDIR}/mcc_generated_files/cloud/cloud_service.o mcc_generated_files/cloud/cloud_service.c + +${OBJECTDIR}/mcc_generated_files/cloud/wifi_service.o: mcc_generated_files/cloud/wifi_service.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/cloud" + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/wifi_service.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/wifi_service.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/cloud/wifi_service.o.d" -MT "${OBJECTDIR}/mcc_generated_files/cloud/wifi_service.o.d" -MT ${OBJECTDIR}/mcc_generated_files/cloud/wifi_service.o -o ${OBJECTDIR}/mcc_generated_files/cloud/wifi_service.o mcc_generated_files/cloud/wifi_service.c + +${OBJECTDIR}/mcc_generated_files/cloud/mqtt_service.o: mcc_generated_files/cloud/mqtt_service.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/cloud" + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/mqtt_service.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/mqtt_service.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/cloud/mqtt_service.o.d" -MT "${OBJECTDIR}/mcc_generated_files/cloud/mqtt_service.o.d" -MT ${OBJECTDIR}/mcc_generated_files/cloud/mqtt_service.o -o ${OBJECTDIR}/mcc_generated_files/cloud/mqtt_service.o mcc_generated_files/cloud/mqtt_service.c + +${OBJECTDIR}/mcc_generated_files/cloud/aws_cloud_service.o: mcc_generated_files/cloud/aws_cloud_service.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/cloud" + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/aws_cloud_service.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/cloud/aws_cloud_service.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/cloud/aws_cloud_service.o.d" -MT "${OBJECTDIR}/mcc_generated_files/cloud/aws_cloud_service.o.d" -MT ${OBJECTDIR}/mcc_generated_files/cloud/aws_cloud_service.o -o ${OBJECTDIR}/mcc_generated_files/cloud/aws_cloud_service.o mcc_generated_files/cloud/aws_cloud_service.c + +${OBJECTDIR}/mcc_generated_files/credentials_storage/credentials_storage.o: mcc_generated_files/credentials_storage/credentials_storage.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/credentials_storage" + @${RM} ${OBJECTDIR}/mcc_generated_files/credentials_storage/credentials_storage.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/credentials_storage/credentials_storage.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/credentials_storage/credentials_storage.o.d" -MT "${OBJECTDIR}/mcc_generated_files/credentials_storage/credentials_storage.o.d" -MT ${OBJECTDIR}/mcc_generated_files/credentials_storage/credentials_storage.o -o ${OBJECTDIR}/mcc_generated_files/credentials_storage/credentials_storage.o mcc_generated_files/credentials_storage/credentials_storage.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.o: mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.o mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.o: mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.o mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.o: mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.o mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.o: mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.o mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.o: mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.o mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.o: mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.o mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.o: mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.o mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.o: mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.o mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.o: mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.o mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.o: mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.o mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.o: mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.o mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.o: mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.o mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.o: mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.o mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.o: mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.o mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.o: mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.o mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.o: mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.o mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.o: mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.o mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.o: mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.o mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.o: mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.o mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.o: mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.o mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.o: mcc_generated_files/CryptoAuthenticationLibrary/atca_command.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_command.o mcc_generated_files/CryptoAuthenticationLibrary/atca_command.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.o: mcc_generated_files/CryptoAuthenticationLibrary/atca_device.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_device.o mcc_generated_files/CryptoAuthenticationLibrary/atca_device.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.o: mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.o mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.o: mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.o mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.c + +${OBJECTDIR}/mcc_generated_files/drivers/spi_master.o: mcc_generated_files/drivers/spi_master.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/drivers" + @${RM} ${OBJECTDIR}/mcc_generated_files/drivers/spi_master.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/drivers/spi_master.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/drivers/spi_master.o.d" -MT "${OBJECTDIR}/mcc_generated_files/drivers/spi_master.o.d" -MT ${OBJECTDIR}/mcc_generated_files/drivers/spi_master.o -o ${OBJECTDIR}/mcc_generated_files/drivers/spi_master.o mcc_generated_files/drivers/spi_master.c + +${OBJECTDIR}/mcc_generated_files/drivers/timeout.o: mcc_generated_files/drivers/timeout.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/drivers" + @${RM} ${OBJECTDIR}/mcc_generated_files/drivers/timeout.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/drivers/timeout.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/drivers/timeout.o.d" -MT "${OBJECTDIR}/mcc_generated_files/drivers/timeout.o.d" -MT ${OBJECTDIR}/mcc_generated_files/drivers/timeout.o -o ${OBJECTDIR}/mcc_generated_files/drivers/timeout.o mcc_generated_files/drivers/timeout.c + +${OBJECTDIR}/mcc_generated_files/drivers/i2c_simple_master.o: mcc_generated_files/drivers/i2c_simple_master.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/drivers" + @${RM} ${OBJECTDIR}/mcc_generated_files/drivers/i2c_simple_master.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/drivers/i2c_simple_master.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/drivers/i2c_simple_master.o.d" -MT "${OBJECTDIR}/mcc_generated_files/drivers/i2c_simple_master.o.d" -MT ${OBJECTDIR}/mcc_generated_files/drivers/i2c_simple_master.o -o ${OBJECTDIR}/mcc_generated_files/drivers/i2c_simple_master.o mcc_generated_files/drivers/i2c_simple_master.c + +${OBJECTDIR}/mcc_generated_files/drivers/uart.o: mcc_generated_files/drivers/uart.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/drivers" + @${RM} ${OBJECTDIR}/mcc_generated_files/drivers/uart.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/drivers/uart.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/drivers/uart.o.d" -MT "${OBJECTDIR}/mcc_generated_files/drivers/uart.o.d" -MT ${OBJECTDIR}/mcc_generated_files/drivers/uart.o -o ${OBJECTDIR}/mcc_generated_files/drivers/uart.o mcc_generated_files/drivers/uart.c + +${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.o: mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd" + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.o.d" -MT "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.o.d" -MT ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.o -o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.o mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.c + +${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core/mqtt_core.o: mcc_generated_files/mqtt/mqtt_core/mqtt_core.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core" + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core/mqtt_core.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core/mqtt_core.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core/mqtt_core.o.d" -MT "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core/mqtt_core.o.d" -MT ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core/mqtt_core.o -o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_core/mqtt_core.o mcc_generated_files/mqtt/mqtt_core/mqtt_core.c + +${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.o: mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer" + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.o.d" -MT "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.o.d" -MT ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.o -o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.o mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.c + +${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.o: mcc_generated_files/mqtt/mqtt_packetTransfer_interface.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/mqtt" + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.o.d" -MT "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.o.d" -MT ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.o -o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_packetTransfer_interface.o mcc_generated_files/mqtt/mqtt_packetTransfer_interface.c + +${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_winc_adapter.o: mcc_generated_files/mqtt/mqtt_winc_adapter.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/mqtt" + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_winc_adapter.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_winc_adapter.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_winc_adapter.o.d" -MT "${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_winc_adapter.o.d" -MT ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_winc_adapter.o -o ${OBJECTDIR}/mcc_generated_files/mqtt/mqtt_winc_adapter.o mcc_generated_files/mqtt/mqtt_winc_adapter.c + +${OBJECTDIR}/mcc_generated_files/src/pin_manager.o: mcc_generated_files/src/pin_manager.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/src" + @${RM} ${OBJECTDIR}/mcc_generated_files/src/pin_manager.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/src/pin_manager.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/src/pin_manager.o.d" -MT "${OBJECTDIR}/mcc_generated_files/src/pin_manager.o.d" -MT ${OBJECTDIR}/mcc_generated_files/src/pin_manager.o -o ${OBJECTDIR}/mcc_generated_files/src/pin_manager.o mcc_generated_files/src/pin_manager.c + +${OBJECTDIR}/mcc_generated_files/src/cpuint.o: mcc_generated_files/src/cpuint.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/src" + @${RM} ${OBJECTDIR}/mcc_generated_files/src/cpuint.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/src/cpuint.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/src/cpuint.o.d" -MT "${OBJECTDIR}/mcc_generated_files/src/cpuint.o.d" -MT ${OBJECTDIR}/mcc_generated_files/src/cpuint.o -o ${OBJECTDIR}/mcc_generated_files/src/cpuint.o mcc_generated_files/src/cpuint.c + +${OBJECTDIR}/mcc_generated_files/src/spi0.o: mcc_generated_files/src/spi0.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/src" + @${RM} ${OBJECTDIR}/mcc_generated_files/src/spi0.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/src/spi0.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/src/spi0.o.d" -MT "${OBJECTDIR}/mcc_generated_files/src/spi0.o.d" -MT ${OBJECTDIR}/mcc_generated_files/src/spi0.o -o ${OBJECTDIR}/mcc_generated_files/src/spi0.o mcc_generated_files/src/spi0.c + +${OBJECTDIR}/mcc_generated_files/src/rtc.o: mcc_generated_files/src/rtc.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/src" + @${RM} ${OBJECTDIR}/mcc_generated_files/src/rtc.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/src/rtc.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/src/rtc.o.d" -MT "${OBJECTDIR}/mcc_generated_files/src/rtc.o.d" -MT ${OBJECTDIR}/mcc_generated_files/src/rtc.o -o ${OBJECTDIR}/mcc_generated_files/src/rtc.o mcc_generated_files/src/rtc.c + +${OBJECTDIR}/mcc_generated_files/src/twi0_master.o: mcc_generated_files/src/twi0_master.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/src" + @${RM} ${OBJECTDIR}/mcc_generated_files/src/twi0_master.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/src/twi0_master.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/src/twi0_master.o.d" -MT "${OBJECTDIR}/mcc_generated_files/src/twi0_master.o.d" -MT ${OBJECTDIR}/mcc_generated_files/src/twi0_master.o -o ${OBJECTDIR}/mcc_generated_files/src/twi0_master.o mcc_generated_files/src/twi0_master.c + +${OBJECTDIR}/mcc_generated_files/src/adc0.o: mcc_generated_files/src/adc0.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/src" + @${RM} ${OBJECTDIR}/mcc_generated_files/src/adc0.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/src/adc0.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/src/adc0.o.d" -MT "${OBJECTDIR}/mcc_generated_files/src/adc0.o.d" -MT ${OBJECTDIR}/mcc_generated_files/src/adc0.o -o ${OBJECTDIR}/mcc_generated_files/src/adc0.o mcc_generated_files/src/adc0.c + +${OBJECTDIR}/mcc_generated_files/src/usart2.o: mcc_generated_files/src/usart2.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/src" + @${RM} ${OBJECTDIR}/mcc_generated_files/src/usart2.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/src/usart2.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/src/usart2.o.d" -MT "${OBJECTDIR}/mcc_generated_files/src/usart2.o.d" -MT ${OBJECTDIR}/mcc_generated_files/src/usart2.o -o ${OBJECTDIR}/mcc_generated_files/src/usart2.o mcc_generated_files/src/usart2.c + +${OBJECTDIR}/mcc_generated_files/winc/driver/winc_spi.o: mcc_generated_files/winc/driver/winc_spi.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/driver" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_spi.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_spi.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_spi.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_spi.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_spi.o -o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_spi.o mcc_generated_files/winc/driver/winc_spi.c + +${OBJECTDIR}/mcc_generated_files/winc/driver/winc_adapter.o: mcc_generated_files/winc/driver/winc_adapter.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/driver" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_adapter.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_adapter.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_adapter.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_adapter.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_adapter.o -o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_adapter.o mcc_generated_files/winc/driver/winc_adapter.c + +${OBJECTDIR}/mcc_generated_files/winc/driver/winc_hif.o: mcc_generated_files/winc/driver/winc_hif.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/driver" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_hif.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_hif.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_hif.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_hif.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_hif.o -o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_hif.o mcc_generated_files/winc/driver/winc_hif.c + +${OBJECTDIR}/mcc_generated_files/winc/driver/winc_asic.o: mcc_generated_files/winc/driver/winc_asic.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/driver" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_asic.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_asic.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_asic.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_asic.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_asic.o -o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_asic.o mcc_generated_files/winc/driver/winc_asic.c + +${OBJECTDIR}/mcc_generated_files/winc/driver/winc_drv.o: mcc_generated_files/winc/driver/winc_drv.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/driver" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_drv.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_drv.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_drv.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/driver/winc_drv.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_drv.o -o ${OBJECTDIR}/mcc_generated_files/winc/driver/winc_drv.o mcc_generated_files/winc/driver/winc_drv.c + +${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ssl.o: mcc_generated_files/winc/m2m/m2m_ssl.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/m2m" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ssl.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ssl.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ssl.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ssl.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ssl.o -o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ssl.o mcc_generated_files/winc/m2m/m2m_ssl.c + +${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_wifi.o: mcc_generated_files/winc/m2m/m2m_wifi.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/m2m" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_wifi.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_wifi.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_wifi.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_wifi.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_wifi.o -o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_wifi.o mcc_generated_files/winc/m2m/m2m_wifi.c + +${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_periph.o: mcc_generated_files/winc/m2m/m2m_periph.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/m2m" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_periph.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_periph.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_periph.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_periph.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_periph.o -o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_periph.o mcc_generated_files/winc/m2m/m2m_periph.c + +${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ota.o: mcc_generated_files/winc/m2m/m2m_ota.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/m2m" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ota.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ota.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ota.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ota.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ota.o -o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_ota.o mcc_generated_files/winc/m2m/m2m_ota.c + +${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_fwinfo.o: mcc_generated_files/winc/m2m/m2m_fwinfo.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/m2m" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_fwinfo.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_fwinfo.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_fwinfo.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_fwinfo.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_fwinfo.o -o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_fwinfo.o mcc_generated_files/winc/m2m/m2m_fwinfo.c + +${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_crypto.o: mcc_generated_files/winc/m2m/m2m_crypto.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/m2m" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_crypto.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_crypto.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_crypto.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_crypto.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_crypto.o -o ${OBJECTDIR}/mcc_generated_files/winc/m2m/m2m_crypto.o mcc_generated_files/winc/m2m/m2m_crypto.c + +${OBJECTDIR}/mcc_generated_files/winc/socket/socket.o: mcc_generated_files/winc/socket/socket.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/socket" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/socket/socket.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/socket/socket.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/socket/socket.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/socket/socket.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/socket/socket.o -o ${OBJECTDIR}/mcc_generated_files/winc/socket/socket.o mcc_generated_files/winc/socket/socket.c + +${OBJECTDIR}/mcc_generated_files/winc/spi_flash/flexible_flash.o: mcc_generated_files/winc/spi_flash/flexible_flash.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/spi_flash" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/flexible_flash.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/flexible_flash.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/spi_flash/flexible_flash.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/spi_flash/flexible_flash.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/flexible_flash.o -o ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/flexible_flash.o mcc_generated_files/winc/spi_flash/flexible_flash.c + +${OBJECTDIR}/mcc_generated_files/winc/spi_flash/spi_flash.o: mcc_generated_files/winc/spi_flash/spi_flash.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/winc/spi_flash" + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/spi_flash.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/spi_flash.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/winc/spi_flash/spi_flash.o.d" -MT "${OBJECTDIR}/mcc_generated_files/winc/spi_flash/spi_flash.o.d" -MT ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/spi_flash.o -o ${OBJECTDIR}/mcc_generated_files/winc/spi_flash/spi_flash.o mcc_generated_files/winc/spi_flash/spi_flash.c + +${OBJECTDIR}/mcc_generated_files/mcc.o: mcc_generated_files/mcc.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files" + @${RM} ${OBJECTDIR}/mcc_generated_files/mcc.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/mcc.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/mcc.o.d" -MT "${OBJECTDIR}/mcc_generated_files/mcc.o.d" -MT ${OBJECTDIR}/mcc_generated_files/mcc.o -o ${OBJECTDIR}/mcc_generated_files/mcc.o mcc_generated_files/mcc.c + +${OBJECTDIR}/mcc_generated_files/delay.o: mcc_generated_files/delay.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files" + @${RM} ${OBJECTDIR}/mcc_generated_files/delay.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/delay.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/delay.o.d" -MT "${OBJECTDIR}/mcc_generated_files/delay.o.d" -MT ${OBJECTDIR}/mcc_generated_files/delay.o -o ${OBJECTDIR}/mcc_generated_files/delay.o mcc_generated_files/delay.c + +${OBJECTDIR}/mcc_generated_files/device_config.o: mcc_generated_files/device_config.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files" + @${RM} ${OBJECTDIR}/mcc_generated_files/device_config.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/device_config.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/device_config.o.d" -MT "${OBJECTDIR}/mcc_generated_files/device_config.o.d" -MT ${OBJECTDIR}/mcc_generated_files/device_config.o -o ${OBJECTDIR}/mcc_generated_files/device_config.o mcc_generated_files/device_config.c + +${OBJECTDIR}/mcc_generated_files/application_manager.o: mcc_generated_files/application_manager.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files" + @${RM} ${OBJECTDIR}/mcc_generated_files/application_manager.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/application_manager.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/application_manager.o.d" -MT "${OBJECTDIR}/mcc_generated_files/application_manager.o.d" -MT ${OBJECTDIR}/mcc_generated_files/application_manager.o -o ${OBJECTDIR}/mcc_generated_files/application_manager.o mcc_generated_files/application_manager.c + +${OBJECTDIR}/mcc_generated_files/debug_print.o: mcc_generated_files/debug_print.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files" + @${RM} ${OBJECTDIR}/mcc_generated_files/debug_print.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/debug_print.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/debug_print.o.d" -MT "${OBJECTDIR}/mcc_generated_files/debug_print.o.d" -MT ${OBJECTDIR}/mcc_generated_files/debug_print.o -o ${OBJECTDIR}/mcc_generated_files/debug_print.o mcc_generated_files/debug_print.c + +${OBJECTDIR}/mcc_generated_files/led.o: mcc_generated_files/led.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files" + @${RM} ${OBJECTDIR}/mcc_generated_files/led.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/led.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/led.o.d" -MT "${OBJECTDIR}/mcc_generated_files/led.o.d" -MT ${OBJECTDIR}/mcc_generated_files/led.o -o ${OBJECTDIR}/mcc_generated_files/led.o mcc_generated_files/led.c + +${OBJECTDIR}/mcc_generated_files/sensors_handling.o: mcc_generated_files/sensors_handling.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files" + @${RM} ${OBJECTDIR}/mcc_generated_files/sensors_handling.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/sensors_handling.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/sensors_handling.o.d" -MT "${OBJECTDIR}/mcc_generated_files/sensors_handling.o.d" -MT ${OBJECTDIR}/mcc_generated_files/sensors_handling.o -o ${OBJECTDIR}/mcc_generated_files/sensors_handling.o mcc_generated_files/sensors_handling.c + +${OBJECTDIR}/mcc_generated_files/time_service.o: mcc_generated_files/time_service.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files" + @${RM} ${OBJECTDIR}/mcc_generated_files/time_service.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/time_service.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/time_service.o.d" -MT "${OBJECTDIR}/mcc_generated_files/time_service.o.d" -MT ${OBJECTDIR}/mcc_generated_files/time_service.o -o ${OBJECTDIR}/mcc_generated_files/time_service.o mcc_generated_files/time_service.c + +${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.o: mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary" + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.o.d" -MT "${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.o.d" -MT ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.o -o ${OBJECTDIR}/mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.o mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.c + +${OBJECTDIR}/main.o: main.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}" + @${RM} ${OBJECTDIR}/main.o.d + @${RM} ${OBJECTDIR}/main.o + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 -Wno-pragmas -MD -MP -MF "${OBJECTDIR}/main.o.d" -MT "${OBJECTDIR}/main.o.d" -MT ${OBJECTDIR}/main.o -o ${OBJECTDIR}/main.o main.c + +endif + +# ------------------------------------------------------------------------------------ +# Rules for buildStep: assemble +ifeq ($(TYPE_IMAGE), DEBUG_RUN) +else +endif + +# ------------------------------------------------------------------------------------ +# Rules for buildStep: assembleWithPreprocess +ifeq ($(TYPE_IMAGE), DEBUG_RUN) +${OBJECTDIR}/mcc_generated_files/src/protected_io.o: mcc_generated_files/src/protected_io.S nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/src" + @${RM} ${OBJECTDIR}/mcc_generated_files/src/protected_io.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/src/protected_io.o + ${MP_CC} -c $(MP_EXTRA_AS_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x assembler-with-cpp -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) -Wno-pragmas -gdwarf-3 -Wa,--defsym=__MPLAB_BUILD=1,--defsym=__MPLAB_DEBUG=1,--defsym=__DEBUG=1 -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/src/protected_io.o.d" -MT "${OBJECTDIR}/mcc_generated_files/src/protected_io.o.d" -MT ${OBJECTDIR}/mcc_generated_files/src/protected_io.o -o ${OBJECTDIR}/mcc_generated_files/src/protected_io.o mcc_generated_files/src/protected_io.S + +else +${OBJECTDIR}/mcc_generated_files/src/protected_io.o: mcc_generated_files/src/protected_io.S nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/mcc_generated_files/src" + @${RM} ${OBJECTDIR}/mcc_generated_files/src/protected_io.o.d + @${RM} ${OBJECTDIR}/mcc_generated_files/src/protected_io.o + ${MP_CC} -c $(MP_EXTRA_AS_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -x assembler-with-cpp -D__$(MP_PROCESSOR_OPTION)__ -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -DXPRJ_AWS_IOT=$(CND_CONF) -Wno-pragmas -gdwarf-3 -Wa,--defsym=__MPLAB_BUILD=1 -MD -MP -MF "${OBJECTDIR}/mcc_generated_files/src/protected_io.o.d" -MT "${OBJECTDIR}/mcc_generated_files/src/protected_io.o.d" -MT ${OBJECTDIR}/mcc_generated_files/src/protected_io.o -o ${OBJECTDIR}/mcc_generated_files/src/protected_io.o mcc_generated_files/src/protected_io.S + +endif + +# ------------------------------------------------------------------------------------ +# Rules for buildStep: link +ifeq ($(TYPE_IMAGE), DEBUG_RUN) +dist/${CND_CONF}/${IMAGE_TYPE}/AVRIoT.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE} + ${MP_CC} $(MP_EXTRA_LD_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -Wl,-Map=dist/${CND_CONF}/${IMAGE_TYPE}/AVRIoT.X.${IMAGE_TYPE}.map -D__DEBUG=1 -DXPRJ_AWS_IOT=$(CND_CONF) -Wl,--defsym=__MPLAB_BUILD=1 -mdfp=${DFP_DIR} -gdwarf-2 -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -Wno-pragmas -gdwarf-3 $(COMPARISON_BUILD) -Wl,--memorysummary,dist/${CND_CONF}/${IMAGE_TYPE}/memoryfile.xml -o dist/${CND_CONF}/${IMAGE_TYPE}/AVRIoT.X.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} -o dist/${CND_CONF}/${IMAGE_TYPE}/AVRIoT.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} -Wl,--start-group -Wl,-lm -Wl,--end-group -Wl,--defsym=__MPLAB_DEBUG=1,--defsym=__DEBUG=1 + @${RM} dist/${CND_CONF}/${IMAGE_TYPE}/AVRIoT.X.${IMAGE_TYPE}.hex + +else +dist/${CND_CONF}/${IMAGE_TYPE}/AVRIoT.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE} + ${MP_CC} $(MP_EXTRA_LD_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -Wl,-Map=dist/${CND_CONF}/${IMAGE_TYPE}/AVRIoT.X.${IMAGE_TYPE}.map -DXPRJ_AWS_IOT=$(CND_CONF) -Wl,--defsym=__MPLAB_BUILD=1 -mdfp=${DFP_DIR} -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -I"mcc_generated_files/mqtt" -I"mcc_generated_files/winc" -I"mcc_generated_files/drivers" -I"mcc_generated_files/CryptoAuthenticationLibrary" -I"mcc_generated_files" -Wall -Wno-pragmas -gdwarf-3 $(COMPARISON_BUILD) -Wl,--memorysummary,dist/${CND_CONF}/${IMAGE_TYPE}/memoryfile.xml -o dist/${CND_CONF}/${IMAGE_TYPE}/AVRIoT.X.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} -o dist/${CND_CONF}/${IMAGE_TYPE}/AVRIoT.X.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} -Wl,--start-group -Wl,-lm -Wl,--end-group + ${MP_CC_DIR}/avr-objcopy -O ihex "dist/${CND_CONF}/${IMAGE_TYPE}/AVRIoT.X.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX}" "dist/${CND_CONF}/${IMAGE_TYPE}/AVRIoT.X.${IMAGE_TYPE}.hex" +endif + + +# Subprojects +.build-subprojects: + + +# Subprojects +.clean-subprojects: + +# Clean Targets +.clean-conf: ${CLEAN_SUBPROJECTS} + ${RM} -r build/AWS_IOT + ${RM} -r dist/AWS_IOT diff --git a/AVRIoT.X/nbproject/Makefile-genesis.properties b/AVRIoT.X/nbproject/Makefile-genesis.properties new file mode 100644 index 0000000..a935be1 --- /dev/null +++ b/AVRIoT.X/nbproject/Makefile-genesis.properties @@ -0,0 +1,10 @@ +# +#Wed Mar 04 19:24:00 UTC 2020 +AWS_IOT.Pack.dfplocation=/opt/microchip/mplabx/v5.30/packs/Microchip/ATmega_DFP/2.0.12 +AWS_IOT.languagetoolchain.dir=/opt/microchip/xc8/v2.10/bin +AWS_IOT.com-microchip-mplab-nbide-toolchainXC8-XC8LanguageToolchain.md5=f87389d82b4b299d292110931953ebdc +configurations-xml=876dc99f951ba1c6a43262976fad320e +com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=7cd2eead2ea6964989cbf02efe721a76 +host.platform=linux +conf.ids=AWS_IOT +AWS_IOT.languagetoolchain.version=2.10 diff --git a/AVRIoT.X/nbproject/Makefile-impl.mk b/AVRIoT.X/nbproject/Makefile-impl.mk new file mode 100644 index 0000000..48056d4 --- /dev/null +++ b/AVRIoT.X/nbproject/Makefile-impl.mk @@ -0,0 +1,69 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a pre- and a post- target defined where you can add customization code. +# +# This makefile implements macros and targets common to all configurations. +# +# NOCDDL + + +# Building and Cleaning subprojects are done by default, but can be controlled with the SUB +# macro. If SUB=no, subprojects will not be built or cleaned. The following macro +# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf +# and .clean-reqprojects-conf unless SUB has the value 'no' +SUB_no=NO +SUBPROJECTS=${SUB_${SUB}} +BUILD_SUBPROJECTS_=.build-subprojects +BUILD_SUBPROJECTS_NO= +BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}} +CLEAN_SUBPROJECTS_=.clean-subprojects +CLEAN_SUBPROJECTS_NO= +CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}} + + +# Project Name +PROJECTNAME=AVRIoT.X + +# Active Configuration +DEFAULTCONF=AWS_IOT +CONF=${DEFAULTCONF} + +# All Configurations +ALLCONFS=AWS_IOT + + +# build +.build-impl: .build-pre + ${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-conf + + +# clean +.clean-impl: .clean-pre + ${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .clean-conf + +# clobber +.clobber-impl: .clobber-pre .depcheck-impl + ${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=AWS_IOT clean + + + +# all +.all-impl: .all-pre .depcheck-impl + ${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=AWS_IOT build + + + +# dependency checking support +.depcheck-impl: +# @echo "# This code depends on make tool being used" >.dep.inc +# @if [ -n "${MAKE_VERSION}" ]; then \ +# echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \ +# echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \ +# echo "include \$${DEPFILES}" >>.dep.inc; \ +# echo "endif" >>.dep.inc; \ +# else \ +# echo ".KEEP_STATE:" >>.dep.inc; \ +# echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \ +# fi diff --git a/AVRIoT.X/nbproject/Makefile-local-AWS_IOT.mk b/AVRIoT.X/nbproject/Makefile-local-AWS_IOT.mk new file mode 100644 index 0000000..658896f --- /dev/null +++ b/AVRIoT.X/nbproject/Makefile-local-AWS_IOT.mk @@ -0,0 +1,37 @@ +# +# Generated Makefile - do not edit! +# +# +# This file contains information about the location of compilers and other tools. +# If you commmit this file into your revision control server, you will be able to +# to checkout the project and build it from the command line with make. However, +# if more than one person works on the same project, then this file might show +# conflicts since different users are bound to have compilers in different places. +# In that case you might choose to not commit this file and let MPLAB X recreate this file +# for each user. The disadvantage of not commiting this file is that you must run MPLAB X at +# least once so the file gets created and the project can be built. Finally, you can also +# avoid using this file at all if you are only building from the command line with make. +# You can invoke make with the values of the macros: +# $ makeMP_CC="/opt/microchip/mplabc30/v3.30c/bin/pic30-gcc" ... +# +PATH_TO_IDE_BIN=/opt/microchip/mplabx/v5.30/mplab_platform/platform/../mplab_ide/modules/../../bin/ +# Adding MPLAB X bin directory to path. +PATH:=/opt/microchip/mplabx/v5.30/mplab_platform/platform/../mplab_ide/modules/../../bin/:$(PATH) +# Path to java used to run MPLAB X when this makefile was created +MP_JAVA_PATH="/opt/microchip/mplabx/v5.30/sys/java/jre1.8.0_181/bin/" +OS_CURRENT="$(shell uname -s)" +MP_CC="/opt/microchip/xc8/v2.10/bin/xc8-cc" +# MP_CPPC is not defined +# MP_BC is not defined +MP_AS="/opt/microchip/xc8/v2.10/bin/xc8-cc" +MP_LD="/opt/microchip/xc8/v2.10/bin/xc8-cc" +MP_AR="/opt/microchip/xc8/v2.10/bin/xc8-ar" +DEP_GEN=${MP_JAVA_PATH}java -jar "/opt/microchip/mplabx/v5.30/mplab_platform/platform/../mplab_ide/modules/../../bin/extractobjectdependencies.jar" +MP_CC_DIR="/opt/microchip/xc8/v2.10/bin" +# MP_CPPC_DIR is not defined +# MP_BC_DIR is not defined +MP_AS_DIR="/opt/microchip/xc8/v2.10/bin" +MP_LD_DIR="/opt/microchip/xc8/v2.10/bin" +MP_AR_DIR="/opt/microchip/xc8/v2.10/bin" +# MP_BC_DIR is not defined +DFP_DIR="/opt/microchip/mplabx/v5.30/packs/Microchip/ATmega_DFP/2.0.12" diff --git a/AVRIoT.X/nbproject/Makefile-variables.mk b/AVRIoT.X/nbproject/Makefile-variables.mk new file mode 100644 index 0000000..c02af33 --- /dev/null +++ b/AVRIoT.X/nbproject/Makefile-variables.mk @@ -0,0 +1,13 @@ +# +# Generated - do not edit! +# +# NOCDDL +# +CND_BASEDIR=`pwd` +# AWS_IOT configuration +CND_ARTIFACT_DIR_AWS_IOT=dist/AWS_IOT/production +CND_ARTIFACT_NAME_AWS_IOT=AVRIoT.X.production.hex +CND_ARTIFACT_PATH_AWS_IOT=dist/AWS_IOT/production/AVRIoT.X.production.hex +CND_PACKAGE_DIR_AWS_IOT=${CND_DISTDIR}/AWS_IOT/package +CND_PACKAGE_NAME_AWS_IOT=avriot.x.tar +CND_PACKAGE_PATH_AWS_IOT=${CND_DISTDIR}/AWS_IOT/package/avriot.x.tar diff --git a/AVRIoT.X/nbproject/Package-AWS_IOT.bash b/AVRIoT.X/nbproject/Package-AWS_IOT.bash new file mode 100644 index 0000000..6570cc4 --- /dev/null +++ b/AVRIoT.X/nbproject/Package-AWS_IOT.bash @@ -0,0 +1,73 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +CND_CONF=AWS_IOT +CND_DISTDIR=dist +TMPDIR=build/${CND_CONF}/${IMAGE_TYPE}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=dist/${CND_CONF}/${IMAGE_TYPE}/AVRIoT.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX} +OUTPUT_BASENAME=AVRIoT.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX} +PACKAGE_TOP_DIR=avriot.x/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p ${CND_DISTDIR}/${CND_CONF}/package +rm -rf ${TMPDIR} +mkdir -p ${TMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory ${TMPDIR}/avriot.x/bin +copyFileToTmpDir "${OUTPUT_PATH}" "${TMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 + + +# Generate tar file +cd "${TOP}" +rm -f ${CND_DISTDIR}/${CND_CONF}/package/avriot.x.tar +cd ${TMPDIR} +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/package/avriot.x.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${TMPDIR} diff --git a/AVRIoT.X/nbproject/configurations.xml b/AVRIoT.X/nbproject/configurations.xml new file mode 100644 index 0000000..ac958da --- /dev/null +++ b/AVRIoT.X/nbproject/configurations.xml @@ -0,0 +1,541 @@ + + + + + + + mcc_generated_files/cli/cli.h + + + + mcc_generated_files/cloud/crypto_client/crypto_client.h + + mcc_generated_files/cloud/cloud_service.h + mcc_generated_files/cloud/wifi_service.h + mcc_generated_files/cloud/mqtt_service.h + mcc_generated_files/cloud/cloud_interface.h + + + mcc_generated_files/config/clock_config.h + mcc_generated_files/config/conf_winc.h + mcc_generated_files/config/IoT_Sensor_Node_config.h + mcc_generated_files/config/cloud_config.h + mcc_generated_files/config/mqtt_config.h + + + mcc_generated_files/credentials_storage/credentials_storage.h + + + + mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert.h + mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.h + mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.h + mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.h + mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.h + mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.h + mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.h + mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.h + + + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.h + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.h + + + + mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.h + mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.h + + mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw.h + mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.h + mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.h + mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.h + mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.h + + + mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.h + mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.h + mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_start_config.h + mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_start_iface.h + + + mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.h + + + mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.h + + mcc_generated_files/CryptoAuthenticationLibrary/atca_bool.h + mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.h + mcc_generated_files/CryptoAuthenticationLibrary/atca_command.h + mcc_generated_files/CryptoAuthenticationLibrary/atca_compiler.h + mcc_generated_files/CryptoAuthenticationLibrary/atca_device.h + mcc_generated_files/CryptoAuthenticationLibrary/atca_devtypes.h + mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.h + mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.h + mcc_generated_files/CryptoAuthenticationLibrary/atca_status.h + + + mcc_generated_files/drivers/spi_master.h + mcc_generated_files/drivers/timeout.h + mcc_generated_files/drivers/i2c_simple_master.h + mcc_generated_files/drivers/uart.h + + + mcc_generated_files/include/cpuint.h + mcc_generated_files/include/port.h + mcc_generated_files/include/rtc.h + mcc_generated_files/include/pin_manager.h + mcc_generated_files/include/rstctrl.h + mcc_generated_files/include/spi0.h + mcc_generated_files/include/protected_io.h + mcc_generated_files/include/ccp.h + mcc_generated_files/include/twi0_master.h + mcc_generated_files/include/usart2.h + mcc_generated_files/include/adc0.h + + + + mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.h + + + mcc_generated_files/mqtt/mqtt_core/mqtt_core.h + + + mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.h + + mcc_generated_files/mqtt/mqtt_packetTransfer_interface.h + mcc_generated_files/mqtt/mqtt_winc_adapter.h + + + + mcc_generated_files/utils/assembler/iar.h + mcc_generated_files/utils/assembler/gas.h + + mcc_generated_files/utils/compiler.h + mcc_generated_files/utils/utils.h + mcc_generated_files/utils/interrupt_avr8.h + mcc_generated_files/utils/utils_assert.h + mcc_generated_files/utils/assembler.h + mcc_generated_files/utils/atomic.h + + + + mcc_generated_files/winc/common/winc_defines.h + mcc_generated_files/winc/common/winc_registers.h + mcc_generated_files/winc/common/ecc_types.h + mcc_generated_files/winc/common/winc_debug.h + mcc_generated_files/winc/common/winc_1500_3A0_registers.h + + + mcc_generated_files/winc/driver/winc_spi.h + mcc_generated_files/winc/driver/winc_adapter.h + mcc_generated_files/winc/driver/winc_drv.h + mcc_generated_files/winc/driver/winc_asic.h + mcc_generated_files/winc/driver/winc_hif.h + + + mcc_generated_files/winc/include/conf_winc_defaults.h + mcc_generated_files/winc/include/winc_legacy.h + mcc_generated_files/winc/include/winc.h + + + mcc_generated_files/winc/m2m/m2m_wifi.h + mcc_generated_files/winc/m2m/m2m_ssl.h + mcc_generated_files/winc/m2m/m2m_periph.h + mcc_generated_files/winc/m2m/m2m_ota.h + mcc_generated_files/winc/m2m/m2m_socket_host_if.h + mcc_generated_files/winc/m2m/m2m_fwinfo.h + mcc_generated_files/winc/m2m/m2m_crypto.h + mcc_generated_files/winc/m2m/m2m_types.h + + + mcc_generated_files/winc/socket/socket.h + + + mcc_generated_files/winc/spi_flash/flexible_flash.h + mcc_generated_files/winc/spi_flash/spi_flash_map.h + mcc_generated_files/winc/spi_flash/spi_flash.h + + + mcc_generated_files/delay.h + mcc_generated_files/mcc.h + mcc_generated_files/application_manager.h + mcc_generated_files/debug_print.h + mcc_generated_files/led.h + mcc_generated_files/sensors_handling.h + mcc_generated_files/time_service.h + mcc_generated_files/banner.h + mcc_generated_files/CryptoAuthenticationLibrary/cryptoauthlib.h + mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.h + mcc_generated_files/CryptoAuthenticationLibrary/cryptoauthlib_config.h + + + + + + + + + mcc_generated_files/docs/mqtt_documentation/Microchip MQTT Client Library.docx + mcc_generated_files/docs/mqtt_documentation/MQTT Readme.md + + + + + + + + mcc_generated_files/cli/cli.c + + + + mcc_generated_files/cloud/crypto_client/crypto_client.c + + mcc_generated_files/cloud/cloud_service.c + mcc_generated_files/cloud/wifi_service.c + mcc_generated_files/cloud/mqtt_service.c + mcc_generated_files/cloud/aws_cloud_service.c + + + mcc_generated_files/credentials_storage/credentials_storage.c + + + + mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_client.c + mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_date.c + mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_def.c + mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_der.c + mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_hw.c + mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_host_sw.c + mcc_generated_files/CryptoAuthenticationLibrary/atcacert/atcacert_pem.c + + + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_checkmac.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_counter.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_derivekey.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_ecdh.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_gendig.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_genkey.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_hmac.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_info.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_kdf.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_lock.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_mac.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_nonce.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_privwrite.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_random.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_read.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_secureboot.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_selftest.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sha.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_sign.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_updateextra.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_verify.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_basic_write.c + mcc_generated_files/CryptoAuthenticationLibrary/basic/atca_helpers.c + + + + mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha1_routines.c + mcc_generated_files/CryptoAuthenticationLibrary/crypto/hashes/sha2_routines.c + + mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_ecdsa.c + mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_rand.c + mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha1.c + mcc_generated_files/CryptoAuthenticationLibrary/crypto/atca_crypto_sw_sha2.c + + + mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_hal.c + mcc_generated_files/CryptoAuthenticationLibrary/hal/atca_i2c_hal.c + mcc_generated_files/CryptoAuthenticationLibrary/hal/hal_i2c_timer.c + + + mcc_generated_files/CryptoAuthenticationLibrary/host/atca_host.c + + + mcc_generated_files/CryptoAuthenticationLibrary/jwt/atca_jwt.c + + mcc_generated_files/CryptoAuthenticationLibrary/atca_cfgs.c + mcc_generated_files/CryptoAuthenticationLibrary/atca_command.c + mcc_generated_files/CryptoAuthenticationLibrary/atca_device.c + mcc_generated_files/CryptoAuthenticationLibrary/atca_execution.c + mcc_generated_files/CryptoAuthenticationLibrary/atca_iface.c + + + mcc_generated_files/drivers/spi_master.c + mcc_generated_files/drivers/timeout.c + mcc_generated_files/drivers/i2c_simple_master.c + mcc_generated_files/drivers/uart.c + + + + mcc_generated_files/mqtt/mqtt_comm_bsd/mqtt_comm_layer.c + + + mcc_generated_files/mqtt/mqtt_core/mqtt_core.c + + + mcc_generated_files/mqtt/mqtt_exchange_buffer/mqtt_exchange_buffer.c + + mcc_generated_files/mqtt/mqtt_packetTransfer_interface.c + mcc_generated_files/mqtt/mqtt_winc_adapter.c + + + mcc_generated_files/src/pin_manager.c + mcc_generated_files/src/cpuint.c + mcc_generated_files/src/spi0.c + mcc_generated_files/src/protected_io.S + mcc_generated_files/src/rtc.c + mcc_generated_files/src/twi0_master.c + mcc_generated_files/src/adc0.c + mcc_generated_files/src/usart2.c + + + + mcc_generated_files/winc/driver/winc_spi.c + mcc_generated_files/winc/driver/winc_adapter.c + mcc_generated_files/winc/driver/winc_hif.c + mcc_generated_files/winc/driver/winc_asic.c + mcc_generated_files/winc/driver/winc_drv.c + + + mcc_generated_files/winc/m2m/m2m_ssl.c + mcc_generated_files/winc/m2m/m2m_wifi.c + mcc_generated_files/winc/m2m/m2m_periph.c + mcc_generated_files/winc/m2m/m2m_ota.c + mcc_generated_files/winc/m2m/m2m_fwinfo.c + mcc_generated_files/winc/m2m/m2m_crypto.c + + + mcc_generated_files/winc/socket/socket.c + + + mcc_generated_files/winc/spi_flash/flexible_flash.c + mcc_generated_files/winc/spi_flash/spi_flash.c + + + mcc_generated_files/mcc.c + mcc_generated_files/delay.c + mcc_generated_files/device_config.c + mcc_generated_files/application_manager.c + mcc_generated_files/debug_print.c + mcc_generated_files/led.c + mcc_generated_files/sensors_handling.c + mcc_generated_files/time_service.c + mcc_generated_files/CryptoAuthenticationLibrary/CryptoAuth_init.c + + main.c + + + Makefile + MyConfig.mc3 + + + + mcc_generated_files + + Makefile + + + + localhost + ATmega4808 + + + nEdbgTool + XC8 + 2.10 + 3 + + + + + + + + + + + + + false + false + + + + + + + false + + false + + false + false + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AVRIoT.X/nbproject/private/configurations.xml b/AVRIoT.X/nbproject/private/configurations.xml new file mode 100644 index 0000000..2e7bf6b --- /dev/null +++ b/AVRIoT.X/nbproject/private/configurations.xml @@ -0,0 +1,25 @@ + + + Makefile + 0 + + + + + + place holder 1 + place holder 2 + + + + + true + 0 + 0 + 0 + + + + + + diff --git a/AVRIoT.X/nbproject/project.xml b/AVRIoT.X/nbproject/project.xml new file mode 100644 index 0000000..44b912d --- /dev/null +++ b/AVRIoT.X/nbproject/project.xml @@ -0,0 +1,29 @@ + + + com.microchip.mplab.nbide.embedded.makeproject + + + AVRIoT + 37cf9aed-daea-4bca-9362-5023c4210f1a + 0 + c + + h + + ISO-8859-1 + + + mcc_generated_files + + + + AWS_IOT + 2 + + + + false + + + + diff --git a/README.md b/README.md index e69de29..1a0be70 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,349 @@ +# Getting Started Guide: Microchip AVR-IoT WA (Wireless for Amazon Web Services) Application + +Devices: \| **ATmega4808(MCU)** \| **WINC1510(Wi-Fi®)** \| **ECC608(CryptoAuthLib)** \| + +--- + +![Board](images/boardAVR.png) + +--- + +## Requirements + ++ **MPLAB® X Integrated Development Environment (IDE) v5.25 or later**: +MPLAB® X IDE is a computer software program based on the open source NetBeans IDE from Oracle. It is used to develop applications for Microchip microcontrollers and digital signal controllers. It runs on Windows®, Mac OS® and Linux®. +For the latest version, please refer to: [MPLAB-X](https://www.microchip.com/mplab/mplab-x-ide) + ++ **MPLAB® XC8 Compiler v2.05 or later**: +MPLAB® XC compilers support all of Microchip’s PIC, AVR and dsPIC devices where the code is written in the C programming language. XC8 is the recommended compiler for 8-bit PIC MCUs and is also supported by some AVR devices. In this lab, as well as with the succeeding labs, you will be using MPLAB® XC8 for an AVR MCU. +For the latest version, please refer to: [XC-Compiler](https://www.microchip.com/mplab/compilers) + ++ **Compiler Optimization** +Compilation of source code can be achieved using supporting MPLAB® XC compiler: **XC8** or **AVR 8-bit GNU Toolchain**. + * XC8 Compiler v2.05 or later: Supported by optimization **level 1, 2 (free)** and **level s (pro)** + * AVR GNU Toolchain v3.62: Supported by optimization **level 1, 2 (free)** and **level s (pro)**. + +MPLAB® X IDE XC8 support all 8-bit PIC® and AVR® microcontrollers (MCUs). This is a internally developed compiler which is specially designed to maximize features aviable to the PIC® and AVR® microcontrollers (MCUs). + +The Atmel AVR 8-bit GNU Toolchain (3.6.1.1750) supports all AVR 8-bit devices. The AVR 8-bit Toolchain is based on the free and open-source GCC compiler. The toolchain includes compiler, assembler, linker and binutils (GCC and Binutils), Standard C library (AVR-libc) and GNU Debugger (GDB). + ++ **AVR IoT Development Board**: +The AVR-IoT development board combines a powerful 8-bit ATmega4808 MCU, an ATECC608A CryptoAuthentication™ secure element IC and the fully certified ATWINC1510 Wi-Fi® network controller - which provides the most simple and effective way to connect your embedded application to a cloud platform. The board also includes an on-board debugger and requires no external hardware to program and debug the MCU. + +--- + +## Application Scope +The AVR-IoT development board has been created with the intention of demostrating a one source solution for evaluation of existing cloud provider solutions. +This example end-device leverages the catalog of devices, and libraries provided through Microchip's extensive product line to showcase a basic Internet of Things product connection. Data exchange between server and in field device is implemented using on board sensors for temperature, and light value observations. Behavior actions are demonstrated through visual indication of the 'Data' LED as controlled through the Web based APIs. + +General Out-Of-Box operation is as described below: +1) Use the On-Board WINC1510 WiFi module to establish local WiFi connection to Router/Switch or Network source. +2) The WINC1510 through use of the ECC608 Cyrpo establishes a Secure (TLS) Socket Connection with select Cloud Provider using a TCP connection. The Blue 'WiFi' LED is used to indicate this status. +3) Using the Microchip Software Library for the Message-Queuing-Telemetry-Transport (MQTT) standard format; data is exchanged between client (end-device) and broker (cloud). The Green 'Connect' LED is used to indicate this status. +4) Sensor Data is sent as Telemetry Data between device and broker at a near periodic rate of (1) Second. The Yellow 'Data' LED is used to indicate this status. +5) Capture of Data sent from Broker to Device can be observed through a Serial terminal when USB-Micro is connected to development board. +6) Behavior variation can be observed on the 'Data' LED when triggered through the web based API, and sent through the broker to end device using MQTT protocol transported through the TCP connection securely established using the ECC608 Crypto device. +7) The Push button has no effect outside of variation of start-up operation; refer to User Guide for additional information regarding Soft-AP operation. + +* The Red 'Data' LED remaining on may indicate a hardware fault issue with the development board. + +--- + +## Application Description + +### Cloud Platforms ++ AWS + 1. Publish payload for sensor data (telemetry) + * topic: + ``thingName/sensors `` + * payload: + ```json + { + "Light": lightValue, + "Temp": temperatureValue + } + ``` + 2. Device publishes payload to update the Device Shadow + * topic: + + `$aws/things/thingName/shadow/update` + + * payload: + ```json + { + "state": + { + "reported": + { + "toggle": updatedToggleValue + } + } + } + ``` + 3. User Interface publishes payload to Device Shadow + * topic: + + `$aws/things/thingName/shadow/update` + + * payload: + ```json + { + "state": + { + "desired": + { + "toggle": toBeUpdatedToggleValue + } + } + } + ``` + 4. Device subscribes to delta to receive actionable changes + * topic: + + `$aws/things/thingName/shadow/update/delta` + + * payload: + + ```json + { + "state": + { + "Light": lightValue, + } + } + ``` + +#### The AVR IoT development board publishes data from the on-board light and temperature sensor every second to the cloud. +#### The data received over the subscribed topic is displayed on a serial terminal. + +### Sending MQTT publish packets ++ The C code for sending MQTT publish packets is available in AVRIoT.X/mcc_generated_files/application_manager.c file. ++ The API ``static void sendToCloud(void)`` is responsible for publishing data at an interval of 1 second. + +### Sending MQTT subscribe packets ++ The C code for sending MQTT subscribe packets is available in AVRIoT.X/mcc_generated_files/application_manager.c file. ++ The API ``static void subscribeToCloud(void)`` is responsible for sending MQTT subscribe packets to the cloud after MQTT connection is established. + +### Processing Packets received over subscribed topic ++ The C code for processing MQTT publish packets received over the subscribed topic is available in AVRIoT.X/mcc_generated_files/application_manager.c file. ++ The ``static void receivedFromCloud(uint8_t *topic, uint8_t *payload)`` function is used for processing packets published over the subscribed topic. + +--- + +## Secure Provisioning & Transport Layer Security + +1. The AVR-IoT board under the Wireless for Amazon Web Services (WA) variation is shipped pre-provisioned for coordination with the AWS Cloud system. +2. Security is achieved by using the built-in Transport Layer Security (TLS) 'stack' configured within the WINC Wi-Fi Module. +3. A Pre-Manufacturing process has configured the appropriate Slot locations on the ATECC608A security device. +4. All required certificates used for signing and authentication have been written to, and 'locked' into allocated slots. + + This process is achieved through: [TrustFlex](https://www.microchip.com/design-centers/security-ics/trust-platform/trustflex/trustflex-aws-iot-authentication) + + Additional options are also supported, such as: [Trust&Go](https://www.microchip.com/design-centers/security-ics/trust-platform/trust-go) + + Fully scope of support for Secure Aspects of development can be found here: [Trust Platform](https://www.microchip.com/design-centers/security-ics/trust-platform) +5. This process has been performed to allow for an Out Of Box (OOB) operation of the AVR-IoT development board along with supporting web page. +6. Shadow Topic are a key application feature being supported through the AWS platform. Further reference can be found here: + + [Shadow MQTT Topics](https://docs.aws.amazon.com/iot/latest/developerguide/device-shadow-mqtt.html) +7. For AVR-IoT development not provisioned for the AWS platform; refer to the below repo location: + + **gitHub Provisioning Repo coming in future. Currently refer to:** + + [AVR-IoT AWS Provisioning](https://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en611265) + +--- + +## Out Of Box (OOB) Operation + 0. There are three possible variations within application behavior possible by holding push buttons on startup + + Default behavior: No Button Pressed + + Soft AP: SW0 is Held on startup (see description farther in document) + + Default behavior Restore DEFAULT Credentials: SW0 & SW1 Held on startup. This state is reflected by **BLINKING GREEN LED** until a Wi-Fi connection is established. + + After a successful connection; last VALID CREDIENTIALS are maintained in the WINC for next power cycle connection. + + 1. Connect board to PC using USB-micro cable. + + + The LEDs will **Cycle** upon startup: **BLUE-->GREEN-->YELLOW-->RED**, short delay, **BLUE-->GREEN-->YELLOW-->RED**. + + 2. The **BLUE LED** will begin to blink, this indicates the board is attempting to join the local **ACCESS POINT**. + + ![Connecting](images/awsLeverage.png) + + 3. Update the Wi-Fi Credentials; upon connecting the blinking will stop, and the **LED** will become **STATIC**. Below are the easiest methods to update credentials. + + The board will appear on the PC enumerated as a mass storage device under the name **CURIOSITY**. Credentials can be downloaded as the file **WIFI.CFG** using the **CLICK-ME.HTM** file stored on the **CURIOSITY** device. + + ![URL Hosted Credentials](images/wifiCredentialsWeb.png) + + + This will launch the URL: https://avr-iot.com/device/{DeviceId} The file produced with entered credentials is produced through the WINC module, and no information is shared through the internet. Drag and Drop, or Copy and Paste the **WIFI.CFG** file onto the **CURIOSITY** device to load new credentials onto the IoT demonstration board. + + ![WiFi Config](images/wifiNotepad.png) + + + Use a **Serial Terminal** to update the WiFi Credentials loaded onto the WINC module. Use the Command Line Interface (CLI) supported command ``wifi host_name,pass_code,auth_type`` | host_name/pass_code are entered strings, auth_type is int value: (0: open, 1: WEP, 2: WPA). + + ![Serial Credentials](images/serialWiFi.png) + + 4. After becoming connected to the ACCESS POINT, the GREEN LED will begin to blink, this indicates the board is attempting to establish a TCP/IP and MQTT connection with the cloud providing service. The GREEN LED will stop blinking and become STATIC when the TCP and MQTT connection is established. + + Using the in module TCP/IP stack pre-configured with provisioned credentials; the device establishes a **MQTT** connection with the IoT Broker provider (AWS). + ![Status Display](images/awsConnection.png) + + 5. After successfully establishing MQTT connection, the **YELLOW LED** will blink, indicating data exchanged between the End-Device (AVR-IoT), and BROKER (AWS). + + ![Telemetry Data](images/PublishDataToAWS.png) + + 6. Connect to the www.avr-iot.com, or www.pic-iot.com, device specific website to view publish/subscribe data. This page can be found via launching the **CLICK-ME.HTM** file on the **CURIOSITY** device. + + There will be (2) scrolling graphs visible. (1) shows temperature sensor, (1) shows the light sensor value. + + Additional graphs can be produced altered through the published topic message. + + ![Telemetry Data](images/awsSensors.png) + + 7. **Control Your Device** using the (3) rows beneath the '**Control Your Device**' section used to publish subscription data to end-devices through the broker. + + **Only the use of Toggle is supported natively** + + **Expanding features would require custom written Firmware implementation** + + These example rows demonstrate options for: Toggle (boolean), Text Field (String), Sliders (integer) + + ![Subscribe Data](images/Actuators.png) + + 8. When connection is established with the Broker, the publish message topic will be printed to a serial terminal through the CDC-USB bridge. + + 9600 is expected Baud Rate. + + When a topic subscription is received, the payload is printed in JSON format to the terminal. + + Topic subscription message are sent when the 'Send to device' push button on the webpage is pressed. + + ![Serial Subscribe Message](images/DeviceStartUpConsole.png) + + 9. When the 'Desired' state is updated in the 'Delta' Shadow Topic. + + Device which required updates to the 'Desired' state which differs from their last 'Reported' value will receieve a published message on the '.../delta' MQTT topic. + + Upon reception the device will report the updated 'Desired' value for the attribute with timestamp on the console. + + ![Delta Subscribe Message](images/DeltaToggle.png) + +--- + +## Understanding the Device Shadow in AWS + + 1. The AWS broker allows for the use of Shadow Topics. The Shadow Topics are used to retain a specific value within the Broker, so End-Device status updates can be managed. + + Shadow Topics are used to restore the state of variables, or applications. + + Shadow Topics retain expected values, and report if Published data reflects a difference in value. + + When difference exist, status of the delta is reported to those subscribed to appropriate topic messages. + + ![ShadowTopic UserStory](images/AWS_ShadowUserStory.png) + + 2. Updates to the device shadow are published on $aws/things/{ThingName}/shadow/update topic. + When a message is sent to the board by changing the value of the **toggle** fiels in **Control Your Device** section: + + This message is published on the $aws/things/{ThingName}/shadow/update topic. + + If the curent value of **toggle** in the device shadow is different from the **toggle** value present in the AWS Device Shadow, the AWS Shadow service reports this change to the device by publishing a message on $aws/things/{ThingName}/shadow/update/delta topic. + + The JSON structure of the message sent should appear as below + ```json + { + "state": { + "desired": { + "toggle": [value] + } + } + } + ``` + + 3. The meta data, and delta difference will be reported via the Serial Terminal upon a difference between desired/reported. + + ![Delta Metadata](images/DeltaToggle.png) + + 4. In response to this, the end device publishes a message to $aws/things/{ThingName}/shadow/update topic. + + This message is published to **report** the update to the **toggle** attribute. + + The JSON structure of the message sent should appear as below + ```json + { + "state": { + "reported": { + "toggle": [value] + } + } + } + ``` + + 5. Application flow when using the device shadow + + ![Message After Delta](images/SequenceOfEvents.png) + +--- + +## Additional Operations + +### Command Line Interface ++ The AVR-IoT development board can also be accessed through a serial command line interface. + + This interface can be used to provide diagnostic information. ++ To access this interface, use any preferred serial terminal application (i.e. Teraterm, Coolterm, PuTTy) and open the serial port labeled Curiosity Virtual COM port, with the following settings: + +| - | - | +| :---: | :---: | +| Baud Rate | 9600 | +| Data | 8-bit | +| Parity Bit | None | +| Stop Bit | 1 bit | +| Flow Control | None | +| Additional Settings | Local Echo: On | +| Transmit to the Microcontroller | CR+LF (Carriage Return + Line Feed) | + +**Note:**  For users of the Windows environment, the USB serial interface requires the installation of an USB serial port driver. + +| Command | Arguments | Description | +| :---: | :---: | :---: | +| reset | - | Reset the settings on the device | +| device | - | Print the unique device ID of the board | +| thing | - | Print the end devices assigned thingName | +| reconnect | - | Re-establish connection to the Cloud | +| version | - | Print the firmware version of the serial port user interface | +| cli_version | - | Print the command line interface firmware version of the serial port user interface | +| wifi | Network SSID, Password, Security Option | Enter Wi-Fi®network authentication details | +| debug | Debug Options | Print debug messages to see status of board operation | + +**wifi Security Options:** ++ 0 : Open - Password and Security option parameters are not required. ++ 1 : WPA/WPA2 - Security Option Parameter not required. ++ 2: WEP - + +**debug Debug Options:** +Type in a number from 0 to 4; for the number of debug messages with 0 - the result is printing no messages and with 4 for printing all the messages. ++ 0 : Minimal ++ 1 : Critical ++ 2 : Warning ++ 3 : Info ++ 4 : All + +### Soft Access Point (AP) +The AVR-IoT development board can be accessed through a Wi-Fi access point enabled by the Software-Enabled Access mode of the WINC1510. This can be another way to connect the board to a Wi-Fi network. To enter Soft AP mode, press and hold the SW0 push button before plugging in the board. When connecting to the module hosted access point, the user will need to enter the desired SSID and password credentials for the network. After the user enters the details, pressing the Connect button will reconfigure network credentials for the device. + +![Soft AP Credentials](images/softApCredentials.png) + +--- + +## Software Features + +### WINC +Microchip's WINC1510 is a low-power consumption 802.11 b/g/n IoT (Internet of Things) module, +specifically optimized for low-power IoT applications. The module integrates the following: Power +Amplifier (PA), Low-Noise Amplifier (LNA), switch, power management, and a printed antenna or a micro +co-ax (u.FL) connector for an external antenna, resulting in a small form factor (21.7 x 14.7 x 2.1 mm) +design. It is interoperable with various vendors’ 802.11 b/g/n access points. This module provides SPI +ports to interface with a host controller. The WINC1510 provides internal Flash memory as well as +multiple peripheral interfaces, including UART and SPI. The only external clock source needed for the +WINC1510 is the built-in, high-speed crystal or oscillator (26 MHz). The WINC1510 is available in a QFN +package or as a certified module. + +![WINC Module](images/wincModule.png) + +### Crypto Authentication Library (CAL) +The ATECC608A is a secure element from the Microchip CryptoAuthentication™ portfolio with advanced +Elliptic Curve Cryptography (ECC) capabilities. With ECDH and ECDSA being built right in, this device is +ideal for the rapidly growing IoT market, by easily supplying the full range of security such as +confidentiality, data integrity, and authentication to systems with MCUs or MPUs running encryption/ +decryption algorithms. Similar to all Microchip CryptoAuthentication products, the new ATECC608A +employs ultra-secure, hardware-based cryptographic key storage and cryptographic countermeasures, +which eliminates any potential backdoors linked to software weaknesses. + +![ECC IC](images/eccDevice.png) + +### Message Queuing Telemetry Transport (MQTT) +MQTT is a lightweight M2M (Machine to Machine) messaging protocol used to exchange data between devices. +This is an established protocol, additional references can found through [MQTT.org](http://mqtt.org) + +The version used with the demostration is a generated software library produced through the +[MPLAB Code Configurator](https://www.microchip.com/mplab/mplab-code-configurator) (MCC) tool, and has been written by Microchip for use family of devices. + +--- + +## Hardware Description + +![Board Callout](images/boardCallout.png) \ No newline at end of file diff --git a/images/AWS_ShadowUserStory.png b/images/AWS_ShadowUserStory.png new file mode 100644 index 0000000..b277d6b Binary files /dev/null and b/images/AWS_ShadowUserStory.png differ diff --git a/images/Actuators.png b/images/Actuators.png new file mode 100644 index 0000000..59d0c54 Binary files /dev/null and b/images/Actuators.png differ diff --git a/images/DeltaToggle.png b/images/DeltaToggle.png new file mode 100644 index 0000000..88ef0aa Binary files /dev/null and b/images/DeltaToggle.png differ diff --git a/images/DeviceStartUpConsole.png b/images/DeviceStartUpConsole.png new file mode 100644 index 0000000..105727c Binary files /dev/null and b/images/DeviceStartUpConsole.png differ diff --git a/images/MetaData.png b/images/MetaData.png new file mode 100644 index 0000000..f0b4b97 Binary files /dev/null and b/images/MetaData.png differ diff --git a/images/PublishDataToAWS.png b/images/PublishDataToAWS.png new file mode 100644 index 0000000..e7f9e06 Binary files /dev/null and b/images/PublishDataToAWS.png differ diff --git a/images/SequenceOfEvents.png b/images/SequenceOfEvents.png new file mode 100644 index 0000000..e481eb7 Binary files /dev/null and b/images/SequenceOfEvents.png differ diff --git a/images/awsCli.PNG b/images/awsCli.PNG new file mode 100644 index 0000000..efd50e0 Binary files /dev/null and b/images/awsCli.PNG differ diff --git a/images/awsConnection.png b/images/awsConnection.png new file mode 100644 index 0000000..30b70d8 Binary files /dev/null and b/images/awsConnection.png differ diff --git a/images/awsCore.png b/images/awsCore.png new file mode 100644 index 0000000..3e0274a Binary files /dev/null and b/images/awsCore.png differ diff --git a/images/awsLeverage.png b/images/awsLeverage.png new file mode 100644 index 0000000..911bfb2 Binary files /dev/null and b/images/awsLeverage.png differ diff --git a/images/awsSendToCloud.PNG b/images/awsSendToCloud.PNG new file mode 100644 index 0000000..5ac97b9 Binary files /dev/null and b/images/awsSendToCloud.PNG differ diff --git a/images/awsSensors.png b/images/awsSensors.png new file mode 100644 index 0000000..2da88e0 Binary files /dev/null and b/images/awsSensors.png differ diff --git a/images/board.png b/images/board.png new file mode 100644 index 0000000..5e06849 Binary files /dev/null and b/images/board.png differ diff --git a/images/boardAVR.png b/images/boardAVR.png new file mode 100644 index 0000000..58a876f Binary files /dev/null and b/images/boardAVR.png differ diff --git a/images/boardCallout.png b/images/boardCallout.png new file mode 100644 index 0000000..5dea1c2 Binary files /dev/null and b/images/boardCallout.png differ diff --git a/images/boardPIC.png b/images/boardPIC.png new file mode 100644 index 0000000..744bafc Binary files /dev/null and b/images/boardPIC.png differ diff --git a/images/capturedMetaData.PNG b/images/capturedMetaData.PNG new file mode 100644 index 0000000..e3c08c4 Binary files /dev/null and b/images/capturedMetaData.PNG differ diff --git a/images/cliMenu.png b/images/cliMenu.png new file mode 100644 index 0000000..77e38db Binary files /dev/null and b/images/cliMenu.png differ diff --git a/images/deviceIdConnect.png b/images/deviceIdConnect.png new file mode 100644 index 0000000..4570ff0 Binary files /dev/null and b/images/deviceIdConnect.png differ diff --git a/images/eccDevice.png b/images/eccDevice.png new file mode 100644 index 0000000..40e5444 Binary files /dev/null and b/images/eccDevice.png differ diff --git a/images/graph.PNG b/images/graph.PNG new file mode 100644 index 0000000..2bf5c6c Binary files /dev/null and b/images/graph.PNG differ diff --git a/images/serialSubscribe.png b/images/serialSubscribe.png new file mode 100644 index 0000000..703a870 Binary files /dev/null and b/images/serialSubscribe.png differ diff --git a/images/serialWiFi.png b/images/serialWiFi.png new file mode 100644 index 0000000..74cbc3c Binary files /dev/null and b/images/serialWiFi.png differ diff --git a/images/softApCredentials.png b/images/softApCredentials.png new file mode 100644 index 0000000..1956bae Binary files /dev/null and b/images/softApCredentials.png differ diff --git a/images/standardConnect.png b/images/standardConnect.png new file mode 100644 index 0000000..b9e5eee Binary files /dev/null and b/images/standardConnect.png differ diff --git a/images/subscribeData.png b/images/subscribeData.png new file mode 100644 index 0000000..ad5d8d1 Binary files /dev/null and b/images/subscribeData.png differ diff --git a/images/telemetryGraphs.png b/images/telemetryGraphs.png new file mode 100644 index 0000000..d5cb4e0 Binary files /dev/null and b/images/telemetryGraphs.png differ diff --git a/images/updateDeviceShadow.png b/images/updateDeviceShadow.png new file mode 100644 index 0000000..01d581d Binary files /dev/null and b/images/updateDeviceShadow.png differ diff --git a/images/updateShadowOnPushButtonPress.PNG b/images/updateShadowOnPushButtonPress.PNG new file mode 100644 index 0000000..a8751bd Binary files /dev/null and b/images/updateShadowOnPushButtonPress.PNG differ diff --git a/images/wifiCredentialsWeb.png b/images/wifiCredentialsWeb.png new file mode 100644 index 0000000..263f146 Binary files /dev/null and b/images/wifiCredentialsWeb.png differ diff --git a/images/wifiNotepad.png b/images/wifiNotepad.png new file mode 100644 index 0000000..82058ea Binary files /dev/null and b/images/wifiNotepad.png differ diff --git a/images/wifiStatus.png b/images/wifiStatus.png new file mode 100644 index 0000000..0eae44a Binary files /dev/null and b/images/wifiStatus.png differ diff --git a/images/wincModule.png b/images/wincModule.png new file mode 100644 index 0000000..50c59cd Binary files /dev/null and b/images/wincModule.png differ