rel_1.6.0 init

This commit is contained in:
guocheng.kgc 2020-06-18 20:06:52 +08:00 committed by shengdong.dsd
commit 27b3e2883d
19359 changed files with 8093121 additions and 0 deletions

View file

@ -0,0 +1,712 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef __Common_h__
#define __Common_h__
// ==== STD LIB ====
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#if defined __GNUC__
#include "platform_toolchain.h"
#elif defined ( __ICCARM__ )
#include "EWARM/platform_toolchain.h"
#elif defined ( __CC_ARM ) //KEIL
#include "RVMDK/platform_toolchain.h"
#endif
//#ifdef CONFIG_PLATFORM_8195A
//#include "rtl_lib.h"
//#endif
#ifdef __cplusplus
extern "C" {
#endif
#define TARGET_RT_LITTLE_ENDIAN
/* Use this macro to define an RTOS-aware interrupt handler where RTOS
* primitives can be safely accessed
*
* @usage:
* WWD_RTOS_DEFINE_ISR( my_irq_handler )
* {
* // Do something here
* }
*/
#if defined( __GNUC__ )
/* Section where IRQ handlers are placed */
#define IRQ_SECTION ".text.irq"
#define MICO_RTOS_DEFINE_ISR( function ) \
void function( void ); \
__attribute__(( interrupt, used, section(IRQ_SECTION) )) void function( void )
#elif defined ( __IAR_SYSTEMS_ICC__ )
#define MICO_RTOS_DEFINE_ISR( function ) \
__irq __root void function( void ); \
__irq __root void function( void )
#elif defined ( __CC_ARM ) //KEIL
#define MICO_RTOS_DEFINE_ISR( function ) \
void function( void ); \
__attribute__(( used )) void function( void )
#else
#define MICO_RTOS_DEFINE_ISR( function ) \
void function( void );
#endif
// ==== COMPATIBILITY TYPES
//typedef uint8_t Boolean;
typedef uint8_t mico_bool_t;
#define MICO_FALSE (0)
#define MICO_TRUE (1)
#if( !defined( INT_MAX ) )
#define INT_MAX 2147483647
#endif
// ==== MiCO Timer Typedef ====
#define NANOSECONDS 1000000UL
#define MICROSECONDS 1000
#define MILLISECONDS (1)
#define SECONDS (1000)
#define MINUTES (60 * SECONDS)
#define HOURS (60 * MINUTES)
#define DAYS (24 * HOURS)
typedef uint32_t mico_time_t; /**< Time value in milliseconds */
typedef uint32_t mico_utc_time_t; /**< UTC Time in seconds */
typedef uint64_t mico_utc_time_ms_t; /**< UTC Time in milliseconds */
// ==== OSStatus ====
typedef int OSStatus;
#define kNoErr 0 //! No error occurred.
#define kGeneralErr -1 //! General error.
#define kInProgressErr 1 //! Operation in progress.
// Generic error codes are in the range -6700 to -6779.
#define kGenericErrorBase -6700 //! Starting error code for all generic errors.
#define kUnknownErr -6700 //! Unknown error occurred.
#define kOptionErr -6701 //! Option was not acceptable.
#define kSelectorErr -6702 //! Selector passed in is invalid or unknown.
#define kExecutionStateErr -6703 //! Call made in the wrong execution state (e.g. called at interrupt time).
#define kPathErr -6704 //! Path is invalid, too long, or otherwise not usable.
#define kParamErr -6705 //! Parameter is incorrect, missing, or not appropriate.
#define kUserRequiredErr -6706 //! User interaction is required.
#define kCommandErr -6707 //! Command invalid or not supported.
#define kIDErr -6708 //! Unknown, invalid, or inappropriate identifier.
#define kStateErr -6709 //! Not in appropriate state to perform operation.
#define kRangeErr -6710 //! Index is out of range or not valid.
#define kRequestErr -6711 //! Request was improperly formed or not appropriate.
#define kResponseErr -6712 //! Response was incorrect or out of sequence.
#define kChecksumErr -6713 //! Checksum does not match the actual data.
#define kNotHandledErr -6714 //! Operation was not handled (or not handled completely).
#define kVersionErr -6715 //! Version is not correct or not compatible.
#define kSignatureErr -6716 //! Signature did not match what was expected.
#define kFormatErr -6717 //! Unknown, invalid, or inappropriate file/data format.
#define kNotInitializedErr -6718 //! Action request before needed services were initialized.
#define kAlreadyInitializedErr -6719 //! Attempt made to initialize when already initialized.
#define kNotInUseErr -6720 //! Object not in use (e.g. cannot abort if not already in use).
#define kAlreadyInUseErr -6721 //! Object is in use (e.g. cannot reuse active param blocks).
#define kTimeoutErr -6722 //! Timeout occurred.
#define kCanceledErr -6723 //! Operation canceled (successful cancel).
#define kAlreadyCanceledErr -6724 //! Operation has already been canceled.
#define kCannotCancelErr -6725 //! Operation could not be canceled (maybe already done or invalid).
#define kDeletedErr -6726 //! Object has already been deleted.
#define kNotFoundErr -6727 //! Something was not found.
#define kNoMemoryErr -6728 //! Not enough memory was available to perform the operation.
#define kNoResourcesErr -6729 //! Resources unavailable to perform the operation.
#define kDuplicateErr -6730 //! Duplicate found or something is a duplicate.
#define kImmutableErr -6731 //! Entity is not changeable.
#define kUnsupportedDataErr -6732 //! Data is unknown or not supported.
#define kIntegrityErr -6733 //! Data is corrupt.
#define kIncompatibleErr -6734 //! Data is not compatible or it is in an incompatible format.
#define kUnsupportedErr -6735 //! Feature or option is not supported.
#define kUnexpectedErr -6736 //! Error occurred that was not expected.
#define kValueErr -6737 //! Value is not appropriate.
#define kNotReadableErr -6738 //! Could not read or reading is not allowed.
#define kNotWritableErr -6739 //! Could not write or writing is not allowed.
#define kBadReferenceErr -6740 //! An invalid or inappropriate reference was specified.
#define kFlagErr -6741 //! An invalid, inappropriate, or unsupported flag was specified.
#define kMalformedErr -6742 //! Something was not formed correctly.
#define kSizeErr -6743 //! Size was too big, too small, or not appropriate.
#define kNameErr -6744 //! Name was not correct, allowed, or appropriate.
#define kNotPreparedErr -6745 //! Device or service is not ready.
#define kReadErr -6746 //! Could not read.
#define kWriteErr -6747 //! Could not write.
#define kMismatchErr -6748 //! Something does not match.
#define kDateErr -6749 //! Date is invalid or out-of-range.
#define kUnderrunErr -6750 //! Less data than expected.
#define kOverrunErr -6751 //! More data than expected.
#define kEndingErr -6752 //! Connection, session, or something is ending.
#define kConnectionErr -6753 //! Connection failed or could not be established.
#define kAuthenticationErr -6754 //! Authentication failed or is not supported.
#define kOpenErr -6755 //! Could not open file, pipe, device, etc.
#define kTypeErr -6756 //! Incorrect or incompatible type (e.g. file, data, etc.).
#define kSkipErr -6757 //! Items should be or was skipped.
#define kNoAckErr -6758 //! No acknowledge.
#define kCollisionErr -6759 //! Collision occurred (e.g. two on bus at same time).
#define kBackoffErr -6760 //! Backoff in progress and operation intentionally failed.
#define kNoAddressAckErr -6761 //! No acknowledge of address.
#define kInternalErr -6762 //! An error internal to the implementation occurred.
#define kNoSpaceErr -6763 //! Not enough space to perform operation.
#define kCountErr -6764 //! Count is incorrect.
#define kEndOfDataErr -6765 //! Reached the end of the data (e.g. recv returned 0).
#define kWouldBlockErr -6766 //! Would need to block to continue (e.g. non-blocking read/write).
#define kLookErr -6767 //! Special case that needs to be looked at (e.g. interleaved data).
#define kSecurityRequiredErr -6768 //! Security is required for the operation (e.g. must use encryption).
#define kOrderErr -6769 //! Order is incorrect.
#define kUpgradeErr -6770 //! Must upgrade.
#define kAsyncNoErr -6771 //! Async operation successfully started and is now in progress.
#define kDeprecatedErr -6772 //! Operation or data is deprecated.
#define kPermissionErr -6773 //! Permission denied.
#define kGenericErrorEnd -6779 //! Last generic error code (inclusive)
// ==== C TYPE SAFE MACROS ====
//---------------------------------------------------------------------------------------------------------------------------
/*! @group ctype safe macros
@abstract Wrappers for the ctype.h macros make them safe when used with signed characters.
@discussion
Some implementations of the ctype.h macros use the character value to directly index into a table.
This can lead to crashes and other problems when used with signed characters if the character value
is greater than 127 because the values 128-255 will appear to be negative if viewed as a signed char.
A negative subscript to an array causes it to index before the beginning and access invalid memory.
To work around this, these *_safe wrappers mask the value and cast it to an unsigned char.
*/
#define isalnum_safe( X ) isalnum( ( (unsigned char)( ( X ) & 0xFF ) ) )
#define isalpha_safe( X ) isalpha( ( (unsigned char)( ( X ) & 0xFF ) ) )
#define iscntrl_safe( X ) iscntrl( ( (unsigned char)( ( X ) & 0xFF ) ) )
#define isdigit_safe( X ) isdigit( ( (unsigned char)( ( X ) & 0xFF ) ) )
#define isgraph_safe( X ) isgraph( ( (unsigned char)( ( X ) & 0xFF ) ) )
#define islower_safe( X ) islower( ( (unsigned char)( ( X ) & 0xFF ) ) )
#define isoctal_safe( X ) isoctal( ( (unsigned char)( ( X ) & 0xFF ) ) )
#define isprint_safe( X ) isprint( ( (unsigned char)( ( X ) & 0xFF ) ) )
#define ispunct_safe( X ) ispunct( ( (unsigned char)( ( X ) & 0xFF ) ) )
#define isspace_safe( X ) isspace( ( (unsigned char)( ( X ) & 0xFF ) ) )
#define isupper_safe( X ) isupper( ( (unsigned char)( ( X ) & 0xFF ) ) )
#define isxdigit_safe( X ) isxdigit( ( (unsigned char)( ( X ) & 0xFF ) ) )
#define tolower_safe( X ) tolower( ( (unsigned char)( ( X ) & 0xFF ) ) )
#define toupper_safe( X ) toupper( ( (unsigned char)( ( X ) & 0xFF ) ) )
// ==== SHA DEFINES ====
#define SHA_DIGEST_LENGTH 20
#define SHA_CTX SHA1Context
#define SHA1_Init( CTX ) SHA1Reset( (CTX) )
#define SHA1_Update( CTX, PTR, LEN ) SHA1Input( (CTX), (PTR), (LEN) )
#define SHA1_Final( DIGEST, CTX ) SHA1Result( (CTX), (DIGEST) )
#define SHA1( PTR, LEN, DIGEST ) SHA1Direct( (PTR), (LEN), (DIGEST) )
#define SHA512_DIGEST_LENGTH 64
#define SHA512_CTX SHA512Context
#define SHA512_Init( CTX ) SHA512Reset( (CTX) )
#define SHA512_Update( CTX, PTR, LEN ) SHA512Input( (CTX), (PTR), (LEN) )
#define SHA512_Final( DIGEST, CTX ) SHA512Result( (CTX), (DIGEST) )
#define SHA512( PTR, LEN, DIGEST ) SHA512Direct( (PTR), (LEN), (DIGEST) )
#define SHA3_DIGEST_LENGTH 64
#define SHA3_CTX SHA3_CTX_compat
#define SHA3_Init( CTX ) SHA3_Init_compat( (CTX) )
#define SHA3_Update( CTX, PTR, LEN ) SHA3_Update_compat( (CTX), (PTR), (LEN) )
#define SHA3_Final( DIGEST, CTX ) SHA3_Final_compat( (DIGEST), (CTX) )
#define SHA3( PTR, LEN, DIGEST ) SHA3_compat( (PTR), (LEN), DIGEST )
// ==== MIN / MAX ====
//---------------------------------------------------------------------------------------------------------------------------
/*! @function Min
@abstract Returns the lesser of X and Y.
*/
#if( !defined( Min ) )
#define Min( X, Y ) ( ( ( X ) < ( Y ) ) ? ( X ) : ( Y ) )
#endif
//---------------------------------------------------------------------------------------------------------------------------
/*! @function Max
@abstract Returns the greater of X and Y.
*/
#if( !defined( Max ) )
#define Max( X, Y ) ( ( ( X ) > ( Y ) ) ? ( X ) : ( Y ) )
#endif
// ==== Alignment / Endian safe read/write/swap macros ====
#define ReadBig16( PTR ) \
( (uint16_t)( \
( ( (uint16_t)( (uint8_t *)(PTR) )[ 0 ] ) << 8 ) | \
( (uint16_t)( (uint8_t *)(PTR) )[ 1 ] ) ) )
#define ReadBig32( PTR ) \
( (uint32_t)( \
( ( (uint32_t)( (uint8_t *)(PTR) )[ 0 ] ) << 24 ) | \
( ( (uint32_t)( (uint8_t *)(PTR) )[ 1 ] ) << 16 ) | \
( ( (uint32_t)( (uint8_t *)(PTR) )[ 2 ] ) << 8 ) | \
( (uint32_t)( (uint8_t *)(PTR) )[ 3 ] ) ) )
#define ReadBig48( PTR ) \
( (uint64_t)( \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 0 ] ) << 40 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 1 ] ) << 32 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 2 ] ) << 24 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 3 ] ) << 16 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 4 ] ) << 8 ) | \
( (uint64_t)( (uint8_t *)(PTR) )[ 5 ] ) ) )
#define ReadBig64( PTR ) \
( (uint64_t)( \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 0 ] ) << 56 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 1 ] ) << 48 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 2 ] ) << 40 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 3 ] ) << 32 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 4 ] ) << 24 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 5 ] ) << 16 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 6 ] ) << 8 ) | \
( (uint64_t)( (uint8_t *)(PTR) )[ 7 ] ) ) )
// Big endian Writing
#define WriteBig16( PTR, X ) \
do \
{ \
( (uint8_t *)(PTR) )[ 0 ] = (uint8_t)( ( (X) >> 8 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 1 ] = (uint8_t)( (X) & 0xFF ); \
\
} while( 0 )
#define WriteBig32( PTR, X ) \
do \
{ \
( (uint8_t *)(PTR) )[ 0 ] = (uint8_t)( ( (X) >> 24 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 1 ] = (uint8_t)( ( (X) >> 16 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 2 ] = (uint8_t)( ( (X) >> 8 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 3 ] = (uint8_t)( (X) & 0xFF ); \
\
} while( 0 )
#define WriteBig48( PTR, X ) \
do \
{ \
( (uint8_t *)(PTR) )[ 0 ] = (uint8_t)( ( (X) >> 40 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 1 ] = (uint8_t)( ( (X) >> 32 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 2 ] = (uint8_t)( ( (X) >> 24 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 3 ] = (uint8_t)( ( (X) >> 16 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 4 ] = (uint8_t)( ( (X) >> 8 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 5 ] = (uint8_t)( (X) & 0xFF ); \
\
} while( 0 )
#define WriteBig64( PTR, X ) \
do \
{ \
( (uint8_t *)(PTR) )[ 0 ] = (uint8_t)( ( (X) >> 56 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 1 ] = (uint8_t)( ( (X) >> 48 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 2 ] = (uint8_t)( ( (X) >> 40 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 3 ] = (uint8_t)( ( (X) >> 32 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 4 ] = (uint8_t)( ( (X) >> 24 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 5 ] = (uint8_t)( ( (X) >> 16 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 6 ] = (uint8_t)( ( (X) >> 8 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 7 ] = (uint8_t)( (X) & 0xFF ); \
\
} while( 0 )
// Little endian reading
#define ReadLittle16( PTR ) \
( (uint16_t)( \
( (uint16_t)( (uint8_t *)(PTR) )[ 0 ] ) | \
( ( (uint16_t)( (uint8_t *)(PTR) )[ 1 ] ) << 8 ) ) )
#define ReadLittle32( PTR ) \
( (uint32_t)( \
( (uint32_t)( (uint8_t *)(PTR) )[ 0 ] ) | \
( ( (uint32_t)( (uint8_t *)(PTR) )[ 1 ] ) << 8 ) | \
( ( (uint32_t)( (uint8_t *)(PTR) )[ 2 ] ) << 16 ) | \
( ( (uint32_t)( (uint8_t *)(PTR) )[ 3 ] ) << 24 ) ) )
#define ReadLittle48( PTR ) \
( (uint64_t)( \
( (uint64_t)( (uint8_t *)(PTR) )[ 0 ] ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 1 ] ) << 8 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 2 ] ) << 16 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 3 ] ) << 24 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 4 ] ) << 32 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 5 ] ) << 40 ) ) )
#define ReadLittle64( PTR ) \
( (uint64_t)( \
( (uint64_t)( (uint8_t *)(PTR) )[ 0 ] ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 1 ] ) << 8 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 2 ] ) << 16 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 3 ] ) << 24 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 4 ] ) << 32 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 5 ] ) << 40 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 6 ] ) << 48 ) | \
( ( (uint64_t)( (uint8_t *)(PTR) )[ 7 ] ) << 56 ) ) )
// Little endian writing
#define WriteLittle16( PTR, X ) \
do \
{ \
( (uint8_t *)(PTR) )[ 0 ] = (uint8_t)( (X) & 0xFF ); \
( (uint8_t *)(PTR) )[ 1 ] = (uint8_t)( ( (X) >> 8 ) & 0xFF ); \
\
} while( 0 )
#define WriteLittle32( PTR, X ) \
do \
{ \
( (uint8_t *)(PTR) )[ 0 ] = (uint8_t)( (X) & 0xFF ); \
( (uint8_t *)(PTR) )[ 1 ] = (uint8_t)( ( (X) >> 8 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 2 ] = (uint8_t)( ( (X) >> 16 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 3 ] = (uint8_t)( ( (X) >> 24 ) & 0xFF ); \
\
} while( 0 )
#define WriteLittle48( PTR, X ) \
do \
{ \
( (uint8_t *)(PTR) )[ 0 ] = (uint8_t)( (X) & 0xFF ); \
( (uint8_t *)(PTR) )[ 1 ] = (uint8_t)( ( (X) >> 8 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 2 ] = (uint8_t)( ( (X) >> 16 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 3 ] = (uint8_t)( ( (X) >> 24 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 4 ] = (uint8_t)( ( (X) >> 32 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 5 ] = (uint8_t)( ( (X) >> 40 ) & 0xFF ); \
\
} while( 0 )
#define WriteLittle64( PTR, X ) \
do \
{ \
( (uint8_t *)(PTR) )[ 0 ] = (uint8_t)( (X) & 0xFF ); \
( (uint8_t *)(PTR) )[ 1 ] = (uint8_t)( ( (X) >> 8 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 2 ] = (uint8_t)( ( (X) >> 16 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 3 ] = (uint8_t)( ( (X) >> 24 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 4 ] = (uint8_t)( ( (X) >> 32 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 5 ] = (uint8_t)( ( (X) >> 40 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 6 ] = (uint8_t)( ( (X) >> 48 ) & 0xFF ); \
( (uint8_t *)(PTR) )[ 7 ] = (uint8_t)( ( (X) >> 56 ) & 0xFF ); \
\
} while( 0 )
#if( !defined( TARGET_RT_LITTLE_ENDIAN ) && !defined( TARGET_RT_BIG_ENDIAN ) )
#error unknown byte order - update your Makefile to define the target platform endianness as TARGET_RT_BIG_ENDIAN / TARGET_RT_LITTLE_ENDIAN
#endif
#if( !defined( TARGET_RT_LITTLE_ENDIAN ) )
#define ReadHost16( PTR ) ReadBig16( (PTR) )
#define ReadHost32( PTR ) ReadBig32( (PTR) )
#define ReadHost48( PTR ) ReadBig48( (PTR) )
#define ReadHost64( PTR ) ReadBig64( (PTR) )
#define WriteHost16( PTR, X ) WriteBig16( (PTR), (X) )
#define WriteHost32( PTR, X ) WriteBig32( (PTR), (X) )
#define WriteHost48( PTR, X ) WriteBig48( (PTR), (X) )
#define WriteHost64( PTR, X ) WriteBig64( (PTR), (X) )
#else
#define ReadHost16( PTR ) ReadLittle16( (PTR) )
#define ReadHost32( PTR ) ReadLittle32( (PTR) )
#define ReadHost48( PTR ) ReadLittle48( (PTR) )
#define ReadHost64( PTR ) ReadLittle64( (PTR) )
#define WriteHost16( PTR, X ) WriteLittle16( (PTR), (X) )
#define WriteHost32( PTR, X ) WriteLittle32( (PTR), (X) )
#define WriteHost48( PTR, X ) WriteLittle48( (PTR), (X) )
#define WriteHost64( PTR, X ) WriteLittle64( (PTR), (X) )
#endif
// Unconditional swap read/write.
#if( !defined( TARGET_RT_LITTLE_ENDIAN ) )
#define ReadSwap16( PTR ) ReadLittle16( (PTR) )
#define ReadSwap32( PTR ) ReadLittle32( (PTR) )
#define ReadSwap48( PTR ) ReadLittle48( (PTR) )
#define ReadSwap64( PTR ) ReadLittle64( (PTR) )
#define WriteSwap16( PTR, X ) WriteLittle16( (PTR), (X) )
#define WriteSwap32( PTR, X ) WriteLittle32( (PTR), (X) )
#define WriteSwap48( PTR, X ) WriteLittle48( (PTR), (X) )
#define WriteSwap64( PTR, X ) WriteLittle64( (PTR), (X) )
#else
#define ReadSwap16( PTR ) ReadBig16( (PTR) )
#define ReadSwap32( PTR ) ReadBig32( (PTR) )
#define ReadSwap48( PTR ) ReadBig48( (PTR) )
#define ReadSwap64( PTR ) ReadBig64( (PTR) )
#define WriteSwap16( PTR, X ) WriteBig16( (PTR), (X) )
#define WriteSwap32( PTR, X ) WriteBig32( (PTR), (X) )
#define WriteSwap48( PTR, X ) WriteBig48( (PTR), (X) )
#define WriteSwap64( PTR, X ) WriteBig64( (PTR), (X) )
#endif
// Memory swaps
#if( !defined( TARGET_RT_LITTLE_ENDIAN ) )
#define HostToBig16Mem( SRC, LEN, DST ) do {} while( 0 )
#define BigToHost16Mem( SRC, LEN, DST ) do {} while( 0 )
#define LittleToHost16Mem( SRC, LEN, DST ) Swap16Mem( (SRC), (LEN), (DST) )
#define LittleToHost16Mem( SRC, LEN, DST ) Swap16Mem( (SRC), (LEN), (DST) )
#else
#define HostToBig16Mem( SRC, LEN, DST ) Swap16Mem( (SRC), (LEN), (DST) )
#define BigToHost16Mem( SRC, LEN, DST ) Swap16Mem( (SRC), (LEN), (DST) )
#define HostToLittle16Mem( SRC, LEN, DST ) do {} while( 0 )
#define LittleToHost16Mem( SRC, LEN, DST ) do {} while( 0 )
#endif
// Unconditional endian swaps
#if !defined (Swap16)
#define Swap16( X ) \
( (uint16_t)( \
( ( ( (uint16_t)(X) ) << 8 ) & UINT16_C( 0xFF00 ) ) | \
( ( ( (uint16_t)(X) ) >> 8 ) & UINT16_C( 0x00FF ) ) ) )
#endif
#if !defined (Swap32)
#define Swap32( X ) \
( (uint32_t)( \
( ( ( (uint32_t)(X) ) << 24 ) & UINT32_C( 0xFF000000 ) ) | \
( ( ( (uint32_t)(X) ) << 8 ) & UINT32_C( 0x00FF0000 ) ) | \
( ( ( (uint32_t)(X) ) >> 8 ) & UINT32_C( 0x0000FF00 ) ) | \
( ( ( (uint32_t)(X) ) >> 24 ) & UINT32_C( 0x000000FF ) ) ) )
#endif
#if !defined (Swap64)
#define Swap64( X ) \
( (uint64_t)( \
( ( ( (uint64_t)(X) ) << 56 ) & UINT64_C( 0xFF00000000000000 ) ) | \
( ( ( (uint64_t)(X) ) << 40 ) & UINT64_C( 0x00FF000000000000 ) ) | \
( ( ( (uint64_t)(X) ) << 24 ) & UINT64_C( 0x0000FF0000000000 ) ) | \
( ( ( (uint64_t)(X) ) << 8 ) & UINT64_C( 0x000000FF00000000 ) ) | \
( ( ( (uint64_t)(X) ) >> 8 ) & UINT64_C( 0x00000000FF000000 ) ) | \
( ( ( (uint64_t)(X) ) >> 24 ) & UINT64_C( 0x0000000000FF0000 ) ) | \
( ( ( (uint64_t)(X) ) >> 40 ) & UINT64_C( 0x000000000000FF00 ) ) | \
( ( ( (uint64_t)(X) ) >> 56 ) & UINT64_C( 0x00000000000000FF ) ) ) )
#endif
// Host<->Network/Big endian swaps
#if( !defined( TARGET_RT_LITTLE_ENDIAN ) )
#define hton16( X ) (X)
#define ntoh16( X ) (X)
#define hton32( X ) (X)
#define ntoh32( X ) (X)
#define hton64( X ) (X)
#define ntoh64( X ) (X)
#else
#define hton16( X ) Swap16( X )
#define ntoh16( X ) Swap16( X )
#define hton32( X ) Swap32( X )
#define ntoh32( X ) Swap32( X )
#define hton64( X ) Swap64( X )
#define ntoh64( X ) Swap64( X )
#endif
#define htons( X ) hton16( X )
#define ntohs( X ) ntoh16( X )
#define htonl( X ) hton32( X )
#define ntohl( X ) ntoh32( X )
//---------------------------------------------------------------------------------------------------------------------------
/*! @function BitArray
@abstract Macros for working with bit arrays.
@discussion
This treats bit numbers starting from the left so bit 0 is 0x80 in byte 0, bit 1 is 0x40 in bit 0,
bit 8 is 0x80 in byte 1, etc. For example, the following ASCII art shows how the bits are arranged:
1 1 1 1 1 1 1 1 1 1 2 2 2 2
Bit 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| x |x | x x| = 0x20 0x80 0x41 (bits 2, 8, 17, and 23).
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Byte 0 1 2
*/
#define BitArray_MinBytes( ARRAY, N_BYTES ) memrlen( (ARRAY), (N_BYTES) )
#define BitArray_MaxBytes( BITS ) ( ( (BITS) + 7 ) / 8 )
#define BitArray_MaxBits( ARRAY_BYTES ) ( (ARRAY_BYTES) * 8 )
#define BitArray_Clear( ARRAY_PTR, ARRAY_BYTES ) memset( (ARRAY_PTR), 0, (ARRAY_BYTES) );
#define BitArray_GetBit( PTR, LEN, BIT ) \
( ( (BIT) < BitArray_MaxBits( (LEN) ) ) && ( (PTR)[ (BIT) / 8 ] & ( 1 << ( 7 - ( (BIT) & 7 ) ) ) ) )
#define BitArray_SetBit( ARRAY, BIT ) ( (ARRAY)[ (BIT) / 8 ] |= ( 1 << ( 7 - ( (BIT) & 7 ) ) ) )
#define BitArray_ClearBit( ARRAY, BIT ) ( (ARRAY)[ (BIT) / 8 ] &= ~( 1 << ( 7 - ( (BIT) & 7 ) ) ) )
//---------------------------------------------------------------------------------------------------------------------------
/*! @group BitRotates
@abstract Rotates X COUNT bits to the left or right.
*/
#define ROTL( X, N, SIZE ) ( ( (X) << (N) ) | ( (X) >> ( (SIZE) - N ) ) )
#define ROTR( X, N, SIZE ) ( ( (X) >> (N) ) | ( (X) << ( (SIZE) - N ) ) )
#define ROTL32( X, N ) ROTL( (X), (N), 32 )
#define ROTR32( X, N ) ROTR( (X), (N), 32 )
#define ROTL64( X, N ) ROTL( (X), (N), 64 )
#define ROTR64( X, N ) ROTR( (X), (N), 64 )
#define RotateBitsLeft( X, N ) ROTL( (X), (N), sizeof( (X) ) * 8 )
#define RotateBitsRight( X, N ) ROTR( (X), (N), sizeof( (X) ) * 8 )
// ==== Macros for minimum-width integer constants ====
#if( !defined( INT8_C ) )
#define INT8_C( value ) value
#endif
#if( !defined( INT16_C ) )
#define INT16_C( value ) value
#endif
#if( !defined( INT32_C ) )
#define INT32_C( value ) value
#endif
#define INT64_C_safe( value ) INT64_C( value )
#if( !defined( INT64_C ) )
#if( defined( _MSC_VER ) )
#define INT64_C( value ) value ## i64
#else
#define INT64_C( value ) value ## LL
#endif
#endif
#define UINT8_C_safe( value ) UINT8_C( value )
#if( !defined( UINT8_C ) )
#define UINT8_C( value ) value ## U
#endif
#define UINT16_C_safe( value ) UINT16_C( value )
#if( !defined( UINT16_C ) )
#define UINT16_C( value ) value ## U
#endif
#define UINT32_C_safe( value ) UINT32_C( value )
#if( !defined( UINT32_C ) )
#define UINT32_C( value ) value ## U
#endif
#define UINT64_C_safe( value ) UINT64_C( value )
#if( !defined( UINT64_C ) )
#if( defined( _MSC_VER ) )
#define UINT64_C( value ) value ## UI64
#else
#define UINT64_C( value ) value ## ULL
#endif
#endif
// ==== SOCKET MACROS ====
#define IsValidSocket( X ) ( ( X ) >= 0 )
/* Suppress unused parameter warning */
#ifndef UNUSED_PARAMETER
#define UNUSED_PARAMETER(x) ( (void)(x) )
#endif
/* Suppress unused variable warning */
#ifndef UNUSED_VARIABLE
#define UNUSED_VARIABLE(x) ( (void)(x) )
#endif
/* Suppress unused variable warning occurring due to an assert which is disabled in release mode */
#ifndef REFERENCE_DEBUG_ONLY_VARIABLE
#define REFERENCE_DEBUG_ONLY_VARIABLE(x) ( (void)(x) )
#endif
#ifdef __cplusplus
}
#endif
#ifdef MICO_ENABLE_MALLOC_DEBUG
#include "malloc_debug.h"
extern void malloc_print_mallocs ( void );
#else
#define calloc_named( name, nelems, elemsize) calloc ( nelems, elemsize )
#define calloc_named_hideleak( name, nelems, elemsize ) calloc ( nelems, elemsize )
#define realloc_named( name, ptr, size ) realloc( ptr, size )
#define malloc_named( name, size ) malloc ( size )
#define malloc_named_hideleak( name, size ) malloc ( size )
#define malloc_set_name( name )
#define malloc_leak_set_ignored( global_flag )
#define malloc_leak_set_base( global_flag )
#define malloc_leak_check( thread, global_flag )
#define malloc_transfer_to_curr_thread( block )
#define malloc_transfer_to_thread( block, thread )
#define malloc_print_mallocs( void )
#define malloc_debug_startup_finished( )
#endif /* ifdef MICO_ENABLE_MALLOC_DEBUG */
/**
******************************************************************************
* Convert a nibble into a hex character
*
* @param[in] nibble The value of the nibble in the lower 4 bits
*
* @return The hex character corresponding to the nibble
*/
static inline ALWAYS_INLINE char nibble_to_hexchar( uint8_t nibble )
{
if (nibble > 9)
{
return (char)('A' + (nibble - 10));
}
else
{
return (char) ('0' + nibble);
}
}
/**
******************************************************************************
* Convert a nibble into a hex character
*
* @param[in] nibble The value of the nibble in the lower 4 bits
*
* @return The hex character corresponding to the nibble
*/
static inline ALWAYS_INLINE char hexchar_to_nibble( char hexchar, uint8_t* nibble )
{
if ( ( hexchar >= '0' ) && ( hexchar <= '9' ) )
{
*nibble = (uint8_t)( hexchar - '0' );
return 0;
}
else if ( ( hexchar >= 'A' ) && ( hexchar <= 'F' ) )
{
*nibble = (uint8_t) ( hexchar - 'A' + 10 );
return 0;
}
else if ( ( hexchar >= 'a' ) && ( hexchar <= 'f' ) )
{
*nibble = (uint8_t) ( hexchar - 'a' + 10 );
return 0;
}
return -1;
}
#endif // __Common_h__

View file

@ -0,0 +1,546 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef __Debug_h__
#define __Debug_h__
#ifndef MICO_PREBUILT_LIBS
#include "platform.h"
#include "platform_config.h"
#endif
#include "mico_rtos.h"
#include "platform_assert.h"
// ==== LOGGING ====
#ifdef __GNUC__
#define SHORT_FILE __FILENAME__
#else
#define SHORT_FILE strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__
#endif
#define YesOrNo(x) (x ? "YES" : "NO")
#ifdef DEBUG
#ifndef MICO_DISABLE_STDIO
#ifndef NO_MICO_RTOS
extern int mico_debug_enabled;
extern mico_mutex_t stdio_tx_mutex;
#define custom_log(N, M, ...) do {if (mico_debug_enabled==0)break;\
mico_rtos_lock_mutex( &stdio_tx_mutex );\
printf("[%ld][%s: %s:%4d] " M "\r\n", mico_rtos_get_time(), N, SHORT_FILE, __LINE__, ##__VA_ARGS__);\
mico_rtos_unlock_mutex( &stdio_tx_mutex );}while(0==1)
#ifndef MICO_ASSERT_INFO_DISABLE
#define debug_print_assert(A,B,C,D,E,F) do {if (mico_debug_enabled==0)break;\
mico_rtos_lock_mutex( &stdio_tx_mutex );\
printf("[%ld][MICO:%s:%s:%4d] **ASSERT** %s""\r\n", mico_rtos_get_time(), D, F, E, (C!=NULL) ? C : "" );\
mico_rtos_unlock_mutex( &stdio_tx_mutex );}while(0==1)
#else // !MICO_ASSERT_INFO_ENABLE
#define debug_print_assert(A,B,C,D,E,F)
#endif // MICO_ASSERT_INFO_ENABLE
#ifdef TRACE
#define custom_log_trace(N) do {if (mico_debug_enabled==0)break;\
mico_rtos_lock_mutex( &stdio_tx_mutex );\
printf("[%s: [TRACE] %s] %s()\r\n", N, SHORT_FILE, __PRETTY_FUNCTION__);\
mico_rtos_unlock_mutex( &stdio_tx_mutex );}while(0==1)
#else // !TRACE
#define custom_log_trace(N)
#endif // TRACE
#else // NO_MICO_RTOS
#define custom_log(N, M, ...) do {printf("[%s: %s:%4d] " M "\r\n", N, SHORT_FILE, __LINE__, ##__VA_ARGS__);}while(0==1)
#ifndef MICO_ASSERT_INFO_DISABLE
#define debug_print_assert(A,B,C,D,E,F) do {printf("[MICO:%s:%s:%4d] **ASSERT** %s""\r\n", D, F, E, (C!=NULL) ? C : "" );}while(0==1)
#else
#define debug_print_assert(A,B,C,D,E,F)
#endif
#ifdef TRACE
#define custom_log_trace(N) do {printf("[%s: [TRACE] %s] %s()\r\n", N, SHORT_FILE, __PRETTY_FUNCTION__);}while(0==1)
#else // !TRACE
#define custom_log_trace(N)
#endif // TRACE
#endif
#else
#define custom_log(N, M, ...)
#define custom_log_trace(N)
#define debug_print_assert(A,B,C,D,E,F)
#endif //MICO_DISABLE_STDIO
#else // DEBUG = 0
// IF !DEBUG, make the logs NO-OP
#define custom_log(N, M, ...)
#define custom_log_trace(N)
#define debug_print_assert(A,B,C,D,E,F)
#endif // DEBUG
// ==== PLATFORM TIMEING FUNCTIONS ====
#ifdef TIME_PLATFORM
#define function_timer_log(M, N, ...) fprintf(stderr, "[FUNCTION TIMER: " N "()] " M "\n", ##__VA_ARGS__)
#define TIMEPLATFORM( FUNC, FUNC_NAME ) \
do \
{ \
struct timespec startTime; \
clock_gettime(CLOCK_MONOTONIC, &startTime); \
{ FUNC; } \
struct timespec endTime; \
clock_gettime(CLOCK_MONOTONIC, &endTime); \
struct timespec timeDiff = TimeDifference( startTime, endTime ); \
function_timer_log("%lld us", \
FUNC_NAME, \
ElapsedTimeInMicroseconds( timeDiff )); \
} \
while( 1==0 )
#else
#define function_timer_log(M, N, ...)
#define TIMEPLATFORM( FUNC, FUNC_NAME ) \
do \
{ \
{ FUNC; } \
} \
while( 1==0 )
#endif
// ==== BRANCH PREDICTION & EXPRESSION EVALUATION ====
#if( !defined( unlikely ) )
//#define unlikely( EXPRESSSION ) __builtin_expect( !!(EXPRESSSION), 0 )
#define unlikely( EXPRESSSION ) !!(EXPRESSSION)
#endif
//---------------------------------------------------------------------------------------------------------------------------
/*! @defined check
@abstract Check that an expression is true (non-zero).
@discussion
If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
function name, etc.) using the default debugging output method.
Code inside check() statements is not compiled into production builds.
*/
#if( !defined( check ) )
#define check( X ) \
do \
{ \
if( unlikely( !(X) ) ) \
{ \
debug_print_assert( 0, #X, NULL, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
} \
\
} while( 1==0 )
#endif
//---------------------------------------------------------------------------------------------------------------------------
/*! @defined check_string
@abstract Check that an expression is true (non-zero) with an explanation.
@discussion
If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
function name, etc.) using the default debugging output method.
Code inside check() statements is not compiled into production builds.
*/
#if( !defined( check_string ) )
#define check_string( X, STR ) \
do \
{ \
if( unlikely( !(X) ) ) \
{ \
debug_print_assert( 0, #X, STR, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
MICO_ASSERTION_FAIL_ACTION(); \
} \
\
} while( 1==0 )
#endif
//---------------------------------------------------------------------------------------------------------------------------
/*! @defined require
@abstract Requires that an expression evaluate to true.
@discussion
If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
function name, etc.) using the default debugging output method then jumps to a label.
*/
#if( !defined( require ) )
#define require( X, LABEL ) \
do \
{ \
if( unlikely( !(X) ) ) \
{ \
debug_print_assert( 0, #X, NULL, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
goto LABEL; \
} \
\
} while( 1==0 )
#endif
//---------------------------------------------------------------------------------------------------------------------------
/*! @defined require_string
@abstract Requires that an expression evaluate to true with an explanation.
@discussion
If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
function name, etc.) and a custom explanation string using the default debugging output method then jumps to a label.
*/
#if( !defined( require_string ) )
#define require_string( X, LABEL, STR ) \
do \
{ \
if( unlikely( !(X) ) ) \
{ \
debug_print_assert( 0, #X, STR, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
goto LABEL; \
} \
\
} while( 1==0 )
#endif
//---------------------------------------------------------------------------------------------------------------------------
/*! @defined require_quiet
@abstract Requires that an expression evaluate to true.
@discussion
If expression evalulates to false, this jumps to a label. No debugging information is printed.
*/
#if( !defined( require_quiet ) )
#define require_quiet( X, LABEL ) \
do \
{ \
if( unlikely( !(X) ) ) \
{ \
goto LABEL; \
} \
\
} while( 1==0 )
#endif
//---------------------------------------------------------------------------------------------------------------------------
/*! @defined require_noerr
@abstract Require that an error code is noErr (0).
@discussion
If the error code is non-0, this prints debugging information (actual expression string, file, line number,
function name, etc.) using the default debugging output method then jumps to a label.
*/
#if( !defined( require_noerr ) )
#define require_noerr( ERR, LABEL ) \
do \
{ \
OSStatus localErr; \
\
localErr = (OSStatus)(ERR); \
if( unlikely( localErr != 0 ) ) \
{ \
debug_print_assert( localErr, NULL, NULL, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
goto LABEL; \
} \
\
} while( 1==0 )
#endif
//---------------------------------------------------------------------------------------------------------------------------
/*! @defined require_noerr_string
@abstract Require that an error code is noErr (0).
@discussion
If the error code is non-0, this prints debugging information (actual expression string, file, line number,
function name, etc.), and a custom explanation string using the default debugging output method using the
default debugging output method then jumps to a label.
*/
#if( !defined( require_noerr_string ) )
#define require_noerr_string( ERR, LABEL, STR ) \
do \
{ \
OSStatus localErr; \
\
localErr = (OSStatus)(ERR); \
if( unlikely( localErr != 0 ) ) \
{ \
debug_print_assert( localErr, NULL, STR, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
goto LABEL; \
} \
\
} while( 1==0 )
#endif
//---------------------------------------------------------------------------------------------------------------------------
/*! @defined require_noerr_action_string
@abstract Require that an error code is noErr (0).
@discussion
If the error code is non-0, this prints debugging information (actual expression string, file, line number,
function name, etc.), and a custom explanation string using the default debugging output method using the
default debugging output method then executes an action and jumps to a label.
*/
#if( !defined( require_noerr_action_string ) )
#define require_noerr_action_string( ERR, LABEL, ACTION, STR ) \
do \
{ \
OSStatus localErr; \
\
localErr = (OSStatus)(ERR); \
if( unlikely( localErr != 0 ) ) \
{ \
debug_print_assert( localErr, NULL, STR, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
{ ACTION; } \
goto LABEL; \
} \
\
} while( 1==0 )
#endif
//---------------------------------------------------------------------------------------------------------------------------
/*! @defined require_noerr_quiet
@abstract Require that an error code is noErr (0).
@discussion
If the error code is non-0, this jumps to a label. No debugging information is printed.
*/
#if( !defined( require_noerr_quiet ) )
#define require_noerr_quiet( ERR, LABEL ) \
do \
{ \
if( unlikely( (ERR) != 0 ) ) \
{ \
goto LABEL; \
} \
\
} while( 1==0 )
#endif
//---------------------------------------------------------------------------------------------------------------------------
/*! @defined require_noerr_action
@abstract Require that an error code is noErr (0) with an action to execute otherwise.
@discussion
If the error code is non-0, this prints debugging information (actual expression string, file, line number,
function name, etc.) using the default debugging output method then executes an action and jumps to a label.
*/
#if( !defined( require_noerr_action ) )
#define require_noerr_action( ERR, LABEL, ACTION ) \
do \
{ \
OSStatus localErr; \
\
localErr = (OSStatus)(ERR); \
if( unlikely( localErr != 0 ) ) \
{ \
debug_print_assert( localErr, NULL, NULL, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
{ ACTION; } \
goto LABEL; \
} \
\
} while( 1==0 )
#endif
//---------------------------------------------------------------------------------------------------------------------------
/*! @defined require_noerr_action_quiet
@abstract Require that an error code is noErr (0) with an action to execute otherwise.
@discussion
If the error code is non-0, this executes an action and jumps to a label. No debugging information is printed.
*/
#if( !defined( require_noerr_action_quiet ) )
#define require_noerr_action_quiet( ERR, LABEL, ACTION ) \
do \
{ \
if( unlikely( (ERR) != 0 ) ) \
{ \
{ ACTION; } \
goto LABEL; \
} \
\
} while( 1==0 )
#endif
//---------------------------------------------------------------------------------------------------------------------------
/*! @defined require_action
@abstract Requires that an expression evaluate to true with an action to execute otherwise.
@discussion
If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
function name, etc.) using the default debugging output method then executes an action and jumps to a label.
*/
#if( !defined( require_action ) )
#define require_action( X, LABEL, ACTION ) \
do \
{ \
if( unlikely( !(X) ) ) \
{ \
debug_print_assert( 0, #X, NULL, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
{ ACTION; } \
goto LABEL; \
} \
\
} while( 1==0 )
#endif
//---------------------------------------------------------------------------------------------------------------------------
/*! @defined require_action_string
@abstract Requires that an expression evaluate to true with an explanation and action to execute otherwise.
@discussion
If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
function name, etc.) and a custom explanation string using the default debugging output method then executes an
action and jumps to a label.
*/
#if( !defined( require_action_string ) )
#define require_action_string( X, LABEL, ACTION, STR ) \
do \
{ \
if( unlikely( !(X) ) ) \
{ \
debug_print_assert( 0, #X, STR, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
{ ACTION; } \
goto LABEL; \
} \
\
} while( 1==0 )
#endif
//---------------------------------------------------------------------------------------------------------------------------
/*! @defined require_action_quiet
@abstract Requires that an expression evaluate to true with an action to execute otherwise.
@discussion
If expression evalulates to false, this executes an action and jumps to a label. No debugging information is printed.
*/
#if( !defined( require_action_quiet ) )
#define require_action_quiet( X, LABEL, ACTION ) \
do \
{ \
if( unlikely( !(X) ) ) \
{ \
{ ACTION; } \
goto LABEL; \
} \
\
} while( 1==0 )
#endif
// ==== ERROR MAPPING ====
#define global_value_errno( VALUE ) ( errno ? errno : kUnknownErr )
#define map_global_value_errno( TEST, VALUE ) ( (TEST) ? 0 : global_value_errno(VALUE) )
#define map_global_noerr_errno( ERR ) ( !(ERR) ? 0 : global_value_errno(ERR) )
#define map_fd_creation_errno( FD ) ( IsValidFD( FD ) ? 0 : global_value_errno( FD ) )
#define map_noerr_errno( ERR ) map_global_noerr_errno( (ERR) )
#define socket_errno( SOCK ) ( errno ? errno : kUnknownErr )
#define socket_value_errno( SOCK, VALUE ) socket_errno( SOCK )
#define map_socket_value_errno( SOCK, TEST, VALUE ) ( (TEST) ? 0 : socket_value_errno( (SOCK), (VALUE) ) )
#define map_socket_noerr_errno( SOCK, ERR ) ( !(ERR) ? 0 : socket_errno( (SOCK) ) )
//---------------------------------------------------------------------------------------------------------------------------
/*! @defined check_ptr_overlap
@abstract Checks that two ptrs do not overlap.
*/
#define check_ptr_overlap( P1, P1_SIZE, P2, P2_SIZE ) \
do \
{ \
check( !( ( (uintptr_t)(P1) >= (uintptr_t)(P2) ) && \
( (uintptr_t)(P1) < ( ( (uintptr_t)(P2) ) + (P2_SIZE) ) ) ) ); \
check( !( ( (uintptr_t)(P2) >= (uintptr_t)(P1) ) && \
( (uintptr_t)(P2) < ( ( (uintptr_t)(P1) ) + (P1_SIZE) ) ) ) ); \
\
} while( 1==0 )
#define IsValidFD( X ) ( ( X ) >= 0 )
//------------------------------------------Memory debug------------------------------------------------------------------
typedef struct
{
int num_of_chunks; /**< number of free chunks*/
int total_memory; /**< maximum total allocated space*/
int allocted_memory; /**< total allocated space*/
int free_memory; /**< total free space*/
} micoMemInfo_t;
#define MicoGetMemoryInfo mico_memory_info
/**
* @brief Get memory usage information
*
* @param None
*
* @return Point to structure of memory usage information in heap
*/
micoMemInfo_t* MicoGetMemoryInfo( void );
//---------------------------------------------------------------------------------------------------------------------------
#ifdef DEBUG
#include "platform_assert.h"
#define MICO_BREAK_IF_DEBUG( ) MICO_ASSERTION_FAIL_ACTION()
#else
#define MICO_BREAK_IF_DEBUG( )
#endif
#ifdef PRINT_PLATFORM_PERMISSION
int platform_wprint_permission(void);
#define PRINT_PLATFORM_PERMISSION_FUNC() platform_print_permission()
#else
#ifdef DEBUG
#define PRINT_PLATFORM_PERMISSION_FUNC() 1
#else
#define PRINT_PLATFORM_PERMISSION_FUNC() 0
#endif
#endif
/******************************************************
* Print declarations
******************************************************/
#define PRINT_ENABLE_LIB_INFO
#define PRINT_ENABLE_LIB_DEBUG
#define PRINT_ENABLE_LIB_ERROR
#define PRINT_MACRO(args) do {if (PRINT_PLATFORM_PERMISSION_FUNC()) printf args;} while(0==1)
/* printing macros for general SDK/Library functions*/
#ifdef PRINT_ENABLE_LIB_INFO
#define WPRINT_LIB_INFO(args) PRINT_MACRO(args)
#else
#define WPRINT_LIB_INFO(args)
#endif
#ifdef PRINT_ENABLE_LIB_DEBUG
#define WPRINT_LIB_DEBUG(args) PRINT_MACRO(args)
#else
#define WPRINT_LIB_DEBUG(args)
#endif
#ifdef PRINT_ENABLE_LIB_ERROR
#define WPRINT_LIB_ERROR(args) { PRINT_MACRO(args); MICO_BREAK_IF_DEBUG(); }
#else
#define WPRINT_LIB_ERROR(args) { MICO_BREAK_IF_DEBUG(); }
#endif
#endif // __Debug_h__

View file

@ -0,0 +1,111 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
/** @mainpage MICO
This documentation describes the MICO APIs.
It consists of:
- MICO Core APIs
- MICO Hardware Abstract Layer APIs
- MICO Algorithm APIs
- MICO System APIs
- MICO Middleware APIs
- MICO Drivers interface
*/
#ifndef __MICO_H_
#define __MICO_H_
/* MiCO SDK APIs */
#include "debug.h"
#include "common.h"
#include <hal/hal.h>
#include "mico_rtos.h"
//#include "mico_socket.h"
//#include "mico_security.h"
#include "mico_platform.h"
//#include "mico_system.h"
#define MicoGetRfVer wlan_driver_version
#define MicoGetVer system_lib_version
#define MicoInit mxchipInit
/** @defgroup MICO_Core_APIs MICO Core APIs
* @brief MiCO Initialization, RTOS, TCP/IP stack, and Network Management
*/
/** @addtogroup MICO_Core_APIs
* @{
*/
/** \defgroup MICO_Init_Info Initialization and Tools
* @brief Get MiCO version or RF version, flash usage information or init MiCO TCPIP stack
* @{
*/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Function Declarations
******************************************************/
/**
* @brief Get RF driver's version.
*
* @note Create a memery buffer to store the version characters.
* THe input buffer length should be 40 bytes at least.
* @note This must be executed after micoInit().
* @param inVersion: Buffer address to store the RF driver.
* @param inLength: Buffer size.
*
* @return int
*/
int MicoGetRfVer( char* outVersion, uint8_t inLength );
/**
* @brief Get MICO's version.
*
* @param None
*
* @return Point to the MICO's version string.
*/
char* MicoGetVer( void );
/**
* @brief Initialize the TCPIP stack thread, RF driver thread, and other
supporting threads needed for wlan connection. Do some necessary
initialization
*
* @param None
*
* @return kNoErr: success, kGeneralErr: fail
*/
OSStatus MicoInit( void );
/**
* @brief Get an identifier id from device, every id is unique and will not change in life-time
*
* @param identifier length
*
* @return Point to the identifier
*/
const uint8_t* mico_generate_cid( uint8_t *length );
#endif /* __MICO_H_ */
/**
* @}
*/
/**
* @}
*/

View file

@ -0,0 +1,168 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef __MICO_ERRNO_H__
#define __MICO_ERRNO_H__
#if defined (__GNUC__)
#include <errno.h>
#else
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Arg list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define EDEADLK 35 /* Resource deadlock would occur */
#define ENAMETOOLONG 36 /* File name too long */
#define ENOLCK 37 /* No record locks available */
#define ENOSYS 38 /* Function not implemented */
#define ENOTEMPTY 39 /* Directory not empty */
#define ELOOP 40 /* Too many symbolic links encountered */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define ENOMSG 42 /* No message of desired type */
#define EIDRM 43 /* Identifier removed */
#define ECHRNG 44 /* Channel number out of range */
#define EL2NSYNC 45 /* Level 2 not synchronized */
#define EL3HLT 46 /* Level 3 halted */
#define EL3RST 47 /* Level 3 reset */
#define ELNRNG 48 /* Link number out of range */
#define EUNATCH 49 /* Protocol driver not attached */
#define ENOCSI 50 /* No CSI structure available */
#define EL2HLT 51 /* Level 2 halted */
#define EBADE 52 /* Invalid exchange */
#define EBADR 53 /* Invalid request descriptor */
#define EXFULL 54 /* Exchange full */
#define ENOANO 55 /* No anode */
#define EBADRQC 56 /* Invalid request code */
#define EBADSLT 57 /* Invalid slot */
#define EDEADLOCK EDEADLK
#define EBFONT 59 /* Bad font file format */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data available */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* Object is remote */
#define ENOLINK 67 /* Link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 72 /* Multihop attempted */
#define EDOTDOT 73 /* RFS specific error */
#define EBADMSG 74 /* Not a data message */
#define EOVERFLOW 75 /* Value too large for defined data type */
#define ENOTUNIQ 76 /* Name not unique on network */
#define EBADFD 77 /* File descriptor in bad state */
#define EREMCHG 78 /* Remote address changed */
#define ELIBACC 79 /* Can not access a needed shared library */
#define ELIBBAD 80 /* Accessing a corrupted shared library */
#define ELIBSCN 81 /* .lib section in a.out corrupted */
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#define EILSEQ 84 /* Illegal byte sequence */
#define ERESTART 85 /* Interrupted system call should be restarted */
#define ESTRPIPE 86 /* Streams pipe error */
#define EUSERS 87 /* Too many users */
#define ENOTSOCK 88 /* Socket operation on non-socket */
#define EDESTADDRREQ 89 /* Destination address required */
#define EMSGSIZE 90 /* Message too long */
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
#define ENOPROTOOPT 92 /* Protocol not available */
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define EADDRINUSE 98 /* Address already in use */
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
#define ENETDOWN 100 /* Network is down */
#define ENETUNREACH 101 /* Network is unreachable */
#define ENETRESET 102 /* Network dropped connection because of reset */
#define ECONNABORTED 103 /* Software caused connection abort */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EISCONN 106 /* Transport endpoint is already connected */
#define ENOTCONN 107 /* Transport endpoint is not connected */
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#define ETIMEDOUT 110 /* Connection timed out */
#define ECONNREFUSED 111 /* Connection refused */
#define EHOSTDOWN 112 /* Host is down */
#define EHOSTUNREACH 113 /* No route to host */
#define EALREADY 114 /* Operation already in progress */
#define EINPROGRESS 115 /* Operation now in progress */
#define ESTALE 116 /* Stale NFS file handle */
#define EUCLEAN 117 /* Structure needs cleaning */
#define ENOTNAM 118 /* Not a XENIX named type file */
#define ENAVAIL 119 /* No XENIX semaphores available */
#define EISNAM 120 /* Is a named type file */
#define EREMOTEIO 121 /* Remote I/O error */
#define EDQUOT 122 /* Quota exceeded */
#define ENOMEDIUM 123 /* No medium found */
#define EMEDIUMTYPE 124 /* Wrong medium type */
#define ENSROK 0 /* DNS server returned answer with no data */
#define ENSRNODATA 160 /* DNS server returned answer with no data */
#define ENSRFORMERR 161 /* DNS server claims query was misformatted */
#define ENSRSERVFAIL 162 /* DNS server returned general failure */
#define ENSRNOTFOUND 163 /* Domain name not found */
#define ENSRNOTIMP 164 /* DNS server does not implement requested operation */
#define ENSRREFUSED 165 /* DNS server refused query */
#define ENSRBADQUERY 166 /* Misformatted DNS query */
#define ENSRBADNAME 167 /* Misformatted domain name */
#define ENSRBADFAMILY 168 /* Unsupported address family */
#define ENSRBADRESP 169 /* Misformatted DNS reply */
#define ENSRCONNREFUSED 170 /* Could not contact DNS servers */
#define ENSRTIMEOUT 171 /* Timeout while contacting DNS servers */
#define ENSROF 172 /* End of file */
#define ENSRFILE 173 /* Error reading file */
#define ENSRNOMEM 174 /* Out of memory */
#define ENSRDESTRUCTION 175 /* Application terminated lookup */
#define ENSRQUERYDOMAINTOOLONG 176 /* Domain name is too long */
#define ENSRCNAMELOOP 177 /* Domain name is too long */
#endif
#undef errno
extern int errno;
#endif //__MICO_ERRNO_H__

View file

@ -0,0 +1,159 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#pragma once
#ifndef __MICOPLATFORM_H__
#define __MICOPLATFORM_H__
#include "common.h"
//#include "platform.h" /* This file is unique for each platform */
#include "platform_peripheral.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef platform_spi_slave_config_t mico_spi_slave_config_t;
typedef platform_spi_slave_transfer_direction_t mico_spi_slave_transfer_direction_t;
typedef platform_spi_slave_transfer_status_t mico_spi_slave_transfer_status_t;
typedef platform_spi_slave_command_t mico_spi_slave_command_t;
typedef platform_spi_slave_data_buffer_t mico_spi_slave_data_buffer_t;
#if 0
#include "MiCODrivers/MiCODriverI2c.h"
#include "MiCODrivers/MiCODriverSpi.h"
#include "MiCODrivers/MiCODriverUart.h"
#include "MiCODrivers/MiCODriverGpio.h"
#include "MiCODrivers/MiCODriverPwm.h"
#include "MiCODrivers/MiCODriverRtc.h"
#include "MiCODrivers/MiCODriverWdg.h"
#include "MiCODrivers/MiCODriverAdc.h"
#include "MiCODrivers/MiCODriverRng.h"
#include "MiCODrivers/MiCODriverFlash.h"
#include "MiCODrivers/MiCODriverMFiAuth.h"
#endif
#define mico_mcu_powersave_config MicoMcuPowerSaveConfig
/** @defgroup MICO_PLATFORM MICO Hardware Abstract Layer APIs
* @brief Control hardware peripherals on different platfroms using standard HAL API functions
*
*/
/** @addtogroup MICO_PLATFORM
* @{
*/
/** @defgroup platform_misc Task switching, reboot, and standby
* @brief Provide task switching,reboot and standby functions
* @{
*/
#define ENABLE_INTERRUPTS __asm("CPSIE i") /**< Enable interrupts to start task switching in MICO RTOS. */
#define DISABLE_INTERRUPTS __asm("CPSID i") /**< Disable interrupts to stop task switching in MICO RTOS. */
/** @brief Software reboot the MICO hardware
*
* @param none
* @return none
*/
void MicoSystemReboot(void);
/** @brief Software reboot the MICO hardware
*
* @param timeToWakeup: MICO will wakeup after secondsToWakeup (seconds)
* @return none
*/
void MicoSystemStandBy(uint32_t secondsToWakeup);
/** @brief Enables the MCU to enter deep sleep mode when all threads are suspended.
*
* @note: When all threads are suspended, mcu can shut down some peripherals to
* save power. For example, STM32 enters STOP mode in this condition,
* its peripherals are not working and needs to be wake up by an external
* interrupt or MICO core's internal timer. So if you are using a peripherals,
* you should disable this function temporarily.
* To make this function works, you should not disable the macro in MicoDefault.h:
* MICO_DISABLE_MCU_POWERSAVE
*
* @param enable : 1 = enable MCU powersave, 0 = disable MCU powersave
* @return none
*/
void MicoMcuPowerSaveConfig( int enable );
/** @brief Set MiCO system led on/off state
*
* @param onff: State of syetem LED,0: OFF,1:ON
* @return none
*/
void MicoSysLed(bool onoff);
/** @brief Set MiCO RF led on/off state
*
* @param onff: State of RF LED,0: OFF,1:ON
* @return none
*/
void MicoRfLed(bool onoff);
/** @brief add
*
* @param add
* @return none
*/
bool MicoShouldEnterMFGMode(void);
/** @brief add
*
* @param add
* @return none
*/
bool MicoShouldEnterATEMode(void);
/** @brief add
*
* @param add
* @return none
*/
bool MicoShouldEnterBootloader(void);
/** @brief add
*
* @param add
* @return none
*/
char *mico_get_bootloader_ver(void);
#ifdef BOOTLOADER
void mico_set_bootload_ver(void);
#endif
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
} /*extern "C" */
#endif
#endif

View file

@ -0,0 +1,654 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef __MICORTOS_H__
#define __MICORTOS_H__
#include "common.h"
/** @addtogroup MICO_Core_APIs
* @{
*/
/** @defgroup MICO_RTOS MICO RTOS Operations
* @brief Provide management APIs for Thread, Mutex, Timer, Semaphore and FIFO
* @{
*/
#define MICO_HARDWARE_IO_WORKER_THREAD ( (mico_worker_thread_t*)&mico_hardware_io_worker_thread)
#define MICO_NETWORKING_WORKER_THREAD ( (mico_worker_thread_t*)&mico_worker_thread )
#define MICO_WORKER_THREAD ( (mico_worker_thread_t*)&mico_worker_thread )
#define MICO_NETWORK_WORKER_PRIORITY (3)
#define MICO_DEFAULT_WORKER_PRIORITY (5)
#define MICO_DEFAULT_LIBRARY_PRIORITY (5)
#define MICO_APPLICATION_PRIORITY (7)
#define kNanosecondsPerSecond 1000000000UUL
#define kMicrosecondsPerSecond 1000000UL
#define kMillisecondsPerSecond 1000
#define MICO_NEVER_TIMEOUT (0xFFFFFFFF)
#define MICO_WAIT_FOREVER (0xFFFFFFFF)
#define MICO_NO_WAIT (0)
typedef enum
{
WAIT_FOR_ANY_EVENT,
WAIT_FOR_ALL_EVENTS,
} mico_event_flags_wait_option_t;
typedef uint32_t mico_event_flags_t;
typedef void * mico_semaphore_t;
typedef void * mico_mutex_t;
typedef void * mico_thread_t;
typedef void * mico_queue_t;
typedef void * mico_event_t;// MICO OS event: mico_semaphore_t, mico_mutex_t or mico_queue_t
typedef void (*timer_handler_t)( void* arg );
typedef OSStatus (*event_handler_t)( void* arg );
typedef struct
{
void * handle;
timer_handler_t function;
void * arg;
}mico_timer_t;
typedef struct
{
mico_thread_t thread;
mico_queue_t event_queue;
} mico_worker_thread_t;
typedef struct
{
event_handler_t function;
void* arg;
mico_timer_t timer;
mico_worker_thread_t* thread;
} mico_timed_event_t;
typedef uint32_t mico_thread_arg_t;
typedef void (*mico_thread_function_t)( mico_thread_arg_t arg );
extern mico_worker_thread_t mico_hardware_io_worker_thread;
extern mico_worker_thread_t mico_worker_thread;
/* Legacy definitions */
#define mico_thread_sleep mico_rtos_thread_sleep
#define mico_thread_msleep mico_rtos_thread_msleep
#define mico_rtos_init_timer mico_init_timer
#define mico_rtos_start_timer mico_start_timer
#define mico_rtos_stop_timer mico_stop_timer
#define mico_rtos_reload_timer mico_reload_timer
#define mico_rtos_deinit_timer mico_deinit_timer
#define mico_rtos_is_timer_running mico_is_timer_running
#define mico_rtos_init_event_fd mico_create_event_fd
#define mico_rtos_deinit_event_fd mico_delete_event_fd
#define mico_rtos_thread_msleep mico_rtos_delay_milliseconds
/** @addtogroup MICO_Core_APIs
* @{
*/
/** @defgroup MICO_RTOS MICO RTOS Operations
* @{
*/
/** @defgroup MICO_RTOS_COMMON MICO RTOS Common Functions
* @brief Provide Generic RTOS Functions.
* @{
*/
/**
* @}
*/
/** @defgroup MICO_RTOS_Thread MICO RTOS Thread Management Functions
* @brief Provide thread creation, delete, suspend, resume, and other RTOS management API
* @verbatim
* MICO thread priority table
*
* +----------+-----------------+
* | Priority | Thread |
* |----------|-----------------|
* | 0 | MICO | Highest priority
* | 1 | Network |
* | 2 | |
* | 3 | Network worker |
* | 4 | |
* | 5 | Default Library |
* | | Default worker |
* | 6 | |
* | 7 | Application |
* | 8 | |
* | 9 | Idle | Lowest priority
* +----------+-----------------+
* @endverbatim
* @{
*/
/** @brief Creates and starts a new thread
*
* @param thread : Pointer to variable that will receive the thread handle (can be null)
* @param priority : A priority number.
* @param name : a text name for the thread (can be null)
* @param function : the main thread function
* @param stack_size : stack size for this thread
* @param arg : argument which will be passed to thread function
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_create_thread( mico_thread_t* thread, uint8_t priority, const char* name, mico_thread_function_t function, uint32_t stack_size, mico_thread_arg_t arg );
/** @brief Deletes a terminated thread
*
* @param thread : the handle of the thread to delete, , NULL is the current thread
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_delete_thread( mico_thread_t* thread );
/** @brief Creates a worker thread
*
* Creates a worker thread
* A worker thread is a thread in whose context timed and asynchronous events
* execute.
*
* @param worker_thread : a pointer to the worker thread to be created
* @param priority : thread priority
* @param stack_size : thread's stack size in number of bytes
* @param event_queue_size : number of events can be pushed into the queue
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_create_worker_thread( mico_worker_thread_t* worker_thread, uint8_t priority, uint32_t stack_size, uint32_t event_queue_size );
/** @brief Deletes a worker thread
*
* @param worker_thread : a pointer to the worker thread to be created
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_delete_worker_thread( mico_worker_thread_t* worker_thread );
/** @brief Suspend a thread
*
* @param thread : the handle of the thread to suspend, NULL is the current thread
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
void mico_rtos_suspend_thread(mico_thread_t* thread);
/** @brief Suspend all other thread
*
* @param none
*
* @return none
*/
void mico_rtos_suspend_all_thread(void);
/** @brief Rresume all other thread
*
* @param none
*
* @return none
*/
long mico_rtos_resume_all_thread(void);
/** @brief Sleeps until another thread has terminated
*
* @Details Causes the current thread to sleep until the specified other thread
* has terminated. If the processor is heavily loaded with higher priority
* tasks, this thread may not wake until significantly after the thread termination.
*
* @param thread : the handle of the other thread which will terminate
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_thread_join( mico_thread_t* thread );
/** @brief Forcibly wakes another thread
*
* @Details Causes the specified thread to wake from suspension. This will usually
* cause an error or timeout in that thread, since the task it was waiting on
* is not complete.
*
* @param thread : the handle of the other thread which will be woken
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_thread_force_awake( mico_thread_t* thread );
/** @brief Checks if a thread is the current thread
*
* @Details Checks if a specified thread is the currently running thread
*
* @param thread : the handle of the other thread against which the current thread
* will be compared
*
* @return true : specified thread is the current thread
* @return false : specified thread is not currently running
*/
bool mico_rtos_is_current_thread( mico_thread_t* thread );
/** @brief Suspend current thread for a specific time
*
* @param num_ms : A time interval (Unit: millisecond)
*
* @return kNoErr.
*/
OSStatus mico_rtos_delay_milliseconds( uint32_t num_ms );
/** @brief Print Thread status into buffer
*
* @param buffer, point to buffer to store thread status
* @param length, length of the buffer
*
* @return none
*/
OSStatus mico_rtos_print_thread_status( char* buffer, int length );
/**
* @}
*/
/** @defgroup MICO_RTOS_SEM MICO RTOS Semaphore Functions
* @brief Provide management APIs for semaphore such as init,set,get and dinit.
* @{
*/
/** @brief Initialises a counting semaphore and set count to 0
*
* @param semaphore : a pointer to the semaphore handle to be initialised
* @param count : the max count number of this semaphore
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_init_semaphore( mico_semaphore_t* semaphore, int count );
/** @brief Set (post/put/increment) a semaphore
*
* @param semaphore : a pointer to the semaphore handle to be set
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_set_semaphore( mico_semaphore_t* semaphore );
/** @brief Get (wait/decrement) a semaphore
*
* @Details Attempts to get (wait/decrement) a semaphore. If semaphore is at zero already,
* then the calling thread will be suspended until another thread sets the
* semaphore with @ref mico_rtos_set_semaphore
*
* @param semaphore : a pointer to the semaphore handle
* @param timeout_ms: the number of milliseconds to wait before returning
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_get_semaphore( mico_semaphore_t* semaphore, uint32_t timeout_ms );
/** @brief De-initialise a semaphore
*
* @Details Deletes a semaphore created with @ref mico_rtos_init_semaphore
*
* @param semaphore : a pointer to the semaphore handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_deinit_semaphore( mico_semaphore_t* semaphore );
/**
* @}
*/
/** @defgroup MICO_RTOS_MUTEX MICO RTOS Mutex Functions
* @brief Provide management APIs for Mutex such as init,lock,unlock and dinit.
* @{
*/
/** @brief Initialises a mutex
*
* @Details A mutex is different to a semaphore in that a thread that already holds
* the lock on the mutex can request the lock again (nested) without causing
* it to be suspended.
*
* @param mutex : a pointer to the mutex handle to be initialised
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_init_mutex( mico_mutex_t* mutex );
/** @brief Obtains the lock on a mutex
*
* @Details Attempts to obtain the lock on a mutex. If the lock is already held
* by another thead, the calling thread will be suspended until the mutex
* lock is released by the other thread.
*
* @param mutex : a pointer to the mutex handle to be locked
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_lock_mutex( mico_mutex_t* mutex );
/** @brief Releases the lock on a mutex
*
* @Details Releases a currently held lock on a mutex. If another thread
* is waiting on the mutex lock, then it will be resumed.
*
* @param mutex : a pointer to the mutex handle to be unlocked
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_unlock_mutex( mico_mutex_t* mutex );
/** @brief De-initialise a mutex
*
* @Details Deletes a mutex created with @ref mico_rtos_init_mutex
*
* @param mutex : a pointer to the mutex handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_deinit_mutex( mico_mutex_t* mutex );
/**
* @}
*/
/** @defgroup MICO_RTOS_QUEUE MICO RTOS FIFO Queue Functions
* @brief Provide management APIs for FIFO such as init,push,pop and dinit.
* @{
*/
/** @brief Initialises a FIFO queue
*
* @param queue : a pointer to the queue handle to be initialised
* @param name : a text string name for the queue (NULL is allowed)
* @param message_size : size in bytes of objects that will be held in the queue
* @param number_of_messages : depth of the queue - i.e. max number of objects in the queue
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_init_queue( mico_queue_t* queue, const char* name, uint32_t message_size, uint32_t number_of_messages );
/** @brief Pushes an object onto a queue
*
* @param queue : a pointer to the queue handle
* @param message : the object to be added to the queue. Size is assumed to be
* the size specified in @ref mico_rtos_init_queue
* @param timeout_ms: the number of milliseconds to wait before returning
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error or timeout occurred
*/
OSStatus mico_rtos_push_to_queue( mico_queue_t* queue, void* message, uint32_t timeout_ms );
/** @brief Pops an object off a queue
*
* @param queue : a pointer to the queue handle
* @param message : pointer to a buffer that will receive the object being
* popped off the queue. Size is assumed to be
* the size specified in @ref mico_rtos_init_queue , hence
* you must ensure the buffer is long enough or memory
* corruption will result
* @param timeout_ms: the number of milliseconds to wait before returning
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error or timeout occurred
*/
OSStatus mico_rtos_pop_from_queue( mico_queue_t* queue, void* message, uint32_t timeout_ms );
/** @brief De-initialise a queue created with @ref mico_rtos_init_queue
*
* @param queue : a pointer to the queue handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_deinit_queue( mico_queue_t* queue );
/** @brief Check if a queue is empty
*
* @param queue : a pointer to the queue handle
*
* @return true : queue is empty.
* @return false : queue is not empty.
*/
bool mico_rtos_is_queue_empty( mico_queue_t* queue );
/** @brief Check if a queue is full
*
* @param queue : a pointer to the queue handle
*
* @return true : queue is empty.
* @return false : queue is not empty.
*/
bool mico_rtos_is_queue_full( mico_queue_t* queue );
/**
* @}
*/
/** @defgroup MICO_RTOS_EVENT MICO RTOS Event Functions
* @{
*/
/**
* @brief Sends an asynchronous event to the associated worker thread
*
* @param worker_thread :the worker thread in which context the callback should execute from
* @param function : the callback function to be called from the worker thread
* @param arg : the argument to be passed to the callback function
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_send_asynchronous_event( mico_worker_thread_t* worker_thread, event_handler_t function, void* arg );
/** Requests a function be called at a regular interval
*
* This function registers a function that will be called at a regular
* interval. Since this is based on the RTOS time-slice scheduling, the
* accuracy is not high, and is affected by processor load.
*
* @param event_object : pointer to a event handle which will be initialised
* @param worker_thread : pointer to the worker thread in whose context the
* callback function runs on
* @param function : the callback function that is to be called regularly
* @param time_ms : the time period between function calls in milliseconds
* @param arg : an argument that will be supplied to the function when
* it is called
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_register_timed_event( mico_timed_event_t* event_object, mico_worker_thread_t* worker_thread, event_handler_t function, uint32_t time_ms, void* arg );
/** Removes a request for a regular function execution
*
* This function de-registers a function that has previously been set-up
* with @ref mico_rtos_register_timed_event.
*
* @param event_object : the event handle used with @ref mico_rtos_register_timed_event
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_deregister_timed_event( mico_timed_event_t* event_object );
/**
* @}
*/
/** @defgroup MICO_RTOS_TIMER MICO RTOS Timer Functions
* @brief Provide management APIs for timer such as init,start,stop,reload and dinit.
* @{
*/
/**
* @brief Gets time in miiliseconds since RTOS start
*
* @note: Since this is only 32 bits, it will roll over every 49 days, 17 hours.
*
* @returns Time in milliseconds since RTOS started.
*/
uint32_t mico_rtos_get_time(void);
/**
* @brief Initialize a RTOS timer
*
* @note Timer does not start running until @ref mico_start_timer is called
*
* @param timer : a pointer to the timer handle to be initialised
* @param time_ms : Timer period in milliseconds
* @param function : the callback handler function that is called each time the
* timer expires
* @param arg : an argument that will be passed to the callback function
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_init_timer( mico_timer_t* timer, uint32_t time_ms, timer_handler_t function, void* arg );
/** @brief Starts a RTOS timer running
*
* @note Timer must have been previously initialised with @ref mico_rtos_init_timer
*
* @param timer : a pointer to the timer handle to start
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_start_timer( mico_timer_t* timer );
/** @brief Stops a running RTOS timer
*
* @note Timer must have been previously started with @ref mico_rtos_init_timer
*
* @param timer : a pointer to the timer handle to stop
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_stop_timer( mico_timer_t* timer );
/** @brief Reloads a RTOS timer that has expired
*
* @note This is usually called in the timer callback handler, to
* reschedule the timer for the next period.
*
* @param timer : a pointer to the timer handle to reload
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_reload_timer( mico_timer_t* timer );
/** @brief De-initialise a RTOS timer
*
* @note Deletes a RTOS timer created with @ref mico_rtos_init_timer
*
* @param timer : a pointer to the RTOS timer handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus mico_rtos_deinit_timer( mico_timer_t* timer );
/** @brief Check if an RTOS timer is running
*
* @param timer : a pointer to the RTOS timer handle
*
* @return true : if running.
* @return false : if not running
*/
bool mico_rtos_is_timer_running( mico_timer_t* timer );
int SetTimer(unsigned long ms, void (*psysTimerHandler)(void));
int SetTimer_uniq(unsigned long ms, void (*psysTimerHandler)(void));
int UnSetTimer(void (*psysTimerHandler)(void));
/** @brief Initialize an endpoint for a RTOS event, a file descriptor
* will be created, can be used for select
*
* @param event_handle : mico_semaphore_t, mico_mutex_t or mico_queue_t
*
* @retval On success, a file descriptor for RTOS event is returned.
* On error, -1 is returned.
*/
int mico_rtos_init_event_fd(mico_event_t event_handle);
/** @brief De-initialise an endpoint created from a RTOS event
*
* @param fd : file descriptor for RTOS event
*
* @retval 0 for success. On error, -1 is returned.
*/
int mico_rtos_deinit_event_fd(int fd);
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

View file

@ -0,0 +1,52 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
#define rtos_log(M, ...) custom_log("RTOS", M, ##__VA_ARGS__)
#define rtos_log_trace() custom_log_trace("RTOS")
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Global Variables
******************************************************/
/******************************************************
* Function Declarations
******************************************************/
/* MiCO <-> RTOS API */
extern OSStatus mico_rtos_init ( void );
extern OSStatus mico_rtos_deinit( void );
/* Entry point for user Application */
extern void application_start ( void );
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -0,0 +1,717 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#pragma once
#include "common.h"
#include "Curve25519/curve25519-donna.h"
#include "SHAUtils/sha.h"
#include "stdint.h"
#include "CheckSumUtils.h"
/** \defgroup MICO_Algorithm_APIs MICO Algorithm APIs
* @brief Provide commonly used Algorithm APIs
* @{
*/
/** @addtogroup MICO_Algorithm_APIs
* @{
*/
/** @defgroup MICO_Security_MD5 MICO MD5 Encryption
* @brief MiCO MD5 Encryption Function
* @{
*/
typedef unsigned char byte;
typedef unsigned short word16;
typedef unsigned int word32;
typedef unsigned long long word64;
/**
* @brief Constant data during MD5 Encryption
*/
enum {
MD5 = 0, /** hash type unique */
MD5_BLOCK_SIZE = 64,
MD5_DIGEST_SIZE = 16,
MD5_PAD_SIZE = 56
};
/**
* @brief MD5 Context definition
*/
typedef struct {
uint32_t state[4]; /** state (ABCD) */
uint32_t count[2]; /** number of bits, modulo 2^64 (lsb first) */
uint32_t buffer[64]; /** input buffer */
} md5_context;
/**
* @brief MD5 context setup
*
* @param ctx context to be initialized
*/
void InitMd5(md5_context *ctx);
/**
* @brief MD5 process buffer
*
* @param ctx MD5 context
* @param input buffer holding the data
* @param ilen length of the input data
*/
void Md5Update(md5_context *ctx, unsigned char *input, int ilen);
/**
* @brief MD5 final digest
*
* @param ctx MD5 context
* @param output MD5 checksum result
*/
void Md5Final(md5_context *ctx, unsigned char output[16]);
/**
* @}
*/
/** @defgroup MICO_Security_HAMC_MD5 MICO HMAC_MD5 Encryption
* @brief MiCO HMAC_MD5 Encryption Function
* @{
*/
/**
* @brief Constant data during HAMC_MD5 Encryption
*/
enum{
HMAC_BLOCK_SIZE = 64,
INNER_HASH_SIZE = 128,
};
/**
* @brief Hash union during HMAC_MD5 Encryption
*/
typedef union {
md5_context md5;
} Hash;
/**
* @brief Hmac digest during HMAC_MD5 Encription
*/
typedef struct Hmac {
Hash hash;
word32 ipad[HMAC_BLOCK_SIZE / sizeof(word32)]; /* same block size all*/
word32 opad[HMAC_BLOCK_SIZE / sizeof(word32)];
word32 innerHash[INNER_HASH_SIZE / sizeof(word32)]; /* max size */
byte macType; /* md5 */
byte innerHashKeyed; /* keyed flag */
} Hmac;
/**
* @brief HMAC_MD5 extend external key into a longer bit string
*
* @param hmac Hmac context
* @param type hash type(only include MD5)
* @param key key
* @param keysz length of key
* @retval None
*/
void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 keySz);
/**
* @brief HMAC_MD5 process buffer
*
* @param Hmac hmac context
* @param byte* buffer holding the input data
* @param inLen length of the input data.
* Note: The length is arbitrary.
* @retval None
*/
void HmacUpdate(Hmac* hmac, const byte* input, word32 inLen);
/**
* @brief HMAC Final Digest
*
* @param hmac Hmac context
* @param output buffer holding the output data
* @retval None
*/
void HmacFinal(Hmac* hmac, byte* output);
/**
* @}
*/
/** @defgroup MICO_Security_DES MICO DES Encryption Algorithm
* @brief MiCO DES Encryption and Decryption Function
* @{
*/
/**
* @brief Constant data during DES Encryption
*/
enum {
DES_ENC_TYPE = 2, /* cipher unique type */
DES3_ENC_TYPE = 3, /* cipher unique type */
DES_BLOCK_SIZE = 8,
DES_KS_SIZE = 32,
DES_ENCRYPTION = 0,
DES_DECRYPTION = 1
};
/**
* @brief Des context
*/
typedef struct Des {
word32 key[DES_KS_SIZE];
word32 reg[DES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */
word32 tmp[DES_BLOCK_SIZE / sizeof(word32)]; /* same */
} Des;
/**
* @brief Des3 context
*/
typedef struct Des3 {
word32 key[3][DES_KS_SIZE];
word32 reg[DES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */
word32 tmp[DES_BLOCK_SIZE / sizeof(word32)]; /* same */
} Des3;
/**
* @brief DES extend external key into a longer bit string
*
* @param des Des context
* @param key external key defined by user,the length must be 64 bits
* @param iv extension key defined by user,must be the same size with key
* @param dir Specify the process of encryption or decryption
* @retval None
*/
void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir);
/**
* @brief DES encryption process in Cbc mode
*
* @param des Des context
* @param output buffer to hold output - Cipher Text. It has the same size with input
* @param input buffer to hold input - Plain Text.
* Note: The size of input must be the multiple of DES_BLOCK_SIZE 64 bits
* @param sz size of input
* Note: input and output have the same size.
* @retval None
*/
/**
* @brief DES decryption process in Cbc mode
*
* @param des Des context
* @param output buffer to hold output - Plain Text.
* @param input buffer to hold input - Cipher Text.
* Note: The size of input - Cipher Text must be with 2^64 bits
* And it must be the multiple of DES_BLOCK_SIZE 8 bytes
* @param sz size of input
* Note: input and output have the same size.
* @retval None
*/
void Des_CbcDecrypt(Des* des, byte* output, const byte* input, word32 sz);
/**
* @brief DES3 extend external key into a longer bit string
*
* @param des Des3 context
* @param key external key defined by user,the length must be 192 bits<EFBFBD><EFBFBD>24 bytes<EFBFBD><EFBFBD>
* @param iv extension key defined by user,must be the same size with key
* @param dir Specify the process of encryption or decryption
* @retval None
*/
void Des3_SetKey(Des3* des, const byte* key, const byte* iv,int dir);
/**
* @brief DES3 encryption process in Cbc mode
*
* @param des Des3 context
* @param output buffer to hold output - Cipher Text. It has the same size with input
* @param input buffer to hold input - Plain Text.
* Note: The size of input must be the multiple of DES_BLOCK_SIZE 64 bits
* @param sz size of input
* Note: input and output have the same size.
* @retval None
*/
void Des3_CbcEncrypt(Des3* des, byte* output, const byte* input,word32 sz);
/**
* @brief DES3 decryption process in Cbc mode
*
* @param des Des3 context
* @param output buffer to hold output - Plain Text.
* @param input buffer to hold input - Cipher Text.
* Note: The size of input - Cipher Text must be with 2^64 bits
* And it must be the multiple of DES_BLOCK_SIZE 8 bytes
* @param sz size of input
* Note: input and output have the same size.
* @retval None
*/
void Des3_CbcDecrypt(Des3* des, byte* output, const byte* input,word32 sz);
/**
* @}
*/
/** @defgroup MICO_Security_AES MICO AES Encryption Algorytm
* @brief MiCO AES Encryption and Decryption Function
* @{
*/
/**
* @brief Constant data during AES Encription
*/
enum {
AES_ENC_TYPE = 1, /* cipher unique type */
AES_ENCRYPTION = 0,
AES_DECRYPTION = 1,
AES_BLOCK_SIZE = 16
};
/**
* @brief Aes context
*/
typedef struct Aes {
/* AESNI needs key first, rounds 2nd, not sure why yet */
word32 key[60];
word32 rounds;
word32 reg[AES_BLOCK_SIZE / sizeof(word32)];
word32 tmp[AES_BLOCK_SIZE / sizeof(word32)];
} Aes;
/**
* @brief AES extend external key into a longer bit string
*
* @param aes AES context
* @param key external key defined by user,must be 128 bits
* @param ilen size of AES_BLOCK_SIZE
* @param iv extension key defined by user,must be the same size with key
* @param dir Specify the process of encryption or decryption
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
int AesSetKey(Aes* aes, const byte* key, word32 ilen, const byte* iv,int dir);
/**
* @brief AES encryption process in Cbc mode
*
* @param aes AES context
* @param output buffer to hold output - Cipher Text.
* @param input buffer to hold input - Plain Text.
* Note: The size of input - Plain Text must be the multiple of AES_BLOCK_SIZE 128 bits
* @param sz size of input
* Note: input and output have the same size.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
int AesCbcEncrypt(Aes* aes, byte* output, const byte* input, word32 sz);
/**
* @brief AES decryption process in Cbc mode
*
* @param aes AES context
* @param output buffer to hold output - Plain Text. It has the same size with input
* @param input buffer to hold input - Cipher Text.
* Note: The size of input must be the multiple of AES_BLOCK_SIZE 128 bits
* @param sz size of input
* Note: input and output have the same size.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
int AesCbcDecrypt(Aes* aes, byte* output, const byte* input, word32 sz);
/**
* @brief AES encryption process in Cbc mode with PKCS#5 padding
*
* @param aes AES context
* @param output buffer to hold output - Cipher Text.
* @param input buffer to hold input - Plain Text.
* @param sz size of input
* @retval the Cipher Text size, should be the multiple of AES_BLOCK_SIZE 128 bits
*/
word32 AesCbcEncryptPkcs5Padding(Aes* aes, byte* output, const byte* input, word32 sz);
/**
* @brief AES decryption process in Cbc mode with PKCS#5 padding
*
* @param aes AES context
* @param output buffer to hold output - Plain Text.
* @param input buffer to hold input - Cipher Text.
* @param sz size of input, must be the multiple of AES_BLOCK_SIZE 128 bits
* @retval the Plain Text size
*/
word32 AesCbcDecryptPkcs5Padding(Aes* aes, byte* output, const byte* input, word32 sz);
/**
* @brief AES extend external key into a longer bit string
*
* @param aes AES context
* @param key external key defined by user,must be 128 bits
* @param ilen size of AES_BLOCK_SIZE.
* @param out buffer to put cipher text.
* @param dir Specify the process of encryption or decryption
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
int AesSetKeyDirect(Aes* aes, const byte* key, word32 ilen,const byte* out, int dir);
/**
* @brief AES encryption process in ecb mode
*
* @param aes AES context
* @param output buffer to hold output - Plain Text. It has the same size with input
* @param input buffer to hold input - Cipher Text.
* Note: The size of input must be the multiple of AES_BLOCK_SIZE 128 bits
* @param sz size of input
* Note: input and output have the same size.
* @retval None.
*/
void AesEncryptDirect(Aes* aes, byte* out, const byte* in);
/**
* @brief AES decryption process in ecb mode
*
* @param aes AES context
* @param output buffer to hold output - Plain Text. It has the same size with input
* @param input buffer to hold input - Cipher Text.
* Note: The size of input must be the multiple of AES_BLOCK_SIZE 128 bits
* @param sz size of input
* Note: input and output have the same size.
* @retval None.
*/
void AesDecryptDirect(Aes* aes, byte* out, const byte* in);
/**
* @}
*/
/** @defgroup MICO_Security_ARC4 MICO ARC4 Encryption Algorytm
* @brief MiCO ARC4 Encryption and Decryption Fucntion
* @{
*/
/**
* @brief Constant data during Arc4 Encription
*/
enum {
ARC4_ENC_TYPE = 4, /* cipher unique type */
ARC4_STATE_SIZE = 256
};
/**
* @brief Arc4 context
*/
typedef struct Arc4 {
byte x;
byte y;
byte state[ARC4_STATE_SIZE];
} Arc4;
/**
* @brief ARC4 extend external key
*
* @param arc4 ARC4 context
* @param key external key defined by user
* @param keylen length of the key, range is 1-256 bits.
* Note: 0 is illegal.
* @retval None.
*/
void Arc4SetKey(Arc4 *arc4, const byte *key, word32 keylen );
/**
* @brief ARC4 encryption or decription process
*
* @param arc4 ARC4 context
* @param output buffer to hold output - Cipher Text.It has the same size with input
* @param input buffer to hold input - Plain Text.
* Note: The length must be within 1 to 20 bytes.
* @param outlen size of output.
* @retval None.
*/
void Arc4Process(Arc4 *arc4, byte *output, const byte *input, word32 outlen);
/**
* @}
*/
/** @defgroup MICO_Security_Rabbit MICO Rabbit Encryption Algorithm
* @brief MiCO Rabbit Encryption and Decryption Function
* @{
*/
/**
* @brief Constant data during Rabbit Encryption
*/
enum {
RABBIT_ENC_TYPE = 5 /* cipher unique type */
};
/**
* @brief Rabbit Context
*/
typedef struct RabbitCtx {
word32 x[8];
word32 c[8];
word32 carry;
} RabbitCtx;
/**
* @brief Rabbit stream cipher
*/
typedef struct Rabbit {
RabbitCtx masterCtx;
RabbitCtx workCtx;
} Rabbit;
/**
* @brief Rabbit extend external key into a longer bit string
*
* @param rabbit Rabbit context
* @param key Key Seed defined by user, but length must be 128 bits
* @param iv initial vector - IV, but length must be 64 bits
*/
int RabbitSetKey(Rabbit* rabbit, const byte* key, const byte* iv);
/**
* @brief Rabbit encryption or decryption process
*
* @param rabbit Rabbit context
* @param output buffer to hold output - Cipher Text.
* Note: The size of output is the same with input.
* @param input buffer to hold input.
* Note: The size must be within 1 to 16bytes
* @param sz size of output.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
int RabbitProcess(Rabbit* rabbit, byte* output, const byte* input, word32 sz);
/**
* @}
*/
/** @defgroup MICO_Security_RSA MICO RSA Encryption Algorithm
* @brief MiCO RSA Encryption and Decryption Function
* @{
*/
/**
* @brief Constant data during RSA Encryption
*/
#define DBRG_SEED_LEN (440/8)
enum {
RSA_PUBLIC = 0,
RSA_PRIVATE = 1
};
/**
* @brief OS specific seeder
*/
typedef struct OS_Seed {
int fd;
} OS_Seed;
/**
* @brief the infamous mp_int structure
*/
typedef struct {
int used, alloc, sign;
unsigned short *dp;
} mp_int;
/**
* @brief rsakey define
*/
typedef struct RsaKey {
mp_int n, e, d, p, q, dP, dQ, u;
int type; /* public or private */
void* heap; /* for user memory overrides */
} RsaKey;
/**
* @brief Constant data during RSA Encryption
*/
enum {
SHA256_BLOCK_SIZE = 64,
SHA256_DIGEST_SIZE = 32,
SHA256_PAD_SIZE = 56
};
/**
* @brief ha256 digest
*/
typedef struct Sha256 {
word32 buffLen; /* in bytes */
word32 loLen; /* length in bytes */
word32 hiLen; /* length in bytes */
word32 digest[SHA256_DIGEST_SIZE / sizeof(word32)];
word32 buffer[SHA256_BLOCK_SIZE / sizeof(word32)];
} Sha256;
/**
* @brief RNG definition used for RSA
*/
typedef struct CyaSSL_RNG {
OS_Seed seed;
Sha256 sha;
byte digest[SHA256_DIGEST_SIZE];
byte V[DBRG_SEED_LEN];
byte C[DBRG_SEED_LEN];
word64 reseed_ctr;
} CyaSSL_RNG;
/**
* @brief Initialize RsaKey
*
* @param key RsaKey context
*
* @retval None
*/
void InitRsaKey(RsaKey* key, void*);
/**
* @brief Free RsaKey
*
* @param key RsaKey context
*
* @retval None
*/
void FreeRsaKey(RsaKey* key);
/**
* @brief Initialize Rng for RSA
*
* @param key CyaSSL_RNG context
*
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
int InitRng(CyaSSL_RNG *);
/**
* @brief Encrypt the string with the public key
*
* @param in string need to be encrypted
* @param inLen string length
* @param out used to store the result of encryption
* @param outLen length of out
* @param key RsaKey context
* @param rng CyaSSL_RNG context
*
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
int RsaPublicEncrypt(const byte* in, word32 inLen, byte* out,
word32 outLen, RsaKey* key, CyaSSL_RNG* rng);
/**
* @brief Decrypt the string with the private key
*
* @param in string need to be decrypted
* @param inLen string length
* @param out used to store the result of decryption
* @param outLen length of out
* @param key RsaKey context
*
* @retval Return the length in bytes written to out or a negative
number in case of an error.
*/
int RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
word32 outLen, RsaKey* key);
/**
* @brief Sign data using RSA
* @param in string need to be signed
* @param inLen string length
* @param out used to store the result of signing
* @param outLen length of out
* @param key RsaKey context
* @param rng rng used to sign
*
* @retval return the length in bytes written to out or a negative
number in case of an error.
*/
int RsaSSL_Sign(const byte* in, word32 inLen, byte* out,
word32 outLen, RsaKey* key, CyaSSL_RNG* rng);
/**
* @brief Verify data using RSA
*
* @param in string need to be verify
* @param inLen string length
* @param out used to store the result of verifying
* @param outLen length of out
* @param key RsaKey context
*
* @retval return the length in bytes written to out or a negative
number in case of an error.
*/
int RsaSSL_Verify(const byte* in, word32 inLen, byte* out,
word32 outLen, RsaKey* key);
/**
* @brief Decode the private key
*
* @param input holds the raw data from the key
* @param inOutIdx start address
* @param key RsaKey context
* @param length length to decode
*
* @retval return the index or error
*/
int RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
word32 length);
/**
* @brief Decode the public key
*
* @param input holds the raw data from the key
* @param inOutIdx start address
* @param key RsaKey context
* @param length length to decode
*
* @retval return the index or error
*/
int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey *key,word32);
/**
* @}
*/
/**
* @}
*/

View file

@ -0,0 +1,720 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef __MICOSOCKET_H__
#define __MICOSOCKET_H__
#if defined __GNUC__
#include <sys/time.h>
#include <sys/select.h>
#endif
#include "mico_errno.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup MICO_Core_APIs
* @{
*/
/** @defgroup MICO_SOCKET MICO Socket Operations
* @brief Communicate with other device using TCP or UDP over MICO network
* @{
*/
/** For compatibility with BSD code */
struct in_addr {
uint32_t s_addr;
};
/** 255.255.255.255 */
#define INADDR_NONE ((uint32_t)0xffffffffUL)
/** 127.0.0.1 */
#define INADDR_LOOPBACK ((uint32_t)0x7f000001UL)
/** 0.0.0.0 */
#define INADDR_ANY ((uint32_t)0x00000000UL)
/** 255.255.255.255 */
#define INADDR_BROADCAST ((uint32_t)0xffffffffUL)
/* members are in network byte order */
struct sockaddr_in {
uint8_t sin_len;
uint8_t sin_family;
uint16_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct sockaddr {
uint8_t sa_len;
uint8_t sa_family;
uint8_t sa_data[14];
};
#ifndef socklen_t
# define socklen_t uint32_t
#endif
struct hostent {
char *h_name; /* Official name of the host. */
char **h_aliases; /* A pointer to an array of pointers to alternative host names,
terminated by a null pointer. */
int h_addrtype; /* Address type. */
int h_length; /* The length, in bytes, of the address. */
char **h_addr_list; /* A pointer to an array of pointers to network addresses (in
network byte order) for the host, terminated by a null pointer. */
#define h_addr h_addr_list[0] /* for backward compatibility */
};
struct addrinfo {
int ai_flags; /* Input flags. */
int ai_family; /* Address family of socket. */
int ai_socktype; /* Socket type. */
int ai_protocol; /* Protocol of socket. */
socklen_t ai_addrlen; /* Length of socket address. */
struct sockaddr *ai_addr; /* Socket address of socket. */
char *ai_canonname; /* Canonical name of service location. */
struct addrinfo *ai_next; /* Pointer to next in list. */
};
/* Socket protocol types (TCP/UDP/RAW) */
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
#define SOCK_RAW 3
#define SOL_SOCKET 0xfff /* options for socket level */
#define AF_UNSPEC 0
#define AF_INET 2
#define PF_INET AF_INET
#define PF_UNSPEC AF_UNSPEC
#define IPPROTO_IP 0
#define IPPROTO_TCP 6
#define IPPROTO_UDP 17
#define IPPROTO_UDPLITE 136
/*
* Options for level IPPROTO_IP
*/
#define IP_TOS 1
#define IP_TTL 2
typedef struct ip_mreq {
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_interface; /* local IP address of interface */
} ip_mreq;
/**
* @brief Socket option types, level: SOL_SOCKET
*/
typedef enum {
SO_DEBUG = 0x0001, /**< Unimplemented: turn on debugging info recording */
SO_ACCEPTCONN = 0x0002, /**< socket has had listen() */
SO_REUSEADDR = 0x0004, /**< Allow local address reuse */
SO_KEEPALIVE = 0x0008, /**< keep connections alive */
SO_DONTROUTE = 0x0010, /**< Just use interface addresses */
SO_BROADCAST = 0x0020, /**< Permit to send and to receive broadcast messages */
SO_USELOOPBACK = 0x0040, /**< Bypass hardware when possible */
SO_LINGER = 0x0080, /**< linger on close if data present */
SO_OOBINLINE = 0x0100, /**< Leave received OOB data in line */
SO_REUSEPORT = 0x0200, /**< Allow local address & port reuse */
SO_BLOCKMODE = 0x1000, /**< set socket as block(optval=0)/non-block(optval=1) mode.
Default is block mode. */
SO_SNDBUF = 0x1001,
SO_SNDTIMEO = 0x1005, /**< Send timeout in block mode. block for ever in dafault mode. */
SO_RCVTIMEO = 0x1006, /**< Recv timeout in block mode. block 1 second in default mode. */
SO_ERROR = 0x1007, /**< Get socket error number. */
SO_TYPE = 0x1008, /**< Get socket type. */
SO_NO_CHECK = 0x100a /**< Don't create UDP checksum. */
} SOCK_OPT_VAL;
struct pollfd {
int fd; /**< fd related to */
short events; /**< which POLL... events to respond to */
short revents; /**< which POLL... events occurred */
};
#define POLLIN 0x0001
#define POLLPRI 0x0002
#define POLLOUT 0x0004
#define POLLERR 0x0008
#define POLLHUP 0x0010
#define POLLNVAL 0x0020
/**
* @brief IP option types, level: IPPROTO_IP
*/
typedef enum {
IP_ADD_MEMBERSHIP = 0x0003, /**< Join multicast group. */
IP_DROP_MEMBERSHIP = 0x0004, /**< Leave multicast group. */
IP_MULTICAST_TTL = 0x0005,
IP_MULTICAST_IF = 0x0006,
IP_MULTICAST_LOOP = 0x0007
} IP_OPT_VAL;
/**
* @brief TCP option types, level: IPPROTO_TCP
*/
typedef enum {
TCP_NODELAY = 0x0001,
TCP_KEEPALIVE = 0x0002,
TCP_CONN_NUM = 0x0006, /**< Read the current connected TCP client number. */
TCP_MAX_CONN_NUM = 0x0007, /**< Set the max number of TCP client that server can support. */
TCP_KEEPIDLE = 0x0003, /**< set pcb->keep_idle - send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */
TCP_KEEPINTVL = 0x0004, /**< set pcb->keep_intvl - Use seconds for get/setsockopt */
TCP_KEEPCNT = 0x0005, /**< set pcb->keep_cnt - Use number of probes sent for get/setsockopt */
} TCP_OPT_VAL;
#if !defined(FIONREAD) || !defined(FIONBIO)
#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */
#define IOC_VOID 0x20000000UL /* no parameters */
#define IOC_OUT 0x40000000UL /* copy out parameters */
#define IOC_IN 0x80000000UL /* copy in parameters */
#define IOC_INOUT (IOC_IN|IOC_OUT)
/* 0x20000000 distinguishes new &
old ioctl's */
#define _IO(x,y) (IOC_VOID|((x)<<8)|(y))
#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
#endif /* !defined(FIONREAD) || !defined(FIONBIO) */
#ifndef FIONREAD
#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */
#endif
#ifndef FIONBIO
#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */
#endif
typedef void* mico_ssl_t;
/**
* @brief Supported SSL protocol version
*/
enum ssl_version_type_e
{
SSL_V3_MODE = 1,
TLS_V1_0_MODE = 2,
TLS_V1_1_MODE = 3,
TLS_V1_2_MODE = 4,
};
typedef uint8_t ssl_version_type_t;
#if !defined __GNUC__
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* and microseconds */
};
#define FD_SETSIZE 64 /**< MAX fd number is 64 in MICO. */
#define howmany(x, y) (((x) + ((y) - 1)) / (y))
#define NBBY 8 /**< number of bits in a byte. */
#define NFDBITS (sizeof(unsigned long) * NBBY) /**< bits per mask */
#define _fdset_mask(n) ((unsigned long)1 << ((n) % NFDBITS))
typedef struct fd_set {
unsigned long fds_bits[howmany(FD_SETSIZE, NFDBITS)];
} fd_set;
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= _fdset_mask(n)) /**< Add a fd to FD set. */
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~_fdset_mask(n)) /**< Remove fd from FD set. */
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & _fdset_mask(n)) /**< Check if the fd is set in FD set. */
#define FD_ZERO(p) memset(p, 0, sizeof(*(p))) /**< Clear FD set. */
#endif
#ifndef SHUT_RD
#define SHUT_RD 1
#define SHUT_WR 2
#define SHUT_RDWR 3
#endif
#define MAX_TCP_CLIENT_PER_SERVER 5
/** @defgroup MICO_SOCKET_GROUP_1 MICO BSD-like Socket Functions
* @brief Provide basic APIs for socket function
* @{
*/
/**
* @brief Create an endpoint for communication
* @attention Never doing operations on one socket in different MICO threads
* @param domain: Specifies a communication domain; this selects the protocol
* family which will be used for communication.
* This parameter can be one value:
* @arg AF_INET: IPv4 Internet protocols.
* @param type: Specifies the communication semantics.
* This parameter can be one of the following values:
* @arg SOCK_STREAM: Provides sequenced, reliable, two-way,
* connection-based byte streams. An out-of-band data
* transmission mechanism may be supported. (TCP)
* @arg SOCK_DGRAM: Supports datagrams (connectionless, unreliable
* messages of a fixed maximum length).(UDP)
* @param protocol: specifies a particular protocol to be used with the socket.
* This parameter can be one of the following values:
* @arg IPPROTO_TCP: TCP protocol
* @arg IPPROTO_UDP: UDP protocol
* @retval On success, a file descriptor for the new socket is returned.
On error, -1 is returned.
*/
int socket(int domain, int type, int protocol);
/**
* @brief Set options on sockets
* @attention Never doing operations on one socket in different MICO threads
* @param socket: A file descriptor
* @param level: This parameter can be : IPPROTO_IP, SOL_SOCKET, IPPROTO_TCP, IPPROTO_UDP
* @param optname: This parameter is defined in SOCK_OPT_VAL
* @param optval: address of buffer in which the value for the requested option(s)
* are to be set.
* @param optlen: containing the size of the buffer pointed to by optval
* @retval On success, zero is returned. On error, -1 is returned.
*/
int setsockopt (int socket, int level, int optname, void *optval, socklen_t optlen);
/**
* @brief Get options on sockets
* @attention Never doing operations on one socket in different MICO threads
* @param socket: A file descriptor
* @param level: This parameter can be : IPPROTO_IP, SOL_SOCKET, IPPROTO_TCP, IPPROTO_UDP
* @param optname: This parameter is defined in SOCK_OPT_VAL
* @param optval: address of buffer in which the value for the requested option(s)
* are to be returned.
* @param optlen_ptr: This is a value-result argument, initially containing the size
* of the buffer pointed to by optval, and modified on return to indicate
* the actual size of the value returned.
* @retval On success, zero is returned. On error, -1 is returned.
*/
int getsockopt (int socket, int level, int optname, void *optval, socklen_t *optlen_ptr);
/**
* @brief bind a name to a socket
* @attention Never doing operations on one socket in different MICO threads
* @note Assigns the address specified by addr to the socket referred to by the file
* descriptor socket.
* @param socket: A file descriptor
* @param addr: Point to the target address to be binded
* @param length: This parameter containing the size of the buffer pointed to by addr
* @retval On success, zero is returned. On error, -1 is returned.
*/
int bind (int socket, struct sockaddr *addr, socklen_t length);
/**
* @brief Initiate a connection on a socket
* @attention Never doing operations on one socket in different MICO threads
* @details The connect() system call connects the socket referred to by the file
* descriptor socket to the address specified by addr.
* @param socket: A file descriptor
* @param addr: Point to the target address to be binded
* @param length: This parameter containing the size of the buffer pointed to by addr
* @retval On success, zero is returned. On error, -1 is returned.
*/
int connect (int socket, struct sockaddr *addr, socklen_t length);
/**
* @brief Listen for connections on a socket
* @attention Never doing operations on one socket in different MICO threads
* @details listen() marks the socket referred to by socket as a passive socket,
* that is, as a socket that will be used to accept incoming connection
* requests using accept().
* @param socket: a file descriptor.
* @param n: Defines the maximum length to which the queue of pending
* connections for socket may grow. This parameter is not used in MICO,
* use 0 is fine.
* @retval On success, zero is returned. On error, -1 is returned.
*/
int listen (int socket, int n);
/**
* @brief Accept a connection on a socket
* @attention Never doing operations on one socket in different MICO threads
* @details The accept() system call is used with connection-based socket types
* (SOCK_STREAM). It extracts the first connection request on the queue
* of pending connections for the listening socket, sockfd, creates a
* new connected socket, and returns a new file descriptor referring to
* that socket. The newly created socket is not in the listening state.
* The original socket socket is unaffected by this call.
* @param socket: A file descriptor.
* @param addr: Point to the buffer to store the address of the accepted client.
* @param length_ptr: This parameter containing the size of the buffer pointed to
* by addr.
* @retval On success, zero is returned. On error, -1 is returned.
*/
int accept (int socket, struct sockaddr *addr, socklen_t *length_ptr);
/**
* @brief Monitor multiple file descriptors, waiting until one or more of the
* file descriptors become "ready" for some class of I/O operation
* (e.g., input possible).
* @attention Never doing operations on one socket in different MICO threads
* @note A file descriptor is considered ready if it is possible to perform
* the corresponding I/O operation (e.g., read()) without blocking.
* @param nfds: is the highest-numbered file descriptor in any of the three
* sets, plus 1. In MICO, the mount of file descriptors is fewer, so
* MICO use the MAX number of these file descriptors inside, and this
* parameter is cared.
* @param readfds: A file descriptor sets will be watched to see if characters
* become available for reading
* @param writefds: A file descriptor sets will be watched to see if a write
* will not block.
* @param exceptfds: A file descriptor sets will be watched for exceptions.
* @param timeout: The timeout argument specifies the interval that select()
* should block waiting for a file descriptor to become ready.
* If timeout is NULL (no timeout), select() can block indefinitely.
* @retval On success, return the number of file descriptors contained in the
* three returned descriptor sets (that is, the total number of bits
* that are set in readfds, writefds, exceptfds) which may be zero if
* the timeout expires before anything interesting happens. On error,
* -1 is returned, the file descriptor sets are unmodified, and timeout
* becomes undefined.
*/
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
int poll(struct pollfd *fds, int nfds, int timeout);
/**
* @brief Send a message on a socket
* @attention Never doing operations on one socket in different MICO threads
* @details The send() call may be used only when the socket is in a connected
* state (so that the intended recipient is known). The only difference
* between send() and write() is the presence of flags. With a zero
* flags argument, send() is equivalent to write().
* @note When the message does not fit into the send buffer of the socket,
* send() normally blocks, unless the socket has been placed in
* nonblocking I/O mode. In nonblocking mode it would fail. The select()
* call may be used to determine when it is possible to send more data.
* @param socket: A file descriptor.
* @param buffer: Point to the send data buffer.
* @param size: Length of the send data buffer.
* @param flags: Zero in MICO.
* @retval On success, these calls return the number of bytes sent. On error,
* -1 is returned,
*/
int send (int socket, const void *buffer, size_t size, int flags);
/**
* @brief Send a message on a socket
* @attention Never doing operations on one socket in different MICO threads
* @note Refer send() for details.
*/
ssize_t write (int filedes, const void *buffer, size_t size);
/**
* @brief Send a message on a socket to a specific target address.
* @attention Never doing operations on one socket in different MICO threads
* @details Refer send() for details. If sendto() is used on a connection-mode
* (SOCK_STREAM, SOCK_SEQPACKET) socket, the arguments dest_addr and
* addrlen are ignored. Otherwise, the address of the target is given by
* dest_addr with addrlen specifying its size.
* @param socket: Refer send() for details.
* @param buffer: Refer send() for details.
* @param size: Refer send() for details.
* @param flags: Refer send() for details.
* @param addr: Point to the target address.
* @param length: This parameter containing the size of the buffer pointed to
* by addr.
* @retval On success, these calls return the number of bytes sent. On error,
* -1 is returned,
*/
int sendto (int socket, const void *buffer, size_t size, int flags, const struct sockaddr *addr, socklen_t length);
/**
* @brief Receive a message from a socket.
* @attention Never doing operations on one socket in different MICO threads
* @details If no messages are available at the socket, the receive calls wait
* for a message to arrive, unless the socket is nonblocking, in
* which case the value -1 is returned. The receive calls normally
* return any data available, up to the requested amount, rather than
* waiting for receipt of the full amount requested.
* @param socket: A file descriptor.
* @param buffer: Point to the send data buffer.
* @param size: Length of the send data buffer.
* @param flags: Zero in MICO.
* @retval These calls return the number of bytes received, or -1 if an error
* occurred.
* When a stream socket peer has performed an orderly shutdown, the
* return value will be 0 (the traditional "end-of-file" return).
* The value 0 may also be returned if the requested number of bytes to
* receive from a stream socket was 0.
*/
int recv (int socket, void *buffer, size_t size, int flags);
/**
* @brief Receive a message from a socket.
* @attention Never doing operations on one socket in different MICO threads
* @note Refer recv() for details.
*/
ssize_t read (int filedes, void *buffer, size_t size);
/**
* @brief Receive a message from a socket and get the source address.
* @attention Never doing operations on one socket in different MICO threads
* @details If src_addr is not NULL, and the underlying protocol provides
* the source address of the message, that source address is placed
* in the buffer pointed to by src_addr. In this case, addrlen is
* a value-result argument. Before the call, it should be
* initialized to the size of the buffer associated with src_addr.
* Upon return, addrlen is updated to contain the actual size of
* the source address. The returned address is truncated if the
* buffer provided is too small; in this case, addrlen will return
* a value greater than was supplied to the call.
* If the caller is not interested in the source address, src_addr
* should be specified as NULL and addrlen should be specified as 0.
* @param sockfd: Refer recv() for details.
* @param buf: Refer recv() for details.
* @param len: Refer recv() for details.
* @param flags: Refer recv() for details.
* @param src_addr: Point to the buffer to store the source address.
* @param addrlen: This parameter containing the size of the buffer pointed to
* by src_addr.
* @retval These calls return the number of bytes received, or -1 if an
* error occurred.
* When a stream socket peer has performed an orderly shutdown, the
* return value will be 0 (the traditional "end-of-file" return).
* The value 0 may also be returned if the requested number of bytes to
* receive from a stream socket was 0.
*/
int recvfrom (int socket, void *buffer, size_t size, int flags, struct sockaddr *addr, socklen_t *length_ptr);
/**
* @brief Close a file descriptor.
* @attention Never doing operations on one socket in different MICO threads
* @details closes a file descriptor, so that it no longer refers to any
* file and may be reused.the resources associated with the
* open file description are freed.
* @param filedes: A file descriptor.
* @retval Returns zero on success. On error, -1 is returned.
*/
int close (int filedes);
int shutdown(int s, int how);
int ioctl(int s, long cmd, void *argp);
/**
* @}
*/
/** @defgroup MICO_SOCKET_GROUP_2 MICO Socket Tool Functions
* @brief Provide APIs for MiCO Socket Tool functions
* @{
*/
/**
* @brief converts the Internet host address from IPv4 numbers-and-dots
* notation into binary data in network byte order
* @note If the input is invalid, INADDR_NONE (usually -1) is returned.
* @param name: Internet host address from IPv4 numbers-and-dots.
* @retval Returns zero on success. On error, -1 is returned.
*/
uint32_t inet_addr (const char *name);
/**
* @brief Converts the Internet host address in, given in network byte
* order, to a string in IPv4 dotted-decimal notation.
* @note The returned string is stored in a given buffer, and the buffer
* size should larger than 16.
* @param s: Point to a buffer to store the returned string in IPv4
* dotted-decimal
* @param x: the Internet host address in.
* @retval Returns the same value as param s.
*/
extern char *inet_ntoa (struct in_addr addr);
/** @brief Get the IP address from a host name.
*
* @note Different to stand BSD function type, this function in MICO do
* not return a buffer that contain the result, but write the result
* to a buffer provided by application. Also this function simplify
* the return value compared to the standard BSD version.
* This functon runs under block mode.
*
* @param name: This parameter is either a hostname, or an IPv4 address in
* standard dot notation.
* @param addr: Point to a buffer to store the returned string in IPv4
* dotted-decimal
* @param addrLen: This parameter containing the size of the buffer pointed
* to by addr, 16 is recommended.
* @retval kNoerr or kGeneralErr
*/
struct hostent* gethostbyname(const char *name);
int getaddrinfo(const char *nodename,
const char *servname,
const struct addrinfo *hints,
struct addrinfo **res);
void freeaddrinfo(struct addrinfo *ai);
int getpeername (int s, struct sockaddr *name, socklen_t *namelen);
int getsockname (int s, struct sockaddr *name, socklen_t *namelen);
/** @brief Set TCP keep-alive mechanism parameters.
*
* @details When TCP data is not transimitting for a certain time (defined by seconds),
* MICO send keep-alive package over the TCP socket, and the remote device
* should return the keep-alive back to MICO. This is a basic TCP function
* deployed on every TCP/IP stack and application's interaction is not required.
* If the remote device doesn't return the keep-alive package, MICO add 1 to an
* internal counter, and close the current socket connection once this count has
* reached the maxErrNum (defined in parm: maxErrNum).
*
* @param inMaxErrNum: The max possible count that the remote device doesn't return the
* keep-alive package. If remote device returns, the internal count is cleared
* to 0.
* @param inSeconds: The time interval between two keep-alive package
*
* @retval kNoerr or kGeneralErr
*/
void set_tcp_keepalive(int inMaxErrNum, int inSeconds);
/** @brief Get TCP keep-alive mechanism parameters. Refer to @ref set_tcp_keepalive
*
* @param outMaxErrNum: Point to the address that store the maxErrNumber.
* @param outSeconds: Point to the address that store the time interval between two
* keep-alive package.
*
* @retval kNoerr or kGeneralErr
*/
void get_tcp_keepalive(int *outMaxErrNum, int *outSeconds);
/* SSL */
/** @brief Used to set the ssl protocol version for both ssl client and ssl server
*
* @note This function should be called before ssl is ready to function (before
* ssl_connect and ssl_accept is called by application ).
*
* @param version: SSL protocol version, Refer SSL_VERSION for details.
*
* @retval void
*/
void ssl_set_client_version( ssl_version_type_t version );
/** @brief Get the internal socket fire description
*
* @note This function should be called after ssl connection is established.
*
* @param ssl: SSL handler.
*
* @retval File descriptor for the SSL connection.
*/
int ssl_socket( mico_ssl_t ssl );
/** @brief Used by the SSL server. Set the certificate and private key for a SSL server.
*
* @details This function is called on the server side to set it's certifact and private key.
* It must be called before ssl_accept. These two arguments must be global
* string buffer, library will not create a copy for them.
*
* @param _cert_pem: Point to the certificate string in PEM format.
* @param private_key_pem: Point to the private key string in PEM format.
*
* @retval void
*/
void ssl_set_cert(const char *_cert_pem, const char *private_key_pem);
/** @brief SSL client create a SSL connection.
*
* @details This function is called on the client side and initiates an SSL/TLS handshake with a
* server. When this function is called, the underlying communication channel has already
* been set up. This function is called after TCP 3-way handshak finished.
*
* @param fd: The fd number for a connected TCP socket.
* @param calen: the string length of ca. 0=do not verify server's certificate.
* @param ca: pointer to the CA certificate string, used to verify server's certificate.
* @param errno: return the errno if ssl_connect return NULL.
*
* @retval return the SSL context pointer on success or NULL for fail.
*/
mico_ssl_t ssl_connect(int fd, int calen, char*ca, int *errno);
/** @brief SSL Server accept a SSL connection
*
* @param fd: The fd number for a connected TCP socket.
*
* @retval return the SSL context pointer on success or NULL for fail.
*/
mico_ssl_t ssl_accept(int fd);
/** @brief SSL send data
*
* @param ssl: Point to the SSL context.
* @param data: Point to send data.
* @param len: data length.
*
* @retval On success, these calls return the number of bytes sent. On error,
* -1 is returned,
*/
int ssl_send(mico_ssl_t ssl, void* data, size_t len);
/** @brief SSL receive data
*
* @param ssl: Point to the SSL context.
* @param data: Point to buffer to receive SSL data.
* @param len: max receive buffer length.
*
* @retval On success, these calls return the number of bytes received. On error,
* -1 is returned,
*/
int ssl_recv(mico_ssl_t ssl, void* data, size_t len);
/** @brief Close the SSL session, release resource.
*
* @param ssl: Point to the SSL context.
*
* @retval kNoerr or kGeneralErr
*/
int ssl_close(mico_ssl_t ssl);
int ssl_pending(void*ssl);
int ssl_get_error(void* ssl, int ret);
void ssl_set_using_nonblock(void* ssl, int nonblock);
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /*__MICO_SOCKET_H__*/

View file

@ -0,0 +1,754 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#if 0
#pragma once
#include "common.h"
#include "system.h"
#include "command_console/mico_cli.h"
#include "json_c/json.h"
#ifndef MICO_PREBUILT_LIBS
#include "mico_config.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef system_state_t mico_system_state_t;
typedef system_config_t mico_Context_t;
typedef system_status_wlan_t mico_system_status_wlan_t;
/** @defgroup MICO_SYSTEM_APIs MICO System APIs
* @brief MiCO System provide a basic framework for application based on MiCO core APIs
* @{
*/
/** @addtogroup MICO_SYSTEM_APIs
* @{
*/
/** @defgroup System_General System General Tools
* @brief Read MiCO system's version
* @{
*/
/**
* @brief Read MiCO SDK version.
* @param major: Major version number.
* @param minor: Minor version number.
* @param revision: Revision nember.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
void mico_sdk_version( uint8_t *major, uint8_t *minor, uint8_t *revision );
/**
* @brief Read MiCO Application information.
* @param p_info: Point to the memory to store the info.
* @param len_info: Size of the menory.
* @retval none.
*/
void mico_app_info(char *p_info, int len_info);
/** @} */
/** @defgroup system_context Core Data Functions
* @brief System core data management, should initialized before other system functions
* @{
*/
/* Parameter section store in flash */
typedef enum
{
PARA_BOOT_TABLE_SECTION,
PARA_MICO_DATA_SECTION,
#ifdef MICO_BLUETOOTH_ENABLE
PARA_BT_DATA_SECTION,
#endif
PARA_SYS_END_SECTION,
PARA_APP_DATA_SECTION,
PARA_END_SECTION
} para_section_t;
/**
* @brief Initialize core data used by MiCO system framework. System and
* application's configuration are read from non-volatile storage:
* flash etc.
* @param size_of_user_data: The length of config data used by application
* @retval Address of core data.
*/
void* mico_system_context_init( uint32_t size_of_user_data );
/**
* @brief Get the address of the core data.
* @param none
* @retval Address of core data.
*/
mico_Context_t* mico_system_context_get( void );
/**
* @brief Get the address of the application's config data.
* @param in_context: The address of the core data.
* @retval Address of the application's config data.
*/
void* mico_system_context_get_user_data( mico_Context_t* const in_context );
/**
* @brief Restore configurations to default settings, it will cause a delegate
* function: appRestoreDefault_callback( ) to give a default value for
* application's config data.
* @param in_context: The address of the core data.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus mico_system_context_restore( mico_Context_t* const in_context );
/**
* @brief Application should give a default value for application's config data
* on address: user_config_data
* @note This a delegate function, can be completed by developer.
* @param user_config_data: The address of the application's config data.
* @param size: The size of the application's config data.
* @retval None
*/
void appRestoreDefault_callback(void * const user_config_data, uint32_t size);
/**
* @brief Write config data hosted by core data to non-volatile storage
* @param in_context: The address of the core data.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus mico_system_context_update( mico_Context_t* const in_context );
OSStatus mico_system_para_read(void** info_ptr, int section, uint32_t offset, uint32_t size);
OSStatus mico_system_para_write(const void* info_ptr, int section, uint32_t offset, uint32_t size);
OSStatus mico_system_para_read_release( void* info_ptr );
/** @} */
/** @defgroup MiCO OTA Functions
* @brief MiCO firmware updation functions
* @{
*/
/**
* @brief Active downloaded firmware that stored in MICO_PARTITION_OTA_TEMP
* @param ota_data_len: the length of the new firmware
* @param ota_data_crc: the crc result of the new firmware
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus mico_ota_switch_to_new_fw(int ota_data_len, uint16_t ota_data_crc);
/** @} */
/** @defgroup system System Framework Functions
* @brief Initialize MiCO system functions defined in mico_config.h
* @{
*/
/** @brief Wlan configuration source */
typedef enum{
CONFIG_BY_NONE, /**< Default value */
CONFIG_BY_EASYLINK_V2, /**< Wlan configured by EasyLink revision 2.0 */
CONFIG_BY_EASYLINK_PLUS, /**< Wlan configured by EasyLink Plus */
CONFIG_BY_EASYLINK_MINUS, /**< Wlan configured by EasyLink Minus */
CONFIG_BY_AIRKISS, /**< Wlan configured by airkiss from wechat Tencent inc. */
CONFIG_BY_SOFT_AP, /**< Wlan configured by EasyLink soft ap mode */
CONFIG_BY_WAC, /**< Wlan configured by wireless accessory configuration from Apple inc. */
CONFIG_BY_USER, /**< Wlan configured by user defined functions. */
} mico_config_source_t;
/**
* @brief Initialize MiCO system functions according to mico_config.h
* @param in_context: The address of the core data.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus mico_system_init( mico_Context_t* const in_context );
/**
* @brief Get IP, MAC, driver info for wlan interface
* @param status: The memory to store wlan status's address.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus mico_system_wlan_get_status( mico_system_status_wlan_t** status );
/**
* @brief Start wlan configuration mode, EasyLink, SoftAP, Airkiss...
* according to macro: MICO_WLAN_CONFIG_MODE
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus mico_system_wlan_start_autoconf( void );
/**
* @brief Inform the application that EasyLink configuration will start
* @note This a delegate function, can be completed by developer.
* @retval None
*/
void mico_system_delegate_config_will_start( void );
/**
* @brief Inform the application that EasyLink configuration will stop
* @note This a delegate function, can be completed by developer.
* @retval None
*/
void mico_system_delegate_config_will_stop( void );
/**
* @brief Inform the application that EasyLink soft ap mode will start
* @note This a delegate function, can be completed by developer.
* @retval None
*/
void mico_system_delegate_soft_ap_will_start( void );
/**
* @brief Inform the application that ssid and key are received from
* EasyLink client
* @note This a delegate function, can be completed by developer.
* @param ssid: The address of the SSID string.
* @param key: The address of the Key string.
* @retval None
*/
void mico_system_delegate_config_recv_ssid ( char *ssid, char *key );
/**
* @brief Inform the application that auth data has received from
* EasyLink client
* @note This a delegate function, can be completed by developer.
* @param userInfo: Authentication data string.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus mico_system_delegate_config_recv_auth_data( char * userInfo );
/**
* @brief Inform the application that Easylink configuration is success.
* (MiCO has connect to wlan with the ssid and key)
* @note This a delegate function, can be completed by developer.
* @param source: The configuration mode used by EasyLink client
* @retval None
*/
void mico_system_delegate_config_success( mico_config_source_t source );
/** @} */
/** @defgroup system_monitor System Monitor Functions
* @brief Create monitors in MiCO. Monitors should be updated periodically,
* if not, a system reboot will perform.
* @{
*/
/** @brief Structure to hold information about a system monitor item
* Application should not destroy or modify a system monitor item
*/
typedef struct _mico_system_monitor_t
{
uint32_t last_update; /**< Time of the last system monitor update */
uint32_t longest_permitted_delay; /**< Longest permitted delay between checkins with the system monitor */
} mico_system_monitor_t;
/**
* @brief Start the system monitor daemon
* @note This function can be called automatically by mico_system_init( )
* if macro: MICO_SYSTEM_MONITOR_ENABLE is defined
* @retval None
*/
OSStatus mico_system_monitor_daemen_start( void );
/**
* @brief Register a system monitor point
* @param system_monitor: The address of a system monitor item.
* @param initial_permitted_delay: Longest permitted delay between checkins with the system monitor.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus mico_system_monitor_register( mico_system_monitor_t* system_monitor, uint32_t initial_permitted_delay );
/**
* @brief Perform a system monitor point checkin
* @param system_monitor: The address of a system monitor item.
* @param permitted_delay: The next permitted delay on the next checkin with the system monitor.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus mico_system_monitor_update ( mico_system_monitor_t* system_monitor, uint32_t permitted_delay );
/**
*
@}
*/
/** @defgroup system_power System Power Management Functions
* @brief Perform a safety power status change on MiCO.
* @{
*/
/**
* @brief Perform a system power change.
* @note This function can be used only after power management daemon is started
* @param in_context: The address of the core data.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus mico_system_power_perform( mico_Context_t* const in_context, mico_system_state_t new_state );
/** @} */
/*****************************************************************************/
/** @defgroup system_notify System Notify Functions
* @brief Register a user function to a MiCO notification, this function will
* be called when a MiCO notification is triggered
* @{
*/
/*****************************************************************************/
typedef notify_wlan_t WiFiEvent;
/** @brief MICO system defined notifications */
typedef enum{
mico_notify_WIFI_SCAN_COMPLETED, /**< A wlan scan is completed, type: void (*function)(ScanResult *pApList, void* arg)*/
mico_notify_WIFI_STATUS_CHANGED, /**< Wlan connection status is changed, type: void (*function)(WiFiEvent status, void* arg)*/
mico_notify_WiFI_PARA_CHANGED, /**< Wlan parameters has received (channel, BSSID, key...), called when connect to a wlan, type: void (*function)(apinfo_adv_t *ap_info, char *key, int key_len, void* arg)*/
mico_notify_DHCP_COMPLETED, /**< MiCO has get the IP address from DHCP server, type: void (*function)(IPStatusTypedef *pnet, void* arg)*/
mico_notify_EASYLINK_WPS_COMPLETED, /**< EasyLink receive SSID, Key, type: void (*function)(network_InitTypeDef_st *nwkpara, void* arg)*/
mico_notify_EASYLINK_GET_EXTRA_DATA, /**< EasyLink receive extra data, type: void (*function)(int datalen, char*data, void* arg)*/
mico_notify_TCP_CLIENT_CONNECTED, /**< A tcp client has connected to TCP server, type: void (*function)(int fd, void* arg)*/
mico_notify_DNS_RESOLVE_COMPLETED, /**< A DNS host address has resolved, type: void (*function)(uint8_t *hostname, uint32_t ip, void* arg)*/
mico_notify_SYS_WILL_POWER_OFF, /**< System power will be turned off, type: void (*function)(void* arg)*/
mico_notify_WIFI_CONNECT_FAILED, /**< A wlan connection attemption is failed, type: void join_fail(OSStatus err, void* arg)*/
mico_notify_WIFI_SCAN_ADV_COMPLETED, /**< A anvanced wlan scan is completed, type: void (*function)(ScanResult_adv *pApList, void* arg)*/
mico_notify_WIFI_Fatal_ERROR, /**< A fatal error occured when communicating with wlan sub-system, type: void (*function)(void* arg)*/
mico_notify_Stack_Overflow_ERROR, /**< A MiCO RTOS thread's stack is over-flowed, type: void (*function)(char *taskname, void* arg)*/
} mico_notify_types_t;
/**
* @brief Register a user function to a MiCO notification.
* @param notify_type: The type of MiCO notification.
* @param functionAddress: The address of user function.
* @param arg: The address of argument, which will be called by registered user function.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus mico_system_notify_register( mico_notify_types_t notify_type, void* functionAddress, void* arg );
/**
* @brief Remove a user function from a MiCO notification.
* @param notify_type: The type of MiCO notification.
* @param functionAddress: The address of user function.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus mico_system_notify_remove( mico_notify_types_t notify_type, void *functionAddress );
/**
* @brief Remove all user function from a MiCO notification.
* @param notify_type: The type of MiCO notification.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus mico_system_notify_remove_all( mico_notify_types_t notify_type);
/** @} */
/** @defgroup config_server System Config Server Daemon
* @brief Local network service, used to change MiCO system's configurations
* @{
*/
/**
* @brief Start local config server.
* @note This function can be called automatically by mico_system_init( )
* if macro: MICO_CONFIG_SERVER_ENABLE is defined.
* @param in_context: The address of the core data.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus config_server_start ( void );
/**
* @brief Stop local config server.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus config_server_stop ( void );
/**
* @brief Inform the application that configuration data is received from
* config client
* @note This a delegate function, can be completed by developer.
* @param key: The name of a configuration item.
* @param value: The value of a configuration item, can be read use a json_object_get_xxx
* function from json_c library.
* @param in_context: The address of the core data.
* @retval None.
*/
void config_server_delegate_recv( const char *key, json_object *value, bool *need_reboot, mico_Context_t *in_context );
/**
* @brief Inform the application that configuration server is collecting application's config data
* @note This a delegate function, can be completed by developer.
* @param config_cell_list: The UI element container to store application's config data.
* Developer can use config_server_create_xxx_cell functions to add customized UI element
* to config_cell_list.
* @param in_context: The address of the core data.
* @retval None.
*/
void config_server_delegate_report( json_object *config_cell_list, mico_Context_t *in_context );
/**
* @brief Add a cell UI holds a string value. config_cell_list(1)<=config_cell(1).
* @param config_cell_list: The config cell container.
* @param name: String indicate the name of a config data.
* @param content: String value of a config data.
* @param privilege: The privilege of a value on config client.
* @arg "RO": Read only. @arg "RW": Read or write.
* @param secectionArray: Generate a selection list for possible value, input NULL if not exist
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus config_server_create_string_cell (json_object* config_cell_list, char* const name, char* const content, char* const privilege, json_object* secectionArray);
/**
* @brief Add a cell UI holds a integer value. config_cell_list(1)<=config_cell(1).
* @param config_cell_list: The config cell container.
* @param name: String indicate the name of a config data.
* @param content: Integer value of a config data.
* @param privilege: The privilege of a value on config client.
* @arg "RO": Read only. @arg "RW": Read or write.
* @param secectionArray: Generate a selection list for possible value, input NULL if not exist
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus config_server_create_number_cell (json_object* config_cell_list, char* const name, int content, char* const privilege, json_object* secectionArray);
/**
* @brief Add a cell UI holds a float value. config_cell_list(1)<=config_cell(1).
* @param config_cell_list: The config cell container.
* @param name: String indicate the name of a config data.
* @param content: Float value of a config data.
* @param privilege: The privilege of a value on config client.
* @arg "RO": Read only. @arg "RW": Read or write.
* @param secectionArray: Generate a selection list for possible value
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus config_server_create_float_cell (json_object* config_cell_list, char* const name, float content, char* const privilege, json_object* secectionArray);
/**
* @brief Add a cell UI holds a bool value. config_cell_list(1)<=config_cell(1).
* @param config_cell_list: The config cell container.
* @param name: String indicate the name of a config data.
* @param content: Bool value of a config data.
* @param privilege: The privilege of a value on config client.
* @arg "RO": Read only. @arg "RW": Read or write.
* @param secectionArray: Generate a selection list for possible value
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus config_server_create_bool_cell (json_object* config_cell_list, char* const name, boolean content, char* const privilege);
/**
* @brief Add a cell UI holds a sub menu, config_cell_list(1)<=sub_menu_array(1).
* @param config_cell_list: The config cell container.
* @param name: String indicate the name of a sub menu.
* @param sub_menu_array: An array that buids a sub menu list.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus config_server_create_sub_menu_cell (json_object* config_cell_list, char* const name, json_object* sub_menu_array);
/**
* @brief Create a new config cell list to an exist menu. sub_menu_array(1)<=config_cell_list(n)
* @param sub_menu_array: An array that buids a sub menu list.
* @param name: String indicate the name of a config cell list.
* @param config_cell_list: The config cell container.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus config_server_create_sector (json_object* sub_menu_array, char* const name, json_object *config_cell_list);
/** @} */
/** \defgroup cli System Command Line Interface
* @brief MiCO command console
* @{
*/
/**
* @brief Initialize the CLI module
* @note This function can be called automatically by mico_system_init( )
* if macro: MICO_CLI_ENABLE is defined.
* @retval 0 is returned on success, otherwise, -1 is returned.
*/
//int cli_init(void);
/** @} */
/** @defgroup system_mdns System mDNS service functions
* @brief Multicast DNS is a way of using familiar DNS programming interfaces,
* packet formats and operating semantics, in a small network.
* @{
*/
/** @brief Structure to store mDNS record data
*/
enum mdns_record_state_e{
RECORD_REMOVED, /**< The service and resources are removed. */
RECORD_UPDATE, /**< The service record is updating, mdns routine will announce the new service content. */
RECORD_REMOVE, /**< The service record is removing, mdns routine will announce the service with TTL = 0 for
1 second, resources will be removed after the announce period */
RECORD_SUSPEND, /**< The service record is suspended, mdns routine will announce the service with TTL = 0 for
1 second and not respond the mdns query. */
RECORD_NORMAL, /**< The service can respond to mdns query . */
};
typedef uint8_t mdns_record_state_t;
typedef struct _mdns_init_t
{
char *service_name; /**< The service name of a mDNS record, example: "_easylink_config._tcp.local." */
char *host_name; /**< The host name of a mDNS record, example: "device_name.local." */
char *instance_name; /**< The instance name of a mDNS record, example: "device_name" */
char *txt_record; /**< Txt record holds customized info, every info is seperated by '.',
the orginal '.' is replaced by "/.", example: "record/.1=1.record/.2=2/.3" */
uint16_t service_port; /**< Service port */
} mdns_init_t;
/**
* @brief Add a new mDNS record, a mDNS service daemon will be start if necessary
* @param record: mDNS record data.
* @param interface: Which network interface, the IP info will be read from when response a nDNS request.
* @param time_to_live: The TTL of a mDNS record.
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
*/
OSStatus mdns_add_record( mdns_init_t record, hal_wifi_type_t interface, uint32_t time_to_live );
/**
* @brief Suspend a mDNS record, announce the TTL of this record equal to zero, and do not respond mDNS request
* @param service_name: The service name of a mDNS record. example: "_easylink_config._tcp.local."
* @param interface: Which network interface, the IP info will be read from when response a nDNS request.
* @param will_remove: Destory record info from memory after announced.
* @retval None.
*/
void mdns_suspend_record( char *service_name, hal_wifi_type_t interface, bool will_remove );
/**
* @brief Resume a suspended mDNS record, announce the TTL of this record to orginal value, and respond to following mDNS request
* @param service_name: The service name of a mDNS record. example: "_easylink_config._tcp.local."
* @param interface: Which network interface, the IP info will be read from when response a nDNS request.
* @retval None.
*/
void mdns_resume_record( char *service_name, hal_wifi_type_t interface );
/**
* @brief Update txt record with a new value
* @param service_name: The service name of a mDNS record. example: "_easylink_config._tcp.local."
* @param interface: Which network interface, the IP info will be read from when response a nDNS request.
* @param txt_record: Txt record holds customized info, every info is seperated by '.', the orginal '.' is
* replaced by "/.", example: "record/.1=1.record/.2=2/.3" = "record.1=1" and "record.2=2.3"
* @retval None.
*/
void mdns_update_txt_record( char *service_name, hal_wifi_type_t interface, char *txt_record );
/**
* @brief Get mdns service status
* @param service_name: The service name of a mDNS record. example: "_easylink_config._tcp.local."
* @param interface: network interface, the mdns service is bonded
* @retval @ref mdns_record_state_t.
*/
mdns_record_state_t mdns_get_record_status( char *service_name, hal_wifi_type_t interface);
/** @} */
/** @defgroup system_time MiCO System time functions
* @brief Functions to get and set the real-time-clock time.
* @{
*/
/** ISO8601 Time Structure
*/
#pragma pack(1)
typedef struct
{
char year[4]; /**< Year */
char dash1; /**< Dash1 */
char month[2]; /**< Month */
char dash2; /**< Dash2 */
char day[2]; /**< Day */
char T; /**< T */
char hour[2]; /**< Hour */
char colon1; /**< Colon1 */
char minute[2]; /**< Minute */
char colon2; /**< Colon2 */
char second[2]; /**< Second */
char decimal; /**< Decimal */
char sub_second[6]; /**< Sub-second */
char Z; /**< UTC timezone */
} iso8601_time_t;
#pragma pack()
/** Get the current system tick time in milliseconds
*
* @note The time will roll over every 49.7 days
*
* @param[out] time : A pointer to the variable which will receive the time value
*
* @return @ref OSStatus
*/
OSStatus mico_time_get_time( mico_time_t* time );
/** Set the current system tick time in milliseconds
*
* @param[in] time : the time value to set
*
* @return @ref OSStatus
*/
OSStatus mico_time_set_time( const mico_time_t* time );
/** Get the current UTC time in seconds
*
* This will only be accurate if the time has previously been set by using @ref mico_time_set_utc_time_ms
*
* @param[out] utc_time : A pointer to the variable which will receive the time value
*
* @return @ref OSStatus
*/
OSStatus mico_time_get_utc_time( mico_utc_time_t* utc_time );
/** Get the current UTC time in milliseconds
*
* This will only be accurate if the time has previously been set by using @ref mico_time_set_utc_time_ms
*
* @param[out] utc_time_ms : A pointer to the variable which will receive the time value
*
* @return @ref OSStatus
*/
OSStatus mico_time_get_utc_time_ms( mico_utc_time_ms_t* utc_time_ms );
/** Set the current UTC time in milliseconds
*
* @param[in] utc_time_ms : the time value to set
*
* @return @ref OSStatus
*/
OSStatus mico_time_set_utc_time_ms( const mico_utc_time_ms_t* utc_time_ms );
/** Get the current UTC time in iso 8601 format e.g. "2012-07-02T17:12:34.567890Z"
*
* @note The time will roll over every 49.7 days
*
* @param[out] iso8601_time : A pointer to the structure variable that
* will receive the time value
*
* @return @ref OSStatus
*/
OSStatus mico_time_get_iso8601_time( iso8601_time_t* iso8601_time );
/** Convert a time from UTC milliseconds to iso 8601 format e.g. "2012-07-02T17:12:34.567890Z"
*
* @param[in] utc_time_ms : the time value to convert
* @param[out] iso8601_time : A pointer to the structure variable that
* will receive the time value
*
* @return @ref OSStatus
*/
OSStatus mico_time_convert_utc_ms_to_iso8601( mico_utc_time_ms_t utc_time_ms, iso8601_time_t* iso8601_time );
#define MicoNanosendDelay mico_nanosecond_delay
/** Delay a period of time
*
* @param[in] delayus : the time value to set ( unit: nanosecond )
*
* @return none: this function will block until target time is reached
*/
void mico_nanosecond_delay( uint64_t delayus );
/** Get current nanosecond time
*
* @return current nanosecond time
*/
uint64_t mico_nanosecond_clock_value( void );
/** Set current nanosecond time to zero
*
* @return none
*/
void mico_nanosecond_reset( void );
/** Initialisse nanosecond counter function
*
* @return none
*/
void mico_nanosecond_init( void );
/** @} */
/** @defgroup tftp_ota Firmware Update From a TFTP Server
* @brief Provide an easy way to download firmware from tftp server, use a
* predefined wlan and server address. It is used under factory environment
* @{
*/
/**
* @brief Get new firmware from a TFTP Server, and replace the old one
* @retval None.
*/
void tftp_ota(void);
/** @} */
/** @} */
/** @} */
#ifdef __cplusplus
} /*extern "C" */
#endif
#else
#define MICO_BT_PARA_LOCAL_KEY_DATA 65 /* BTM_SECURITY_LOCAL_KEY_DATA_LEN */
#define MICO_BT_DCT_NAME 249
#define MICO_BT_DCT_MAX_KEYBLOBS 146 /* Maximum size of key blobs to be stored := size of BR-EDR link keys + size of BLE keys*/
#define MICO_BT_DCT_ADDR_FIELD 6
#define MICO_BT_DCT_LENGTH_FIELD 2
#ifndef MICO_BT_DCT_MAX_DEVICES
#define MICO_BT_DCT_MAX_DEVICES 10 /* Maximum number of device records stored in nvram */
#endif
#define MICO_BT_DCT_ADDR_TYPE 1
#define MICO_BT_DCT_DEVICE_TYPE 1
/* Length of BD_ADDR + 2bytes length field */
#define MICO_BT_DCT_ENTRY_HDR_LENGTH (MICO_BT_DCT_ADDR_FIELD + MICO_BT_DCT_LENGTH_FIELD + MICO_BT_DCT_ADDR_TYPE + MICO_BT_DCT_DEVICE_TYPE)
#define MICO_BT_DCT_LOCAL_KEY_OFFSET OFFSETOF( mico_bt_config_t, bluetooth_local_key )
#define MICO_BT_DCT_REMOTE_KEY_OFFSET OFFSETOF( mico_bt_config_t, bluetooth_remote_key )
#pragma pack(1)
typedef struct
{
// uint8_t bluetooth_local_addeess[6];
// uint8_t bluetooth_local_name[249]; /* including null termination */
uint8_t bluetooth_local_key[MICO_BT_PARA_LOCAL_KEY_DATA];
uint8_t bluetooth_remote_key[MICO_BT_DCT_ENTRY_HDR_LENGTH + MICO_BT_DCT_MAX_KEYBLOBS][MICO_BT_DCT_MAX_DEVICES];
uint8_t padding[1]; /* to ensure 32-bit aligned size */
} mico_bt_config_t;
#pragma pack()
#endif

View file

@ -0,0 +1,90 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#pragma once
#include <stddef.h>
#ifdef __cplusplus
extern "C"
{
#endif
/******************************************************
* Macros
******************************************************/
#ifndef WEAK
#ifndef __MINGW32__
#define WEAK __attribute__((weak))
#else
/* MinGW doesn't support weak */
#define WEAK
#endif
#endif
#ifndef USED
#define USED __attribute__((used))
#endif
#ifndef MAY_BE_UNUSED
#define MAY_BE_UNUSED __attribute__((unused))
#endif
#ifndef NORETURN
#define NORETURN __attribute__((noreturn))
#endif
#ifndef ALIGNED
#define ALIGNED(size) __attribute__((aligned(size)))
#endif
#ifndef SECTION
#define SECTION(name) __attribute__((section(name)))
#endif
#ifndef NEVER_INLINE
#define NEVER_INLINE __attribute__((noinline))
#endif
#ifndef ALWAYS_INLINE
#define ALWAYS_INLINE __attribute__((always_inline))
#endif
/******************************************************
* Constants
******************************************************/
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Global Variables
******************************************************/
/******************************************************
* Function Declarations
******************************************************/
void *memrchr( const void *s, int c, size_t n );
/* Windows doesn't come with support for strlcpy */
#ifdef WIN32
size_t strlcpy (char *dest, const char *src, size_t size);
#endif /* WIN32 */
#ifdef __cplusplus
} /* extern "C" */
#endif