fix:wifi_app mistake (#13)

This commit is contained in:
luckfox-eng33
2023-10-27 17:12:27 +08:00
committed by GitHub
parent b496d0e4f8
commit 395d161f40
1323 changed files with 537512 additions and 492255 deletions
+1 -9
View File
@@ -1,12 +1,4 @@
# *.o *.o
# !hostapd-2.6/hostapd/*.o
# !hostapd-2.6/src/common/*.o
# !hostapd-2.6/src/crypto/*.o
# !hostapd-2.6/src/drivers/*.o
# !hostapd-2.6/src/drivers/*.o
# !hostapd-2.6/src/drivers/*.o
# !hostapd-2.6/src/drivers/*.o
hostapd-2.6/hostapd/hostapd hostapd-2.6/hostapd/hostapd
hostapd-2.6/hostapd/hostapd_cli hostapd-2.6/hostapd/hostapd_cli
install_out install_out
File diff suppressed because it is too large Load Diff
+121 -209
View File
@@ -24,27 +24,23 @@
#define cJSON__h #define cJSON__h
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
#if !defined(__WINDOWS__) && \ #if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
(defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__ #define __WINDOWS__
#endif #endif
#ifdef __WINDOWS__ #ifdef __WINDOWS__
/* When compiling for windows, we specify a specific calling convention to avoid /* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
issues where we are being called from a project with a different default calling
convention. For windows you have 3 define options:
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
dllexport symbols CJSON_EXPORT_SYMBOLS - Define this on library build when you CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
want to dllexport symbols (default) CJSON_IMPORT_SYMBOLS - Define this if you CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
want to dllimport symbol
For *nix builds that support visibility attribute, you can define similar For *nix builds that support visibility attribute, you can define similar behavior by
behavior by
setting default visibility to hidden by adding setting default visibility to hidden by adding
-fvisibility=hidden (for gcc) -fvisibility=hidden (for gcc)
@@ -52,35 +48,31 @@ or
-xldscope=hidden (for sun cc) -xldscope=hidden (for sun cc)
to CFLAGS to CFLAGS
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
CJSON_EXPORT_SYMBOLS does
*/ */
#define CJSON_CDECL __cdecl #define CJSON_CDECL __cdecl
#define CJSON_STDCALL __stdcall #define CJSON_STDCALL __stdcall
/* export symbols by default, this is necessary for copy pasting the C and /* export symbols by default, this is necessary for copy pasting the C and header file */
* header file */ #if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && \
!defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_EXPORT_SYMBOLS #define CJSON_EXPORT_SYMBOLS
#endif #endif
#if defined(CJSON_HIDE_SYMBOLS) #if defined(CJSON_HIDE_SYMBOLS)
#define CJSON_PUBLIC(type) type CJSON_STDCALL #define CJSON_PUBLIC(type) type CJSON_STDCALL
#elif defined(CJSON_EXPORT_SYMBOLS) #elif defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL #define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
#elif defined(CJSON_IMPORT_SYMBOLS) #elif defined(CJSON_IMPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL #define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
#endif #endif
#else /* !__WINDOWS__ */ #else /* !__WINDOWS__ */
#define CJSON_CDECL #define CJSON_CDECL
#define CJSON_STDCALL #define CJSON_STDCALL
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && \ #if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
defined(CJSON_API_VISIBILITY) #define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#else #else
#define CJSON_PUBLIC(type) type #define CJSON_PUBLIC(type) type
#endif #endif
@@ -95,140 +87,109 @@ CJSON_EXPORT_SYMBOLS does
/* cJSON Types: */ /* cJSON Types: */
#define cJSON_Invalid (0) #define cJSON_Invalid (0)
#define cJSON_False (1 << 0) #define cJSON_False (1 << 0)
#define cJSON_True (1 << 1) #define cJSON_True (1 << 1)
#define cJSON_NULL (1 << 2) #define cJSON_NULL (1 << 2)
#define cJSON_Number (1 << 3) #define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4) #define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5) #define cJSON_Array (1 << 5)
#define cJSON_Object (1 << 6) #define cJSON_Object (1 << 6)
#define cJSON_Raw (1 << 7) /* raw json */ #define cJSON_Raw (1 << 7) /* raw json */
#define cJSON_IsReference 256 #define cJSON_IsReference 256
#define cJSON_StringIsConst 512 #define cJSON_StringIsConst 512
/* The cJSON structure: */ /* The cJSON structure: */
typedef struct cJSON { typedef struct cJSON
/* next/prev allow you to walk array/object chains. Alternatively, use {
* GetArraySize/GetArrayItem/GetObjectItem */ /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *next; struct cJSON *next;
struct cJSON *prev; struct cJSON *prev;
/* An array or object item will have a child pointer pointing to a chain of /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
* the items in the array/object. */ struct cJSON *child;
struct cJSON *child;
/* The type of the item, as above. */ /* The type of the item, as above. */
int type; int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */ /* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *valuestring; char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint; int valueint;
/* The item's number, if type==cJSON_Number */ /* The item's number, if type==cJSON_Number */
double valuedouble; double valuedouble;
/* The item's name string, if this item is the child of, or is in the list of /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
* subitems of an object. */ char *string;
char *string;
} cJSON; } cJSON;
typedef struct cJSON_Hooks { typedef struct cJSON_Hooks
/* malloc/free are CDECL on Windows regardless of the default calling {
* convention of the compiler, so ensure the hooks allow passing those /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
* functions directly. */ void *(CJSON_CDECL *malloc_fn)(size_t sz);
void *(CJSON_CDECL *malloc_fn)(size_t sz); void (CJSON_CDECL *free_fn)(void *ptr);
void(CJSON_CDECL *free_fn)(void *ptr);
} cJSON_Hooks; } cJSON_Hooks;
typedef int cJSON_bool; typedef int cJSON_bool;
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse /* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
* them. This is to prevent stack overflows. */ * This is to prevent stack overflows. */
#ifndef CJSON_NESTING_LIMIT #ifndef CJSON_NESTING_LIMIT
#define CJSON_NESTING_LIMIT 1000 #define CJSON_NESTING_LIMIT 1000
#endif #endif
/* returns the version of cJSON as a string */ /* returns the version of cJSON as a string */
CJSON_PUBLIC(const char *) cJSON_Version(void); CJSON_PUBLIC(const char*) cJSON_Version(void);
/* Supply malloc, realloc and free functions to cJSON */ /* Supply malloc, realloc and free functions to cJSON */
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks *hooks); CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
/* Memory Management: the caller is always responsible to free the results from /* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
* all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib /* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
* free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is
* cJSON_PrintPreallocated, where the caller has full responsibility of the
* buffer. */
/* Supply a block of JSON, and this returns a cJSON object you can interrogate.
*/
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
cJSON_ParseWithLength(const char *value, size_t buffer_length); /* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
/* ParseWithOpts allows you to require (and check) that the JSON is null /* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
* terminated, and to retrieve the pointer to the final byte parsed. */ CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
/* If you supply a ptr in return_parse_end and parsing fails, then CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
* return_parse_end will contain a pointer to the error so will match
* cJSON_GetErrorPtr(). */
CJSON_PUBLIC(cJSON *)
cJSON_ParseWithOpts(const char *value, const char **return_parse_end,
cJSON_bool require_null_terminated);
CJSON_PUBLIC(cJSON *)
cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length,
const char **return_parse_end,
cJSON_bool require_null_terminated);
/* Render a cJSON entity to text for transfer/storage. */ /* Render a cJSON entity to text for transfer/storage. */
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. */ /* Render a cJSON entity to text for transfer/storage without any formatting. */
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item); CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess /* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
* at the final size. guessing well reduces reallocation. fmt=0 gives CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
* unformatted, =1 gives formatted */ /* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
CJSON_PUBLIC(char *) /* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt); CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
/* Render a cJSON entity to text using a buffer already allocated in memory with
* given length. Returns 1 on success and 0 on failure. */
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will
* use, so to be safe allocate 5 bytes more than you actually need */
CJSON_PUBLIC(cJSON_bool)
cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length,
const cJSON_bool format);
/* Delete a cJSON entity and all subentities. */ /* Delete a cJSON entity and all subentities. */
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item); CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
/* Returns the number of items in an array (or object). */ /* Returns the number of items in an array (or object). */
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array); CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
/* Retrieve item number "index" from array "array". Returns NULL if /* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
* unsuccessful. */
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index); CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
/* Get item "string" from object. Case insensitive. */ /* Get item "string" from object. Case insensitive. */
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
cJSON_GetObjectItem(const cJSON *const object, const char *const string); CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
cJSON_GetObjectItemCaseSensitive(const cJSON *const object, /* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
const char *const string);
CJSON_PUBLIC(cJSON_bool)
cJSON_HasObjectItem(const cJSON *object, const char *string);
/* For analysing failed parses. This returns a pointer to the parse error.
* You'll probably need to look a few chars back to make sense of it. Defined
* when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
/* Check item type and return its value */ /* Check item type and return its value */
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON *const item); CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON *const item); CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
/* These functions check the type of an item */ /* These functions check the type of an item */
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
/* These calls create a cJSON item of the appropriate type. */ /* These calls create a cJSON item of the appropriate type. */
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void); CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
@@ -251,126 +212,77 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child); CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
/* These utilities create an Array of count items. /* These utilities create an Array of count items.
* The parameter count cannot be greater than the number of elements in the * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
* number array, otherwise array access will be out of bounds.*/
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
cJSON_CreateStringArray(const char *const *strings, int count);
/* Append item to the specified array/object. */ /* Append item to the specified array/object. */
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item); CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(cJSON_bool) CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); /* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
/* Use this when string is definitely const (i.e. a literal, or as good as), and * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
* will definitely survive the cJSON object. WARNING: When this function was * writing to `item->string` */
* used, make sure to always check that (item->type & cJSON_StringIsConst) is CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
* zero before writing to `item->string` */ /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
CJSON_PUBLIC(cJSON_bool) CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
/* Append reference to item to the specified array/object. Use this when you
* want to add an existing cJSON to a new cJSON, but don't want to corrupt your
* existing cJSON. */
CJSON_PUBLIC(cJSON_bool)
cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(cJSON_bool)
cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
/* Remove/Detach items from Arrays/Objects. */ /* Remove/Detach items from Arrays/Objects. */
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
cJSON_DetachItemViaPointer(cJSON *parent, cJSON *const item);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which); CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which); CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
cJSON_DetachItemFromObject(cJSON *object, const char *string); CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string); CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
CJSON_PUBLIC(void)
cJSON_DeleteItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(void)
cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
/* Update array items. */ /* Update array items. */
CJSON_PUBLIC(cJSON_bool) CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
cJSON_InsertItemInArray( CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
cJSON *array, int which, CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
cJSON *newitem); /* Shifts pre-existing items to the right. */ CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
CJSON_PUBLIC(cJSON_bool) CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
cJSON_ReplaceItemViaPointer(cJSON *const parent, cJSON *const item,
cJSON *replacement);
CJSON_PUBLIC(cJSON_bool)
cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
CJSON_PUBLIC(cJSON_bool)
cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem);
CJSON_PUBLIC(cJSON_bool)
cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string,
cJSON *newitem);
/* Duplicate a cJSON item */ /* Duplicate a cJSON item */
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new /* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
* memory that will need to be released. With recurse!=0, it will duplicate any * need to be released. With recurse!=0, it will duplicate any children connected to the item.
* children connected to the item. The item->next and ->prev pointers are always * The item->next and ->prev pointers are always zero on return from Duplicate. */
* zero on return from Duplicate. */ /* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
/* Recursively compare two cJSON items for equality. If either a or b is NULL or * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
* invalid, they will be considered unequal. case_sensitive determines if object CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
* keys are treated case sensitive (1) or case insensitive (0) */
CJSON_PUBLIC(cJSON_bool)
cJSON_Compare(const cJSON *const a, const cJSON *const b,
const cJSON_bool case_sensitive);
/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from /* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
* strings. The input pointer json cannot point to a read-only address area, * The input pointer json cannot point to a read-only address area, such as a string constant,
* such as a string constant, but should point to a readable and writable adress * but should point to a readable and writable adress area. */
* area. */
CJSON_PUBLIC(void) cJSON_Minify(char *json); CJSON_PUBLIC(void) cJSON_Minify(char *json);
/* Helper functions for creating and adding items to an object at the same time. /* Helper functions for creating and adding items to an object at the same time.
* They return the added item or NULL on failure. */ * They return the added item or NULL on failure. */
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
cJSON_AddNullToObject(cJSON *const object, const char *const name); CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
cJSON_AddTrueToObject(cJSON *const object, const char *const name); CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
cJSON_AddFalseToObject(cJSON *const object, const char *const name); CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
cJSON_AddBoolToObject(cJSON *const object, const char *const name, CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
const cJSON_bool boolean); CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON *)
cJSON_AddNumberToObject(cJSON *const object, const char *const name,
const double number);
CJSON_PUBLIC(cJSON *)
cJSON_AddStringToObject(cJSON *const object, const char *const name,
const char *const string);
CJSON_PUBLIC(cJSON *)
cJSON_AddRawToObject(cJSON *const object, const char *const name,
const char *const raw);
CJSON_PUBLIC(cJSON *)
cJSON_AddObjectToObject(cJSON *const object, const char *const name);
CJSON_PUBLIC(cJSON *)
cJSON_AddArrayToObject(cJSON *const object, const char *const name);
/* When assigning an integer value, it needs to be propagated to valuedouble /* When assigning an integer value, it needs to be propagated to valuedouble too. */
* too. */ #define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
#define cJSON_SetIntValue(object, number) \
((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
/* helper for the cJSON_SetNumberValue macro */ /* helper for the cJSON_SetNumberValue macro */
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
#define cJSON_SetNumberValue(object, number) \ #define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) /* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
/* Change the valuestring of a cJSON_String object, only takes effect when type CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
* of object is cJSON_String */
CJSON_PUBLIC(char *)
cJSON_SetValuestring(cJSON *object, const char *valuestring);
/* Macro for iterating over an array or object */ /* Macro for iterating over an array or object */
#define cJSON_ArrayForEach(element, array) \ #define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
for (element = (array != NULL) ? (array)->child : NULL; element != NULL; \
element = element->next)
/* malloc/free objects using the malloc/free functions that have been set with /* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
* cJSON_InitHooks */
CJSON_PUBLIC(void *) cJSON_malloc(size_t size); CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
CJSON_PUBLIC(void) cJSON_free(void *object); CJSON_PUBLIC(void) cJSON_free(void *object);
@@ -1,173 +1,173 @@
/* /*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
* reserved. Description: sample cli file. Author: Hisilicon Create: 2020-09-09 * Description: sample cli file.
* Author: Hisilicon
* Create: 2020-09-09
*/ */
/***************************************************************************** /*****************************************************************************
1 头文件包含 1 头文件包含
*****************************************************************************/ *****************************************************************************/
#include "hi_base.h" #include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "hi_types.h" #include "hi_types.h"
#include "securec.h" #include "securec.h"
#include <arpa/inet.h> #include "hi_base.h"
#include <errno.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include "cJSON.h" #include "cJSON.h"
/***************************************************************************** /*****************************************************************************
4 函数实现 4 函数实现
*****************************************************************************/ *****************************************************************************/
hi_void client_wait_event(hi_u8 cmdval) { hi_void client_wait_event(hi_u8 cmdval)
ssize_t recvbytes; {
char buf[SOCK_BUF_MAX]; ssize_t recvbytes;
struct sockaddr_in clientaddr; char buf[SOCK_BUF_MAX];
socklen_t addrlen = sizeof(clientaddr); struct sockaddr_in clientaddr;
struct timeval tv; socklen_t addrlen = sizeof(clientaddr);
struct timeval tv;
int sockfd = socket(AF_INET, SOCK_DGRAM, 0); int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) { if (sockfd == -1) {
sample_log_print("socket error:%s\n", strerror(errno)); sample_log_print("socket error:%s\n", strerror(errno));
return -1; return -1;
}
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(SOCK_EVENT_PORT);
if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) ==
-1) {
sample_log_print("bind error:%s", strerror(errno));
goto error_bind;
}
tv.tv_sec = 10;
tv.tv_usec = 0;
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)) !=
0) {
sample_log_print("setsockopt error:%s", strerror(errno));
goto error_setsockopt;
}
memset(buf, 0, sizeof(buf));
recvbytes = recvfrom(sockfd, buf, sizeof(buf), 0,
(struct sockaddr *)&clientaddr, &addrlen);
if (recvbytes < 0) {
sample_log_print("recvfrom error:%s\n", strerror(errno));
goto error_recvfrom;
}
sample_log_print("SAMPLE_CLIENT:--[%s]-[%d]--\n", buf, strlen(buf));
cJSON *root = cJSON_Parse(buf);
if (NULL == root) {
sample_log_print("SAMPLE_CLIENT:parseJson---Parse fail\n");
goto error_recvfrom;
}
cJSON *item = cJSON_GetObjectItem(root, "cmd");
if (NULL != item) {
if (cmdval == atoi(item->valuestring)) {
} }
}
cJSON_Delete(root); struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(SOCK_EVENT_PORT);
if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
sample_log_print("bind error:%s", strerror(errno));
goto error_bind;
}
tv.tv_sec = 10;
tv.tv_usec = 0;
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)) != 0) {
sample_log_print("setsockopt error:%s", strerror(errno));
goto error_setsockopt;
}
memset(buf, 0, sizeof(buf));
recvbytes = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&clientaddr, &addrlen);
if (recvbytes < 0) {
sample_log_print("recvfrom error:%s\n", strerror(errno));
goto error_recvfrom;
}
sample_log_print("SAMPLE_CLIENT:--[%s]-[%d]--\n", buf, strlen(buf));
cJSON* root = cJSON_Parse(buf);
if (NULL == root) {
sample_log_print("SAMPLE_CLIENT:parseJson---Parse fail\n");
goto error_recvfrom;
}
cJSON* item = cJSON_GetObjectItem(root, "cmd");
if (NULL != item) {
if (cmdval == atoi(item->valuestring)) {
}
}
cJSON_Delete(root);
error_bind: error_bind:
error_setsockopt: error_setsockopt:
error_recvfrom: error_recvfrom:
close(sockfd); close(sockfd);
} }
hi_void client_send_cmd(hi_s32 sockfd, const hi_char *cmd, hi_u32 cmd_len) { hi_void client_send_cmd(hi_s32 sockfd, const hi_char *cmd, hi_u32 cmd_len)
struct sockaddr_in servaddr; {
ssize_t recvbytes; struct sockaddr_in servaddr;
hi_char buf[SOCK_BUF_MAX]; ssize_t recvbytes;
struct sockaddr_in clientaddr; hi_char buf[SOCK_BUF_MAX];
socklen_t addrlen = sizeof(clientaddr); struct sockaddr_in clientaddr;
struct timeval tv; socklen_t addrlen = sizeof(clientaddr);
int retry = 3; struct timeval tv;
int retry = 3;
servaddr.sin_family = AF_INET; servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(SOCK_PORT); servaddr.sin_port = htons(SOCK_PORT);
if (cmd_len > SOCK_BUF_MAX) { if (cmd_len > SOCK_BUF_MAX) {
sample_log_print("cmd length is overflow\n"); sample_log_print("cmd length is overflow\n");
return; return;
}
if (sendto(sockfd, cmd, strlen(cmd), 0, (const struct sockaddr *)&servaddr,
sizeof(servaddr)) == -1) {
sample_log_print("SAMPLE_CLIENT: sendto error:%s\n", strerror(errno));
return;
}
tv.tv_sec = 10;
tv.tv_usec = 0;
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)) !=
0) {
sample_log_print("setsockopt error:%s", strerror(errno));
return;
}
memset(buf, 0, sizeof(buf));
recvbytes = recvfrom(sockfd, buf, sizeof(buf), 0,
(struct sockaddr *)&clientaddr, &addrlen);
if (recvbytes < 0) {
sample_log_print("recvfrom error:%s\n", strerror(errno));
return;
}
if (strcmp("OK", buf) != 0) {
sample_log_print("SAMPLE_CLIENT: sendto cmd error!\n");
return;
}
if (strcmp("getmac", cmd) == 0) {
client_wait_event(2);
} else if (strcmp("getip", cmd) == 0) {
client_wait_event(3);
} else if (strcmp("wakecode", cmd) == 0) {
client_wait_event(15);
} else if (strcmp("getall", cmd) == 0) {
client_wait_event(20);
}
sample_log_print("SAMPLE_CLIENT: send cmd ok!\n");
}
hi_s32 main(hi_s32 argc, const hi_char **argv) {
(void)argc;
hi_char cmd[SOCK_BUF_MAX] = {0};
if (argc < 2 || argv == NULL) { /* 2:参数个数 */
sample_log_print("usage sample_cli <cmd>\n");
return -1;
}
if (strcmp("pirset", argv[1]) == 0) {
if (sprintf_s(cmd, sizeof(cmd), "%s %s", argv[1], argv[2]) < 0) {
sample_log_print("sprintf_s is error\n");
} }
} else {
if (strcpy_s(cmd, sizeof(cmd), argv[1]) < 0) { if (sendto(sockfd, cmd, strlen(cmd), 0, (const struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
sample_log_print("strcpt is error\n"); sample_log_print("SAMPLE_CLIENT: sendto error:%s\n", strerror(errno));
return;
} }
cmd[strlen(argv[1])] = '\0';
}
hi_s32 sockfd = socket(AF_INET, SOCK_DGRAM, 0); tv.tv_sec = 10;
if (sockfd == -1) { tv.tv_usec = 0;
sample_log_print("socket is error:%s\n", strerror(errno)); if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)) != 0) {
return -1; sample_log_print("setsockopt error:%s", strerror(errno));
} return;
}
client_send_cmd(sockfd, cmd, strlen(cmd)); memset(buf, 0, sizeof(buf));
close(sockfd); recvbytes = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&clientaddr, &addrlen);
return 0; if (recvbytes < 0) {
sample_log_print("recvfrom error:%s\n", strerror(errno));
return;
}
if (strcmp("OK", buf) != 0) {
sample_log_print("SAMPLE_CLIENT: sendto cmd error!\n");
return;
}
if (strcmp("getmac", cmd) == 0) {
client_wait_event(2);
} else if (strcmp("getip", cmd) == 0) {
client_wait_event(3);
} else if (strcmp("wakecode", cmd) == 0) {
client_wait_event(15);
} else if (strcmp("getall", cmd) == 0) {
client_wait_event(20);
}
sample_log_print("SAMPLE_CLIENT: send cmd ok!\n");
} }
hi_s32 main(hi_s32 argc, const hi_char **argv)
{
(void)argc;
hi_char cmd[SOCK_BUF_MAX] = {0};
if (argc < 2 || argv == NULL) { /* 2:参数个数 */
sample_log_print("usage sample_cli <cmd>\n");
return -1;
}
if (strcmp("pirset", argv[1]) == 0) {
if (sprintf_s(cmd, sizeof(cmd), "%s %s", argv[1], argv[2]) < 0) {
sample_log_print("sprintf_s is error\n");
}
} else {
if (strcpy_s(cmd, sizeof(cmd), argv[1]) < 0) {
sample_log_print("strcpt is error\n");
}
cmd[strlen(argv[1])] = '\0';
}
hi_s32 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {
sample_log_print("socket is error:%s\n", strerror(errno));
return -1;
}
client_send_cmd(sockfd, cmd, strlen(cmd));
close(sockfd);
return 0;
}
+11 -10
View File
@@ -1,7 +1,8 @@
/* /*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
* reserved. Description: header file for Wi-Fi Station component Author: * Description: header file for Wi-Fi Station component
* Hisilicon Create: 2020-09-09 * Author: Hisilicon
* Create: 2020-09-09
*/ */
#ifndef __SAMPLE_COMM_H__ #ifndef __SAMPLE_COMM_H__
@@ -12,17 +13,17 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
#define CMD_MAX_LEN 1500 #define CMD_MAX_LEN 1500
#define SOCK_BUF_MAX 1500 #define SOCK_BUF_MAX 1500
#define SOCK_PORT 8822 #define SOCK_PORT 8822
#define SOCK_EVENT_PORT 8823 #define SOCK_EVENT_PORT 8823
#define sample_log_print(fmt, args...) \ #define sample_log_print(fmt, args...) \
printf("[%s][%s][l:%d]," fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, \ printf("[%s][%s][l:%d]," fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, ##args);
##args);
#define sample_unused(x) ((x) = (x)) #define sample_unused(x) ((x) = (x))
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif #endif
@@ -1,470 +1,474 @@
/* /*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2019. All rights * Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2019. All rights reserved.
* reserved. Description: Error code returned by the interface. Author: * Description: Error code returned by the interface.
* Hisilicon Create: 2019-08-02 * Author: Hisilicon
* Create: 2019-08-02
*/ */
#ifndef __HI_ERRNO_H__ #ifndef __HI_ERRNO_H__
#define __HI_ERRNO_H__ #define __HI_ERRNO_H__
/***************************************************************************** /*****************************************************************************
* 1、通用错误码。注意0x8000 0000最好别用,产生截断误判为成功 * 1、通用错误码。注意0x8000 0000最好别用,产生截断误判为成功
*****************************************************************************/ *****************************************************************************/
#define HI_SUCCESS 0 #define HI_SUCCESS 0
#define HI_FAILURE (hi_u32)(-1) #define HI_FAILURE (hi_u32)(-1)
#define HI_S_FAILURE (-1) #define HI_S_FAILURE (-1)
#define HI_MALLOC_FAILUE 0x80000001 #define HI_MALLOC_FAILUE 0x80000001
#define HI_TIMEOUT 0x80000002 #define HI_TIMEOUT 0x80000002
#define HI_RECVING 0x80000003 #define HI_RECVING 0x80000003
#define HI_MEMCPY_S 0x80000004 #define HI_MEMCPY_S 0x80000004
#define HI_MEMSET_S 0x80000005 #define HI_MEMSET_S 0x80000005
#define HI_SPRINTF_S 0x80000006 #define HI_SPRINTF_S 0x80000006
#define HI_STRCPY_S 0x80000007 #define HI_STRCPY_S 0x80000007
/***************************************************************************** /*****************************************************************************
* 2、系统适配层:错误码 * 2、系统适配层:错误码
*****************************************************************************/ *****************************************************************************/
/* 任务 */ /* 任务 */
#define HI_ERR_TASK_INVALID_PARAM 0x80000080 #define HI_ERR_TASK_INVALID_PARAM 0x80000080
#define HI_ERR_TASK_CREATE_FAIL 0x80000081 #define HI_ERR_TASK_CREATE_FAIL 0x80000081
#define HI_ERR_TASK_DELETE_FAIL 0x80000082 #define HI_ERR_TASK_DELETE_FAIL 0x80000082
#define HI_ERR_TASK_SUPPEND_FAIL 0x80000083 #define HI_ERR_TASK_SUPPEND_FAIL 0x80000083
#define HI_ERR_TASK_RESUME_FAIL 0x80000084 #define HI_ERR_TASK_RESUME_FAIL 0x80000084
#define HI_ERR_TASK_GET_PRI_FAIL 0x80000085 #define HI_ERR_TASK_GET_PRI_FAIL 0x80000085
#define HI_ERR_TASK_SET_PRI_FAIL 0x80000086 #define HI_ERR_TASK_SET_PRI_FAIL 0x80000086
#define HI_ERR_TASK_LOCK_FAIL 0x80000087 #define HI_ERR_TASK_LOCK_FAIL 0x80000087
#define HI_ERR_TASK_UNLOCK_FAIL 0x80000088 #define HI_ERR_TASK_UNLOCK_FAIL 0x80000088
#define HI_ERR_TASK_DELAY_FAIL 0x80000089 #define HI_ERR_TASK_DELAY_FAIL 0x80000089
#define HI_ERR_TASK_GET_INFO_FAIL 0x8000008A #define HI_ERR_TASK_GET_INFO_FAIL 0x8000008A
#define HI_ERR_TASK_REGISTER_SCHEDULE_FAIL 0x8000008B #define HI_ERR_TASK_REGISTER_SCHEDULE_FAIL 0x8000008B
#define HI_ERR_TASK_NOT_CREATED 0x8000008C #define HI_ERR_TASK_NOT_CREATED 0x8000008C
/* 中断ISR */ /* 中断ISR */
#define HI_ERR_ISR_INVALID_PARAM 0x800000C0 #define HI_ERR_ISR_INVALID_PARAM 0x800000C0
#define HI_ERR_ISR_REQ_IRQ_FAIL 0x800000C1 #define HI_ERR_ISR_REQ_IRQ_FAIL 0x800000C1
#define HI_ERR_ISR_ADD_JOB_MALLOC_FAIL 0x800000C2 #define HI_ERR_ISR_ADD_JOB_MALLOC_FAIL 0x800000C2
#define HI_ERR_ISR_ADD_JOB_SYS_FAIL 0x800000C3 #define HI_ERR_ISR_ADD_JOB_SYS_FAIL 0x800000C3
#define HI_ERR_ISR_DEL_IRQ_FAIL 0x800000C4 #define HI_ERR_ISR_DEL_IRQ_FAIL 0x800000C4
#define HI_ERR_ISR_ALREADY_CREATED 0x800000C5 #define HI_ERR_ISR_ALREADY_CREATED 0x800000C5
#define HI_ERR_ISR_NOT_CREATED 0x800000C6 #define HI_ERR_ISR_NOT_CREATED 0x800000C6
#define HI_ERR_ISR_ENABLE_IRQ_FAIL 0x800000C7 #define HI_ERR_ISR_ENABLE_IRQ_FAIL 0x800000C7
#define HI_ERR_ISR_IRQ_ADDR_NOK 0x800000C8 #define HI_ERR_ISR_IRQ_ADDR_NOK 0x800000C8
/* 内存 */ /* 内存 */
#define HI_ERR_MEM_INVALID_PARAM 0x80000100 #define HI_ERR_MEM_INVALID_PARAM 0x80000100
#define HI_ERR_MEM_CREAT_POOL_FAIL 0x80000101 #define HI_ERR_MEM_CREAT_POOL_FAIL 0x80000101
#define HI_ERR_MEM_CREATE_POOL_NOT_ENOUGH_HANDLE 0x80000102 #define HI_ERR_MEM_CREATE_POOL_NOT_ENOUGH_HANDLE 0x80000102
#define HI_ERR_MEM_FREE_FAIL 0x80000103 #define HI_ERR_MEM_FREE_FAIL 0x80000103
#define HI_ERR_MEM_RE_INIT 0x80000104 #define HI_ERR_MEM_RE_INIT 0x80000104
#define HI_ERR_MEM_NOT_INIT 0x80000105 #define HI_ERR_MEM_NOT_INIT 0x80000105
#define HI_ERR_MEM_CREAT_POOL_MALLOC_FAIL 0x80000106 #define HI_ERR_MEM_CREAT_POOL_MALLOC_FAIL 0x80000106
#define HI_ERR_MEM_GET_INFO_FAIL 0x80000107 #define HI_ERR_MEM_GET_INFO_FAIL 0x80000107
#define HI_ERR_MEM_GET_OS_INFO_NOK 0x80000108 #define HI_ERR_MEM_GET_OS_INFO_NOK 0x80000108
/* OSTIMER定时器 */ /* OSTIMER定时器 */
#define HI_ERR_TIMER_FAILURE 0x80000140 #define HI_ERR_TIMER_FAILURE 0x80000140
#define HI_ERR_TIMER_INVALID_PARAM 0x80000141 #define HI_ERR_TIMER_INVALID_PARAM 0x80000141
#define HI_ERR_TIMER_CREATE_HANDLE_FAIL 0x80000142 #define HI_ERR_TIMER_CREATE_HANDLE_FAIL 0x80000142
#define HI_ERR_TIMER_START_FAIL 0x80000143 #define HI_ERR_TIMER_START_FAIL 0x80000143
#define HI_ERR_TIMER_HANDLE_NOT_CREATE 0x80000144 #define HI_ERR_TIMER_HANDLE_NOT_CREATE 0x80000144
#define HI_ERR_TIMER_HANDLE_INVALID 0x80000145 #define HI_ERR_TIMER_HANDLE_INVALID 0x80000145
#define HI_ERR_TIMER_STATUS_INVALID 0x80000146 #define HI_ERR_TIMER_STATUS_INVALID 0x80000146
#define HI_ERR_TIMER_STATUS_START 0x80000147 #define HI_ERR_TIMER_STATUS_START 0x80000147
#define HI_ERR_TIMER_INVALID_MODE 0x80000148 #define HI_ERR_TIMER_INVALID_MODE 0x80000148
#define HI_ERR_TIMER_EXPIRE_INVALID 0x80000149 #define HI_ERR_TIMER_EXPIRE_INVALID 0x80000149
#define HI_ERR_TIMER_FUNCTION_NULL 0x8000014A #define HI_ERR_TIMER_FUNCTION_NULL 0x8000014A
#define HI_ERR_TIMER_HANDLE_MAXSIZE 0x8000014B #define HI_ERR_TIMER_HANDLE_MAXSIZE 0x8000014B
#define HI_ERR_TIMER_MALLOC_FAIL 0x8000014C #define HI_ERR_TIMER_MALLOC_FAIL 0x8000014C
#define HI_ERR_TIMER_NOT_INIT 0x8000014D #define HI_ERR_TIMER_NOT_INIT 0x8000014D
/* 信号量 */ /* 信号量 */
#define HI_ERR_SEM_INVALID_PARAM 0x80000180 #define HI_ERR_SEM_INVALID_PARAM 0x80000180
#define HI_ERR_SEM_CREATE_FAIL 0x80000181 #define HI_ERR_SEM_CREATE_FAIL 0x80000181
#define HI_ERR_SEM_DELETE_FAIL 0x80000182 #define HI_ERR_SEM_DELETE_FAIL 0x80000182
#define HI_ERR_SEM_WAIT_FAIL 0x80000183 #define HI_ERR_SEM_WAIT_FAIL 0x80000183
#define HI_ERR_SEM_SIG_FAIL 0x80000184 #define HI_ERR_SEM_SIG_FAIL 0x80000184
#define HI_ERR_SEM_WAIT_TIME_OUT 0x80000185 #define HI_ERR_SEM_WAIT_TIME_OUT 0x80000185
/* 互斥锁 */ /* 互斥锁 */
#define HI_ERR_MUX_INVALID_PARAM 0x800001C0 #define HI_ERR_MUX_INVALID_PARAM 0x800001C0
#define HI_ERR_MUX_CREATE_FAIL 0x800001C1 #define HI_ERR_MUX_CREATE_FAIL 0x800001C1
#define HI_ERR_MUX_DELETE_FAIL 0x800001C2 #define HI_ERR_MUX_DELETE_FAIL 0x800001C2
#define HI_ERR_MUX_PEND_FAIL 0x800001C3 #define HI_ERR_MUX_PEND_FAIL 0x800001C3
#define HI_ERR_MUX_POST_FAIL 0x800001C4 #define HI_ERR_MUX_POST_FAIL 0x800001C4
/* 消息 */ /* 消息 */
#define HI_ERR_MSG_INVALID_PARAM 0x80000200 #define HI_ERR_MSG_INVALID_PARAM 0x80000200
#define HI_ERR_MSG_CREATE_Q_FAIL 0x80000201 #define HI_ERR_MSG_CREATE_Q_FAIL 0x80000201
#define HI_ERR_MSG_DELETE_Q_FAIL 0x80000202 #define HI_ERR_MSG_DELETE_Q_FAIL 0x80000202
#define HI_ERR_MSG_WAIT_FAIL 0x80000203 #define HI_ERR_MSG_WAIT_FAIL 0x80000203
#define HI_ERR_MSG_SEND_FAIL 0x80000204 #define HI_ERR_MSG_SEND_FAIL 0x80000204
#define HI_ERR_MSG_GET_Q_INFO_FAIL 0x80000205 #define HI_ERR_MSG_GET_Q_INFO_FAIL 0x80000205
#define HI_ERR_MSG_Q_DELETE_FAIL 0x80000206 #define HI_ERR_MSG_Q_DELETE_FAIL 0x80000206
#define HI_ERR_MSG_WAIT_TIME_OUT 0x80000207 #define HI_ERR_MSG_WAIT_TIME_OUT 0x80000207
/* 事件 */ /* 事件 */
#define HI_ERR_EVENT_INVALID_PARAM 0x80000240 #define HI_ERR_EVENT_INVALID_PARAM 0x80000240
#define HI_ERR_EVENT_CREATE_NO_HADNLE 0x80000241 #define HI_ERR_EVENT_CREATE_NO_HADNLE 0x80000241
#define HI_ERR_EVENT_CREATE_SYS_FAIL 0x80000242 #define HI_ERR_EVENT_CREATE_SYS_FAIL 0x80000242
#define HI_ERR_EVENT_SEND_FAIL 0x80000243 #define HI_ERR_EVENT_SEND_FAIL 0x80000243
#define HI_ERR_EVENT_WAIT_FAIL 0x80000244 #define HI_ERR_EVENT_WAIT_FAIL 0x80000244
#define HI_ERR_EVENT_CLEAR_FAIL 0x80000245 #define HI_ERR_EVENT_CLEAR_FAIL 0x80000245
#define HI_ERR_EVENT_RE_INIT 0x80000246 #define HI_ERR_EVENT_RE_INIT 0x80000246
#define HI_ERR_EVENT_NOT_ENOUGH_MEMORY 0x80000247 #define HI_ERR_EVENT_NOT_ENOUGH_MEMORY 0x80000247
#define HI_ERR_EVENT_NOT_INIT 0x80000248 #define HI_ERR_EVENT_NOT_INIT 0x80000248
#define HI_ERR_EVENT_DELETE_FAIL 0x80000249 #define HI_ERR_EVENT_DELETE_FAIL 0x80000249
#define HI_ERR_EVENT_WAIT_TIME_OUT 0x8000024A #define HI_ERR_EVENT_WAIT_TIME_OUT 0x8000024A
/* os维测 */ /* os维测 */
#define HI_ERR_OSSTAT_INVALID_PARAM 0x80000280 #define HI_ERR_OSSTAT_INVALID_PARAM 0x80000280
#define HI_ERR_OSSTAT_SYSTEM_CALL_ERROR 0x80000281 #define HI_ERR_OSSTAT_SYSTEM_CALL_ERROR 0x80000281
/* liteos fpb */ /* liteos fpb */
#define HI_ERR_FPB_COMP_REPEAT 0x800002C0 #define HI_ERR_FPB_COMP_REPEAT 0x800002C0
#define HI_ERR_FPB_NO_COMP 0x800002C1 #define HI_ERR_FPB_NO_COMP 0x800002C1
#define HI_ERR_FPB_TYPE 0x800002C2 #define HI_ERR_FPB_TYPE 0x800002C2
#define HI_ERR_FPB_NO_FREE_COMP 0x800002C3 #define HI_ERR_FPB_NO_FREE_COMP 0x800002C3
#define HI_ERR_FPB_ADDR_NOT_ALIGN 0x800002C4 #define HI_ERR_FPB_ADDR_NOT_ALIGN 0x800002C4
#define HI_ERR_FPB_TARGET_ADDR 0x800002C5 #define HI_ERR_FPB_TARGET_ADDR 0x800002C5
#define HI_ERR_FPB_BUSY 0x800002C6 /* ????????? */ #define HI_ERR_FPB_BUSY 0x800002C6 /* ????????? */
#define HI_ERR_FPB_ERROR_INPUT 0x800002C7 #define HI_ERR_FPB_ERROR_INPUT 0x800002C7
/* CPU */ /* CPU */
#define HI_ERR_CPUP_NOT_INIT 0x80000300 #define HI_ERR_CPUP_NOT_INIT 0x80000300
#define HI_ERR_CPUP_INVALID_PARAM 0x80000301 #define HI_ERR_CPUP_INVALID_PARAM 0x80000301
#define HI_ERR_CPU_CLK_INVALID_PARAM 0x80000302 #define HI_ERR_CPU_CLK_INVALID_PARAM 0x80000302
/* file system */ /* file system */
#define HI_ERR_FS_INVALID_PARAM 0x80000400 #define HI_ERR_FS_INVALID_PARAM 0x80000400
#define HI_ERR_FS_NO_DEVICE 0x80000401 #define HI_ERR_FS_NO_DEVICE 0x80000401
#define HI_ERR_FS_NO_SPACE 0x80000402 /* No space left on device */ #define HI_ERR_FS_NO_SPACE 0x80000402 /* No space left on device */
#define HI_ERR_FS_BAD_DESCRIPTOR 0x80000403 #define HI_ERR_FS_BAD_DESCRIPTOR 0x80000403
#define HI_ERR_FS_FILE_EXISTS 0x80000404 #define HI_ERR_FS_FILE_EXISTS 0x80000404
#define HI_ERR_FS_NOT_FOUND 0x80000405 #define HI_ERR_FS_NOT_FOUND 0x80000405
#define HI_ERR_FS_NAME_TOO_LONG 0x80000406 #define HI_ERR_FS_NAME_TOO_LONG 0x80000406
#define HI_ERR_FS_READ_ONLY_FS 0x80000407 /* Read-only file system */ #define HI_ERR_FS_READ_ONLY_FS 0x80000407 /* Read-only file system */
#define HI_ERR_FS_IO_ERROR 0x80000408 #define HI_ERR_FS_IO_ERROR 0x80000408
#define HI_ERR_FS_NO_MORE_FILES 0x80000409 #define HI_ERR_FS_NO_MORE_FILES 0x80000409
/***************************************************************************** /*****************************************************************************
* 3、驱动:错误码 * 3、驱动:错误码
*****************************************************************************/ *****************************************************************************/
/* 串口 */ /* 串口 */
#define HI_ERR_UART_INVALID_PARAMETER 0x80001000 #define HI_ERR_UART_INVALID_PARAMETER 0x80001000
#define HI_ERR_UART_INVALID_SUSPEND 0x80001001 #define HI_ERR_UART_INVALID_SUSPEND 0x80001001
#define HI_ERR_UART_INVALID_PARITY 0x80001002 #define HI_ERR_UART_INVALID_PARITY 0x80001002
#define HI_ERR_UART_INVALID_DATA_BITS 0x80001003 #define HI_ERR_UART_INVALID_DATA_BITS 0x80001003
#define HI_ERR_UART_INVALID_STOP_BITS 0x80001004 #define HI_ERR_UART_INVALID_STOP_BITS 0x80001004
#define HI_ERR_UART_INVALID_BAUD 0x80001005 #define HI_ERR_UART_INVALID_BAUD 0x80001005
#define HI_ERR_UART_INVALID_COM_PORT 0x80001006 #define HI_ERR_UART_INVALID_COM_PORT 0x80001006
#define HI_ERR_UART_NOT_SUPPORT_DMA 0x80001007 #define HI_ERR_UART_NOT_SUPPORT_DMA 0x80001007
/* gpio */ /* gpio */
#define HI_ERR_GPIO_INVALID_PARAMETER 0x80001040 #define HI_ERR_GPIO_INVALID_PARAMETER 0x80001040
#define HI_ERR_GPIO_REPEAT_INIT 0x80001041 #define HI_ERR_GPIO_REPEAT_INIT 0x80001041
#define HI_ERR_GPIO_NOT_INIT 0x80001042 #define HI_ERR_GPIO_NOT_INIT 0x80001042
#define HI_ERR_GPIO_NOT_SUPPORT 0x80001043 #define HI_ERR_GPIO_NOT_SUPPORT 0x80001043
/* 看门狗 */ /* 看门狗 */
#define HI_ERR_WATCHDOG_PARA_ERROR 0x80001080 #define HI_ERR_WATCHDOG_PARA_ERROR 0x80001080
/* Flash */ /* Flash */
#define HI_ERR_FLASH_NOT_INIT 0x800010C0 #define HI_ERR_FLASH_NOT_INIT 0x800010C0
#define HI_ERR_FLASH_INVALID_PARAM 0x800010C1 #define HI_ERR_FLASH_INVALID_PARAM 0x800010C1
#define HI_ERR_FLASH_INVALID_PARAM_BEYOND_ADDR 0x800010C2 #define HI_ERR_FLASH_INVALID_PARAM_BEYOND_ADDR 0x800010C2
#define HI_ERR_FLASH_INVALID_PARAM_SIZE_ZERO 0x800010C3 #define HI_ERR_FLASH_INVALID_PARAM_SIZE_ZERO 0x800010C3
#define HI_ERR_FLASH_INVALID_PARAM_ERASE_NOT_ALIGN 0x800010C4 #define HI_ERR_FLASH_INVALID_PARAM_ERASE_NOT_ALIGN 0x800010C4
#define HI_ERR_FLASH_INVALID_PARAM_IOCTRL_DATA_NULL 0x800010C5 #define HI_ERR_FLASH_INVALID_PARAM_IOCTRL_DATA_NULL 0x800010C5
#define HI_ERR_FLASH_INVALID_PARAM_DATA_NULL 0x800010C6 #define HI_ERR_FLASH_INVALID_PARAM_DATA_NULL 0x800010C6
#define HI_ERR_FLASH_INVALID_PARAM_PAD1 0x800010C7 #define HI_ERR_FLASH_INVALID_PARAM_PAD1 0x800010C7
#define HI_ERR_FLASH_INVALID_PARAM_PAD2 0x800010C8 #define HI_ERR_FLASH_INVALID_PARAM_PAD2 0x800010C8
#define HI_ERR_FLASH_INVALID_PARAM_PAD3 0x800010C9 #define HI_ERR_FLASH_INVALID_PARAM_PAD3 0x800010C9
#define HI_ERR_FLASH_INVALID_PARAM_PAD4 0x800010CA #define HI_ERR_FLASH_INVALID_PARAM_PAD4 0x800010CA
#define HI_ERR_FLASH_TIME_OUT_WAIT_READY 0x800010CB #define HI_ERR_FLASH_TIME_OUT_WAIT_READY 0x800010CB
#define HI_ERR_FLASH_QUAD_MODE_READ_REG1 0x800010CC #define HI_ERR_FLASH_QUAD_MODE_READ_REG1 0x800010CC
#define HI_ERR_FLASH_QUAD_MODE_READ_REG2 0x800010CD #define HI_ERR_FLASH_QUAD_MODE_READ_REG2 0x800010CD
#define HI_ERR_FLASH_QUAD_MODE_COMPARE_REG 0x800010CE #define HI_ERR_FLASH_QUAD_MODE_COMPARE_REG 0x800010CE
#define HI_ERR_FLASH_NO_MATCH_FLASH 0x800010CF #define HI_ERR_FLASH_NO_MATCH_FLASH 0x800010CF
#define HI_ERR_FLASH_WRITE_ENABLE 0x800010D0 #define HI_ERR_FLASH_WRITE_ENABLE 0x800010D0
#define HI_ERR_FLASH_NO_MATCH_ERASE_SIZE 0x800010D1 #define HI_ERR_FLASH_NO_MATCH_ERASE_SIZE 0x800010D1
#define HI_ERR_FLASH_MAX_SPI_OP 0x800010D2 #define HI_ERR_FLASH_MAX_SPI_OP 0x800010D2
#define HI_ERR_FLASH_NOT_SUPPORT_IOCTRL_ID 0x800010D3 #define HI_ERR_FLASH_NOT_SUPPORT_IOCTRL_ID 0x800010D3
#define HI_ERR_FLASH_INVALID_CHIP_ID 0x800010D4 #define HI_ERR_FLASH_INVALID_CHIP_ID 0x800010D4
#define HI_ERR_FLASH_RE_INIT 0x800010D5 #define HI_ERR_FLASH_RE_INIT 0x800010D5
#define HI_ERR_FLASH_WRITE_NOT_SUPPORT_ERASE 0x800010D6 #define HI_ERR_FLASH_WRITE_NOT_SUPPORT_ERASE 0x800010D6
#define HI_ERR_FLASH_WRITE_COMPARE_WRONG 0x800010D7 #define HI_ERR_FLASH_WRITE_COMPARE_WRONG 0x800010D7
#define HI_ERR_FLASH_WAIT_CFG_START_TIME_OUT 0x800010D8 #define HI_ERR_FLASH_WAIT_CFG_START_TIME_OUT 0x800010D8
#define HI_ERR_FLASH_PATITION_INIT_FAIL 0x800010D9 #define HI_ERR_FLASH_PATITION_INIT_FAIL 0x800010D9
#define HI_ERR_FLASH_INITILIZATION 0x800010DA #define HI_ERR_FLASH_INITILIZATION 0x800010DA
#define HI_ERR_FLASH_ERASE_NOT_4K_ALIGN 0x800010DB #define HI_ERR_FLASH_ERASE_NOT_4K_ALIGN 0x800010DB
#define HI_ERR_FLASH_PROTECT_NOT_SUPPORT 0x800010DC #define HI_ERR_FLASH_PROTECT_NOT_SUPPORT 0x800010DC
#define HI_ERR_FLASH_PROTECT_NOT_INIT 0x800010DD #define HI_ERR_FLASH_PROTECT_NOT_INIT 0x800010DD
#define HI_ERR_FLASH_PROTECT_RE_INIT 0x800010DE #define HI_ERR_FLASH_PROTECT_RE_INIT 0x800010DE
#define HI_ERR_FLASH_PROTECT_NOT_FIND_CHIP 0x800010DF #define HI_ERR_FLASH_PROTECT_NOT_FIND_CHIP 0x800010DF
#define HI_ERR_FLASH_MEMCPY_FAIL 0x800010E0 #define HI_ERR_FLASH_MEMCPY_FAIL 0x800010E0
/* HRTIMER定时器 */ /* HRTIMER定时器 */
#define HI_ERR_HRTIMER_ALREADY_INIT 0x80001100 #define HI_ERR_HRTIMER_ALREADY_INIT 0x80001100
#define HI_ERR_HRTIMER_NOT_INIT 0x80001101 #define HI_ERR_HRTIMER_NOT_INIT 0x80001101
#define HI_ERR_HRTIMER_HAVE_NO_AVAILABLE_HANDLE 0x80001102 #define HI_ERR_HRTIMER_HAVE_NO_AVAILABLE_HANDLE 0x80001102
#define HI_ERR_HRTIMER_NOT_CREATE_HANDLE 0x80001103 #define HI_ERR_HRTIMER_NOT_CREATE_HANDLE 0x80001103
#define HI_ERR_HRTIMER_IN_START_STATUS 0x80001104 #define HI_ERR_HRTIMER_IN_START_STATUS 0x80001104
#define HI_ERR_HRTIMER_NOT_START 0x80001105 #define HI_ERR_HRTIMER_NOT_START 0x80001105
#define HI_ERR_HRTIMER_INVALID_ID 0x80001106 #define HI_ERR_HRTIMER_INVALID_ID 0x80001106
#define HI_ERR_HRTIMER_INVALID_PARAMETER 0x80001107 #define HI_ERR_HRTIMER_INVALID_PARAMETER 0x80001107
#define HI_ERR_HRTIMER_MALLOC_FAILUE 0x80001108 #define HI_ERR_HRTIMER_MALLOC_FAILUE 0x80001108
/* hardware timer */ /* hardware timer */
#define HI_ERR_HWTIMER_INVALID_PARAMETER 0x80001140 #define HI_ERR_HWTIMER_INVALID_PARAMETER 0x80001140
#define HI_ERR_HWTIMER_INITILIZATION_ALREADY 0x80001141 #define HI_ERR_HWTIMER_INITILIZATION_ALREADY 0x80001141
#define HI_ERR_HWTIMER_NO_INIT 0x80001142 #define HI_ERR_HWTIMER_NO_INIT 0x80001142
/* i2c */ /* i2c */
#define HI_ERR_I2C_NOT_INIT 0x80001180 #define HI_ERR_I2C_NOT_INIT 0x80001180
#define HI_ERR_I2C_INVALID_PARAMETER 0x80001181 #define HI_ERR_I2C_INVALID_PARAMETER 0x80001181
#define HI_ERR_I2C_TIMEOUT_START 0x80001182 #define HI_ERR_I2C_TIMEOUT_START 0x80001182
#define HI_ERR_I2C_TIMEOUT_WAIT 0x80001183 #define HI_ERR_I2C_TIMEOUT_WAIT 0x80001183
#define HI_ERR_I2C_TIMEOUT_STOP 0x80001184 #define HI_ERR_I2C_TIMEOUT_STOP 0x80001184
#define HI_ERR_I2C_TIMEOUT_RCV_BYTE 0x80001185 #define HI_ERR_I2C_TIMEOUT_RCV_BYTE 0x80001185
#define HI_ERR_I2C_TIMEOUT_RCV_BYTE_PROC 0x80001186 #define HI_ERR_I2C_TIMEOUT_RCV_BYTE_PROC 0x80001186
#define HI_ERR_I2C_WAIT_SEM_FAIL 0x80001187 #define HI_ERR_I2C_WAIT_SEM_FAIL 0x80001187
#define HI_ERR_I2C_START_ACK_ERR 0x80001188 #define HI_ERR_I2C_START_ACK_ERR 0x80001188
#define HI_ERR_I2C_WAIT_ACK_ERR 0x80001189 #define HI_ERR_I2C_WAIT_ACK_ERR 0x80001189
/* spi */ /* spi */
#define HI_ERR_SPI_NOT_INIT 0x800011C0 #define HI_ERR_SPI_NOT_INIT 0x800011C0
#define HI_ERR_SPI_REINIT 0x800011C1 #define HI_ERR_SPI_REINIT 0x800011C1
#define HI_ERR_SPI_PARAMETER_WRONG 0x800011C2 #define HI_ERR_SPI_PARAMETER_WRONG 0x800011C2
#define HI_ERR_SPI_BUSY 0x800011C3 #define HI_ERR_SPI_BUSY 0x800011C3
#define HI_ERR_SPI_WRITE_TIMEOUT 0x800011C4 #define HI_ERR_SPI_WRITE_TIMEOUT 0x800011C4
#define HI_ERR_SPI_READ_TIMEOUT 0x800011C5 #define HI_ERR_SPI_READ_TIMEOUT 0x800011C5
#define HI_ERR_SPI_NOT_SUPPORT_DMA 0x800011C6 #define HI_ERR_SPI_NOT_SUPPORT_DMA 0x800011C6
/* efuse */ /* efuse */
#define HI_ERR_EFUSE_INVALIDATE_ID 0x80001200 #define HI_ERR_EFUSE_INVALIDATE_ID 0x80001200
#define HI_ERR_EFUSE_INVALIDATE_PARA 0x80001201 #define HI_ERR_EFUSE_INVALIDATE_PARA 0x80001201
#define HI_ERR_EFUSE_WRITE_ERR 0x80001202 #define HI_ERR_EFUSE_WRITE_ERR 0x80001202
#define HI_ERR_EFUSE_INVALIDATE_AUTH 0x80001203 #define HI_ERR_EFUSE_INVALIDATE_AUTH 0x80001203
#define HI_ERR_EFUSE_BUSY 0x80001204 #define HI_ERR_EFUSE_BUSY 0x80001204
#define HI_ERR_EFUSE_TIMEOUT 0x80001205 #define HI_ERR_EFUSE_TIMEOUT 0x80001205
/* cipher */ /* cipher */
#define HI_ERR_CIPHER_NOT_INIT 0x80001240 #define HI_ERR_CIPHER_NOT_INIT 0x80001240
#define HI_ERR_CIPHER_INVALID_POINT 0x80001241 #define HI_ERR_CIPHER_INVALID_POINT 0x80001241
#define HI_ERR_CIPHER_INVALID_PARAMETER 0x80001242 #define HI_ERR_CIPHER_INVALID_PARAMETER 0x80001242
#define HI_ERR_CIPHER_NO_AVAILABLE_RNG 0x80001243 #define HI_ERR_CIPHER_NO_AVAILABLE_RNG 0x80001243
#define HI_ERR_CIPHER_FAILED_MEM 0x80001244 #define HI_ERR_CIPHER_FAILED_MEM 0x80001244
#define HI_ERR_CIPHER_OVERFLOW 0x80001245 #define HI_ERR_CIPHER_OVERFLOW 0x80001245
#define HI_ERR_CIPHER_TIMEOUT 0x80001246 #define HI_ERR_CIPHER_TIMEOUT 0x80001246
#define HI_ERR_CIPHER_UNSUPPORTED 0x80001247 #define HI_ERR_CIPHER_UNSUPPORTED 0x80001247
#define HI_ERR_CIPHER_REGISTER_IRQ 0x80001248 #define HI_ERR_CIPHER_REGISTER_IRQ 0x80001248
#define HI_ERR_CIPHER_ILLEGAL_KEY 0x80001249 #define HI_ERR_CIPHER_ILLEGAL_KEY 0x80001249
#define HI_ERR_CIPHER_INVALID_ADDR 0x8000124A #define HI_ERR_CIPHER_INVALID_ADDR 0x8000124A
#define HI_ERR_CIPHER_INVALID_LENGTH 0x8000124B #define HI_ERR_CIPHER_INVALID_LENGTH 0x8000124B
#define HI_ERR_CIPHER_ILLEGAL_DATA 0x8000124C #define HI_ERR_CIPHER_ILLEGAL_DATA 0x8000124C
#define HI_ERR_CIPHER_RSA_SIGN 0x8000124D #define HI_ERR_CIPHER_RSA_SIGN 0x8000124D
#define HI_ERR_CIPHER_RSA_VERIFY 0x8000124E #define HI_ERR_CIPHER_RSA_VERIFY 0x8000124E
#define HI_ERR_CIPHER_RESULT_WARNING 0x8000124F #define HI_ERR_CIPHER_RESULT_WARNING 0x8000124F
#define HI_ERR_CIPHER_FLUSH_DCACHE_FAILED 0x80001250 #define HI_ERR_CIPHER_FLUSH_DCACHE_FAILED 0x80001250
/* sdio */ /* sdio */
#define HI_ERR_SDIO_INVALID_PARAMETER 0x80001280 #define HI_ERR_SDIO_INVALID_PARAMETER 0x80001280
/* tsensor */ /* tsensor */
#define HI_ERR_TSENSOR_INVALID_PARAMETER 0x800012C0 #define HI_ERR_TSENSOR_INVALID_PARAMETER 0x800012C0
/* adc */ /* adc */
#define HI_ERR_ADC_PARAMETER_WRONG 0x80001300 #define HI_ERR_ADC_PARAMETER_WRONG 0x80001300
#define HI_ERR_ADC_INVALID_CHANNEL_ID 0x80001301 #define HI_ERR_ADC_INVALID_CHANNEL_ID 0x80001301
#define HI_ERR_ADC_TIMEOUT 0x80001302 #define HI_ERR_ADC_TIMEOUT 0x80001302
#define HI_ERR_ADC_NOT_INIT 0x80001303 #define HI_ERR_ADC_NOT_INIT 0x80001303
/* pmw */ /* pmw */
#define HI_ERR_PWM_NO_INIT 0x80001340 #define HI_ERR_PWM_NO_INIT 0x80001340
#define HI_ERR_PWM_INITILIZATION_ALREADY 0x80001341 #define HI_ERR_PWM_INITILIZATION_ALREADY 0x80001341
#define HI_ERR_PWM_INVALID_PARAMETER 0x80001342 #define HI_ERR_PWM_INVALID_PARAMETER 0x80001342
/* dma */ /* dma */
#define HI_ERR_DMA_INVALID_PARA 0x80001380 #define HI_ERR_DMA_INVALID_PARA 0x80001380
#define HI_ERR_DMA_NOT_INIT 0x80001381 #define HI_ERR_DMA_NOT_INIT 0x80001381
#define HI_ERR_DMA_BUSY 0x80001382 #define HI_ERR_DMA_BUSY 0x80001382
#define HI_ERR_DMA_TRANSFER_FAIL 0x80001383 #define HI_ERR_DMA_TRANSFER_FAIL 0x80001383
#define HI_ERR_DMA_TRANSFER_TIMEOUT 0x80001384 #define HI_ERR_DMA_TRANSFER_TIMEOUT 0x80001384
#define HI_ERR_DMA_GET_NOTE_FAIL 0x80001385 #define HI_ERR_DMA_GET_NOTE_FAIL 0x80001385
#define HI_ERR_DMA_LLI_NOT_CREATE 0x80001386 #define HI_ERR_DMA_LLI_NOT_CREATE 0x80001386
#define HI_ERR_DMA_CH_IRQ_ENABLE_FAIL 0x80001387 #define HI_ERR_DMA_CH_IRQ_ENABLE_FAIL 0x80001387
/* audio */ /* audio */
#define HI_ERR_AUDIO_BUSY 0x800013C0 #define HI_ERR_AUDIO_BUSY 0x800013C0
#define HI_ERR_AUDIO_INVALID_PARAMETER 0x800013C1 #define HI_ERR_AUDIO_INVALID_PARAMETER 0x800013C1
/* i2s */ /* i2s */
#define HI_ERR_I2S_INVALID_PARAMETER 0x80001400 #define HI_ERR_I2S_INVALID_PARAMETER 0x80001400
#define HI_ERR_I2S_WRITE_TIMEOUT 0x80001401 #define HI_ERR_I2S_WRITE_TIMEOUT 0x80001401
/***************************************************************************** /*****************************************************************************
* 4、中间应用:错误码 * 4、中间应用:错误码
*****************************************************************************/ *****************************************************************************/
/* NV */ /* NV */
#define HI_ERR_NV_FILE_ERR 0x80003000 #define HI_ERR_NV_FILE_ERR 0x80003000
#define HI_ERR_NV_MEMCPY_FAIL 0x80003001 #define HI_ERR_NV_MEMCPY_FAIL 0x80003001
#define HI_ERR_NV_WRITE_FILE_FAIL 0x80003002 #define HI_ERR_NV_WRITE_FILE_FAIL 0x80003002
#define HI_ERR_NV_UPDATA_DATA_FAIL 0x80003003 #define HI_ERR_NV_UPDATA_DATA_FAIL 0x80003003
#define HI_ERR_NV_UPDATA_FILE_FAIL 0x80003004 #define HI_ERR_NV_UPDATA_FILE_FAIL 0x80003004
#define HI_ERR_NV_NOT_SUPPORT_WRITE 0x80003005 #define HI_ERR_NV_NOT_SUPPORT_WRITE 0x80003005
#define HI_ERR_NV_FSEC_TOTAL_NUM_INVALID 0x80003006 /* 工厂NV项个数非法 */ #define HI_ERR_NV_FSEC_TOTAL_NUM_INVALID 0x80003006 /* 工厂NV项个数非法 */
#define HI_ERR_NV_FAIL_N_TIMES 0x80003007 #define HI_ERR_NV_FAIL_N_TIMES 0x80003007
#define HI_ERR_NV_SEM_FAIL 0x80003008 #define HI_ERR_NV_SEM_FAIL 0x80003008
#define HI_ERR_NV_LEN_ERR 0x80003009 #define HI_ERR_NV_LEN_ERR 0x80003009
#define HI_ERR_NV_NOT_FOUND 0x8000300A #define HI_ERR_NV_NOT_FOUND 0x8000300A
#define HI_ERR_NV_FULL 0x8000300B #define HI_ERR_NV_FULL 0x8000300B
#define HI_ERR_NV_NOT_ENOUGH_MEMORY 0x8000300C #define HI_ERR_NV_NOT_ENOUGH_MEMORY 0x8000300C
#define HI_ERR_NV_NOT_SUPPORT 0x8000300D #define HI_ERR_NV_NOT_SUPPORT 0x8000300D
#define HI_ERR_NV_NOT_SUPPORT_ID 0x8000300E #define HI_ERR_NV_NOT_SUPPORT_ID 0x8000300E
#define HI_ERR_NV_BAD_DATA 0x8000300F #define HI_ERR_NV_BAD_DATA 0x8000300F
#define HI_ERR_NV_INVALID_TYPE 0x80003010 #define HI_ERR_NV_INVALID_TYPE 0x80003010
/* NV读取失败" "Read NVIM Failure" */ /* NV读取失败" "Read NVIM Failure" */
#define HI_ERR_NV_ERROR_READ 0x80003011 #define HI_ERR_NV_ERROR_READ 0x80003011
/* NV写失败,长度过长""Write Error for Length Overflow" */ /* NV写失败,长度过长""Write Error for Length Overflow" */
#define HI_ERR_NV_NOT_SUPPORT_LENTH 0x80003012 #define HI_ERR_NV_NOT_SUPPORT_LENTH 0x80003012
/* NV写失败,Flash坏块" "Write Error for Flash Bad Block" */ /* NV写失败,Flash坏块" "Write Error for Flash Bad Block" */
#define HI_ERR_NV_BAD_BLOCK 0x80003013 #define HI_ERR_NV_BAD_BLOCK 0x80003013
/* NV写失败,其他错误" "Write Error for Unknown Reason" */ /* NV写失败,其他错误" "Write Error for Unknown Reason" */
#define HI_ERR_NV_ERROR_WRITE 0x80003014 #define HI_ERR_NV_ERROR_WRITE 0x80003014
#define HI_ERR_NV_INITILIZATION 0x80003015 #define HI_ERR_NV_INITILIZATION 0x80003015
#define HI_ERR_NV_INVALID_PARAMETER 0x80003016 #define HI_ERR_NV_INVALID_PARAMETER 0x80003016
/* 低功耗 */ /* 低功耗 */
#define HI_ERR_LOWPOWER_INVALID_PARAMETER 0x80003040 #define HI_ERR_LOWPOWER_INVALID_PARAMETER 0x80003040
/* upgrade common error */ /* upgrade common error */
#define HI_ERR_UPG_COMMON 0x80003060 #define HI_ERR_UPG_COMMON 0x80003060
#define HI_ERR_UPG_NULL_POINTER (HI_ERR_UPG_COMMON + 0x0) #define HI_ERR_UPG_NULL_POINTER (HI_ERR_UPG_COMMON + 0x0)
#define HI_ERR_UPG_PARAMETER (HI_ERR_UPG_COMMON + 0x1) #define HI_ERR_UPG_PARAMETER (HI_ERR_UPG_COMMON + 0x1)
#define HI_ERR_UPG_BACKUP_ADDR (HI_ERR_UPG_COMMON + 0x2) #define HI_ERR_UPG_BACKUP_ADDR (HI_ERR_UPG_COMMON + 0x2)
#define HI_ERR_UPG_BUSY (HI_ERR_UPG_COMMON + 0x3) #define HI_ERR_UPG_BUSY (HI_ERR_UPG_COMMON + 0x3)
#define HI_ERR_UPG_FLASH_BAD (HI_ERR_UPG_COMMON + 0x4) #define HI_ERR_UPG_FLASH_BAD (HI_ERR_UPG_COMMON + 0x4)
#define HI_ERR_UPG_START_ADDR (HI_ERR_UPG_COMMON + 0x5) #define HI_ERR_UPG_START_ADDR (HI_ERR_UPG_COMMON + 0x5)
#define HI_ERR_UPG_INITILIZATION_ALREADY (HI_ERR_UPG_COMMON + 0x6) #define HI_ERR_UPG_INITILIZATION_ALREADY (HI_ERR_UPG_COMMON + 0x6)
#define HI_ERR_UPG_FILE_LEN (HI_ERR_UPG_COMMON + 0x7) #define HI_ERR_UPG_FILE_LEN (HI_ERR_UPG_COMMON + 0x7)
#define HI_ERR_UPG_NOT_START (HI_ERR_UPG_COMMON + 0x8) #define HI_ERR_UPG_NOT_START (HI_ERR_UPG_COMMON + 0x8)
#define HI_ERR_UPG_MALLOC_FAIL (HI_ERR_UPG_COMMON + 0x9) #define HI_ERR_UPG_MALLOC_FAIL (HI_ERR_UPG_COMMON + 0x9)
#define HI_ERR_UPG_GET_SECTION_HEAD (HI_ERR_UPG_COMMON + 0xA) #define HI_ERR_UPG_GET_SECTION_HEAD (HI_ERR_UPG_COMMON + 0xA)
#define HI_ERR_UPG_BUF_LEN (HI_ERR_UPG_COMMON + 0xB) #define HI_ERR_UPG_BUF_LEN (HI_ERR_UPG_COMMON + 0xB)
#define HI_ERR_UPG_FLASH_SIZE (HI_ERR_UPG_COMMON + 0xC) #define HI_ERR_UPG_FLASH_SIZE (HI_ERR_UPG_COMMON + 0xC)
#define HI_ERR_UPG_NV_SIZE (HI_ERR_UPG_COMMON + 0xD) #define HI_ERR_UPG_NV_SIZE (HI_ERR_UPG_COMMON + 0xD)
#define HI_ERR_UPG_ALREADY_FINISH (HI_ERR_UPG_COMMON + 0xE) #define HI_ERR_UPG_ALREADY_FINISH (HI_ERR_UPG_COMMON + 0xE)
#define HI_ERR_UPG_RSA_KEY_ADDR (HI_ERR_UPG_COMMON + 0xF) #define HI_ERR_UPG_RSA_KEY_ADDR (HI_ERR_UPG_COMMON + 0xF)
#define HI_ERR_UPG_ECC_KEY_ADDR (HI_ERR_UPG_COMMON + 0x10) #define HI_ERR_UPG_ECC_KEY_ADDR (HI_ERR_UPG_COMMON + 0x10)
#define HI_ERR_UPG_FILE_LEN_OVER (HI_ERR_UPG_COMMON + 0x11) #define HI_ERR_UPG_FILE_LEN_OVER (HI_ERR_UPG_COMMON + 0x11)
#define HI_ERR_UPG_STOP (HI_ERR_UPG_COMMON + 0x12) #define HI_ERR_UPG_STOP (HI_ERR_UPG_COMMON + 0x12)
#define HI_ERR_UPG_LOW_FIRMWARE_VER (HI_ERR_UPG_COMMON + 0x13) #define HI_ERR_UPG_LOW_FIRMWARE_VER (HI_ERR_UPG_COMMON + 0x13)
#define HI_ERR_UPG_FULL_FIRMWARE_VER (HI_ERR_UPG_COMMON + 0x14) #define HI_ERR_UPG_FULL_FIRMWARE_VER (HI_ERR_UPG_COMMON + 0x14)
#define HI_ERR_UPG_LOW_BOOT_VER (HI_ERR_UPG_COMMON + 0x15) #define HI_ERR_UPG_LOW_BOOT_VER (HI_ERR_UPG_COMMON + 0x15)
#define HI_ERR_UPG_FULL_BOOT_VER (HI_ERR_UPG_COMMON + 0x16) #define HI_ERR_UPG_FULL_BOOT_VER (HI_ERR_UPG_COMMON + 0x16)
#define HI_ERR_UPG_FIRST_PACKET_OFFSET (HI_ERR_UPG_COMMON + 0x17) #define HI_ERR_UPG_FIRST_PACKET_OFFSET (HI_ERR_UPG_COMMON + 0x17)
#define HI_ERR_UPG_MEMCPY_FAIL (HI_ERR_UPG_COMMON + 0x18) #define HI_ERR_UPG_MEMCPY_FAIL (HI_ERR_UPG_COMMON + 0x18)
/* upgrade file check error */ /* upgrade file check error */
#define HI_ERR_UPG_CHECK 0x80003080 #define HI_ERR_UPG_CHECK 0x80003080
#define HI_ERR_UPG_IMAGE_ID (HI_ERR_UPG_CHECK + 0x0) #define HI_ERR_UPG_IMAGE_ID (HI_ERR_UPG_CHECK + 0x0)
#define HI_ERR_UPG_FILE_TYPE (HI_ERR_UPG_CHECK + 0x1) #define HI_ERR_UPG_FILE_TYPE (HI_ERR_UPG_CHECK + 0x1)
#define HI_ERR_UPG_HEAD_LEN (HI_ERR_UPG_CHECK + 0x2) #define HI_ERR_UPG_HEAD_LEN (HI_ERR_UPG_CHECK + 0x2)
#define HI_ERR_UPG_SIGN_ALG (HI_ERR_UPG_CHECK + 0x3) #define HI_ERR_UPG_SIGN_ALG (HI_ERR_UPG_CHECK + 0x3)
#define HI_ERR_UPG_RSA_KEY_LEN (HI_ERR_UPG_CHECK + 0x4) #define HI_ERR_UPG_RSA_KEY_LEN (HI_ERR_UPG_CHECK + 0x4)
#define HI_ERR_UPG_RSA_HEAD_SIGN (HI_ERR_UPG_CHECK + 0x5) #define HI_ERR_UPG_RSA_HEAD_SIGN (HI_ERR_UPG_CHECK + 0x5)
#define HI_ERR_UPG_ECC_KEY_LEN (HI_ERR_UPG_CHECK + 0x6) #define HI_ERR_UPG_ECC_KEY_LEN (HI_ERR_UPG_CHECK + 0x6)
#define HI_ERR_UPG_ECC_HEAD_SIGN (HI_ERR_UPG_CHECK + 0x7) #define HI_ERR_UPG_ECC_HEAD_SIGN (HI_ERR_UPG_CHECK + 0x7)
#define HI_ERR_UPG_COMMON_SHA256 (HI_ERR_UPG_CHECK + 0x8) #define HI_ERR_UPG_COMMON_SHA256 (HI_ERR_UPG_CHECK + 0x8)
#define HI_ERR_UPG_SECTION_SHA256 (HI_ERR_UPG_CHECK + 0x9) #define HI_ERR_UPG_SECTION_SHA256 (HI_ERR_UPG_CHECK + 0x9)
#define HI_ERR_UPG_FIRMWARE_VER (HI_ERR_UPG_CHECK + 0xA) #define HI_ERR_UPG_FIRMWARE_VER (HI_ERR_UPG_CHECK + 0xA)
#define HI_ERR_UPG_BOOT_VER (HI_ERR_UPG_CHECK + 0xB) #define HI_ERR_UPG_BOOT_VER (HI_ERR_UPG_CHECK + 0xB)
#define HI_ERR_UPG_BOOT_HEAD (HI_ERR_UPG_CHECK + 0xC) #define HI_ERR_UPG_BOOT_HEAD (HI_ERR_UPG_CHECK + 0xC)
#define HI_ERR_UPG_BOOT_LEN (HI_ERR_UPG_CHECK + 0xD) #define HI_ERR_UPG_BOOT_LEN (HI_ERR_UPG_CHECK + 0xD)
#define HI_ERR_UPG_BOOT_ROOT_KEY (HI_ERR_UPG_CHECK + 0xE) #define HI_ERR_UPG_BOOT_ROOT_KEY (HI_ERR_UPG_CHECK + 0xE)
#define HI_ERR_UPG_BOOT_ROOT_KEY_LEN (HI_ERR_UPG_CHECK + 0xF) #define HI_ERR_UPG_BOOT_ROOT_KEY_LEN (HI_ERR_UPG_CHECK + 0xF)
#define HI_ERR_UPG_BOOT_KEY_ID (HI_ERR_UPG_CHECK + 0x10) #define HI_ERR_UPG_BOOT_KEY_ID (HI_ERR_UPG_CHECK + 0x10)
#define HI_ERR_UPG_BOOT_SIGN_ALG (HI_ERR_UPG_CHECK + 0x11) #define HI_ERR_UPG_BOOT_SIGN_ALG (HI_ERR_UPG_CHECK + 0x11)
#define HI_ERR_UPG_BOOT_SUB_KEY (HI_ERR_UPG_CHECK + 0x12) #define HI_ERR_UPG_BOOT_SUB_KEY (HI_ERR_UPG_CHECK + 0x12)
#define HI_ERR_UPG_BOOT_SUB_KEY_CAT (HI_ERR_UPG_CHECK + 0x13) #define HI_ERR_UPG_BOOT_SUB_KEY_CAT (HI_ERR_UPG_CHECK + 0x13)
#define HI_ERR_UPG_BOOT_SUB_KEY_RSIM (HI_ERR_UPG_CHECK + 0x14) #define HI_ERR_UPG_BOOT_SUB_KEY_RSIM (HI_ERR_UPG_CHECK + 0x14)
#define HI_ERR_UPG_BOOT_DIE_ID (HI_ERR_UPG_CHECK + 0x15) #define HI_ERR_UPG_BOOT_DIE_ID (HI_ERR_UPG_CHECK + 0x15)
#define HI_ERR_UPG_BOOT_HASH (HI_ERR_UPG_CHECK + 0x16) #define HI_ERR_UPG_BOOT_HASH (HI_ERR_UPG_CHECK + 0x16)
#define HI_ERR_UPG_BOOT_SUB_KEY_LEN (HI_ERR_UPG_CHECK + 0x17) #define HI_ERR_UPG_BOOT_SUB_KEY_LEN (HI_ERR_UPG_CHECK + 0x17)
/* DIAG */ /* DIAG */
#define HI_ERR_DIAG_NOT_FOUND 0x800030C0 #define HI_ERR_DIAG_NOT_FOUND 0x800030C0
#define HI_ERR_DIAG_INVALID_ID 0x800030C1 #define HI_ERR_DIAG_INVALID_ID 0x800030C1
#define HI_ERR_DIAG_FULL 0x800030C2 #define HI_ERR_DIAG_FULL 0x800030C2
#define HI_ERR_DIAG_CONSUMED 0x800030C3 #define HI_ERR_DIAG_CONSUMED 0x800030C3
#define HI_ERR_DIAG_CONTINUE 0x800030C4 #define HI_ERR_DIAG_CONTINUE 0x800030C4
#define HI_ERR_DIAG_TOO_SMALL_BUFFER 0x800030C5 #define HI_ERR_DIAG_TOO_SMALL_BUFFER 0x800030C5
#define HI_ERR_DIAG_NO_MORE_DATA 0x800030C6 #define HI_ERR_DIAG_NO_MORE_DATA 0x800030C6
#define HI_ERR_DIAG_NOT_ENOUGH_MEMORY 0x800030C7 #define HI_ERR_DIAG_NOT_ENOUGH_MEMORY 0x800030C7
#define HI_ERR_DIAG_INVALID_HEAP_ADDR 0x800030C8 #define HI_ERR_DIAG_INVALID_HEAP_ADDR 0x800030C8
#define HI_ERR_DIAG_NOT_CONNECT 0x800030C9 #define HI_ERR_DIAG_NOT_CONNECT 0x800030C9
#define HI_ERR_DIAG_BUSY 0x800030CA #define HI_ERR_DIAG_BUSY 0x800030CA
#define HI_ERR_DIAG_TOO_LARGE_FRAME 0x800030CB #define HI_ERR_DIAG_TOO_LARGE_FRAME 0x800030CB
#define HI_ERR_DIAG_RAM_ALIGN 0x800030CC #define HI_ERR_DIAG_RAM_ALIGN 0x800030CC
#define HI_ERR_DIAG_NOT_SUPPORT 0x800030CD #define HI_ERR_DIAG_NOT_SUPPORT 0x800030CD
#define HI_ERR_DIAG_UNAVAILABLE 0x800030CE #define HI_ERR_DIAG_UNAVAILABLE 0x800030CE
#define HI_ERR_DIAG_CFG_NOT_ALLOW 0x800030CF #define HI_ERR_DIAG_CFG_NOT_ALLOW 0x800030CF
#define HI_ERR_DIAG_INVALID_CODE_ADDR 0x800030D0 #define HI_ERR_DIAG_INVALID_CODE_ADDR 0x800030D0
#define HI_ERR_DIAG_OBJ_NOT_FOUND 0x800030D1 #define HI_ERR_DIAG_OBJ_NOT_FOUND 0x800030D1
#define HI_ERR_DIAG_QUEUE_FULL 0x800030D2 #define HI_ERR_DIAG_QUEUE_FULL 0x800030D2
#define HI_ERR_DIAG_NO_MORE_MEMORY 0x800030D3 #define HI_ERR_DIAG_NO_MORE_MEMORY 0x800030D3
#define HI_ERR_DIAG_SYSTEM_CALL_ERROR 0x800030D4 #define HI_ERR_DIAG_SYSTEM_CALL_ERROR 0x800030D4
#define HI_ERR_DIAG_NO_INIT 0x800030D5 #define HI_ERR_DIAG_NO_INIT 0x800030D5
#define HI_ERR_DIAG_INVALID_PARAMETER 0x800030D6 #define HI_ERR_DIAG_INVALID_PARAMETER 0x800030D6
#define HI_ERR_DIAG_STAT_NOT_SUPPORT 0x800030D7 #define HI_ERR_DIAG_STAT_NOT_SUPPORT 0x800030D7
#define HI_ERR_DIAG_ID_OR_CALLBACK_ALREADY_REGISTERED 0x800030D8 #define HI_ERR_DIAG_ID_OR_CALLBACK_ALREADY_REGISTERED 0x800030D8
#define HI_ERR_DIAG_SET_CONN_ACK_INFO 0x800030D9 #define HI_ERR_DIAG_SET_CONN_ACK_INFO 0x800030D9
#define HI_ERR_DIAG_CMD_NUM_EXCEED_UPPER_LIMIT 0x800030DA #define HI_ERR_DIAG_CMD_NUM_EXCEED_UPPER_LIMIT 0x800030DA
#define HI_ERR_DIAG_MEMCPY_FAIL 0x800030DB #define HI_ERR_DIAG_MEMCPY_FAIL 0x800030DB
/* reset 复位 */ /* reset 复位 */
#define HI_ERR_RESET_TOO_LARGE_DATA 0x80003100 #define HI_ERR_RESET_TOO_LARGE_DATA 0x80003100
#define HI_ERR_RESET_INVALID_PARAMETER 0x80003101 #define HI_ERR_RESET_INVALID_PARAMETER 0x80003101
/* syserror */ /* syserror */
#define HI_ERR_SYSERROR_NOT_FOUND 0x80003140 #define HI_ERR_SYSERROR_NOT_FOUND 0x80003140
#define HI_ERR_SYSERROR_INVALID_PARAMETER 0x80003141 #define HI_ERR_SYSERROR_INVALID_PARAMETER 0x80003141
/* APP */ /* APP */
#define HI_ERR_APP_INITILIZATION_ALREADY 0x80003180 #define HI_ERR_APP_INITILIZATION_ALREADY 0x80003180
#define HI_ERR_APP_INVALID_PARAMETER 0x80003181 #define HI_ERR_APP_INVALID_PARAMETER 0x80003181
/* CRC */ /* CRC */
#define HI_ERR_CRC_INVALID_PARAMETER 0x800031C0 #define HI_ERR_CRC_INVALID_PARAMETER 0x800031C0
/* sigma */ /* sigma */
#define HI_ERR_SIGMA_INVALID_PARAMETER 0x80003200 #define HI_ERR_SIGMA_INVALID_PARAMETER 0x80003200
/* data collect */ /* data collect */
#define HI_ERR_DATACOLLECT_INVALID_PARAMETER 0x80003240 #define HI_ERR_DATACOLLECT_INVALID_PARAMETER 0x80003240
#define HI_ERR_DATACOLLECT_BUSY 0x80003241 #define HI_ERR_DATACOLLECT_BUSY 0x80003241
/* AT */ /* AT */
#define HI_ERR_AT_NAME_OR_FUNC_REPEAT_REGISTERED 0x80003280 #define HI_ERR_AT_NAME_OR_FUNC_REPEAT_REGISTERED 0x80003280
#define HI_ERR_AT_INVALID_PARAMETER 0x80003281 #define HI_ERR_AT_INVALID_PARAMETER 0x80003281
/***************************************************************************** /*****************************************************************************
* 5、协议栈:错误码 * 5、协议栈:错误码
*****************************************************************************/ *****************************************************************************/
/* wifi */ /* wifi */
/* 说明:wifi错误码hi_err_code_enum 将base基值修改为起始值,其他错误码一次延顺 */ /* 说明:wifi错误码hi_err_code_enum 将base基值修改为起始值,其他错误码一次延顺 */
/* dmac */ /* dmac */
#define HI_ERR_WIFI_DMAC_NOT_SUPPORT 0x80004000 #define HI_ERR_WIFI_DMAC_NOT_SUPPORT 0x80004000
/* hmac */ /* hmac */
#define HI_ERR_WIFI_HMAC_INVALID_PARAMETER 0x80004040 #define HI_ERR_WIFI_HMAC_INVALID_PARAMETER 0x80004040
/* wal */ /* wal */
#define HI_ERR_WIFI_WAL_MALLOC_FAIL 0x80004080 #define HI_ERR_WIFI_WAL_MALLOC_FAIL 0x80004080
#define HI_ERR_WIFI_WAL_FAILURE 0x80004081 #define HI_ERR_WIFI_WAL_FAILURE 0x80004081
#define HI_ERR_WIFI_WAL_BUSY 0x80004082 #define HI_ERR_WIFI_WAL_BUSY 0x80004082
#define HI_ERR_WIFI_WAL_INVALID_PARAMETER 0x80004083 #define HI_ERR_WIFI_WAL_INVALID_PARAMETER 0x80004083
/***************************************************************************** /*****************************************************************************
* 6、Hisi保留 unit128个 * 6、Hisi保留 unit128个
* 7、客户使用预留 unit64个 * 7、客户使用预留 unit64个
*****************************************************************************/ *****************************************************************************/
#endif /* __HI_ERRNO_H__ */ #endif /* __HI_ERRNO_H__ */
@@ -1,9 +1,9 @@
/* /*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
* reserved. Description: A parameter is added to the security C APIs based on * Description: A parameter is added to the security C APIs based on the standard C interface, that is, the upper
* the standard C interface, that is, the upper limit of the write operation * limit of the write operation address space to prevent out-of-bounds write.
* address space to prevent out-of-bounds write. Author: Hisilicon Create: * Author: Hisilicon
* 2018-08-04 * Create: 2018-08-04
*/ */
/** /**
@@ -31,27 +31,22 @@ typedef unsigned int size_t;
/** /**
* @ingroup iot_secure_c * @ingroup iot_secure_c
* @brief Copies the source string to the destination * @brief Copies the source string to the destination buffer.CNcomment:复制源字符串到目的缓冲区。CNend
buffer.CNcomment:复制源字符串到目的缓冲区。CNend
* *
* @par 描述: Copies the source string to the destination buffer. * @par 描述: Copies the source string to the destination buffer.
CNcomment:复制源字符串到目的缓冲区。CNend CNcomment:复制源字符串到目的缓冲区。CNend
* *
* @attention None * @attention None
* *
* @param dest [OUT] type #char *, Destination * @param dest [OUT] type #char *, Destination buffer.CNcomment:目的缓冲区。CNend
buffer.CNcomment:目的缓冲区。CNend * @param dest_max [IN] type #size_t, Size of the destination buffer.CNcomment:目的缓冲区大小。CNend
* @param dest_max [IN] type #size_t, Size of the destination * @param src [IN] type #const #char *, Source buffer.CNcomment:源缓冲区。CNend
buffer.CNcomment:目的缓冲区大小。CNend
* @param src [IN] type #const #char *, Source
buffer.CNcomment:源缓冲区。CNend
* *
* @retval #EOK Success * @retval #EOK Success
* @retval #Other Failure * @retval #Other Failure
* *
* @par 依赖: * @par 依赖:
* @li hi_stdlib.h: This file declares the * @li hi_stdlib.h: This file declares the APIs.CNcomment:该接口声明所在的头文件。CNend
APIs.CNcomment:该接口声明所在的头文件。CNend
* @see None * @see None
* @since Hi3861_V100R001C00 * @since Hi3861_V100R001C00
*/ */
@@ -59,33 +54,28 @@ extern errno_t strcpy_s(char *dest, size_t dest_max, const char *src);
/** /**
* @ingroup iot_secure_c * @ingroup iot_secure_c
* @brief Copies the source string of a specified length to the destination * @brief Copies the source string of a specified length to the destination buffer.
buffer. CNcomment:复制指定长度源字符串到目的缓冲区。CNend CNcomment:复制指定长度源字符串到目的缓冲区。CNend
* *
* @par 描述:Copies the source string of a specified length to the destination * @par 描述:Copies the source string of a specified length to the destination buffer.
buffer. CNcomment:复制指定长度源字符串到目的缓冲区。CNend CNcomment:复制指定长度源字符串到目的缓冲区。CNend
* @attention None * @attention None
* *
* @param dest [IN] type #char *, Destination * @param dest [IN] type #char *, Destination buffer.CNcomment:目的缓冲区。CNend
buffer.CNcomment:目的缓冲区。CNend * @param dest_max [IN] type #size_t, Size of the destination buffer.CNcomment:目的缓冲区大小。CNend
* @param dest_max [IN] type #size_t, Size of the destination * @param src [IN] type #const #char *, Source buffer.CNcomment:源缓冲区。CNend
buffer.CNcomment:目的缓冲区大小。CNend * @param count [IN] type #size_t, Number of characters copied from the source buffer.
* @param src [IN] type #const #char *, Source CNcomment:从源缓冲区中复制的字符数。CNend
buffer.CNcomment:源缓冲区。CNend
* @param count [IN] type #size_t, Number of characters copied from the source
buffer. CNcomment:从源缓冲区中复制的字符数。CNend
* *
* @retval #EOK Success * @retval #EOK Success
* @retval #Other Failure * @retval #Other Failure
* *
* @par 依赖: * @par 依赖:
* @li hi_stdlib.h: This file declares the * @li hi_stdlib.h: This file declares the APIs.CNcomment:该接口声明所在的头文件。CNend
APIs.CNcomment:该接口声明所在的头文件。CNend
* @see None * @see None
* @since Hi3861_V100R001C00 * @since Hi3861_V100R001C00
*/ */
extern errno_t strncpy_s(char *dest, size_t dest_max, const char *src, extern errno_t strncpy_s(char *dest, size_t dest_max, const char *src, size_t count);
size_t count);
/** /**
* @ingroup iot_secure_c * @ingroup iot_secure_c
@@ -96,19 +86,15 @@ CNcomment:
CNcomment:将源字符串连接到目的字符串后面。CNend CNcomment:将源字符串连接到目的字符串后面。CNend
* @attention None * @attention None
* *
* @param dest [IN] type #char *, Destination * @param dest [IN] type #char *, Destination buffer.CNcomment:目的缓冲区。CNend
buffer.CNcomment:目的缓冲区。CNend * @param dest_max [IN] type #size_t, Size of the destination buffer.CNcomment:目的缓冲区大小。CNend
* @param dest_max [IN] type #size_t, Size of the destination * @param src [IN] type #const #char *, Source buffer.CNcomment:源缓冲区。CNend
buffer.CNcomment:目的缓冲区大小。CNend
* @param src [IN] type #const #char *, Source
buffer.CNcomment:源缓冲区。CNend
* *
* @retval #EOK Success * @retval #EOK Success
* @retval #Other Failure * @retval #Other Failure
* *
* @par 依赖: * @par 依赖:
* @li hi_stdlib.h: This file declares the * @li hi_stdlib.h: This file declares the APIs.CNcomment:该接口声明所在的头文件。CNend
APIs.CNcomment:该接口声明所在的头文件。CNend
* @see None * @see None
* @since Hi3861_V100R001C00 * @since Hi3861_V100R001C00
*/ */
@@ -116,34 +102,28 @@ extern errno_t strcat_s(char *dest, size_t dest_max, const char *src);
/** /**
* @ingroup iot_secure_c * @ingroup iot_secure_c
* @brief Concatenates the source string of a specified length to the end of the * @brief Concatenates the source string of a specified length to the end of the destination string.
destination string. CNcomment:将指定长度的源字符串连接到目的字符串后面。CNend CNcomment:将指定长度的源字符串连接到目的字符串后面。CNend
* *
* @par 描述: Concatenates the source string of a specified length to the end of * @par 描述: Concatenates the source string of a specified length to the end of the destination string.
the destination string.
CNcomment:将指定长度的源字符串连接到目的字符串后面。CNend CNcomment:将指定长度的源字符串连接到目的字符串后面。CNend
* @attention None * @attention None
* *
* @param dest [IN] type #char *, Destination * @param dest [IN] type #char *, Destination buffer.CNcomment:目的缓冲区。CNend
buffer.CNcomment:目的缓冲区。CNend * @param dest_max [IN] type #size_t, Size of the destination buffer.CNcomment:目的缓冲区大小。CNend
* @param dest_max [IN] type #size_t, Size of the destination * @param src [IN] type #const #char *, Source buffer.CNcomment:源缓冲区。CNend
buffer.CNcomment:目的缓冲区大小。CNend * @param count [IN] type #size_t, Number of characters copied from the source buffer.
* @param src [IN] type #const #char *, Source CNcomment:从源缓冲区连接的字符数。CNend
buffer.CNcomment:源缓冲区。CNend
* @param count [IN] type #size_t, Number of characters copied from the source
buffer. CNcomment:从源缓冲区连接的字符数。CNend
* *
* @retval #EOK Success * @retval #EOK Success
* @retval #Other Failure * @retval #Other Failure
* *
* @par 依赖: * @par 依赖:
* @li hi_stdlib.h: This file declares the * @li hi_stdlib.h: This file declares the APIs.CNcomment:该接口声明所在的头文件。CNend
APIs.CNcomment:该接口声明所在的头文件。CNend
* @see None * @see None
* @since Hi3861_V100R001C00 * @since Hi3861_V100R001C00
*/ */
extern errno_t strncat_s(char *dest, size_t dest_max, const char *src, extern errno_t strncat_s(char *dest, size_t dest_max, const char *src, size_t count);
size_t count);
/** /**
* @ingroup iot_secure_c * @ingroup iot_secure_c
@@ -154,26 +134,21 @@ CNcomment:
CNcomment:复制源缓冲区的数据到目的缓冲区。CNend CNcomment:复制源缓冲区的数据到目的缓冲区。CNend
* @attention None * @attention None
* *
* @param dest [IN] type #char *, Destination * @param dest [IN] type #char *, Destination buffer.CNcomment:目的缓冲区。CNend
buffer.CNcomment:目的缓冲区。CNend * @param dest_max [IN] type #size_t, Size of the destination buffer.CNcomment:目的缓冲区大小。CNend
* @param dest_max [IN] type #size_t, Size of the destination * @param src [IN] type #const #char *, Source buffer.CNcomment:源缓冲区。CNend
buffer.CNcomment:目的缓冲区大小。CNend * @param count [IN] type #size_t, Number of characters copied from the source buffer.
* @param src [IN] type #const #char *, Source CNcomment:从源缓冲区中复制的字符数。CNend
buffer.CNcomment:源缓冲区。CNend
* @param count [IN] type #size_t, Number of characters copied from the source
buffer. CNcomment:从源缓冲区中复制的字符数。CNend
* *
* @retval #EOK Success * @retval #EOK Success
* @retval #Other Failure * @retval #Other Failure
* *
* @par 依赖: * @par 依赖:
* @li hi_stdlib.h: This file declares the * @li hi_stdlib.h: This file declares the APIs.CNcomment:该接口声明所在的头文件。CNend
APIs.CNcomment:该接口声明所在的头文件。CNend
* @see None * @see None
* @since Hi3861_V100R001C00 * @since Hi3861_V100R001C00
*/ */
extern errno_t memcpy_s(void *dest, size_t dest_max, const void *src, extern errno_t memcpy_s(void *dest, size_t dest_max, const void *src, size_t count);
size_t count);
/** /**
* @ingroup iot_secure_c * @ingroup iot_secure_c
@@ -184,21 +159,17 @@ CNcomment:
CNcomment:设置目的缓冲区为特定值。CNend CNcomment:设置目的缓冲区为特定值。CNend
* @attention None * @attention None
* *
* @param dest [IN] type #char *, Destination * @param dest [IN] type #char *, Destination buffer.CNcomment:目的缓冲区。CNend
buffer.CNcomment:目的缓冲区。CNend * @param dest_max [IN] type #size_t, Size of the destination buffer.CNcomment:目的缓冲区大小。CNend
* @param dest_max [IN] type #size_t, Size of the destination * @param c [IN] type #const #char *, Source buffer.CNcomment:特定值。CNend
buffer.CNcomment:目的缓冲区大小。CNend * @param count [IN] type #size_t, Number of characters copied from the source buffer.
* @param c [IN] type #const #char *, Source CNcomment:设置为特定值的字符数。CNend
buffer.CNcomment:特定值。CNend
* @param count [IN] type #size_t, Number of characters copied from the source
buffer. CNcomment:设置为特定值的字符数。CNend
* *
* @retval #EOK Success * @retval #EOK Success
* @retval #Other Failure * @retval #Other Failure
* *
* @par 依赖: * @par 依赖:
* @li hi_stdlib.h: This file declares the * @li hi_stdlib.h: This file declares the APIs.CNcomment:该接口声明所在的头文件。CNend
APIs.CNcomment:该接口声明所在的头文件。CNend
* @see None * @see None
* @since Hi3861_V100R001C00 * @since Hi3861_V100R001C00
*/ */
@@ -213,51 +184,42 @@ CNcomment:
CNcomment:移动源缓冲区的数据到目的缓冲区。CNend CNcomment:移动源缓冲区的数据到目的缓冲区。CNend
* @attention None * @attention None
* *
* @param dest [IN] type #char *, Destination * @param dest [IN] type #char *, Destination buffer.CNcomment:目的缓冲区。CNend
buffer.CNcomment:目的缓冲区。CNend * @param dest_max [IN] type #size_t, Size of the destination buffer.CNcomment:目的缓冲区大小。CNend
* @param dest_max [IN] type #size_t, Size of the destination * @param src [IN] type #const #char *, Source buffer.CNcomment:源缓冲区。CNend
buffer.CNcomment:目的缓冲区大小。CNend * @param count [IN] type #size_t, Number of characters copied from the source buffer.
* @param src [IN] type #const #char *, Source CNcomment:从源缓冲区中移动的字符数。CNend
buffer.CNcomment:源缓冲区。CNend
* @param count [IN] type #size_t, Number of characters copied from the source
buffer. CNcomment:从源缓冲区中移动的字符数。CNend
* *
* @retval #EOK Success * @retval #EOK Success
* @retval #Other Failure * @retval #Other Failure
* *
* @par 依赖: * @par 依赖:
* @li hi_stdlib.h: This file declares the * @li hi_stdlib.h: This file declares the APIs.CNcomment:该接口声明所在的头文件。CNend
APIs.CNcomment:该接口声明所在的头文件。CNend
* @see None * @see None
* @since Hi3861_V100R001C00 * @since Hi3861_V100R001C00
*/ */
extern errno_t memmove_s(void *dest, size_t dest_max, const void *src, extern errno_t memmove_s(void *dest, size_t dest_max, const void *src, size_t count);
size_t count);
/** /**
* @ingroup iot_secure_c * @ingroup iot_secure_c
* @brief Splits a string into substrings according to the specified separators. * @brief Splits a string into substrings according to the specified separators.
CNcomment:将字符串按照指定的分隔符分割成子字符串。CNend CNcomment:将字符串按照指定的分隔符分割成子字符串。CNend
* *
* @par 描述: Splits a string into substrings according to the specified * @par 描述: Splits a string into substrings according to the specified separators.
separators. CNcomment:将字符串按照指定的分隔符分割成子字符串。CNend CNcomment:将字符串按照指定的分隔符分割成子字符串。CNend
* @attention None * @attention None
* *
* @param token [IN] type #char *。 String to be * @param token [IN] type #char *。 String to be split.CNcomment:要分割的字符串。CNend
split.CNcomment:要分割的字符串。CNend * @param delimit [IN] type #const char *。 String separator.CNcomment:字符串分隔符。CNend
* @param delimit [IN] type #const char *。 String * @param context [IN] type #char* 。Position information after a call to HI_strtok_s is saved.
separator.CNcomment:字符串分隔符。CNend CNcomment:保存调用HI_strtok_s后的位置信息。CNend
* @param context [IN] type #char* 。Position information after a call to
HI_strtok_s is saved. CNcomment:保存调用HI_strtok_s后的位置信息。CNend
* *
* @retval #char* Point to the next token. * @retval #char* Point to the next token. CNcomment:指向在token中的下一个token。CNend
CNcomment:指向在token中的下一个token。CNend
* @retval #HI_NULL A specified substring is not found or an error occurs. * @retval #HI_NULL A specified substring is not found or an error occurs.
CNcomment:没有找到指定的子字符串或者发生错误。CNend CNcomment:没有找到指定的子字符串或者发生错误。CNend
* *
* @par 依赖: * @par 依赖:
* @li hi_stdlib.h: This file declares the * @li hi_stdlib.h: This file declares the APIs.CNcomment:该接口声明所在的头文件。CNend
APIs.CNcomment:该接口声明所在的头文件。CNend
* @see None * @see None
* @since Hi3861_V100R001C00 * @since Hi3861_V100R001C00
*/ */
@@ -272,21 +234,17 @@ CNcomment:
CNcomment:将数据格式化输出到目的缓冲区。CNend CNcomment:将数据格式化输出到目的缓冲区。CNend
* @attention None * @attention None
* *
* @param dest [OUT] type #char *。 Destination * @param dest [OUT] type #char *。 Destination buffer.CNcomment:目的缓冲区。CNend
buffer.CNcomment:目的缓冲区。CNend * @param dest_max [IN] type #size_t。 Size of the destination buffer.CNcomment:目的缓冲区大小。CNend
* @param dest_max [IN] type #size_t。 Size of the destination * @param format [IN] type #const #char *。 Formatting control string.CNcomment:格式化控制字符串。CNend
buffer.CNcomment:目的缓冲区大小。CNend
* @param format [IN] type #const #char *。 Formatting control
string.CNcomment:格式化控制字符串。CNend
* @param ... [IN] Optional parameter CNcomment:可选参数。CNend * @param ... [IN] Optional parameter CNcomment:可选参数。CNend
* *
* @retval #>=0 Return the number of bytes stored in dest, not counting the * @retval #>=0 Return the number of bytes stored in dest, not counting the terminating null character.
terminating null character. CNcomment:返回存储在dest的字节数,不包括结束符CNend CNcomment:返回存储在dest的字节数,不包括结束符CNend
* @retval #-1 Failure * @retval #-1 Failure
* *
* @par 依赖: * @par 依赖:
* @li hi_stdlib.h: This file declares the * @li hi_stdlib.h: This file declares the APIs.CNcomment:该接口声明所在的头文件。CNend
APIs.CNcomment:该接口声明所在的头文件。CNend
* @see None * @see None
* @since Hi3861_V100R001C00 * @since Hi3861_V100R001C00
*/ */
@@ -294,38 +252,30 @@ extern int sprintf_s(char *dest, size_t dest_max, const char *format, ...);
/** /**
* @ingroup iot_secure_c * @ingroup iot_secure_c
* @brief Formats the data according to a specified length and outputs the data * @brief Formats the data according to a specified length and outputs the data to the destination buffer.
to the destination buffer.
CNcomment:将数据按照指定长度格式化输出到目的缓冲区。CNend CNcomment:将数据按照指定长度格式化输出到目的缓冲区。CNend
* *
* @par 描述: Formats the data according to a specified length and outputs the * @par 描述: Formats the data according to a specified length and outputs the data to the destination buffer.
data to the destination buffer.
CNcomment:将数据按照指定长度格式化输出到目的缓冲区。CNend CNcomment:将数据按照指定长度格式化输出到目的缓冲区。CNend
* @attention None * @attention None
* *
* @param dest [OUT] type #char *。 Destination * @param dest [OUT] type #char *。 Destination buffer.CNcomment:目的缓冲区。CNend
buffer.CNcomment:目的缓冲区。CNend * @param dest_max [IN] type #size_t。 Size of the destination buffer.CNcomment:目的缓冲区大小。CNend
* @param dest_max [IN] type #size_t。 Size of the destination * @param count [IN] type #size_t。 Number of formatted characters to be output to the destination buffer.
buffer.CNcomment:目的缓冲区大小。CNend
* @param count [IN] type #size_t。 Number of formatted characters to be
output to the destination buffer.
CNcomment:要输出到目的缓冲区的格式化字符个数。CNend CNcomment:要输出到目的缓冲区的格式化字符个数。CNend
* @param format [IN] type #const #char *。 Formatting control * @param format [IN] type #const #char *。 Formatting control string.CNcomment:格式化控制字符串。CNend
string.CNcomment:格式化控制字符串。CNend
* @param ... [IN] Optional parameter CNcomment:可选参数。CNend * @param ... [IN] Optional parameter CNcomment:可选参数。CNend
* *
* @retval #>=0 Return the number of bytes stored in dest, not counting the * @retval #>=0 Return the number of bytes stored in dest, not counting the terminating null character.
terminating null character. CNcomment:返回存储在dest的字节数,不包括结束符CNend CNcomment:返回存储在dest的字节数,不包括结束符CNend
* @retval #-1 Failure * @retval #-1 Failure
* *
* @par 依赖: * @par 依赖:
* @li hi_stdlib.h: This file declares the * @li hi_stdlib.h: This file declares the APIs.CNcomment:该接口声明所在的头文件。CNend
APIs.CNcomment:该接口声明所在的头文件。CNend
* @see None * @see None
* @since Hi3861_V100R001C00 * @since Hi3861_V100R001C00
*/ */
extern int snprintf_s(char *dest, size_t dest_max, size_t count, extern int snprintf_s(char *dest, size_t dest_max, size_t count, const char *format, ...);
const char *format, ...);
/* /*
* C库接口 * C库接口
@@ -347,3 +297,4 @@ extern UT_CONST char *strchr(const char *s, int c);
HI_END_HEADER HI_END_HEADER
#endif /* __HI_STDLIB_H__ */ #endif /* __HI_STDLIB_H__ */
@@ -1,31 +1,36 @@
/* /*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2019. All rights * Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2019. All rights reserved.
* reserved. Description: file hi_types.h. Author: HiSilicon Create: 2019-4-3 * Description: file hi_types.h.
*/ * Author: HiSilicon
* Create: 2019-4-3
*/
/** /**
* @file hi_types.h * @file hi_types.h
* *
* Copyright (c) Hisilicon Technologies Co., Ltd. 2018. All rights reserved. \n * Copyright (c) Hisilicon Technologies Co., Ltd. 2018. All rights reserved. \n
* *
* 数据类型说明 * 数据类型说明
*/ */
#ifndef __HI_TYPES_H__ #ifndef __HI_TYPES_H__
#define __HI_TYPES_H__ #define __HI_TYPES_H__
#include <hi_errno.h>
#include <hi_types_base.h> #include <hi_types_base.h>
#include <hi_errno.h>
/* linux错误码 */ /* linux错误码 */
#define OAL_SUCC 0 #define OAL_SUCC 0
#define OAL_EFAIL 1 /* 内核通用错误返回值 -1 */ #define OAL_EFAIL 1 /* 内核通用错误返回值 -1 */
#define OAL_EIO 5 /* I/O error */ #define OAL_EIO 5 /* I/O error */
#define OAL_ENOMEM 12 /* Out of memory */ #define OAL_ENOMEM 12 /* Out of memory */
#define OAL_EFAUL 14 /* Bad address */ #define OAL_EFAUL 14 /* Bad address */
#define OAL_EBUSY 16 /* Device or resource busy */ #define OAL_EBUSY 16 /* Device or resource busy */
#define OAL_ENODEV 19 /* No such device */ #define OAL_ENODEV 19 /* No such device */
#define OAL_EINVAL 22 /* Invalid argument */ #define OAL_EINVAL 22 /* Invalid argument */
#define oal_reference(data) ((void)(data)) #define oal_reference(data) ((void)(data))
#endif // __HI_TYPES_H__ #endif // __HI_TYPES_H__
@@ -1,6 +1,7 @@
/* /*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2019. All rights * Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2019. All rights reserved.
* reserved. Description: 数据类型定义和公用宏和结构定义 Author: Hisilicon * Description: 数据类型定义和公用宏和结构定义
* Author: Hisilicon
* Create: 2019-06-02 * Create: 2019-06-02
*/ */
@@ -21,8 +22,7 @@
#endif #endif
#if !defined(HI_HAVE_CROSS_COMPILER_DIAB_AS) #if !defined(HI_HAVE_CROSS_COMPILER_DIAB_AS)
#if defined(HI_HAVE_CROSS_COMPILER_ARM_GCC) || \ #if defined(HI_HAVE_CROSS_COMPILER_ARM_GCC) || defined(HI_HAVE_CROSS_COMPILER_ARM_ARMCC) || \
defined(HI_HAVE_CROSS_COMPILER_ARM_ARMCC) || \
defined(HI_HAVE_CROSS_COMPILER_DIAB) defined(HI_HAVE_CROSS_COMPILER_DIAB)
#undef HI_HAVE_CROSS_COMPILER #undef HI_HAVE_CROSS_COMPILER
#define HI_HAVE_CROSS_COMPILER #define HI_HAVE_CROSS_COMPILER
@@ -33,89 +33,85 @@
#endif #endif
#ifdef PRODUCT_CFG_OS_WIN #ifdef PRODUCT_CFG_OS_WIN
#undef SAL_HAVE_OS_WIN_VER # undef SAL_HAVE_OS_WIN_VER
#undef SAL_HAVE_OS_NU_VER # undef SAL_HAVE_OS_NU_VER
#undef SAL_HAVE_OS_VX_VER # undef SAL_HAVE_OS_VX_VER
#define SAL_HAVE_OS_WIN_VER #define SAL_HAVE_OS_WIN_VER
#endif #endif
#if defined(PRODUCT_CFG_OS_LOS) #if defined (PRODUCT_CFG_OS_LOS)
#undef SAL_HAVE_OS_VX_VER # undef SAL_HAVE_OS_VX_VER
#define SAL_HAVE_OS_VX_VER # define SAL_HAVE_OS_VX_VER
#else #else
#if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1200) # if defined (_WIN32) && defined (_MSC_VER) && (_MSC_VER >= 1200)
#pragma once # pragma once
#ifndef SAL_HAVE_SIMU_WIN_VER # ifndef SAL_HAVE_SIMU_WIN_VER
#define SAL_HAVE_SIMU_WIN_VER # define SAL_HAVE_SIMU_WIN_VER
#ifdef _USRDLL # ifdef _USRDLL
#if !defined(PRODUCT_CFG_MSVC_HIDE_AUTOLINK_OUTPUT_INFO) # if !defined(PRODUCT_CFG_MSVC_HIDE_AUTOLINK_OUTPUT_INFO)
#pragma message("Windows VC Simulator DLL Version ") # pragma message("Windows VC Simulator DLL Version ")
#endif # endif
#endif # endif
#ifdef _LIB # ifdef _LIB
#if !defined(PRODUCT_CFG_MSVC_HIDE_AUTOLINK_OUTPUT_INFO) # if !defined(PRODUCT_CFG_MSVC_HIDE_AUTOLINK_OUTPUT_INFO)
#pragma message("Windows VC Simulator lib Version ") # pragma message("Windows VC Simulator lib Version ")
#endif # endif
#endif # endif
#ifdef _CONSOLE # ifdef _CONSOLE
#if !defined(PRODUCT_CFG_MSVC_HIDE_AUTOLINK_OUTPUT_INFO) # if !defined(PRODUCT_CFG_MSVC_HIDE_AUTOLINK_OUTPUT_INFO)
#pragma message("Windows VC Simulator console Version ") # pragma message("Windows VC Simulator console Version ")
#endif # endif
#endif # endif
#else # else
#if !defined(PRODUCT_CFG_MSVC_HIDE_AUTOLINK_OUTPUT_INFO) # if !defined(PRODUCT_CFG_MSVC_HIDE_AUTOLINK_OUTPUT_INFO)
#pragma message("Windows Version") # pragma message("Windows Version")
#endif # endif
#endif # endif
#endif # endif
#endif #endif
#undef HI_SYS_DEBUG #undef HI_SYS_DEBUG
#if (defined(PRODUCT_CFG_VERSION_DEBUG) || defined(SAL_HAVE_DEBUG_VERSION)) && \ #if (defined(PRODUCT_CFG_VERSION_DEBUG) || defined(SAL_HAVE_DEBUG_VERSION)) && !defined(SAL_HAVE_RELEASE_VERSION)
!defined(SAL_HAVE_RELEASE_VERSION) # define HI_SYS_DEBUG
#define HI_SYS_DEBUG
#endif #endif
#if defined(PRODUCT_CFG_OS_WIN) #if defined(PRODUCT_CFG_OS_WIN)
#pragma warning(disable : 4200) /* disable nonstandard extension used : \ #pragma warning(disable:4200) /* disable nonstandard extension used : zero-sized array in struct/union. */
zero-sized array in struct/union. */ #pragma warning(disable:4214) /* allows bitfield structure members to be of any integral type. */
#pragma warning(disable : 4214) /* allows bitfield structure members to be of \ #pragma warning(disable:4201)
any integral type. */ #pragma warning(disable:4514)
#pragma warning(disable : 4201) #pragma warning(disable:4127)
#pragma warning(disable : 4514)
#pragma warning(disable : 4127)
#endif #endif
/* 基本数据类型定义 */ /* 基本数据类型定义 */
typedef unsigned int hi_u32; typedef unsigned int hi_u32;
typedef int hi_s32; typedef int hi_s32;
typedef unsigned short hi_u16; typedef unsigned short hi_u16;
typedef signed short hi_s16; typedef signed short hi_s16;
typedef unsigned char hi_u8; typedef unsigned char hi_u8;
typedef signed char hi_s8; typedef signed char hi_s8;
typedef void hi_void; typedef void hi_void;
typedef char hi_char; typedef char hi_char;
typedef unsigned char hi_uchar; typedef unsigned char hi_uchar;
typedef hi_u8 hi_bool; typedef hi_u8 hi_bool;
typedef void *hi_pvoid; typedef void* hi_pvoid;
typedef hi_u8 hi_byte; typedef hi_u8 hi_byte;
typedef hi_pvoid hi_handle; typedef hi_pvoid hi_handle;
typedef hi_byte *hi_pbyte; typedef hi_byte* hi_pbyte;
typedef float hi_float; typedef float hi_float;
typedef double hi_double; typedef double hi_double;
typedef volatile hi_u32 hi_u32_reg; typedef volatile hi_u32 hi_u32_reg;
typedef hi_pvoid hi_func_ptr; typedef hi_pvoid hi_func_ptr;
typedef hi_u32 hi_func; typedef hi_u32 hi_func;
typedef unsigned int hi_size_t; typedef unsigned int hi_size_t;
typedef int hi_ssize_t; typedef int hi_ssize_t;
typedef int hi_offset_t; typedef int hi_offset_t;
/* for 64bits platform, intptr_t/uintptr_t should be defined as 64bits length. /* for 64bits platform, intptr_t/uintptr_t should be defined as 64bits length. */
*/ typedef int intptr_t;
typedef int intptr_t;
#if defined(__LITEOS__) #if defined(__LITEOS__)
typedef unsigned int uintptr_t; typedef unsigned int uintptr_t;
#endif #endif
#undef ERROR #undef ERROR
@@ -127,152 +123,151 @@ typedef unsigned int uintptr_t;
#define NULL 0 #define NULL 0
#endif #endif
#define HI_CONST const #define HI_CONST const
#define HI_REG register #define HI_REG register
#define HI_U32_MAX 0xFFFFFFFF #define HI_U32_MAX 0xFFFFFFFF
#define HI_U64_MAX 0xFFFFFFFFFFFFFFFFUL #define HI_U64_MAX 0xFFFFFFFFFFFFFFFFUL
#define HI_U16_MAX 0xFFFF #define HI_U16_MAX 0xFFFF
typedef hi_pvoid (*hi_pvoid_callback_f)(hi_void); typedef hi_pvoid (*hi_pvoid_callback_f)(hi_void);
typedef hi_void (*hi_void_callback_f)(hi_void); typedef hi_void (*hi_void_callback_f)(hi_void);
typedef hi_void (*hi_void_callback)(hi_void); typedef hi_void (*hi_void_callback)(hi_void);
typedef hi_bool (*hi_bool_callback_f)(hi_void); typedef hi_bool (*hi_bool_callback_f)(hi_void);
typedef hi_void (*hi_void_u32_callback_f)(hi_u32); typedef hi_void (*hi_void_u32_callback_f)(hi_u32);
typedef hi_u32 (*hi_u32_pvoid_callback_f)(hi_pvoid); typedef hi_u32 (*hi_u32_pvoid_callback_f)(hi_pvoid);
typedef hi_u32 (*hi_u32_void_callback)(hi_void); /* 周边代码待刷新 */ typedef hi_u32 (*hi_u32_void_callback)(hi_void); /* 周边代码待刷新 */
typedef hi_u32 (*hi_u32_u32_pvoid_callback_f)(hi_pvoid, hi_u32); typedef hi_u32 (*hi_u32_u32_pvoid_callback_f)(hi_pvoid, hi_u32);
typedef hi_s32 (*funcptr)(hi_void); /* ptr to function returning int */ typedef hi_s32 (*funcptr)(hi_void); /* ptr to function returning int */
typedef hi_void (*voidfuncptr)(hi_void); /* ptr to function returning void */ typedef hi_void (*voidfuncptr)(hi_void); /* ptr to function returning void */
typedef HI_CONST hi_char *hi_pcstr; typedef HI_CONST hi_char* hi_pcstr;
#ifdef PRODUCT_CFG_OS_WIN #ifdef PRODUCT_CFG_OS_WIN
typedef unsigned __int64 hi_u64; typedef unsigned __int64 hi_u64;
typedef __int64 hi_s64; typedef __int64 hi_s64;
#elif defined(HI_HAVE_CROSS_COMPILER_ARM_ARMCC) #elif defined(HI_HAVE_CROSS_COMPILER_ARM_ARMCC)
typedef unsigned __int64 hi_u64; typedef unsigned __int64 hi_u64;
typedef __int64 hi_s64; typedef __int64 hi_s64;
#elif defined(HI_HAVE_CROSS_COMPILER_ARM_GCC) || defined(HAVE_PCLINT_CHECK) #elif defined(HI_HAVE_CROSS_COMPILER_ARM_GCC) || defined(HAVE_PCLINT_CHECK)
typedef unsigned long long hi_u64; typedef unsigned long long hi_u64;
typedef long long hi_s64; typedef long long hi_s64;
#elif defined(HI_HAVE_CROSS_COMPILER_DIAB) #elif defined(HI_HAVE_CROSS_COMPILER_DIAB)
typedef unsigned long long hi_u64; typedef unsigned long long hi_u64;
typedef long long hi_s64; typedef long long hi_s64;
#elif !defined(PRODUCT_CFG_HSO) #elif !defined(PRODUCT_CFG_HSO)
/* #error "unknown compiler" */ /* #error "unknown compiler" */
typedef unsigned __int64 hi_u64; typedef unsigned __int64 hi_u64;
typedef __int64 hi_s64; typedef __int64 hi_s64;
#endif #endif
#define HI_S32_BITS 32 #define HI_S32_BITS 32
#define HI_S32_MAX (~(~0 << (HI_S32_BITS - 1))) #define HI_S32_MAX (~(~0 << (HI_S32_BITS - 1)))
#define HI_PUBLIC extern #define HI_PUBLIC extern
#if !defined(PRODUCT_CFG_FEATURE_UT) #if !defined(PRODUCT_CFG_FEATURE_UT)
#define HI_PRV static # define HI_PRV static
#else #else
#define HI_PRV # define HI_PRV
#endif #endif
#define STATIC static # define STATIC static
#endif /* HI_HAVE_CROSS_COMPILER_DIAB_AS */ #endif /* HI_HAVE_CROSS_COMPILER_DIAB_AS */
#ifdef PRODUCT_CFG_OS_WIN #ifdef PRODUCT_CFG_OS_WIN
#define HI_API _declspec(dllexport) # define HI_API _declspec(dllexport)
#define HI_INLINE __inline # define HI_INLINE __inline
#elif defined(HI_HAVE_CROSS_COMPILER_ARM_GCC) #elif defined(HI_HAVE_CROSS_COMPILER_ARM_GCC)
#define HI_INLINE inline # define HI_INLINE inline
#define HI_API # define HI_API
#elif defined(HI_HAVE_CROSS_COMPILER_ARM_ARMCC) #elif defined(HI_HAVE_CROSS_COMPILER_ARM_ARMCC)
#define HI_INLINE inline # define HI_INLINE inline
#define HI_API # define HI_API
#elif defined(HI_HAVE_CROSS_COMPILER_DIAB) #elif defined(HI_HAVE_CROSS_COMPILER_DIAB)
#define HI_INLINE __inline__ # define HI_INLINE __inline__
#define HI_API # define HI_API
#else # else
#define HI_INLINE __inline # define HI_INLINE __inline
#define HI_API # define HI_API
#endif #endif
#define HI_PRVL HI_PRV HI_INLINE #define HI_PRVL HI_PRV HI_INLINE
#if defined(__ONEBUILDER__CROSS_COMPILER_PRODUCT_CONFIG__) #if defined(__ONEBUILDER__CROSS_COMPILER_PRODUCT_CONFIG__)
#if defined(HI_HAVE_CROSS_COMPILER_ARM_ARMCC) || \ #if defined(HI_HAVE_CROSS_COMPILER_ARM_ARMCC) || defined(HI_HAVE_CROSS_COMPILER_ARM_GCC)
defined(HI_HAVE_CROSS_COMPILER_ARM_GCC) # define hi_section(name_string) __attribute__ ((section(name_string)))
#define hi_section(name_string) __attribute__((section(name_string))) # define HI_PACKED __attribute__((packed))
#define HI_PACKED __attribute__((packed)) # define HI_ALIGNED4 __attribute__ ((aligned (4)))
#define HI_ALIGNED4 __attribute__((aligned(4)))
#elif defined(HI_HAVE_CROSS_COMPILER_DIAB) #elif defined(HI_HAVE_CROSS_COMPILER_DIAB)
#define hi_section(name_string) __attribute__((section(name_string))) # define hi_section(name_string) __attribute__ ((section(name_string)))
#define HI_PACKED __attribute__((packed)) # define HI_PACKED __attribute__((packed))
#define HI_ALIGNED4 __attribute__((aligned(4))) # define HI_ALIGNED4 __attribute__ ((aligned (4)))
#endif #endif
#elif defined(SAL_HAVE_OS_WIN_VER) || defined(PRODUCT_CFG_HSO) #elif defined(SAL_HAVE_OS_WIN_VER) || defined(PRODUCT_CFG_HSO)
#define hi_section(name_string) # define hi_section(name_string)
#define HI_PACKED # define HI_PACKED
#define HI_ALIGNED4 # define HI_ALIGNED4
#else #else
#define hi_section(name_string) # define hi_section(name_string)
#define HI_PACKED # define HI_PACKED
#define HI_ALIGNED4 # define HI_ALIGNED4
#endif #endif
#if defined(SAL_HAVE_OS_WIN_VER) #if defined(SAL_HAVE_OS_WIN_VER)
#if defined(_DEBUG) || defined(PRODUCT_CFG_VERSION_DEBUG) # if defined(_DEBUG) || defined(PRODUCT_CFG_VERSION_DEBUG)
#define hi_dll_lib_name(x) x##"_debug.dll" # define hi_dll_lib_name(x) x ## "_debug.dll"
#else # else
#define hi_dll_lib_name(x) x##"_release.dll" # define hi_dll_lib_name(x) x ## "_release.dll"
#endif # endif
#else #else
#if defined(HI_HAVE_CROSS_COMPILER_ARM_GCC) #if defined(HI_HAVE_CROSS_COMPILER_ARM_GCC)
#define hi_dll_lib_name(x) x # define hi_dll_lib_name(x) x
#else #else
#define hi_dll_lib_name(x) x##".lib" # define hi_dll_lib_name(x) x ## ".lib"
#endif #endif
#endif #endif
#if defined(SAL_HAVE_NO_EXTERN_DEFINED) #if defined(SAL_HAVE_NO_EXTERN_DEFINED)
#define HI_EXTERN # define HI_EXTERN
#define HI_EXTERN_C # define HI_EXTERN_C
#else #else
#if defined(PRODUCT_CFG_OS_WIN) # if defined(PRODUCT_CFG_OS_WIN)
#define HI_EXTERN extern HI_API # define HI_EXTERN extern HI_API
#define HI_EXTERN_C HI_EXTERN # define HI_EXTERN_C HI_EXTERN
#define HI_EAPI extern HI_API # define HI_EAPI extern HI_API
#else # else
#define HI_EXTERN extern # define HI_EXTERN extern
#define HI_EAPI # define HI_EAPI
#define HI_EXTERN_C # define HI_EXTERN_C
#endif # endif
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
#define HI_CPP_START extern "C" { # define HI_CPP_START extern "C" {
#define HI_CPP_END } # define HI_CPP_END }
#else #else
#define HI_CPP_START # define HI_CPP_START
#define HI_CPP_END # define HI_CPP_END
#endif #endif
#if defined(HI_HAVE_CROSS_COMPILER_ARM_ARMCC) #if defined(HI_HAVE_CROSS_COMPILER_ARM_ARMCC)
#define HI_NOP __asm { nop } #define HI_NOP __asm { nop }
#define hi_dbg_break() __asm { swi 0x14DEAD } #define hi_dbg_break() __asm { swi 0x14DEAD }
#elif defined(HI_HAVE_CROSS_COMPILER_DIAB) #elif defined(HI_HAVE_CROSS_COMPILER_DIAB)
#define HI_NOP #define HI_NOP
#define hi_dbg_break() #define hi_dbg_break()
#else #else
#define HI_NOP #define HI_NOP
#ifdef PRODUCT_CFG_OS_WIN #ifdef PRODUCT_CFG_OS_WIN
#define hi_dbg_break() _asm { int 3 } #define hi_dbg_break() _asm { int 3 }
#else #else
#define hi_dbg_break() #define hi_dbg_break()
#endif #endif
#endif #endif
#define HI_START_HEADER HI_CPP_START #define HI_START_HEADER HI_CPP_START
#define HI_END_HEADER HI_CPP_END #define HI_END_HEADER HI_CPP_END
#undef HI_OUT #undef HI_OUT
#undef HI_IN #undef HI_IN
@@ -281,275 +276,239 @@ typedef __int64 hi_s64;
#define HI_IN #define HI_IN
#define HI_INOUT #define HI_INOUT
#define HI_FALSE 0 #define HI_FALSE 0
#define HI_TRUE 1 #define HI_TRUE 1
#define HI_SWITCH_OFF 0 #define HI_SWITCH_OFF 0
#define HI_SWITCH_ON 1 #define HI_SWITCH_ON 1
#ifdef __cplusplus #ifdef __cplusplus
#define HI_NULL 0 #define HI_NULL 0
#else #else
#define HI_NULL ((void *)0) #define HI_NULL ((void *)0)
#endif #endif
#define hi_array_count(x) (sizeof(x) / sizeof((x)[0]))
#define hi_array_count(x) (sizeof(x) / sizeof((x)[0]))
#if !defined(hi_unref_param) && !defined(HI_HAVE_CROSS_COMPILER_DIAB) #if !defined(hi_unref_param) && !defined(HI_HAVE_CROSS_COMPILER_DIAB)
#define hi_unref_param(P) ((P) = (P)) #define hi_unref_param(P) ((P) = (P))
#else #else
#define hi_unref_param(P) #define hi_unref_param(P)
#endif #endif
#if defined(PRODUCT_CFG_PLATFORM_HI3921) #if defined(PRODUCT_CFG_PLATFORM_HI3921)
#if defined(HI_HAVE_CROSS_COMPILER_ARM_ARMCC) #if defined(HI_HAVE_CROSS_COMPILER_ARM_ARMCC)
#define HI_VOLATILE volatile #define HI_VOLATILE volatile
#define hi_sys_get_lr() __return_address() #define hi_sys_get_lr() __return_address()
#elif defined(HAVE_PCLINT_CHECK) #elif defined(HAVE_PCLINT_CHECK)
#define HI_VOLATILE #define HI_VOLATILE
#define hi_sys_get_lr() 0 #define hi_sys_get_lr() 0
#elif defined(HI_HAVE_CROSS_COMPILER_DIAB) #elif defined(HI_HAVE_CROSS_COMPILER_DIAB)
#define HI_VOLATILE volatile #define HI_VOLATILE volatile
#define hi_sys_get_lr() 0 #define hi_sys_get_lr() 0
#else #else
#define HI_VOLATILE __volatile__ #define HI_VOLATILE __volatile__
#define hi_sys_get_lr() 0 #define hi_sys_get_lr() 0
#endif #endif
#else #else
#define HI_VOLATILE #define HI_VOLATILE
#define hi_sys_get_lr() 0 #define hi_sys_get_lr() 0
#endif #endif
#define hi_aligin_u32_size(x) (((x) & (~3)) + 4) /* 构造4个字节对齐 */ #define hi_aligin_u32_size(x) (((x) & (~3)) + 4) /* 构造4个字节对齐 */
#define hi_is_align_u32(x) (!((x)&3)) /* 判断是否为4字节对齐 */ #define hi_is_align_u32(x) (!((x) & 3)) /* 判断是否为4字节对齐 */
#define hi_is_unalign_u32(x) ((x)&3) /* 判断是否为4字节对齐 */ #define hi_is_unalign_u32(x) ((x) & 3) /* 判断是否为4字节对齐 */
#if defined(HAVE_PCLINT_CHECK) #if defined(HAVE_PCLINT_CHECK)
#define hi_fieldoffset(s, m) (0) #define hi_fieldoffset(s, m) (0)
#else #else
#define hi_fieldoffset(s, m) ((hi_u32) & (((s *)0)->m)) /* 结构成员偏移 */ #define hi_fieldoffset(s, m) ((hi_u32)&(((s *)0)->m)) /* 结构成员偏移 */
#endif #endif
#define HI_CHAR_CR '\r' /* 0x0D */ #define HI_CHAR_CR '\r' /* 0x0D */
#define HI_CHAR_LF '\n' /* 0x0A */ #define HI_CHAR_LF '\n' /* 0x0A */
#define hi_tolower(x) \ #define hi_tolower(x) ((x) | 0x20) /* Works only for digits and letters, but small and fast */
((x) | 0x20) /* Works only for digits and letters, but small and fast */
#define hi_array_size(_array) (sizeof(_array) / sizeof((_array)[0])) #define hi_array_size(_array) (sizeof(_array) / sizeof((_array)[0]))
#define hi_makeu16(a, b) ((hi_u16)(((hi_u8)(a)) | ((hi_u16)((hi_u8)(b))) << 8)) #define hi_makeu16(a, b) ((hi_u16)(((hi_u8)(a)) | ((hi_u16)((hi_u8)(b))) << 8))
#define hi_makeu32(a, b) \ #define hi_makeu32(a, b) ((hi_u32)(((hi_u16)(a)) | ((hi_u32)((hi_u16)(b))) << 16))
((hi_u32)(((hi_u16)(a)) | ((hi_u32)((hi_u16)(b))) << 16)) #define hi_makeu64(a, b) ((hi_u64)(((hi_u32)(a)) | ((hi_u64)((hi_u32)(b))) <<32))
#define hi_makeu64(a, b) \ #define hi_joinu32(a, b, c, d) ((a) | ((hi_u32)(b) << 8) | ((hi_u32)(c) << 16) | ((hi_u32)(d) << 24))
((hi_u64)(((hi_u32)(a)) | ((hi_u64)((hi_u32)(b))) << 32))
#define hi_joinu32(a, b, c, d) \
((a) | ((hi_u32)(b) << 8) | ((hi_u32)(c) << 16) | ((hi_u32)(d) << 24))
#define hi_hiu32(l) ((hi_u32)(((hi_u64)(l) >> 32) & 0xFFFFFFFF)) #define hi_hiu32(l) ((hi_u32)(((hi_u64)(l) >> 32) & 0xFFFFFFFF))
#define hi_lou32(l) ((hi_u32)(l)) #define hi_lou32(l) ((hi_u32)(l))
#define hi_hiu16(l) ((hi_u16)(((hi_u32)(l) >> 16) & 0xFFFF)) #define hi_hiu16(l) ((hi_u16)(((hi_u32)(l) >> 16) & 0xFFFF))
#define hi_lou16(l) ((hi_u16)(l)) #define hi_lou16(l) ((hi_u16)(l))
#define hi_hiu8(l) ((hi_u8)(((hi_u16)(l) >> 8) & 0xFF)) #define hi_hiu8(l) ((hi_u8)(((hi_u16)(l) >> 8) & 0xFF))
#define hi_lou8(l) ((hi_u8)(l)) #define hi_lou8(l) ((hi_u8)(l))
#define hi_max(a, b) (((a) > (b)) ? (a) : (b)) #define hi_max(a, b) (((a) > (b)) ? (a) : (b))
#define hi_min(a, b) (((a) < (b)) ? (a) : (b)) #define hi_min(a, b) (((a) < (b)) ? (a) : (b))
#define hi_sub(a, b) (((a) > (b)) ? ((a) - (b)) : 0) #define hi_sub(a, b) (((a) > (b)) ? ((a) - (b)) : 0)
#define hi_abs_sub(a, b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a))) #define hi_abs_sub(a, b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a)))
#define hi_byte_align(value, align) (((value) + (align)-1) & (~((align)-1))) #define hi_byte_align(value, align) (((value) + (align) - 1) & (~((align) -1)))
#define hi_is_byte_align(value, align) (((hi_u32)(value) & ((align)-1)) == 0) #define hi_is_byte_align(value, align) (((hi_u32)(value) & ((align) - 1))== 0)
#define hi_inc_wraparound(value, round_size) \ #define hi_inc_wraparound(value, round_size) ++(value); (value) &= ((round_size) - 1)
++(value); \ #define hi_dec_wraparound(value, round_size) --(value); (value) &= ((round_size) - 1)
(value) &= ((round_size)-1)
#define hi_dec_wraparound(value, round_size) \
--(value); \
(value) &= ((round_size)-1)
#define hi_swap_byteorder_16(value) \ #define hi_swap_byteorder_16(value) ((((value) & 0xFF) << 8) + (((value) & 0xFF00) >> 8))
((((value)&0xFF) << 8) + (((value)&0xFF00) >> 8))
#define hi_swap_byteorder_32(value) \ #define hi_swap_byteorder_32(value) \
((hi_u32)(((value)&0x000000FF) << 24) + \ ((hi_u32)(((value) & 0x000000FF) << 24) + \
(hi_u32)(((value)&0x0000FF00) << 8) + (hi_u32)(((value)&0x00FF0000) >> 8) + \ (hi_u32)(((value) & 0x0000FF00) << 8) + \
(hi_u32)(((value)&0xFF000000) >> 24)) (hi_u32)(((value) & 0x00FF0000) >> 8) + \
(hi_u32)(((value) & 0xFF000000) >> 24))
#define hi_swap_byteorder_64(value) \ #define hi_swap_byteorder_64(value) \
((((value)&0x00000000000000ffULL) << 56) + \ ((((value) & 0x00000000000000ffULL) << 56) + \
(((value)&0x000000000000ff00ULL) << 40) + \ (((value) & 0x000000000000ff00ULL) << 40) + \
(((value)&0x0000000000ff0000ULL) << 24) + \ (((value) & 0x0000000000ff0000ULL) << 24) + \
(((value)&0x00000000ff000000ULL) << 8) + \ (((value) & 0x00000000ff000000ULL) << 8) + \
(((value)&0x000000ff00000000ULL) >> 8) + \ (((value) & 0x000000ff00000000ULL) >> 8) + \
(((value)&0x0000ff0000000000ULL) >> 24) + \ (((value) & 0x0000ff0000000000ULL) >> 24) + \
(((value)&0x00ff000000000000ULL) >> 40) + \ (((value) & 0x00ff000000000000ULL) >> 40) + \
(((value)&0xff00000000000000ULL) >> 56)) (((value) & 0xff00000000000000ULL) >> 56))
#undef MIN_T #undef MIN_T
#define MIN_T hi_min #define MIN_T hi_min
#define hi_make_identifier(a, b, c, d) \ #define hi_make_identifier(a, b, c, d) hi_makeu32(hi_makeu16(a, b), hi_makeu16(c, d))
hi_makeu32(hi_makeu16(a, b), hi_makeu16(c, d)) #define hi_make_ver16(spc, b) ((hi_u16)(((hi_u8)((spc)&0x0F)) | ((hi_u16)((hi_u8)(b))) << 12))
#define hi_make_ver16(spc, b) \
((hi_u16)(((hi_u8)((spc)&0x0F)) | ((hi_u16)((hi_u8)(b))) << 12))
#define hi_set_bit_i(val, n) ((val) |= (1 << (n))) #define hi_set_bit_i(val, n) ((val) |= (1 << (n)))
#define hi_clr_bit_i(val, n) ((val) &= ~(1 << (n))) #define hi_clr_bit_i(val, n) ((val) &= ~(1 << (n)))
#define hi_is_bit_set_i(val, n) ((val) & (1 << (n))) #define hi_is_bit_set_i(val, n) ((val) & (1 << (n)))
#define hi_is_bit_clr_i(val, n) (~((val) & (1 << (n)))) #define hi_is_bit_clr_i(val, n) (~((val) & (1 << (n))))
#define hi_switch_bit_i(val, n) ((val) ^= (1 << (n))) #define hi_switch_bit_i(val, n) ((val) ^= (1 << (n)))
#define hi_get_bit_i(val, n) (((val) >> (n)) & 1) #define hi_get_bit_i(val, n) (((val) >> (n)) & 1)
#define hi_reg_clr_bit_i(reg, n) \ #define hi_reg_clr_bit_i(reg, n) ((*(volatile unsigned int *)(reg)) &= ~(1 << (n)))
((*(volatile unsigned int *)(reg)) &= ~(1 << (n)))
#define hi_u8_bit_val(b7, b6, b5, b4, b3, b2, b1, b0) \ #define hi_u8_bit_val(b7, b6, b5, b4, b3, b2, b1, b0) \
(((b7) << 7) | ((b6) << 6) | ((b5) << 5) | ((b4) << 4) | ((b3) << 3) | \ (((b7) << 7) | ((b6) << 6) | ((b5) << 5) | ((b4) << 4) | ((b3) << 3) | ((b2) << 2) | ((b1) << 1) | ((b0) << 0))
((b2) << 2) | ((b1) << 1) | ((b0) << 0)) #define hi_u16_bit_val(b12,b11,b10,b9,b8,b7,b6,b5,b4,b3,b2,b1,b0) \
#define hi_u16_bit_val(b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0) \ (hi_u16)(((b12) << 12) | ((b11) << 11) | ((b10) << 10) | ((b9) << 9) | ((b8) << 8) | ((b7) << 7) | \
(hi_u16)(((b12) << 12) | ((b11) << 11) | ((b10) << 10) | ((b9) << 9) | \ ((b6) << 6) | ((b5) << 5) | ((b4) << 4) | ((b3) << 3) | ((b2) << 2) | ((b1) << 1) | ((b0) << 0))
((b8) << 8) | ((b7) << 7) | ((b6) << 6) | ((b5) << 5) | \
((b4) << 4) | ((b3) << 3) | ((b2) << 2) | ((b1) << 1) | \
((b0) << 0))
#if defined(__ONEBUILDER__CROSS_COMPILER_PRODUCT_CONFIG__) #if defined(__ONEBUILDER__CROSS_COMPILER_PRODUCT_CONFIG__)
#define HSO_ENUM HI_ALIGNED4 enum #define HSO_ENUM HI_ALIGNED4 enum
#define HI_U8A HI_ALIGNED4 hi_u8 #define HI_U8A HI_ALIGNED4 hi_u8
#define HI_U16A HI_ALIGNED4 hi_u16 #define HI_U16A HI_ALIGNED4 hi_u16
#define HI_CHARTA HI_ALIGNED4 hi_char #define HI_CHARTA HI_ALIGNED4 hi_char
#else #else
#define HSO_ENUM enum #define HSO_ENUM enum
#define HI_U8A hi_u8 #define HI_U8A hi_u8
#define HI_U16A hi_u16 #define HI_U16A hi_u16
#define HI_CHARTA hi_char #define HI_CHARTA hi_char
#endif #endif
#if defined(PRODUCT_CFG_HSO) && defined(HI_HAVE_NOTIVE_COMPILER_VC) #if defined(PRODUCT_CFG_HSO) && defined(HI_HAVE_NOTIVE_COMPILER_VC)
#define __FUNCTION__ "NA" #define __FUNCTION__ "NA"
#endif #endif
/*****************************************************************************/ /*****************************************************************************/
#define hi_set_u32_ptr_val(ptr, offset, val) \ #define hi_set_u32_ptr_val(ptr, offset, val) (*((hi_u32*)(((hi_u8*)(ptr)) + (offset))) = (val))
(*((hi_u32 *)(((hi_u8 *)(ptr)) + (offset))) = (val)) #define hi_get_u32_ptr_val(ptr, offset) *((hi_u32*)(((hi_u8*)(ptr)) + (offset)))
#define hi_get_u32_ptr_val(ptr, offset) \
*((hi_u32 *)(((hi_u8 *)(ptr)) + (offset)))
/*****************************************************************************/ /*****************************************************************************/
/*****************************************************************************/ /*****************************************************************************/
#define HI_SIZE_1K 1024 #define HI_SIZE_1K 1024
#define HI_SIZE_1M (1024 * 1024) #define HI_SIZE_1M (1024 * 1024)
/*****************************************************************************/ /*****************************************************************************/
#ifndef bit #ifndef bit
#define bit(x) (1UL << (x)) #define bit(x) (1UL << (x))
#endif #endif
#define BIT31 ((hi_u32)(1UL << 31)) #define BIT31 ((hi_u32)(1UL << 31))
#define BIT30 ((hi_u32)(1 << 30)) #define BIT30 ((hi_u32)(1 << 30))
#define BIT29 ((hi_u32)(1 << 29)) #define BIT29 ((hi_u32)(1 << 29))
#define BIT28 ((hi_u32)(1 << 28)) #define BIT28 ((hi_u32)(1 << 28))
#define BIT27 ((hi_u32)(1 << 27)) #define BIT27 ((hi_u32)(1 << 27))
#define BIT26 ((hi_u32)(1 << 26)) #define BIT26 ((hi_u32)(1 << 26))
#define BIT25 ((hi_u32)(1 << 25)) #define BIT25 ((hi_u32)(1 << 25))
#define BIT24 ((hi_u32)(1 << 24)) #define BIT24 ((hi_u32)(1 << 24))
#define BIT23 ((hi_u32)(1 << 23)) #define BIT23 ((hi_u32)(1 << 23))
#define BIT22 ((hi_u32)(1 << 22)) #define BIT22 ((hi_u32)(1 << 22))
#define BIT21 ((hi_u32)(1 << 21)) #define BIT21 ((hi_u32)(1 << 21))
#define BIT20 ((hi_u32)(1 << 20)) #define BIT20 ((hi_u32)(1 << 20))
#define BIT19 ((hi_u32)(1 << 19)) #define BIT19 ((hi_u32)(1 << 19))
#define BIT18 ((hi_u32)(1 << 18)) #define BIT18 ((hi_u32)(1 << 18))
#define BIT17 ((hi_u32)(1 << 17)) #define BIT17 ((hi_u32)(1 << 17))
#define BIT16 ((hi_u32)(1 << 16)) #define BIT16 ((hi_u32)(1 << 16))
#define BIT15 ((hi_u32)(1 << 15)) #define BIT15 ((hi_u32)(1 << 15))
#define BIT14 ((hi_u32)(1 << 14)) #define BIT14 ((hi_u32)(1 << 14))
#define BIT13 ((hi_u32)(1 << 13)) #define BIT13 ((hi_u32)(1 << 13))
#define BIT12 ((hi_u32)(1 << 12)) #define BIT12 ((hi_u32)(1 << 12))
#define BIT11 ((hi_u32)(1 << 11)) #define BIT11 ((hi_u32)(1 << 11))
#define BIT10 ((hi_u32)(1 << 10)) #define BIT10 ((hi_u32)(1 << 10))
#define BIT9 ((hi_u32)(1 << 9)) #define BIT9 ((hi_u32)(1 << 9))
#define BIT8 ((hi_u32)(1 << 8)) #define BIT8 ((hi_u32)(1 << 8))
#define BIT7 ((hi_u32)(1 << 7)) #define BIT7 ((hi_u32)(1 << 7))
#define BIT6 ((hi_u32)(1 << 6)) #define BIT6 ((hi_u32)(1 << 6))
#define BIT5 ((hi_u32)(1 << 5)) #define BIT5 ((hi_u32)(1 << 5))
#define BIT4 ((hi_u32)(1 << 4)) #define BIT4 ((hi_u32)(1 << 4))
#define BIT3 ((hi_u32)(1 << 3)) #define BIT3 ((hi_u32)(1 << 3))
#define BIT2 ((hi_u32)(1 << 2)) #define BIT2 ((hi_u32)(1 << 2))
#define BIT1 ((hi_u32)(1 << 1)) #define BIT1 ((hi_u32)(1 << 1))
#define BIT0 ((hi_u32)(1 << 0)) #define BIT0 ((hi_u32)(1 << 0))
#define HALFWORD_BIT_WIDTH 16 #define HALFWORD_BIT_WIDTH 16
/* 寄存器访问接口 */ /* 寄存器访问接口 */
#define hi_reg_write(addr, val) \ #define hi_reg_write(addr, val) (*(volatile unsigned int *)(uintptr_t)(addr) = (val))
(*(volatile unsigned int *)(uintptr_t)(addr) = (val)) #define hi_reg_read(addr, val) ((val) = *(volatile unsigned int *)(uintptr_t)(addr))
#define hi_reg_read(addr, val) \ #define hi_reg_write32(addr, val) (*(volatile unsigned int *)(uintptr_t)(addr) = (val))
((val) = *(volatile unsigned int *)(uintptr_t)(addr)) #define hi_reg_read32(addr, val) ((val) = *(volatile unsigned int *)(uintptr_t)(addr))
#define hi_reg_write32(addr, val) \ #define hi_reg_read_val32(addr) (*(volatile unsigned int*)(uintptr_t)(addr))
(*(volatile unsigned int *)(uintptr_t)(addr) = (val)) #define hi_reg_setbitmsk(addr, msk) ((hi_reg_read_val32(addr)) |= (msk))
#define hi_reg_read32(addr, val) \ #define hi_reg_clrbitmsk(addr, msk) ((hi_reg_read_val32(addr)) &= ~(msk))
((val) = *(volatile unsigned int *)(uintptr_t)(addr)) #define hi_reg_clrbit(addr, pos) ((hi_reg_read_val32(addr)) &= ~((unsigned int)(1) << (pos)))
#define hi_reg_read_val32(addr) (*(volatile unsigned int *)(uintptr_t)(addr)) #define hi_reg_setbit(addr, pos) ((hi_reg_read_val32(addr)) |= ((unsigned int)(1) << (pos)))
#define hi_reg_setbitmsk(addr, msk) ((hi_reg_read_val32(addr)) |= (msk)) #define hi_reg_clrbits(addr, pos, bits) (hi_reg_read_val32(addr) &= ~((((unsigned int)1 << (bits)) - 1) << (pos)))
#define hi_reg_clrbitmsk(addr, msk) ((hi_reg_read_val32(addr)) &= ~(msk)) #define hi_reg_setbits(addr, pos, bits, val) (hi_reg_read_val32(addr) = \
#define hi_reg_clrbit(addr, pos) \ (hi_reg_read_val32(addr) & (~((((unsigned int)1 << (bits)) - 1) << (pos)))) | \
((hi_reg_read_val32(addr)) &= ~((unsigned int)(1) << (pos))) ((unsigned int)((val) & (((unsigned int)1 << (bits)) - 1)) << (pos)))
#define hi_reg_setbit(addr, pos) \ #define hi_reg_getbits(addr, pos, bits) ((hi_reg_read_val32(addr) >> (pos)) & (((unsigned int)1 << (bits)) - 1))
((hi_reg_read_val32(addr)) |= ((unsigned int)(1) << (pos)))
#define hi_reg_clrbits(addr, pos, bits) \
(hi_reg_read_val32(addr) &= ~((((unsigned int)1 << (bits)) - 1) << (pos)))
#define hi_reg_setbits(addr, pos, bits, val) \
(hi_reg_read_val32(addr) = \
(hi_reg_read_val32(addr) & \
(~((((unsigned int)1 << (bits)) - 1) << (pos)))) | \
((unsigned int)((val) & (((unsigned int)1 << (bits)) - 1)) << (pos)))
#define hi_reg_getbits(addr, pos, bits) \
((hi_reg_read_val32(addr) >> (pos)) & (((unsigned int)1 << (bits)) - 1))
#define hi_reg_write16(addr, val) \ #define hi_reg_write16(addr, val) (*(volatile unsigned short *)(uintptr_t)(addr) = (val))
(*(volatile unsigned short *)(uintptr_t)(addr) = (val)) #define hi_reg_read16(addr, val) ((val) = *(volatile unsigned short *)(uintptr_t)(addr))
#define hi_reg_read16(addr, val) \ #define hi_reg_read_val16(addr) (*(volatile unsigned short*)(uintptr_t)(addr))
((val) = *(volatile unsigned short *)(uintptr_t)(addr)) #define hi_reg_clrbit16(addr, pos) ((hi_reg_read_val16(addr)) &= ~((unsigned short)(1) << (pos)))
#define hi_reg_read_val16(addr) (*(volatile unsigned short *)(uintptr_t)(addr)) #define hi_reg_setbit16(addr, pos) ((hi_reg_read_val16(addr)) |= ((unsigned short)(1) << (pos)))
#define hi_reg_clrbit16(addr, pos) \ #define hi_reg_clrbits16(addr, pos, bits) (hi_reg_read_val16(addr) &= ~((((unsigned short)1 << (bits)) - 1) << (pos)))
((hi_reg_read_val16(addr)) &= ~((unsigned short)(1) << (pos))) #define hi_reg_setbits16(addr, pos, bits, val) (hi_reg_read_val16(addr) = \
#define hi_reg_setbit16(addr, pos) \ (hi_reg_read_val16(addr) & (~((((unsigned short)1 << (bits)) - 1) << (pos)))) | \
((hi_reg_read_val16(addr)) |= ((unsigned short)(1) << (pos))) ((unsigned short)((val) & (((unsigned short)1 << (bits)) - 1)) << (pos)))
#define hi_reg_clrbits16(addr, pos, bits) \ #define hi_reg_getbits16(addr, pos, bits) ((hi_reg_read_val16(addr) >> (pos)) & (((unsigned short)1 << (bits)) - 1))
(hi_reg_read_val16(addr) &= ~((((unsigned short)1 << (bits)) - 1) << (pos)))
#define hi_reg_setbits16(addr, pos, bits, val) \
(hi_reg_read_val16(addr) = \
(hi_reg_read_val16(addr) & \
(~((((unsigned short)1 << (bits)) - 1) << (pos)))) | \
((unsigned short)((val) & (((unsigned short)1 << (bits)) - 1)) \
<< (pos)))
#define hi_reg_getbits16(addr, pos, bits) \
((hi_reg_read_val16(addr) >> (pos)) & (((unsigned short)1 << (bits)) - 1))
#define reg_write32(addr, val) \ #define reg_write32(addr, val) (*(volatile unsigned int *)(uintptr_t)(addr) = (val))
(*(volatile unsigned int *)(uintptr_t)(addr) = (val)) #define reg_read32(addr, val) ((val) = *(volatile unsigned int *)(uintptr_t)(addr))
#define reg_read32(addr, val) \ #define reg_read_val(addr) (*(volatile unsigned *)(uintptr_t)(addr))
((val) = *(volatile unsigned int *)(uintptr_t)(addr))
#define reg_read_val(addr) (*(volatile unsigned *)(uintptr_t)(addr))
#ifndef BSP_RAM_TEXT_SECTION #ifndef BSP_RAM_TEXT_SECTION
#define BSP_RAM_TEXT_SECTION __attribute__((section(".bsp.ram.text"))) #define BSP_RAM_TEXT_SECTION __attribute__ ((section(".bsp.ram.text")))
#endif #endif
#ifndef BSP_ROM_RODATA_SECTION #ifndef BSP_ROM_RODATA_SECTION
#define BSP_ROM_RODATA_SECTION __attribute__((section(".bsp.rom.rodata"))) #define BSP_ROM_RODATA_SECTION __attribute__ ((section(".bsp.rom.rodata")))
#endif #endif
#ifndef BSP_ROM_DATA0_SECTION #ifndef BSP_ROM_DATA0_SECTION
#define BSP_ROM_DATA0_SECTION __attribute__((section(".bsp.rom.data0"))) #define BSP_ROM_DATA0_SECTION __attribute__ ((section(".bsp.rom.data0")))
#endif #endif
#ifndef ROM_TEXT_PATCH_SECTION #ifndef ROM_TEXT_PATCH_SECTION
#define ROM_TEXT_PATCH_SECTION __attribute__((section(".rom.text.patch"))) #define ROM_TEXT_PATCH_SECTION __attribute__ ((section(".rom.text.patch")))
#endif #endif
#ifndef LP_RAM_BSS_SECTION #ifndef LP_RAM_BSS_SECTION
#define LP_RAM_BSS_SECTION __attribute__((section(".lowpower.ram.bss"))) #define LP_RAM_BSS_SECTION __attribute__ ((section(".lowpower.ram.bss")))
#endif #endif
#ifndef ROM_DATA_PATCH_SECTION #ifndef ROM_DATA_PATCH_SECTION
#define ROM_DATA_PATCH_SECTION __attribute__((section(".rom.data.patch"))) #define ROM_DATA_PATCH_SECTION __attribute__ ((section(".rom.data.patch")))
#endif #endif
#ifdef HAVE_PCLINT_CHECK #ifdef HAVE_PCLINT_CHECK
#define hi_likely(x) (x) #define hi_likely(x) (x)
#define hi_unlikely(x) (x) #define hi_unlikely(x) (x)
#else #else
#define hi_likely(x) __builtin_expect(!!(x), 1) #define hi_likely(x) __builtin_expect(!!(x), 1)
#define hi_unlikely(x) __builtin_expect(!!(x), 0) #define hi_unlikely(x) __builtin_expect(!!(x), 0)
@@ -557,19 +516,20 @@ typedef __int64 hi_s64;
#define HI_ALWAYS_STAIC_INLINE __attribute__((always_inline)) static inline #define HI_ALWAYS_STAIC_INLINE __attribute__((always_inline)) static inline
#ifdef HAVE_PCLINT_CHECK #ifdef HAVE_PCLINT_CHECK
#define hi_offset_of_member(type, member) 0 #define hi_offset_of_member(type, member) 0
#else #else
#define hi_offset_of_member(type, member) ((hi_u32)(&((type *)0)->member)) #define hi_offset_of_member(type, member) ((hi_u32)(&((type *)0)->member))
#endif #endif
#define BITS_PER_BYTE 8 #define BITS_PER_BYTE 8
#define HEXADECIMAL 16 #define HEXADECIMAL 16
#define DECIMAL 10 #define DECIMAL 10
#define SZ_1KB 1024 #define SZ_1KB 1024
#define SZ_1MB (SZ_1KB * SZ_1KB) #define SZ_1MB (SZ_1KB * SZ_1KB)
#define SZ_4KB 4096 #define SZ_4KB 4096
/*****************************************************************************/ /*****************************************************************************/
#include <hi_errno.h> #include <hi_errno.h>
#define HI_SYS_WAIT_FOREVER 0xFFFFFFFF #define HI_SYS_WAIT_FOREVER 0xFFFFFFFF
#endif /* __HI_TYPES__BASE_H__ */ #endif /* __HI_TYPES__BASE_H__ */
@@ -1,207 +1,211 @@
/* /*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
* reserved. Description: sample cli file. Author: Hisilicon Create: 2020-09-09 * Description: sample cli file.
* Author: Hisilicon
* Create: 2020-09-09
*/ */
/***************************************************************************** /*****************************************************************************
1 头文件包含 1 头文件包含
*****************************************************************************/ *****************************************************************************/
#include <unistd.h>
#include <pthread.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/sockios.h> #include <linux/sockios.h>
#include <linux/wireless.h> #include <linux/wireless.h>
#include <netinet/in.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include "securec.h"
#include "hi_base.h" #include "hi_base.h"
#include "hichannel_host.h" #include "hichannel_host.h"
#include "securec.h"
/***************************************************************************** /*****************************************************************************
2 宏定义、全局变量 2 宏定义、全局变量
*****************************************************************************/ *****************************************************************************/
#define NETLINK_SOCKET_PORT_ID 1100 #define NETLINK_SOCKET_PORT_ID 1100
#define NETLINK_CHANNEL_MODEID 28 #define NETLINK_CHANNEL_MODEID 28
#undef NLMSG_ALIGNTO #undef NLMSG_ALIGNTO
#define NLMSG_ALIGNTO 1 #define NLMSG_ALIGNTO 1
#define USLEEP_TIMES 10 #define USLEEP_TIMES 10
typedef struct { typedef struct {
hi_s32 skfd; hi_s32 skfd;
pthread_t channel_thread; pthread_t channel_thread;
hi_channel_rx_func rx_func; hi_channel_rx_func rx_func;
} netlink_monitor_s; } netlink_monitor_s;
/***************************************************************************** /*****************************************************************************
3 枚举、结构体定义 3 枚举、结构体定义
*****************************************************************************/ *****************************************************************************/
static hi_bool g_channel_terminate = HI_FALSE; static hi_bool g_channel_terminate = HI_FALSE;
static netlink_monitor_s *g_channel_monitor = HI_NULL; static netlink_monitor_s *g_channel_monitor = HI_NULL;
/***************************************************************************** /*****************************************************************************
4 函数实现 4 函数实现
*****************************************************************************/ *****************************************************************************/
static hi_void *hi_channel_host_thread(hi_void *args) { static hi_void *hi_channel_host_thread(hi_void *args)
hi_s32 rev_len; {
hi_s32 payload_len; hi_s32 rev_len;
hi_char msg[SYSTEM_CMD_SIZE]; hi_s32 payload_len;
struct nlmsghdr *nlh = HI_NULL; hi_char msg[SYSTEM_CMD_SIZE];
struct sockaddr_nl daddr; struct nlmsghdr *nlh = HI_NULL;
socklen_t len = sizeof(struct sockaddr_nl); struct sockaddr_nl daddr;
sample_unused(args); socklen_t len = sizeof(struct sockaddr_nl);
sample_unused(args);
while (!g_channel_terminate) { while (!g_channel_terminate) {
(hi_void) memset_s(&msg[0], sizeof(msg), 0, sizeof(msg)); (hi_void)memset_s(&msg[0], sizeof(msg), 0, sizeof(msg));
rev_len = recvfrom(g_channel_monitor->skfd, &msg[0], sizeof(msg), rev_len = recvfrom(g_channel_monitor->skfd, &msg[0], sizeof(msg),
MSG_WAITALL, (struct sockaddr *)&daddr, &len); MSG_WAITALL, (struct sockaddr *)&daddr, &len);
if (rev_len == -1) { if (rev_len == -1) {
if (errno == EINTR) { if (errno == EINTR) {
usleep(USLEEP_TIMES); usleep(USLEEP_TIMES);
continue; continue;
} else { } else {
sample_log_print("recvfrom error! fd:%d\n", g_channel_monitor->skfd); sample_log_print("recvfrom error! fd:%d\n", g_channel_monitor->skfd);
return HI_NULL; return HI_NULL;
} }
}
if (rev_len <= NLMSG_HDRLEN) {
usleep(USLEEP_TIMES);
continue;
}
nlh = (struct nlmsghdr *)msg;
payload_len = rev_len - NLMSG_HDRLEN;
sample_log_print("hi_channel_host_thread:%x,%d,%d,%d\n", nlh->nlmsg_type, payload_len, rev_len, NLMSG_HDRLEN);
if (g_channel_monitor->rx_func != HI_NULL) {
g_channel_monitor->rx_func((hi_u8 *)NLMSG_DATA(nlh), payload_len);
}
} }
if (rev_len <= NLMSG_HDRLEN) { return HI_NULL;
usleep(USLEEP_TIMES);
continue;
}
nlh = (struct nlmsghdr *)msg;
payload_len = rev_len - NLMSG_HDRLEN;
sample_log_print("hi_channel_host_thread:%x,%d,%d,%d\n", nlh->nlmsg_type,
payload_len, rev_len, NLMSG_HDRLEN);
if (g_channel_monitor->rx_func != HI_NULL) {
g_channel_monitor->rx_func((hi_u8 *)NLMSG_DATA(nlh), payload_len);
}
}
return HI_NULL;
} }
hi_s32 hi_channel_register_rx_cb(hi_channel_rx_func rx_func) { hi_s32 hi_channel_register_rx_cb(hi_channel_rx_func rx_func)
if ((g_channel_monitor == HI_NULL) || (rx_func == HI_NULL)) { {
sample_log_print("hi_channel_register_rx_cb is fail\n"); if ((g_channel_monitor == HI_NULL) || (rx_func == HI_NULL)) {
return HI_FAILURE; sample_log_print("hi_channel_register_rx_cb is fail\n");
} return HI_FAILURE;
}
g_channel_monitor->rx_func = rx_func; g_channel_monitor->rx_func = rx_func;
return HI_SUCCESS; return HI_SUCCESS;
} }
hi_s32 hi_channel_send_to_dev(unsigned char *buf, int len) { hi_s32 hi_channel_send_to_dev(unsigned char *buf, int len)
int ret; {
struct nlmsghdr *nlh = HI_NULL; int ret;
struct sockaddr_nl daddr; struct nlmsghdr *nlh = HI_NULL;
struct sockaddr_nl daddr;
if ((buf == HI_NULL) || (len <= 0) || (len > MAX_SEND_DATA_SIZE)) { if ((buf == HI_NULL) || (len <= 0) || (len > MAX_SEND_DATA_SIZE)) {
sample_log_print("sendto sata len:%d\n", len); sample_log_print("sendto sata len:%d\n", len);
return HI_FAILURE; return HI_FAILURE;
} }
(hi_void) memset_s(&daddr, sizeof(daddr), 0, sizeof(daddr)); (hi_void)memset_s(&daddr, sizeof(daddr), 0, sizeof(daddr));
daddr.nl_family = AF_NETLINK; /* netlink id */ daddr.nl_family = AF_NETLINK; /* netlink id */
nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(len)); nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(len));
if (nlh == HI_NULL) { if (nlh == HI_NULL) {
sample_log_print("malloc mem is fail\n"); sample_log_print("malloc mem is fail\n");
return HI_FAILURE; return HI_FAILURE;
} }
(hi_void)memset_s(nlh, sizeof(nlh), 0x00, sizeof(nlh));
nlh->nlmsg_len = NLMSG_SPACE(len);
nlh->nlmsg_pid = NETLINK_SOCKET_PORT_ID;
(hi_void)memcpy_s(NLMSG_DATA(nlh), NLMSG_SPACE(len), buf, len);
ret = sendto(g_channel_monitor->skfd, nlh, nlh->nlmsg_len, 0,
(struct sockaddr *)&daddr, sizeof(struct sockaddr_nl));
if (ret == -1) {
sample_log_print("sendto error:%s\n", strerror(errno));
free(nlh);
return HI_FAILURE;
}
(hi_void) memset_s(nlh, sizeof(nlh), 0x00, sizeof(nlh));
nlh->nlmsg_len = NLMSG_SPACE(len);
nlh->nlmsg_pid = NETLINK_SOCKET_PORT_ID;
(hi_void) memcpy_s(NLMSG_DATA(nlh), NLMSG_SPACE(len), buf, len);
ret = sendto(g_channel_monitor->skfd, nlh, nlh->nlmsg_len, 0,
(struct sockaddr *)&daddr, sizeof(struct sockaddr_nl));
if (ret == -1) {
sample_log_print("sendto error:%s\n", strerror(errno));
free(nlh); free(nlh);
return HI_FAILURE; return 0;
}
free(nlh);
return 0;
} }
hi_s32 hi_channel_init(hi_void) { hi_s32 hi_channel_init(hi_void)
hi_s32 ret; {
struct sockaddr_nl saddr = {0}; hi_s32 ret;
struct sockaddr_nl saddr = {0};
if (g_channel_monitor != HI_NULL) { if (g_channel_monitor != HI_NULL) {
sample_log_print("hi_channel_init is fail\n"); sample_log_print("hi_channel_init is fail\n");
return HI_FAILURE; return HI_FAILURE;
} }
g_channel_monitor = (netlink_monitor_s *)malloc(sizeof(netlink_monitor_s)); g_channel_monitor = (netlink_monitor_s *)malloc(sizeof(netlink_monitor_s));
if (g_channel_monitor == HI_NULL) { if (g_channel_monitor == HI_NULL) {
return HI_FAILURE; return HI_FAILURE;
} }
g_channel_terminate = HI_FALSE; g_channel_terminate = HI_FALSE;
(hi_void) memset_s(g_channel_monitor, sizeof(netlink_monitor_s), 0, (hi_void)memset_s(g_channel_monitor, sizeof(netlink_monitor_s), 0, sizeof(netlink_monitor_s));
sizeof(netlink_monitor_s)); g_channel_monitor->skfd = -1;
g_channel_monitor->skfd = -1; g_channel_monitor->skfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_CHANNEL_MODEID);
g_channel_monitor->skfd = if (g_channel_monitor->skfd == -1) {
socket(AF_NETLINK, SOCK_RAW, NETLINK_CHANNEL_MODEID); sample_log_print("create is fail:%s\n", strerror(errno));
if (g_channel_monitor->skfd == -1) { goto deinit;
sample_log_print("create is fail:%s\n", strerror(errno)); }
goto deinit;
}
(hi_void) memset_s(&saddr, sizeof(saddr), 0x00, sizeof(saddr)); (hi_void)memset_s(&saddr, sizeof(saddr), 0x00, sizeof(saddr));
saddr.nl_family = AF_NETLINK; /* netlink id */ saddr.nl_family = AF_NETLINK; /* netlink id */
saddr.nl_pid = NETLINK_SOCKET_PORT_ID; /* self pid */ saddr.nl_pid = NETLINK_SOCKET_PORT_ID; /* self pid */
ret = bind(g_channel_monitor->skfd, (struct sockaddr *)&saddr, sizeof(saddr)); ret = bind(g_channel_monitor->skfd, (struct sockaddr *)&saddr, sizeof(saddr));
if (ret != 0) { if (ret != 0) {
goto deinit; goto deinit;
} }
ret = pthread_create(&g_channel_monitor->channel_thread, HI_NULL, ret = pthread_create(&g_channel_monitor->channel_thread, HI_NULL, hi_channel_host_thread, HI_NULL);
hi_channel_host_thread, HI_NULL); if (ret != HI_SUCCESS) {
if (ret != HI_SUCCESS) { goto deinit;
goto deinit; }
}
return HI_SUCCESS; return HI_SUCCESS;
deinit: deinit:
if (g_channel_monitor->skfd != -1) { if (g_channel_monitor->skfd != -1) {
close(g_channel_monitor->skfd); close(g_channel_monitor->skfd);
g_channel_monitor->skfd = -1; g_channel_monitor->skfd = -1;
} }
if (g_channel_monitor != HI_NULL) { if (g_channel_monitor != HI_NULL) {
free(g_channel_monitor); free(g_channel_monitor);
g_channel_monitor = HI_NULL; g_channel_monitor = HI_NULL;
} }
return HI_FAILURE;
}
hi_s32 hi_channel_deinit(hi_void) {
if (g_channel_monitor == HI_NULL) {
sample_log_print("hi_channel_deinit is fail\n");
return HI_FAILURE; return HI_FAILURE;
}
g_channel_terminate = HI_TRUE;
if (g_channel_monitor->channel_thread) {
pthread_cancel(g_channel_monitor->channel_thread);
pthread_join(g_channel_monitor->channel_thread, HI_NULL);
}
if (g_channel_monitor->skfd != -1) {
close(g_channel_monitor->skfd);
g_channel_monitor->skfd = -1;
}
if (g_channel_monitor != HI_NULL) {
free(g_channel_monitor);
g_channel_monitor = HI_NULL;
}
return HI_SUCCESS;
} }
hi_s32 hi_channel_deinit(hi_void)
{
if (g_channel_monitor == HI_NULL) {
sample_log_print("hi_channel_deinit is fail\n");
return HI_FAILURE;
}
g_channel_terminate = HI_TRUE;
if (g_channel_monitor->channel_thread) {
pthread_cancel(g_channel_monitor->channel_thread);
pthread_join(g_channel_monitor->channel_thread, HI_NULL);
}
if (g_channel_monitor->skfd != -1) {
close(g_channel_monitor->skfd);
g_channel_monitor->skfd = -1;
}
if (g_channel_monitor != HI_NULL) {
free(g_channel_monitor);
g_channel_monitor = HI_NULL;
}
return HI_SUCCESS;
}
@@ -1,6 +1,8 @@
/* /*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
* reserved. Description: sample link file. Author: Hisilicon Create: 2020-09-09 * Description: sample link file.
* Author: Hisilicon
* Create: 2020-09-09
*/ */
#ifndef HISI_LINK_H #ifndef HISI_LINK_H
@@ -13,9 +15,9 @@ extern "C" {
/***************************************************************************** /*****************************************************************************
1 宏定义 1 宏定义
*****************************************************************************/ *****************************************************************************/
#define SYSTEM_CMD_SIZE 384 /* 小于这个值的数据报文通过高优先级通道传输 */ #define SYSTEM_CMD_SIZE 384 /* 小于这个值的数据报文通过高优先级通道传输 */
#define MAX_SEND_DATA_SIZE 1500 /* 小于这个值的数据报文通过低优先级通道传输 */ #define MAX_SEND_DATA_SIZE 1500 /* 小于这个值的数据报文通过低优先级通道传输 */
#define SYSTEM_NETDEV_NAME "wlan0" #define SYSTEM_NETDEV_NAME "wlan0"
typedef void (*hi_channel_rx_func)(unsigned char *msg_data, int len); typedef void (*hi_channel_rx_func)(unsigned char *msg_data, int len);
/***************************************************************************** /*****************************************************************************
@@ -1,20 +1,21 @@
/* /*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
* reserved. Description: sample common file. Author: Hisilicon Create: * Description: sample common file.
* 2018-08-04 * Author: Hisilicon
* Create: 2018-08-04
*/ */
/***************************************************************************** /*****************************************************************************
1 头文件包含 1 头文件包含
*****************************************************************************/ *****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "securec.h"
#include "hichannel_host_comm.h" #include "hichannel_host_comm.h"
#include "hi_base.h" #include "hi_base.h"
#include "securec.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/***************************************************************************** /*****************************************************************************
2 宏定义、全局变量 2 宏定义、全局变量
@@ -24,119 +25,117 @@ static sample_cmd_common g_cmd_com = {0};
/***************************************************************************** /*****************************************************************************
4 函数实现 4 函数实现
*****************************************************************************/ *****************************************************************************/
hi_s32 sample_get_cmd_one_arg(const hi_char *pc_cmd, hi_char *pc_arg, hi_s32 sample_get_cmd_one_arg(const hi_char *pc_cmd, hi_char *pc_arg, hi_u32 pc_arg_len, hi_u32 *pul_cmd_offset)
hi_u32 pc_arg_len, hi_u32 *pul_cmd_offset) { {
const hi_char *pc_cmd_copy = HI_NULL; const hi_char *pc_cmd_copy = HI_NULL;
hi_u32 pos = 0; hi_u32 pos = 0;
if ((pc_cmd == HI_NULL) || (pc_arg == HI_NULL) || if ((pc_cmd == HI_NULL) || (pc_arg == HI_NULL) || (pul_cmd_offset == HI_NULL)) {
(pul_cmd_offset == HI_NULL)) { sample_log_print("pc_cmd/pc_arg/pul_cmd_offset null ptr error %pK, %pK, %pK!\n", \
sample_log_print( pc_cmd, pc_arg, pul_cmd_offset);
"pc_cmd/pc_arg/pul_cmd_offset null ptr error %pK, %pK, %pK!\n", pc_cmd,
pc_arg, pul_cmd_offset);
return HI_FAILURE;
}
pc_cmd_copy = pc_cmd;
while (*pc_cmd_copy != '\0' &&
!((*(pc_cmd_copy) == ',') && (*(pc_cmd_copy - 1) != '\\'))) {
if ((*(pc_cmd_copy + 1) == ',') && (*(pc_cmd_copy) == '\\')) {
++pc_cmd_copy;
continue;
}
pc_arg[pos] = *pc_cmd_copy;
++pos;
++pc_cmd_copy;
if (pos >= pc_arg_len) {
sample_log_print("ul_pos >= WLAN_CMD_NAME_MAX_LEN, ul_pos %d!\n", pos);
return HI_FAILURE;
}
}
pc_arg[pos] = '\0';
/* 字符串到结尾,返回错误码 */
if (pos == 0) {
sample_log_print("return param pc_arg is null!}\r\n");
return HI_FAILURE;
}
*pul_cmd_offset = (hi_u32)(pc_cmd_copy - pc_cmd);
return HI_SUCCESS;
}
hi_s32 sample_parse_cmd(hi_void *wdata, hi_char *cmd, ssize_t len,
hi_void *msg) {
hi_u8 cmd_id;
hi_u32 off_set = 0;
hi_char wlan_name[SAMPLE_CMD_MAX_LEN] = {0};
if (cmd == HI_NULL) {
return HI_FAILURE;
}
if (sample_get_cmd_one_arg(cmd, wlan_name, SAMPLE_CMD_MAX_LEN, &off_set) !=
HI_SUCCESS) {
return HI_FAILURE;
}
cmd += (off_set + 1);
for (cmd_id = 0; cmd_id < g_cmd_com.count; cmd_id++) {
if (strcmp(g_cmd_com.cmd_tbl[cmd_id].cmd_name, wlan_name) == 0) {
if (g_cmd_com.cmd_tbl[cmd_id].func(wdata, cmd, len, msg) != HI_SUCCESS) {
sample_log_print("cmd exec fail!\n");
return HI_FAILURE; return HI_FAILURE;
}
return HI_SUCCESS;
} }
}
return HI_FAILURE; pc_cmd_copy = pc_cmd;
while (*pc_cmd_copy != '\0' && !((*(pc_cmd_copy) == ',') && (*(pc_cmd_copy - 1) != '\\'))) {
if ((*(pc_cmd_copy + 1) == ',') && (*(pc_cmd_copy) == '\\')) {
++pc_cmd_copy;
continue;
}
pc_arg[pos] = *pc_cmd_copy;
++pos;
++pc_cmd_copy;
if (pos >= pc_arg_len) {
sample_log_print("ul_pos >= WLAN_CMD_NAME_MAX_LEN, ul_pos %d!\n", pos);
return HI_FAILURE;
}
}
pc_arg[pos] = '\0';
/* 字符串到结尾,返回错误码 */
if (pos == 0) {
sample_log_print("return param pc_arg is null!}\r\n");
return HI_FAILURE;
}
*pul_cmd_offset = (hi_u32)(pc_cmd_copy - pc_cmd);
return HI_SUCCESS;
} }
hi_s32 sample_sock_cmd_entry(hi_void *wdata, const char *cmd, ssize_t len, hi_s32 sample_parse_cmd(hi_void *wdata, hi_char *cmd, ssize_t len, hi_void *msg)
hi_void *msg) { {
hi_char *pcmd = HI_NULL; hi_u8 cmd_id;
hi_char *pcmd_tmp = HI_NULL; hi_u32 off_set = 0;
if (len > SAMPLE_CMD_MAX_LEN) { hi_char wlan_name[SAMPLE_CMD_MAX_LEN] = {0};
sample_log_print("command len > %d!\n", SAMPLE_CMD_MAX_LEN);
return HI_FAILURE;
}
pcmd = malloc(SAMPLE_CMD_MAX_LEN);
if (pcmd == HI_NULL) {
return HI_FAILURE;
}
if (cmd != HI_NULL) {
if (memcpy_s(pcmd, len, cmd, len) != EOK) {
sample_log_print("command memcpy_s failed!\n");
free(pcmd);
return HI_FAILURE;
}
}
pcmd[len] = '\0'; if (cmd == HI_NULL) {
pcmd_tmp = pcmd; return HI_FAILURE;
if (sample_parse_cmd(wdata, pcmd_tmp, len, msg) != HI_SUCCESS) { }
if (sample_get_cmd_one_arg(cmd, wlan_name, SAMPLE_CMD_MAX_LEN, &off_set) != HI_SUCCESS) {
return HI_FAILURE;
}
cmd += (off_set + 1);
for (cmd_id = 0; cmd_id < g_cmd_com.count; cmd_id++) {
if (strcmp(g_cmd_com.cmd_tbl[cmd_id].cmd_name, wlan_name) == 0) {
if (g_cmd_com.cmd_tbl[cmd_id].func(wdata, cmd, len, msg) != HI_SUCCESS) {
sample_log_print("cmd exec fail!\n");
return HI_FAILURE;
}
return HI_SUCCESS;
}
}
return HI_FAILURE;
}
hi_s32 sample_sock_cmd_entry(hi_void *wdata, const char *cmd, ssize_t len, hi_void *msg)
{
hi_char *pcmd = HI_NULL;
hi_char *pcmd_tmp = HI_NULL;
if (len > SAMPLE_CMD_MAX_LEN) {
sample_log_print("command len > %d!\n", SAMPLE_CMD_MAX_LEN);
return HI_FAILURE;
}
pcmd = malloc(SAMPLE_CMD_MAX_LEN);
if (pcmd == HI_NULL) {
return HI_FAILURE;
}
if (cmd != HI_NULL) {
if (memcpy_s(pcmd, len, cmd, len) != EOK) {
sample_log_print("command memcpy_s failed!\n");
free(pcmd);
return HI_FAILURE;
}
}
pcmd[len] = '\0';
pcmd_tmp = pcmd;
if (sample_parse_cmd(wdata, pcmd_tmp, len, msg) != HI_SUCCESS) {
free(pcmd);
return HI_FAILURE;
}
free(pcmd); free(pcmd);
return HI_FAILURE; return HI_SUCCESS;
}
free(pcmd);
return HI_SUCCESS;
} }
hi_s32 sample_register_cmd(sample_cmd_entry_stru *cmd_tbl, hi_u32 num) { hi_s32 sample_register_cmd(sample_cmd_entry_stru *cmd_tbl, hi_u32 num)
hi_u32 i; {
sample_cmd_common *tmp_list = HI_NULL; hi_u32 i;
tmp_list = (sample_cmd_common *)&g_cmd_com; sample_cmd_common *tmp_list = HI_NULL;
for (i = 0; i < num; i++) { tmp_list = (sample_cmd_common *)&g_cmd_com;
if (cmd_tbl[i].cmd_name == HI_NULL || cmd_tbl[i].func == HI_NULL) { for (i = 0; i < num; i++) {
sample_log_print("SAMPLE_COMMON: register cmd table failed!\n"); if (cmd_tbl[i].cmd_name == HI_NULL || cmd_tbl[i].func == HI_NULL) {
return HI_FAILURE; sample_log_print("SAMPLE_COMMON: register cmd table failed!\n");
return HI_FAILURE;
}
} }
} tmp_list->cmd_tbl = cmd_tbl;
tmp_list->cmd_tbl = cmd_tbl; tmp_list->count = num;
tmp_list->count = num; return HI_SUCCESS;
return HI_SUCCESS;
} }
@@ -1,7 +1,8 @@
/* /*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
* reserved. Description: sample common file. Author: Hisilicon Create: * Description: sample common file.
* 2018-08-04 * Author: Hisilicon
* Create: 2018-08-04
*/ */
#ifndef __SAMPLE_COMMON_H__ #ifndef __SAMPLE_COMMON_H__
@@ -19,30 +20,27 @@
/***************************************************************************** /*****************************************************************************
3 枚举、结构体定义 3 枚举、结构体定义
*****************************************************************************/ *****************************************************************************/
typedef hi_s32 (*sample_cmd_func)(hi_void *wdata, hi_char *param, hi_u32 len, typedef hi_s32(*sample_cmd_func)(hi_void *wdata, hi_char *param, hi_u32 len, hi_void *pmsg);
hi_void *pmsg);
typedef struct { typedef struct {
hi_char *cmd_name; /* 命令字符串 */ hi_char *cmd_name; /* 命令字符串 */
sample_cmd_func func; /* 命令对应处理函数 */ sample_cmd_func func; /* 命令对应处理函数 */
} sample_cmd_entry_stru; } sample_cmd_entry_stru;
typedef struct { typedef struct {
sample_cmd_entry_stru *cmd_tbl; /* 命令表 */ sample_cmd_entry_stru *cmd_tbl; /* 命令表 */
hi_u32 count; /* 命令总数 */ hi_u32 count; /* 命令总数 */
} sample_cmd_common; } sample_cmd_common;
/***************************************************************************** /*****************************************************************************
4 函数声明 4 函数声明
*****************************************************************************/ *****************************************************************************/
hi_s32 sample_get_cmd_one_arg(const hi_char *pc_cmd, hi_char *pc_arg, hi_s32 sample_get_cmd_one_arg(const hi_char *pc_cmd, hi_char *pc_arg, hi_u32 pc_arg_len, hi_u32 *pul_cmd_offset);
hi_u32 pc_arg_len, hi_u32 *pul_cmd_offset);
hi_s32 sample_parse_cmd(hi_void *wdata, hi_char *cmd, ssize_t len, hi_s32 sample_parse_cmd(hi_void *wdata, hi_char *cmd, ssize_t len, hi_void *msg);
hi_void *msg);
hi_s32 sample_sock_cmd_entry(hi_void *wdata, const char *cmd, ssize_t len, hi_s32 sample_sock_cmd_entry(hi_void *wdata, const char *cmd, ssize_t len, hi_void *msg);
hi_void *msg);
hi_s32 sample_register_cmd(sample_cmd_entry_stru *cmd_tbl, hi_u32 num); hi_s32 sample_register_cmd(sample_cmd_entry_stru *cmd_tbl, hi_u32 num);
#endif #endif
@@ -1,35 +1,35 @@
/* /*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
* reserved. Description: sample cli file. Author: Hisilicon Create: 2020-09-09 * Description: sample cli file.
* Author: Hisilicon
* Create: 2020-09-09
*/ */
/***************************************************************************** /*****************************************************************************
1 头文件包含 1 头文件包含
*****************************************************************************/ *****************************************************************************/
#include <linux/if.h> #include <unistd.h>
#include <linux/sockios.h>
#include <linux/wireless.h>
#include <netinet/in.h>
#include <pthread.h>
#include <signal.h> #include <signal.h>
#include <sys/socket.h> #include <pthread.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <sys/socket.h>
#include <netinet/in.h>
#include <linux/sockios.h>
#include <linux/if.h>
#include <linux/wireless.h>
#include "securec.h"
#include "hi_base.h" #include "hi_base.h"
#include "hichannel_host.h" #include "hichannel_host.h"
#include "hichannel_host_comm.h" #include "hichannel_host_comm.h"
#include "securec.h"
/***************************************************************************** /*****************************************************************************
2 宏定义、全局变量 2 宏定义、全局变量
*****************************************************************************/ *****************************************************************************/
static hi_s32 sample_exit_cmd_process(hi_void *wdata, hi_char *param, static hi_s32 sample_exit_cmd_process(hi_void *wdata, hi_char *param, hi_u32 len, hi_void *pmsg);
hi_u32 len, hi_void *pmsg); static hi_s32 sample_help_cmd_process(hi_void *wdata, hi_char *param, hi_u32 len, hi_void *pmsg);
static hi_s32 sample_help_cmd_process(hi_void *wdata, hi_char *param,
hi_u32 len, hi_void *pmsg);
static const sample_cmd_entry_stru g_sample_cmd[] = { static const sample_cmd_entry_stru g_sample_cmd[] = {
{"help", sample_help_cmd_process}, {"help", sample_help_cmd_process},
{"exit", sample_exit_cmd_process}, {"exit", sample_exit_cmd_process},
}; };
@@ -43,494 +43,490 @@ static const sample_cmd_entry_stru g_sample_cmd[] = {
3 枚举、结构体定义 3 枚举、结构体定义
*****************************************************************************/ *****************************************************************************/
typedef enum { typedef enum {
/* commands */ /* commands */
SAMPLE_CMD_IOCTL, SAMPLE_CMD_IOCTL,
SAMPLE_CMD_HELP, SAMPLE_CMD_HELP,
SAMPLE_CMD_EXIT, SAMPLE_CMD_EXIT,
SAMPLE_CMD_BUTT, SAMPLE_CMD_BUTT,
} sample_cmd_e; } sample_cmd_e;
typedef enum { typedef enum {
HOST_CMD_GET_MAC, HOST_CMD_GET_MAC,
HOST_CMD_GET_IP, HOST_CMD_GET_IP,
HOST_CMD_SET_FILTER, HOST_CMD_SET_FILTER,
HOST_CMD_TBTT, HOST_CMD_TBTT,
} host_cmd_e; }host_cmd_e;
/* command/event information */ /* command/event information */
typedef struct { typedef struct {
sample_cmd_e what; sample_cmd_e what;
hi_u32 len; hi_u32 len;
hi_u8 obj[CMD_MAX_LEN]; hi_u8 obj[CMD_MAX_LEN];
} sample_message_s; } sample_message_s;
struct snode { struct snode {
sample_message_s message; sample_message_s message;
struct snode *next; struct snode *next;
}; };
struct squeue { struct squeue {
struct snode *front; struct snode *front;
struct snode *rear; struct snode *rear;
}; };
typedef struct { typedef struct {
pthread_mutex_t mut; pthread_mutex_t mut;
pthread_cond_t cond; pthread_cond_t cond;
struct squeue cmd_queue; struct squeue cmd_queue;
pthread_t sock_thread; pthread_t sock_thread;
hi_s32 sockfd; hi_s32 sockfd;
} sample_link_s; } sample_link_s;
static hi_bool g_terminate = HI_FALSE; static hi_bool g_terminate = HI_FALSE;
static sample_link_s *g_sample_link = HI_NULL; static sample_link_s *g_sample_link = HI_NULL;
static hi_char host_cmd[][MAX_CMD_LEN] = {"cmd_get_mac", "cmd_get_ip", static hi_char host_cmd[][MAX_CMD_LEN] = {"cmd_get_mac", "cmd_get_ip", "cmd_set_filter"};
"cmd_set_filter"};
/***************************************************************************** /*****************************************************************************
4 函数实现 4 函数实现
*****************************************************************************/ *****************************************************************************/
static hi_void sample_usage(hi_void) { static hi_void sample_usage(hi_void)
printf("\nUsage:\n"); {
printf("\tsample_cli quit quit sample_ap\n"); printf("\nUsage:\n");
printf("\tsample_cli help show this message\n"); printf("\tsample_cli quit quit sample_ap\n");
printf("\tsample_cli help show this message\n");
} }
hi_s32 sample_str_cmd_process(hi_void *wdata, hi_char *param, hi_u32 len, hi_s32 sample_str_cmd_process(hi_void *wdata, hi_char *param, hi_u32 len, hi_void *pmsg)
hi_void *pmsg) { {
sample_unused(wdata); sample_unused(wdata);
sample_message_s *msg = (sample_message_s *)pmsg; sample_message_s *msg = (sample_message_s *)pmsg;
msg->what = SAMPLE_CMD_IOCTL; msg->what = SAMPLE_CMD_IOCTL;
msg->len = len; msg->len = len;
(hi_void) memcpy_s(msg->obj, CMD_MAX_LEN, param, len); (hi_void)memcpy_s(msg->obj, CMD_MAX_LEN, param, len);
msg->obj[CMD_MAX_LEN - 1] = '\0'; msg->obj[CMD_MAX_LEN - 1] = '\0';
return HI_SUCCESS;
}
hi_s32 sample_help_cmd_process(hi_void *wdata, hi_char *param, hi_u32 len,
hi_void *pmsg) {
sample_unused(wdata);
sample_unused(param);
sample_unused(len);
sample_message_s *msg = (sample_message_s *)pmsg;
msg->what = SAMPLE_CMD_HELP;
return HI_SUCCESS;
}
static hi_s32 sample_exit_cmd_process(hi_void *wdata, hi_char *param,
hi_u32 len, hi_void *pmsg) {
sample_unused(wdata);
sample_unused(param);
sample_unused(len);
sample_message_s *msg = (sample_message_s *)pmsg;
msg->what = SAMPLE_CMD_EXIT;
return HI_SUCCESS;
}
static hi_void sample_cleanup(hi_void) {
sample_log_print("sample_cleanup enter\n");
if (g_sample_link->sock_thread) {
pthread_cancel(g_sample_link->sock_thread);
pthread_join(g_sample_link->sock_thread, HI_NULL);
}
pthread_mutex_destroy(&g_sample_link->mut);
pthread_cond_destroy(&g_sample_link->cond);
if (g_sample_link->sockfd != -1) {
close(g_sample_link->sockfd);
}
if (g_sample_link != HI_NULL) {
free(g_sample_link);
g_sample_link = HI_NULL;
}
}
static hi_void sample_terminate(hi_s32 sig) {
sample_unused(sig);
sample_cleanup();
g_terminate = HI_TRUE;
_exit(0);
}
static hi_void sample_power(hi_s32 sig) { sample_unused(sig); }
static hi_s32 sample_wlan_init_up(hi_void) {
hi_s32 ret;
hi_char cmd[SYSTEM_CMD_SIZE] = {0};
(hi_void) memset_s(cmd, SYSTEM_CMD_SIZE, 0, SYSTEM_CMD_SIZE);
if (snprintf_s(cmd, SYSTEM_CMD_SIZE, SYSTEM_CMD_SIZE - 1, "ifconfig %s up",
SYSTEM_NETDEV_NAME) == -1) {
sample_log_print("snprintf_s fail\n");
return HI_FAILURE;
}
ret = system(cmd);
if (ret == -1) {
sample_log_print("%s up error\n", SYSTEM_NETDEV_NAME);
return HI_FAILURE;
}
sample_log_print("net device up success\n");
return HI_SUCCESS;
}
static hi_s32 sample_wlan_init_mac(hi_u8 *mac_addr, hi_u8 len) {
hi_s32 ret;
hi_char cmd[SYSTEM_CMD_SIZE] = {0};
if (len != WIFI_MAC_LEN) {
return HI_FAILURE;
}
(hi_void) memset_s(cmd, SYSTEM_CMD_SIZE, 0, SYSTEM_CMD_SIZE);
if (snprintf_s(cmd, SYSTEM_CMD_SIZE, SYSTEM_CMD_SIZE - 1, "ifconfig %s down",
SYSTEM_NETDEV_NAME) == -1) {
sample_log_print("snprintf_s fail\n");
return HI_FAILURE;
}
ret = system(cmd);
if (ret == -1) {
sample_log_print("%s down error\n", SYSTEM_NETDEV_NAME);
return HI_FAILURE;
}
(hi_void) memset_s(cmd, SYSTEM_CMD_SIZE, 0, SYSTEM_CMD_SIZE);
if (snprintf_s(cmd, SYSTEM_CMD_SIZE, SYSTEM_CMD_SIZE - 1,
"ifconfig %s hw ether %x:%x:%x:%x:%x:%x",
/* 2, 3, 4, 5: MAC地址的第2, 3, 4, 5 Byte */
SYSTEM_NETDEV_NAME, mac_addr[0], mac_addr[1], mac_addr[2],
mac_addr[3], mac_addr[4], mac_addr[5]) == -1) {
sample_log_print("snprintf_s fail\n");
return HI_FAILURE;
}
ret = system(cmd);
if (ret == -1) {
sample_log_print("%s set mac error\n", SYSTEM_NETDEV_NAME);
return HI_FAILURE;
}
(hi_void) memset_s(cmd, SYSTEM_CMD_SIZE, 0, SYSTEM_CMD_SIZE);
if (snprintf_s(cmd, SYSTEM_CMD_SIZE, SYSTEM_CMD_SIZE - 1, "ifconfig %s up",
SYSTEM_NETDEV_NAME) == -1) {
sample_log_print("snprintf_s fail\n");
return HI_FAILURE;
}
ret = system(cmd);
if (ret == -1) {
sample_log_print("%s up error\n", SYSTEM_NETDEV_NAME);
return HI_FAILURE;
}
sample_log_print("net device set mac success\n");
return HI_SUCCESS;
}
static hi_s32 sample_wlan_init_ip(hi_u8 *ip_addr, hi_u8 len) {
hi_s32 ret;
hi_char cmd[SYSTEM_CMD_SIZE] = {0};
sample_unused(len);
if ((ip_addr[0] == 0) && (ip_addr[1] == 0) && (ip_addr[2] == 0) &&
(ip_addr[3] == 0)) { /* 1 2 3 ipaddr */
return HI_SUCCESS; return HI_SUCCESS;
}
(hi_void) memset_s(cmd, SYSTEM_CMD_SIZE, 0, SYSTEM_CMD_SIZE);
if (snprintf_s(cmd, SYSTEM_CMD_SIZE, SYSTEM_CMD_SIZE - 1, "ifconfig %s down",
SYSTEM_NETDEV_NAME) == -1) {
sample_log_print("snprintf_s fail\n");
return HI_FAILURE;
}
ret = system(cmd);
if (ret == -1) {
sample_log_print("%s down error\n", SYSTEM_NETDEV_NAME);
return HI_FAILURE;
}
(hi_void) memset_s(cmd, SYSTEM_CMD_SIZE, 0, SYSTEM_CMD_SIZE);
if (snprintf_s(cmd, SYSTEM_CMD_SIZE, SYSTEM_CMD_SIZE - 1,
"ifconfig %s %d.%d.%d.%d netmask %d.%d.%d.%d",
SYSTEM_NETDEV_NAME,
/* 2, 3, 4, 5, 6, 7: 分别为IP地址的第2, 3, 4, 5, 6, 7 Byte */
ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3], ip_addr[4],
ip_addr[5], ip_addr[6], ip_addr[7]) == -1) {
sample_log_print("snprintf_s fail\n");
return HI_FAILURE;
}
ret = system(cmd);
if (ret == -1) {
sample_log_print("%s set ip error\n", SYSTEM_NETDEV_NAME);
return HI_FAILURE;
}
(hi_void) memset_s(cmd, SYSTEM_CMD_SIZE, 0, SYSTEM_CMD_SIZE);
if (snprintf_s(cmd, SYSTEM_CMD_SIZE, SYSTEM_CMD_SIZE - 1, "ifconfig %s up",
SYSTEM_NETDEV_NAME) == -1) {
sample_log_print("snprintf_s fail\n");
return HI_FAILURE;
}
ret = system(cmd);
if (ret == -1) {
sample_log_print("%s up error\n", SYSTEM_NETDEV_NAME);
return HI_FAILURE;
}
sample_log_print("net device set ip success\n");
return HI_SUCCESS;
} }
static hi_void set_lo_ipaddr(hi_void) { hi_s32 sample_help_cmd_process(hi_void *wdata, hi_char *param, hi_u32 len, hi_void *pmsg)
hi_s32 results; {
hi_char cmd[SYSTEM_CMD_SIZE] = {0}; /* system Temporary variables */ sample_unused(wdata);
hi_char *spawn_args[] = {"ifconfig", "lo", "127.0.0.1", HI_NULL}; sample_unused(param);
sample_unused(len);
results = sprintf_s( sample_message_s *msg = (sample_message_s *)pmsg;
cmd, sizeof(cmd), "%s %s %s", spawn_args[0], /* spawn_args[0]:ifconfig */ msg->what = SAMPLE_CMD_HELP;
spawn_args[1], spawn_args[2]); /* spawn_args[1]:lo,spawn_args[2]:ipaddr */ return HI_SUCCESS;
if (results < EOK) {
sample_log_print("SAMPLE_STA: set lo ipaddr sprintf_s err!\n");
return;
}
system(cmd);
} }
static hi_s32 sample_sock_create(hi_void) { static hi_s32 sample_exit_cmd_process(hi_void *wdata, hi_char *param, hi_u32 len, hi_void *pmsg)
if (g_sample_link == HI_NULL) { {
return HI_FAILURE; sample_unused(wdata);
} sample_unused(param);
sample_unused(len);
g_sample_link->sockfd = socket(AF_INET, SOCK_DGRAM, 0); sample_message_s *msg = (sample_message_s *)pmsg;
if (g_sample_link->sockfd == -1) { msg->what = SAMPLE_CMD_EXIT;
sample_log_print("error:%s", strerror(errno)); return HI_SUCCESS;
return HI_FAILURE;
}
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SOCK_PORT);
if (bind(g_sample_link->sockfd, (const struct sockaddr *)&servaddr,
sizeof(servaddr)) == -1) {
sample_log_print("error:%s", strerror(errno));
return HI_FAILURE;
}
return HI_SUCCESS;
} }
static hi_s32 sample_enqueue(struct squeue *pqueue, static hi_void sample_cleanup(hi_void)
const sample_message_s *element) { {
struct snode *pnew = HI_NULL; sample_log_print("sample_cleanup enter\n");
if (g_sample_link->sock_thread) {
if (pqueue == HI_NULL || element == HI_NULL) { pthread_cancel(g_sample_link->sock_thread);
return -1; pthread_join(g_sample_link->sock_thread, HI_NULL);
}
/* Create a new node */
pnew = malloc(sizeof(struct snode));
if (pnew == HI_NULL) {
return -1;
}
pnew->message = *element;
pnew->next = HI_NULL;
if (pqueue->rear == HI_NULL) {
/* queue is empty, set front and rear points to new node */
pqueue->front = pqueue->rear = pnew;
} else {
/* queue is not empty, set rear points to the new node */
pqueue->rear = pqueue->rear->next = pnew;
}
return HI_SUCCESS;
}
static hi_s32 sample_dequeue(struct squeue *pqueue, sample_message_s *element) {
struct snode *p = HI_NULL;
if (pqueue == HI_NULL || element == HI_NULL) {
return HI_FAILURE;
}
if (pqueue->front == HI_NULL) {
return HI_FAILURE;
}
*element = pqueue->front->message;
p = pqueue->front;
pqueue->front = p->next;
/* if the queue is empty, set rear = NULL */
if (pqueue->front == HI_NULL) {
pqueue->rear = HI_NULL;
}
free(p);
return HI_SUCCESS;
}
static hi_void *sample_sock_thread(hi_void *args) {
hi_char link_buf[SOCK_BUF_MAX];
ssize_t recvbytes;
sample_message_s message;
struct sockaddr_in clientaddr;
socklen_t addrlen = sizeof(clientaddr);
sample_unused(args);
while (1) {
/* 安全编程规则6.6例外(1)
* 对固定长度的数组进行初始化,或对固定长度的结构体进行内存初始化 */
(hi_void) memset_s(link_buf, sizeof(link_buf), 0, sizeof(link_buf));
/* 安全编程规则6.6例外(1)
* 对固定长度的数组进行初始化,或对固定长度的结构体进行内存初始化 */
(hi_void) memset_s(&clientaddr, sizeof(struct sockaddr_in), 0, addrlen);
recvbytes = recvfrom(g_sample_link->sockfd, link_buf, sizeof(link_buf), 0,
(struct sockaddr *)&clientaddr, &addrlen);
if (recvbytes < 0) {
if (errno == EINTR) {
usleep(SLEEP_TIME);
continue;
} else {
sample_log_print("recvfrom error! fd:%d\n", g_sample_link->sockfd);
return HI_NULL;
}
} }
if (sample_sock_cmd_entry(g_sample_link, link_buf, recvbytes, pthread_mutex_destroy(&g_sample_link->mut);
(hi_void *)&message) != HI_SUCCESS) { pthread_cond_destroy(&g_sample_link->cond);
sample_log_print("sample_str_cmd_process entry\n");
sample_str_cmd_process(g_sample_link, link_buf, recvbytes, if (g_sample_link->sockfd != -1) {
(hi_void *)&message); close(g_sample_link->sockfd);
} }
if (sendto(g_sample_link->sockfd, "OK", strlen("OK"), MSG_DONTWAIT, if (g_sample_link != HI_NULL) {
(const struct sockaddr *)&clientaddr, addrlen) == -1) { free(g_sample_link);
sample_log_print("sendto error!fd:%d\n", g_sample_link->sockfd); g_sample_link = HI_NULL;
} }
pthread_mutex_lock(&g_sample_link->mut);
if (sample_enqueue(&g_sample_link->cmd_queue, &message) == HI_SUCCESS) {
pthread_cond_signal(&g_sample_link->cond);
}
pthread_mutex_unlock(&g_sample_link->mut);
}
} }
void sample_link_rec_cb(unsigned char *msg_data, int len) { static hi_void sample_terminate(hi_s32 sig)
hi_s32 ret; {
hi_s32 index; sample_unused(sig);
sample_cleanup();
if ((len == 0) || (msg_data == HI_NULL)) { g_terminate = HI_TRUE;
return; _exit(0);
}
index = msg_data[0];
sample_log_print("hisi_link_rec:%d\n", index);
if (index == HOST_CMD_GET_MAC) {
ret = sample_wlan_init_mac(&msg_data[1], WIFI_MAC_LEN);
if (ret != HI_SUCCESS) {
sample_log_print("sample_wlan_init_mac is fail\n");
}
} else if (index == HOST_CMD_GET_IP) {
ret = sample_wlan_init_ip(&msg_data[1], len - 1);
if (ret != HI_SUCCESS) {
sample_log_print("sample_wlan_init_ip is fail\n");
}
} else {
sample_log_print("hisi_link_rec is fail\n");
}
} }
void main_process(void) { static hi_void sample_power(hi_s32 sig)
/* main loop */ {
while (!g_terminate) { sample_unused(sig);
}
static hi_s32 sample_wlan_init_up(hi_void)
{
hi_s32 ret;
hi_char cmd[SYSTEM_CMD_SIZE] = {0};
(hi_void)memset_s(cmd, SYSTEM_CMD_SIZE, 0, SYSTEM_CMD_SIZE);
if (snprintf_s(cmd, SYSTEM_CMD_SIZE, SYSTEM_CMD_SIZE - 1, "ifconfig %s up", SYSTEM_NETDEV_NAME) == -1) {
sample_log_print("snprintf_s fail\n");
return HI_FAILURE;
}
ret = system(cmd);
if (ret == -1) {
sample_log_print("%s up error\n", SYSTEM_NETDEV_NAME);
return HI_FAILURE;
}
sample_log_print("net device up success\n");
return HI_SUCCESS;
}
static hi_s32 sample_wlan_init_mac(hi_u8 *mac_addr, hi_u8 len)
{
hi_s32 ret;
hi_char cmd[SYSTEM_CMD_SIZE] = {0};
if (len != WIFI_MAC_LEN) {
return HI_FAILURE;
}
(hi_void)memset_s(cmd, SYSTEM_CMD_SIZE, 0, SYSTEM_CMD_SIZE);
if (snprintf_s(cmd, SYSTEM_CMD_SIZE, SYSTEM_CMD_SIZE - 1, "ifconfig %s down", SYSTEM_NETDEV_NAME) == -1) {
sample_log_print("snprintf_s fail\n");
return HI_FAILURE;
}
ret = system(cmd);
if (ret == -1) {
sample_log_print("%s down error\n", SYSTEM_NETDEV_NAME);
return HI_FAILURE;
}
(hi_void)memset_s(cmd, SYSTEM_CMD_SIZE, 0, SYSTEM_CMD_SIZE);
if (snprintf_s(cmd, SYSTEM_CMD_SIZE, SYSTEM_CMD_SIZE - 1, "ifconfig %s hw ether %x:%x:%x:%x:%x:%x",
/* 2, 3, 4, 5: MAC地址的第2, 3, 4, 5 Byte */
SYSTEM_NETDEV_NAME, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]) == -1) {
sample_log_print("snprintf_s fail\n");
return HI_FAILURE;
}
ret = system(cmd);
if (ret == -1) {
sample_log_print("%s set mac error\n", SYSTEM_NETDEV_NAME);
return HI_FAILURE;
}
(hi_void)memset_s(cmd, SYSTEM_CMD_SIZE, 0, SYSTEM_CMD_SIZE);
if (snprintf_s(cmd, SYSTEM_CMD_SIZE, SYSTEM_CMD_SIZE - 1, "ifconfig %s up", SYSTEM_NETDEV_NAME) == -1) {
sample_log_print("snprintf_s fail\n");
return HI_FAILURE;
}
ret = system(cmd);
if (ret == -1) {
sample_log_print("%s up error\n", SYSTEM_NETDEV_NAME);
return HI_FAILURE;
}
sample_log_print("net device set mac success\n");
return HI_SUCCESS;
}
static hi_s32 sample_wlan_init_ip(hi_u8 *ip_addr, hi_u8 len)
{
hi_s32 ret;
hi_char cmd[SYSTEM_CMD_SIZE] = {0};
sample_unused(len);
if ((ip_addr[0] == 0) && (ip_addr[1] == 0) && (ip_addr[2] == 0) && (ip_addr[3] == 0)) { /* 1 2 3 ipaddr */
return HI_SUCCESS;
}
(hi_void)memset_s(cmd, SYSTEM_CMD_SIZE, 0, SYSTEM_CMD_SIZE);
if (snprintf_s(cmd, SYSTEM_CMD_SIZE, SYSTEM_CMD_SIZE - 1, "ifconfig %s down", SYSTEM_NETDEV_NAME) == -1) {
sample_log_print("snprintf_s fail\n");
return HI_FAILURE;
}
ret = system(cmd);
if (ret == -1) {
sample_log_print("%s down error\n", SYSTEM_NETDEV_NAME);
return HI_FAILURE;
}
(hi_void)memset_s(cmd, SYSTEM_CMD_SIZE, 0, SYSTEM_CMD_SIZE);
if (snprintf_s(cmd, SYSTEM_CMD_SIZE, SYSTEM_CMD_SIZE - 1,
"ifconfig %s %d.%d.%d.%d netmask %d.%d.%d.%d",
SYSTEM_NETDEV_NAME,
/* 2, 3, 4, 5, 6, 7: 分别为IP地址的第2, 3, 4, 5, 6, 7 Byte */
ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3], ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]) == -1) {
sample_log_print("snprintf_s fail\n");
return HI_FAILURE;
}
ret = system(cmd);
if (ret == -1) {
sample_log_print("%s set ip error\n", SYSTEM_NETDEV_NAME);
return HI_FAILURE;
}
(hi_void)memset_s(cmd, SYSTEM_CMD_SIZE, 0, SYSTEM_CMD_SIZE);
if (snprintf_s(cmd, SYSTEM_CMD_SIZE, SYSTEM_CMD_SIZE - 1, "ifconfig %s up", SYSTEM_NETDEV_NAME) == -1) {
sample_log_print("snprintf_s fail\n");
return HI_FAILURE;
}
ret = system(cmd);
if (ret == -1) {
sample_log_print("%s up error\n", SYSTEM_NETDEV_NAME);
return HI_FAILURE;
}
sample_log_print("net device set ip success\n");
return HI_SUCCESS;
}
static hi_void set_lo_ipaddr(hi_void)
{
hi_s32 results;
hi_char cmd[SYSTEM_CMD_SIZE] = {0}; /* system Temporary variables */
hi_char *spawn_args[] = {"ifconfig", "lo", "127.0.0.1", HI_NULL};
results = sprintf_s(cmd, sizeof(cmd), "%s %s %s", spawn_args[0], /* spawn_args[0]:ifconfig */
spawn_args[1], spawn_args[2]); /* spawn_args[1]:lo,spawn_args[2]:ipaddr */
if (results < EOK) {
sample_log_print("SAMPLE_STA: set lo ipaddr sprintf_s err!\n");
return;
}
system(cmd);
}
static hi_s32 sample_sock_create(hi_void)
{
if (g_sample_link == HI_NULL) {
return HI_FAILURE;
}
g_sample_link->sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (g_sample_link->sockfd == -1) {
sample_log_print("error:%s", strerror(errno));
return HI_FAILURE;
}
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SOCK_PORT);
if (bind(g_sample_link->sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
sample_log_print("error:%s", strerror(errno));
return HI_FAILURE;
}
return HI_SUCCESS;
}
static hi_s32 sample_enqueue(struct squeue *pqueue, const sample_message_s *element)
{
struct snode *pnew = HI_NULL;
if (pqueue == HI_NULL || element == HI_NULL) {
return -1;
}
/* Create a new node */
pnew = malloc(sizeof(struct snode));
if (pnew == HI_NULL) {
return -1;
}
pnew->message = *element;
pnew->next = HI_NULL;
if (pqueue->rear == HI_NULL) {
/* queue is empty, set front and rear points to new node */
pqueue->front = pqueue->rear = pnew;
} else {
/* queue is not empty, set rear points to the new node */
pqueue->rear = pqueue->rear->next = pnew;
}
return HI_SUCCESS;
}
static hi_s32 sample_dequeue(struct squeue *pqueue, sample_message_s *element)
{
struct snode *p = HI_NULL;
if (pqueue == HI_NULL || element == HI_NULL) {
return HI_FAILURE;
}
if (pqueue->front == HI_NULL) {
return HI_FAILURE;
}
*element = pqueue->front->message;
p = pqueue->front;
pqueue->front = p->next;
/* if the queue is empty, set rear = NULL */
if (pqueue->front == HI_NULL) {
pqueue->rear = HI_NULL;
}
free(p);
return HI_SUCCESS;
}
static hi_void *sample_sock_thread(hi_void *args)
{
hi_char link_buf[SOCK_BUF_MAX];
ssize_t recvbytes;
sample_message_s message; sample_message_s message;
pthread_mutex_lock(&g_sample_link->mut); struct sockaddr_in clientaddr;
while (sample_dequeue(&g_sample_link->cmd_queue, &message) != HI_SUCCESS) { socklen_t addrlen = sizeof(clientaddr);
pthread_cond_wait(&g_sample_link->cond, &g_sample_link->mut); sample_unused(args);
}
pthread_mutex_unlock(&g_sample_link->mut);
sample_log_print("=====SAMPLE LOOP RECIEVE MSG:%d LEN:%d=====\n",
message.what, message.len);
fflush(stdout);
switch (message.what) { while (1) {
case SAMPLE_CMD_HELP: /* 安全编程规则6.6例外(1) 对固定长度的数组进行初始化,或对固定长度的结构体进行内存初始化 */
sample_usage(); (hi_void)memset_s(link_buf, sizeof(link_buf), 0, sizeof(link_buf));
break; /* 安全编程规则6.6例外(1) 对固定长度的数组进行初始化,或对固定长度的结构体进行内存初始化 */
case SAMPLE_CMD_EXIT: (hi_void)memset_s(&clientaddr, sizeof(struct sockaddr_in), 0, addrlen);
g_terminate = HI_TRUE;
break; recvbytes = recvfrom(g_sample_link->sockfd, link_buf, sizeof(link_buf), 0,
case SAMPLE_CMD_IOCTL: (struct sockaddr *)&clientaddr, &addrlen);
if (hi_channel_send_to_dev(message.obj, message.len) != HI_SUCCESS) { if (recvbytes < 0) {
sample_log_print("sample_iwpriv_cmd send fail\n"); if (errno == EINTR) {
} usleep(SLEEP_TIME);
break; continue;
default: } else {
break; sample_log_print("recvfrom error! fd:%d\n", g_sample_link->sockfd);
return HI_NULL;
}
}
if (sample_sock_cmd_entry(g_sample_link, link_buf, recvbytes, (hi_void *)&message) != HI_SUCCESS) {
sample_log_print("sample_str_cmd_process entry\n");
sample_str_cmd_process(g_sample_link, link_buf, recvbytes, (hi_void *)&message);
}
if (sendto(g_sample_link->sockfd, "OK", strlen("OK"), MSG_DONTWAIT, (const struct sockaddr *)&clientaddr,
addrlen) == -1) {
sample_log_print("sendto error!fd:%d\n", g_sample_link->sockfd);
}
pthread_mutex_lock(&g_sample_link->mut);
if (sample_enqueue(&g_sample_link->cmd_queue, &message) == HI_SUCCESS) {
pthread_cond_signal(&g_sample_link->cond);
}
pthread_mutex_unlock(&g_sample_link->mut);
} }
}
} }
int main(int argc, char *argv[]) { void sample_link_rec_cb(unsigned char *msg_data, int len)
hi_s32 ret; {
sample_unused(argc); hi_s32 ret;
sample_unused(argv); hi_s32 index;
set_lo_ipaddr();
signal(SIGINT, sample_terminate); if ((len == 0) || (msg_data == HI_NULL)) {
signal(SIGTERM, sample_terminate); return;
signal(SIGPWR, sample_power); }
g_sample_link = (sample_link_s *)malloc(sizeof(sample_link_s)); index = msg_data[0];
if (g_sample_link == HI_NULL) { sample_log_print("hisi_link_rec:%d\n", index);
return -1; if (index == HOST_CMD_GET_MAC) {
} ret = sample_wlan_init_mac(&msg_data[1], WIFI_MAC_LEN);
if (ret != HI_SUCCESS) {
sample_log_print("sample_wlan_init_mac is fail\n");
}
} else if (index == HOST_CMD_GET_IP) {
ret = sample_wlan_init_ip(&msg_data[1], len - 1);
if (ret != HI_SUCCESS) {
sample_log_print("sample_wlan_init_ip is fail\n");
}
} else {
sample_log_print("hisi_link_rec is fail\n");
}
}
(void)memset_s(g_sample_link, sizeof(sample_link_s), 0, void main_process(void)
sizeof(sample_link_s)); {
pthread_mutex_init(&g_sample_link->mut, HI_NULL); /* main loop */
pthread_cond_init(&g_sample_link->cond, HI_NULL); while (!g_terminate) {
sample_message_s message;
pthread_mutex_lock(&g_sample_link->mut);
while (sample_dequeue(&g_sample_link->cmd_queue, &message) != HI_SUCCESS) {
pthread_cond_wait(&g_sample_link->cond, &g_sample_link->mut);
}
pthread_mutex_unlock(&g_sample_link->mut);
sample_log_print("=====SAMPLE LOOP RECIEVE MSG:%d LEN:%d=====\n", message.what, message.len);
fflush(stdout);
if (sample_wlan_init_up() != HI_SUCCESS) { switch (message.what) {
sample_log_print("sample_wlan_init_up is fail\n"); case SAMPLE_CMD_HELP:
} sample_usage();
break;
case SAMPLE_CMD_EXIT:
g_terminate = HI_TRUE;
break;
case SAMPLE_CMD_IOCTL:
if (hi_channel_send_to_dev(message.obj, message.len) != HI_SUCCESS) {
sample_log_print("sample_iwpriv_cmd send fail\n");
}
break;
default:
break;
}
}
}
if (hi_channel_init() != HI_SUCCESS) { int main(int argc, char *argv[])
sample_log_print("hi_channel_init is fail\n"); {
} hi_s32 ret;
sample_unused(argc);
sample_unused(argv);
set_lo_ipaddr();
hi_channel_register_rx_cb(sample_link_rec_cb); signal(SIGINT, sample_terminate);
hi_channel_send_to_dev((hi_u8 *)host_cmd[HOST_CMD_GET_MAC], signal(SIGTERM, sample_terminate);
(hi_s32)strlen(host_cmd[HOST_CMD_GET_MAC])); signal(SIGPWR, sample_power);
if (sample_register_cmd((sample_cmd_entry_stru *)&g_sample_cmd, g_sample_link = (sample_link_s *)malloc(sizeof(sample_link_s));
SAMPLE_CMD_NUM) != HI_SUCCESS) { if (g_sample_link == HI_NULL) {
sample_log_print("register wlan cmd is fail\n"); return -1;
goto link_out; }
}
if (sample_sock_create() != HI_SUCCESS) { (void)memset_s(g_sample_link, sizeof(sample_link_s), 0, sizeof(sample_link_s));
sample_log_print("create sock is fail\n"); pthread_mutex_init(&g_sample_link->mut, HI_NULL);
goto link_out; pthread_cond_init(&g_sample_link->cond, HI_NULL);
}
ret = pthread_create(&g_sample_link->sock_thread, HI_NULL, sample_sock_thread, if (sample_wlan_init_up() != HI_SUCCESS) {
HI_NULL); sample_log_print("sample_wlan_init_up is fail\n");
if (ret != HI_SUCCESS) { }
sample_log_print("create sock thread is fail\n");
goto link_out;
}
main_process(); if (hi_channel_init() != HI_SUCCESS) {
sample_log_print("hi_channel_init is fail\n");
}
hi_channel_register_rx_cb(sample_link_rec_cb);
hi_channel_send_to_dev((hi_u8 *)host_cmd[HOST_CMD_GET_MAC], (hi_s32)strlen(host_cmd[HOST_CMD_GET_MAC]));
if (sample_register_cmd((sample_cmd_entry_stru *)&g_sample_cmd, SAMPLE_CMD_NUM) != HI_SUCCESS) {
sample_log_print("register wlan cmd is fail\n");
goto link_out;
}
if (sample_sock_create() != HI_SUCCESS) {
sample_log_print("create sock is fail\n");
goto link_out;
}
ret = pthread_create(&g_sample_link->sock_thread, HI_NULL, sample_sock_thread, HI_NULL);
if (ret != HI_SUCCESS) {
sample_log_print("create sock thread is fail\n");
goto link_out;
}
main_process();
link_out: link_out:
sample_cleanup(); sample_cleanup();
return 0; return 0;
} }
+2542 -2219
View File
File diff suppressed because it is too large Load Diff
+121 -209
View File
@@ -24,27 +24,23 @@
#define cJSON__h #define cJSON__h
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
#if !defined(__WINDOWS__) && \ #if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
(defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__ #define __WINDOWS__
#endif #endif
#ifdef __WINDOWS__ #ifdef __WINDOWS__
/* When compiling for windows, we specify a specific calling convention to avoid /* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
issues where we are being called from a project with a different default calling
convention. For windows you have 3 define options:
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
dllexport symbols CJSON_EXPORT_SYMBOLS - Define this on library build when you CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
want to dllexport symbols (default) CJSON_IMPORT_SYMBOLS - Define this if you CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
want to dllimport symbol
For *nix builds that support visibility attribute, you can define similar For *nix builds that support visibility attribute, you can define similar behavior by
behavior by
setting default visibility to hidden by adding setting default visibility to hidden by adding
-fvisibility=hidden (for gcc) -fvisibility=hidden (for gcc)
@@ -52,35 +48,31 @@ or
-xldscope=hidden (for sun cc) -xldscope=hidden (for sun cc)
to CFLAGS to CFLAGS
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
CJSON_EXPORT_SYMBOLS does
*/ */
#define CJSON_CDECL __cdecl #define CJSON_CDECL __cdecl
#define CJSON_STDCALL __stdcall #define CJSON_STDCALL __stdcall
/* export symbols by default, this is necessary for copy pasting the C and /* export symbols by default, this is necessary for copy pasting the C and header file */
* header file */ #if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && \
!defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_EXPORT_SYMBOLS #define CJSON_EXPORT_SYMBOLS
#endif #endif
#if defined(CJSON_HIDE_SYMBOLS) #if defined(CJSON_HIDE_SYMBOLS)
#define CJSON_PUBLIC(type) type CJSON_STDCALL #define CJSON_PUBLIC(type) type CJSON_STDCALL
#elif defined(CJSON_EXPORT_SYMBOLS) #elif defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL #define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
#elif defined(CJSON_IMPORT_SYMBOLS) #elif defined(CJSON_IMPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL #define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
#endif #endif
#else /* !__WINDOWS__ */ #else /* !__WINDOWS__ */
#define CJSON_CDECL #define CJSON_CDECL
#define CJSON_STDCALL #define CJSON_STDCALL
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && \ #if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
defined(CJSON_API_VISIBILITY) #define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#else #else
#define CJSON_PUBLIC(type) type #define CJSON_PUBLIC(type) type
#endif #endif
@@ -95,140 +87,109 @@ CJSON_EXPORT_SYMBOLS does
/* cJSON Types: */ /* cJSON Types: */
#define cJSON_Invalid (0) #define cJSON_Invalid (0)
#define cJSON_False (1 << 0) #define cJSON_False (1 << 0)
#define cJSON_True (1 << 1) #define cJSON_True (1 << 1)
#define cJSON_NULL (1 << 2) #define cJSON_NULL (1 << 2)
#define cJSON_Number (1 << 3) #define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4) #define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5) #define cJSON_Array (1 << 5)
#define cJSON_Object (1 << 6) #define cJSON_Object (1 << 6)
#define cJSON_Raw (1 << 7) /* raw json */ #define cJSON_Raw (1 << 7) /* raw json */
#define cJSON_IsReference 256 #define cJSON_IsReference 256
#define cJSON_StringIsConst 512 #define cJSON_StringIsConst 512
/* The cJSON structure: */ /* The cJSON structure: */
typedef struct cJSON { typedef struct cJSON
/* next/prev allow you to walk array/object chains. Alternatively, use {
* GetArraySize/GetArrayItem/GetObjectItem */ /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *next; struct cJSON *next;
struct cJSON *prev; struct cJSON *prev;
/* An array or object item will have a child pointer pointing to a chain of /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
* the items in the array/object. */ struct cJSON *child;
struct cJSON *child;
/* The type of the item, as above. */ /* The type of the item, as above. */
int type; int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */ /* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *valuestring; char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint; int valueint;
/* The item's number, if type==cJSON_Number */ /* The item's number, if type==cJSON_Number */
double valuedouble; double valuedouble;
/* The item's name string, if this item is the child of, or is in the list of /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
* subitems of an object. */ char *string;
char *string;
} cJSON; } cJSON;
typedef struct cJSON_Hooks { typedef struct cJSON_Hooks
/* malloc/free are CDECL on Windows regardless of the default calling {
* convention of the compiler, so ensure the hooks allow passing those /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
* functions directly. */ void *(CJSON_CDECL *malloc_fn)(size_t sz);
void *(CJSON_CDECL *malloc_fn)(size_t sz); void (CJSON_CDECL *free_fn)(void *ptr);
void(CJSON_CDECL *free_fn)(void *ptr);
} cJSON_Hooks; } cJSON_Hooks;
typedef int cJSON_bool; typedef int cJSON_bool;
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse /* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
* them. This is to prevent stack overflows. */ * This is to prevent stack overflows. */
#ifndef CJSON_NESTING_LIMIT #ifndef CJSON_NESTING_LIMIT
#define CJSON_NESTING_LIMIT 1000 #define CJSON_NESTING_LIMIT 1000
#endif #endif
/* returns the version of cJSON as a string */ /* returns the version of cJSON as a string */
CJSON_PUBLIC(const char *) cJSON_Version(void); CJSON_PUBLIC(const char*) cJSON_Version(void);
/* Supply malloc, realloc and free functions to cJSON */ /* Supply malloc, realloc and free functions to cJSON */
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks *hooks); CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
/* Memory Management: the caller is always responsible to free the results from /* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
* all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib /* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
* free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is
* cJSON_PrintPreallocated, where the caller has full responsibility of the
* buffer. */
/* Supply a block of JSON, and this returns a cJSON object you can interrogate.
*/
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
cJSON_ParseWithLength(const char *value, size_t buffer_length); /* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
/* ParseWithOpts allows you to require (and check) that the JSON is null /* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
* terminated, and to retrieve the pointer to the final byte parsed. */ CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
/* If you supply a ptr in return_parse_end and parsing fails, then CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
* return_parse_end will contain a pointer to the error so will match
* cJSON_GetErrorPtr(). */
CJSON_PUBLIC(cJSON *)
cJSON_ParseWithOpts(const char *value, const char **return_parse_end,
cJSON_bool require_null_terminated);
CJSON_PUBLIC(cJSON *)
cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length,
const char **return_parse_end,
cJSON_bool require_null_terminated);
/* Render a cJSON entity to text for transfer/storage. */ /* Render a cJSON entity to text for transfer/storage. */
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. */ /* Render a cJSON entity to text for transfer/storage without any formatting. */
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item); CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess /* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
* at the final size. guessing well reduces reallocation. fmt=0 gives CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
* unformatted, =1 gives formatted */ /* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
CJSON_PUBLIC(char *) /* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt); CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
/* Render a cJSON entity to text using a buffer already allocated in memory with
* given length. Returns 1 on success and 0 on failure. */
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will
* use, so to be safe allocate 5 bytes more than you actually need */
CJSON_PUBLIC(cJSON_bool)
cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length,
const cJSON_bool format);
/* Delete a cJSON entity and all subentities. */ /* Delete a cJSON entity and all subentities. */
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item); CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
/* Returns the number of items in an array (or object). */ /* Returns the number of items in an array (or object). */
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array); CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
/* Retrieve item number "index" from array "array". Returns NULL if /* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
* unsuccessful. */
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index); CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
/* Get item "string" from object. Case insensitive. */ /* Get item "string" from object. Case insensitive. */
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
cJSON_GetObjectItem(const cJSON *const object, const char *const string); CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
cJSON_GetObjectItemCaseSensitive(const cJSON *const object, /* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
const char *const string);
CJSON_PUBLIC(cJSON_bool)
cJSON_HasObjectItem(const cJSON *object, const char *string);
/* For analysing failed parses. This returns a pointer to the parse error.
* You'll probably need to look a few chars back to make sense of it. Defined
* when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
/* Check item type and return its value */ /* Check item type and return its value */
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON *const item); CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON *const item); CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
/* These functions check the type of an item */ /* These functions check the type of an item */
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON *const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
/* These calls create a cJSON item of the appropriate type. */ /* These calls create a cJSON item of the appropriate type. */
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void); CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
@@ -251,126 +212,77 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child); CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
/* These utilities create an Array of count items. /* These utilities create an Array of count items.
* The parameter count cannot be greater than the number of elements in the * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
* number array, otherwise array access will be out of bounds.*/
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
cJSON_CreateStringArray(const char *const *strings, int count);
/* Append item to the specified array/object. */ /* Append item to the specified array/object. */
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item); CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(cJSON_bool) CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); /* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
/* Use this when string is definitely const (i.e. a literal, or as good as), and * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
* will definitely survive the cJSON object. WARNING: When this function was * writing to `item->string` */
* used, make sure to always check that (item->type & cJSON_StringIsConst) is CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
* zero before writing to `item->string` */ /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
CJSON_PUBLIC(cJSON_bool) CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
/* Append reference to item to the specified array/object. Use this when you
* want to add an existing cJSON to a new cJSON, but don't want to corrupt your
* existing cJSON. */
CJSON_PUBLIC(cJSON_bool)
cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(cJSON_bool)
cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
/* Remove/Detach items from Arrays/Objects. */ /* Remove/Detach items from Arrays/Objects. */
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
cJSON_DetachItemViaPointer(cJSON *parent, cJSON *const item);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which); CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which); CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
cJSON_DetachItemFromObject(cJSON *object, const char *string); CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string); CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
CJSON_PUBLIC(void)
cJSON_DeleteItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(void)
cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
/* Update array items. */ /* Update array items. */
CJSON_PUBLIC(cJSON_bool) CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
cJSON_InsertItemInArray( CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
cJSON *array, int which, CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
cJSON *newitem); /* Shifts pre-existing items to the right. */ CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
CJSON_PUBLIC(cJSON_bool) CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
cJSON_ReplaceItemViaPointer(cJSON *const parent, cJSON *const item,
cJSON *replacement);
CJSON_PUBLIC(cJSON_bool)
cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
CJSON_PUBLIC(cJSON_bool)
cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem);
CJSON_PUBLIC(cJSON_bool)
cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string,
cJSON *newitem);
/* Duplicate a cJSON item */ /* Duplicate a cJSON item */
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new /* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
* memory that will need to be released. With recurse!=0, it will duplicate any * need to be released. With recurse!=0, it will duplicate any children connected to the item.
* children connected to the item. The item->next and ->prev pointers are always * The item->next and ->prev pointers are always zero on return from Duplicate. */
* zero on return from Duplicate. */ /* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
/* Recursively compare two cJSON items for equality. If either a or b is NULL or * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
* invalid, they will be considered unequal. case_sensitive determines if object CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
* keys are treated case sensitive (1) or case insensitive (0) */
CJSON_PUBLIC(cJSON_bool)
cJSON_Compare(const cJSON *const a, const cJSON *const b,
const cJSON_bool case_sensitive);
/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from /* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
* strings. The input pointer json cannot point to a read-only address area, * The input pointer json cannot point to a read-only address area, such as a string constant,
* such as a string constant, but should point to a readable and writable adress * but should point to a readable and writable adress area. */
* area. */
CJSON_PUBLIC(void) cJSON_Minify(char *json); CJSON_PUBLIC(void) cJSON_Minify(char *json);
/* Helper functions for creating and adding items to an object at the same time. /* Helper functions for creating and adding items to an object at the same time.
* They return the added item or NULL on failure. */ * They return the added item or NULL on failure. */
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
cJSON_AddNullToObject(cJSON *const object, const char *const name); CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
cJSON_AddTrueToObject(cJSON *const object, const char *const name); CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
cJSON_AddFalseToObject(cJSON *const object, const char *const name); CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
CJSON_PUBLIC(cJSON *) CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
cJSON_AddBoolToObject(cJSON *const object, const char *const name, CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
const cJSON_bool boolean); CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON *)
cJSON_AddNumberToObject(cJSON *const object, const char *const name,
const double number);
CJSON_PUBLIC(cJSON *)
cJSON_AddStringToObject(cJSON *const object, const char *const name,
const char *const string);
CJSON_PUBLIC(cJSON *)
cJSON_AddRawToObject(cJSON *const object, const char *const name,
const char *const raw);
CJSON_PUBLIC(cJSON *)
cJSON_AddObjectToObject(cJSON *const object, const char *const name);
CJSON_PUBLIC(cJSON *)
cJSON_AddArrayToObject(cJSON *const object, const char *const name);
/* When assigning an integer value, it needs to be propagated to valuedouble /* When assigning an integer value, it needs to be propagated to valuedouble too. */
* too. */ #define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
#define cJSON_SetIntValue(object, number) \
((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
/* helper for the cJSON_SetNumberValue macro */ /* helper for the cJSON_SetNumberValue macro */
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
#define cJSON_SetNumberValue(object, number) \ #define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) /* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
/* Change the valuestring of a cJSON_String object, only takes effect when type CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
* of object is cJSON_String */
CJSON_PUBLIC(char *)
cJSON_SetValuestring(cJSON *object, const char *valuestring);
/* Macro for iterating over an array or object */ /* Macro for iterating over an array or object */
#define cJSON_ArrayForEach(element, array) \ #define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
for (element = (array != NULL) ? (array)->child : NULL; element != NULL; \
element = element->next)
/* malloc/free objects using the malloc/free functions that have been set with /* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
* cJSON_InitHooks */
CJSON_PUBLIC(void *) cJSON_malloc(size_t size); CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
CJSON_PUBLIC(void) cJSON_free(void *object); CJSON_PUBLIC(void) cJSON_free(void *object);
+159 -155
View File
@@ -1,207 +1,211 @@
/* /*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
* reserved. Description: sample cli file. Author: Hisilicon Create: 2020-09-09 * Description: sample cli file.
* Author: Hisilicon
* Create: 2020-09-09
*/ */
/***************************************************************************** /*****************************************************************************
1 头文件包含 1 头文件包含
*****************************************************************************/ *****************************************************************************/
#include <unistd.h>
#include <pthread.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/sockios.h> #include <linux/sockios.h>
#include <linux/wireless.h> #include <linux/wireless.h>
#include <netinet/in.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include "securec.h"
#include "hi_base.h" #include "hi_base.h"
#include "hichannel_host.h" #include "hichannel_host.h"
#include "securec.h"
/***************************************************************************** /*****************************************************************************
2 宏定义、全局变量 2 宏定义、全局变量
*****************************************************************************/ *****************************************************************************/
#define NETLINK_SOCKET_PORT_ID 1100 #define NETLINK_SOCKET_PORT_ID 1100
#define NETLINK_CHANNEL_MODEID 28 #define NETLINK_CHANNEL_MODEID 28
#undef NLMSG_ALIGNTO #undef NLMSG_ALIGNTO
#define NLMSG_ALIGNTO 1 #define NLMSG_ALIGNTO 1
#define USLEEP_TIMES 10 #define USLEEP_TIMES 10
typedef struct { typedef struct {
hi_s32 skfd; hi_s32 skfd;
pthread_t channel_thread; pthread_t channel_thread;
hi_channel_rx_func rx_func; hi_channel_rx_func rx_func;
} netlink_monitor_s; } netlink_monitor_s;
/***************************************************************************** /*****************************************************************************
3 枚举、结构体定义 3 枚举、结构体定义
*****************************************************************************/ *****************************************************************************/
static hi_bool g_channel_terminate = HI_FALSE; static hi_bool g_channel_terminate = HI_FALSE;
static netlink_monitor_s *g_channel_monitor = HI_NULL; static netlink_monitor_s *g_channel_monitor = HI_NULL;
/***************************************************************************** /*****************************************************************************
4 函数实现 4 函数实现
*****************************************************************************/ *****************************************************************************/
static hi_void *hi_channel_host_thread(hi_void *args) { static hi_void *hi_channel_host_thread(hi_void *args)
hi_s32 rev_len; {
hi_s32 payload_len; hi_s32 rev_len;
hi_char msg[SYSTEM_CMD_SIZE]; hi_s32 payload_len;
struct nlmsghdr *nlh = HI_NULL; hi_char msg[SYSTEM_CMD_SIZE];
struct sockaddr_nl daddr; struct nlmsghdr *nlh = HI_NULL;
socklen_t len = sizeof(struct sockaddr_nl); struct sockaddr_nl daddr;
sample_unused(args); socklen_t len = sizeof(struct sockaddr_nl);
sample_unused(args);
while (!g_channel_terminate) { while (!g_channel_terminate) {
(hi_void) memset_s(&msg[0], sizeof(msg), 0, sizeof(msg)); (hi_void)memset_s(&msg[0], sizeof(msg), 0, sizeof(msg));
rev_len = recvfrom(g_channel_monitor->skfd, &msg[0], sizeof(msg), rev_len = recvfrom(g_channel_monitor->skfd, &msg[0], sizeof(msg),
MSG_WAITALL, (struct sockaddr *)&daddr, &len); MSG_WAITALL, (struct sockaddr *)&daddr, &len);
if (rev_len == -1) { if (rev_len == -1) {
if (errno == EINTR) { if (errno == EINTR) {
usleep(USLEEP_TIMES); usleep(USLEEP_TIMES);
continue; continue;
} else { } else {
sample_log_print("recvfrom error! fd:%d\n", g_channel_monitor->skfd); sample_log_print("recvfrom error! fd:%d\n", g_channel_monitor->skfd);
return HI_NULL; return HI_NULL;
} }
}
if (rev_len <= NLMSG_HDRLEN) {
usleep(USLEEP_TIMES);
continue;
}
nlh = (struct nlmsghdr *)msg;
payload_len = rev_len - NLMSG_HDRLEN;
sample_log_print("hi_channel_host_thread:%x,%d,%d,%d\n", nlh->nlmsg_type, payload_len, rev_len, NLMSG_HDRLEN);
if (g_channel_monitor->rx_func != HI_NULL) {
g_channel_monitor->rx_func((hi_u8 *)NLMSG_DATA(nlh), payload_len);
}
} }
if (rev_len <= NLMSG_HDRLEN) { return HI_NULL;
usleep(USLEEP_TIMES);
continue;
}
nlh = (struct nlmsghdr *)msg;
payload_len = rev_len - NLMSG_HDRLEN;
sample_log_print("hi_channel_host_thread:%x,%d,%d,%d\n", nlh->nlmsg_type,
payload_len, rev_len, NLMSG_HDRLEN);
if (g_channel_monitor->rx_func != HI_NULL) {
g_channel_monitor->rx_func((hi_u8 *)NLMSG_DATA(nlh), payload_len);
}
}
return HI_NULL;
} }
hi_s32 hi_channel_register_rx_cb(hi_channel_rx_func rx_func) { hi_s32 hi_channel_register_rx_cb(hi_channel_rx_func rx_func)
if ((g_channel_monitor == HI_NULL) || (rx_func == HI_NULL)) { {
sample_log_print("hi_channel_register_rx_cb is fail\n"); if ((g_channel_monitor == HI_NULL) || (rx_func == HI_NULL)) {
return HI_FAILURE; sample_log_print("hi_channel_register_rx_cb is fail\n");
} return HI_FAILURE;
}
g_channel_monitor->rx_func = rx_func; g_channel_monitor->rx_func = rx_func;
return HI_SUCCESS; return HI_SUCCESS;
} }
hi_s32 hi_channel_send_to_dev(unsigned char *buf, int len) { hi_s32 hi_channel_send_to_dev(unsigned char *buf, int len)
int ret; {
struct nlmsghdr *nlh = HI_NULL; int ret;
struct sockaddr_nl daddr; struct nlmsghdr *nlh = HI_NULL;
struct sockaddr_nl daddr;
if ((buf == HI_NULL) || (len <= 0) || (len > MAX_SEND_DATA_SIZE)) { if ((buf == HI_NULL) || (len <= 0) || (len > MAX_SEND_DATA_SIZE)) {
sample_log_print("sendto sata len:%d\n", len); sample_log_print("sendto sata len:%d\n", len);
return HI_FAILURE; return HI_FAILURE;
} }
(hi_void) memset_s(&daddr, sizeof(daddr), 0, sizeof(daddr)); (hi_void)memset_s(&daddr, sizeof(daddr), 0, sizeof(daddr));
daddr.nl_family = AF_NETLINK; /* netlink id */ daddr.nl_family = AF_NETLINK; /* netlink id */
nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(len)); nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(len));
if (nlh == HI_NULL) { if (nlh == HI_NULL) {
sample_log_print("malloc mem is fail\n"); sample_log_print("malloc mem is fail\n");
return HI_FAILURE; return HI_FAILURE;
} }
(hi_void)memset_s(nlh, sizeof(nlh), 0x00, sizeof(nlh));
nlh->nlmsg_len = NLMSG_SPACE(len);
nlh->nlmsg_pid = NETLINK_SOCKET_PORT_ID;
(hi_void)memcpy_s(NLMSG_DATA(nlh), NLMSG_SPACE(len), buf, len);
ret = sendto(g_channel_monitor->skfd, nlh, nlh->nlmsg_len, 0,
(struct sockaddr *)&daddr, sizeof(struct sockaddr_nl));
if (ret == -1) {
sample_log_print("sendto error:%s\n", strerror(errno));
free(nlh);
return HI_FAILURE;
}
(hi_void) memset_s(nlh, sizeof(nlh), 0x00, sizeof(nlh));
nlh->nlmsg_len = NLMSG_SPACE(len);
nlh->nlmsg_pid = NETLINK_SOCKET_PORT_ID;
(hi_void) memcpy_s(NLMSG_DATA(nlh), NLMSG_SPACE(len), buf, len);
ret = sendto(g_channel_monitor->skfd, nlh, nlh->nlmsg_len, 0,
(struct sockaddr *)&daddr, sizeof(struct sockaddr_nl));
if (ret == -1) {
sample_log_print("sendto error:%s\n", strerror(errno));
free(nlh); free(nlh);
return HI_FAILURE; return 0;
}
free(nlh);
return 0;
} }
hi_s32 hi_channel_init(hi_void) { hi_s32 hi_channel_init(hi_void)
hi_s32 ret; {
struct sockaddr_nl saddr = {0}; hi_s32 ret;
struct sockaddr_nl saddr = {0};
if (g_channel_monitor != HI_NULL) { if (g_channel_monitor != HI_NULL) {
sample_log_print("hi_channel_init is fail\n"); sample_log_print("hi_channel_init is fail\n");
return HI_FAILURE; return HI_FAILURE;
} }
g_channel_monitor = (netlink_monitor_s *)malloc(sizeof(netlink_monitor_s)); g_channel_monitor = (netlink_monitor_s *)malloc(sizeof(netlink_monitor_s));
if (g_channel_monitor == HI_NULL) { if (g_channel_monitor == HI_NULL) {
return HI_FAILURE; return HI_FAILURE;
} }
g_channel_terminate = HI_FALSE; g_channel_terminate = HI_FALSE;
(hi_void) memset_s(g_channel_monitor, sizeof(netlink_monitor_s), 0, (hi_void)memset_s(g_channel_monitor, sizeof(netlink_monitor_s), 0, sizeof(netlink_monitor_s));
sizeof(netlink_monitor_s)); g_channel_monitor->skfd = -1;
g_channel_monitor->skfd = -1; g_channel_monitor->skfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_CHANNEL_MODEID);
g_channel_monitor->skfd = if (g_channel_monitor->skfd == -1) {
socket(AF_NETLINK, SOCK_RAW, NETLINK_CHANNEL_MODEID); sample_log_print("create is fail:%s\n", strerror(errno));
if (g_channel_monitor->skfd == -1) { goto deinit;
sample_log_print("create is fail:%s\n", strerror(errno)); }
goto deinit;
}
(hi_void) memset_s(&saddr, sizeof(saddr), 0x00, sizeof(saddr)); (hi_void)memset_s(&saddr, sizeof(saddr), 0x00, sizeof(saddr));
saddr.nl_family = AF_NETLINK; /* netlink id */ saddr.nl_family = AF_NETLINK; /* netlink id */
saddr.nl_pid = NETLINK_SOCKET_PORT_ID; /* self pid */ saddr.nl_pid = NETLINK_SOCKET_PORT_ID; /* self pid */
ret = bind(g_channel_monitor->skfd, (struct sockaddr *)&saddr, sizeof(saddr)); ret = bind(g_channel_monitor->skfd, (struct sockaddr *)&saddr, sizeof(saddr));
if (ret != 0) { if (ret != 0) {
goto deinit; goto deinit;
} }
ret = pthread_create(&g_channel_monitor->channel_thread, HI_NULL, ret = pthread_create(&g_channel_monitor->channel_thread, HI_NULL, hi_channel_host_thread, HI_NULL);
hi_channel_host_thread, HI_NULL); if (ret != HI_SUCCESS) {
if (ret != HI_SUCCESS) { goto deinit;
goto deinit; }
}
return HI_SUCCESS; return HI_SUCCESS;
deinit: deinit:
if (g_channel_monitor->skfd != -1) { if (g_channel_monitor->skfd != -1) {
close(g_channel_monitor->skfd); close(g_channel_monitor->skfd);
g_channel_monitor->skfd = -1; g_channel_monitor->skfd = -1;
} }
if (g_channel_monitor != HI_NULL) { if (g_channel_monitor != HI_NULL) {
free(g_channel_monitor); free(g_channel_monitor);
g_channel_monitor = HI_NULL; g_channel_monitor = HI_NULL;
} }
return HI_FAILURE;
}
hi_s32 hi_channel_deinit(hi_void) {
if (g_channel_monitor == HI_NULL) {
sample_log_print("hi_channel_deinit is fail\n");
return HI_FAILURE; return HI_FAILURE;
}
g_channel_terminate = HI_TRUE;
if (g_channel_monitor->channel_thread) {
pthread_cancel(g_channel_monitor->channel_thread);
pthread_join(g_channel_monitor->channel_thread, HI_NULL);
}
if (g_channel_monitor->skfd != -1) {
close(g_channel_monitor->skfd);
g_channel_monitor->skfd = -1;
}
if (g_channel_monitor != HI_NULL) {
free(g_channel_monitor);
g_channel_monitor = HI_NULL;
}
return HI_SUCCESS;
} }
hi_s32 hi_channel_deinit(hi_void)
{
if (g_channel_monitor == HI_NULL) {
sample_log_print("hi_channel_deinit is fail\n");
return HI_FAILURE;
}
g_channel_terminate = HI_TRUE;
if (g_channel_monitor->channel_thread) {
pthread_cancel(g_channel_monitor->channel_thread);
pthread_join(g_channel_monitor->channel_thread, HI_NULL);
}
if (g_channel_monitor->skfd != -1) {
close(g_channel_monitor->skfd);
g_channel_monitor->skfd = -1;
}
if (g_channel_monitor != HI_NULL) {
free(g_channel_monitor);
g_channel_monitor = HI_NULL;
}
return HI_SUCCESS;
}
+7 -5
View File
@@ -1,6 +1,8 @@
/* /*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
* reserved. Description: sample link file. Author: Hisilicon Create: 2020-09-09 * Description: sample link file.
* Author: Hisilicon
* Create: 2020-09-09
*/ */
#ifndef HISI_LINK_H #ifndef HISI_LINK_H
@@ -13,9 +15,9 @@ extern "C" {
/***************************************************************************** /*****************************************************************************
1 宏定义 1 宏定义
*****************************************************************************/ *****************************************************************************/
#define SYSTEM_CMD_SIZE 384 /* 小于这个值的数据报文通过高优先级通道传输 */ #define SYSTEM_CMD_SIZE 384 /* 小于这个值的数据报文通过高优先级通道传输 */
#define MAX_SEND_DATA_SIZE 1500 /* 小于这个值的数据报文通过低优先级通道传输 */ #define MAX_SEND_DATA_SIZE 1500 /* 小于这个值的数据报文通过低优先级通道传输 */
#define SYSTEM_NETDEV_NAME "wlan0" #define SYSTEM_NETDEV_NAME "wlan0"
typedef void (*hi_channel_rx_func)(unsigned char *msg_data, int len); typedef void (*hi_channel_rx_func)(unsigned char *msg_data, int len);
/***************************************************************************** /*****************************************************************************
+112 -113
View File
@@ -1,20 +1,21 @@
/* /*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
* reserved. Description: sample common file. Author: Hisilicon Create: * Description: sample common file.
* 2018-08-04 * Author: Hisilicon
* Create: 2018-08-04
*/ */
/***************************************************************************** /*****************************************************************************
1 头文件包含 1 头文件包含
*****************************************************************************/ *****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "securec.h"
#include "hichannel_host_comm.h" #include "hichannel_host_comm.h"
#include "hi_base.h" #include "hi_base.h"
#include "securec.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/***************************************************************************** /*****************************************************************************
2 宏定义、全局变量 2 宏定义、全局变量
@@ -24,119 +25,117 @@ static sample_cmd_common g_cmd_com = {0};
/***************************************************************************** /*****************************************************************************
4 函数实现 4 函数实现
*****************************************************************************/ *****************************************************************************/
hi_s32 sample_get_cmd_one_arg(const hi_char *pc_cmd, hi_char *pc_arg, hi_s32 sample_get_cmd_one_arg(const hi_char *pc_cmd, hi_char *pc_arg, hi_u32 pc_arg_len, hi_u32 *pul_cmd_offset)
hi_u32 pc_arg_len, hi_u32 *pul_cmd_offset) { {
const hi_char *pc_cmd_copy = HI_NULL; const hi_char *pc_cmd_copy = HI_NULL;
hi_u32 pos = 0; hi_u32 pos = 0;
if ((pc_cmd == HI_NULL) || (pc_arg == HI_NULL) || if ((pc_cmd == HI_NULL) || (pc_arg == HI_NULL) || (pul_cmd_offset == HI_NULL)) {
(pul_cmd_offset == HI_NULL)) { sample_log_print("pc_cmd/pc_arg/pul_cmd_offset null ptr error %pK, %pK, %pK!\n", \
sample_log_print( pc_cmd, pc_arg, pul_cmd_offset);
"pc_cmd/pc_arg/pul_cmd_offset null ptr error %pK, %pK, %pK!\n", pc_cmd,
pc_arg, pul_cmd_offset);
return HI_FAILURE;
}
pc_cmd_copy = pc_cmd;
while (*pc_cmd_copy != '\0' &&
!((*(pc_cmd_copy) == ',') && (*(pc_cmd_copy - 1) != '\\'))) {
if ((*(pc_cmd_copy + 1) == ',') && (*(pc_cmd_copy) == '\\')) {
++pc_cmd_copy;
continue;
}
pc_arg[pos] = *pc_cmd_copy;
++pos;
++pc_cmd_copy;
if (pos >= pc_arg_len) {
sample_log_print("ul_pos >= WLAN_CMD_NAME_MAX_LEN, ul_pos %d!\n", pos);
return HI_FAILURE;
}
}
pc_arg[pos] = '\0';
/* 字符串到结尾,返回错误码 */
if (pos == 0) {
sample_log_print("return param pc_arg is null!}\r\n");
return HI_FAILURE;
}
*pul_cmd_offset = (hi_u32)(pc_cmd_copy - pc_cmd);
return HI_SUCCESS;
}
hi_s32 sample_parse_cmd(hi_void *wdata, hi_char *cmd, ssize_t len,
hi_void *msg) {
hi_u8 cmd_id;
hi_u32 off_set = 0;
hi_char wlan_name[SAMPLE_CMD_MAX_LEN] = {0};
if (cmd == HI_NULL) {
return HI_FAILURE;
}
if (sample_get_cmd_one_arg(cmd, wlan_name, SAMPLE_CMD_MAX_LEN, &off_set) !=
HI_SUCCESS) {
return HI_FAILURE;
}
cmd += (off_set + 1);
for (cmd_id = 0; cmd_id < g_cmd_com.count; cmd_id++) {
if (strcmp(g_cmd_com.cmd_tbl[cmd_id].cmd_name, wlan_name) == 0) {
if (g_cmd_com.cmd_tbl[cmd_id].func(wdata, cmd, len, msg) != HI_SUCCESS) {
sample_log_print("cmd exec fail!\n");
return HI_FAILURE; return HI_FAILURE;
}
return HI_SUCCESS;
} }
}
return HI_FAILURE; pc_cmd_copy = pc_cmd;
while (*pc_cmd_copy != '\0' && !((*(pc_cmd_copy) == ',') && (*(pc_cmd_copy - 1) != '\\'))) {
if ((*(pc_cmd_copy + 1) == ',') && (*(pc_cmd_copy) == '\\')) {
++pc_cmd_copy;
continue;
}
pc_arg[pos] = *pc_cmd_copy;
++pos;
++pc_cmd_copy;
if (pos >= pc_arg_len) {
sample_log_print("ul_pos >= WLAN_CMD_NAME_MAX_LEN, ul_pos %d!\n", pos);
return HI_FAILURE;
}
}
pc_arg[pos] = '\0';
/* 字符串到结尾,返回错误码 */
if (pos == 0) {
sample_log_print("return param pc_arg is null!}\r\n");
return HI_FAILURE;
}
*pul_cmd_offset = (hi_u32)(pc_cmd_copy - pc_cmd);
return HI_SUCCESS;
} }
hi_s32 sample_sock_cmd_entry(hi_void *wdata, const char *cmd, ssize_t len, hi_s32 sample_parse_cmd(hi_void *wdata, hi_char *cmd, ssize_t len, hi_void *msg)
hi_void *msg) { {
hi_char *pcmd = HI_NULL; hi_u8 cmd_id;
hi_char *pcmd_tmp = HI_NULL; hi_u32 off_set = 0;
if (len > SAMPLE_CMD_MAX_LEN) { hi_char wlan_name[SAMPLE_CMD_MAX_LEN] = {0};
sample_log_print("command len > %d!\n", SAMPLE_CMD_MAX_LEN);
return HI_FAILURE;
}
pcmd = malloc(SAMPLE_CMD_MAX_LEN);
if (pcmd == HI_NULL) {
return HI_FAILURE;
}
if (cmd != HI_NULL) {
if (memcpy_s(pcmd, len, cmd, len) != EOK) {
sample_log_print("command memcpy_s failed!\n");
free(pcmd);
return HI_FAILURE;
}
}
pcmd[len] = '\0'; if (cmd == HI_NULL) {
pcmd_tmp = pcmd; return HI_FAILURE;
if (sample_parse_cmd(wdata, pcmd_tmp, len, msg) != HI_SUCCESS) { }
if (sample_get_cmd_one_arg(cmd, wlan_name, SAMPLE_CMD_MAX_LEN, &off_set) != HI_SUCCESS) {
return HI_FAILURE;
}
cmd += (off_set + 1);
for (cmd_id = 0; cmd_id < g_cmd_com.count; cmd_id++) {
if (strcmp(g_cmd_com.cmd_tbl[cmd_id].cmd_name, wlan_name) == 0) {
if (g_cmd_com.cmd_tbl[cmd_id].func(wdata, cmd, len, msg) != HI_SUCCESS) {
sample_log_print("cmd exec fail!\n");
return HI_FAILURE;
}
return HI_SUCCESS;
}
}
return HI_FAILURE;
}
hi_s32 sample_sock_cmd_entry(hi_void *wdata, const char *cmd, ssize_t len, hi_void *msg)
{
hi_char *pcmd = HI_NULL;
hi_char *pcmd_tmp = HI_NULL;
if (len > SAMPLE_CMD_MAX_LEN) {
sample_log_print("command len > %d!\n", SAMPLE_CMD_MAX_LEN);
return HI_FAILURE;
}
pcmd = malloc(SAMPLE_CMD_MAX_LEN);
if (pcmd == HI_NULL) {
return HI_FAILURE;
}
if (cmd != HI_NULL) {
if (memcpy_s(pcmd, len, cmd, len) != EOK) {
sample_log_print("command memcpy_s failed!\n");
free(pcmd);
return HI_FAILURE;
}
}
pcmd[len] = '\0';
pcmd_tmp = pcmd;
if (sample_parse_cmd(wdata, pcmd_tmp, len, msg) != HI_SUCCESS) {
free(pcmd);
return HI_FAILURE;
}
free(pcmd); free(pcmd);
return HI_FAILURE; return HI_SUCCESS;
}
free(pcmd);
return HI_SUCCESS;
} }
hi_s32 sample_register_cmd(sample_cmd_entry_stru *cmd_tbl, hi_u32 num) { hi_s32 sample_register_cmd(sample_cmd_entry_stru *cmd_tbl, hi_u32 num)
hi_u32 i; {
sample_cmd_common *tmp_list = HI_NULL; hi_u32 i;
tmp_list = (sample_cmd_common *)&g_cmd_com; sample_cmd_common *tmp_list = HI_NULL;
for (i = 0; i < num; i++) { tmp_list = (sample_cmd_common *)&g_cmd_com;
if (cmd_tbl[i].cmd_name == HI_NULL || cmd_tbl[i].func == HI_NULL) { for (i = 0; i < num; i++) {
sample_log_print("SAMPLE_COMMON: register cmd table failed!\n"); if (cmd_tbl[i].cmd_name == HI_NULL || cmd_tbl[i].func == HI_NULL) {
return HI_FAILURE; sample_log_print("SAMPLE_COMMON: register cmd table failed!\n");
return HI_FAILURE;
}
} }
} tmp_list->cmd_tbl = cmd_tbl;
tmp_list->cmd_tbl = cmd_tbl; tmp_list->count = num;
tmp_list->count = num; return HI_SUCCESS;
return HI_SUCCESS;
} }
+34 -36
View File
@@ -1,7 +1,8 @@
/* /*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
* reserved. Description: sample common file. Author: Hisilicon Create: * Description: sample common file.
* 2018-08-04 * Author: Hisilicon
* Create: 2018-08-04
*/ */
#ifndef __SAMPLE_COMMON_H__ #ifndef __SAMPLE_COMMON_H__
@@ -19,53 +20,50 @@
/***************************************************************************** /*****************************************************************************
3 枚举、结构体定义 3 枚举、结构体定义
*****************************************************************************/ *****************************************************************************/
typedef hi_s32 (*sample_cmd_func)(hi_void *wdata, hi_char *param, hi_u32 len, typedef hi_s32(*sample_cmd_func)(hi_void *wdata, hi_char *param, hi_u32 len, hi_void *pmsg);
hi_void *pmsg);
typedef struct { typedef struct {
hi_char *cmd_name; /* 命令字符串 */ hi_char *cmd_name; /* 命令字符串 */
sample_cmd_func func; /* 命令对应处理函数 */ sample_cmd_func func; /* 命令对应处理函数 */
} sample_cmd_entry_stru; } sample_cmd_entry_stru;
typedef struct { typedef struct {
sample_cmd_entry_stru *cmd_tbl; /* 命令表 */ sample_cmd_entry_stru *cmd_tbl; /* 命令表 */
hi_u32 count; /* 命令总数 */ hi_u32 count; /* 命令总数 */
} sample_cmd_common; } sample_cmd_common;
#define CMD_SENDMSG_NETCFG 0x01 #define CMD_SENDMSG_NETCFG 0x01
#define CMD_SENDMSG_GETMAC 0x02 #define CMD_SENDMSG_GETMAC 0x02
#define CMD_SENDMSG_GETIP 0x03 #define CMD_SENDMSG_GETIP 0x03
#define CMD_SENDMSG_SETFILTER 0x04 #define CMD_SENDMSG_SETFILTER 0x04
#define CMD_SENDMSG_KEEPLIVE 0x05 #define CMD_SENDMSG_KEEPLIVE 0x05
#define CMD_SENDMSG_STANDBY 0x06 #define CMD_SENDMSG_STANDBY 0x06
#define CMD_SENDMSG_DEEPSLEEP 0x07 #define CMD_SENDMSG_DEEPSLEEP 0x07
#define CMD_SENDMSG_STARTAP 0x08 #define CMD_SENDMSG_STARTAP 0x08
#define CMD_SENDMSG_STARTOTA 0x09 #define CMD_SENDMSG_STARTOTA 0x09
#define CMD_SENDMSG_OTADATA 0x0a #define CMD_SENDMSG_OTADATA 0x0a
#define CMD_SENDMSG_OTAWRITERET 0x0b #define CMD_SENDMSG_OTAWRITERET 0x0b
#define CMD_SENDMSG_OTARET 0x0c #define CMD_SENDMSG_OTARET 0x0c
#define CMD_SENDMSG_GET_RSSI 0x0d #define CMD_SENDMSG_GET_RSSI 0x0d
#define CMD_SENDMSG_GET_VERSION 0x0e #define CMD_SENDMSG_GET_VERSION 0x0e
#define CMD_SENDMSG_GET_WAKECODE 0x0f #define CMD_SENDMSG_GET_WAKECODE 0x0f
#define CMD_SENDMSG_FACTORY_RESET 0x10 #define CMD_SENDMSG_FACTORY_RESET 0x10
#define CMD_SENDMSG_PIR_SET 0x11 #define CMD_SENDMSG_PIR_SET 0x11
#define CMD_SENDMSG_PIR_GET 0x12 #define CMD_SENDMSG_PIR_GET 0x12
#define CMD_SENDMSG_TUYA_SET 0x13 #define CMD_SENDMSG_TUYA_SET 0x13
#define CMD_SENDMSG_GETALL 0x14 #define CMD_SENDMSG_GETALL 0x14
#define CMD_SENDMSG_PIR_CLR 0x17 #define CMD_SENDMSG_PIR_CLR 0x17
/***************************************************************************** /*****************************************************************************
4 函数声明 4 函数声明
*****************************************************************************/ *****************************************************************************/
hi_s32 sample_get_cmd_one_arg(const hi_char *pc_cmd, hi_char *pc_arg, hi_s32 sample_get_cmd_one_arg(const hi_char *pc_cmd, hi_char *pc_arg, hi_u32 pc_arg_len, hi_u32 *pul_cmd_offset);
hi_u32 pc_arg_len, hi_u32 *pul_cmd_offset);
hi_s32 sample_parse_cmd(hi_void *wdata, hi_char *cmd, ssize_t len, hi_s32 sample_parse_cmd(hi_void *wdata, hi_char *cmd, ssize_t len, hi_void *msg);
hi_void *msg);
hi_s32 sample_sock_cmd_entry(hi_void *wdata, const char *cmd, ssize_t len, hi_s32 sample_sock_cmd_entry(hi_void *wdata, const char *cmd, ssize_t len, hi_void *msg);
hi_void *msg);
hi_s32 sample_register_cmd(sample_cmd_entry_stru *cmd_tbl, hi_u32 num); hi_s32 sample_register_cmd(sample_cmd_entry_stru *cmd_tbl, hi_u32 num);
#endif #endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,91 +1,97 @@
/* /*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
* reserved. Description: sample cli file. Author: Hisilicon Create: 2020-09-09 * Description: sample cli file.
* Author: Hisilicon
* Create: 2020-09-09
*/ */
/***************************************************************************** /*****************************************************************************
1 Í·Îļþ°üº¬ 1 Í·Îļþ°üº¬
*****************************************************************************/ *****************************************************************************/
#include <linux/if.h> #include <unistd.h>
#include <linux/sockios.h>
#include <linux/wireless.h>
#include <netinet/in.h>
#include <pthread.h>
#include <signal.h> #include <signal.h>
#include <sys/socket.h> #include <pthread.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <sys/socket.h>
#include <netinet/in.h>
#include <linux/sockios.h>
#include <linux/if.h>
#include <linux/wireless.h>
#include "securec.h"
#include "hi_base.h" #include "hi_base.h"
#include "hichannel_host.h" #include "hichannel_host.h"
#include "hichannel_host_comm.h" #include "hichannel_host_comm.h"
#include "securec.h"
#include "cJSON.h" #include "cJSON.h"
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h>
#include <netinet/in.h>
#define MAXLINE 4096 #define MAXLINE 4096
#define TCP_PORT 20000 #define TCP_PORT 20000
void *vlink_tcp_socket_thread(void *arg) { void* vlink_tcp_socket_thread(void* arg)
int listenfd, connfd; {
struct sockaddr_in servaddr; int listenfd, connfd;
char buff[4096]; struct sockaddr_in servaddr;
int n; char buff[4096];
int n;
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){
printf("create socket error: %s(errno: %d)\n", strerror(errno), errno); printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
return 0; return 0;
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("192.168.43.1"); // htonl(INADDR_ANY);
servaddr.sin_port = htons(TCP_PORT);
if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
printf("bind socket error: %s(errno: %d)\n", strerror(errno), errno);
return 0;
}
if (listen(listenfd, 10) == -1) {
printf("listen socket error: %s(errno: %d)\n", strerror(errno), errno);
return 0;
}
printf("======waiting for client's request===ip[%s]=port[%d]==\n",
"192.168.43.1", TCP_PORT);
while (1) {
if ((connfd = accept(listenfd, (struct sockaddr *)NULL, NULL)) == -1) {
printf("accept socket error: %s(errno: %d)", strerror(errno), errno);
continue;
}
n = recv(connfd, buff, MAXLINE, 0);
buff[n] = '\0';
printf("recv msg from client: %s\n", buff);
if (send(connfd, buff, strlen(buff), 0) < 0) {
printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
return 0;
} }
close(connfd); memset(&servaddr, 0, sizeof(servaddr));
} servaddr.sin_family = AF_INET;
close(listenfd); servaddr.sin_addr.s_addr = inet_addr("192.168.43.1");//htonl(INADDR_ANY);
return 0; servaddr.sin_port = htons(TCP_PORT);
if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){
printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);
return 0;
}
if( listen(listenfd, 10) == -1){
printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);
return 0;
}
printf("======waiting for client's request===ip[%s]=port[%d]==\n", "192.168.43.1", TCP_PORT);
while(1){
if( (connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1){
printf("accept socket error: %s(errno: %d)",strerror(errno),errno);
continue;
}
n = recv(connfd, buff, MAXLINE, 0);
buff[n] = '\0';
printf("recv msg from client: %s\n", buff);
if( send(connfd, buff, strlen(buff), 0) < 0){
printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
return 0;
}
close(connfd);
}
close(listenfd);
return 0;
} }
int vlink_tcp_socket_start_info(void) { int vlink_tcp_socket_start_info(void)
pthread_t tcpserver; {
int rc1 = 0; pthread_t tcpserver;
rc1 = pthread_create(&tcpserver, NULL, vlink_tcp_socket_thread, NULL); int rc1 = 0;
if (rc1 != 0) rc1 = pthread_create(&tcpserver, NULL, vlink_tcp_socket_thread, NULL);
printf("%s: %d\n", __func__, strerror(rc1)); if(rc1 != 0)
printf("%s: %d\n",__func__, strerror(rc1));
pthread_detach(tcpserver); pthread_detach(tcpserver);
} }
+163 -134
View File
@@ -1,178 +1,207 @@
/* /*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
* reserved. Description: sample cli file. Author: Hisilicon Create: 2020-09-09 * Description: sample cli file.
* Author: Hisilicon
* Create: 2020-09-09
*/ */
/***************************************************************************** /*****************************************************************************
1 Í·Îļþ°üº¬ 1 Í·Îļþ°üº¬
*****************************************************************************/ *****************************************************************************/
#include <linux/if.h> #include <unistd.h>
#include <linux/sockios.h>
#include <linux/wireless.h>
#include <netinet/in.h>
#include <pthread.h>
#include <signal.h> #include <signal.h>
#include <sys/socket.h> #include <pthread.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <sys/socket.h>
#include <netinet/in.h>
#include <linux/sockios.h>
#include <linux/if.h>
#include <linux/wireless.h>
#include "securec.h"
#include "hi_base.h" #include "hi_base.h"
#include "hichannel_host.h" #include "hichannel_host.h"
#include "hichannel_host_comm.h" #include "hichannel_host_comm.h"
#include "securec.h"
#include "cJSON.h" #include "cJSON.h"
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <sys/un.h> #define SOCKET_DOMAIN "/tmp/wifiota.domain"
#define SOCKET_DOMAIN "/tmp/wifiota.domain"
#define VLINK_WIFI_OTA_PATH "/mnt/T31ZL/030/Hi3861L_demo_ota.bin" #define VLINK_WIFI_OTA_PATH "/mnt/T31ZL/030/Hi3861L_demo_ota.bin"
#define MAXLINE 4096 #define MAXLINE 4096
#define TCP_PORT 20000 #define TCP_PORT 20000
static int create_wifi_ota_server_socket(void) {
int listen_fd;
int ret;
struct sockaddr_un srv_addr;
listen_fd = socket(PF_LOCAL, SOCK_DGRAM, 0);
if (listen_fd < 0) {
printf("cannot create communication socket\n");
return -1;
}
// set server addr_param
srv_addr.sun_family = AF_LOCAL;
strncpy(srv_addr.sun_path, SOCKET_DOMAIN, sizeof(srv_addr.sun_path) - 1);
unlink(SOCKET_DOMAIN);
// bind sockfd & addr
ret = bind(listen_fd, (struct sockaddr *)&srv_addr, sizeof(srv_addr));
if (ret == -1) {
printf("cannot bind server socket\n");
close(listen_fd);
unlink(SOCKET_DOMAIN);
return -1;
}
return listen_fd; static int create_wifi_ota_server_socket(void)
} {
int listen_fd;
int ret;
void vlink_wifi_ota_process_write_ret(char *result) { struct sockaddr_un srv_addr;
listen_fd = socket(PF_LOCAL, SOCK_DGRAM, 0);
if(listen_fd < 0)
{
printf("cannot create communication socket\n");
return -1;
}
//set server addr_param
srv_addr.sun_family = AF_LOCAL;
strncpy(srv_addr.sun_path, SOCKET_DOMAIN, sizeof(srv_addr.sun_path) - 1);
unlink(SOCKET_DOMAIN);
//bind sockfd & addr
ret = bind(listen_fd, (struct sockaddr*)&srv_addr, sizeof(srv_addr));
if(ret == -1)
{
printf("cannot bind server socket\n");
close(listen_fd);
unlink(SOCKET_DOMAIN);
return -1;
}
return listen_fd;
}
void vlink_wifi_ota_process_write_ret(char* result)
{
#define SENDSTRING "OK" #define SENDSTRING "OK"
int ret = atoi(result); int ret = atoi(result);
printf("vlink_wifi_ota_process_write_ret-[%d]-\n", ret); printf("vlink_wifi_ota_process_write_ret-[%d]-\n", ret);
if (ret == 0) { if (ret == 0)
int fd = -1; {
struct sockaddr_un srv_addr; int fd = -1;
struct sockaddr_un srv_addr;
// create socket //create socket
fd = socket(PF_LOCAL, SOCK_DGRAM, 0); fd = socket(PF_LOCAL, SOCK_DGRAM, 0);
if (fd < 0) { if (fd < 0)
printf("cannot bind server socket\n"); {
return; printf("cannot bind server socket\n");
return;
}
srv_addr.sun_family = AF_LOCAL;
strcpy(srv_addr.sun_path, SOCKET_DOMAIN);
sendto(fd, SENDSTRING, strlen(SENDSTRING), 0, (struct sockaddr *)&srv_addr, sizeof(struct sockaddr_un));
}
}
int getIndexOfSigns(char ch)
{
if(ch >= '0' && ch <= '9')
{
return ch - '0';
} }
if(ch >= 'A' && ch <='F')
srv_addr.sun_family = AF_LOCAL; {
strcpy(srv_addr.sun_path, SOCKET_DOMAIN); return ch - 'A' + 10;
sendto(fd, SENDSTRING, strlen(SENDSTRING), 0, (struct sockaddr *)&srv_addr, }
sizeof(struct sockaddr_un)); if(ch >= 'a' && ch <= 'f')
} {
return ch - 'a' + 10;
}
return -1;
} }
int getIndexOfSigns(char ch) { int hexToDec(char *source)
if (ch >= '0' && ch <= '9') { {
return ch - '0'; int sum = 0;
} int t = 1;
if (ch >= 'A' && ch <= 'F') { int i, len;
return ch - 'A' + 10;
} len = strlen(source);
if (ch >= 'a' && ch <= 'f') { for(i=len-1; i>=0; i--)
return ch - 'a' + 10; {
} sum += t * getIndexOfSigns(*(source + i));
return -1; t *= 16;
}
return sum;
} }
int hexToDec(char *source) { void* vlink_wifi_ota_thread(void* arg)
int sum = 0; {
int t = 1;
int i, len;
len = strlen(source);
for (i = len - 1; i >= 0; i--) {
sum += t * getIndexOfSigns(*(source + i));
t *= 16;
}
return sum;
}
void *vlink_wifi_ota_thread(void *arg) {
#define BUFFSIZE 1450 #define BUFFSIZE 1450
int listen_fd = create_wifi_ota_server_socket(); int listen_fd = create_wifi_ota_server_socket();
char recv_buf[5]; char recv_buf[5];
hi_uchar read_buf[BUFFSIZE]; hi_uchar read_buf[BUFFSIZE];
hi_uchar send_buf[SAMPLE_CMD_MAX_LEN]; hi_uchar send_buf[SAMPLE_CMD_MAX_LEN];
int send_len = 0; int send_len = 0;
int file_end = 0; int file_end = 0;
FILE *fpRead = NULL; FILE *fpRead = NULL;
printf("vlink_wifi_ota_thread------start-----------\n");
if(listen_fd < 0)
{
printf("vlink_wifi_ota_thread--cannot creatServerSocket\n");
unlink(SOCKET_DOMAIN);
return NULL;
}
fpRead = fopen(VLINK_WIFI_OTA_PATH, "rb");
fseek(fpRead, 0, SEEK_SET);
while (1)
{
int num = 0;
memset(recv_buf, 0, 5);
num = recvfrom (listen_fd, recv_buf, 5, 0, NULL, NULL);
if (num > 0)
{
recv_buf[num] = '\0';
if (strcmp(recv_buf, "OK") == 0)
{
memset(send_buf, 0, SAMPLE_CMD_MAX_LEN);
send_buf[0] = CMD_SENDMSG_OTADATA;
printf("vlink_wifi_ota_thread------start-----------\n");
if (listen_fd < 0) {
printf("vlink_wifi_ota_thread--cannot creatServerSocket\n");
unlink(SOCKET_DOMAIN);
return NULL;
}
fpRead = fopen(VLINK_WIFI_OTA_PATH, "rb");
fseek(fpRead, 0, SEEK_SET);
while (1) { if (file_end == 0)
int num = 0; {
memset(recv_buf, 0, 5); bzero (read_buf, BUFFSIZE);
num = recvfrom(listen_fd, recv_buf, 5, 0, NULL, NULL); int count = fread(read_buf, sizeof (char), BUFFSIZE, fpRead);
if (num > 0) { file_end = feof(fpRead);
recv_buf[num] = '\0'; printf ("%d, %d\n", count, file_end);
if (strcmp(recv_buf, "OK") == 0) { send_len = count + 3;
memset(send_buf, 0, SAMPLE_CMD_MAX_LEN); memcpy_s(&send_buf[3], count, read_buf, count);
send_buf[0] = CMD_SENDMSG_OTADATA; } else {
send_len = 3;
}
if (file_end == 0) { send_buf[1] = (send_len >> 8) & 0xFF;
bzero(read_buf, BUFFSIZE); send_buf[2] = send_len & 0xFF;
int count = fread(read_buf, sizeof(char), BUFFSIZE, fpRead);
file_end = feof(fpRead);
printf("%d, %d\n", count, file_end);
send_len = count + 3;
memcpy_s(&send_buf[3], count, read_buf, count);
} else {
send_len = 3;
}
send_buf[1] = (send_len >> 8) & 0xFF; if (hi_channel_send_to_dev(send_buf, send_len) != HI_SUCCESS) {
send_buf[2] = send_len & 0xFF; printf("vlink_hi_channel_cmd_startota--send fail\n");
} else {
if (hi_channel_send_to_dev(send_buf, send_len) != HI_SUCCESS) { printf("vlink_hi_channel_cmd_startota--send ok\n");
printf("vlink_hi_channel_cmd_startota--send fail\n"); }
} else { }
printf("vlink_hi_channel_cmd_startota--send ok\n"); }
} }
} return NULL;
}
}
return NULL;
} }
int vlink_wifi_ota_start_info(void) { int vlink_wifi_ota_start_info(void)
pthread_t wifiota; {
int rc1 = 0; pthread_t wifiota;
rc1 = pthread_create(&wifiota, NULL, vlink_wifi_ota_thread, NULL); int rc1 = 0;
if (rc1 != 0) rc1 = pthread_create(&wifiota, NULL, vlink_wifi_ota_thread, NULL);
printf("%s: %d\n", __func__, strerror(rc1)); if(rc1 != 0)
printf("%s: %d\n",__func__, strerror(rc1));
pthread_detach(wifiota); pthread_detach(wifiota);
} }
@@ -10,13 +10,12 @@
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The fscanf_s function is equivalent to fscanf except that the c, s, * The fscanf_s function is equivalent to fscanf except that the c, s,
* and [ conversion specifiers apply to a pair of arguments (unless * and [ conversion specifiers apply to a pair of arguments (unless assignment suppression is indicated by a*)
* assignment suppression is indicated by a*) The fscanf function reads data * The fscanf function reads data from the current position of stream into
* from the current position of stream into the locations given by argument (if * the locations given by argument (if any). Each argument must be a pointer
* any). Each argument must be a pointer to a variable of a type that * to a variable of a type that corresponds to a type specifier in format.
* corresponds to a type specifier in format. format controls the interpretation * format controls the interpretation of the input fields and has the same
* of the input fields and has the same form and function as the format argument * form and function as the format argument for scanf.
* for scanf.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* stream Pointer to FILE structure. * stream Pointer to FILE structure.
@@ -27,20 +26,22 @@
* ... The convered value stored in user assigned address * ... The convered value stored in user assigned address
* *
* <RETURN VALUE> * <RETURN VALUE>
* Each of these functions returns the number of fields successfully * Each of these functions returns the number of fields successfully converted
* converted and assigned; the return value does not include fields that were * and assigned; the return value does not include fields that were read but
* read but not assigned. A return value of 0 indicates that no fields were * not assigned. A return value of 0 indicates that no fields were assigned.
* assigned. return -1 if an error occurs. * return -1 if an error occurs.
*/ */
int fscanf_s(FILE *stream, const char *format, ...) { int fscanf_s(FILE *stream, const char *format, ...)
int ret; /* If initialization causes e838 */ {
va_list argList; int ret; /* If initialization causes e838 */
va_list argList;
va_start(argList, format); va_start(argList, format);
ret = vfscanf_s(stream, format, argList); ret = vfscanf_s(stream, format, argList);
va_end(argList); va_end(argList);
(void)argList; /* To clear e438 last value assigned not used , the compiler (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
will optimize this code */
return ret; return ret;
} }
@@ -9,12 +9,12 @@
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The fwscanf_s function is the wide-character equivalent of the * The fwscanf_s function is the wide-character equivalent of the fscanf_s function
* fscanf_s function The fwscanf_s function reads data from the current position * The fwscanf_s function reads data from the current position of stream into
* of stream into the locations given by argument (if any). Each argument must * the locations given by argument (if any). Each argument must be a pointer
* be a pointer to a variable of a type that corresponds to a type specifier in * to a variable of a type that corresponds to a type specifier in format.
* format. format controls the interpretation of the input fields and has the * format controls the interpretation of the input fields and has the same
* same form and function as the format argument for scanf. * form and function as the format argument for scanf.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* stream Pointer to FILE structure. * stream Pointer to FILE structure.
@@ -22,24 +22,25 @@
* ... Optional arguments. * ... Optional arguments.
* *
* <OUTPUT PARAMETERS> * <OUTPUT PARAMETERS>
* ... The converted value stored in user assigned * ... The converted value stored in user assigned address
* address
* *
* <RETURN VALUE> * <RETURN VALUE>
* Each of these functions returns the number of fields successfully * Each of these functions returns the number of fields successfully converted
* converted and assigned; the return value does not include fields that were * and assigned; the return value does not include fields that were read but
* read but not assigned. A return value of 0 indicates that no fields were * not assigned. A return value of 0 indicates that no fields were assigned.
* assigned. return -1 if an error occurs. * return -1 if an error occurs.
*/ */
int fwscanf_s(FILE *stream, const wchar_t *format, ...) { int fwscanf_s(FILE *stream, const wchar_t *format, ...)
int ret; /* If initialization causes e838 */ {
va_list argList; int ret; /* If initialization causes e838 */
va_list argList;
va_start(argList, format); va_start(argList, format);
ret = vfwscanf_s(stream, format, argList); ret = vfwscanf_s(stream, format, argList);
va_end(argList); va_end(argList);
(void)argList; /* To clear e438 last value assigned not used , the compiler (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
will optimize this code */
return ret; return ret;
} }
@@ -7,24 +7,24 @@
#include "securecutil.h" #include "securecutil.h"
SECUREC_INLINE void SecTrimCRLF(char *buffer, size_t len) { SECUREC_INLINE void SecTrimCRLF(char *buffer, size_t len)
int i; {
/* No need to determine whether integer overflow exists */ int i;
for (i = (int)(len - 1); i >= 0 && (buffer[i] == '\r' || buffer[i] == '\n'); /* No need to determine whether integer overflow exists */
--i) { for (i = (int)(len - 1); i >= 0 && (buffer[i] == '\r' || buffer[i] == '\n'); --i) {
buffer[i] = '\0'; buffer[i] = '\0';
} }
} }
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The gets_s function reads at most one less than the number of characters * The gets_s function reads at most one less than the number of characters
* specified by destMax from the std input stream, into the array pointed to * specified by destMax from the std input stream, into the array pointed to by buffer
* by buffer The line consists of all characters up to and including the first * The line consists of all characters up to and including
* newline character ('\n'). gets_s then replaces the newline character with a * the first newline character ('\n'). gets_s then replaces the newline
* null character ('\0') before returning the line. If the first character read * character with a null character ('\0') before returning the line.
* is the end-of-file character, a null character is stored at the beginning of * If the first character read is the end-of-file character, a null character
* buffer and NULL is returned. * is stored at the beginning of buffer and NULL is returned.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* buffer Storage location for input string. * buffer Storage location for input string.
@@ -37,29 +37,29 @@ SECUREC_INLINE void SecTrimCRLF(char *buffer, size_t len) {
* buffer Successful operation * buffer Successful operation
* NULL Improper parameter or read fail * NULL Improper parameter or read fail
*/ */
char *gets_s(char *buffer, size_t numberOfElements) { char *gets_s(char *buffer, size_t numberOfElements)
size_t len; {
size_t len;
#ifdef SECUREC_COMPATIBLE_WIN_FORMAT #ifdef SECUREC_COMPATIBLE_WIN_FORMAT
size_t bufferSize = ((numberOfElements == (size_t)-1) ? SECUREC_STRING_MAX_LEN size_t bufferSize = ((numberOfElements == (size_t)-1) ? SECUREC_STRING_MAX_LEN : numberOfElements);
: numberOfElements);
#else #else
size_t bufferSize = numberOfElements; size_t bufferSize = numberOfElements;
#endif #endif
if (buffer == NULL || bufferSize == 0 || if (buffer == NULL || bufferSize == 0 || bufferSize > SECUREC_STRING_MAX_LEN) {
bufferSize > SECUREC_STRING_MAX_LEN) { SECUREC_ERROR_INVALID_PARAMTER("gets_s");
SECUREC_ERROR_INVALID_PARAMTER("gets_s"); return NULL;
return NULL; }
}
if (fgets(buffer, (int)bufferSize, SECUREC_STREAM_STDIN) == NULL) { if (fgets(buffer, (int)bufferSize, SECUREC_STREAM_STDIN) == NULL) {
return NULL; return NULL;
} }
len = strlen(buffer); len = strlen(buffer);
if (len > 0 && len < bufferSize) { if (len > 0 && len < bufferSize) {
SecTrimCRLF(buffer, len); SecTrimCRLF(buffer, len);
} }
return buffer; return buffer;
} }
File diff suppressed because it is too large Load Diff
@@ -6,9 +6,8 @@
*/ */
/* /*
* [Standardize-exceptions] Use unsafe function: Portability * [Standardize-exceptions] Use unsafe function: Portability
* [reason] Use unsafe function to implement security function to maintain * [reason] Use unsafe function to implement security function to maintain platform compatibility.
* platform compatibility. And sufficient input validation is performed before * And sufficient input validation is performed before calling
* calling
*/ */
#include "securecutil.h" #include "securecutil.h"
@@ -17,34 +16,35 @@
/* /*
* Implementing memory data movement * Implementing memory data movement
*/ */
SECUREC_INLINE void SecUtilMemmove(void *dst, const void *src, size_t count) { SECUREC_INLINE void SecUtilMemmove(void *dst, const void *src, size_t count)
unsigned char *pDest = (unsigned char *)dst; {
const unsigned char *pSrc = (const unsigned char *)src; unsigned char *pDest = (unsigned char *)dst;
size_t maxCount = count; const unsigned char *pSrc = (const unsigned char *)src;
size_t maxCount = count;
if (dst <= src || pDest >= (pSrc + maxCount)) { if (dst <= src || pDest >= (pSrc + maxCount)) {
/* /*
* Non-Overlapping Buffers * Non-Overlapping Buffers
* Copy from lower addresses to higher addresses * Copy from lower addresses to higher addresses
*/ */
while (maxCount--) { while (maxCount--) {
*pDest = *pSrc; *pDest = *pSrc;
++pDest; ++pDest;
++pSrc; ++pSrc;
}
} else {
/*
* Overlapping Buffers
* Copy from higher addresses to lower addresses
*/
pDest = pDest + maxCount - 1;
pSrc = pSrc + maxCount - 1;
while (maxCount--) {
*pDest = *pSrc;
--pDest;
--pSrc;
}
} }
} else {
/*
* Overlapping Buffers
* Copy from higher addresses to lower addresses
*/
pDest = pDest + maxCount - 1;
pSrc = pSrc + maxCount - 1;
while (maxCount--) {
*pDest = *pSrc;
--pDest;
--pSrc;
}
}
} }
#endif #endif
@@ -63,51 +63,52 @@ SECUREC_INLINE void SecUtilMemmove(void *dst, const void *src, size_t count) {
* *
* <RETURN VALUE> * <RETURN VALUE>
* EOK Success * EOK Success
* EINVAL dest is NULL and destMax != 0 and destMax <= * EINVAL dest is NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
* SECUREC_MEM_MAX_LEN EINVAL_AND_RESET dest != NULL and src is NULLL and * EINVAL_AND_RESET dest != NULL and src is NULLL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
* destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN ERANGE destMax > * ERANGE destMax > SECUREC_MEM_MAX_LEN or destMax is 0
* SECUREC_MEM_MAX_LEN or destMax is 0 ERANGE_AND_RESET count > destMax * ERANGE_AND_RESET count > destMax and dest != NULL and src != NULL and destMax != 0
* and dest != NULL and src != NULL and destMax != 0 and destMax <= * and destMax <= SECUREC_MEM_MAX_LEN
* SECUREC_MEM_MAX_LEN
* *
* If an error occured, dest will be filled with 0 when dest and destMax * If an error occured, dest will be filled with 0 when dest and destMax valid.
* valid. If some regions of the source area and the destination overlap, * If some regions of the source area and the destination overlap, memmove_s
* memmove_s ensures that the original source bytes in the overlapping region * ensures that the original source bytes in the overlapping region are copied
* are copied before being overwritten. * before being overwritten.
*/ */
errno_t memmove_s(void *dest, size_t destMax, const void *src, size_t count) { errno_t memmove_s(void *dest, size_t destMax, const void *src, size_t count)
if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) { {
SECUREC_ERROR_INVALID_RANGE("memmove_s"); if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) {
return ERANGE; SECUREC_ERROR_INVALID_RANGE("memmove_s");
} return ERANGE;
if (dest == NULL || src == NULL) { }
SECUREC_ERROR_INVALID_PARAMTER("memmove_s"); if (dest == NULL || src == NULL) {
if (dest != NULL) { SECUREC_ERROR_INVALID_PARAMTER("memmove_s");
(void)memset(dest, 0, destMax); if (dest != NULL) {
return EINVAL_AND_RESET; (void)memset(dest, 0, destMax);
return EINVAL_AND_RESET;
}
return EINVAL;
}
if (count > destMax) {
(void)memset(dest, 0, destMax);
SECUREC_ERROR_INVALID_RANGE("memmove_s");
return ERANGE_AND_RESET;
}
if (dest == src) {
return EOK;
} }
return EINVAL;
}
if (count > destMax) {
(void)memset(dest, 0, destMax);
SECUREC_ERROR_INVALID_RANGE("memmove_s");
return ERANGE_AND_RESET;
}
if (dest == src) {
return EOK;
}
if (count > 0) { if (count > 0) {
#ifdef SECUREC_NOT_CALL_LIBC_CORE_API #ifdef SECUREC_NOT_CALL_LIBC_CORE_API
SecUtilMemmove(dest, src, count); SecUtilMemmove(dest, src, count);
#else #else
/* Use underlying memmove for performance consideration */ /* Use underlying memmove for performance consideration */
(void)memmove(dest, src, count); (void)memmove(dest, src, count);
#endif #endif
} }
return EOK; return EOK;
} }
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
EXPORT_SYMBOL(memmove_s); EXPORT_SYMBOL(memmove_s);
#endif #endif
+426 -495
View File
@@ -6,9 +6,8 @@
*/ */
/* /*
* [Standardize-exceptions] Use unsafe function: Portability * [Standardize-exceptions] Use unsafe function: Portability
* [reason] Use unsafe function to implement security function to maintain * [reason] Use unsafe function to implement security function to maintain platform compatibility.
* platform compatibility. And sufficient input validation is performed before * And sufficient input validation is performed before calling
* calling
*/ */
#include "securecutil.h" #include "securecutil.h"
@@ -17,502 +16,431 @@
#define SECUREC_MEMSET_WITH_PERFORMANCE 0 #define SECUREC_MEMSET_WITH_PERFORMANCE 0
#endif #endif
#define SECUREC_MEMSET_PARAM_OK(dest, destMax, count) \ #define SECUREC_MEMSET_PARAM_OK(dest, destMax, count) (SECUREC_LIKELY((destMax) <= SECUREC_MEM_MAX_LEN && \
(SECUREC_LIKELY((destMax) <= SECUREC_MEM_MAX_LEN && (dest) != NULL && \ (dest) != NULL && (count) <= (destMax)))
(count) <= (destMax)))
#if SECUREC_WITH_PERFORMANCE_ADDONS || SECUREC_MEMSET_WITH_PERFORMANCE #if SECUREC_WITH_PERFORMANCE_ADDONS || SECUREC_MEMSET_WITH_PERFORMANCE
/* Use union to clear strict-aliasing warning */ /* Use union to clear strict-aliasing warning */
typedef union { typedef union {
SecStrBuf32 buf32; SecStrBuf32 buf32;
SecStrBuf31 buf31; SecStrBuf31 buf31;
SecStrBuf30 buf30; SecStrBuf30 buf30;
SecStrBuf29 buf29; SecStrBuf29 buf29;
SecStrBuf28 buf28; SecStrBuf28 buf28;
SecStrBuf27 buf27; SecStrBuf27 buf27;
SecStrBuf26 buf26; SecStrBuf26 buf26;
SecStrBuf25 buf25; SecStrBuf25 buf25;
SecStrBuf24 buf24; SecStrBuf24 buf24;
SecStrBuf23 buf23; SecStrBuf23 buf23;
SecStrBuf22 buf22; SecStrBuf22 buf22;
SecStrBuf21 buf21; SecStrBuf21 buf21;
SecStrBuf20 buf20; SecStrBuf20 buf20;
SecStrBuf19 buf19; SecStrBuf19 buf19;
SecStrBuf18 buf18; SecStrBuf18 buf18;
SecStrBuf17 buf17; SecStrBuf17 buf17;
SecStrBuf16 buf16; SecStrBuf16 buf16;
SecStrBuf15 buf15; SecStrBuf15 buf15;
SecStrBuf14 buf14; SecStrBuf14 buf14;
SecStrBuf13 buf13; SecStrBuf13 buf13;
SecStrBuf12 buf12; SecStrBuf12 buf12;
SecStrBuf11 buf11; SecStrBuf11 buf11;
SecStrBuf10 buf10; SecStrBuf10 buf10;
SecStrBuf9 buf9; SecStrBuf9 buf9;
SecStrBuf8 buf8; SecStrBuf8 buf8;
SecStrBuf7 buf7; SecStrBuf7 buf7;
SecStrBuf6 buf6; SecStrBuf6 buf6;
SecStrBuf5 buf5; SecStrBuf5 buf5;
SecStrBuf4 buf4; SecStrBuf4 buf4;
SecStrBuf3 buf3; SecStrBuf3 buf3;
SecStrBuf2 buf2; SecStrBuf2 buf2;
SecStrBuf1 buf1; SecStrBuf1 buf1;
} SecStrBuf32Union; } SecStrBuf32Union;
/* C standard initializes the first member of the consortium. */ /* C standard initializes the first member of the consortium. */
static const SecStrBuf32 g_allZero = { static const SecStrBuf32 g_allZero = {{
{'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'}}; '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
static const SecStrBuf32 g_allFF = { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }};
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, static const SecStrBuf32 g_allFF = {{
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
}};
/* Clear coversion warning strict aliasing" */ /* Clear coversion warning strict aliasing" */
SECUREC_INLINE const SecStrBuf32Union * SECUREC_INLINE const SecStrBuf32Union *SecStrictAliasingCast(const SecStrBuf32 *buf)
SecStrictAliasingCast(const SecStrBuf32 *buf) { {
return (const SecStrBuf32Union *)buf; return (const SecStrBuf32Union *)buf;
} }
#ifndef SECUREC_MEMSET_THRESHOLD_SIZE #ifndef SECUREC_MEMSET_THRESHOLD_SIZE
#define SECUREC_MEMSET_THRESHOLD_SIZE 32UL #define SECUREC_MEMSET_THRESHOLD_SIZE 32UL
#endif #endif
#define SECUREC_UNALIGNED_SET(dest, c, count) \ #define SECUREC_UNALIGNED_SET(dest, c, count) do { \
do { \ char *pcDest = (char *)(dest); \
char *pcDest = (char *)(dest); \ switch (count) { \
switch (count) { \ case 32: \
case 32: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 31: \
case 31: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 30: \
case 30: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 29: \
case 29: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 28: \
case 28: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 27: \
case 27: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 26: \
case 26: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 25: \
case 25: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 24: \
case 24: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 23: \
case 23: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 22: \
case 22: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 21: \
case 21: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 20: \
case 20: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 19: \
case 19: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 18: \
case 18: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 17: \
case 17: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 16: \
case 16: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 15: \
case 15: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 14: \
case 14: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 13: \
case 13: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 12: \
case 12: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 11: \
case 11: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 10: \
case 10: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 9: \
case 9: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 8: \
case 8: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 7: \
case 7: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 6: \
case 6: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 5: \
case 5: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 4: \
case 4: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 3: \
case 3: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 2: \
case 2: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ case 1: \
case 1: \ *(pcDest++) = (char)(c); \
*(pcDest++) = (char)(c); \ /* fall-through */ /* FALLTHRU */ \
/* fall-through */ /* FALLTHRU */ \ default: \
default: \ break; \
break; \ } \
} \ } SECUREC_WHILE_ZERO
} \
SECUREC_WHILE_ZERO
#define SECUREC_ALIGNED_SET_OPT_ZERO_FF(dest, c, count) \ #define SECUREC_ALIGNED_SET_OPT_ZERO_FF(dest, c, count) do { \
do { \ switch (c) { \
switch (c) { \ case 0: \
case 0: \ switch (count) { \
switch (count) { \ case 1: \
case 1: \ *(SecStrBuf1 *)(dest) = *(const SecStrBuf1 *)(&((SecStrictAliasingCast(&g_allZero))->buf1)); \
*(SecStrBuf1 *)(dest) = *( \ break; \
const SecStrBuf1 *)(&((SecStrictAliasingCast(&g_allZero))->buf1)); \ case 2: \
break; \ *(SecStrBuf2 *)(dest) = *(const SecStrBuf2 *)(&((SecStrictAliasingCast(&g_allZero))->buf2)); \
case 2: \ break; \
*(SecStrBuf2 *)(dest) = *( \ case 3: \
const SecStrBuf2 *)(&((SecStrictAliasingCast(&g_allZero))->buf2)); \ *(SecStrBuf3 *)(dest) = *(const SecStrBuf3 *)(&((SecStrictAliasingCast(&g_allZero))->buf3)); \
break; \ break; \
case 3: \ case 4: \
*(SecStrBuf3 *)(dest) = *( \ *(SecStrBuf4 *)(dest) = *(const SecStrBuf4 *)(&((SecStrictAliasingCast(&g_allZero))->buf4)); \
const SecStrBuf3 *)(&((SecStrictAliasingCast(&g_allZero))->buf3)); \ break; \
break; \ case 5: \
case 4: \ *(SecStrBuf5 *)(dest) = *(const SecStrBuf5 *)(&((SecStrictAliasingCast(&g_allZero))->buf5)); \
*(SecStrBuf4 *)(dest) = *( \ break; \
const SecStrBuf4 *)(&((SecStrictAliasingCast(&g_allZero))->buf4)); \ case 6: \
break; \ *(SecStrBuf6 *)(dest) = *(const SecStrBuf6 *)(&((SecStrictAliasingCast(&g_allZero))->buf6)); \
case 5: \ break; \
*(SecStrBuf5 *)(dest) = *( \ case 7: \
const SecStrBuf5 *)(&((SecStrictAliasingCast(&g_allZero))->buf5)); \ *(SecStrBuf7 *)(dest) = *(const SecStrBuf7 *)(&((SecStrictAliasingCast(&g_allZero))->buf7)); \
break; \ break; \
case 6: \ case 8: \
*(SecStrBuf6 *)(dest) = *( \ *(SecStrBuf8 *)(dest) = *(const SecStrBuf8 *)(&((SecStrictAliasingCast(&g_allZero))->buf8)); \
const SecStrBuf6 *)(&((SecStrictAliasingCast(&g_allZero))->buf6)); \ break; \
break; \ case 9: \
case 7: \ *(SecStrBuf9 *)(dest) = *(const SecStrBuf9 *)(&((SecStrictAliasingCast(&g_allZero))->buf9)); \
*(SecStrBuf7 *)(dest) = *( \ break; \
const SecStrBuf7 *)(&((SecStrictAliasingCast(&g_allZero))->buf7)); \ case 10: \
break; \ *(SecStrBuf10 *)(dest) = *(const SecStrBuf10 *)(&((SecStrictAliasingCast(&g_allZero))->buf10)); \
case 8: \ break; \
*(SecStrBuf8 *)(dest) = *( \ case 11: \
const SecStrBuf8 *)(&((SecStrictAliasingCast(&g_allZero))->buf8)); \ *(SecStrBuf11 *)(dest) = *(const SecStrBuf11 *)(&((SecStrictAliasingCast(&g_allZero))->buf11)); \
break; \ break; \
case 9: \ case 12: \
*(SecStrBuf9 *)(dest) = *( \ *(SecStrBuf12 *)(dest) = *(const SecStrBuf12 *)(&((SecStrictAliasingCast(&g_allZero))->buf12)); \
const SecStrBuf9 *)(&((SecStrictAliasingCast(&g_allZero))->buf9)); \ break; \
break; \ case 13: \
case 10: \ *(SecStrBuf13 *)(dest) = *(const SecStrBuf13 *)(&((SecStrictAliasingCast(&g_allZero))->buf13)); \
*(SecStrBuf10 *)(dest) = *(const SecStrBuf10 *)(&( \ break; \
(SecStrictAliasingCast(&g_allZero))->buf10)); \ case 14: \
break; \ *(SecStrBuf14 *)(dest) = *(const SecStrBuf14 *)(&((SecStrictAliasingCast(&g_allZero))->buf14)); \
case 11: \ break; \
*(SecStrBuf11 *)(dest) = *(const SecStrBuf11 *)(&( \ case 15: \
(SecStrictAliasingCast(&g_allZero))->buf11)); \ *(SecStrBuf15 *)(dest) = *(const SecStrBuf15 *)(&((SecStrictAliasingCast(&g_allZero))->buf15)); \
break; \ break; \
case 12: \ case 16: \
*(SecStrBuf12 *)(dest) = *(const SecStrBuf12 *)(&( \ *(SecStrBuf16 *)(dest) = *(const SecStrBuf16 *)(&((SecStrictAliasingCast(&g_allZero))->buf16)); \
(SecStrictAliasingCast(&g_allZero))->buf12)); \ break; \
break; \ case 17: \
case 13: \ *(SecStrBuf17 *)(dest) = *(const SecStrBuf17 *)(&((SecStrictAliasingCast(&g_allZero))->buf17)); \
*(SecStrBuf13 *)(dest) = *(const SecStrBuf13 *)(&( \ break; \
(SecStrictAliasingCast(&g_allZero))->buf13)); \ case 18: \
break; \ *(SecStrBuf18 *)(dest) = *(const SecStrBuf18 *)(&((SecStrictAliasingCast(&g_allZero))->buf18)); \
case 14: \ break; \
*(SecStrBuf14 *)(dest) = *(const SecStrBuf14 *)(&( \ case 19: \
(SecStrictAliasingCast(&g_allZero))->buf14)); \ *(SecStrBuf19 *)(dest) = *(const SecStrBuf19 *)(&((SecStrictAliasingCast(&g_allZero))->buf19)); \
break; \ break; \
case 15: \ case 20: \
*(SecStrBuf15 *)(dest) = *(const SecStrBuf15 *)(&( \ *(SecStrBuf20 *)(dest) = *(const SecStrBuf20 *)(&((SecStrictAliasingCast(&g_allZero))->buf20)); \
(SecStrictAliasingCast(&g_allZero))->buf15)); \ break; \
break; \ case 21: \
case 16: \ *(SecStrBuf21 *)(dest) = *(const SecStrBuf21 *)(&((SecStrictAliasingCast(&g_allZero))->buf21)); \
*(SecStrBuf16 *)(dest) = *(const SecStrBuf16 *)(&( \ break; \
(SecStrictAliasingCast(&g_allZero))->buf16)); \ case 22: \
break; \ *(SecStrBuf22 *)(dest) = *(const SecStrBuf22 *)(&((SecStrictAliasingCast(&g_allZero))->buf22)); \
case 17: \ break; \
*(SecStrBuf17 *)(dest) = *(const SecStrBuf17 *)(&( \ case 23: \
(SecStrictAliasingCast(&g_allZero))->buf17)); \ *(SecStrBuf23 *)(dest) = *(const SecStrBuf23 *)(&((SecStrictAliasingCast(&g_allZero))->buf23)); \
break; \ break; \
case 18: \ case 24: \
*(SecStrBuf18 *)(dest) = *(const SecStrBuf18 *)(&( \ *(SecStrBuf24 *)(dest) = *(const SecStrBuf24 *)(&((SecStrictAliasingCast(&g_allZero))->buf24)); \
(SecStrictAliasingCast(&g_allZero))->buf18)); \ break; \
break; \ case 25: \
case 19: \ *(SecStrBuf25 *)(dest) = *(const SecStrBuf25 *)(&((SecStrictAliasingCast(&g_allZero))->buf25)); \
*(SecStrBuf19 *)(dest) = *(const SecStrBuf19 *)(&( \ break; \
(SecStrictAliasingCast(&g_allZero))->buf19)); \ case 26: \
break; \ *(SecStrBuf26 *)(dest) = *(const SecStrBuf26 *)(&((SecStrictAliasingCast(&g_allZero))->buf26)); \
case 20: \ break; \
*(SecStrBuf20 *)(dest) = *(const SecStrBuf20 *)(&( \ case 27: \
(SecStrictAliasingCast(&g_allZero))->buf20)); \ *(SecStrBuf27 *)(dest) = *(const SecStrBuf27 *)(&((SecStrictAliasingCast(&g_allZero))->buf27)); \
break; \ break; \
case 21: \ case 28: \
*(SecStrBuf21 *)(dest) = *(const SecStrBuf21 *)(&( \ *(SecStrBuf28 *)(dest) = *(const SecStrBuf28 *)(&((SecStrictAliasingCast(&g_allZero))->buf28)); \
(SecStrictAliasingCast(&g_allZero))->buf21)); \ break; \
break; \ case 29: \
case 22: \ *(SecStrBuf29 *)(dest) = *(const SecStrBuf29 *)(&((SecStrictAliasingCast(&g_allZero))->buf29)); \
*(SecStrBuf22 *)(dest) = *(const SecStrBuf22 *)(&( \ break; \
(SecStrictAliasingCast(&g_allZero))->buf22)); \ case 30: \
break; \ *(SecStrBuf30 *)(dest) = *(const SecStrBuf30 *)(&((SecStrictAliasingCast(&g_allZero))->buf30)); \
case 23: \ break; \
*(SecStrBuf23 *)(dest) = *(const SecStrBuf23 *)(&( \ case 31: \
(SecStrictAliasingCast(&g_allZero))->buf23)); \ *(SecStrBuf31 *)(dest) = *(const SecStrBuf31 *)(&((SecStrictAliasingCast(&g_allZero))->buf31)); \
break; \ break; \
case 24: \ case 32: \
*(SecStrBuf24 *)(dest) = *(const SecStrBuf24 *)(&( \ *(SecStrBuf32 *)(dest) = *(const SecStrBuf32 *)(&((SecStrictAliasingCast(&g_allZero))->buf32)); \
(SecStrictAliasingCast(&g_allZero))->buf24)); \ break; \
break; \ default: \
case 25: \ break; \
*(SecStrBuf25 *)(dest) = *(const SecStrBuf25 *)(&( \ } \
(SecStrictAliasingCast(&g_allZero))->buf25)); \ break; \
break; \ case 0xFF: \
case 26: \ switch (count) { \
*(SecStrBuf26 *)(dest) = *(const SecStrBuf26 *)(&( \ case 1: \
(SecStrictAliasingCast(&g_allZero))->buf26)); \ *(SecStrBuf1 *)(dest) = *(const SecStrBuf1 *)(&((SecStrictAliasingCast(&g_allFF))->buf1)); \
break; \ break; \
case 27: \ case 2: \
*(SecStrBuf27 *)(dest) = *(const SecStrBuf27 *)(&( \ *(SecStrBuf2 *)(dest) = *(const SecStrBuf2 *)(&((SecStrictAliasingCast(&g_allFF))->buf2)); \
(SecStrictAliasingCast(&g_allZero))->buf27)); \ break; \
break; \ case 3: \
case 28: \ *(SecStrBuf3 *)(dest) = *(const SecStrBuf3 *)(&((SecStrictAliasingCast(&g_allFF))->buf3)); \
*(SecStrBuf28 *)(dest) = *(const SecStrBuf28 *)(&( \ break; \
(SecStrictAliasingCast(&g_allZero))->buf28)); \ case 4: \
break; \ *(SecStrBuf4 *)(dest) = *(const SecStrBuf4 *)(&((SecStrictAliasingCast(&g_allFF))->buf4)); \
case 29: \ break; \
*(SecStrBuf29 *)(dest) = *(const SecStrBuf29 *)(&( \ case 5: \
(SecStrictAliasingCast(&g_allZero))->buf29)); \ *(SecStrBuf5 *)(dest) = *(const SecStrBuf5 *)(&((SecStrictAliasingCast(&g_allFF))->buf5)); \
break; \ break; \
case 30: \ case 6: \
*(SecStrBuf30 *)(dest) = *(const SecStrBuf30 *)(&( \ *(SecStrBuf6 *)(dest) = *(const SecStrBuf6 *)(&((SecStrictAliasingCast(&g_allFF))->buf6)); \
(SecStrictAliasingCast(&g_allZero))->buf30)); \ break; \
break; \ case 7: \
case 31: \ *(SecStrBuf7 *)(dest) = *(const SecStrBuf7 *)(&((SecStrictAliasingCast(&g_allFF))->buf7)); \
*(SecStrBuf31 *)(dest) = *(const SecStrBuf31 *)(&( \ break; \
(SecStrictAliasingCast(&g_allZero))->buf31)); \ case 8: \
break; \ *(SecStrBuf8 *)(dest) = *(const SecStrBuf8 *)(&((SecStrictAliasingCast(&g_allFF))->buf8)); \
case 32: \ break; \
*(SecStrBuf32 *)(dest) = *(const SecStrBuf32 *)(&( \ case 9: \
(SecStrictAliasingCast(&g_allZero))->buf32)); \ *(SecStrBuf9 *)(dest) = *(const SecStrBuf9 *)(&((SecStrictAliasingCast(&g_allFF))->buf9)); \
break; \ break; \
default: \ case 10: \
break; \ *(SecStrBuf10 *)(dest) = *(const SecStrBuf10 *)(&((SecStrictAliasingCast(&g_allFF))->buf10)); \
} \ break; \
break; \ case 11: \
case 0xFF: \ *(SecStrBuf11 *)(dest) = *(const SecStrBuf11 *)(&((SecStrictAliasingCast(&g_allFF))->buf11)); \
switch (count) { \ break; \
case 1: \ case 12: \
*(SecStrBuf1 *)(dest) = \ *(SecStrBuf12 *)(dest) = *(const SecStrBuf12 *)(&((SecStrictAliasingCast(&g_allFF))->buf12)); \
*(const SecStrBuf1 *)(&((SecStrictAliasingCast(&g_allFF))->buf1)); \ break; \
break; \ case 13: \
case 2: \ *(SecStrBuf13 *)(dest) = *(const SecStrBuf13 *)(&((SecStrictAliasingCast(&g_allFF))->buf13)); \
*(SecStrBuf2 *)(dest) = \ break; \
*(const SecStrBuf2 *)(&((SecStrictAliasingCast(&g_allFF))->buf2)); \ case 14: \
break; \ *(SecStrBuf14 *)(dest) = *(const SecStrBuf14 *)(&((SecStrictAliasingCast(&g_allFF))->buf14)); \
case 3: \ break; \
*(SecStrBuf3 *)(dest) = \ case 15: \
*(const SecStrBuf3 *)(&((SecStrictAliasingCast(&g_allFF))->buf3)); \ *(SecStrBuf15 *)(dest) = *(const SecStrBuf15 *)(&((SecStrictAliasingCast(&g_allFF))->buf15)); \
break; \ break; \
case 4: \ case 16: \
*(SecStrBuf4 *)(dest) = \ *(SecStrBuf16 *)(dest) = *(const SecStrBuf16 *)(&((SecStrictAliasingCast(&g_allFF))->buf16)); \
*(const SecStrBuf4 *)(&((SecStrictAliasingCast(&g_allFF))->buf4)); \ break; \
break; \ case 17: \
case 5: \ *(SecStrBuf17 *)(dest) = *(const SecStrBuf17 *)(&((SecStrictAliasingCast(&g_allFF))->buf17)); \
*(SecStrBuf5 *)(dest) = \ break; \
*(const SecStrBuf5 *)(&((SecStrictAliasingCast(&g_allFF))->buf5)); \ case 18: \
break; \ *(SecStrBuf18 *)(dest) = *(const SecStrBuf18 *)(&((SecStrictAliasingCast(&g_allFF))->buf18)); \
case 6: \ break; \
*(SecStrBuf6 *)(dest) = \ case 19: \
*(const SecStrBuf6 *)(&((SecStrictAliasingCast(&g_allFF))->buf6)); \ *(SecStrBuf19 *)(dest) = *(const SecStrBuf19 *)(&((SecStrictAliasingCast(&g_allFF))->buf19)); \
break; \ break; \
case 7: \ case 20: \
*(SecStrBuf7 *)(dest) = \ *(SecStrBuf20 *)(dest) = *(const SecStrBuf20 *)(&((SecStrictAliasingCast(&g_allFF))->buf20)); \
*(const SecStrBuf7 *)(&((SecStrictAliasingCast(&g_allFF))->buf7)); \ break; \
break; \ case 21: \
case 8: \ *(SecStrBuf21 *)(dest) = *(const SecStrBuf21 *)(&((SecStrictAliasingCast(&g_allFF))->buf21)); \
*(SecStrBuf8 *)(dest) = \ break; \
*(const SecStrBuf8 *)(&((SecStrictAliasingCast(&g_allFF))->buf8)); \ case 22: \
break; \ *(SecStrBuf22 *)(dest) = *(const SecStrBuf22 *)(&((SecStrictAliasingCast(&g_allFF))->buf22)); \
case 9: \ break; \
*(SecStrBuf9 *)(dest) = \ case 23: \
*(const SecStrBuf9 *)(&((SecStrictAliasingCast(&g_allFF))->buf9)); \ *(SecStrBuf23 *)(dest) = *(const SecStrBuf23 *)(&((SecStrictAliasingCast(&g_allFF))->buf23)); \
break; \ break; \
case 10: \ case 24: \
*(SecStrBuf10 *)(dest) = *( \ *(SecStrBuf24 *)(dest) = *(const SecStrBuf24 *)(&((SecStrictAliasingCast(&g_allFF))->buf24)); \
const SecStrBuf10 *)(&((SecStrictAliasingCast(&g_allFF))->buf10)); \ break; \
break; \ case 25: \
case 11: \ *(SecStrBuf25 *)(dest) = *(const SecStrBuf25 *)(&((SecStrictAliasingCast(&g_allFF))->buf25)); \
*(SecStrBuf11 *)(dest) = *( \ break; \
const SecStrBuf11 *)(&((SecStrictAliasingCast(&g_allFF))->buf11)); \ case 26: \
break; \ *(SecStrBuf26 *)(dest) = *(const SecStrBuf26 *)(&((SecStrictAliasingCast(&g_allFF))->buf26)); \
case 12: \ break; \
*(SecStrBuf12 *)(dest) = *( \ case 27: \
const SecStrBuf12 *)(&((SecStrictAliasingCast(&g_allFF))->buf12)); \ *(SecStrBuf27 *)(dest) = *(const SecStrBuf27 *)(&((SecStrictAliasingCast(&g_allFF))->buf27)); \
break; \ break; \
case 13: \ case 28: \
*(SecStrBuf13 *)(dest) = *( \ *(SecStrBuf28 *)(dest) = *(const SecStrBuf28 *)(&((SecStrictAliasingCast(&g_allFF))->buf28)); \
const SecStrBuf13 *)(&((SecStrictAliasingCast(&g_allFF))->buf13)); \ break; \
break; \ case 29: \
case 14: \ *(SecStrBuf29 *)(dest) = *(const SecStrBuf29 *)(&((SecStrictAliasingCast(&g_allFF))->buf29)); \
*(SecStrBuf14 *)(dest) = *( \ break; \
const SecStrBuf14 *)(&((SecStrictAliasingCast(&g_allFF))->buf14)); \ case 30: \
break; \ *(SecStrBuf30 *)(dest) = *(const SecStrBuf30 *)(&((SecStrictAliasingCast(&g_allFF))->buf30)); \
case 15: \ break; \
*(SecStrBuf15 *)(dest) = *( \ case 31: \
const SecStrBuf15 *)(&((SecStrictAliasingCast(&g_allFF))->buf15)); \ *(SecStrBuf31 *)(dest) = *(const SecStrBuf31 *)(&((SecStrictAliasingCast(&g_allFF))->buf31)); \
break; \ break; \
case 16: \ case 32: \
*(SecStrBuf16 *)(dest) = *( \ *(SecStrBuf32 *)(dest) = *(const SecStrBuf32 *)(&((SecStrictAliasingCast(&g_allFF))->buf32)); \
const SecStrBuf16 *)(&((SecStrictAliasingCast(&g_allFF))->buf16)); \ break; \
break; \ default: \
case 17: \ break; \
*(SecStrBuf17 *)(dest) = *( \ } \
const SecStrBuf17 *)(&((SecStrictAliasingCast(&g_allFF))->buf17)); \ break; \
break; \ default: \
case 18: \ SECUREC_UNALIGNED_SET((dest), (c), (count)); \
*(SecStrBuf18 *)(dest) = *( \ } /* END switch */ \
const SecStrBuf18 *)(&((SecStrictAliasingCast(&g_allFF))->buf18)); \ } SECUREC_WHILE_ZERO
break; \
case 19: \
*(SecStrBuf19 *)(dest) = *( \
const SecStrBuf19 *)(&((SecStrictAliasingCast(&g_allFF))->buf19)); \
break; \
case 20: \
*(SecStrBuf20 *)(dest) = *( \
const SecStrBuf20 *)(&((SecStrictAliasingCast(&g_allFF))->buf20)); \
break; \
case 21: \
*(SecStrBuf21 *)(dest) = *( \
const SecStrBuf21 *)(&((SecStrictAliasingCast(&g_allFF))->buf21)); \
break; \
case 22: \
*(SecStrBuf22 *)(dest) = *( \
const SecStrBuf22 *)(&((SecStrictAliasingCast(&g_allFF))->buf22)); \
break; \
case 23: \
*(SecStrBuf23 *)(dest) = *( \
const SecStrBuf23 *)(&((SecStrictAliasingCast(&g_allFF))->buf23)); \
break; \
case 24: \
*(SecStrBuf24 *)(dest) = *( \
const SecStrBuf24 *)(&((SecStrictAliasingCast(&g_allFF))->buf24)); \
break; \
case 25: \
*(SecStrBuf25 *)(dest) = *( \
const SecStrBuf25 *)(&((SecStrictAliasingCast(&g_allFF))->buf25)); \
break; \
case 26: \
*(SecStrBuf26 *)(dest) = *( \
const SecStrBuf26 *)(&((SecStrictAliasingCast(&g_allFF))->buf26)); \
break; \
case 27: \
*(SecStrBuf27 *)(dest) = *( \
const SecStrBuf27 *)(&((SecStrictAliasingCast(&g_allFF))->buf27)); \
break; \
case 28: \
*(SecStrBuf28 *)(dest) = *( \
const SecStrBuf28 *)(&((SecStrictAliasingCast(&g_allFF))->buf28)); \
break; \
case 29: \
*(SecStrBuf29 *)(dest) = *( \
const SecStrBuf29 *)(&((SecStrictAliasingCast(&g_allFF))->buf29)); \
break; \
case 30: \
*(SecStrBuf30 *)(dest) = *( \
const SecStrBuf30 *)(&((SecStrictAliasingCast(&g_allFF))->buf30)); \
break; \
case 31: \
*(SecStrBuf31 *)(dest) = *( \
const SecStrBuf31 *)(&((SecStrictAliasingCast(&g_allFF))->buf31)); \
break; \
case 32: \
*(SecStrBuf32 *)(dest) = *( \
const SecStrBuf32 *)(&((SecStrictAliasingCast(&g_allFF))->buf32)); \
break; \
default: \
break; \
} \
break; \
default: \
SECUREC_UNALIGNED_SET((dest), (c), (count)); \
} /* END switch */ \
} \
SECUREC_WHILE_ZERO
#define SECUREC_SMALL_MEM_SET(dest, c, count) \ #define SECUREC_SMALL_MEM_SET(dest, c, count); do { \
; \ if (SECUREC_ADDR_ALIGNED_8((dest))) { \
do { \ SECUREC_ALIGNED_SET_OPT_ZERO_FF((dest), (c), (count)); \
if (SECUREC_ADDR_ALIGNED_8((dest))) { \ } else { \
SECUREC_ALIGNED_SET_OPT_ZERO_FF((dest), (c), (count)); \ SECUREC_UNALIGNED_SET((dest), (c), (count)); \
} else { \ } \
SECUREC_UNALIGNED_SET((dest), (c), (count)); \ } SECUREC_WHILE_ZERO
} \
} \
SECUREC_WHILE_ZERO
/* /*
* Performance optimization * Performance optimization
*/ */
#define SECUREC_MEMSET_OPT(dest, c, count) \ #define SECUREC_MEMSET_OPT(dest, c, count) do { \
do { \ if ((count) > SECUREC_MEMSET_THRESHOLD_SIZE) { \
if ((count) > SECUREC_MEMSET_THRESHOLD_SIZE) { \ SECUREC_MEMSET_WARP_OPT((dest), (c), (count)); \
SECUREC_MEMSET_WARP_OPT((dest), (c), (count)); \ } else { \
} else { \ SECUREC_SMALL_MEM_SET((dest), (c), (count)); \
SECUREC_SMALL_MEM_SET((dest), (c), (count)); \ } \
} \ } SECUREC_WHILE_ZERO
} \
SECUREC_WHILE_ZERO
#endif #endif
/* /*
* Handling errors * Handling errors
*/ */
SECUREC_INLINE errno_t SecMemsetError(void *dest, size_t destMax, int c, SECUREC_INLINE errno_t SecMemsetError(void *dest, size_t destMax, int c, size_t count)
size_t count) { {
/* Check destMax is 0 compatible with _sp macro */ /* Check destMax is 0 compatible with _sp macro */
if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) { if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) {
SECUREC_ERROR_INVALID_RANGE("memset_s"); SECUREC_ERROR_INVALID_RANGE("memset_s");
return ERANGE; return ERANGE;
} }
if (dest == NULL) { if (dest == NULL) {
SECUREC_ERROR_INVALID_PARAMTER("memset_s"); SECUREC_ERROR_INVALID_PARAMTER("memset_s");
return EINVAL; return EINVAL;
} }
if (count > destMax) { if (count > destMax) {
(void)memset(dest, c, destMax); /* Set entire buffer to value c */ (void)memset(dest, c, destMax); /* Set entire buffer to value c */
SECUREC_ERROR_INVALID_RANGE("memset_s"); SECUREC_ERROR_INVALID_RANGE("memset_s");
return ERANGE_AND_RESET; return ERANGE_AND_RESET;
} }
return EOK; return EOK;
} }
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The memset_s function copies the value of c (converted to an unsigned * The memset_s function copies the value of c (converted to an unsigned char)
* char) into each of the first count characters of the object pointed to by * into each of the first count characters of the object pointed to by dest.
* dest.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* dest Pointer to destination. * dest Pointer to destination.
@@ -525,24 +453,24 @@ SECUREC_INLINE errno_t SecMemsetError(void *dest, size_t destMax, int c,
* *
* <RETURN VALUE> * <RETURN VALUE>
* EOK Success * EOK Success
* EINVAL dest == NULL and destMax != 0 and destMax <= * EINVAL dest == NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
* SECUREC_MEM_MAX_LEN ERANGE destMax > SECUREC_MEM_MAX_LEN or * ERANGE destMax > SECUREC_MEM_MAX_LEN or (destMax is 0 and count > destMax)
* (destMax is 0 and count > destMax) ERANGE_AND_RESET count > destMax and * ERANGE_AND_RESET count > destMax and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN and dest != NULL
* destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN and dest != NULL
* *
* if return ERANGE_AND_RESET then fill dest to c ,fill length is destMax * if return ERANGE_AND_RESET then fill dest to c ,fill length is destMax
*/ */
errno_t memset_s(void *dest, size_t destMax, int c, size_t count) { errno_t memset_s(void *dest, size_t destMax, int c, size_t count)
if (SECUREC_MEMSET_PARAM_OK(dest, destMax, count)) { {
if (SECUREC_MEMSET_PARAM_OK(dest, destMax, count)) {
#if SECUREC_MEMSET_WITH_PERFORMANCE #if SECUREC_MEMSET_WITH_PERFORMANCE
SECUREC_MEMSET_OPT(dest, c, count); SECUREC_MEMSET_OPT(dest, c, count);
#else #else
SECUREC_MEMSET_WARP_OPT(dest, c, count); SECUREC_MEMSET_WARP_OPT(dest, c, count);
#endif #endif
return EOK; return EOK;
} }
/* Meet some runtime violation, return error code */ /* Meet some runtime violation, return error code */
return SecMemsetError(dest, destMax, c, count); return SecMemsetError(dest, destMax, c, count);
} }
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
@@ -553,24 +481,27 @@ EXPORT_SYMBOL(memset_s);
/* /*
* Performance optimization * Performance optimization
*/ */
errno_t memset_sOptAsm(void *dest, size_t destMax, int c, size_t count) { errno_t memset_sOptAsm(void *dest, size_t destMax, int c, size_t count)
if (SECUREC_MEMSET_PARAM_OK(dest, destMax, count)) { {
SECUREC_MEMSET_OPT(dest, c, count); if (SECUREC_MEMSET_PARAM_OK(dest, destMax, count)) {
return EOK; SECUREC_MEMSET_OPT(dest, c, count);
} return EOK;
/* Meet some runtime violation, return error code */ }
return SecMemsetError(dest, destMax, c, count); /* Meet some runtime violation, return error code */
return SecMemsetError(dest, destMax, c, count);
} }
/* /*
* Performance optimization, trim judgement on "destMax <= SECUREC_MEM_MAX_LEN" * Performance optimization, trim judgement on "destMax <= SECUREC_MEM_MAX_LEN"
*/ */
errno_t memset_sOptTc(void *dest, size_t destMax, int c, size_t count) { errno_t memset_sOptTc(void *dest, size_t destMax, int c, size_t count)
if (SECUREC_LIKELY(count <= destMax && dest != NULL)) { {
SECUREC_MEMSET_OPT(dest, c, count); if (SECUREC_LIKELY(count <= destMax && dest != NULL)) {
return EOK; SECUREC_MEMSET_OPT(dest, c, count);
} return EOK;
/* Meet some runtime violation, return error code */ }
return SecMemsetError(dest, destMax, c, count); /* Meet some runtime violation, return error code */
return SecMemsetError(dest, destMax, c, count);
} }
#endif #endif
@@ -9,20 +9,19 @@
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The scanf_s function is equivalent to fscanf_s with the argument stdin * The scanf_s function is equivalent to fscanf_s with the argument stdin interposed before the arguments to scanf_s
* interposed before the arguments to scanf_s The scanf_s function reads data * The scanf_s function reads data from the standard input stream stdin and
* from the standard input stream stdin and writes the data into the location * writes the data into the location that's given by argument. Each argument
* that's given by argument. Each argument must be a pointer to a variable of a * must be a pointer to a variable of a type that corresponds to a type specifier
* type that corresponds to a type specifier in format. If copying occurs * in format. If copying occurs between strings that overlap, the behavior is
* between strings that overlap, the behavior is undefined. * undefined.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* format Format control string. * format Format control string.
* ... Optional arguments. * ... Optional arguments.
* *
* <OUTPUT PARAMETERS> * <OUTPUT PARAMETERS>
* ... The converted value stored in user assigned * ... The converted value stored in user assigned address
* address
* *
* <RETURN VALUE> * <RETURN VALUE>
* Returns the number of fields successfully converted and assigned; * Returns the number of fields successfully converted and assigned;
@@ -30,15 +29,17 @@
* A return value of 0 indicates that no fields were assigned. * A return value of 0 indicates that no fields were assigned.
* return -1 if an error occurs. * return -1 if an error occurs.
*/ */
int scanf_s(const char *format, ...) { int scanf_s(const char *format, ...)
int ret; /* If initialization causes e838 */ {
va_list argList; int ret; /* If initialization causes e838 */
va_list argList;
va_start(argList, format); va_start(argList, format);
ret = vscanf_s(format, argList); ret = vscanf_s(format, argList);
va_end(argList); va_end(argList);
(void)argList; /* To clear e438 last value assigned not used , the compiler (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
will optimize this code */
return ret; return ret;
} }
@@ -10,40 +10,39 @@
#define SEC_INPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C #define SEC_INPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C
#include "securecutil.h" #include "securecutil.h"
#define SECUREC_SCANF_EINVAL (-1) #define SECUREC_SCANF_EINVAL (-1)
#define SECUREC_SCANF_ERROR_PARA (-2) #define SECUREC_SCANF_ERROR_PARA (-2)
/* For internal stream flag */ /* For internal stream flag */
#define SECUREC_MEM_STR_FLAG 0X01 #define SECUREC_MEM_STR_FLAG 0X01
#define SECUREC_FILE_STREAM_FLAG 0X02 #define SECUREC_FILE_STREAM_FLAG 0X02
#define SECUREC_PIPE_STREAM_FLAG 0X04 #define SECUREC_PIPE_STREAM_FLAG 0X04
#define SECUREC_LOAD_FILE_TO_MEM_FLAG 0X08 #define SECUREC_LOAD_FILE_TO_MEM_FLAG 0X08
#define SECUREC_BOM_HEADER_SIZE 2 #define SECUREC_BOM_HEADER_SIZE 2
#define SECUREC_BOM_HEADER_BE_1ST 0xFEU #define SECUREC_BOM_HEADER_BE_1ST 0xFEU
#define SECUREC_BOM_HEADER_BE_2ST 0xFFU #define SECUREC_BOM_HEADER_BE_2ST 0xFFU
#define SECUREC_BOM_HEADER_LE_1ST 0xFFU #define SECUREC_BOM_HEADER_LE_1ST 0xFFU
#define SECUREC_BOM_HEADER_LE_2ST 0xFEU #define SECUREC_BOM_HEADER_LE_2ST 0xFEU
#define SECUREC_UTF8_BOM_HEADER_SIZE 3 #define SECUREC_UTF8_BOM_HEADER_SIZE 3
#define SECUREC_UTF8_BOM_HEADER_1ST 0xEFU #define SECUREC_UTF8_BOM_HEADER_1ST 0xEFU
#define SECUREC_UTF8_BOM_HEADER_2ND 0xBBU #define SECUREC_UTF8_BOM_HEADER_2ND 0xBBU
#define SECUREC_UTF8_BOM_HEADER_3RD 0xBFU #define SECUREC_UTF8_BOM_HEADER_3RD 0xBFU
#define SECUREC_UTF8_LEAD_1ST 0xE0 #define SECUREC_UTF8_LEAD_1ST 0xE0
#define SECUREC_UTF8_LEAD_2ND 0x80 #define SECUREC_UTF8_LEAD_2ND 0x80
typedef struct { typedef struct {
unsigned int flag; /* Mark the properties of input stream */ unsigned int flag; /* Mark the properties of input stream */
int count; /* The size of buffered string in bytes */ int count; /* The size of buffered string in bytes */
const char *cur; /* The pointer to next read position */ const char *cur; /* The pointer to next read position */
char *base; /* The pointer to the header of buffered string */ char *base; /* The pointer to the header of buffered string */
#if SECUREC_ENABLE_SCANF_FILE #if SECUREC_ENABLE_SCANF_FILE
FILE *pf; /* The file pointer */ FILE *pf; /* The file pointer */
long oriFilePos; /* The original position of file offset when fscanf is called long oriFilePos; /* The original position of file offset when fscanf is called */
*/ int fileRealRead;
int fileRealRead;
#ifdef SECUREC_NO_STD_UNGETC #ifdef SECUREC_NO_STD_UNGETC
unsigned int lastChar; /* The char code of last input */ unsigned int lastChar; /* The char code of last input */
int fUnGet; /* The boolean flag of pushing a char back to read stream */ int fUnGet; /* The boolean flag of pushing a char back to read stream */
#endif #endif
#endif #endif
} SecFileStream; } SecFileStream;
@@ -52,19 +51,19 @@ typedef struct {
/* /*
* This initialization for eliminating redundant initialization. * This initialization for eliminating redundant initialization.
*/ */
SECUREC_INLINE void SecInitFileStreamFromString(SecFileStream *stream, SECUREC_INLINE void SecInitFileStreamFromString(SecFileStream *stream, const char *cur, int count)
const char *cur, int count) { {
stream->flag = SECUREC_MEM_STR_FLAG; stream->flag = SECUREC_MEM_STR_FLAG;
stream->count = count; stream->count = count;
stream->cur = cur; stream->cur = cur;
stream->base = NULL; stream->base = NULL;
#if SECUREC_ENABLE_SCANF_FILE #if SECUREC_ENABLE_SCANF_FILE
stream->pf = NULL; stream->pf = NULL;
stream->oriFilePos = 0; stream->oriFilePos = 0;
stream->fileRealRead = 0; stream->fileRealRead = 0;
#ifdef SECUREC_NO_STD_UNGETC #ifdef SECUREC_NO_STD_UNGETC
stream->lastChar = 0; stream->lastChar = 0;
stream->fUnGet = 0; stream->fUnGet = 0;
#endif #endif
#endif #endif
} }
@@ -74,42 +73,44 @@ SECUREC_INLINE void SecInitFileStreamFromString(SecFileStream *stream,
/* /*
* This initialization for eliminating redundant initialization. * This initialization for eliminating redundant initialization.
*/ */
SECUREC_INLINE void SecInitFileStreamFromStdin(SecFileStream *stream) { SECUREC_INLINE void SecInitFileStreamFromStdin(SecFileStream *stream)
stream->flag = SECUREC_PIPE_STREAM_FLAG; {
stream->count = 0; stream->flag = SECUREC_PIPE_STREAM_FLAG;
stream->cur = NULL; stream->count = 0;
stream->base = NULL; stream->cur = NULL;
stream->base = NULL;
#if SECUREC_ENABLE_SCANF_FILE #if SECUREC_ENABLE_SCANF_FILE
stream->pf = SECUREC_STREAM_STDIN; stream->pf = SECUREC_STREAM_STDIN;
stream->oriFilePos = 0; stream->oriFilePos = 0;
stream->fileRealRead = 0; stream->fileRealRead = 0;
#ifdef SECUREC_NO_STD_UNGETC #ifdef SECUREC_NO_STD_UNGETC
stream->lastChar = 0; stream->lastChar = 0;
stream->fUnGet = 0; stream->fUnGet = 0;
#endif #endif
#endif #endif
} }
#endif #endif
#ifdef SECUREC_INLINE_INIT_FILE_STREAM_FILE #ifdef SECUREC_INLINE_INIT_FILE_STREAM_FILE
/* /*
* This initialization for eliminating redundant initialization. * This initialization for eliminating redundant initialization.
* Compared with the previous version initialization 0, * Compared with the previous version initialization 0,
* the current code causes the binary size to increase by some bytes * the current code causes the binary size to increase by some bytes
*/ */
SECUREC_INLINE void SecInitFileStreamFromFile(SecFileStream *stream, SECUREC_INLINE void SecInitFileStreamFromFile(SecFileStream *stream, FILE *file)
FILE *file) { {
stream->flag = SECUREC_FILE_STREAM_FLAG; stream->flag = SECUREC_FILE_STREAM_FLAG;
stream->count = 0; stream->count = 0;
stream->cur = NULL; stream->cur = NULL;
stream->base = NULL; stream->base = NULL;
#if SECUREC_ENABLE_SCANF_FILE #if SECUREC_ENABLE_SCANF_FILE
stream->pf = file; stream->pf = file;
stream->oriFilePos = 0; stream->oriFilePos = 0;
stream->fileRealRead = 0; stream->fileRealRead = 0;
#ifdef SECUREC_NO_STD_UNGETC #ifdef SECUREC_NO_STD_UNGETC
stream->lastChar = 0; stream->lastChar = 0;
stream->fUnGet = 0; stream->fUnGet = 0;
#endif #endif
#endif #endif
} }
@@ -119,32 +120,26 @@ SECUREC_INLINE void SecInitFileStreamFromFile(SecFileStream *stream,
extern "C" { extern "C" {
#endif #endif
extern int SecInputS(SecFileStream *stream, const char *cFormat, extern int SecInputS(SecFileStream *stream, const char *cFormat, va_list argList);
va_list argList); extern void SecClearDestBuf(const char *buffer, const char *format, va_list argList);
extern void SecClearDestBuf(const char *buffer, const char *format,
va_list argList);
#if SECUREC_IN_KERNEL == 0 #if SECUREC_IN_KERNEL == 0
extern int SecInputSW(SecFileStream *stream, const wchar_t *cFormat, extern int SecInputSW(SecFileStream *stream, const wchar_t *cFormat, va_list argList);
va_list argList); extern void SecClearDestBufW(const wchar_t *buffer, const wchar_t *format, va_list argList);
extern void SecClearDestBufW(const wchar_t *buffer, const wchar_t *format,
va_list argList);
#endif #endif
/* 20150105 For software and hardware decoupling,such as UMG */ /* 20150105 For software and hardware decoupling,such as UMG */
#if defined(SECUREC_SYSAPI4VXWORKS) #if defined(SECUREC_SYSAPI4VXWORKS)
#ifdef feof #ifdef feof
#undef feof #undef feof
#endif #endif
extern int feof(FILE *stream); extern int feof(FILE *stream);
#endif #endif
#if defined(SECUREC_SYSAPI4VXWORKS) || defined(SECUREC_CTYPE_MACRO_ADAPT) #if defined(SECUREC_SYSAPI4VXWORKS) || defined(SECUREC_CTYPE_MACRO_ADAPT)
#ifndef isspace #ifndef isspace
#define isspace(c) \ #define isspace(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) == '\n'))
(((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) == '\n'))
#endif #endif
#ifndef iswspace #ifndef iswspace
#define iswspace(c) \ #define iswspace(c) (((c) == L' ') || ((c) == L'\t') || ((c) == L'\r') || ((c) == L'\n'))
(((c) == L' ') || ((c) == L'\t') || ((c) == L'\r') || ((c) == L'\n'))
#endif #endif
#ifndef isascii #ifndef isascii
#define isascii(c) (((unsigned char)(c)) <= 0x7f) #define isascii(c) (((unsigned char)(c)) <= 0x7f)
@@ -181,3 +176,5 @@ extern int feof(FILE *stream);
#define SECUREC_LOCK_STDIN(i, s) #define SECUREC_LOCK_STDIN(i, s)
#define SECUREC_UNLOCK_STDIN(i, s) #define SECUREC_UNLOCK_STDIN(i, s)
#endif #endif
File diff suppressed because it is too large Load Diff
@@ -1,14 +1,13 @@
/* /*
* Copyright (c) Huawei Technologies Co., Ltd. 2014-2018. All rights reserved. * Copyright (c) Huawei Technologies Co., Ltd. 2014-2018. All rights reserved.
* Description: Define internal used macro and data type. The marco of * Description: Define internal used macro and data type. The marco of SECUREC_ON_64BITS
* SECUREC_ON_64BITS will be determined in this header file, which is a switch * will be determined in this header file, which is a switch for part
* for part of code. Some macro are used to supress warning by MS compiler. * of code. Some macro are used to supress warning by MS compiler.
* Author: lishunda * Author: lishunda
* Create: 2014-02-25 * Create: 2014-02-25
* Notes: User can change the value of SECUREC_STRING_MAX_LEN and * Notes: User can change the value of SECUREC_STRING_MAX_LEN and SECUREC_MEM_MAX_LEN
* SECUREC_MEM_MAX_LEN macro to meet their special need, but The maximum value * macro to meet their special need, but The maximum value should not exceed 2G.
* should not exceed 2G. History: 2018-09-27 zhaozhijian Code base quality * History: 2018-09-27 zhaozhijian Code base quality improvement
* improvement
*/ */
/* /*
* [Standardize-exceptions]: Performance-sensitive * [Standardize-exceptions]: Performance-sensitive
@@ -21,32 +20,31 @@
#ifndef SECUREC_USING_STD_SECURE_LIB #ifndef SECUREC_USING_STD_SECURE_LIB
#if defined(_MSC_VER) && _MSC_VER >= 1400 #if defined(_MSC_VER) && _MSC_VER >= 1400
#if defined(__STDC_WANT_SECURE_LIB__) && __STDC_WANT_SECURE_LIB__ == 0 #if defined(__STDC_WANT_SECURE_LIB__) && __STDC_WANT_SECURE_LIB__ == 0
/* Security functions have been provided since vs2005, default use of system /* Security functions have been provided since vs2005, default use of system library functions */
* library functions */ #define SECUREC_USING_STD_SECURE_LIB 0
#define SECUREC_USING_STD_SECURE_LIB 0
#else #else
#define SECUREC_USING_STD_SECURE_LIB 1 #define SECUREC_USING_STD_SECURE_LIB 1
#endif #endif
#else #else
#define SECUREC_USING_STD_SECURE_LIB 0 #define SECUREC_USING_STD_SECURE_LIB 0
#endif #endif
#endif #endif
/* Compatibility with older Secure C versions, shielding VC symbol redefinition
* warning */ /* Compatibility with older Secure C versions, shielding VC symbol redefinition warning */
#if defined(_MSC_VER) && _MSC_VER >= 1400 && SECUREC_USING_STD_SECURE_LIB == 0 #if defined(_MSC_VER) && _MSC_VER >= 1400 && SECUREC_USING_STD_SECURE_LIB == 0
#ifndef SECUREC_DISABLE_CRT_FUNC #ifndef SECUREC_DISABLE_CRT_FUNC
#define SECUREC_DISABLE_CRT_FUNC 1 #define SECUREC_DISABLE_CRT_FUNC 1
#endif #endif
#ifndef SECUREC_DISABLE_CRT_IMP #ifndef SECUREC_DISABLE_CRT_IMP
#define SECUREC_DISABLE_CRT_IMP 1 #define SECUREC_DISABLE_CRT_IMP 1
#endif #endif
#else /* MSC VER */ #else /* MSC VER */
#ifndef SECUREC_DISABLE_CRT_FUNC #ifndef SECUREC_DISABLE_CRT_FUNC
#define SECUREC_DISABLE_CRT_FUNC 0 #define SECUREC_DISABLE_CRT_FUNC 0
#endif #endif
#ifndef SECUREC_DISABLE_CRT_IMP #ifndef SECUREC_DISABLE_CRT_IMP
#define SECUREC_DISABLE_CRT_IMP 0 #define SECUREC_DISABLE_CRT_IMP 0
#endif #endif
#endif #endif
@@ -54,233 +52,232 @@
#ifdef __STDC_WANT_SECURE_LIB__ #ifdef __STDC_WANT_SECURE_LIB__
#undef __STDC_WANT_SECURE_LIB__ #undef __STDC_WANT_SECURE_LIB__
#endif #endif
#define __STDC_WANT_SECURE_LIB__ 0 #define __STDC_WANT_SECURE_LIB__ 0
#endif #endif
#if SECUREC_DISABLE_CRT_IMP #if SECUREC_DISABLE_CRT_IMP
#ifdef _CRTIMP_ALTERNATIVE #ifdef _CRTIMP_ALTERNATIVE
#undef _CRTIMP_ALTERNATIVE #undef _CRTIMP_ALTERNATIVE
#endif #endif
#define _CRTIMP_ALTERNATIVE /* Comment microsoft *_s function */ #define _CRTIMP_ALTERNATIVE /* Comment microsoft *_s function */
#endif #endif
/* Compile in kernel under macro control */ /* Compile in kernel under macro control */
#ifndef SECUREC_IN_KERNEL #ifndef SECUREC_IN_KERNEL
#ifdef __KERNEL__ #ifdef __KERNEL__
#define SECUREC_IN_KERNEL 1 #define SECUREC_IN_KERNEL 1
#else #else
#define SECUREC_IN_KERNEL 0 #define SECUREC_IN_KERNEL 0
#endif #endif
#endif #endif
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
#ifndef SECUREC_ENABLE_SCANF_FILE #ifndef SECUREC_ENABLE_SCANF_FILE
#define SECUREC_ENABLE_SCANF_FILE 0 #define SECUREC_ENABLE_SCANF_FILE 0
#endif #endif
#ifndef SECUREC_ENABLE_WCHAR_FUNC #ifndef SECUREC_ENABLE_WCHAR_FUNC
#define SECUREC_ENABLE_WCHAR_FUNC 0 #define SECUREC_ENABLE_WCHAR_FUNC 0
#endif #endif
#else /* SECUREC_IN_KERNEL */ #else /* SECUREC_IN_KERNEL */
#ifndef SECUREC_ENABLE_SCANF_FILE #ifndef SECUREC_ENABLE_SCANF_FILE
#define SECUREC_ENABLE_SCANF_FILE 1 #define SECUREC_ENABLE_SCANF_FILE 1
#endif #endif
#ifndef SECUREC_ENABLE_WCHAR_FUNC #ifndef SECUREC_ENABLE_WCHAR_FUNC
#define SECUREC_ENABLE_WCHAR_FUNC 1 #define SECUREC_ENABLE_WCHAR_FUNC 1
#endif #endif
#endif #endif
/* Default secure function declaration, default declarations for non-standard
* functions */ /* Default secure function declaration, default declarations for non-standard functions */
#ifndef SECUREC_SNPRINTF_TRUNCATED #ifndef SECUREC_SNPRINTF_TRUNCATED
#define SECUREC_SNPRINTF_TRUNCATED 1 #define SECUREC_SNPRINTF_TRUNCATED 1
#endif #endif
#if SECUREC_USING_STD_SECURE_LIB #if SECUREC_USING_STD_SECURE_LIB
#if defined(_MSC_VER) && _MSC_VER >= 1400 #if defined(_MSC_VER) && _MSC_VER >= 1400
/* Declare secure functions that are not available in the VS compiler */ /* Declare secure functions that are not available in the VS compiler */
#ifndef SECUREC_ENABLE_MEMSET #ifndef SECUREC_ENABLE_MEMSET
#define SECUREC_ENABLE_MEMSET 1 #define SECUREC_ENABLE_MEMSET 1
#endif #endif
/* VS 2005 have vsnprintf_s function */ /* VS 2005 have vsnprintf_s function */
#ifndef SECUREC_ENABLE_VSNPRINTF #ifndef SECUREC_ENABLE_VSNPRINTF
#define SECUREC_ENABLE_VSNPRINTF 0 #define SECUREC_ENABLE_VSNPRINTF 0
#endif #endif
#ifndef SECUREC_ENABLE_SNPRINTF #ifndef SECUREC_ENABLE_SNPRINTF
/* VS 2005 have vsnprintf_s function Adapt the snprintf_s of the security /* VS 2005 have vsnprintf_s function Adapt the snprintf_s of the security function */
* function */
#define snprintf_s _snprintf_s #define snprintf_s _snprintf_s
#define SECUREC_ENABLE_SNPRINTF 0 #define SECUREC_ENABLE_SNPRINTF 0
#endif #endif
/* Before VS 2010 do not have v functions */ /* Before VS 2010 do not have v functions */
#if _MSC_VER <= 1600 || defined(SECUREC_FOR_V_SCANFS) #if _MSC_VER <= 1600 || defined(SECUREC_FOR_V_SCANFS)
#ifndef SECUREC_ENABLE_VFSCANF #ifndef SECUREC_ENABLE_VFSCANF
#define SECUREC_ENABLE_VFSCANF 1 #define SECUREC_ENABLE_VFSCANF 1
#endif #endif
#ifndef SECUREC_ENABLE_VSCANF #ifndef SECUREC_ENABLE_VSCANF
#define SECUREC_ENABLE_VSCANF 1 #define SECUREC_ENABLE_VSCANF 1
#endif #endif
#ifndef SECUREC_ENABLE_VSSCANF #ifndef SECUREC_ENABLE_VSSCANF
#define SECUREC_ENABLE_VSSCANF 1 #define SECUREC_ENABLE_VSSCANF 1
#endif #endif
#endif #endif
#else /* MSC VER */ #else /* MSC VER */
#ifndef SECUREC_ENABLE_MEMSET #ifndef SECUREC_ENABLE_MEMSET
#define SECUREC_ENABLE_MEMSET 0 #define SECUREC_ENABLE_MEMSET 0
#endif #endif
#ifndef SECUREC_ENABLE_SNPRINTF #ifndef SECUREC_ENABLE_SNPRINTF
#define SECUREC_ENABLE_SNPRINTF 0 #define SECUREC_ENABLE_SNPRINTF 0
#endif #endif
#ifndef SECUREC_ENABLE_VSNPRINTF #ifndef SECUREC_ENABLE_VSNPRINTF
#define SECUREC_ENABLE_VSNPRINTF 0 #define SECUREC_ENABLE_VSNPRINTF 0
#endif #endif
#endif #endif
#ifndef SECUREC_ENABLE_MEMMOVE #ifndef SECUREC_ENABLE_MEMMOVE
#define SECUREC_ENABLE_MEMMOVE 0 #define SECUREC_ENABLE_MEMMOVE 0
#endif #endif
#ifndef SECUREC_ENABLE_MEMCPY #ifndef SECUREC_ENABLE_MEMCPY
#define SECUREC_ENABLE_MEMCPY 0 #define SECUREC_ENABLE_MEMCPY 0
#endif #endif
#ifndef SECUREC_ENABLE_STRCPY #ifndef SECUREC_ENABLE_STRCPY
#define SECUREC_ENABLE_STRCPY 0 #define SECUREC_ENABLE_STRCPY 0
#endif #endif
#ifndef SECUREC_ENABLE_STRNCPY #ifndef SECUREC_ENABLE_STRNCPY
#define SECUREC_ENABLE_STRNCPY 0 #define SECUREC_ENABLE_STRNCPY 0
#endif #endif
#ifndef SECUREC_ENABLE_STRCAT #ifndef SECUREC_ENABLE_STRCAT
#define SECUREC_ENABLE_STRCAT 0 #define SECUREC_ENABLE_STRCAT 0
#endif #endif
#ifndef SECUREC_ENABLE_STRNCAT #ifndef SECUREC_ENABLE_STRNCAT
#define SECUREC_ENABLE_STRNCAT 0 #define SECUREC_ENABLE_STRNCAT 0
#endif #endif
#ifndef SECUREC_ENABLE_SPRINTF #ifndef SECUREC_ENABLE_SPRINTF
#define SECUREC_ENABLE_SPRINTF 0 #define SECUREC_ENABLE_SPRINTF 0
#endif #endif
#ifndef SECUREC_ENABLE_VSPRINTF #ifndef SECUREC_ENABLE_VSPRINTF
#define SECUREC_ENABLE_VSPRINTF 0 #define SECUREC_ENABLE_VSPRINTF 0
#endif #endif
#ifndef SECUREC_ENABLE_SSCANF #ifndef SECUREC_ENABLE_SSCANF
#define SECUREC_ENABLE_SSCANF 0 #define SECUREC_ENABLE_SSCANF 0
#endif #endif
#ifndef SECUREC_ENABLE_VSSCANF #ifndef SECUREC_ENABLE_VSSCANF
#define SECUREC_ENABLE_VSSCANF 0 #define SECUREC_ENABLE_VSSCANF 0
#endif #endif
#ifndef SECUREC_ENABLE_SCANF #ifndef SECUREC_ENABLE_SCANF
#define SECUREC_ENABLE_SCANF 0 #define SECUREC_ENABLE_SCANF 0
#endif #endif
#ifndef SECUREC_ENABLE_VSCANF #ifndef SECUREC_ENABLE_VSCANF
#define SECUREC_ENABLE_VSCANF 0 #define SECUREC_ENABLE_VSCANF 0
#endif #endif
#ifndef SECUREC_ENABLE_FSCANF #ifndef SECUREC_ENABLE_FSCANF
#define SECUREC_ENABLE_FSCANF 0 #define SECUREC_ENABLE_FSCANF 0
#endif #endif
#ifndef SECUREC_ENABLE_VFSCANF #ifndef SECUREC_ENABLE_VFSCANF
#define SECUREC_ENABLE_VFSCANF 0 #define SECUREC_ENABLE_VFSCANF 0
#endif #endif
#ifndef SECUREC_ENABLE_STRTOK #ifndef SECUREC_ENABLE_STRTOK
#define SECUREC_ENABLE_STRTOK 0 #define SECUREC_ENABLE_STRTOK 0
#endif #endif
#ifndef SECUREC_ENABLE_GETS #ifndef SECUREC_ENABLE_GETS
#define SECUREC_ENABLE_GETS 0 #define SECUREC_ENABLE_GETS 0
#endif #endif
#else /* SECUREC USE STD SECURE LIB */ #else /* SECUREC USE STD SECURE LIB */
#ifndef SECUREC_ENABLE_MEMSET #ifndef SECUREC_ENABLE_MEMSET
#define SECUREC_ENABLE_MEMSET 1 #define SECUREC_ENABLE_MEMSET 1
#endif #endif
#ifndef SECUREC_ENABLE_MEMMOVE #ifndef SECUREC_ENABLE_MEMMOVE
#define SECUREC_ENABLE_MEMMOVE 1 #define SECUREC_ENABLE_MEMMOVE 1
#endif #endif
#ifndef SECUREC_ENABLE_MEMCPY #ifndef SECUREC_ENABLE_MEMCPY
#define SECUREC_ENABLE_MEMCPY 1 #define SECUREC_ENABLE_MEMCPY 1
#endif #endif
#ifndef SECUREC_ENABLE_STRCPY #ifndef SECUREC_ENABLE_STRCPY
#define SECUREC_ENABLE_STRCPY 1 #define SECUREC_ENABLE_STRCPY 1
#endif #endif
#ifndef SECUREC_ENABLE_STRNCPY #ifndef SECUREC_ENABLE_STRNCPY
#define SECUREC_ENABLE_STRNCPY 1 #define SECUREC_ENABLE_STRNCPY 1
#endif #endif
#ifndef SECUREC_ENABLE_STRCAT #ifndef SECUREC_ENABLE_STRCAT
#define SECUREC_ENABLE_STRCAT 1 #define SECUREC_ENABLE_STRCAT 1
#endif #endif
#ifndef SECUREC_ENABLE_STRNCAT #ifndef SECUREC_ENABLE_STRNCAT
#define SECUREC_ENABLE_STRNCAT 1 #define SECUREC_ENABLE_STRNCAT 1
#endif #endif
#ifndef SECUREC_ENABLE_SPRINTF #ifndef SECUREC_ENABLE_SPRINTF
#define SECUREC_ENABLE_SPRINTF 1 #define SECUREC_ENABLE_SPRINTF 1
#endif #endif
#ifndef SECUREC_ENABLE_VSPRINTF #ifndef SECUREC_ENABLE_VSPRINTF
#define SECUREC_ENABLE_VSPRINTF 1 #define SECUREC_ENABLE_VSPRINTF 1
#endif #endif
#ifndef SECUREC_ENABLE_SNPRINTF #ifndef SECUREC_ENABLE_SNPRINTF
#define SECUREC_ENABLE_SNPRINTF 1 #define SECUREC_ENABLE_SNPRINTF 1
#endif #endif
#ifndef SECUREC_ENABLE_VSNPRINTF #ifndef SECUREC_ENABLE_VSNPRINTF
#define SECUREC_ENABLE_VSNPRINTF 1 #define SECUREC_ENABLE_VSNPRINTF 1
#endif #endif
#ifndef SECUREC_ENABLE_SSCANF #ifndef SECUREC_ENABLE_SSCANF
#define SECUREC_ENABLE_SSCANF 1 #define SECUREC_ENABLE_SSCANF 1
#endif #endif
#ifndef SECUREC_ENABLE_VSSCANF #ifndef SECUREC_ENABLE_VSSCANF
#define SECUREC_ENABLE_VSSCANF 1 #define SECUREC_ENABLE_VSSCANF 1
#endif #endif
#ifndef SECUREC_ENABLE_SCANF #ifndef SECUREC_ENABLE_SCANF
#if SECUREC_ENABLE_SCANF_FILE #if SECUREC_ENABLE_SCANF_FILE
#define SECUREC_ENABLE_SCANF 1 #define SECUREC_ENABLE_SCANF 1
#else #else
#define SECUREC_ENABLE_SCANF 0 #define SECUREC_ENABLE_SCANF 0
#endif #endif
#endif #endif
#ifndef SECUREC_ENABLE_VSCANF #ifndef SECUREC_ENABLE_VSCANF
#if SECUREC_ENABLE_SCANF_FILE #if SECUREC_ENABLE_SCANF_FILE
#define SECUREC_ENABLE_VSCANF 1 #define SECUREC_ENABLE_VSCANF 1
#else #else
#define SECUREC_ENABLE_VSCANF 0 #define SECUREC_ENABLE_VSCANF 0
#endif #endif
#endif #endif
#ifndef SECUREC_ENABLE_FSCANF #ifndef SECUREC_ENABLE_FSCANF
#if SECUREC_ENABLE_SCANF_FILE #if SECUREC_ENABLE_SCANF_FILE
#define SECUREC_ENABLE_FSCANF 1 #define SECUREC_ENABLE_FSCANF 1
#else #else
#define SECUREC_ENABLE_FSCANF 0 #define SECUREC_ENABLE_FSCANF 0
#endif #endif
#endif #endif
#ifndef SECUREC_ENABLE_VFSCANF #ifndef SECUREC_ENABLE_VFSCANF
#if SECUREC_ENABLE_SCANF_FILE #if SECUREC_ENABLE_SCANF_FILE
#define SECUREC_ENABLE_VFSCANF 1 #define SECUREC_ENABLE_VFSCANF 1
#else #else
#define SECUREC_ENABLE_VFSCANF 0 #define SECUREC_ENABLE_VFSCANF 0
#endif #endif
#endif #endif
#ifndef SECUREC_ENABLE_STRTOK #ifndef SECUREC_ENABLE_STRTOK
#define SECUREC_ENABLE_STRTOK 1 #define SECUREC_ENABLE_STRTOK 1
#endif #endif
#ifndef SECUREC_ENABLE_GETS #ifndef SECUREC_ENABLE_GETS
#define SECUREC_ENABLE_GETS 1 #define SECUREC_ENABLE_GETS 1
#endif #endif
#endif /* SECUREC_USE_STD_SECURE_LIB */ #endif /* SECUREC_USE_STD_SECURE_LIB */
#if SECUREC_ENABLE_SCANF_FILE == 0 #if SECUREC_ENABLE_SCANF_FILE == 0
#if SECUREC_ENABLE_FSCANF #if SECUREC_ENABLE_FSCANF
#undef SECUREC_ENABLE_FSCANF #undef SECUREC_ENABLE_FSCANF
#define SECUREC_ENABLE_FSCANF 0 #define SECUREC_ENABLE_FSCANF 0
#endif #endif
#if SECUREC_ENABLE_VFSCANF #if SECUREC_ENABLE_VFSCANF
#undef SECUREC_ENABLE_VFSCANF #undef SECUREC_ENABLE_VFSCANF
#define SECUREC_ENABLE_VFSCANF 0 #define SECUREC_ENABLE_VFSCANF 0
#endif #endif
#if SECUREC_ENABLE_SCANF #if SECUREC_ENABLE_SCANF
#undef SECUREC_ENABLE_SCANF #undef SECUREC_ENABLE_SCANF
#define SECUREC_ENABLE_SCANF 0 #define SECUREC_ENABLE_SCANF 0
#endif #endif
#if SECUREC_ENABLE_FSCANF #if SECUREC_ENABLE_FSCANF
#undef SECUREC_ENABLE_FSCANF #undef SECUREC_ENABLE_FSCANF
#define SECUREC_ENABLE_FSCANF 0 #define SECUREC_ENABLE_FSCANF 0
#endif #endif
#endif #endif
@@ -310,9 +307,8 @@
#endif #endif
/* /*
* If you need high performance, enable the SECUREC_WITH_PERFORMANCE_ADDONS * If you need high performance, enable the SECUREC_WITH_PERFORMANCE_ADDONS macro, default is enable.
* macro, default is enable. The macro is automatically closed on the windows * The macro is automatically closed on the windows platform and linux kernel
* platform and linux kernel
*/ */
#ifndef SECUREC_WITH_PERFORMANCE_ADDONS #ifndef SECUREC_WITH_PERFORMANCE_ADDONS
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
@@ -322,18 +318,15 @@
#endif #endif
#endif #endif
/* If enable SECUREC_COMPATIBLE_WIN_FORMAT, the output format will be compatible /* If enable SECUREC_COMPATIBLE_WIN_FORMAT, the output format will be compatible to Windows. */
* to Windows. */ #if (defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)) && !defined(SECUREC_COMPATIBLE_LINUX_FORMAT)
#if (defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)) && \
!defined(SECUREC_COMPATIBLE_LINUX_FORMAT)
#ifndef SECUREC_COMPATIBLE_WIN_FORMAT #ifndef SECUREC_COMPATIBLE_WIN_FORMAT
#define SECUREC_COMPATIBLE_WIN_FORMAT #define SECUREC_COMPATIBLE_WIN_FORMAT
#endif #endif
#endif #endif
#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) #if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
/* On windows platform, can't use optimized function for there is no /* On windows platform, can't use optimized function for there is no __builtin_constant_p like function */
* __builtin_constant_p like function */
/* If need optimized macro, can define this: define __builtin_constant_p(x) 0 */ /* If need optimized macro, can define this: define __builtin_constant_p(x) 0 */
#ifdef SECUREC_WITH_PERFORMANCE_ADDONS #ifdef SECUREC_WITH_PERFORMANCE_ADDONS
#undef SECUREC_WITH_PERFORMANCE_ADDONS #undef SECUREC_WITH_PERFORMANCE_ADDONS
@@ -341,17 +334,15 @@
#endif #endif
#endif #endif
#if defined(__VXWORKS__) || defined(__vxworks) || defined(__VXWORKS) || \ #if defined(__VXWORKS__) || defined(__vxworks) || defined(__VXWORKS) || defined(_VXWORKS_PLATFORM_) || \
defined(_VXWORKS_PLATFORM_) || defined(SECUREC_VXWORKS_VERSION_5_4) defined(SECUREC_VXWORKS_VERSION_5_4)
#ifndef SECUREC_VXWORKS_PLATFORM #ifndef SECUREC_VXWORKS_PLATFORM
#define SECUREC_VXWORKS_PLATFORM #define SECUREC_VXWORKS_PLATFORM
#endif #endif
#endif #endif
/* If enable SECUREC_COMPATIBLE_LINUX_FORMAT, the output format will be /* If enable SECUREC_COMPATIBLE_LINUX_FORMAT, the output format will be compatible to Linux. */
* compatible to Linux. */ #if !defined(SECUREC_COMPATIBLE_WIN_FORMAT) && !defined(SECUREC_VXWORKS_PLATFORM)
#if !defined(SECUREC_COMPATIBLE_WIN_FORMAT) && \
!defined(SECUREC_VXWORKS_PLATFORM)
#ifndef SECUREC_COMPATIBLE_LINUX_FORMAT #ifndef SECUREC_COMPATIBLE_LINUX_FORMAT
#define SECUREC_COMPATIBLE_LINUX_FORMAT #define SECUREC_COMPATIBLE_LINUX_FORMAT
#endif #endif
@@ -368,10 +359,9 @@
#endif #endif
/* /*
* Add the -DSECUREC_SUPPORT_FORMAT_WARNING compiler option to supoort * Add the -DSECUREC_SUPPORT_FORMAT_WARNING compiler option to supoort -Wformat.
* -Wformat. Default does not check the format is that the same data type in the * Default does not check the format is that the same data type in the actual code.
* actual code. In the product is different in the original data type definition * In the product is different in the original data type definition of VxWorks and Linux.
* of VxWorks and Linux.
*/ */
#ifndef SECUREC_SUPPORT_FORMAT_WARNING #ifndef SECUREC_SUPPORT_FORMAT_WARNING
#define SECUREC_SUPPORT_FORMAT_WARNING 0 #define SECUREC_SUPPORT_FORMAT_WARNING 0
@@ -379,19 +369,18 @@
/* SECUREC_PCLINT for tool do not recognize __attribute__ just for pclint */ /* SECUREC_PCLINT for tool do not recognize __attribute__ just for pclint */
#if SECUREC_SUPPORT_FORMAT_WARNING && !defined(SECUREC_PCLINT) #if SECUREC_SUPPORT_FORMAT_WARNING && !defined(SECUREC_PCLINT)
#define SECUREC_ATTRIBUTE(x, y) __attribute__((format(printf, (x), (y)))) #define SECUREC_ATTRIBUTE(x, y) __attribute__((format(printf, (x), (y))))
#else #else
#define SECUREC_ATTRIBUTE(x, y) #define SECUREC_ATTRIBUTE(x, y)
#endif #endif
/* SECUREC_PCLINT for tool do not recognize __builtin_expect, just for pclint */ /* SECUREC_PCLINT for tool do not recognize __builtin_expect, just for pclint */
#if defined(__GNUC__) && \ #if defined(__GNUC__) && \
((__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3))) && \ ((__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3))) && \
!defined(SECUREC_PCLINT) !defined(SECUREC_PCLINT)
/* /*
* This is a built-in function that can be used without a declaration, if you * This is a built-in function that can be used without a declaration, if you encounter an undeclared compilation alarm,
* encounter an undeclared compilation alarm, you can add * you can add -DSECUREC_NEED_BUILTIN_EXPECT_DECLARE to complier options
* -DSECUREC_NEED_BUILTIN_EXPECT_DECLARE to complier options
*/ */
#ifdef SECUREC_NEED_BUILTIN_EXPECT_DECLARE #ifdef SECUREC_NEED_BUILTIN_EXPECT_DECLARE
long __builtin_expect(long exp, long c); long __builtin_expect(long exp, long c);
@@ -429,8 +418,7 @@ long __builtin_expect(long exp, long c);
#define SECUREC_ON_64BITS #define SECUREC_ON_64BITS
#endif #endif
#if (!defined(SECUREC_ON_64BITS) && defined(__GNUC__) && \ #if (!defined(SECUREC_ON_64BITS) && defined(__GNUC__) && defined(__SIZEOF_POINTER__))
defined(__SIZEOF_POINTER__))
#if __SIZEOF_POINTER__ == 8 #if __SIZEOF_POINTER__ == 8
#define SECUREC_ON_64BITS #define SECUREC_ON_64BITS
#endif #endif
@@ -445,30 +433,31 @@ long __builtin_expect(long exp, long c);
#endif #endif
/* /*
* Codes should run under the macro SECUREC_COMPATIBLE_LINUX_FORMAT in unknow * Codes should run under the macro SECUREC_COMPATIBLE_LINUX_FORMAT in unknow system on default,
* system on default, and strtold. The function strtold is referenced first at * and strtold.
* ISO9899:1999(C99), and some old compilers can not support these functions. * The function strtold is referenced first at ISO9899:1999(C99), and some old compilers can
* Here provides a macro to open these functions: SECUREC_SUPPORT_STRTOLD -- If * not support these functions. Here provides a macro to open these functions:
* defined, strtold will be used * SECUREC_SUPPORT_STRTOLD -- If defined, strtold will be used
*/ */
#ifndef SECUREC_SUPPORT_STRTOLD #ifndef SECUREC_SUPPORT_STRTOLD
#define SECUREC_SUPPORT_STRTOLD 0 #define SECUREC_SUPPORT_STRTOLD 0
#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT))
#if defined(__USE_ISOC99) || (defined(_AIX) && defined(_ISOC99_SOURCE)) || \ #if defined(__USE_ISOC99) || \
(defined(__hpux) && defined(__ia64)) || \ (defined(_AIX) && defined(_ISOC99_SOURCE)) || \
(defined(SECUREC_ON_SOLARIS) && \ (defined(__hpux) && defined(__ia64)) || \
(!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \ (defined(SECUREC_ON_SOLARIS) && (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \
defined(_STDC_C99) || defined(__EXTENSIONS__)) defined(_STDC_C99) || defined(__EXTENSIONS__))
#undef SECUREC_SUPPORT_STRTOLD #undef SECUREC_SUPPORT_STRTOLD
#define SECUREC_SUPPORT_STRTOLD 1 #define SECUREC_SUPPORT_STRTOLD 1
#endif #endif
#endif #endif
#if ((defined(SECUREC_WRLINUX_BELOW4) || defined(_WRLINUX_BELOW4_))) #if ((defined(SECUREC_WRLINUX_BELOW4) || defined(_WRLINUX_BELOW4_)))
#undef SECUREC_SUPPORT_STRTOLD #undef SECUREC_SUPPORT_STRTOLD
#define SECUREC_SUPPORT_STRTOLD 0 #define SECUREC_SUPPORT_STRTOLD 0
#endif #endif
#endif #endif
#if SECUREC_WITH_PERFORMANCE_ADDONS #if SECUREC_WITH_PERFORMANCE_ADDONS
#ifndef SECUREC_TWO_MIN #ifndef SECUREC_TWO_MIN
@@ -476,121 +465,102 @@ long __builtin_expect(long exp, long c);
#endif #endif
/* For strncpy_s performance optimization */ /* For strncpy_s performance optimization */
#define SECUREC_STRNCPY_SM(dest, destMax, src, count) \ #define SECUREC_STRNCPY_SM(dest, destMax, src, count) \
(((void *)(dest) != NULL && (void *)(src) != NULL && \ (((void *)(dest) != NULL && (void *)(src) != NULL && (size_t)(destMax) > 0 && \
(size_t)(destMax) > 0 && \ (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \
(((unsigned long long)(destMax) & (unsigned long long)(-2)) < \ (SECUREC_TWO_MIN((size_t)(count), strlen(src)) + 1) <= (size_t)(destMax)) ? \
SECUREC_STRING_MAX_LEN) && \ (((size_t)(count) < strlen(src)) ? (memcpy((dest), (src), (count)), *((char *)(dest) + (count)) = '\0', EOK) : \
(SECUREC_TWO_MIN((size_t)(count), strlen(src)) + 1) <= (size_t)(destMax)) \ (memcpy((dest), (src), strlen(src) + 1), EOK)) : (strncpy_error((dest), (destMax), (src), (count))))
? (((size_t)(count) < strlen(src)) \
? (memcpy((dest), (src), (count)), \
*((char *)(dest) + (count)) = '\0', EOK) \
: (memcpy((dest), (src), strlen(src) + 1), EOK)) \
: (strncpy_error((dest), (destMax), (src), (count))))
#define SECUREC_STRCPY_SM(dest, destMax, src) \ #define SECUREC_STRCPY_SM(dest, destMax, src) \
(((void *)(dest) != NULL && (void *)(src) != NULL && \ (((void *)(dest) != NULL && (void *)(src) != NULL && (size_t)(destMax) > 0 && \
(size_t)(destMax) > 0 && \ (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \
(((unsigned long long)(destMax) & (unsigned long long)(-2)) < \ (strlen(src) + 1) <= (size_t)(destMax)) ? (memcpy((dest), (src), strlen(src) + 1), EOK) : \
SECUREC_STRING_MAX_LEN) && \ (strcpy_error((dest), (destMax), (src))))
(strlen(src) + 1) <= (size_t)(destMax)) \
? (memcpy((dest), (src), strlen(src) + 1), EOK) \
: (strcpy_error((dest), (destMax), (src))))
/* For strcat_s performance optimization */ /* For strcat_s performance optimization */
#if defined(__GNUC__) #if defined(__GNUC__)
#define SECUREC_STRCAT_SM(dest, destMax, src) \ #define SECUREC_STRCAT_SM(dest, destMax, src) ({ \
({ \ int catRet = EOK; \
int catRet = EOK; \ if ((void *)(dest) != NULL && (void *)(src) != NULL && (size_t)(destMax) > 0 && \
if ((void *)(dest) != NULL && (void *)(src) != NULL && \ (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN)) { \
(size_t)(destMax) > 0 && \ char *catTmpDst = (char *)(dest); \
(((unsigned long long)(destMax) & (unsigned long long)(-2)) < \ size_t catRestSize = (destMax); \
SECUREC_STRING_MAX_LEN)) { \ while (catRestSize > 0 && *catTmpDst != '\0') { \
char *catTmpDst = (char *)(dest); \ ++catTmpDst; \
size_t catRestSize = (destMax); \ --catRestSize; \
while (catRestSize > 0 && *catTmpDst != '\0') { \ } \
++catTmpDst; \ if (catRestSize == 0) { \
--catRestSize; \ catRet = EINVAL; \
} \ } else if ((strlen(src) + 1) <= catRestSize) { \
if (catRestSize == 0) { \ memcpy(catTmpDst, (src), strlen(src) + 1); \
catRet = EINVAL; \ catRet = EOK; \
} else if ((strlen(src) + 1) <= catRestSize) { \ } else { \
memcpy(catTmpDst, (src), strlen(src) + 1); \ catRet = ERANGE; \
catRet = EOK; \ } \
} else { \ if (catRet != EOK) { \
catRet = ERANGE; \ catRet = strcat_s((dest), (destMax), (src)); \
} \ } \
if (catRet != EOK) { \ } else { \
catRet = strcat_s((dest), (destMax), (src)); \ catRet = strcat_s((dest), (destMax), (src)); \
} \ } \
} else { \ catRet; \
catRet = strcat_s((dest), (destMax), (src)); \ })
} \
catRet; \
})
#else #else
#define SECUREC_STRCAT_SM(dest, destMax, src) strcat_s((dest), (destMax), (src)) #define SECUREC_STRCAT_SM(dest, destMax, src) strcat_s((dest), (destMax), (src))
#endif #endif
/* For strncat_s performance optimization */ /* For strncat_s performance optimization */
#if defined(__GNUC__) #if defined(__GNUC__)
#define SECUREC_STRNCAT_SM(dest, destMax, src, count) \ #define SECUREC_STRNCAT_SM(dest, destMax, src, count) ({ \
({ \ int ncatRet = EOK; \
int ncatRet = EOK; \ if ((void *)(dest) != NULL && (void *)(src) != NULL && (size_t)(destMax) > 0 && \
if ((void *)(dest) != NULL && (void *)(src) != NULL && \ (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \
(size_t)(destMax) > 0 && \ (((unsigned long long)(count) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN)) { \
(((unsigned long long)(destMax) & (unsigned long long)(-2)) < \ char *ncatTmpDest = (char *)(dest); \
SECUREC_STRING_MAX_LEN) && \ size_t ncatRestSize = (size_t)(destMax); \
(((unsigned long long)(count) & (unsigned long long)(-2)) < \ while (ncatRestSize > 0 && *ncatTmpDest != '\0') { \
SECUREC_STRING_MAX_LEN)) { \ ++ncatTmpDest; \
char *ncatTmpDest = (char *)(dest); \ --ncatRestSize; \
size_t ncatRestSize = (size_t)(destMax); \ } \
while (ncatRestSize > 0 && *ncatTmpDest != '\0') { \ if (ncatRestSize == 0) { \
++ncatTmpDest; \ ncatRet = EINVAL; \
--ncatRestSize; \ } else if ((SECUREC_TWO_MIN((count), strlen(src)) + 1) <= ncatRestSize) { \
} \ if ((size_t)(count) < strlen(src)) { \
if (ncatRestSize == 0) { \ memcpy(ncatTmpDest, (src), (count)); \
ncatRet = EINVAL; \ *(ncatTmpDest + (count)) = '\0'; \
} else if ((SECUREC_TWO_MIN((count), strlen(src)) + 1) <= \ } else { \
ncatRestSize) { \ memcpy(ncatTmpDest, (src), strlen(src) + 1); \
if ((size_t)(count) < strlen(src)) { \ } \
memcpy(ncatTmpDest, (src), (count)); \ } else { \
*(ncatTmpDest + (count)) = '\0'; \ ncatRet = ERANGE; \
} else { \ } \
memcpy(ncatTmpDest, (src), strlen(src) + 1); \ if (ncatRet != EOK) { \
} \ ncatRet = strncat_s((dest), (destMax), (src), (count)); \
} else { \ } \
ncatRet = ERANGE; \ } else { \
} \ ncatRet = strncat_s((dest), (destMax), (src), (count)); \
if (ncatRet != EOK) { \ } \
ncatRet = strncat_s((dest), (destMax), (src), (count)); \ ncatRet; \
} \ })
} else { \
ncatRet = strncat_s((dest), (destMax), (src), (count)); \
} \
ncatRet; \
})
#else #else
#define SECUREC_STRNCAT_SM(dest, destMax, src, count) \ #define SECUREC_STRNCAT_SM(dest, destMax, src, count) strncat_s((dest), (destMax), (src), (count))
strncat_s((dest), (destMax), (src), (count))
#endif #endif
/* This macro do not check buffer overlap by default */ /* This macro do not check buffer overlap by default */
#define SECUREC_MEMCPY_SM(dest, destMax, src, count) \ #define SECUREC_MEMCPY_SM(dest, destMax, src, count) \
(!(((size_t)(destMax) == 0) || \ (!(((size_t)(destMax) == 0) || \
(((unsigned long long)(destMax) & (unsigned long long)(-2)) > \ (((unsigned long long)(destMax) & (unsigned long long)(-2)) > SECUREC_MEM_MAX_LEN) || \
SECUREC_MEM_MAX_LEN) || \ ((size_t)(count) > (size_t)(destMax)) || ((void *)(dest)) == NULL || ((void *)(src) == NULL)) ? \
((size_t)(count) > (size_t)(destMax)) || ((void *)(dest)) == NULL || \ (memcpy((dest), (src), (count)), EOK) : \
((void *)(src) == NULL)) \ (memcpy_s((dest), (destMax), (src), (count))))
? (memcpy((dest), (src), (count)), EOK) \
: (memcpy_s((dest), (destMax), (src), (count))))
#define SECUREC_MEMSET_SM(dest, destMax, c, count) \ #define SECUREC_MEMSET_SM(dest, destMax, c, count) \
(!((((unsigned long long)(destMax) & (unsigned long long)(-2)) > \ (!((((unsigned long long)(destMax) & (unsigned long long)(-2)) > SECUREC_MEM_MAX_LEN) || \
SECUREC_MEM_MAX_LEN) || \ ((void *)(dest) == NULL) || ((size_t)(count) > (size_t)(destMax))) ? \
((void *)(dest) == NULL) || ((size_t)(count) > (size_t)(destMax))) \ (memset((dest), (c), (count)), EOK) : \
? (memset((dest), (c), (count)), EOK) \ (memset_s((dest), (destMax), (c), (count))))
: (memset_s((dest), (destMax), (c), (count))))
#endif #endif
#endif /* __SECURECTYPE_H__A7BBB686_AADA_451B_B9F9_44DACDAE18A7 */ #endif /* __SECURECTYPE_H__A7BBB686_AADA_451B_B9F9_44DACDAE18A7 */
@@ -16,23 +16,27 @@
/* /*
* Convert wide characters to narrow multi-bytes * Convert wide characters to narrow multi-bytes
*/ */
int wctomb(char *s, wchar_t wc) { return wcrtomb(s, wc, NULL); } int wctomb(char *s, wchar_t wc)
{
return wcrtomb(s, wc, NULL);
}
#endif #endif
#if SECUREC_HAVE_MBTOWC #if SECUREC_HAVE_MBTOWC
/* /*
* Converting narrow multi-byte characters to wide characters * Converting narrow multi-byte characters to wide characters
*/ */
int mbtowc(wchar_t *pwc, const char *s, size_t n) { int mbtowc(wchar_t *pwc, const char *s, size_t n)
return mbrtowc(pwc, s, n, NULL); {
return mbrtowc(pwc, s, n, NULL);
} }
#endif #endif
#endif #endif
/* The V100R001C01 version num is 0x5 */ /* The V100R001C01 version num is 0x5 */
#define SECUREC_C_VERSION (0x5 << 8) #define SECUREC_C_VERSION (0x5 << 8)
#define SECUREC_SPC_VERSION 9 #define SECUREC_SPC_VERSION 9
#define SECUREC_VERSION_STR "Huawei Secure C V100R001C01SPC009B003" #define SECUREC_VERSION_STR "Huawei Secure C V100R001C01SPC009B003"
/* /*
* SPC verNumber<->verStr like: * SPC verNumber<->verStr like:
@@ -51,12 +55,14 @@ int mbtowc(wchar_t *pwc, const char *s, size_t n) {
* 0X602<->CP0002 * 0X602<->CP0002
* ... * ...
*/ */
const char *GetHwSecureCVersion(unsigned short *verNumber) { const char *GetHwSecureCVersion(unsigned short *verNumber)
if (verNumber != NULL) { {
*verNumber = (unsigned short)(SECUREC_C_VERSION | SECUREC_SPC_VERSION); if (verNumber != NULL) {
} *verNumber = (unsigned short)(SECUREC_C_VERSION | SECUREC_SPC_VERSION);
return SECUREC_VERSION_STR; }
return SECUREC_VERSION_STR;
} }
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
EXPORT_SYMBOL(GetHwSecureCVersion); EXPORT_SYMBOL(GetHwSecureCVersion);
#endif #endif
@@ -1,8 +1,9 @@
/* /*
* Copyright (c) Huawei Technologies Co., Ltd. 2014-2018. All rights reserved. * Copyright (c) Huawei Technologies Co., Ltd. 2014-2018. All rights reserved.
* Description: Define macro, data struct, and declare internal used function * Description: Define macro, data struct, and declare internal used function prototype,
* prototype, which is used by secure functions. Author: lishunda Create: * which is used by secure functions.
* 2014-02-25 * Author: lishunda
* Create: 2014-02-25
*/ */
#ifndef SECURECUTIL_H_46C86578_F8FF_4E49_8E64_9B175241761F #ifndef SECURECUTIL_H_46C86578_F8FF_4E49_8E64_9B175241761F
@@ -10,28 +11,23 @@
#include "securec.h" #include "securec.h"
#if (defined(_MSC_VER)) && (_MSC_VER >= 1400) #if (defined(_MSC_VER)) && (_MSC_VER >= 1400)
/* Shield compilation alerts using discarded functions and Constant expression /* Shield compilation alerts using discarded functions and Constant expression to maximize code compatibility */
* to maximize code compatibility */ #define SECUREC_MASK_MSVC_CRT_WARNING __pragma(warning(push)) \
#define SECUREC_MASK_MSVC_CRT_WARNING \ __pragma(warning(disable : 4996 4127))
__pragma(warning(push)) __pragma(warning(disable : 4996 4127)) #define SECUREC_END_MASK_MSVC_CRT_WARNING __pragma(warning(pop))
#define SECUREC_END_MASK_MSVC_CRT_WARNING __pragma(warning(pop))
#else #else
#define SECUREC_MASK_MSVC_CRT_WARNING #define SECUREC_MASK_MSVC_CRT_WARNING
#define SECUREC_END_MASK_MSVC_CRT_WARNING #define SECUREC_END_MASK_MSVC_CRT_WARNING
#endif #endif
#define SECUREC_WHILE_ZERO \ #define SECUREC_WHILE_ZERO SECUREC_MASK_MSVC_CRT_WARNING while (0) SECUREC_END_MASK_MSVC_CRT_WARNING
SECUREC_MASK_MSVC_CRT_WARNING while (0) SECUREC_END_MASK_MSVC_CRT_WARNING
/* Automatically identify the platform that supports strnlen function, and use /* Automatically identify the platform that supports strnlen function, and use this function to improve performance */
* this function to improve performance */
#ifndef SECUREC_HAVE_STRNLEN #ifndef SECUREC_HAVE_STRNLEN
#if (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700) || \ #if (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L)
(defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L)
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
#define SECUREC_HAVE_STRNLEN 0 #define SECUREC_HAVE_STRNLEN 0
#else #else
#if defined(__GLIBC__) && __GLIBC__ >= 2 && defined(__GLIBC_MINOR__) && \ #if defined(__GLIBC__) && __GLIBC__ >= 2 && defined(__GLIBC_MINOR__) && __GLIBC_MINOR__ >= 10
__GLIBC_MINOR__ >= 10
#define SECUREC_HAVE_STRNLEN 1 #define SECUREC_HAVE_STRNLEN 1
#else #else
#define SECUREC_HAVE_STRNLEN 0 #define SECUREC_HAVE_STRNLEN 0
@@ -109,135 +105,118 @@
#define SECUREC_STREAM_STDIN stdin #define SECUREC_STREAM_STDIN stdin
#endif #endif
#define SECUREC_INT_MAX 2147483647 #define SECUREC_INT_MAX 2147483647
#define SECUREC_MUL_SIXTEEN(x) ((x) << 4) #define SECUREC_MUL_SIXTEEN(x) ((x) << 4)
#define SECUREC_MUL_EIGHT(x) ((x) << 3) #define SECUREC_MUL_EIGHT(x) ((x) << 3)
#define SECUREC_MUL_TEN(x) ((((x) << 2) + (x)) << 1) #define SECUREC_MUL_TEN(x) ((((x) << 2) + (x)) << 1)
/* Limited format input and output width */ /* Limited format input and output width */
#define SECUREC_MAX_WIDTH_LEN_DIV_TEN 21474836 #define SECUREC_MAX_WIDTH_LEN_DIV_TEN 21474836
#define SECUREC_MAX_WIDTH_LEN SECUREC_MUL_TEN(SECUREC_MAX_WIDTH_LEN_DIV_TEN) #define SECUREC_MAX_WIDTH_LEN SECUREC_MUL_TEN(SECUREC_MAX_WIDTH_LEN_DIV_TEN)
/* Is the x multiplied by 10 greater than */ /* Is the x multiplied by 10 greater than */
#define SECUREC_MUL_TEN_ADD_BEYOND_MAX(x) \ #define SECUREC_MUL_TEN_ADD_BEYOND_MAX(x) (((x) > SECUREC_MAX_WIDTH_LEN_DIV_TEN))
(((x) > SECUREC_MAX_WIDTH_LEN_DIV_TEN))
#define SECUREC_FLOAT_BUFSIZE (309 + 40) /* Max length of double value */ #define SECUREC_FLOAT_BUFSIZE (309 + 40) /* Max length of double value */
#define SECUREC_FLOAT_BUFSIZE_LB \ #define SECUREC_FLOAT_BUFSIZE_LB (4932 + 40) /* Max length of long double value */
(4932 + 40) /* Max length of long double value */ #define SECUREC_FLOAT_DEFAULT_PRECISION 6
#define SECUREC_FLOAT_DEFAULT_PRECISION 6
/* This macro does not handle pointer equality or integer overflow */ /* This macro does not handle pointer equality or integer overflow */
#define SECUREC_MEMORY_NO_OVERLAP(dest, src, count) \ #define SECUREC_MEMORY_NO_OVERLAP(dest, src, count) \
(((src) < (dest) && ((const char *)(src) + (count)) <= (char *)(dest)) || \ (((src) < (dest) && ((const char *)(src) + (count)) <= (char *)(dest)) || \
((dest) < (src) && ((char *)(dest) + (count)) <= (const char *)(src))) ((dest) < (src) && ((char *)(dest) + (count)) <= (const char *)(src)))
#define SECUREC_MEMORY_IS_OVERLAP(dest, src, count) \ #define SECUREC_MEMORY_IS_OVERLAP(dest, src, count) \
(((src) < (dest) && ((const char *)(src) + (count)) > (char *)(dest)) || \ (((src) < (dest) && ((const char *)(src) + (count)) > (char *)(dest)) || \
((dest) < (src) && ((char *)(dest) + (count)) > (const char *)(src))) ((dest) < (src) && ((char *)(dest) + (count)) > (const char *)(src)))
/* /*
* Check whether the strings overlap, len is the length of the string not * Check whether the strings overlap, len is the length of the string not include terminator
* include terminator Length is related to data type char or wchar , do not * Length is related to data type char or wchar , do not force conversion of types
* force conversion of types
*/ */
#define SECUREC_STRING_NO_OVERLAP(dest, src, len) \ #define SECUREC_STRING_NO_OVERLAP(dest, src, len) \
(((src) < (dest) && ((src) + (len)) < (dest)) || \ (((src) < (dest) && ((src) + (len)) < (dest)) || \
((dest) < (src) && ((dest) + (len)) < (src))) ((dest) < (src) && ((dest) + (len)) < (src)))
/* /*
* Check whether the strings overlap for strcpy wcscpy function, dest len and * Check whether the strings overlap for strcpy wcscpy function, dest len and src Len are not include terminator
* src Len are not include terminator Length is related to data type char or * Length is related to data type char or wchar , do not force conversion of types
* wchar , do not force conversion of types
*/ */
#define SECUREC_STRING_IS_OVERLAP(dest, src, len) \ #define SECUREC_STRING_IS_OVERLAP(dest, src, len) \
(((src) < (dest) && ((src) + (len)) >= (dest)) || \ (((src) < (dest) && ((src) + (len)) >= (dest)) || \
((dest) < (src) && ((dest) + (len)) >= (src))) ((dest) < (src) && ((dest) + (len)) >= (src)))
/* /*
* Check whether the strings overlap for strcat wcscat function, dest len and * Check whether the strings overlap for strcat wcscat function, dest len and src Len are not include terminator
* src Len are not include terminator Length is related to data type char or * Length is related to data type char or wchar , do not force conversion of types
* wchar , do not force conversion of types
*/ */
#define SECUREC_CAT_STRING_IS_OVERLAP(dest, destLen, src, srcLen) \ #define SECUREC_CAT_STRING_IS_OVERLAP(dest, destLen, src, srcLen) \
(((dest) < (src) && ((dest) + (destLen) + (srcLen)) >= (src)) || \ (((dest) < (src) && ((dest) + (destLen) + (srcLen)) >= (src)) || \
((src) < (dest) && ((src) + (srcLen)) >= (dest))) ((src) < (dest) && ((src) + (srcLen)) >= (dest)))
#if SECUREC_HAVE_STRNLEN #if SECUREC_HAVE_STRNLEN
#define SECUREC_CALC_STR_LEN(str, maxLen, outLen) \ #define SECUREC_CALC_STR_LEN(str, maxLen, outLen) do { \
do { \ *(outLen) = strnlen((str), (maxLen)); \
*(outLen) = strnlen((str), (maxLen)); \ } SECUREC_WHILE_ZERO
} \ #define SECUREC_CALC_STR_LEN_OPT(str, maxLen, outLen) do { \
SECUREC_WHILE_ZERO if ((maxLen) > 8) { \
#define SECUREC_CALC_STR_LEN_OPT(str, maxLen, outLen) \ /* Optimization or len less then 8 */ \
do { \ if (*((str) + 0) == '\0') { \
if ((maxLen) > 8) { \ *(outLen) = 0; \
/* Optimization or len less then 8 */ \ } else if (*((str) + 1) == '\0') { \
if (*((str) + 0) == '\0') { \ *(outLen) = 1; \
*(outLen) = 0; \ } else if (*((str) + 2) == '\0') { \
} else if (*((str) + 1) == '\0') { \ *(outLen) = 2; \
*(outLen) = 1; \ } else if (*((str) + 3) == '\0') { \
} else if (*((str) + 2) == '\0') { \ *(outLen) = 3; \
*(outLen) = 2; \ } else if (*((str) + 4) == '\0') { \
} else if (*((str) + 3) == '\0') { \ *(outLen) = 4; \
*(outLen) = 3; \ } else if (*((str) + 5) == '\0') { \
} else if (*((str) + 4) == '\0') { \ *(outLen) = 5; \
*(outLen) = 4; \ } else if (*((str) + 6) == '\0') { \
} else if (*((str) + 5) == '\0') { \ *(outLen) = 6; \
*(outLen) = 5; \ } else if (*((str) + 7) == '\0') { \
} else if (*((str) + 6) == '\0') { \ *(outLen) = 7; \
*(outLen) = 6; \ } else if (*((str) + 8) == '\0') { \
} else if (*((str) + 7) == '\0') { \ /* Optimization with a length of 8 */ \
*(outLen) = 7; \ *(outLen) = 8; \
} else if (*((str) + 8) == '\0') { \ } else { \
/* Optimization with a length of 8 */ \ /* The offset is 8 because the performance of 8 byte alignment is high */ \
*(outLen) = 8; \ *(outLen) = 8 + strnlen((str) + 8, (maxLen) - 8); \
} else { \ } \
/* The offset is 8 because the performance of 8 byte alignment is high \ } else { \
*/ \ SECUREC_CALC_STR_LEN((str), (maxLen), (outLen)); \
*(outLen) = 8 + strnlen((str) + 8, (maxLen)-8); \ } \
} \ } SECUREC_WHILE_ZERO
} else { \
SECUREC_CALC_STR_LEN((str), (maxLen), (outLen)); \
} \
} \
SECUREC_WHILE_ZERO
#else #else
#define SECUREC_CALC_STR_LEN(str, maxLen, outLen) \ #define SECUREC_CALC_STR_LEN(str, maxLen, outLen) do { \
do { \ const char *strEnd = (const char *)(str); \
const char *strEnd = (const char *)(str); \ size_t availableSize = (size_t)(maxLen); \
size_t availableSize = (size_t)(maxLen); \ while (availableSize > 0 && *strEnd != '\0') { \
while (availableSize > 0 && *strEnd != '\0') { \ --availableSize; \
--availableSize; \ ++strEnd; \
++strEnd; \ } \
} \ *(outLen) = (size_t)(strEnd - (str)); \
*(outLen) = (size_t)(strEnd - (str)); \ } SECUREC_WHILE_ZERO
} \
SECUREC_WHILE_ZERO
#define SECUREC_CALC_STR_LEN_OPT SECUREC_CALC_STR_LEN #define SECUREC_CALC_STR_LEN_OPT SECUREC_CALC_STR_LEN
#endif #endif
#define SECUREC_CALC_WSTR_LEN(str, maxLen, outLen) \ #define SECUREC_CALC_WSTR_LEN(str, maxLen, outLen) do { \
do { \ const wchar_t *strEnd = (const wchar_t *)(str); \
const wchar_t *strEnd = (const wchar_t *)(str); \ size_t len = 0; \
size_t len = 0; \ while (len < (maxLen) && *strEnd != L'\0') { \
while (len < (maxLen) && *strEnd != L'\0') { \ ++len; \
++len; \ ++strEnd; \
++strEnd; \ } \
} \ *(outLen) = len; \
*(outLen) = len; \ } SECUREC_WHILE_ZERO
} \
SECUREC_WHILE_ZERO
/* Performance optimization, product may disable inline function */ /* Performance optimization, product may disable inline function */
#ifdef SECUREC_USE_ASM #ifdef SECUREC_USE_ASM
#define SECUREC_MEMCPY_WARP_OPT(dest, src, count) \ #define SECUREC_MEMCPY_WARP_OPT(dest, src, count) (void)memcpy_opt((dest), (src), (count))
(void)memcpy_opt((dest), (src), (count)) #define SECUREC_MEMSET_WARP_OPT(dest, c, count) (void)memset_opt((dest), (c), (count))
#define SECUREC_MEMSET_WARP_OPT(dest, c, count) \
(void)memset_opt((dest), (c), (count))
#else #else
#define SECUREC_MEMCPY_WARP_OPT(dest, src, count) \ #define SECUREC_MEMCPY_WARP_OPT(dest, src, count) (void)memcpy((dest), (src), (count))
(void)memcpy((dest), (src), (count)) #define SECUREC_MEMSET_WARP_OPT(dest, c, count) (void)memset((dest), (c), (count))
#define SECUREC_MEMSET_WARP_OPT(dest, c, count) \
(void)memset((dest), (c), (count))
#endif #endif
#ifdef SECUREC_FORMAT_OUTPUT_INPUT #ifdef SECUREC_FORMAT_OUTPUT_INPUT
@@ -278,12 +257,11 @@ typedef unsigned int SecUnsignedInt;
* Determine whether the address is 8-byte aligned * Determine whether the address is 8-byte aligned
* Some systems do not have uintptr_t type, so use NULL to clear tool alarm 507 * Some systems do not have uintptr_t type, so use NULL to clear tool alarm 507
*/ */
#define SECUREC_ADDR_ALIGNED_8(addr) \ #define SECUREC_ADDR_ALIGNED_8(addr) ((((size_t)(addr)) & 7) == 0) /* Use 7 to check aligned 8 */
((((size_t)(addr)) & 7) == 0) /* Use 7 to check aligned 8 */
/* /*
* If you define the memory allocation function, you need to define the function * If you define the memory allocation function, you need to define the function prototype.
* prototype. You can define this macro as a header file. * You can define this macro as a header file.
*/ */
#if defined(SECUREC_MALLOC_PROTOTYPE) #if defined(SECUREC_MALLOC_PROTOTYPE)
SECUREC_MALLOC_PROTOTYPE SECUREC_MALLOC_PROTOTYPE
@@ -294,265 +272,201 @@ SECUREC_MALLOC_PROTOTYPE
#endif #endif
#ifndef SECUREC_FREE #ifndef SECUREC_FREE
#define SECUREC_FREE(x) free((void *)(x)) #define SECUREC_FREE(x) free((void *)(x))
#endif #endif
/* Struct for performance */ /* Struct for performance */
typedef struct { typedef struct {
unsigned char buf[1]; /* Performance optimization code structure assignment unsigned char buf[1]; /* Performance optimization code structure assignment length 1 bytes */
length 1 bytes */
} SecStrBuf1; } SecStrBuf1;
typedef struct { typedef struct {
unsigned char buf[2]; /* Performance optimization code structure assignment unsigned char buf[2]; /* Performance optimization code structure assignment length 2 bytes */
length 2 bytes */
} SecStrBuf2; } SecStrBuf2;
typedef struct { typedef struct {
unsigned char buf[3]; /* Performance optimization code structure assignment unsigned char buf[3]; /* Performance optimization code structure assignment length 3 bytes */
length 3 bytes */
} SecStrBuf3; } SecStrBuf3;
typedef struct { typedef struct {
unsigned char buf[4]; /* Performance optimization code structure assignment unsigned char buf[4]; /* Performance optimization code structure assignment length 4 bytes */
length 4 bytes */
} SecStrBuf4; } SecStrBuf4;
typedef struct { typedef struct {
unsigned char buf[5]; /* Performance optimization code structure assignment unsigned char buf[5]; /* Performance optimization code structure assignment length 5 bytes */
length 5 bytes */
} SecStrBuf5; } SecStrBuf5;
typedef struct { typedef struct {
unsigned char buf[6]; /* Performance optimization code structure assignment unsigned char buf[6]; /* Performance optimization code structure assignment length 6 bytes */
length 6 bytes */
} SecStrBuf6; } SecStrBuf6;
typedef struct { typedef struct {
unsigned char buf[7]; /* Performance optimization code structure assignment unsigned char buf[7]; /* Performance optimization code structure assignment length 7 bytes */
length 7 bytes */
} SecStrBuf7; } SecStrBuf7;
typedef struct { typedef struct {
unsigned char buf[8]; /* Performance optimization code structure assignment unsigned char buf[8]; /* Performance optimization code structure assignment length 8 bytes */
length 8 bytes */
} SecStrBuf8; } SecStrBuf8;
typedef struct { typedef struct {
unsigned char buf[9]; /* Performance optimization code structure assignment unsigned char buf[9]; /* Performance optimization code structure assignment length 9 bytes */
length 9 bytes */
} SecStrBuf9; } SecStrBuf9;
typedef struct { typedef struct {
unsigned char buf[10]; /* Performance optimization code structure assignment unsigned char buf[10]; /* Performance optimization code structure assignment length 10 bytes */
length 10 bytes */
} SecStrBuf10; } SecStrBuf10;
typedef struct { typedef struct {
unsigned char buf[11]; /* Performance optimization code structure assignment unsigned char buf[11]; /* Performance optimization code structure assignment length 11 bytes */
length 11 bytes */
} SecStrBuf11; } SecStrBuf11;
typedef struct { typedef struct {
unsigned char buf[12]; /* Performance optimization code structure assignment unsigned char buf[12]; /* Performance optimization code structure assignment length 12 bytes */
length 12 bytes */
} SecStrBuf12; } SecStrBuf12;
typedef struct { typedef struct {
unsigned char buf[13]; /* Performance optimization code structure assignment unsigned char buf[13]; /* Performance optimization code structure assignment length 13 bytes */
length 13 bytes */
} SecStrBuf13; } SecStrBuf13;
typedef struct { typedef struct {
unsigned char buf[14]; /* Performance optimization code structure assignment unsigned char buf[14]; /* Performance optimization code structure assignment length 14 bytes */
length 14 bytes */
} SecStrBuf14; } SecStrBuf14;
typedef struct { typedef struct {
unsigned char buf[15]; /* Performance optimization code structure assignment unsigned char buf[15]; /* Performance optimization code structure assignment length 15 bytes */
length 15 bytes */
} SecStrBuf15; } SecStrBuf15;
typedef struct { typedef struct {
unsigned char buf[16]; /* Performance optimization code structure assignment unsigned char buf[16]; /* Performance optimization code structure assignment length 16 bytes */
length 16 bytes */
} SecStrBuf16; } SecStrBuf16;
typedef struct { typedef struct {
unsigned char buf[17]; /* Performance optimization code structure assignment unsigned char buf[17]; /* Performance optimization code structure assignment length 17 bytes */
length 17 bytes */
} SecStrBuf17; } SecStrBuf17;
typedef struct { typedef struct {
unsigned char buf[18]; /* Performance optimization code structure assignment unsigned char buf[18]; /* Performance optimization code structure assignment length 18 bytes */
length 18 bytes */
} SecStrBuf18; } SecStrBuf18;
typedef struct { typedef struct {
unsigned char buf[19]; /* Performance optimization code structure assignment unsigned char buf[19]; /* Performance optimization code structure assignment length 19 bytes */
length 19 bytes */
} SecStrBuf19; } SecStrBuf19;
typedef struct { typedef struct {
unsigned char buf[20]; /* Performance optimization code structure assignment unsigned char buf[20]; /* Performance optimization code structure assignment length 20 bytes */
length 20 bytes */
} SecStrBuf20; } SecStrBuf20;
typedef struct { typedef struct {
unsigned char buf[21]; /* Performance optimization code structure assignment unsigned char buf[21]; /* Performance optimization code structure assignment length 21 bytes */
length 21 bytes */
} SecStrBuf21; } SecStrBuf21;
typedef struct { typedef struct {
unsigned char buf[22]; /* Performance optimization code structure assignment unsigned char buf[22]; /* Performance optimization code structure assignment length 22 bytes */
length 22 bytes */
} SecStrBuf22; } SecStrBuf22;
typedef struct { typedef struct {
unsigned char buf[23]; /* Performance optimization code structure assignment unsigned char buf[23]; /* Performance optimization code structure assignment length 23 bytes */
length 23 bytes */
} SecStrBuf23; } SecStrBuf23;
typedef struct { typedef struct {
unsigned char buf[24]; /* Performance optimization code structure assignment unsigned char buf[24]; /* Performance optimization code structure assignment length 24 bytes */
length 24 bytes */
} SecStrBuf24; } SecStrBuf24;
typedef struct { typedef struct {
unsigned char buf[25]; /* Performance optimization code structure assignment unsigned char buf[25]; /* Performance optimization code structure assignment length 25 bytes */
length 25 bytes */
} SecStrBuf25; } SecStrBuf25;
typedef struct { typedef struct {
unsigned char buf[26]; /* Performance optimization code structure assignment unsigned char buf[26]; /* Performance optimization code structure assignment length 26 bytes */
length 26 bytes */
} SecStrBuf26; } SecStrBuf26;
typedef struct { typedef struct {
unsigned char buf[27]; /* Performance optimization code structure assignment unsigned char buf[27]; /* Performance optimization code structure assignment length 27 bytes */
length 27 bytes */
} SecStrBuf27; } SecStrBuf27;
typedef struct { typedef struct {
unsigned char buf[28]; /* Performance optimization code structure assignment unsigned char buf[28]; /* Performance optimization code structure assignment length 28 bytes */
length 28 bytes */
} SecStrBuf28; } SecStrBuf28;
typedef struct { typedef struct {
unsigned char buf[29]; /* Performance optimization code structure assignment unsigned char buf[29]; /* Performance optimization code structure assignment length 29 bytes */
length 29 bytes */
} SecStrBuf29; } SecStrBuf29;
typedef struct { typedef struct {
unsigned char buf[30]; /* Performance optimization code structure assignment unsigned char buf[30]; /* Performance optimization code structure assignment length 30 bytes */
length 30 bytes */
} SecStrBuf30; } SecStrBuf30;
typedef struct { typedef struct {
unsigned char buf[31]; /* Performance optimization code structure assignment unsigned char buf[31]; /* Performance optimization code structure assignment length 31 bytes */
length 31 bytes */
} SecStrBuf31; } SecStrBuf31;
typedef struct { typedef struct {
unsigned char buf[32]; /* Performance optimization code structure assignment unsigned char buf[32]; /* Performance optimization code structure assignment length 32 bytes */
length 32 bytes */
} SecStrBuf32; } SecStrBuf32;
typedef struct { typedef struct {
unsigned char buf[33]; /* Performance optimization code structure assignment unsigned char buf[33]; /* Performance optimization code structure assignment length 33 bytes */
length 33 bytes */
} SecStrBuf33; } SecStrBuf33;
typedef struct { typedef struct {
unsigned char buf[34]; /* Performance optimization code structure assignment unsigned char buf[34]; /* Performance optimization code structure assignment length 34 bytes */
length 34 bytes */
} SecStrBuf34; } SecStrBuf34;
typedef struct { typedef struct {
unsigned char buf[35]; /* Performance optimization code structure assignment unsigned char buf[35]; /* Performance optimization code structure assignment length 35 bytes */
length 35 bytes */
} SecStrBuf35; } SecStrBuf35;
typedef struct { typedef struct {
unsigned char buf[36]; /* Performance optimization code structure assignment unsigned char buf[36]; /* Performance optimization code structure assignment length 36 bytes */
length 36 bytes */
} SecStrBuf36; } SecStrBuf36;
typedef struct { typedef struct {
unsigned char buf[37]; /* Performance optimization code structure assignment unsigned char buf[37]; /* Performance optimization code structure assignment length 37 bytes */
length 37 bytes */
} SecStrBuf37; } SecStrBuf37;
typedef struct { typedef struct {
unsigned char buf[38]; /* Performance optimization code structure assignment unsigned char buf[38]; /* Performance optimization code structure assignment length 38 bytes */
length 38 bytes */
} SecStrBuf38; } SecStrBuf38;
typedef struct { typedef struct {
unsigned char buf[39]; /* Performance optimization code structure assignment unsigned char buf[39]; /* Performance optimization code structure assignment length 39 bytes */
length 39 bytes */
} SecStrBuf39; } SecStrBuf39;
typedef struct { typedef struct {
unsigned char buf[40]; /* Performance optimization code structure assignment unsigned char buf[40]; /* Performance optimization code structure assignment length 40 bytes */
length 40 bytes */
} SecStrBuf40; } SecStrBuf40;
typedef struct { typedef struct {
unsigned char buf[41]; /* Performance optimization code structure assignment unsigned char buf[41]; /* Performance optimization code structure assignment length 41 bytes */
length 41 bytes */
} SecStrBuf41; } SecStrBuf41;
typedef struct { typedef struct {
unsigned char buf[42]; /* Performance optimization code structure assignment unsigned char buf[42]; /* Performance optimization code structure assignment length 42 bytes */
length 42 bytes */
} SecStrBuf42; } SecStrBuf42;
typedef struct { typedef struct {
unsigned char buf[43]; /* Performance optimization code structure assignment unsigned char buf[43]; /* Performance optimization code structure assignment length 43 bytes */
length 43 bytes */
} SecStrBuf43; } SecStrBuf43;
typedef struct { typedef struct {
unsigned char buf[44]; /* Performance optimization code structure assignment unsigned char buf[44]; /* Performance optimization code structure assignment length 44 bytes */
length 44 bytes */
} SecStrBuf44; } SecStrBuf44;
typedef struct { typedef struct {
unsigned char buf[45]; /* Performance optimization code structure assignment unsigned char buf[45]; /* Performance optimization code structure assignment length 45 bytes */
length 45 bytes */
} SecStrBuf45; } SecStrBuf45;
typedef struct { typedef struct {
unsigned char buf[46]; /* Performance optimization code structure assignment unsigned char buf[46]; /* Performance optimization code structure assignment length 46 bytes */
length 46 bytes */
} SecStrBuf46; } SecStrBuf46;
typedef struct { typedef struct {
unsigned char buf[47]; /* Performance optimization code structure assignment unsigned char buf[47]; /* Performance optimization code structure assignment length 47 bytes */
length 47 bytes */
} SecStrBuf47; } SecStrBuf47;
typedef struct { typedef struct {
unsigned char buf[48]; /* Performance optimization code structure assignment unsigned char buf[48]; /* Performance optimization code structure assignment length 48 bytes */
length 48 bytes */
} SecStrBuf48; } SecStrBuf48;
typedef struct { typedef struct {
unsigned char buf[49]; /* Performance optimization code structure assignment unsigned char buf[49]; /* Performance optimization code structure assignment length 49 bytes */
length 49 bytes */
} SecStrBuf49; } SecStrBuf49;
typedef struct { typedef struct {
unsigned char buf[50]; /* Performance optimization code structure assignment unsigned char buf[50]; /* Performance optimization code structure assignment length 50 bytes */
length 50 bytes */
} SecStrBuf50; } SecStrBuf50;
typedef struct { typedef struct {
unsigned char buf[51]; /* Performance optimization code structure assignment unsigned char buf[51]; /* Performance optimization code structure assignment length 51 bytes */
length 51 bytes */
} SecStrBuf51; } SecStrBuf51;
typedef struct { typedef struct {
unsigned char buf[52]; /* Performance optimization code structure assignment unsigned char buf[52]; /* Performance optimization code structure assignment length 52 bytes */
length 52 bytes */
} SecStrBuf52; } SecStrBuf52;
typedef struct { typedef struct {
unsigned char buf[53]; /* Performance optimization code structure assignment unsigned char buf[53]; /* Performance optimization code structure assignment length 53 bytes */
length 53 bytes */
} SecStrBuf53; } SecStrBuf53;
typedef struct { typedef struct {
unsigned char buf[54]; /* Performance optimization code structure assignment unsigned char buf[54]; /* Performance optimization code structure assignment length 54 bytes */
length 54 bytes */
} SecStrBuf54; } SecStrBuf54;
typedef struct { typedef struct {
unsigned char buf[55]; /* Performance optimization code structure assignment unsigned char buf[55]; /* Performance optimization code structure assignment length 55 bytes */
length 55 bytes */
} SecStrBuf55; } SecStrBuf55;
typedef struct { typedef struct {
unsigned char buf[56]; /* Performance optimization code structure assignment unsigned char buf[56]; /* Performance optimization code structure assignment length 56 bytes */
length 56 bytes */
} SecStrBuf56; } SecStrBuf56;
typedef struct { typedef struct {
unsigned char buf[57]; /* Performance optimization code structure assignment unsigned char buf[57]; /* Performance optimization code structure assignment length 57 bytes */
length 57 bytes */
} SecStrBuf57; } SecStrBuf57;
typedef struct { typedef struct {
unsigned char buf[58]; /* Performance optimization code structure assignment unsigned char buf[58]; /* Performance optimization code structure assignment length 58 bytes */
length 58 bytes */
} SecStrBuf58; } SecStrBuf58;
typedef struct { typedef struct {
unsigned char buf[59]; /* Performance optimization code structure assignment unsigned char buf[59]; /* Performance optimization code structure assignment length 59 bytes */
length 59 bytes */
} SecStrBuf59; } SecStrBuf59;
typedef struct { typedef struct {
unsigned char buf[60]; /* Performance optimization code structure assignment unsigned char buf[60]; /* Performance optimization code structure assignment length 60 bytes */
length 60 bytes */
} SecStrBuf60; } SecStrBuf60;
typedef struct { typedef struct {
unsigned char buf[61]; /* Performance optimization code structure assignment unsigned char buf[61]; /* Performance optimization code structure assignment length 61 bytes */
length 61 bytes */
} SecStrBuf61; } SecStrBuf61;
typedef struct { typedef struct {
unsigned char buf[62]; /* Performance optimization code structure assignment unsigned char buf[62]; /* Performance optimization code structure assignment length 62 bytes */
length 62 bytes */
} SecStrBuf62; } SecStrBuf62;
typedef struct { typedef struct {
unsigned char buf[63]; /* Performance optimization code structure assignment unsigned char buf[63]; /* Performance optimization code structure assignment length 63 bytes */
length 63 bytes */
} SecStrBuf63; } SecStrBuf63;
typedef struct { typedef struct {
unsigned char buf[64]; /* Performance optimization code structure assignment unsigned char buf[64]; /* Performance optimization code structure assignment length 64 bytes */
length 64 bytes */
} SecStrBuf64; } SecStrBuf64;
/* /*
@@ -561,29 +475,23 @@ typedef struct {
*/ */
#if defined(_DEBUG) || defined(DEBUG) #if defined(_DEBUG) || defined(DEBUG)
#if defined(SECUREC_ERROR_HANDLER_BY_ASSERT) #if defined(SECUREC_ERROR_HANDLER_BY_ASSERT)
#define SECUREC_ERROR_INVALID_PARAMTER(msg) \ #define SECUREC_ERROR_INVALID_PARAMTER(msg) assert(msg "invalid argument" == NULL)
assert(msg "invalid argument" == NULL) #define SECUREC_ERROR_INVALID_RANGE(msg) assert(msg "invalid dest buffer size" == NULL)
#define SECUREC_ERROR_INVALID_RANGE(msg) \ #define SECUREC_ERROR_BUFFER_OVERLAP(msg) assert(msg "buffer overlap" == NULL)
assert(msg "invalid dest buffer size" == NULL)
#define SECUREC_ERROR_BUFFER_OVERLAP(msg) assert(msg "buffer overlap" == NULL)
#elif defined(SECUREC_ERROR_HANDLER_BY_PRINTF) #elif defined(SECUREC_ERROR_HANDLER_BY_PRINTF)
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
#define SECUREC_ERROR_INVALID_PARAMTER(msg) printk("%s invalid argument\n", msg) #define SECUREC_ERROR_INVALID_PARAMTER(msg) printk("%s invalid argument\n", msg)
#define SECUREC_ERROR_INVALID_RANGE(msg) \ #define SECUREC_ERROR_INVALID_RANGE(msg) printk("%s invalid dest buffer size\n", msg)
printk("%s invalid dest buffer size\n", msg) #define SECUREC_ERROR_BUFFER_OVERLAP(msg) printk("%s buffer overlap\n", msg)
#define SECUREC_ERROR_BUFFER_OVERLAP(msg) printk("%s buffer overlap\n", msg)
#else #else
#define SECUREC_ERROR_INVALID_PARAMTER(msg) printf("%s invalid argument\n", msg) #define SECUREC_ERROR_INVALID_PARAMTER(msg) printf("%s invalid argument\n", msg)
#define SECUREC_ERROR_INVALID_RANGE(msg) \ #define SECUREC_ERROR_INVALID_RANGE(msg) printf("%s invalid dest buffer size\n", msg)
printf("%s invalid dest buffer size\n", msg) #define SECUREC_ERROR_BUFFER_OVERLAP(msg) printf("%s buffer overlap\n", msg)
#define SECUREC_ERROR_BUFFER_OVERLAP(msg) printf("%s buffer overlap\n", msg)
#endif #endif
#elif defined(SECUREC_ERROR_HANDLER_BY_FILE_LOG) #elif defined(SECUREC_ERROR_HANDLER_BY_FILE_LOG)
#define SECUREC_ERROR_INVALID_PARAMTER(msg) \ #define SECUREC_ERROR_INVALID_PARAMTER(msg) LogSecureCRuntimeError(msg " EINVAL\n")
LogSecureCRuntimeError(msg " EINVAL\n") #define SECUREC_ERROR_INVALID_RANGE(msg) LogSecureCRuntimeError(msg " ERANGE\n")
#define SECUREC_ERROR_INVALID_RANGE(msg) LogSecureCRuntimeError(msg " ERANGE\n") #define SECUREC_ERROR_BUFFER_OVERLAP(msg) LogSecureCRuntimeError(msg " EOVERLAP\n")
#define SECUREC_ERROR_BUFFER_OVERLAP(msg) \
LogSecureCRuntimeError(msg " EOVERLAP\n")
#endif #endif
#endif #endif
@@ -592,10 +500,10 @@ typedef struct {
#define SECUREC_ERROR_INVALID_PARAMTER(msg) ((void)0) #define SECUREC_ERROR_INVALID_PARAMTER(msg) ((void)0)
#endif #endif
#ifndef SECUREC_ERROR_INVALID_RANGE #ifndef SECUREC_ERROR_INVALID_RANGE
#define SECUREC_ERROR_INVALID_RANGE(msg) ((void)0) #define SECUREC_ERROR_INVALID_RANGE(msg) ((void)0)
#endif #endif
#ifndef SECUREC_ERROR_BUFFER_OVERLAP #ifndef SECUREC_ERROR_BUFFER_OVERLAP
#define SECUREC_ERROR_BUFFER_OVERLAP(msg) ((void)0) #define SECUREC_ERROR_BUFFER_OVERLAP(msg) ((void)0)
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@@ -604,15 +512,16 @@ extern "C" {
/* Assembly language memory copy and memory set for X86 or MIPS ... */ /* Assembly language memory copy and memory set for X86 or MIPS ... */
#ifdef SECUREC_USE_ASM #ifdef SECUREC_USE_ASM
extern void *memcpy_opt(void *, const void *, size_t); extern void *memcpy_opt(void *, const void *, size_t);
extern void *memset_opt(void *, int, size_t); extern void *memset_opt(void *, int, size_t);
#endif #endif
#if defined(SECUREC_ERROR_HANDLER_BY_FILE_LOG) #if defined(SECUREC_ERROR_HANDLER_BY_FILE_LOG)
extern void LogSecureCRuntimeError(const char *errDetail); extern void LogSecureCRuntimeError(const char *errDetail);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif #endif
@@ -1,8 +1,9 @@
/* /*
* Copyright (c) Huawei Technologies Co., Ltd. 2014-2018. All rights reserved. * Copyright (c) Huawei Technologies Co., Ltd. 2014-2018. All rights reserved.
* Description: By defining data type for ANSI string and including "input.inl", * Description: By defining data type for ANSI string and including "input.inl",
* this file generates real underlying function used by scanf * this file generates real underlying function used by scanf family API.
* family API. Author: lishunda Create: 2014-02-25 * Author: lishunda
* Create: 2014-02-25
*/ */
#define SECUREC_FORMAT_OUTPUT_INPUT 1 #define SECUREC_FORMAT_OUTPUT_INPUT 1
#ifdef SECUREC_FOR_WCHAR #ifdef SECUREC_FOR_WCHAR
@@ -13,13 +14,17 @@
#include "input.inl" #include "input.inl"
SECUREC_INLINE int SecIsDigit(SecInt ch) { SECUREC_INLINE int SecIsDigit(SecInt ch)
/* SecInt to unsigned char clear 571 */ {
return isdigit((unsigned char)(ch)&0x00ff); /* SecInt to unsigned char clear 571 */
return isdigit((unsigned char)(ch) & 0x00ff);
} }
SECUREC_INLINE int SecIsXdigit(SecInt ch) { SECUREC_INLINE int SecIsXdigit(SecInt ch)
return isxdigit((unsigned char)(ch)&0x00ff); {
return isxdigit((unsigned char)(ch) & 0x00ff);
} }
SECUREC_INLINE int SecIsSpace(SecInt ch) { SECUREC_INLINE int SecIsSpace(SecInt ch)
return isspace((unsigned char)(ch)&0x00ff); {
return isspace((unsigned char)(ch) & 0x00ff);
} }
@@ -1,8 +1,9 @@
/* /*
* Copyright (c) Huawei Technologies Co., Ltd. 2014-2018. All rights reserved. * Copyright (c) Huawei Technologies Co., Ltd. 2014-2018. All rights reserved.
* Description: By defining data type for UNICODE string and including * Description: By defining data type for UNICODE string and including "input.inl",
* "input.inl", this file generates real underlying function used by scanf * this file generates real underlying function used by scanf family API.
* family API. Author: lishunda Create: 2014-02-25 * Author: lishunda
* Create: 2014-02-25
*/ */
/* If some platforms don't have wchar.h, dont't include it */ /* If some platforms don't have wchar.h, dont't include it */
@@ -14,15 +15,15 @@
#define __STDC_WANT_SECURE_LIB__ 0 #define __STDC_WANT_SECURE_LIB__ 0
#endif #endif
#ifndef _CRTIMP_ALTERNATIVE #ifndef _CRTIMP_ALTERNATIVE
#define _CRTIMP_ALTERNATIVE /* Comment microsoft *_s function */ #define _CRTIMP_ALTERNATIVE /* Comment microsoft *_s function */
#endif #endif
#endif #endif
#include <wchar.h> #include <wchar.h>
#endif #endif
/* Disable wchar func to clear vs warning */ /* Disable wchar func to clear vs warning */
#define SECUREC_ENABLE_WCHAR_FUNC 0 #define SECUREC_ENABLE_WCHAR_FUNC 0
#define SECUREC_FORMAT_OUTPUT_INPUT 1 #define SECUREC_FORMAT_OUTPUT_INPUT 1
#ifndef SECUREC_FOR_WCHAR #ifndef SECUREC_FOR_WCHAR
#define SECUREC_FOR_WCHAR #define SECUREC_FOR_WCHAR
@@ -32,13 +33,19 @@
#include "input.inl" #include "input.inl"
SECUREC_INLINE int SecIsDigit(SecInt ch) { SECUREC_INLINE int SecIsDigit(SecInt ch)
/* Convert int to unsigned int clear 571 */ {
return (!((unsigned int)(int)(ch)&0xff00) && /* Convert int to unsigned int clear 571 */
isdigit(((unsigned int)(int)(ch)&0x00ff))); return (!((unsigned int)(int)(ch) & 0xff00) && isdigit(((unsigned int)(int)(ch) & 0x00ff)));
} }
SECUREC_INLINE int SecIsXdigit(SecInt ch) { SECUREC_INLINE int SecIsXdigit(SecInt ch)
return (!((unsigned int)(int)(ch)&0xff00) && {
isxdigit(((unsigned int)(int)(ch)&0x00ff))); return (!((unsigned int)(int)(ch) & 0xff00) && isxdigit(((unsigned int)(int)(ch) & 0x00ff)));
} }
SECUREC_INLINE int SecIsSpace(SecInt ch) { return iswspace((wint_t)(int)(ch)); } SECUREC_INLINE int SecIsSpace(SecInt ch)
{
return iswspace((wint_t)(int)(ch));
}
@@ -1,7 +1,7 @@
/* /*
* Copyright (c) Huawei Technologies Co., Ltd. 2014-2018. All rights reserved. * Copyright (c) Huawei Technologies Co., Ltd. 2014-2018. All rights reserved.
* Description: Define macro, enum, data struct, and declare internal used * Description: Define macro, enum, data struct, and declare internal used function
* function prototype, which is used by output.inl, secureprintoutput_w.c and * prototype, which is used by output.inl, secureprintoutput_w.c and
* secureprintoutput_a.c. * secureprintoutput_a.c.
* Author: lishunda * Author: lishunda
* Create: 2014-02-25 * Create: 2014-02-25
@@ -13,115 +13,108 @@
/* /*
* Flag definitions. * Flag definitions.
* Using macros instead of enumerations is because some of the enumerated types * Using macros instead of enumerations is because some of the enumerated types under the compiler are 16bit.
* under the compiler are 16bit.
*/ */
#define SECUREC_FLAG_SIGN 0x00001U #define SECUREC_FLAG_SIGN 0x00001U
#define SECUREC_FLAG_SIGN_SPACE 0x00002U #define SECUREC_FLAG_SIGN_SPACE 0x00002U
#define SECUREC_FLAG_LEFT 0x00004U #define SECUREC_FLAG_LEFT 0x00004U
#define SECUREC_FLAG_LEADZERO 0x00008U #define SECUREC_FLAG_LEADZERO 0x00008U
#define SECUREC_FLAG_LONG 0x00010U #define SECUREC_FLAG_LONG 0x00010U
#define SECUREC_FLAG_SHORT 0x00020U #define SECUREC_FLAG_SHORT 0x00020U
#define SECUREC_FLAG_SIGNED 0x00040U #define SECUREC_FLAG_SIGNED 0x00040U
#define SECUREC_FLAG_ALTERNATE 0x00080U #define SECUREC_FLAG_ALTERNATE 0x00080U
#define SECUREC_FLAG_NEGATIVE 0x00100U #define SECUREC_FLAG_NEGATIVE 0x00100U
#define SECUREC_FLAG_FORCE_OCTAL 0x00200U #define SECUREC_FLAG_FORCE_OCTAL 0x00200U
#define SECUREC_FLAG_LONG_DOUBLE 0x00400U #define SECUREC_FLAG_LONG_DOUBLE 0x00400U
#define SECUREC_FLAG_WIDECHAR 0x00800U #define SECUREC_FLAG_WIDECHAR 0x00800U
#define SECUREC_FLAG_LONGLONG 0x01000U #define SECUREC_FLAG_LONGLONG 0x01000U
#define SECUREC_FLAG_CHAR 0x02000U #define SECUREC_FLAG_CHAR 0x02000U
#define SECUREC_FLAG_POINTER 0x04000U #define SECUREC_FLAG_POINTER 0x04000U
#define SECUREC_FLAG_I64 0x08000U #define SECUREC_FLAG_I64 0x08000U
#define SECUREC_FLAG_PTRDIFF 0x10000U #define SECUREC_FLAG_PTRDIFF 0x10000U
#define SECUREC_FLAG_SIZE 0x20000U #define SECUREC_FLAG_SIZE 0x20000U
#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
#define SECUREC_FLAG_INTMAX 0x40000U #define SECUREC_FLAG_INTMAX 0x40000U
#endif #endif
/* State definitions. Identify the status of the current format */ /* State definitions. Identify the status of the current format */
typedef enum { typedef enum {
STAT_NORMAL, STAT_NORMAL,
STAT_PERCENT, STAT_PERCENT,
STAT_FLAG, STAT_FLAG,
STAT_WIDTH, STAT_WIDTH,
STAT_DOT, STAT_DOT,
STAT_PRECIS, STAT_PRECIS,
STAT_SIZE, STAT_SIZE,
STAT_TYPE, STAT_TYPE,
STAT_INVALID STAT_INVALID
} SecFmtState; } SecFmtState;
/* Format output buffer pointer and available size */ /* Format output buffer pointer and available size */
typedef struct { typedef struct {
int count; int count;
char *cur; char *cur;
} SecPrintfStream; } SecPrintfStream;
#ifndef SECUREC_BUFFER_SIZE #ifndef SECUREC_BUFFER_SIZE
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
#define SECUREC_BUFFER_SIZE 32 #define SECUREC_BUFFER_SIZE 32
#elif defined(SECUREC_STACK_SIZE_LESS_THAN_1K) #elif defined(SECUREC_STACK_SIZE_LESS_THAN_1K)
/* /*
* SECUREC BUFFER SIZE Can not be less than 23 * SECUREC BUFFER SIZE Can not be less than 23
* The length of the octal representation of 64-bit integers with zero lead * The length of the octal representation of 64-bit integers with zero lead
*/ */
#define SECUREC_BUFFER_SIZE 256 #define SECUREC_BUFFER_SIZE 256
#else #else
#define SECUREC_BUFFER_SIZE 512 #define SECUREC_BUFFER_SIZE 512
#endif #endif
#endif #endif
#if SECUREC_BUFFER_SIZE < 23 #if SECUREC_BUFFER_SIZE < 23
#error SECUREC_BUFFER_SIZE Can not be less than 23 #error SECUREC_BUFFER_SIZE Can not be less than 23
#endif #endif
/* Buffer size for wchar, use 4 to make the compiler aligns as 8 bytes as /* Buffer size for wchar, use 4 to make the compiler aligns as 8 bytes as possible */
* possible */
#define SECUREC_WCHAR_BUFFER_SIZE 4 #define SECUREC_WCHAR_BUFFER_SIZE 4
#define SECUREC_MAX_PRECISION SECUREC_BUFFER_SIZE
#define SECUREC_MAX_PRECISION SECUREC_BUFFER_SIZE
/* Max. # bytes in multibyte char ,see MB_LEN_MAX */ /* Max. # bytes in multibyte char ,see MB_LEN_MAX */
#define SECUREC_MB_LEN 16 #define SECUREC_MB_LEN 16
/* The return value of the internal function, which is returned when truncated /* The return value of the internal function, which is returned when truncated */
*/
#define SECUREC_PRINTF_TRUNCATE (-2) #define SECUREC_PRINTF_TRUNCATE (-2)
#define SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, maxLimit) \ #define SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, maxLimit) \
((format) == NULL || (strDest) == NULL || (destMax) == 0 || \ ((format) == NULL || (strDest) == NULL || (destMax) == 0 || (destMax) > (maxLimit))
(destMax) > (maxLimit))
#define SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, maxLimit) \ #define SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, maxLimit) do { \
do { \ if ((strDest) != NULL && (destMax) > 0 && (destMax) <= (maxLimit)) { \
if ((strDest) != NULL && (destMax) > 0 && (destMax) <= (maxLimit)) { \ *(strDest) = '\0'; \
*(strDest) = '\0'; \ } \
} \ } SECUREC_WHILE_ZERO
} \
SECUREC_WHILE_ZERO
#ifdef SECUREC_COMPATIBLE_WIN_FORMAT #ifdef SECUREC_COMPATIBLE_WIN_FORMAT
#define SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, \ #define SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, maxLimit) \
maxLimit) \ (((format) == NULL || (strDest) == NULL || (destMax) == 0 || (destMax) > (maxLimit)) || \
(((format) == NULL || (strDest) == NULL || (destMax) == 0 || \ ((count) > (SECUREC_STRING_MAX_LEN - 1) && (count) != (size_t)(-1)))
(destMax) > (maxLimit)) || \
((count) > (SECUREC_STRING_MAX_LEN - 1) && (count) != (size_t)(-1)))
#else #else
#define SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, \ #define SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, maxLimit) \
maxLimit) \ (((format) == NULL || (strDest) == NULL || (destMax) == 0 || (destMax) > (maxLimit)) || \
(((format) == NULL || (strDest) == NULL || (destMax) == 0 || \ ((count) > (SECUREC_STRING_MAX_LEN - 1)))
(destMax) > (maxLimit)) || \
((count) > (SECUREC_STRING_MAX_LEN - 1)))
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
extern int SecVsnprintfImpl(char *string, size_t count, const char *format, extern int SecVsnprintfImpl(char *string, size_t count, const char *format, va_list argList);
va_list argList);
#if SECUREC_IN_KERNEL == 0 #if SECUREC_IN_KERNEL == 0
extern int SecVswprintfImpl(wchar_t *string, size_t sizeInWchar, extern int SecVswprintfImpl(wchar_t *string, size_t sizeInWchar, const wchar_t *format, va_list argList);
const wchar_t *format, va_list argList);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif
@@ -1,8 +1,9 @@
/* /*
* Copyright (c) Huawei Technologies Co., Ltd. 2014-2018. All rights reserved. * Copyright (c) Huawei Technologies Co., Ltd. 2014-2018. All rights reserved.
* Description: By defining corresponding macro for ANSI string and including * Description: By defining corresponding macro for ANSI string and including "output.inl",
* "output.inl", this file generates real underlying function used by printf * this file generates real underlying function used by printf family API.
* family API. Author: lishunda Create: 2014-02-25 * Author: lishunda
* Create: 2014-02-25
*/ */
#define SECUREC_FORMAT_OUTPUT_INPUT 1 #define SECUREC_FORMAT_OUTPUT_INPUT 1
@@ -18,77 +19,74 @@ static const unsigned char g_flagTable[SECUREC_FORMAT_FLAG_TABLE_SIZE] = {
/* /*
* Known flag is "0123456789 +-#hlLwZzjqt*I" * Known flag is "0123456789 +-#hlLwZzjqt*I"
*/ */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, };
0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
SECUREC_INLINE const char *SecSkipKnownFlags(const char *format) { SECUREC_INLINE const char *SecSkipKnownFlags(const char *format)
const char *fmt = format; {
while (*fmt != '\0') { const char *fmt = format;
char fmtChar = *fmt; while (*fmt != '\0') {
if ((unsigned char)fmtChar > char fmtChar = *fmt;
0x7f) { /* 0x7f is upper limit of format char value */ if ((unsigned char)fmtChar > 0x7f) { /* 0x7f is upper limit of format char value */
break; break;
}
if (g_flagTable[(unsigned char)fmtChar] == 0) {
break;
}
++fmt;
} }
if (g_flagTable[(unsigned char)fmtChar] == 0) { return fmt;
break;
}
++fmt;
}
return fmt;
} }
SECUREC_INLINE int SecFormatContainN(const char *format) { SECUREC_INLINE int SecFormatContainN(const char *format)
const char *fmt = format; {
while (*fmt != '\0') { const char *fmt = format;
++fmt; while (*fmt != '\0') {
/* Skip normal char */ ++fmt;
if (*(fmt - 1) != '%') { /* Skip normal char */
continue; if (*(fmt - 1) != '%') {
continue;
}
/* Meet %% */
if (*fmt == '%') {
++fmt; /* Point to the character after the %. Correct handling %%xx */
continue;
}
/* Now parse %..., fmt point to the character after the % */
fmt = SecSkipKnownFlags(fmt);
if (*fmt == 'n') {
return 1;
}
} }
/* Meet %% */ return 0;
if (*fmt == '%') {
++fmt; /* Point to the character after the %. Correct handling %%xx */
continue;
}
/* Now parse %..., fmt point to the character after the % */
fmt = SecSkipKnownFlags(fmt);
if (*fmt == 'n') {
return 1;
}
}
return 0;
} }
/* /*
* Multi character formatted output implementation, the count include \0 * Multi character formatted output implementation, the count include \0 character, must be greater than zero
* character, must be greater than zero
*/ */
int SecVsnprintfImpl(char *string, size_t count, const char *format, int SecVsnprintfImpl(char *string, size_t count, const char *format, va_list argList)
va_list argList) { {
int retVal; int retVal;
if (SecFormatContainN(format)) { if (SecFormatContainN(format)) {
string[0] = '\0'; string[0] = '\0';
return -1; return -1;
} }
retVal = vsnprintf(string, count, format, argList); retVal = vsnprintf(string, count, format, argList);
if (retVal >= (int)count) { /* The size_t to int is ok, count max is if (retVal >= (int)count) { /* The size_t to int is ok, count max is SECUREC_STRING_MAX_LEN */
SECUREC_STRING_MAX_LEN */ /* The buffer was too small; we return truncation */
/* The buffer was too small; we return truncation */ string[count - 1] = '\0';
string[count - 1] = '\0'; return SECUREC_PRINTF_TRUNCATE;
return SECUREC_PRINTF_TRUNCATE; } else if (retVal < 0) {
} else if (retVal < 0) { string[0] = '\0'; /* Empty the dest strDest */
string[0] = '\0'; /* Empty the dest strDest */ return -1;
return -1; }
} return retVal;
return retVal;
} }
#else #else
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
@@ -96,76 +94,73 @@ int SecVsnprintfImpl(char *string, size_t count, const char *format,
#endif #endif
#define SECUREC_CHAR(x) x #define SECUREC_CHAR(x) x
#define SECUREC_WRITE_MULTI_CHAR SecWriteMultiChar #define SECUREC_WRITE_MULTI_CHAR SecWriteMultiChar
#define SECUREC_WRITE_STRING SecWriteString #define SECUREC_WRITE_STRING SecWriteString
#ifndef EOF #ifndef EOF
#define EOF (-1) #define EOF (-1)
#endif #endif
SECUREC_INLINE void SecWriteMultiChar(char ch, int num, SecPrintfStream *f, SECUREC_INLINE void SecWriteMultiChar(char ch, int num, SecPrintfStream *f, int *pnumwritten);
int *pnumwritten); SECUREC_INLINE void SecWriteString(const char *string, int len, SecPrintfStream *f, int *pnumwritten);
SECUREC_INLINE void SecWriteString(const char *string, int len,
SecPrintfStream *f, int *pnumwritten);
#include "output.inl" #include "output.inl"
/* /*
* Multi character formatted output implementation * Multi character formatted output implementation
*/ */
int SecVsnprintfImpl(char *string, size_t count, const char *format, int SecVsnprintfImpl(char *string, size_t count, const char *format, va_list argList)
va_list argList) { {
SecPrintfStream str; SecPrintfStream str;
int retVal; int retVal;
str.count = (int) str.count = (int)count; /* The count include \0 character, must be greater than zero */
count; /* The count include \0 character, must be greater than zero */ str.cur = string;
str.cur = string;
retVal = SecOutputS(&str, format, argList); retVal = SecOutputS(&str, format, argList);
if (retVal >= 0 && SecPutZeroChar(&str) == 0) { if (retVal >= 0 && SecPutZeroChar(&str) == 0) {
return retVal; return retVal;
} else if (str.count < 0) { } else if (str.count < 0) {
/* The buffer was too small; we return truncation */ /* The buffer was too small; we return truncation */
string[count - 1] = '\0'; string[count - 1] = '\0';
return SECUREC_PRINTF_TRUNCATE; return SECUREC_PRINTF_TRUNCATE;
} }
string[0] = '\0'; /* Empty the dest strDest */ string[0] = '\0'; /* Empty the dest strDest */
return -1; return -1;
} }
/* /*
* Write a wide character * Write a wide character
*/ */
SECUREC_INLINE void SecWriteMultiChar(char ch, int num, SecPrintfStream *f, SECUREC_INLINE void SecWriteMultiChar(char ch, int num, SecPrintfStream *f, int *pnumwritten)
int *pnumwritten) { {
int count = num; int count = num;
while (count-- > 0 && --(f->count) >= 0) { while (count-- > 0 && --(f->count) >= 0) {
*(f->cur) = ch; *(f->cur) = ch;
++(f->cur); ++(f->cur);
*pnumwritten = *pnumwritten + 1; *pnumwritten = *pnumwritten + 1;
} }
if (f->count < 0) { if (f->count < 0) {
*pnumwritten = -1; *pnumwritten = -1;
} }
} }
/* /*
* Write string function, where this function is called, make sure that len is * Write string function, where this function is called, make sure that len is greater than 0
* greater than 0
*/ */
SECUREC_INLINE void SecWriteString(const char *string, int len, SECUREC_INLINE void SecWriteString(const char *string, int len, SecPrintfStream *f, int *pnumwritten)
SecPrintfStream *f, int *pnumwritten) { {
const char *str = string; const char *str = string;
int count = len; int count = len;
while (count-- > 0 && --(f->count) >= 0) { while (count-- > 0 && --(f->count) >= 0) {
*(f->cur) = *str; *(f->cur) = *str;
++(f->cur); ++(f->cur);
++str; ++str;
} }
*pnumwritten = *pnumwritten + (int)(size_t)(str - string); *pnumwritten = *pnumwritten + (int)(size_t)(str - string);
if (f->count < 0) { if (f->count < 0) {
*pnumwritten = -1; *pnumwritten = -1;
} }
} }
#endif #endif
@@ -1,8 +1,9 @@
/* /*
* Copyright (c) Huawei Technologies Co., Ltd. 2014-2018. All rights reserved. * Copyright (c) Huawei Technologies Co., Ltd. 2014-2018. All rights reserved.
* Description: By defining corresponding macro for UNICODE string and including * Description: By defining corresponding macro for UNICODE string and including "output.inl",
* "output.inl", this file generates real underlying function used by printf * this file generates real underlying function used by printf family API.
* family API. Author: lishunda Create: 2014-02-25 * Author: lishunda
* Create: 2014-02-25
*/ */
/* If some platforms don't have wchar.h, dont't include it */ /* If some platforms don't have wchar.h, dont't include it */
@@ -10,7 +11,7 @@
/* If there is no macro above, it will cause compiling alarm */ /* If there is no macro above, it will cause compiling alarm */
#if defined(_MSC_VER) && (_MSC_VER >= 1400) #if defined(_MSC_VER) && (_MSC_VER >= 1400)
#ifndef _CRTIMP_ALTERNATIVE #ifndef _CRTIMP_ALTERNATIVE
#define _CRTIMP_ALTERNATIVE /* Comment microsoft *_s function */ #define _CRTIMP_ALTERNATIVE /* Comment microsoft *_s function */
#endif #endif
#ifndef __STDC_WANT_SECURE_LIB__ #ifndef __STDC_WANT_SECURE_LIB__
#define __STDC_WANT_SECURE_LIB__ 0 #define __STDC_WANT_SECURE_LIB__ 0
@@ -20,7 +21,7 @@
#endif #endif
/* Disable wchar func to clear vs warning */ /* Disable wchar func to clear vs warning */
#define SECUREC_ENABLE_WCHAR_FUNC 0 #define SECUREC_ENABLE_WCHAR_FUNC 0
#define SECUREC_FORMAT_OUTPUT_INPUT 1 #define SECUREC_FORMAT_OUTPUT_INPUT 1
#ifndef SECUREC_FOR_WCHAR #ifndef SECUREC_FOR_WCHAR
@@ -34,114 +35,108 @@
#include "secureprintoutput.h" #include "secureprintoutput.h"
#define SECUREC_CHAR(x) L##x #define SECUREC_CHAR(x) L ## x
#define SECUREC_WRITE_MULTI_CHAR SecWriteMultiCharW #define SECUREC_WRITE_MULTI_CHAR SecWriteMultiCharW
#define SECUREC_WRITE_STRING SecWriteStringW #define SECUREC_WRITE_STRING SecWriteStringW
SECUREC_INLINE void SecWriteCharW(wchar_t ch, SecPrintfStream *f, SECUREC_INLINE void SecWriteCharW(wchar_t ch, SecPrintfStream *f, int *pnumwritten);
int *pnumwritten); SECUREC_INLINE void SecWriteMultiCharW(wchar_t ch, int num, SecPrintfStream *f, int *pnumwritten);
SECUREC_INLINE void SecWriteMultiCharW(wchar_t ch, int num, SecPrintfStream *f, SECUREC_INLINE void SecWriteStringW(const wchar_t *string, int len, SecPrintfStream *f, int *pnumwritten);
int *pnumwritten); SECUREC_INLINE int SecPutWcharStrEndingZero(SecPrintfStream *str, int zeroCount);
SECUREC_INLINE void SecWriteStringW(const wchar_t *string, int len,
SecPrintfStream *f, int *pnumwritten);
SECUREC_INLINE int SecPutWcharStrEndingZero(SecPrintfStream *str,
int zeroCount);
#include "output.inl" #include "output.inl"
/* /*
* Wide character formatted output implementation * Wide character formatted output implementation
*/ */
int SecVswprintfImpl(wchar_t *string, size_t sizeInWchar, const wchar_t *format, int SecVswprintfImpl(wchar_t *string, size_t sizeInWchar, const wchar_t *format, va_list argList)
va_list argList) { {
SecPrintfStream str; SecPrintfStream str;
int retVal; /* If initialization causes e838 */ int retVal; /* If initialization causes e838 */
str.cur = (char *)string; str.cur = (char *)string;
/* This count include \0 character, Must be greater than zero */ /* This count include \0 character, Must be greater than zero */
str.count = (int)(sizeInWchar * sizeof(wchar_t)); str.count = (int)(sizeInWchar * sizeof(wchar_t));
retVal = SecOutputSW(&str, format, argList); retVal = SecOutputSW(&str, format, argList);
if (retVal >= 0 && if (retVal >= 0 && SecPutWcharStrEndingZero(&str, (int)sizeof(wchar_t)) == 0) {
SecPutWcharStrEndingZero(&str, (int)sizeof(wchar_t)) == 0) { return (retVal);
return (retVal); } else if (str.count < 0) {
} else if (str.count < 0) { /* The buffer was too small; we return truncation */
/* The buffer was too small; we return truncation */ string[sizeInWchar - 1] = L'\0';
string[sizeInWchar - 1] = L'\0'; return SECUREC_PRINTF_TRUNCATE;
return SECUREC_PRINTF_TRUNCATE; }
} string[0] = L'\0';
string[0] = L'\0'; return -1;
return -1;
} }
/* /*
* Output a wide character zero end into the SecPrintfStream structure * Output a wide character zero end into the SecPrintfStream structure
*/ */
SECUREC_INLINE int SecPutWcharStrEndingZero(SecPrintfStream *str, SECUREC_INLINE int SecPutWcharStrEndingZero(SecPrintfStream *str, int zeroCount)
int zeroCount) { {
int i = 0; int i = 0;
while (i < zeroCount && SecPutZeroChar(str) == 0) { while (i < zeroCount && SecPutZeroChar(str) == 0) {
++i; ++i;
} }
if (i == zeroCount) { if (i == zeroCount) {
return 0; return 0;
} }
return -1; return -1;
} }
/* /*
* Output a wide character into the SecPrintfStream structure * Output a wide character into the SecPrintfStream structure
*/ */
SECUREC_INLINE int SecPutCharW(wchar_t ch, SecPrintfStream *f) { SECUREC_INLINE int SecPutCharW(wchar_t ch, SecPrintfStream *f)
if (((f)->count -= (int)sizeof(wchar_t)) >= 0) { {
*(wchar_t *)(void *)(f->cur) = ch; if (((f)->count -= (int)sizeof(wchar_t)) >= 0) {
f->cur += sizeof(wchar_t); *(wchar_t *)(void *)(f->cur) = ch;
return 0; f->cur += sizeof(wchar_t);
} return 0;
return -1;
}
/*
* Output a wide character into the SecPrintfStream structure, returns the
* number of characters written
*/
SECUREC_INLINE void SecWriteCharW(wchar_t ch, SecPrintfStream *f,
int *pnumwritten) {
if (SecPutCharW(ch, f) == 0) {
*pnumwritten = *pnumwritten + 1;
} else {
*pnumwritten = -1;
}
}
/*
* Output multiple wide character into the SecPrintfStream structure, returns
* the number of characters written
*/
SECUREC_INLINE void SecWriteMultiCharW(wchar_t ch, int num, SecPrintfStream *f,
int *pnumwritten) {
int count = num;
while (count-- > 0) {
SecWriteCharW(ch, f, pnumwritten);
if (*pnumwritten == -1) {
break;
} }
} return -1;
} }
/* /*
* Output a wide string into the SecPrintfStream structure, returns the number * Output a wide character into the SecPrintfStream structure, returns the number of characters written
* of characters written
*/ */
SECUREC_INLINE void SecWriteStringW(const wchar_t *string, int len, SECUREC_INLINE void SecWriteCharW(wchar_t ch, SecPrintfStream *f, int *pnumwritten)
SecPrintfStream *f, int *pnumwritten) { {
const wchar_t *str = string; if (SecPutCharW(ch, f) == 0) {
int count = len; *pnumwritten = *pnumwritten + 1;
while (count-- > 0) { } else {
SecWriteCharW(*str, f, pnumwritten); *pnumwritten = -1;
++str;
if (*pnumwritten == -1) {
break;
} }
}
} }
/*
* Output multiple wide character into the SecPrintfStream structure, returns the number of characters written
*/
SECUREC_INLINE void SecWriteMultiCharW(wchar_t ch, int num, SecPrintfStream *f, int *pnumwritten)
{
int count = num;
while (count-- > 0) {
SecWriteCharW(ch, f, pnumwritten);
if (*pnumwritten == -1) {
break;
}
}
}
/*
* Output a wide string into the SecPrintfStream structure, returns the number of characters written
*/
SECUREC_INLINE void SecWriteStringW(const wchar_t *string, int len, SecPrintfStream *f, int *pnumwritten)
{
const wchar_t *str = string;
int count = len;
while (count-- > 0) {
SecWriteCharW(*str, f, pnumwritten);
++str;
if (*pnumwritten == -1) {
break;
}
}
}
@@ -11,19 +11,18 @@
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The snprintf_s function is equivalent to the snprintf function * The snprintf_s function is equivalent to the snprintf function
* except for the parameter destMax/count and the explicit * except for the parameter destMax/count and the explicit runtime-constraints violation
* runtime-constraints violation The snprintf_s function formats and stores * The snprintf_s function formats and stores count or fewer characters in
* count or fewer characters in strDest and appends a terminating null. Each * strDest and appends a terminating null. Each argument (if any) is converted
* argument (if any) is converted and output according to the corresponding * and output according to the corresponding format specification in format.
* format specification in format. The formatting is consistent with the printf * The formatting is consistent with the printf family of functions; If copying
* family of functions; If copying occurs between strings that overlap, the * occurs between strings that overlap, the behavior is undefined.
* behavior is undefined.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* strDest Storage location for the output. * strDest Storage location for the output.
* destMax The size of the storage location for output. Size * destMax The size of the storage location for output. Size
* in bytes for snprintf_s or size in words for * in bytes for snprintf_s or size in words for snwprintf_s.
* snwprintf_s. count Maximum number of character to store. * count Maximum number of character to store.
* format Format-control string. * format Format-control string.
* ... Optional arguments. * ... Optional arguments.
* *
@@ -31,26 +30,24 @@
* strDest is updated * strDest is updated
* *
* <RETURN VALUE> * <RETURN VALUE>
* return the number of characters written, not including the terminating * return the number of characters written, not including the terminating null
* null return -1 if an error occurs. return -1 if count < destMax and the * return -1 if an error occurs.
* output string has been truncated * return -1 if count < destMax and the output string has been truncated
* *
* If there is a runtime-constraint violation, strDest[0] will be set to the * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
* '\0' when strDest and destMax valid
* *
*/ */
int snprintf_s(char *strDest, size_t destMax, size_t count, const char *format, int snprintf_s(char *strDest, size_t destMax, size_t count, const char *format, ...)
...) { {
int ret; /* If initialization causes e838 */ int ret; /* If initialization causes e838 */
va_list argList; va_list argList;
va_start(argList, format); va_start(argList, format);
ret = vsnprintf_s(strDest, destMax, count, format, argList); ret = vsnprintf_s(strDest, destMax, count, format, argList);
va_end(argList); va_end(argList);
(void)argList; /* To clear e438 last value assigned not used , the compiler (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
will optimize this code */
return ret; return ret;
} }
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
EXPORT_SYMBOL(snprintf_s); EXPORT_SYMBOL(snprintf_s);
@@ -61,48 +58,47 @@ EXPORT_SYMBOL(snprintf_s);
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The snprintf_truncated_s function is equivalent to the snprintf function * The snprintf_truncated_s function is equivalent to the snprintf function
* except for the parameter destMax/count and the explicit * except for the parameter destMax/count and the explicit runtime-constraints violation
* runtime-constraints violation The snprintf_truncated_s function formats and * The snprintf_truncated_s function formats and stores count or fewer characters in
* stores count or fewer characters in strDest and appends a terminating null. * strDest and appends a terminating null. Each argument (if any) is converted
* Each argument (if any) is converted and output according to the corresponding * and output according to the corresponding format specification in format.
* format specification in format. The formatting is consistent with the printf * The formatting is consistent with the printf family of functions; If copying
* family of functions; If copying occurs between strings that overlap, the * occurs between strings that overlap, the behavior is undefined.
* behavior is undefined.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* strDest Storage location for the output. * strDest Storage location for the output.
* destMax The size of the storage location for output. Size * destMax The size of the storage location for output. Size
* in bytes for snprintf_truncated_s or size in * in bytes for snprintf_truncated_s or size in words for snwprintf_s.
* words for snwprintf_s. format Format-control string. * format Format-control string.
* ... Optional arguments. * ... Optional arguments.
* *
* <OUTPUT PARAMETERS> * <OUTPUT PARAMETERS>
* strDest is updated * strDest is updated
* *
* <RETURN VALUE> * <RETURN VALUE>
* return the number of characters written, not including the terminating * return the number of characters written, not including the terminating null
* null return -1 if an error occurs. return destMax-1 if output string has * return -1 if an error occurs.
* been truncated * return destMax-1 if output string has been truncated
* *
* If there is a runtime-constraint violation, strDest[0] will be set to the * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
* '\0' when strDest and destMax valid
* *
*/ */
int snprintf_truncated_s(char *strDest, size_t destMax, const char *format, int snprintf_truncated_s(char *strDest, size_t destMax, const char *format, ...)
...) { {
int ret; /* If initialization causes e838 */ int ret; /* If initialization causes e838 */
va_list argList; va_list argList;
va_start(argList, format); va_start(argList, format);
ret = vsnprintf_truncated_s(strDest, destMax, format, argList); ret = vsnprintf_truncated_s(strDest, destMax, format, argList);
va_end(argList); va_end(argList);
(void)argList; /* To clear e438 last value assigned not used , the compiler (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
will optimize this code */
return ret; return ret;
} }
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
EXPORT_SYMBOL(snprintf_truncated_s); EXPORT_SYMBOL(snprintf_truncated_s);
#endif #endif
#endif #endif
@@ -10,14 +10,13 @@
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The sprintf_s function is equivalent to the sprintf function * The sprintf_s function is equivalent to the sprintf function
* except for the parameter destMax and the explicit runtime-constraints * except for the parameter destMax and the explicit runtime-constraints violation
* violation The sprintf_s function formats and stores a series of characters * The sprintf_s function formats and stores a series of characters and values
* and values in strDest. Each argument (if any) is converted and output * in strDest. Each argument (if any) is converted and output according to
* according to the corresponding format specification in format. The format * the corresponding format specification in format. The format consists of
* consists of ordinary characters and has the same form and function as the * ordinary characters and has the same form and function as the format argument
* format argument for printf. A null character is appended after the last * for printf. A null character is appended after the last character written.
* character written. If copying occurs between strings that overlap, the * If copying occurs between strings that overlap, the behavior is undefined.
* behavior is undefined.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* strDest Storage location for output. * strDest Storage location for output.
@@ -29,24 +28,25 @@
* strDest is updated * strDest is updated
* *
* <RETURN VALUE> * <RETURN VALUE>
* return the number of bytes stored in strDest, not counting the terminating * return the number of bytes stored in strDest, not counting the terminating null character.
* null character. return -1 if an error occurred. * return -1 if an error occurred.
* *
* If there is a runtime-constraint violation, strDest[0] will be set to the * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
* '\0' when strDest and destMax valid
*/ */
int sprintf_s(char *strDest, size_t destMax, const char *format, ...) { int sprintf_s(char *strDest, size_t destMax, const char *format, ...)
int ret; /* If initialization causes e838 */ {
va_list argList; int ret; /* If initialization causes e838 */
va_list argList;
va_start(argList, format); va_start(argList, format);
ret = vsprintf_s(strDest, destMax, format, argList); ret = vsprintf_s(strDest, destMax, format, argList);
va_end(argList); va_end(argList);
(void)argList; /* To clear e438 last value assigned not used , the compiler (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
will optimize this code */
return ret; return ret;
} }
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
EXPORT_SYMBOL(sprintf_s); EXPORT_SYMBOL(sprintf_s);
#endif #endif
@@ -10,13 +10,13 @@
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The sscanf_s function is equivalent to fscanf_s, * The sscanf_s function is equivalent to fscanf_s,
* except that input is obtained from a string (specified by the argument * except that input is obtained from a string (specified by the argument buffer) rather than from a stream
* buffer) rather than from a stream The sscanf function reads data from buffer * The sscanf function reads data from buffer into the location given by each
* into the location given by each argument. Every argument must be a pointer to * argument. Every argument must be a pointer to a variable with a type that
* a variable with a type that corresponds to a type specifier in format. The * corresponds to a type specifier in format. The format argument controls the
* format argument controls the interpretation of the input fields and has the * interpretation of the input fields and has the same form and function as
* same form and function as the format argument for the scanf function. If * the format argument for the scanf function.
* copying takes place between strings that overlap, the behavior is undefined. * If copying takes place between strings that overlap, the behavior is undefined.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* buffer Stored data. * buffer Stored data.
@@ -27,23 +27,26 @@
* ... The converted value stored in user assigned address * ... The converted value stored in user assigned address
* *
* <RETURN VALUE> * <RETURN VALUE>
* Each of these functions returns the number of fields successfully * Each of these functions returns the number of fields successfully converted
* converted and assigned; the return value does not include fields that were * and assigned; the return value does not include fields that were read but
* read but not assigned. A return value of 0 indicates that no fields were * not assigned.
* assigned. return -1 if an error occurs. * A return value of 0 indicates that no fields were assigned.
* return -1 if an error occurs.
*/ */
int sscanf_s(const char *buffer, const char *format, ...) { int sscanf_s(const char *buffer, const char *format, ...)
int ret; /* If initialization causes e838 */ {
va_list argList; int ret; /* If initialization causes e838 */
va_list argList;
va_start(argList, format); va_start(argList, format);
ret = vsscanf_s(buffer, format, argList); ret = vsscanf_s(buffer, format, argList);
va_end(argList); va_end(argList);
(void)argList; /* To clear e438 last value assigned not used , the compiler (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
will optimize this code */
return ret; return ret;
} }
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
EXPORT_SYMBOL(sscanf_s); EXPORT_SYMBOL(sscanf_s);
#endif #endif
@@ -10,46 +10,44 @@
/* /*
* Befor this function, the basic parameter checking has been done * Befor this function, the basic parameter checking has been done
*/ */
SECUREC_INLINE errno_t SecDoCat(char *strDest, size_t destMax, SECUREC_INLINE errno_t SecDoCat(char *strDest, size_t destMax, const char *strSrc)
const char *strSrc) { {
size_t destLen; size_t destLen;
size_t srcLen; size_t srcLen;
size_t maxSrcLen; size_t maxSrcLen;
SECUREC_CALC_STR_LEN(strDest, destMax, &destLen); SECUREC_CALC_STR_LEN(strDest, destMax, &destLen);
/* Only optimize strSrc, do not apply this function to strDest */ /* Only optimize strSrc, do not apply this function to strDest */
maxSrcLen = destMax - destLen; maxSrcLen = destMax - destLen;
SECUREC_CALC_STR_LEN_OPT(strSrc, maxSrcLen, &srcLen); SECUREC_CALC_STR_LEN_OPT(strSrc, maxSrcLen, &srcLen);
if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) { if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) {
strDest[0] = '\0'; strDest[0] = '\0';
if (strDest + destLen <= strSrc && destLen == destMax) { if (strDest + destLen <= strSrc && destLen == destMax) {
SECUREC_ERROR_INVALID_PARAMTER("strcat_s"); SECUREC_ERROR_INVALID_PARAMTER("strcat_s");
return EINVAL_AND_RESET; return EINVAL_AND_RESET;
}
SECUREC_ERROR_BUFFER_OVERLAP("strcat_s");
return EOVERLAP_AND_RESET;
} }
SECUREC_ERROR_BUFFER_OVERLAP("strcat_s"); if (srcLen + destLen >= destMax || strDest == strSrc) {
return EOVERLAP_AND_RESET; strDest[0] = '\0';
} if (destLen == destMax) {
if (srcLen + destLen >= destMax || strDest == strSrc) { SECUREC_ERROR_INVALID_PARAMTER("strcat_s");
strDest[0] = '\0'; return EINVAL_AND_RESET;
if (destLen == destMax) { }
SECUREC_ERROR_INVALID_PARAMTER("strcat_s"); SECUREC_ERROR_INVALID_RANGE("strcat_s");
return EINVAL_AND_RESET; return ERANGE_AND_RESET;
} }
SECUREC_ERROR_INVALID_RANGE("strcat_s"); SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc, srcLen + 1); /* Single character length include \0 */
return ERANGE_AND_RESET; return EOK;
}
SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc,
srcLen + 1); /* Single character length include \0 */
return EOK;
} }
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The strcat_s function appends a copy of the string pointed to by strSrc * The strcat_s function appends a copy of the string pointed to by strSrc (including the terminating null character)
* (including the terminating null character) to the end of the string pointed * to the end of the string pointed to by strDest.
* to by strDest. The initial character of strSrc overwrites the terminating * The initial character of strSrc overwrites the terminating null character of strDest.
* null character of strDest. strcat_s will return EOVERLAP_AND_RESET if the * strcat_s will return EOVERLAP_AND_RESET if the source and destination strings overlap.
* source and destination strings overlap.
* *
* Note that the second parameter is the total size of the buffer, not the * Note that the second parameter is the total size of the buffer, not the
* remaining size. * remaining size.
@@ -64,34 +62,33 @@ SECUREC_INLINE errno_t SecDoCat(char *strDest, size_t destMax,
* *
* <RETURN VALUE> * <RETURN VALUE>
* EOK Success * EOK Success
* EINVAL strDest is NULL and destMax != 0 and destMax <= * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN
* SECUREC_STRING_MAX_LEN EINVAL_AND_RESET (strDest unterminated and all * EINVAL_AND_RESET (strDest unterminated and all other parameters are valid)or
* other parameters are valid)or (strDest != NULL and strSrc is NULL and destMax * (strDest != NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN)
* != 0 and destMax <= SECUREC_STRING_MAX_LEN) ERANGE destMax is 0 * ERANGE destMax is 0 and destMax > SECUREC_STRING_MAX_LEN
* and destMax > SECUREC_STRING_MAX_LEN ERANGE_AND_RESET strDest have not * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap
* enough space and all other parameters are valid and not overlap * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid
* EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all
* parameters are valid
* *
* If there is a runtime-constraint violation, strDest[0] will be set to the * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
* '\0' when strDest and destMax valid
*/ */
errno_t strcat_s(char *strDest, size_t destMax, const char *strSrc) { errno_t strcat_s(char *strDest, size_t destMax, const char *strSrc)
if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) { {
SECUREC_ERROR_INVALID_RANGE("strcat_s"); if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) {
return ERANGE; SECUREC_ERROR_INVALID_RANGE("strcat_s");
} return ERANGE;
if (strDest == NULL || strSrc == NULL) {
SECUREC_ERROR_INVALID_PARAMTER("strcat_s");
if (strDest != NULL) {
strDest[0] = '\0';
return EINVAL_AND_RESET;
} }
return EINVAL; if (strDest == NULL || strSrc == NULL) {
} SECUREC_ERROR_INVALID_PARAMTER("strcat_s");
return SecDoCat(strDest, destMax, strSrc); if (strDest != NULL) {
strDest[0] = '\0';
return EINVAL_AND_RESET;
}
return EINVAL;
}
return SecDoCat(strDest, destMax, strSrc);
} }
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
EXPORT_SYMBOL(strcat_s); EXPORT_SYMBOL(strcat_s);
#endif #endif
+276 -313
View File
@@ -18,317 +18,282 @@
#if (SECUREC_IN_KERNEL == 0) && SECUREC_STRCPY_WITH_PERFORMANCE #if (SECUREC_IN_KERNEL == 0) && SECUREC_STRCPY_WITH_PERFORMANCE
#ifndef SECUREC_STRCOPY_THRESHOLD_SIZE #ifndef SECUREC_STRCOPY_THRESHOLD_SIZE
#define SECUREC_STRCOPY_THRESHOLD_SIZE 32UL #define SECUREC_STRCOPY_THRESHOLD_SIZE 32UL
#endif #endif
/* The purpose of converting to void is to clean up the alarm */ /* The purpose of converting to void is to clean up the alarm */
#define SECUREC_SMALL_STR_COPY(strDest, strSrc, srcStrLen) \ #define SECUREC_SMALL_STR_COPY(strDest, strSrc, srcStrLen) do { \
do { \ if (SECUREC_ADDR_ALIGNED_8(strDest) && SECUREC_ADDR_ALIGNED_8(strSrc)) { \
if (SECUREC_ADDR_ALIGNED_8(strDest) && SECUREC_ADDR_ALIGNED_8(strSrc)) { \ /* Use struct assignment */ \
/* Use struct assignment */ \ switch (srcStrLen) { \
switch (srcStrLen) { \ case 1: \
case 1: \ *(SecStrBuf1 *)(void *)(strDest) = *(const SecStrBuf1 *)(const void *)(strSrc); \
*(SecStrBuf1 *)(void *)(strDest) = \ break; \
*(const SecStrBuf1 *)(const void *)(strSrc); \ case 2: \
break; \ *(SecStrBuf2 *)(void *)(strDest) = *(const SecStrBuf2 *)(const void *)(strSrc); \
case 2: \ break; \
*(SecStrBuf2 *)(void *)(strDest) = \ case 3: \
*(const SecStrBuf2 *)(const void *)(strSrc); \ *(SecStrBuf3 *)(void *)(strDest) = *(const SecStrBuf3 *)(const void *)(strSrc); \
break; \ break; \
case 3: \ case 4: \
*(SecStrBuf3 *)(void *)(strDest) = \ *(SecStrBuf4 *)(void *)(strDest) = *(const SecStrBuf4 *)(const void *)(strSrc); \
*(const SecStrBuf3 *)(const void *)(strSrc); \ break; \
break; \ case 5: \
case 4: \ *(SecStrBuf5 *)(void *)(strDest) = *(const SecStrBuf5 *)(const void *)(strSrc); \
*(SecStrBuf4 *)(void *)(strDest) = \ break; \
*(const SecStrBuf4 *)(const void *)(strSrc); \ case 6: \
break; \ *(SecStrBuf6 *)(void *)(strDest) = *(const SecStrBuf6 *)(const void *)(strSrc); \
case 5: \ break; \
*(SecStrBuf5 *)(void *)(strDest) = \ case 7: \
*(const SecStrBuf5 *)(const void *)(strSrc); \ *(SecStrBuf7 *)(void *)(strDest) = *(const SecStrBuf7 *)(const void *)(strSrc); \
break; \ break; \
case 6: \ case 8: \
*(SecStrBuf6 *)(void *)(strDest) = \ *(SecStrBuf8 *)(void *)(strDest) = *(const SecStrBuf8 *)(const void *)(strSrc); \
*(const SecStrBuf6 *)(const void *)(strSrc); \ break; \
break; \ case 9: \
case 7: \ *(SecStrBuf9 *)(void *)(strDest) = *(const SecStrBuf9 *)(const void *)(strSrc); \
*(SecStrBuf7 *)(void *)(strDest) = \ break; \
*(const SecStrBuf7 *)(const void *)(strSrc); \ case 10: \
break; \ *(SecStrBuf10 *)(void *)(strDest) = *(const SecStrBuf10 *)(const void *)(strSrc); \
case 8: \ break; \
*(SecStrBuf8 *)(void *)(strDest) = \ case 11: \
*(const SecStrBuf8 *)(const void *)(strSrc); \ *(SecStrBuf11 *)(void *)(strDest) = *(const SecStrBuf11 *)(const void *)(strSrc); \
break; \ break; \
case 9: \ case 12: \
*(SecStrBuf9 *)(void *)(strDest) = \ *(SecStrBuf12 *)(void *)(strDest) = *(const SecStrBuf12 *)(const void *)(strSrc); \
*(const SecStrBuf9 *)(const void *)(strSrc); \ break; \
break; \ case 13: \
case 10: \ *(SecStrBuf13 *)(void *)(strDest) = *(const SecStrBuf13 *)(const void *)(strSrc); \
*(SecStrBuf10 *)(void *)(strDest) = \ break; \
*(const SecStrBuf10 *)(const void *)(strSrc); \ case 14: \
break; \ *(SecStrBuf14 *)(void *)(strDest) = *(const SecStrBuf14 *)(const void *)(strSrc); \
case 11: \ break; \
*(SecStrBuf11 *)(void *)(strDest) = \ case 15: \
*(const SecStrBuf11 *)(const void *)(strSrc); \ *(SecStrBuf15 *)(void *)(strDest) = *(const SecStrBuf15 *)(const void *)(strSrc); \
break; \ break; \
case 12: \ case 16: \
*(SecStrBuf12 *)(void *)(strDest) = \ *(SecStrBuf16 *)(void *)(strDest) = *(const SecStrBuf16 *)(const void *)(strSrc); \
*(const SecStrBuf12 *)(const void *)(strSrc); \ break; \
break; \ case 17: \
case 13: \ *(SecStrBuf17 *)(void *)(strDest) = *(const SecStrBuf17 *)(const void *)(strSrc); \
*(SecStrBuf13 *)(void *)(strDest) = \ break; \
*(const SecStrBuf13 *)(const void *)(strSrc); \ case 18: \
break; \ *(SecStrBuf18 *)(void *)(strDest) = *(const SecStrBuf18 *)(const void *)(strSrc); \
case 14: \ break; \
*(SecStrBuf14 *)(void *)(strDest) = \ case 19: \
*(const SecStrBuf14 *)(const void *)(strSrc); \ *(SecStrBuf19 *)(void *)(strDest) = *(const SecStrBuf19 *)(const void *)(strSrc); \
break; \ break; \
case 15: \ case 20: \
*(SecStrBuf15 *)(void *)(strDest) = \ *(SecStrBuf20 *)(void *)(strDest) = *(const SecStrBuf20 *)(const void *)(strSrc); \
*(const SecStrBuf15 *)(const void *)(strSrc); \ break; \
break; \ case 21: \
case 16: \ *(SecStrBuf21 *)(void *)(strDest) = *(const SecStrBuf21 *)(const void *)(strSrc); \
*(SecStrBuf16 *)(void *)(strDest) = \ break; \
*(const SecStrBuf16 *)(const void *)(strSrc); \ case 22: \
break; \ *(SecStrBuf22 *)(void *)(strDest) = *(const SecStrBuf22 *)(const void *)(strSrc); \
case 17: \ break; \
*(SecStrBuf17 *)(void *)(strDest) = \ case 23: \
*(const SecStrBuf17 *)(const void *)(strSrc); \ *(SecStrBuf23 *)(void *)(strDest) = *(const SecStrBuf23 *)(const void *)(strSrc); \
break; \ break; \
case 18: \ case 24: \
*(SecStrBuf18 *)(void *)(strDest) = \ *(SecStrBuf24 *)(void *)(strDest) = *(const SecStrBuf24 *)(const void *)(strSrc); \
*(const SecStrBuf18 *)(const void *)(strSrc); \ break; \
break; \ case 25: \
case 19: \ *(SecStrBuf25 *)(void *)(strDest) = *(const SecStrBuf25 *)(const void *)(strSrc); \
*(SecStrBuf19 *)(void *)(strDest) = \ break; \
*(const SecStrBuf19 *)(const void *)(strSrc); \ case 26: \
break; \ *(SecStrBuf26 *)(void *)(strDest) = *(const SecStrBuf26 *)(const void *)(strSrc); \
case 20: \ break; \
*(SecStrBuf20 *)(void *)(strDest) = \ case 27: \
*(const SecStrBuf20 *)(const void *)(strSrc); \ *(SecStrBuf27 *)(void *)(strDest) = *(const SecStrBuf27 *)(const void *)(strSrc); \
break; \ break; \
case 21: \ case 28: \
*(SecStrBuf21 *)(void *)(strDest) = \ *(SecStrBuf28 *)(void *)(strDest) = *(const SecStrBuf28 *)(const void *)(strSrc); \
*(const SecStrBuf21 *)(const void *)(strSrc); \ break; \
break; \ case 29: \
case 22: \ *(SecStrBuf29 *)(void *)(strDest) = *(const SecStrBuf29 *)(const void *)(strSrc); \
*(SecStrBuf22 *)(void *)(strDest) = \ break; \
*(const SecStrBuf22 *)(const void *)(strSrc); \ case 30: \
break; \ *(SecStrBuf30 *)(void *)(strDest) = *(const SecStrBuf30 *)(const void *)(strSrc); \
case 23: \ break; \
*(SecStrBuf23 *)(void *)(strDest) = \ case 31: \
*(const SecStrBuf23 *)(const void *)(strSrc); \ *(SecStrBuf31 *)(void *)(strDest) = *(const SecStrBuf31 *)(const void *)(strSrc); \
break; \ break; \
case 24: \ case 32: \
*(SecStrBuf24 *)(void *)(strDest) = \ *(SecStrBuf32 *)(void *)(strDest) = *(const SecStrBuf32 *)(const void *)(strSrc); \
*(const SecStrBuf24 *)(const void *)(strSrc); \ break; \
break; \ default: \
case 25: \ break; \
*(SecStrBuf25 *)(void *)(strDest) = \ } /* END switch */ \
*(const SecStrBuf25 *)(const void *)(strSrc); \ } else { \
break; \ char *tmpStrDest = (char *)(strDest); \
case 26: \ const char *tmpStrSrc = (const char *)(strSrc); \
*(SecStrBuf26 *)(void *)(strDest) = \ switch (srcStrLen) { \
*(const SecStrBuf26 *)(const void *)(strSrc); \ case 32: \
break; \ *(tmpStrDest++) = *(tmpStrSrc++); \
case 27: \ /* fall-through */ /* FALLTHRU */ \
*(SecStrBuf27 *)(void *)(strDest) = \ case 31: \
*(const SecStrBuf27 *)(const void *)(strSrc); \ *(tmpStrDest++) = *(tmpStrSrc++); \
break; \ /* fall-through */ /* FALLTHRU */ \
case 28: \ case 30: \
*(SecStrBuf28 *)(void *)(strDest) = \ *(tmpStrDest++) = *(tmpStrSrc++); \
*(const SecStrBuf28 *)(const void *)(strSrc); \ /* fall-through */ /* FALLTHRU */ \
break; \ case 29: \
case 29: \ *(tmpStrDest++) = *(tmpStrSrc++); \
*(SecStrBuf29 *)(void *)(strDest) = \ /* fall-through */ /* FALLTHRU */ \
*(const SecStrBuf29 *)(const void *)(strSrc); \ case 28: \
break; \ *(tmpStrDest++) = *(tmpStrSrc++); \
case 30: \ /* fall-through */ /* FALLTHRU */ \
*(SecStrBuf30 *)(void *)(strDest) = \ case 27: \
*(const SecStrBuf30 *)(const void *)(strSrc); \ *(tmpStrDest++) = *(tmpStrSrc++); \
break; \ /* fall-through */ /* FALLTHRU */ \
case 31: \ case 26: \
*(SecStrBuf31 *)(void *)(strDest) = \ *(tmpStrDest++) = *(tmpStrSrc++); \
*(const SecStrBuf31 *)(const void *)(strSrc); \ /* fall-through */ /* FALLTHRU */ \
break; \ case 25: \
case 32: \ *(tmpStrDest++) = *(tmpStrSrc++); \
*(SecStrBuf32 *)(void *)(strDest) = \ /* fall-through */ /* FALLTHRU */ \
*(const SecStrBuf32 *)(const void *)(strSrc); \ case 24: \
break; \ *(tmpStrDest++) = *(tmpStrSrc++); \
default: \ /* fall-through */ /* FALLTHRU */ \
break; \ case 23: \
} /* END switch */ \ *(tmpStrDest++) = *(tmpStrSrc++); \
} else { \ /* fall-through */ /* FALLTHRU */ \
char *tmpStrDest = (char *)(strDest); \ case 22: \
const char *tmpStrSrc = (const char *)(strSrc); \ *(tmpStrDest++) = *(tmpStrSrc++); \
switch (srcStrLen) { \ /* fall-through */ /* FALLTHRU */ \
case 32: \ case 21: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 31: \ case 20: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 30: \ case 19: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 29: \ case 18: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 28: \ case 17: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 27: \ case 16: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 26: \ case 15: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 25: \ case 14: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 24: \ case 13: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 23: \ case 12: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 22: \ case 11: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 21: \ case 10: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 20: \ case 9: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 19: \ case 8: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 18: \ case 7: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 17: \ case 6: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 16: \ case 5: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 15: \ case 4: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 14: \ case 3: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 13: \ case 2: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 12: \ case 1: \
*(tmpStrDest++) = *(tmpStrSrc++); \ *(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \ /* fall-through */ /* FALLTHRU */ \
case 11: \ default: \
*(tmpStrDest++) = *(tmpStrSrc++); \ break; \
/* fall-through */ /* FALLTHRU */ \ } \
case 10: \ } \
*(tmpStrDest++) = *(tmpStrSrc++); \ } SECUREC_WHILE_ZERO
/* fall-through */ /* FALLTHRU */ \
case 9: \
*(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \
case 8: \
*(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \
case 7: \
*(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \
case 6: \
*(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \
case 5: \
*(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \
case 4: \
*(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \
case 3: \
*(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \
case 2: \
*(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \
case 1: \
*(tmpStrDest++) = *(tmpStrSrc++); \
/* fall-through */ /* FALLTHRU */ \
default: \
break; \
} \
} \
} \
SECUREC_WHILE_ZERO
#endif #endif
#if SECUREC_IN_KERNEL || (SECUREC_STRCPY_WITH_PERFORMANCE == 0) #if SECUREC_IN_KERNEL || (SECUREC_STRCPY_WITH_PERFORMANCE == 0)
#define SECUREC_STRCPY_OPT(dest, src, lenWithTerm) \ #define SECUREC_STRCPY_OPT(dest, src, lenWithTerm) SECUREC_MEMCPY_WARP_OPT((dest), (src), (lenWithTerm))
SECUREC_MEMCPY_WARP_OPT((dest), (src), (lenWithTerm))
#else #else
/* /*
* Performance optimization. lenWithTerm include '\0' * Performance optimization. lenWithTerm include '\0'
*/ */
#define SECUREC_STRCPY_OPT(dest, src, lenWithTerm) \ #define SECUREC_STRCPY_OPT(dest, src, lenWithTerm) do { \
do { \ if ((lenWithTerm) > SECUREC_STRCOPY_THRESHOLD_SIZE) { \
if ((lenWithTerm) > SECUREC_STRCOPY_THRESHOLD_SIZE) { \ SECUREC_MEMCPY_WARP_OPT((dest), (src), (lenWithTerm)); \
SECUREC_MEMCPY_WARP_OPT((dest), (src), (lenWithTerm)); \ } else { \
} else { \ SECUREC_SMALL_STR_COPY((dest), (src), (lenWithTerm)); \
SECUREC_SMALL_STR_COPY((dest), (src), (lenWithTerm)); \ } \
} \ } SECUREC_WHILE_ZERO
} \
SECUREC_WHILE_ZERO
#endif #endif
/* /*
* Check Src Range * Check Src Range
*/ */
SECUREC_INLINE errno_t CheckSrcRange(char *strDest, size_t destMax, SECUREC_INLINE errno_t CheckSrcRange(char *strDest, size_t destMax, const char *strSrc)
const char *strSrc) { {
size_t tmpDestMax = destMax; size_t tmpDestMax = destMax;
const char *tmpSrc = strSrc; const char *tmpSrc = strSrc;
/* Use destMax as boundary checker and destMax must be greater than zero */ /* Use destMax as boundary checker and destMax must be greater than zero */
while (*(tmpSrc) != '\0' && tmpDestMax > 0) { while (*(tmpSrc) != '\0' && tmpDestMax > 0) {
++tmpSrc; ++tmpSrc;
--tmpDestMax; --tmpDestMax;
} }
if (tmpDestMax == 0) { if (tmpDestMax == 0) {
strDest[0] = '\0'; strDest[0] = '\0';
SECUREC_ERROR_INVALID_RANGE("strcpy_s"); SECUREC_ERROR_INVALID_RANGE("strcpy_s");
return ERANGE_AND_RESET; return ERANGE_AND_RESET;
} }
return EOK; return EOK;
} }
/* /*
* Handling errors * Handling errors
*/ */
errno_t strcpy_error(char *strDest, size_t destMax, const char *strSrc) { errno_t strcpy_error(char *strDest, size_t destMax, const char *strSrc)
if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) { {
SECUREC_ERROR_INVALID_RANGE("strcpy_s"); if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) {
return ERANGE; SECUREC_ERROR_INVALID_RANGE("strcpy_s");
} else if (strDest == NULL || strSrc == NULL) { return ERANGE;
SECUREC_ERROR_INVALID_PARAMTER("strcpy_s"); } else if (strDest == NULL || strSrc == NULL) {
if (strDest != NULL) { SECUREC_ERROR_INVALID_PARAMTER("strcpy_s");
strDest[0] = '\0'; if (strDest != NULL) {
return EINVAL_AND_RESET; strDest[0] = '\0';
return EINVAL_AND_RESET;
}
return EINVAL;
} }
return EINVAL; return CheckSrcRange(strDest, destMax, strSrc);
}
return CheckSrcRange(strDest, destMax, strSrc);
} }
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The strcpy_s function copies the string pointed to strSrc * The strcpy_s function copies the string pointed to strSrc
* (including the terminating null character) into the array pointed to * (including the terminating null character) into the array pointed to by strDest
* by strDest The destination string must be large enough to hold the source * The destination string must be large enough to hold the source string,
* string, including the terminating null character. strcpy_s will return * including the terminating null character. strcpy_s will return EOVERLAP_AND_RESET
* EOVERLAP_AND_RESET if the source and destination strings overlap. * if the source and destination strings overlap.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* strDest Location of destination string buffer * strDest Location of destination string buffer
@@ -340,40 +305,38 @@ errno_t strcpy_error(char *strDest, size_t destMax, const char *strSrc) {
* *
* <RETURN VALUE> * <RETURN VALUE>
* EOK Success * EOK Success
* EINVAL strDest is NULL and destMax != 0 and * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN
* destMax <= SECUREC_STRING_MAX_LEN EINVAL_AND_RESET strDest != NULL and * EINVAL_AND_RESET strDest != NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN
* strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN ERANGE * ERANGE destMax is 0 and destMax > SECUREC_STRING_MAX_LEN
* destMax is 0 and destMax > SECUREC_STRING_MAX_LEN ERANGE_AND_RESET strDest * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap
* have not enough space and all other parameters are valid and not overlap * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid
* EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all
* parameters are valid
* *
* If there is a runtime-constraint violation, strDest[0] will be set to the * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
* '\0' when strDest and destMax valid
*/ */
errno_t strcpy_s(char *strDest, size_t destMax, const char *strSrc) { errno_t strcpy_s(char *strDest, size_t destMax, const char *strSrc)
if ((destMax > 0 && destMax <= SECUREC_STRING_MAX_LEN && strDest != NULL && {
strSrc != NULL && strDest != strSrc)) { if ((destMax > 0 && destMax <= SECUREC_STRING_MAX_LEN && strDest != NULL && strSrc != NULL && strDest != strSrc)) {
size_t srcStrLen; size_t srcStrLen;
SECUREC_CALC_STR_LEN(strSrc, destMax, &srcStrLen); SECUREC_CALC_STR_LEN(strSrc, destMax, &srcStrLen);
++srcStrLen; /* The length include '\0' */ ++srcStrLen; /* The length include '\0' */
if (srcStrLen <= destMax) { if (srcStrLen <= destMax) {
/* Use mem overlap check include '\0' */ /* Use mem overlap check include '\0' */
if (SECUREC_MEMORY_NO_OVERLAP(strDest, strSrc, srcStrLen)) { if (SECUREC_MEMORY_NO_OVERLAP(strDest, strSrc, srcStrLen)) {
/* Performance optimization srcStrLen include '\0' */ /* Performance optimization srcStrLen include '\0' */
SECUREC_STRCPY_OPT(strDest, strSrc, srcStrLen); SECUREC_STRCPY_OPT(strDest, strSrc, srcStrLen);
return EOK; return EOK;
} else { } else {
strDest[0] = '\0'; strDest[0] = '\0';
SECUREC_ERROR_BUFFER_OVERLAP("strcpy_s"); SECUREC_ERROR_BUFFER_OVERLAP("strcpy_s");
return EOVERLAP_AND_RESET; return EOVERLAP_AND_RESET;
} }
}
} }
} return strcpy_error(strDest, destMax, strSrc);
return strcpy_error(strDest, destMax, strSrc);
} }
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
EXPORT_SYMBOL(strcpy_s); EXPORT_SYMBOL(strcpy_s);
#endif #endif
@@ -10,53 +10,52 @@
/* /*
* Befor this function, the basic parameter checking has been done * Befor this function, the basic parameter checking has been done
*/ */
SECUREC_INLINE errno_t SecDoCatLimit(char *strDest, size_t destMax, SECUREC_INLINE errno_t SecDoCatLimit(char *strDest, size_t destMax, const char *strSrc, size_t count)
const char *strSrc, size_t count) { {
size_t destLen; size_t destLen;
size_t srcLen; size_t srcLen;
SECUREC_CALC_STR_LEN(strDest, destMax, &destLen); SECUREC_CALC_STR_LEN(strDest, destMax, &destLen);
/* /*
* The strSrc is no longer optimized. The reason is that when count is small, * The strSrc is no longer optimized. The reason is that when count is small,
* the efficiency of strnlen is higher than that of self realization. * the efficiency of strnlen is higher than that of self realization.
*/ */
SECUREC_CALC_STR_LEN(strSrc, count, &srcLen); SECUREC_CALC_STR_LEN(strSrc, count, &srcLen);
if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) { if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) {
strDest[0] = '\0'; strDest[0] = '\0';
if (strDest + destLen <= strSrc && destLen == destMax) { if (strDest + destLen <= strSrc && destLen == destMax) {
SECUREC_ERROR_INVALID_PARAMTER("strncat_s"); SECUREC_ERROR_INVALID_PARAMTER("strncat_s");
return EINVAL_AND_RESET; return EINVAL_AND_RESET;
}
SECUREC_ERROR_BUFFER_OVERLAP("strncat_s");
return EOVERLAP_AND_RESET;
} }
SECUREC_ERROR_BUFFER_OVERLAP("strncat_s"); if (srcLen + destLen >= destMax || strDest == strSrc) {
return EOVERLAP_AND_RESET; strDest[0] = '\0';
} if (destLen == destMax) {
if (srcLen + destLen >= destMax || strDest == strSrc) { SECUREC_ERROR_INVALID_PARAMTER("strncat_s");
strDest[0] = '\0'; return EINVAL_AND_RESET;
if (destLen == destMax) { }
SECUREC_ERROR_INVALID_PARAMTER("strncat_s"); SECUREC_ERROR_INVALID_RANGE("strncat_s");
return EINVAL_AND_RESET; return ERANGE_AND_RESET;
} }
SECUREC_ERROR_INVALID_RANGE("strncat_s"); SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc, srcLen); /* No terminator */
return ERANGE_AND_RESET; *(strDest + destLen + srcLen) = '\0';
} return EOK;
SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc,
srcLen); /* No terminator */
*(strDest + destLen + srcLen) = '\0';
return EOK;
} }
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The strncat_s function appends not more than n successive characters * The strncat_s function appends not more than n successive characters
* (not including the terminating null character) * (not including the terminating null character)
* from the array pointed to by strSrc to the end of the string pointed to * from the array pointed to by strSrc to the end of the string pointed to by strDest
* by strDest The strncat_s function try to append the first D characters of * The strncat_s function try to append the first D characters of strSrc to
* strSrc to the end of strDest, where D is the lesser of count and the length * the end of strDest, where D is the lesser of count and the length of strSrc.
* of strSrc. If appending those D characters will fit within strDest (whose * If appending those D characters will fit within strDest (whose size is given
* size is given as destMax) and still leave room for a null terminator, then * as destMax) and still leave room for a null terminator, then those characters
* those characters are appended, starting at the original terminating null of * are appended, starting at the original terminating null of strDest, and a
* strDest, and a new terminating null is appended; otherwise, strDest[0] is set * new terminating null is appended; otherwise, strDest[0] is set to the null
* to the null character. * character.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* strDest Null-terminated destination string. * strDest Null-terminated destination string.
@@ -69,47 +68,45 @@ SECUREC_INLINE errno_t SecDoCatLimit(char *strDest, size_t destMax,
* *
* <RETURN VALUE> * <RETURN VALUE>
* EOK Success * EOK Success
* EINVAL strDest is NULL and destMax != 0 and destMax <= * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN
* SECUREC_STRING_MAX_LEN EINVAL_AND_RESET (strDest unterminated and all * EINVAL_AND_RESET (strDest unterminated and all other parameters are valid)or
* other parameters are valid)or (strDest != NULL and strSrc is NULL and * (strDest != NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN)
* destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN) ERANGE destMax is 0 and * ERANGE destMax is 0 and destMax > SECUREC_STRING_MAX_LEN
* destMax > SECUREC_STRING_MAX_LEN ERANGE_AND_RESET strDest have not * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap
* enough space and all other parameters are valid and not overlap * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid
* EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all
* parameters are valid
* *
* If there is a runtime-constraint violation, strDest[0] will be set to the * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
* '\0' when strDest and destMax valid
*/ */
errno_t strncat_s(char *strDest, size_t destMax, const char *strSrc, errno_t strncat_s(char *strDest, size_t destMax, const char *strSrc, size_t count)
size_t count) { {
if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) { if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) {
SECUREC_ERROR_INVALID_RANGE("strncat_s"); SECUREC_ERROR_INVALID_RANGE("strncat_s");
return ERANGE; return ERANGE;
} }
if (strDest == NULL || strSrc == NULL) { if (strDest == NULL || strSrc == NULL) {
SECUREC_ERROR_INVALID_PARAMTER("strncat_s"); SECUREC_ERROR_INVALID_PARAMTER("strncat_s");
if (strDest != NULL) { if (strDest != NULL) {
strDest[0] = '\0'; strDest[0] = '\0';
return EINVAL_AND_RESET; return EINVAL_AND_RESET;
} }
return EINVAL; return EINVAL;
}
if (count > SECUREC_STRING_MAX_LEN) {
#ifdef SECUREC_COMPATIBLE_WIN_FORMAT
if (count == (size_t)(-1)) {
/* Windows internal functions may pass in -1 when calling this function */
return SecDoCatLimit(strDest, destMax, strSrc, destMax);
} }
if (count > SECUREC_STRING_MAX_LEN) {
#ifdef SECUREC_COMPATIBLE_WIN_FORMAT
if (count == (size_t)(-1)) {
/* Windows internal functions may pass in -1 when calling this function */
return SecDoCatLimit(strDest, destMax, strSrc, destMax);
}
#endif #endif
strDest[0] = '\0'; strDest[0] = '\0';
SECUREC_ERROR_INVALID_RANGE("strncat_s"); SECUREC_ERROR_INVALID_RANGE("strncat_s");
return ERANGE_AND_RESET; return ERANGE_AND_RESET;
} }
return SecDoCatLimit(strDest, destMax, strSrc, count); return SecDoCatLimit(strDest, destMax, strSrc, count);
} }
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
EXPORT_SYMBOL(strncat_s); EXPORT_SYMBOL(strncat_s);
#endif #endif
@@ -13,134 +13,124 @@
#include "securecutil.h" #include "securecutil.h"
#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) #if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
#define SECUREC_STRNCPY_PARAM_OK(strDest, destMax, strSrc, count) \ #define SECUREC_STRNCPY_PARAM_OK(strDest, destMax, strSrc, count) \
(((destMax) > 0 && (destMax) <= SECUREC_STRING_MAX_LEN && \ (((destMax) > 0 && (destMax) <= SECUREC_STRING_MAX_LEN && (strDest) != NULL && (strSrc) != NULL && \
(strDest) != NULL && (strSrc) != NULL && \ ((count) <= SECUREC_STRING_MAX_LEN || (count) == ((size_t)(-1))) && (count) > 0))
((count) <= SECUREC_STRING_MAX_LEN || (count) == ((size_t)(-1))) && \
(count) > 0))
#else #else
#define SECUREC_STRNCPY_PARAM_OK(strDest, destMax, strSrc, count) \ #define SECUREC_STRNCPY_PARAM_OK(strDest, destMax, strSrc, count) \
(((destMax) > 0 && (destMax) <= SECUREC_STRING_MAX_LEN && \ (((destMax) > 0 && (destMax) <= SECUREC_STRING_MAX_LEN && (strDest) != NULL && (strSrc) != NULL && \
(strDest) != NULL && (strSrc) != NULL && \
(count) <= SECUREC_STRING_MAX_LEN && (count) > 0)) (count) <= SECUREC_STRING_MAX_LEN && (count) > 0))
#endif #endif
/* /*
* Check Src Count Range * Check Src Count Range
*/ */
SECUREC_INLINE errno_t CheckSrcCountRange(char *strDest, size_t destMax, SECUREC_INLINE errno_t CheckSrcCountRange(char *strDest, size_t destMax, const char *strSrc, size_t count)
const char *strSrc, size_t count) { {
size_t tmpDestMax = destMax; size_t tmpDestMax = destMax;
size_t tmpCount = count; size_t tmpCount = count;
const char *endPos = strSrc; const char *endPos = strSrc;
/* Use destMax and count as boundary checker and destMax must be greater than /* Use destMax and count as boundary checker and destMax must be greater than zero */
* zero */ while (*(endPos) != '\0' && tmpDestMax > 0 && tmpCount > 0) {
while (*(endPos) != '\0' && tmpDestMax > 0 && tmpCount > 0) { ++endPos;
++endPos; --tmpCount;
--tmpCount; --tmpDestMax;
--tmpDestMax; }
} if (tmpDestMax == 0) {
if (tmpDestMax == 0) { strDest[0] = '\0';
strDest[0] = '\0'; SECUREC_ERROR_INVALID_RANGE("strncpy_s");
SECUREC_ERROR_INVALID_RANGE("strncpy_s"); return ERANGE_AND_RESET;
return ERANGE_AND_RESET; }
} return EOK;
return EOK;
} }
/* /*
* Handling errors, when dest euqal src return EOK * Handling errors, when dest euqal src return EOK
*/ */
errno_t strncpy_error(char *strDest, size_t destMax, const char *strSrc, errno_t strncpy_error(char *strDest, size_t destMax, const char *strSrc, size_t count)
size_t count) { {
if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) { if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) {
SECUREC_ERROR_INVALID_RANGE("strncpy_s"); SECUREC_ERROR_INVALID_RANGE("strncpy_s");
return ERANGE; return ERANGE;
} else if (strDest == NULL || strSrc == NULL) { } else if (strDest == NULL || strSrc == NULL) {
SECUREC_ERROR_INVALID_PARAMTER("strncpy_s"); SECUREC_ERROR_INVALID_PARAMTER("strncpy_s");
if (strDest != NULL) { if (strDest != NULL) {
strDest[0] = '\0'; strDest[0] = '\0';
return EINVAL_AND_RESET; return EINVAL_AND_RESET;
}
return EINVAL;
} else if (count > SECUREC_STRING_MAX_LEN) {
strDest[0] = '\0'; /* Clear dest string */
SECUREC_ERROR_INVALID_RANGE("strncpy_s");
return ERANGE_AND_RESET;
} else if (count == 0) {
strDest[0] = '\0';
return EOK;
} }
return EINVAL;
} else if (count > SECUREC_STRING_MAX_LEN) {
strDest[0] = '\0'; /* Clear dest string */
SECUREC_ERROR_INVALID_RANGE("strncpy_s");
return ERANGE_AND_RESET;
} else if (count == 0) {
strDest[0] = '\0';
return EOK;
}
return CheckSrcCountRange(strDest, destMax, strSrc, count); return CheckSrcCountRange(strDest, destMax, strSrc, count);
} }
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The strncpy_s function copies not more than n successive characters (not * The strncpy_s function copies not more than n successive characters (not including the terminating null character)
* including the terminating null character) from the array pointed to by strSrc * from the array pointed to by strSrc to the array pointed to by strDest.
* to the array pointed to by strDest.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* strDest Destination string. * strDest Destination string.
* destMax The size of the destination string, in * destMax The size of the destination string, in characters.
* characters. strSrc Source string. count Number of * strSrc Source string.
* characters to be copied. * count Number of characters to be copied.
* *
* <OUTPUT PARAMETERS> * <OUTPUT PARAMETERS>
* strDest is updated * strDest is updated
* *
* <RETURN VALUE> * <RETURN VALUE>
* EOK Success * EOK Success
* EINVAL strDest is NULL and destMax != 0 and * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN
* destMax <= SECUREC_STRING_MAX_LEN EINVAL_AND_RESET strDest != NULL and * EINVAL_AND_RESET strDest != NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN
* strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN ERANGE * ERANGE destMax is 0 and destMax > SECUREC_STRING_MAX_LEN
* destMax is 0 and destMax > SECUREC_STRING_MAX_LEN ERANGE_AND_RESET strDest * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap
* have not enough space and all other parameters are valid and not overlap * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid
* EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all
* parameters are valid
* *
* If there is a runtime-constraint violation, strDest[0] will be set to the * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
* '\0' when strDest and destMax valid
*/ */
errno_t strncpy_s(char *strDest, size_t destMax, const char *strSrc, errno_t strncpy_s(char *strDest, size_t destMax, const char *strSrc, size_t count)
size_t count) { {
if (SECUREC_STRNCPY_PARAM_OK(strDest, destMax, strSrc, count)) { if (SECUREC_STRNCPY_PARAM_OK(strDest, destMax, strSrc, count)) {
size_t minCpLen; /* Use it to store the maxi length limit */ size_t minCpLen; /* Use it to store the maxi length limit */
if (count < destMax) { if (count < destMax) {
SECUREC_CALC_STR_LEN(strSrc, count, &minCpLen); /* No ending terminator */ SECUREC_CALC_STR_LEN(strSrc, count, &minCpLen); /* No ending terminator */
} else { } else {
size_t tmpCount = destMax; size_t tmpCount = destMax;
#ifdef SECUREC_COMPATIBLE_WIN_FORMAT #ifdef SECUREC_COMPATIBLE_WIN_FORMAT
if (count == ((size_t)(-1))) { if (count == ((size_t)(-1))) {
tmpCount = destMax - 1; tmpCount = destMax - 1;
} }
#endif #endif
SECUREC_CALC_STR_LEN(strSrc, tmpCount, SECUREC_CALC_STR_LEN(strSrc, tmpCount, &minCpLen); /* No ending terminator */
&minCpLen); /* No ending terminator */ if (minCpLen == destMax) {
if (minCpLen == destMax) { strDest[0] = '\0';
strDest[0] = '\0'; SECUREC_ERROR_INVALID_RANGE("strncpy_s");
SECUREC_ERROR_INVALID_RANGE("strncpy_s"); return ERANGE_AND_RESET;
return ERANGE_AND_RESET; }
} }
if (SECUREC_STRING_NO_OVERLAP(strDest, strSrc, minCpLen) || strDest == strSrc) {
/* Not overlap */
SECUREC_MEMCPY_WARP_OPT(strDest, strSrc, minCpLen); /* Copy string without terminator */
strDest[minCpLen] = '\0';
return EOK;
} else {
strDest[0] = '\0';
SECUREC_ERROR_BUFFER_OVERLAP("strncpy_s");
return EOVERLAP_AND_RESET;
}
} }
if (SECUREC_STRING_NO_OVERLAP(strDest, strSrc, minCpLen) || return strncpy_error(strDest, destMax, strSrc, count);
strDest == strSrc) {
/* Not overlap */
SECUREC_MEMCPY_WARP_OPT(strDest, strSrc,
minCpLen); /* Copy string without terminator */
strDest[minCpLen] = '\0';
return EOK;
} else {
strDest[0] = '\0';
SECUREC_ERROR_BUFFER_OVERLAP("strncpy_s");
return EOVERLAP_AND_RESET;
}
}
return strncpy_error(strDest, destMax, strSrc, count);
} }
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
EXPORT_SYMBOL(strncpy_s); EXPORT_SYMBOL(strncpy_s);
#endif #endif
@@ -7,103 +7,106 @@
#include "securecutil.h" #include "securecutil.h"
SECUREC_INLINE int SecIsInDelimit(char ch, const char *strDelimit) {
const char *ctl = strDelimit; SECUREC_INLINE int SecIsInDelimit(char ch, const char *strDelimit)
while (*ctl != '\0' && *ctl != ch) { {
++ctl; const char *ctl = strDelimit;
} while (*ctl != '\0' && *ctl != ch) {
return (int)(*ctl != '\0'); ++ctl;
}
return (int)(*ctl != '\0');
} }
/* /*
* Find beginning of token (skip over leading delimiters). * Find beginning of token (skip over leading delimiters).
* Note that there is no token if this loop sets string to point to the terminal * Note that there is no token if this loop sets string to point to the terminal null.
* null.
*/ */
SECUREC_INLINE char *SecFindBegin(char *strToken, const char *strDelimit) { SECUREC_INLINE char *SecFindBegin(char *strToken, const char *strDelimit)
char *token = strToken; {
while (*token != '\0') { char *token = strToken;
if (SecIsInDelimit(*token, strDelimit)) { while (*token != '\0') {
++token; if (SecIsInDelimit(*token, strDelimit)) {
continue; ++token;
continue;
}
/* Don't find any delimiter in string header, break the loop */
break;
} }
/* Don't find any delimiter in string header, break the loop */ return token;
break;
}
return token;
} }
/* /*
* Find rest of token * Find rest of token
*/ */
SECUREC_INLINE char *SecFindRest(char *strToken, const char *strDelimit) { SECUREC_INLINE char *SecFindRest(char *strToken, const char *strDelimit)
/* Find the rest of the token. If it is not the end of the string, put a null {
* there */ /* Find the rest of the token. If it is not the end of the string, put a null there */
char *token = strToken; char *token = strToken;
while (*token != '\0') { while (*token != '\0') {
if (SecIsInDelimit(*token, strDelimit)) { if (SecIsInDelimit(*token, strDelimit)) {
/* Find a delimiter, set string termintor */ /* Find a delimiter, set string termintor */
*token = '\0'; *token = '\0';
++token; ++token;
break; break;
}
++token;
} }
++token; return token;
}
return token;
} }
/* /*
* Find the final position pointer * Find the final position pointer
*/ */
SECUREC_INLINE char *SecUpdateToken(char *strToken, const char *strDelimit, SECUREC_INLINE char *SecUpdateToken(char *strToken, const char *strDelimit, char **context)
char **context) { {
/* Point to updated position */ /* Point to updated position */
char *token = SecFindRest(strToken, strDelimit); char *token = SecFindRest(strToken, strDelimit);
/* Record string position for next search in the context */ /* Record string position for next search in the context */
*context = token; *context = token;
/* Determine if a token has been found. */ /* Determine if a token has been found. */
if (token == strToken) { if (token == strToken) {
return NULL; return NULL;
} }
return strToken; return strToken;
} }
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The strtok_s function parses a string into a sequence of strToken, * The strtok_s function parses a string into a sequence of strToken,
* replace all characters in strToken string that match to strDelimit set * replace all characters in strToken string that match to strDelimit set with 0.
* with 0. On the first call to strtok_s the string to be parsed should be * On the first call to strtok_s the string to be parsed should be specified in strToken.
* specified in strToken. In each subsequent call that should parse the same * In each subsequent call that should parse the same string, strToken should be NULL
* string, strToken should be NULL <INPUT PARAMETERS> strToken String * <INPUT PARAMETERS>
* containing token or tokens. strDelimit Set of delimiter characters. * strToken String containing token or tokens.
* strDelimit Set of delimiter characters.
* context Used to store position information between calls * context Used to store position information between calls
* to strtok_s * to strtok_s
* <OUTPUT PARAMETERS> * <OUTPUT PARAMETERS>
* context is updated * context is updated
* <RETURN VALUE> * <RETURN VALUE>
* On the first call returns the address of the first non \0 character, * On the first call returns the address of the first non \0 character, otherwise NULL is returned.
* otherwise NULL is returned. In subsequent calls, the strtoken is set to NULL, * In subsequent calls, the strtoken is set to NULL, and the context set is the same as the previous call,
* and the context set is the same as the previous call, return NULL if the * return NULL if the *context string length is equal 0, otherwise return *context.
* *context string length is equal 0, otherwise return *context.
*/ */
char *strtok_s(char *strToken, const char *strDelimit, char **context) { char *strtok_s(char *strToken, const char *strDelimit, char **context)
char *orgToken = strToken; {
/* Validate delimiter and string context */ char *orgToken = strToken;
if (context == NULL || strDelimit == NULL) { /* Validate delimiter and string context */
return NULL; if (context == NULL || strDelimit == NULL) {
} return NULL;
/* Valid input string and string pointer from where to search */ }
if (orgToken == NULL && *context == NULL) { /* Valid input string and string pointer from where to search */
return NULL; if (orgToken == NULL && *context == NULL) {
} return NULL;
/* If string is null, continue searching from previous string position stored }
* in context */ /* If string is null, continue searching from previous string position stored in context */
if (orgToken == NULL) { if (orgToken == NULL) {
orgToken = *context; orgToken = *context;
} }
orgToken = SecFindBegin(orgToken, strDelimit); orgToken = SecFindBegin(orgToken, strDelimit);
return SecUpdateToken(orgToken, strDelimit, context); return SecUpdateToken(orgToken, strDelimit, context);
} }
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
EXPORT_SYMBOL(strtok_s); EXPORT_SYMBOL(strtok_s);
#endif #endif
@@ -9,8 +9,7 @@
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The swprintf_s function is the wide-character equivalent of the * The swprintf_s function is the wide-character equivalent of the sprintf_s function
* sprintf_s function
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* strDest Storage location for the output. * strDest Storage location for the output.
@@ -22,21 +21,22 @@
* strDest is updated * strDest is updated
* *
* <RETURN VALUE> * <RETURN VALUE>
* return the number of wide characters stored in strDest, not counting the * return the number of wide characters stored in strDest, not counting the terminating null wide character.
* terminating null wide character. return -1 if an error occurred. * return -1 if an error occurred.
* *
* If there is a runtime-constraint violation, strDest[0] will be set to the * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
* '\0' when strDest and destMax valid
*/ */
int swprintf_s(wchar_t *strDest, size_t destMax, const wchar_t *format, ...) { int swprintf_s(wchar_t *strDest, size_t destMax, const wchar_t *format, ...)
int ret; /* If initialization causes e838 */ {
va_list argList; int ret; /* If initialization causes e838 */
va_list argList;
va_start(argList, format); va_start(argList, format);
ret = vswprintf_s(strDest, destMax, format, argList); ret = vswprintf_s(strDest, destMax, format, argList);
va_end(argList); va_end(argList);
(void)argList; /* To clear e438 last value assigned not used , the compiler (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
will optimize this code */
return ret; return ret;
} }
@@ -9,13 +9,13 @@
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The swscanf_s function is the wide-character equivalent of the * The swscanf_s function is the wide-character equivalent of the sscanf_s function
* sscanf_s function The swscanf_s function reads data from buffer into the * The swscanf_s function reads data from buffer into the location given by
* location given by each argument. Every argument must be a pointer to a * each argument. Every argument must be a pointer to a variable with a type
* variable with a type that corresponds to a type specifier in format. The * that corresponds to a type specifier in format. The format argument controls
* format argument controls the interpretation of the input fields and has the * the interpretation of the input fields and has the same form and function
* same form and function as the format argument for the scanf function. If * as the format argument for the scanf function. If copying takes place between
* copying takes place between strings that overlap, the behavior is undefined. * strings that overlap, the behavior is undefined.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* buffer Stored data. * buffer Stored data.
@@ -26,20 +26,23 @@
* ... the converted value stored in user assigned address * ... the converted value stored in user assigned address
* *
* <RETURN VALUE> * <RETURN VALUE>
* Each of these functions returns the number of fields successfully * Each of these functions returns the number of fields successfully converted
* converted and assigned; The return value does not include fields that were * and assigned; The return value does not include fields that were read but not
* read but not assigned. A return value of 0 indicates that no fields were * assigned.
* assigned. return -1 if an error occurs. * A return value of 0 indicates that no fields were assigned.
* return -1 if an error occurs.
*/ */
int swscanf_s(const wchar_t *buffer, const wchar_t *format, ...) { int swscanf_s(const wchar_t *buffer, const wchar_t *format, ...)
int ret; /* If initialization causes e838 */ {
va_list argList; int ret; /* If initialization causes e838 */
va_list argList;
va_start(argList, format); va_start(argList, format);
ret = vswscanf_s(buffer, format, argList); ret = vswscanf_s(buffer, format, argList);
va_end(argList); va_end(argList);
(void)argList; /* To clear e438 last value assigned not used , the compiler (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
will optimize this code */
return ret; return ret;
} }
@@ -10,12 +10,12 @@
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The vfscanf_s function is equivalent to fscanf_s, with the variable * The vfscanf_s function is equivalent to fscanf_s, with the variable argument list replaced by argList
* argument list replaced by argList The vfscanf_s function reads data from the * The vfscanf_s function reads data from the current position of stream into
* current position of stream into the locations given by argument (if any). * the locations given by argument (if any). Each argument must be a pointer
* Each argument must be a pointer to a variable of a type that corresponds to a * to a variable of a type that corresponds to a type specifier in format.
* type specifier in format. format controls the interpretation of the input * format controls the interpretation of the input fields and has the same
* fields and has the same form and function as the format argument for scanf. * form and function as the format argument for scanf.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* stream Pointer to FILE structure. * stream Pointer to FILE structure.
@@ -26,31 +26,34 @@
* argList the converted value stored in user assigned address * argList the converted value stored in user assigned address
* *
* <RETURN VALUE> * <RETURN VALUE>
* Each of these functions returns the number of fields successfully * Each of these functions returns the number of fields successfully converted
* converted and assigned; the return value does not include fields that were * and assigned; the return value does not include fields that were read but
* read but not assigned. A return value of 0 indicates that no fields were * not assigned. A return value of 0 indicates that no fields were assigned.
* assigned. return -1 if an error occurs. * return -1 if an error occurs.
*/ */
int vfscanf_s(FILE *stream, const char *format, va_list argList) { int vfscanf_s(FILE *stream, const char *format, va_list argList)
int retVal; /* If initialization causes e838 */ {
SecFileStream fStr; int retVal; /* If initialization causes e838 */
SecFileStream fStr;
if (stream == NULL || format == NULL) { if (stream == NULL || format == NULL) {
SECUREC_ERROR_INVALID_PARAMTER("vfscanf_s"); SECUREC_ERROR_INVALID_PARAMTER("vfscanf_s");
return SECUREC_SCANF_EINVAL; return SECUREC_SCANF_EINVAL;
} }
if (stream == SECUREC_STREAM_STDIN) { if (stream == SECUREC_STREAM_STDIN) {
return vscanf_s(format, argList); return vscanf_s(format, argList);
} }
SECUREC_LOCK_FILE(stream); SECUREC_LOCK_FILE(stream);
SecInitFileStreamFromFile(&fStr, stream); SecInitFileStreamFromFile(&fStr, stream);
retVal = SecInputS(&fStr, format, argList); retVal = SecInputS(&fStr, format, argList);
SECUREC_UNLOCK_FILE(stream); SECUREC_UNLOCK_FILE(stream);
if (retVal < 0) { if (retVal < 0) {
SECUREC_ERROR_INVALID_PARAMTER("vfscanf_s"); SECUREC_ERROR_INVALID_PARAMTER("vfscanf_s");
return SECUREC_SCANF_EINVAL; return SECUREC_SCANF_EINVAL;
} }
return retVal; return retVal;
} }
@@ -10,12 +10,12 @@
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The vfwscanf_s function is the wide-character equivalent of the * The vfwscanf_s function is the wide-character equivalent of the vfscanf_s function
* vfscanf_s function The vfwscanf_s function reads data from the current * The vfwscanf_s function reads data from the current position of stream into
* position of stream into the locations given by argument (if any). Each * the locations given by argument (if any). Each argument must be a pointer
* argument must be a pointer to a variable of a type that corresponds to a type * to a variable of a type that corresponds to a type specifier in format.
* specifier in format. format controls the interpretation of the input fields * format controls the interpretation of the input fields and has the same form
* and has the same form and function as the format argument for scanf. * and function as the format argument for scanf.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* stream Pointer to FILE structure. * stream Pointer to FILE structure.
@@ -26,30 +26,33 @@
* argList the converted value stored in user assigned address * argList the converted value stored in user assigned address
* *
* <RETURN VALUE> * <RETURN VALUE>
* Each of these functions returns the number of fields successfully * Each of these functions returns the number of fields successfully converted
* converted and assigned; the return value does not include fields that were * and assigned; the return value does not include fields that were read but
* read but not assigned. A return value of 0 indicates that no fields were * not assigned. A return value of 0 indicates that no fields were assigned.
* assigned. return -1 if an error occurs. * return -1 if an error occurs.
*/ */
int vfwscanf_s(FILE *stream, const wchar_t *format, va_list argList) { int vfwscanf_s(FILE *stream, const wchar_t *format, va_list argList)
int retVal; /* If initialization causes e838 */ {
SecFileStream fStr; int retVal; /* If initialization causes e838 */
SecFileStream fStr;
if (stream == NULL || format == NULL) { if (stream == NULL || format == NULL) {
SECUREC_ERROR_INVALID_PARAMTER("vfwscanf_s"); SECUREC_ERROR_INVALID_PARAMTER("vfwscanf_s");
return SECUREC_SCANF_EINVAL; return SECUREC_SCANF_EINVAL;
} }
if (stream == SECUREC_STREAM_STDIN) { if (stream == SECUREC_STREAM_STDIN) {
return vwscanf_s(format, argList); return vwscanf_s(format, argList);
} }
SECUREC_LOCK_FILE(stream); SECUREC_LOCK_FILE(stream);
SecInitFileStreamFromFile(&fStr, stream); SecInitFileStreamFromFile(&fStr, stream);
retVal = SecInputSW(&fStr, format, argList); retVal = SecInputSW(&fStr, format, argList);
SECUREC_UNLOCK_FILE(stream); SECUREC_UNLOCK_FILE(stream);
if (retVal < 0) { if (retVal < 0) {
SECUREC_ERROR_INVALID_PARAMTER("vfwscanf_s"); SECUREC_ERROR_INVALID_PARAMTER("vfwscanf_s");
return SECUREC_SCANF_EINVAL; return SECUREC_SCANF_EINVAL;
} }
return retVal; return retVal;
} }
@@ -10,12 +10,12 @@
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The vscanf_s function is equivalent to scanf_s, with the variable * The vscanf_s function is equivalent to scanf_s, with the variable argument list replaced by argList,
* argument list replaced by argList, The vscanf_s function reads data from the * The vscanf_s function reads data from the standard input stream stdin and
* standard input stream stdin and writes the data into the location that's * writes the data into the location that's given by argument. Each argument
* given by argument. Each argument must be a pointer to a variable of a type * must be a pointer to a variable of a type that corresponds to a type specifier
* that corresponds to a type specifier in format. If copying occurs between * in format. If copying occurs between strings that overlap, the behavior is
* strings that overlap, the behavior is undefined. * undefined.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* format Format control string. * format Format control string.
@@ -30,29 +30,31 @@
* A return value of 0 indicates that no fields were assigned. * A return value of 0 indicates that no fields were assigned.
* return -1 if an error occurs. * return -1 if an error occurs.
*/ */
int vscanf_s(const char *format, va_list argList) { int vscanf_s(const char *format, va_list argList)
int retVal; /* If initialization causes e838 */ {
SecFileStream fStr; int retVal; /* If initialization causes e838 */
SecInitFileStreamFromStdin(&fStr); SecFileStream fStr;
/* SecInitFileStreamFromStdin(&fStr);
* The "va_list" has different definition on different platform, so we can't /*
* use argList == NULL To determine it's invalid. If you has fixed platform, * The "va_list" has different definition on different platform, so we can't use argList == NULL
* you can check some fields to validate it, such as "argList == NULL" or * To determine it's invalid. If you has fixed platform, you can check some fields to validate it,
* argList.xxx != NULL or *(size_t *)&argList != 0. * such as "argList == NULL" or argList.xxx != NULL or *(size_t *)&argList != 0.
*/ */
if (format == NULL || fStr.pf == NULL) { if (format == NULL || fStr.pf == NULL) {
SECUREC_ERROR_INVALID_PARAMTER("vscanf_s"); SECUREC_ERROR_INVALID_PARAMTER("vscanf_s");
return SECUREC_SCANF_EINVAL; return SECUREC_SCANF_EINVAL;
} }
SECUREC_LOCK_STDIN(0, fStr.pf); SECUREC_LOCK_STDIN(0, fStr.pf);
retVal = SecInputS(&fStr, format, argList); retVal = SecInputS(&fStr, format, argList);
SECUREC_UNLOCK_STDIN(0, fStr.pf); SECUREC_UNLOCK_STDIN(0, fStr.pf);
if (retVal < 0) { if (retVal < 0) {
SECUREC_ERROR_INVALID_PARAMTER("vscanf_s"); SECUREC_ERROR_INVALID_PARAMTER("vscanf_s");
return SECUREC_SCANF_EINVAL; return SECUREC_SCANF_EINVAL;
} }
return retVal; return retVal;
} }
@@ -11,69 +11,67 @@
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The vsnprintf_s function is equivalent to the vsnprintf function * The vsnprintf_s function is equivalent to the vsnprintf function
* except for the parameter destMax/count and the explicit * except for the parameter destMax/count and the explicit runtime-constraints violation
* runtime-constraints violation The vsnprintf_s function takes a pointer to an * The vsnprintf_s function takes a pointer to an argument list, then formats
* argument list, then formats and writes up to count characters of the given * and writes up to count characters of the given data to the memory pointed
* data to the memory pointed to by strDest and appends a terminating null. * to by strDest and appends a terminating null.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* strDest Storage location for the output. * strDest Storage location for the output.
* destMax The size of the strDest for output. * destMax The size of the strDest for output.
* count Maximum number of character to write(not * count Maximum number of character to write(not including
* including the terminating NULL) format Format-control * the terminating NULL)
* string. argList pointer to list of arguments. * format Format-control string.
* argList pointer to list of arguments.
* *
* <OUTPUT PARAMETERS> * <OUTPUT PARAMETERS>
* strDest is updated * strDest is updated
* *
* <RETURN VALUE> * <RETURN VALUE>
* return the number of characters written, not including the terminating * return the number of characters written, not including the terminating null
* null return -1 if an error occurs. return -1 if count < destMax and the * return -1 if an error occurs.
* output string has been truncated * return -1 if count < destMax and the output string has been truncated
* *
* If there is a runtime-constraint violation, strDest[0] will be set to the * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
* '\0' when strDest and destMax valid
*/ */
int vsnprintf_s(char *strDest, size_t destMax, size_t count, const char *format, int vsnprintf_s(char *strDest, size_t destMax, size_t count, const char *format, va_list argList)
va_list argList) { {
int retVal; int retVal;
if (SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, if (SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, SECUREC_STRING_MAX_LEN)) {
SECUREC_STRING_MAX_LEN)) { SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN);
SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN); SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_s");
SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_s"); return -1;
return -1;
}
if (destMax > count) {
retVal = SecVsnprintfImpl(strDest, count + 1, format, argList);
if (retVal == SECUREC_PRINTF_TRUNCATE) { /* To keep dest buffer not
destroyed 2014.2.18 */
/* The string has been truncated, return -1 */
return -1; /* To skip error handler, return strlen(strDest) or -1 */
} }
} else {
retVal = SecVsnprintfImpl(strDest, destMax, format, argList); if (destMax > count) {
retVal = SecVsnprintfImpl(strDest, count + 1, format, argList);
if (retVal == SECUREC_PRINTF_TRUNCATE) { /* To keep dest buffer not destroyed 2014.2.18 */
/* The string has been truncated, return -1 */
return -1; /* To skip error handler, return strlen(strDest) or -1 */
}
} else {
retVal = SecVsnprintfImpl(strDest, destMax, format, argList);
#ifdef SECUREC_COMPATIBLE_WIN_FORMAT #ifdef SECUREC_COMPATIBLE_WIN_FORMAT
if (retVal == SECUREC_PRINTF_TRUNCATE && count == (size_t)(-1)) { if (retVal == SECUREC_PRINTF_TRUNCATE && count == (size_t)(-1)) {
return -1; return -1;
} }
#endif #endif
}
if (retVal < 0) {
strDest[0] = '\0'; /* Empty the dest strDest */
if (retVal == SECUREC_PRINTF_TRUNCATE) {
/* Buffer too small */
SECUREC_ERROR_INVALID_RANGE("vsnprintf_s");
} }
SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_s"); if (retVal < 0) {
return -1; strDest[0] = '\0'; /* Empty the dest strDest */
}
return retVal; if (retVal == SECUREC_PRINTF_TRUNCATE) {
/* Buffer too small */
SECUREC_ERROR_INVALID_RANGE("vsnprintf_s");
}
SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_s");
return -1;
}
return retVal;
} }
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
EXPORT_SYMBOL(vsnprintf_s); EXPORT_SYMBOL(vsnprintf_s);
@@ -84,11 +82,10 @@ EXPORT_SYMBOL(vsnprintf_s);
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The vsnprintf_truncated_s function is equivalent to the vsnprintf function * The vsnprintf_truncated_s function is equivalent to the vsnprintf function
* except for the parameter destMax/count and the explicit * except for the parameter destMax/count and the explicit runtime-constraints violation
* runtime-constraints violation The vsnprintf_truncated_s function takes a * The vsnprintf_truncated_s function takes a pointer to an argument list, then formats
* pointer to an argument list, then formats and writes up to count characters * and writes up to count characters of the given data to the memory pointed
* of the given data to the memory pointed to by strDest and appends a * to by strDest and appends a terminating null.
* terminating null.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* strDest Storage location for the output. * strDest Storage location for the output.
@@ -101,38 +98,37 @@ EXPORT_SYMBOL(vsnprintf_s);
* strDest is updated * strDest is updated
* *
* <RETURN VALUE> * <RETURN VALUE>
* return the number of characters written, not including the terminating * return the number of characters written, not including the terminating null
* null return -1 if an error occurs. return destMax-1 if output string has * return -1 if an error occurs.
* been truncated * return destMax-1 if output string has been truncated
* *
* If there is a runtime-constraint violation, strDest[0] will be set to the * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
* '\0' when strDest and destMax valid
*/ */
int vsnprintf_truncated_s(char *strDest, size_t destMax, const char *format, int vsnprintf_truncated_s(char *strDest, size_t destMax, const char *format, va_list argList)
va_list argList) { {
int retVal; int retVal;
if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, SECUREC_STRING_MAX_LEN)) {
SECUREC_STRING_MAX_LEN)) { SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN);
SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN); SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_truncated_s");
SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_truncated_s"); return -1;
return -1;
}
retVal = SecVsnprintfImpl(strDest, destMax, format, argList);
if (retVal < 0) {
if (retVal == SECUREC_PRINTF_TRUNCATE) {
return (int)(destMax -
1); /* To skip error handler, return strlen(strDest) */
} }
strDest[0] = '\0'; /* Empty the dest strDest */
SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_truncated_s");
return -1;
}
return retVal; retVal = SecVsnprintfImpl(strDest, destMax, format, argList);
if (retVal < 0) {
if (retVal == SECUREC_PRINTF_TRUNCATE) {
return (int)(destMax - 1); /* To skip error handler, return strlen(strDest) */
}
strDest[0] = '\0'; /* Empty the dest strDest */
SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_truncated_s");
return -1;
}
return retVal;
} }
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
EXPORT_SYMBOL(vsnprintf_truncated_s); EXPORT_SYMBOL(vsnprintf_truncated_s);
#endif #endif
#endif #endif
@@ -10,9 +10,9 @@
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The vsprintf_s function is equivalent to the vsprintf function * The vsprintf_s function is equivalent to the vsprintf function
* except for the parameter destMax and the explicit runtime-constraints * except for the parameter destMax and the explicit runtime-constraints violation
* violation The vsprintf_s function takes a pointer to an argument list, and * The vsprintf_s function takes a pointer to an argument list, and then formats
* then formats and writes the given data to the memory pointed to by strDest. * and writes the given data to the memory pointed to by strDest.
* The function differ from the non-secure versions only in that the secure * The function differ from the non-secure versions only in that the secure
* versions support positional parameters. * versions support positional parameters.
* *
@@ -26,36 +26,36 @@
* strDest is updated * strDest is updated
* *
* <RETURN VALUE> * <RETURN VALUE>
* return the number of characters written, not including the terminating * return the number of characters written, not including the terminating null character,
* null character, return -1 if an error occurs. * return -1 if an error occurs.
* *
* If there is a runtime-constraint violation, strDest[0] will be set to the * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
* '\0' when strDest and destMax valid
*/ */
int vsprintf_s(char *strDest, size_t destMax, const char *format, int vsprintf_s(char *strDest, size_t destMax, const char *format, va_list argList)
va_list argList) { {
int retVal; /* If initialization causes e838 */ int retVal; /* If initialization causes e838 */
if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, SECUREC_STRING_MAX_LEN)) {
SECUREC_STRING_MAX_LEN)) { SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN);
SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN); SECUREC_ERROR_INVALID_PARAMTER("vsprintf_s");
SECUREC_ERROR_INVALID_PARAMTER("vsprintf_s"); return -1;
return -1;
}
retVal = SecVsnprintfImpl(strDest, destMax, format, argList);
if (retVal < 0) {
strDest[0] = '\0';
if (retVal == SECUREC_PRINTF_TRUNCATE) {
/* Buffer is too small */
SECUREC_ERROR_INVALID_RANGE("vsprintf_s");
} }
SECUREC_ERROR_INVALID_PARAMTER("vsprintf_s");
return -1;
}
return retVal; retVal = SecVsnprintfImpl(strDest, destMax, format, argList);
if (retVal < 0) {
strDest[0] = '\0';
if (retVal == SECUREC_PRINTF_TRUNCATE) {
/* Buffer is too small */
SECUREC_ERROR_INVALID_RANGE("vsprintf_s");
}
SECUREC_ERROR_INVALID_PARAMTER("vsprintf_s");
return -1;
}
return retVal;
} }
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
EXPORT_SYMBOL(vsprintf_s); EXPORT_SYMBOL(vsprintf_s);
#endif #endif
@@ -7,7 +7,7 @@
#define SECUREC_INLINE_INIT_FILE_STREAM_STR 1 #define SECUREC_INLINE_INIT_FILE_STREAM_STR 1
#include "secinput.h" #include "secinput.h"
#if defined(SECUREC_VXWORKS_PLATFORM) && !SECUREC_IN_KERNEL && \ #if defined(SECUREC_VXWORKS_PLATFORM) && !SECUREC_IN_KERNEL && \
(!defined(SECUREC_SYSAPI4VXWORKS) && !defined(SECUREC_CTYPE_MACRO_ADAPT)) (!defined(SECUREC_SYSAPI4VXWORKS) && !defined(SECUREC_CTYPE_MACRO_ADAPT))
#include <ctype.h> #include <ctype.h>
#endif #endif
@@ -18,14 +18,13 @@
* *
* *
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The vsscanf_s function is equivalent to sscanf_s, with the variable * The vsscanf_s function is equivalent to sscanf_s, with the variable argument list replaced by argList
* argument list replaced by argList The vsscanf_s function reads data from * The vsscanf_s function reads data from buffer into the location given by
* buffer into the location given by each argument. Every argument must be a * each argument. Every argument must be a pointer to a variable with a type
* pointer to a variable with a type that corresponds to a type specifier in * that corresponds to a type specifier in format. The format argument controls
* format. The format argument controls the interpretation of the input fields * the interpretation of the input fields and has the same form and function
* and has the same form and function as the format argument for the scanf * as the format argument for the scanf function.
* function. If copying takes place between strings that overlap, the behavior * If copying takes place between strings that overlap, the behavior is undefined.
* is undefined.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* buffer Stored data * buffer Stored data
@@ -36,46 +35,47 @@
* argList the converted value stored in user assigned address * argList the converted value stored in user assigned address
* *
* <RETURN VALUE> * <RETURN VALUE>
* Each of these functions returns the number of fields successfully * Each of these functions returns the number of fields successfully converted
* converted and assigned; the return value does not include fields that were * and assigned; the return value does not include fields that were read but
* read but not assigned. A return value of 0 indicates that no fields were * not assigned. A return value of 0 indicates that no fields were assigned.
* assigned. return -1 if an error occurs. * return -1 if an error occurs.
*/ */
int vsscanf_s(const char *buffer, const char *format, va_list argList) { int vsscanf_s(const char *buffer, const char *format, va_list argList)
size_t count; /* If initialization causes e838 */ {
int retVal; size_t count; /* If initialization causes e838 */
SecFileStream fStr; int retVal;
SecFileStream fStr;
/* Validation section */ /* Validation section */
if (buffer == NULL || format == NULL) { if (buffer == NULL || format == NULL) {
SECUREC_ERROR_INVALID_PARAMTER("vsscanf_s"); SECUREC_ERROR_INVALID_PARAMTER("vsscanf_s");
return SECUREC_SCANF_EINVAL; return SECUREC_SCANF_EINVAL;
} }
count = strlen(buffer); count = strlen(buffer);
if (count == 0 || count > SECUREC_STRING_MAX_LEN) { if (count == 0 || count > SECUREC_STRING_MAX_LEN) {
SecClearDestBuf(buffer, format, argList); SecClearDestBuf(buffer, format, argList);
SECUREC_ERROR_INVALID_PARAMTER("vsscanf_s"); SECUREC_ERROR_INVALID_PARAMTER("vsscanf_s");
return SECUREC_SCANF_EINVAL; return SECUREC_SCANF_EINVAL;
} }
#if defined(SECUREC_VXWORKS_PLATFORM) && !SECUREC_IN_KERNEL #if defined(SECUREC_VXWORKS_PLATFORM) && !SECUREC_IN_KERNEL
/* /*
* On vxworks platform when buffer is white string, will set first %s argument * On vxworks platform when buffer is white string, will set first %s argument tu zero.like following useage:
* tu zero.like following useage: " \v\f\t\r\n", "%s", str, strSize Do not * " \v\f\t\r\n", "%s", str, strSize
* check all character, just first and last character then consider it is * Do not check all character, just first and last character then consider it is white string
* white string */
*/ if (isspace((int)buffer[0]) && isspace((int)buffer[count - 1])) {
if (isspace((int)buffer[0]) && isspace((int)buffer[count - 1])) { SecClearDestBuf(buffer, format, argList);
SecClearDestBuf(buffer, format, argList); }
}
#endif #endif
SecInitFileStreamFromString(&fStr, buffer, (int)count); SecInitFileStreamFromString(&fStr, buffer, (int)count);
retVal = SecInputS(&fStr, format, argList); retVal = SecInputS(&fStr, format, argList);
if (retVal < 0) { if (retVal < 0) {
SECUREC_ERROR_INVALID_PARAMTER("vsscanf_s"); SECUREC_ERROR_INVALID_PARAMTER("vsscanf_s");
return SECUREC_SCANF_EINVAL; return SECUREC_SCANF_EINVAL;
} }
return retVal; return retVal;
} }
#if SECUREC_IN_KERNEL #if SECUREC_IN_KERNEL
EXPORT_SYMBOL(vsscanf_s); EXPORT_SYMBOL(vsscanf_s);
#endif #endif
@@ -7,10 +7,10 @@
#include "secureprintoutput.h" #include "secureprintoutput.h"
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The vswprintf_s function is the wide-character equivalent of the * The vswprintf_s function is the wide-character equivalent of the vsprintf_s function
* vsprintf_s function
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* strDest Storage location for the output. * strDest Storage location for the output.
@@ -22,32 +22,32 @@
* strDest is updated * strDest is updated
* *
* <RETURN VALUE> * <RETURN VALUE>
* return the number of wide characters stored in strDest, not counting the * return the number of wide characters stored in strDest, not counting the terminating null wide character.
* terminating null wide character. return -1 if an error occurred. * return -1 if an error occurred.
* *
* If there is a runtime-constraint violation, strDest[0] will be set to the * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
* '\0' when strDest and destMax valid
*/ */
int vswprintf_s(wchar_t *strDest, size_t destMax, const wchar_t *format, int vswprintf_s(wchar_t *strDest, size_t destMax, const wchar_t *format, va_list argList)
va_list argList) { {
int retVal; /* If initialization causes e838 */ int retVal; /* If initialization causes e838 */
if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, SECUREC_WCHAR_STRING_MAX_LEN)) {
SECUREC_WCHAR_STRING_MAX_LEN)) { SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_WCHAR_STRING_MAX_LEN);
SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_WCHAR_STRING_MAX_LEN); SECUREC_ERROR_INVALID_PARAMTER("vswprintf_s");
SECUREC_ERROR_INVALID_PARAMTER("vswprintf_s"); return -1;
return -1;
}
retVal = SecVswprintfImpl(strDest, destMax, format, argList);
if (retVal < 0) {
strDest[0] = '\0';
if (retVal == SECUREC_PRINTF_TRUNCATE) {
/* Buffer too small */
SECUREC_ERROR_INVALID_RANGE("vswprintf_s");
} }
SECUREC_ERROR_INVALID_PARAMTER("vswprintf_s");
return -1;
}
return retVal; retVal = SecVswprintfImpl(strDest, destMax, format, argList);
if (retVal < 0) {
strDest[0] = '\0';
if (retVal == SECUREC_PRINTF_TRUNCATE) {
/* Buffer too small */
SECUREC_ERROR_INVALID_RANGE("vswprintf_s");
}
SECUREC_ERROR_INVALID_PARAMTER("vswprintf_s");
return -1;
}
return retVal;
} }
@@ -8,23 +8,24 @@
#define SECUREC_INLINE_INIT_FILE_STREAM_STR 1 #define SECUREC_INLINE_INIT_FILE_STREAM_STR 1
#include "secinput.h" #include "secinput.h"
SECUREC_INLINE size_t SecWcslen(const wchar_t *s) { SECUREC_INLINE size_t SecWcslen(const wchar_t *s)
const wchar_t *end = s; {
while (*end != L'\0') { const wchar_t *end = s;
++end; while (*end != L'\0') {
} ++end;
return ((size_t)((end - s))); }
return ((size_t)((end - s)));
} }
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The vswscanf_s function is the wide-character equivalent of the * The vswscanf_s function is the wide-character equivalent of the vsscanf_s function
* vsscanf_s function The vsscanf_s function reads data from buffer into the * The vsscanf_s function reads data from buffer into the location given by
* location given by each argument. Every argument must be a pointer to a * each argument. Every argument must be a pointer to a variable with a type
* variable with a type that corresponds to a type specifier in format. The * that corresponds to a type specifier in format.
* format argument controls the interpretation of the input fields and has the * The format argument controls the interpretation of the input fields and
* same form and function as the format argument for the scanf function. If * has the same form and function as the format argument for the scanf function.
* copying takes place between strings that overlap, the behavior is undefined. * If copying takes place between strings that overlap, the behavior is undefined.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* buffer Stored data * buffer Stored data
@@ -35,33 +36,35 @@ SECUREC_INLINE size_t SecWcslen(const wchar_t *s) {
* argList the converted value stored in user assigned address * argList the converted value stored in user assigned address
* *
* <RETURN VALUE> * <RETURN VALUE>
* Each of these functions returns the number of fields successfully * Each of these functions returns the number of fields successfully converted
* converted and assigned; the return value does not include fields that were * and assigned; the return value does not include fields that were read but
* read but not assigned. A return value of 0 indicates that no fields were * not assigned. A return value of 0 indicates that no fields were assigned.
* assigned. return -1 if an error occurs. * return -1 if an error occurs.
*/ */
int vswscanf_s(const wchar_t *buffer, const wchar_t *format, va_list argList) { int vswscanf_s(const wchar_t *buffer, const wchar_t *format, va_list argList)
size_t count; /* If initialization causes e838 */ {
SecFileStream fStr; size_t count; /* If initialization causes e838 */
int retVal; SecFileStream fStr;
int retVal;
/* Validation section */ /* Validation section */
if (buffer == NULL || format == NULL) { if (buffer == NULL || format == NULL) {
SECUREC_ERROR_INVALID_PARAMTER("vswscanf_s"); SECUREC_ERROR_INVALID_PARAMTER("vswscanf_s");
return SECUREC_SCANF_EINVAL; return SECUREC_SCANF_EINVAL;
} }
count = SecWcslen(buffer); count = SecWcslen(buffer);
if (count == 0 || count > SECUREC_WCHAR_STRING_MAX_LEN) { if (count == 0 || count > SECUREC_WCHAR_STRING_MAX_LEN) {
SecClearDestBufW(buffer, format, argList); SecClearDestBufW(buffer, format, argList);
SECUREC_ERROR_INVALID_PARAMTER("vswscanf_s"); SECUREC_ERROR_INVALID_PARAMTER("vswscanf_s");
return SECUREC_SCANF_EINVAL; return SECUREC_SCANF_EINVAL;
} }
SecInitFileStreamFromString(&fStr, (const char *)buffer, SecInitFileStreamFromString(&fStr, (const char *)buffer, (int)count * ((int)sizeof(wchar_t)));
(int)count * ((int)sizeof(wchar_t))); retVal = SecInputSW(&fStr, format, argList);
retVal = SecInputSW(&fStr, format, argList); if (retVal < 0) {
if (retVal < 0) { SECUREC_ERROR_INVALID_PARAMTER("vswscanf_s");
SECUREC_ERROR_INVALID_PARAMTER("vswscanf_s"); return SECUREC_SCANF_EINVAL;
return SECUREC_SCANF_EINVAL; }
} return retVal;
return retVal;
} }
@@ -10,13 +10,13 @@
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The vwscanf_s function is the wide-character equivalent of the * The vwscanf_s function is the wide-character equivalent of the vscanf_s function
* vscanf_s function The vwscanf_s function is the wide-character version of * The vwscanf_s function is the wide-character version of vscanf_s. The
* vscanf_s. The function reads data from the standard input stream stdin and * function reads data from the standard input stream stdin and writes the
* writes the data into the location that's given by argument. Each argument * data into the location that's given by argument. Each argument must be a
* must be a pointer to a variable of a type that corresponds to a type * pointer to a variable of a type that corresponds to a type specifier in
* specifier in format. If copying occurs between strings that overlap, the * format. If copying occurs between strings that overlap, the behavior is
* behavior is undefined. * undefined.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* format Format control string. * format Format control string.
@@ -31,26 +31,29 @@
* A return value of 0 indicates that no fields were assigned. * A return value of 0 indicates that no fields were assigned.
* return -1 if an error occurs. * return -1 if an error occurs.
*/ */
int vwscanf_s(const wchar_t *format, va_list argList) { int vwscanf_s(const wchar_t *format, va_list argList)
int retVal; /* If initialization causes e838 */ {
SecFileStream fStr; int retVal; /* If initialization causes e838 */
SecFileStream fStr;
SecInitFileStreamFromStdin(&fStr); SecInitFileStreamFromStdin(&fStr);
if (format == NULL || fStr.pf == NULL) { if (format == NULL || fStr.pf == NULL) {
SECUREC_ERROR_INVALID_PARAMTER("vwscanf_s"); SECUREC_ERROR_INVALID_PARAMTER("vwscanf_s");
return SECUREC_SCANF_EINVAL; return SECUREC_SCANF_EINVAL;
} }
SECUREC_LOCK_STDIN(0, fStr.pf); SECUREC_LOCK_STDIN(0, fStr.pf);
retVal = SecInputSW(&fStr, format, argList); retVal = SecInputSW(&fStr, format, argList);
SECUREC_UNLOCK_STDIN(0, fStr.pf); SECUREC_UNLOCK_STDIN(0, fStr.pf);
if (retVal < 0) { if (retVal < 0) {
SECUREC_ERROR_INVALID_PARAMTER("vwscanf_s"); SECUREC_ERROR_INVALID_PARAMTER("vwscanf_s");
return SECUREC_SCANF_EINVAL; return SECUREC_SCANF_EINVAL;
} }
return retVal; return retVal;
} }
@@ -10,53 +10,51 @@
/* /*
* Befor this function, the basic parameter checking has been done * Befor this function, the basic parameter checking has been done
*/ */
SECUREC_INLINE errno_t SecDoCatW(wchar_t *strDest, size_t destMax, SECUREC_INLINE errno_t SecDoCatW(wchar_t *strDest, size_t destMax, const wchar_t *strSrc)
const wchar_t *strSrc) { {
size_t destLen; size_t destLen;
size_t srcLen; size_t srcLen;
size_t maxCount; /* Store the maximum available count */ size_t maxCount; /* Store the maximum available count */
/* To calculate the length of a wide character, the parameter must be a wide /* To calculate the length of a wide character, the parameter must be a wide character */
* character */ SECUREC_CALC_WSTR_LEN(strDest, destMax, &destLen);
SECUREC_CALC_WSTR_LEN(strDest, destMax, &destLen); maxCount = destMax - destLen;
maxCount = destMax - destLen; SECUREC_CALC_WSTR_LEN(strSrc, maxCount, &srcLen);
SECUREC_CALC_WSTR_LEN(strSrc, maxCount, &srcLen);
if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) { if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) {
strDest[0] = L'\0'; strDest[0] = L'\0';
if (strDest + destLen <= strSrc && destLen == destMax) { if (strDest + destLen <= strSrc && destLen == destMax) {
SECUREC_ERROR_INVALID_PARAMTER("wcscat_s"); SECUREC_ERROR_INVALID_PARAMTER("wcscat_s");
return EINVAL_AND_RESET; return EINVAL_AND_RESET;
}
SECUREC_ERROR_BUFFER_OVERLAP("wcscat_s");
return EOVERLAP_AND_RESET;
} }
SECUREC_ERROR_BUFFER_OVERLAP("wcscat_s"); if (srcLen + destLen >= destMax || strDest == strSrc) {
return EOVERLAP_AND_RESET; strDest[0] = L'\0';
} if (destLen == destMax) {
if (srcLen + destLen >= destMax || strDest == strSrc) { SECUREC_ERROR_INVALID_PARAMTER("wcscat_s");
strDest[0] = L'\0'; return EINVAL_AND_RESET;
if (destLen == destMax) { }
SECUREC_ERROR_INVALID_PARAMTER("wcscat_s"); SECUREC_ERROR_INVALID_RANGE("wcscat_s");
return EINVAL_AND_RESET; return ERANGE_AND_RESET;
} }
SECUREC_ERROR_INVALID_RANGE("wcscat_s"); /* Copy single character length include \0 */
return ERANGE_AND_RESET; SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc, (srcLen + 1) * sizeof(wchar_t));
} return EOK;
/* Copy single character length include \0 */
SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc,
(srcLen + 1) * sizeof(wchar_t));
return EOK;
} }
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The wcscat_s function appends a copy of the wide string pointed to by * The wcscat_s function appends a copy of the wide string pointed to by strSrc
* strSrc (including the terminating null wide character) to the end of the wide * (including the terminating null wide character)
* string pointed to by strDest. The arguments and return value of wcscat_s are * to the end of the wide string pointed to by strDest.
* wide-character strings. * The arguments and return value of wcscat_s are wide-character strings.
* *
* The wcscat_s function appends strSrc to strDest and terminates the * The wcscat_s function appends strSrc to strDest and terminates the resulting
* resulting string with a null character. The initial character of strSrc * string with a null character. The initial character of strSrc overwrites the
* overwrites the terminating null character of strDest. wcscat_s will return * terminating null character of strDest. wcscat_s will return EOVERLAP_AND_RESET if the
* EOVERLAP_AND_RESET if the source and destination strings overlap. * source and destination strings overlap.
* *
* Note that the second parameter is the total size of the buffer, not the * Note that the second parameter is the total size of the buffer, not the
* remaining size. * remaining size.
@@ -71,32 +69,33 @@ SECUREC_INLINE errno_t SecDoCatW(wchar_t *strDest, size_t destMax,
* *
* <RETURN VALUE> * <RETURN VALUE>
* EOK Success * EOK Success
* EINVAL strDest is NULL and destMax != 0 and destMax <= * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
* SECUREC_WCHAR_STRING_MAX_LEN EINVAL_AND_RESET (strDest unterminated and * EINVAL_AND_RESET (strDest unterminated and all other parameters are valid) or
* all other parameters are valid) or (strDest != NULL and strSrc is NULLL and * (strDest != NULL and strSrc is NULLL and destMax != 0
* destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN) ERANGE destMax > * and destMax <= SECUREC_WCHAR_STRING_MAX_LEN)
* SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0 ERANGE_AND_RESET strDest * ERANGE destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0
* have not enough space and all other parameters are valid and not overlap * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap
* EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid
* all parameters are valid
* *
* If there is a runtime-constraint violation, strDest[0] will be set to the * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
* '\0' when strDest and destMax valid
*/ */
errno_t wcscat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc) { errno_t wcscat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc)
if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) { {
SECUREC_ERROR_INVALID_RANGE("wcscat_s"); if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) {
return ERANGE; SECUREC_ERROR_INVALID_RANGE("wcscat_s");
} return ERANGE;
if (strDest == NULL || strSrc == NULL) {
SECUREC_ERROR_INVALID_PARAMTER("wcscat_s");
if (strDest != NULL) {
strDest[0] = L'\0';
return EINVAL_AND_RESET;
} }
return EINVAL;
}
return SecDoCatW(strDest, destMax, strSrc); if (strDest == NULL || strSrc == NULL) {
SECUREC_ERROR_INVALID_PARAMTER("wcscat_s");
if (strDest != NULL) {
strDest[0] = L'\0';
return EINVAL_AND_RESET;
}
return EINVAL;
}
return SecDoCatW(strDest, destMax, strSrc);
} }
@@ -7,37 +7,35 @@
#include "securecutil.h" #include "securecutil.h"
SECUREC_INLINE errno_t SecDoCpyW(wchar_t *strDest, size_t destMax, SECUREC_INLINE errno_t SecDoCpyW(wchar_t *strDest, size_t destMax, const wchar_t *strSrc)
const wchar_t *strSrc) { {
size_t srcStrLen; size_t srcStrLen;
SECUREC_CALC_WSTR_LEN(strSrc, destMax, &srcStrLen); SECUREC_CALC_WSTR_LEN(strSrc, destMax, &srcStrLen);
if (srcStrLen == destMax) { if (srcStrLen == destMax) {
strDest[0] = '\0'; strDest[0] = '\0';
SECUREC_ERROR_INVALID_RANGE("wcscpy_s"); SECUREC_ERROR_INVALID_RANGE("wcscpy_s");
return ERANGE_AND_RESET; return ERANGE_AND_RESET;
} }
if (strDest == strSrc) { if (strDest == strSrc) {
return EOK; return EOK;
} }
if (SECUREC_STRING_NO_OVERLAP(strDest, strSrc, srcStrLen)) { if (SECUREC_STRING_NO_OVERLAP(strDest, strSrc, srcStrLen)) {
/* Performance optimization, srcStrLen is single character length include /* Performance optimization, srcStrLen is single character length include '\0' */
* '\0' */ SECUREC_MEMCPY_WARP_OPT(strDest, strSrc, (srcStrLen + 1) * sizeof(wchar_t));
SECUREC_MEMCPY_WARP_OPT(strDest, strSrc, (srcStrLen + 1) * sizeof(wchar_t)); return EOK;
return EOK; } else {
} else { strDest[0] = L'\0';
strDest[0] = L'\0'; SECUREC_ERROR_BUFFER_OVERLAP("wcscpy_s");
SECUREC_ERROR_BUFFER_OVERLAP("wcscpy_s"); return EOVERLAP_AND_RESET;
return EOVERLAP_AND_RESET; }
}
} }
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The wcscpy_s function copies the wide string pointed to by strSrc * The wcscpy_s function copies the wide string pointed to by strSrc
* (including theterminating null wide character) into the array pointed to by * (including theterminating null wide character) into the array pointed to by strDest
strDest
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* strDest Destination string buffer * strDest Destination string buffer
@@ -49,38 +47,34 @@ SECUREC_INLINE errno_t SecDoCpyW(wchar_t *strDest, size_t destMax,
* *
* <RETURN VALUE> * <RETURN VALUE>
* EOK Success * EOK Success
* EINVAL strDest is NULL and destMax != 0 and destMax <= * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
SECUREC_WCHAR_STRING_MAX_LEN
* EINVAL_AND_RESET strDest != NULL and strSrc is NULLL and destMax != 0 * EINVAL_AND_RESET strDest != NULL and strSrc is NULLL and destMax != 0
* and destMax <= SECUREC_WCHAR_STRING_MAX_LEN * and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
* ERANGE destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is * ERANGE destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0
0
* ERANGE_AND_RESET destMax <= length of strSrc and strDest != strSrc * ERANGE_AND_RESET destMax <= length of strSrc and strDest != strSrc
* and strDest != NULL and strSrc != NULL and destMax * and strDest != NULL and strSrc != NULL and destMax != 0
!= 0 * and destMax <= SECUREC_WCHAR_STRING_MAX_LEN and not overlap
* and destMax <= SECUREC_WCHAR_STRING_MAX_LEN and not * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and destMax != 0
overlap
* EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and
destMax != 0
* and destMax <= SECUREC_WCHAR_STRING_MAX_LEN * and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
* and strDest != NULL and strSrc !=NULL and strDest != * and strDest != NULL and strSrc !=NULL and strDest != strSrc
strSrc
* *
* If there is a runtime-constraint violation, strDest[0] will be set to the * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
'\0' when strDest and destMax valid
*/ */
errno_t wcscpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc) { errno_t wcscpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc)
if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) { {
SECUREC_ERROR_INVALID_RANGE("wcscpy_s"); if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) {
return ERANGE; SECUREC_ERROR_INVALID_RANGE("wcscpy_s");
} return ERANGE;
if (strDest == NULL || strSrc == NULL) {
SECUREC_ERROR_INVALID_PARAMTER("wcscpy_s");
if (strDest != NULL) {
strDest[0] = L'\0';
return EINVAL_AND_RESET;
} }
return EINVAL; if (strDest == NULL || strSrc == NULL) {
} SECUREC_ERROR_INVALID_PARAMTER("wcscpy_s");
return SecDoCpyW(strDest, destMax, strSrc); if (strDest != NULL) {
strDest[0] = L'\0';
return EINVAL_AND_RESET;
}
return EINVAL;
}
return SecDoCpyW(strDest, destMax, strSrc);
} }
@@ -10,50 +10,47 @@
/* /*
* Befor this function, the basic parameter checking has been done * Befor this function, the basic parameter checking has been done
*/ */
SECUREC_INLINE errno_t SecDoCatLimitW(wchar_t *strDest, size_t destMax, SECUREC_INLINE errno_t SecDoCatLimitW(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count)
const wchar_t *strSrc, size_t count) { {
/* To calculate the length of a wide character, the parameter must be a wide /* To calculate the length of a wide character, the parameter must be a wide character */
* character */ size_t destLen;
size_t destLen; size_t srcLen;
size_t srcLen; SECUREC_CALC_WSTR_LEN(strDest, destMax, &destLen);
SECUREC_CALC_WSTR_LEN(strDest, destMax, &destLen); SECUREC_CALC_WSTR_LEN(strSrc, count, &srcLen);
SECUREC_CALC_WSTR_LEN(strSrc, count, &srcLen);
if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) { if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) {
strDest[0] = L'\0'; strDest[0] = L'\0';
if (strDest + destLen <= strSrc && destLen == destMax) { if (strDest + destLen <= strSrc && destLen == destMax) {
SECUREC_ERROR_INVALID_PARAMTER("wcsncat_s"); SECUREC_ERROR_INVALID_PARAMTER("wcsncat_s");
return EINVAL_AND_RESET; return EINVAL_AND_RESET;
}
SECUREC_ERROR_BUFFER_OVERLAP("wcsncat_s");
return EOVERLAP_AND_RESET;
} }
SECUREC_ERROR_BUFFER_OVERLAP("wcsncat_s"); if (srcLen + destLen >= destMax || strDest == strSrc) {
return EOVERLAP_AND_RESET; strDest[0] = L'\0';
} if (destLen == destMax) {
if (srcLen + destLen >= destMax || strDest == strSrc) { SECUREC_ERROR_INVALID_PARAMTER("wcsncat_s");
strDest[0] = L'\0'; return EINVAL_AND_RESET;
if (destLen == destMax) { }
SECUREC_ERROR_INVALID_PARAMTER("wcsncat_s"); SECUREC_ERROR_INVALID_RANGE("wcsncat_s");
return EINVAL_AND_RESET; return ERANGE_AND_RESET;
} }
SECUREC_ERROR_INVALID_RANGE("wcsncat_s"); SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc, srcLen * sizeof(wchar_t)); /* no terminator */
return ERANGE_AND_RESET; *(strDest + destLen + srcLen) = L'\0';
} return EOK;
SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc,
srcLen * sizeof(wchar_t)); /* no terminator */
*(strDest + destLen + srcLen) = L'\0';
return EOK;
} }
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The wcsncat_s function appends not more than n successive wide characters * The wcsncat_s function appends not more than n successive wide characters
* (not including the terminating null wide character) * (not including the terminating null wide character)
* from the array pointed to by strSrc to the end of the wide string pointed * from the array pointed to by strSrc to the end of the wide string pointed to by strDest.
* to by strDest.
* *
* The wcsncat_s function try to append the first D characters of strSrc to * The wcsncat_s function try to append the first D characters of strSrc to
* the end of strDest, where D is the lesser of count and the length of * the end of strDest, where D is the lesser of count and the length of strSrc.
* strSrc. If appending those D characters will fit within strDest (whose size * If appending those D characters will fit within strDest (whose size is
* is given as destMax) and still leave room for a null terminator, then those * given as destMax) and still leave room for a null terminator, then those
* characters are appended, starting at the original terminating null of * characters are appended, starting at the original terminating null of
* strDest, and a new terminating null is appended; otherwise, strDest[0] is * strDest, and a new terminating null is appended; otherwise, strDest[0] is
* set to the null character. * set to the null character.
@@ -69,42 +66,41 @@ SECUREC_INLINE errno_t SecDoCatLimitW(wchar_t *strDest, size_t destMax,
* *
* <RETURN VALUE> * <RETURN VALUE>
* EOK Success * EOK Success
* EINVAL strDest is NULL and destMax != 0 and destMax <= * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
* SECUREC_WCHAR_STRING_MAX_LEN EINVAL_AND_RESET (strDest unterminated and * EINVAL_AND_RESET (strDest unterminated and all other parameters are valid) or
* all other parameters are valid) or (strDest != NULL and strSrc is NULLL and * (strDest != NULL and strSrc is NULLL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN)
* destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN) ERANGE destMax > * ERANGE destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0
* SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0 ERANGE_AND_RESET strDest * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap
* have not enough space and all other parameters are valid and not overlap * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid
* EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and
* all parameters are valid
* *
* If there is a runtime-constraint violation, strDest[0] will be set to the * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
* '\0' when strDest and destMax valid
*/ */
errno_t wcsncat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, errno_t wcsncat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count)
size_t count) { {
if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) { if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) {
SECUREC_ERROR_INVALID_RANGE("wcsncat_s"); SECUREC_ERROR_INVALID_RANGE("wcsncat_s");
return ERANGE; return ERANGE;
}
if (strDest == NULL || strSrc == NULL) {
SECUREC_ERROR_INVALID_PARAMTER("wcsncat_s");
if (strDest != NULL) {
strDest[0] = L'\0';
return EINVAL_AND_RESET;
} }
return EINVAL; if (strDest == NULL || strSrc == NULL) {
} SECUREC_ERROR_INVALID_PARAMTER("wcsncat_s");
if (count > SECUREC_WCHAR_STRING_MAX_LEN) { if (strDest != NULL) {
#ifdef SECUREC_COMPATIBLE_WIN_FORMAT strDest[0] = L'\0';
if (count == ((size_t)-1)) { return EINVAL_AND_RESET;
/* Windows internal functions may pass in -1 when calling this function */ }
return SecDoCatLimitW(strDest, destMax, strSrc, destMax); return EINVAL;
} }
if (count > SECUREC_WCHAR_STRING_MAX_LEN) {
#ifdef SECUREC_COMPATIBLE_WIN_FORMAT
if (count == ((size_t)-1)) {
/* Windows internal functions may pass in -1 when calling this function */
return SecDoCatLimitW(strDest, destMax, strSrc, destMax);
}
#endif #endif
strDest[0] = L'\0'; strDest[0] = L'\0';
SECUREC_ERROR_INVALID_RANGE("wcsncat_s"); SECUREC_ERROR_INVALID_RANGE("wcsncat_s");
return ERANGE_AND_RESET; return ERANGE_AND_RESET;
} }
return SecDoCatLimitW(strDest, destMax, strSrc, count); return SecDoCatLimitW(strDest, destMax, strSrc, count);
} }
@@ -7,32 +7,32 @@
#include "securecutil.h" #include "securecutil.h"
SECUREC_INLINE errno_t SecDoCpyLimitW(wchar_t *strDest, size_t destMax, SECUREC_INLINE errno_t SecDoCpyLimitW(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count)
const wchar_t *strSrc, size_t count) { {
size_t srcStrLen; size_t srcStrLen;
if (count < destMax) { if (count < destMax) {
SECUREC_CALC_WSTR_LEN(strSrc, count, &srcStrLen); SECUREC_CALC_WSTR_LEN(strSrc, count, &srcStrLen);
} else { } else {
SECUREC_CALC_WSTR_LEN(strSrc, destMax, &srcStrLen); SECUREC_CALC_WSTR_LEN(strSrc, destMax, &srcStrLen);
} }
if (srcStrLen == destMax) { if (srcStrLen == destMax) {
strDest[0] = '\0'; strDest[0] = '\0';
SECUREC_ERROR_INVALID_RANGE("wcsncpy_s"); SECUREC_ERROR_INVALID_RANGE("wcsncpy_s");
return ERANGE_AND_RESET; return ERANGE_AND_RESET;
} }
if (strDest == strSrc) { if (strDest == strSrc) {
return EOK; return EOK;
} }
if (SECUREC_STRING_NO_OVERLAP(strDest, strSrc, srcStrLen)) { if (SECUREC_STRING_NO_OVERLAP(strDest, strSrc, srcStrLen)) {
/* Performance optimization srcStrLen not include '\0' */ /* Performance optimization srcStrLen not include '\0' */
SECUREC_MEMCPY_WARP_OPT(strDest, strSrc, srcStrLen * sizeof(wchar_t)); SECUREC_MEMCPY_WARP_OPT(strDest, strSrc, srcStrLen * sizeof(wchar_t));
*(strDest + srcStrLen) = L'\0'; *(strDest + srcStrLen) = L'\0';
return EOK; return EOK;
} else { } else {
strDest[0] = L'\0'; strDest[0] = L'\0';
SECUREC_ERROR_BUFFER_OVERLAP("wcsncpy_s"); SECUREC_ERROR_BUFFER_OVERLAP("wcsncpy_s");
return EOVERLAP_AND_RESET; return EOVERLAP_AND_RESET;
} }
} }
/* /*
@@ -52,49 +52,49 @@ SECUREC_INLINE errno_t SecDoCpyLimitW(wchar_t *strDest, size_t destMax,
* *
* <RETURN VALUE> * <RETURN VALUE>
* EOK Success * EOK Success
* EINVAL strDest is NULL and destMax != 0 and destMax <= * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
* SECUREC_WCHAR_STRING_MAX_LEN EINVAL_AND_RESET strDest != NULL and strSrc * EINVAL_AND_RESET strDest != NULL and strSrc is NULLL and destMax != 0
* is NULLL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN ERANGE * and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
* destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0 ERANGE_AND_RESET count * ERANGE destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0
* > SECUREC_WCHAR_STRING_MAX_LEN or (destMax <= length of strSrc and destMax <= * ERANGE_AND_RESET count > SECUREC_WCHAR_STRING_MAX_LEN or
* count and strDest != strSrc and strDest != NULL and strSrc != NULL and * (destMax <= length of strSrc and destMax <= count and strDest != strSrc
* destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN and not overlap) * and strDest != NULL and strSrc != NULL and destMax != 0 and
* EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and * destMax <= SECUREC_WCHAR_STRING_MAX_LEN and not overlap)
* all parameters are valid * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid
* *
* *
* If there is a runtime-constraint violation, strDest[0] will be set to the * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
* '\0' when strDest and destMax valid
*/ */
errno_t wcsncpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, errno_t wcsncpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count)
size_t count) { {
if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) { if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) {
SECUREC_ERROR_INVALID_RANGE("wcsncpy_s"); SECUREC_ERROR_INVALID_RANGE("wcsncpy_s");
return ERANGE; return ERANGE;
}
if (strDest == NULL || strSrc == NULL) {
SECUREC_ERROR_INVALID_PARAMTER("wcsncpy_s");
if (strDest != NULL) {
strDest[0] = '\0';
return EINVAL_AND_RESET;
} }
return EINVAL; if (strDest == NULL || strSrc == NULL) {
} SECUREC_ERROR_INVALID_PARAMTER("wcsncpy_s");
if (count > SECUREC_WCHAR_STRING_MAX_LEN) { if (strDest != NULL) {
strDest[0] = '\0';
return EINVAL_AND_RESET;
}
return EINVAL;
}
if (count > SECUREC_WCHAR_STRING_MAX_LEN) {
#ifdef SECUREC_COMPATIBLE_WIN_FORMAT #ifdef SECUREC_COMPATIBLE_WIN_FORMAT
if (count == (size_t)(-1)) { if (count == (size_t)(-1)) {
return SecDoCpyLimitW(strDest, destMax, strSrc, destMax - 1); return SecDoCpyLimitW(strDest, destMax, strSrc, destMax - 1);
} }
#endif #endif
strDest[0] = '\0'; /* Clear dest string */ strDest[0] = '\0'; /* Clear dest string */
SECUREC_ERROR_INVALID_RANGE("wcsncpy_s"); SECUREC_ERROR_INVALID_RANGE("wcsncpy_s");
return ERANGE_AND_RESET; return ERANGE_AND_RESET;
} }
if (count == 0) { if (count == 0) {
strDest[0] = '\0'; strDest[0] = '\0';
return EOK; return EOK;
} }
return SecDoCpyLimitW(strDest, destMax, strSrc, count); return SecDoCpyLimitW(strDest, destMax, strSrc, count);
} }
@@ -7,67 +7,66 @@
#include "securecutil.h" #include "securecutil.h"
SECUREC_INLINE int SecIsInDelimitW(wchar_t ch, const wchar_t *strDelimit) {
const wchar_t *ctl = strDelimit; SECUREC_INLINE int SecIsInDelimitW(wchar_t ch, const wchar_t *strDelimit)
while (*ctl != L'\0' && *ctl != ch) { {
++ctl; const wchar_t *ctl = strDelimit;
} while (*ctl != L'\0' && *ctl != ch) {
return (int)(*ctl != L'\0'); ++ctl;
}
return (int)(*ctl != L'\0');
} }
/* /*
* Find beginning of token (skip over leading delimiters). * Find beginning of token (skip over leading delimiters).
* Note that there is no token if this loop sets string to point to the terminal * Note that there is no token if this loop sets string to point to the terminal null.
* null.
*/ */
SECUREC_INLINE wchar_t *SecFindBeginW(wchar_t *strToken, SECUREC_INLINE wchar_t *SecFindBeginW(wchar_t *strToken, const wchar_t *strDelimit)
const wchar_t *strDelimit) { {
wchar_t *token = strToken; wchar_t *token = strToken;
while (*token != L'\0') { while (*token != L'\0') {
if (SecIsInDelimitW(*token, strDelimit)) { if (SecIsInDelimitW(*token, strDelimit)) {
++token; ++token;
continue; continue;
}
/* Don't find any delimiter in string header, break the loop */
break;
} }
/* Don't find any delimiter in string header, break the loop */ return token;
break;
}
return token;
} }
/* /*
* Find the end of the token. If it is not the end of the string, put a null * Find the end of the token. If it is not the end of the string, put a null there.
* there.
*/ */
SECUREC_INLINE wchar_t *SecFindRestW(wchar_t *strToken, SECUREC_INLINE wchar_t *SecFindRestW(wchar_t *strToken, const wchar_t *strDelimit)
const wchar_t *strDelimit) { {
wchar_t *token = strToken; wchar_t *token = strToken;
while (*token != L'\0') { while (*token != L'\0') {
if (SecIsInDelimitW(*token, strDelimit)) { if (SecIsInDelimitW(*token, strDelimit)) {
/* Find a delimiter, set string termintor */ /* Find a delimiter, set string termintor */
*token = L'\0'; *token = L'\0';
++token; ++token;
break; break;
}
++token;
} }
++token; return token;
}
return token;
} }
/* /*
* Update Token wide character function * Update Token wide character function
*/ */
SECUREC_INLINE wchar_t *SecUpdateTokenW(wchar_t *strToken, SECUREC_INLINE wchar_t *SecUpdateTokenW(wchar_t *strToken, const wchar_t *strDelimit, wchar_t **context)
const wchar_t *strDelimit, {
wchar_t **context) { /* Point to updated position */
/* Point to updated position */ wchar_t *token = SecFindRestW(strToken, strDelimit);
wchar_t *token = SecFindRestW(strToken, strDelimit); /* Update the context */
/* Update the context */ *context = token;
*context = token; /* Determine if a token has been found. */
/* Determine if a token has been found. */ if (token == strToken) {
if (token == strToken) { return NULL;
return NULL; }
} return strToken;
return strToken;
} }
/* /*
@@ -76,8 +75,7 @@ SECUREC_INLINE wchar_t *SecUpdateTokenW(wchar_t *strToken,
* *
* *
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The wcstok_s function is the wide-character equivalent of the * The wcstok_s function is the wide-character equivalent of the strtok_s function
* strtok_s function
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* strToken String containing token or tokens. * strToken String containing token or tokens.
@@ -88,23 +86,23 @@ SECUREC_INLINE wchar_t *SecUpdateTokenW(wchar_t *strToken,
* <OUTPUT PARAMETERS> * <OUTPUT PARAMETERS>
* context is updated * context is updated
* <RETURN VALUE> * <RETURN VALUE>
* The wcstok_s function is the wide-character equivalent of the * The wcstok_s function is the wide-character equivalent of the strtok_s function
* strtok_s function
*/ */
wchar_t *wcstok_s(wchar_t *strToken, const wchar_t *strDelimit, wchar_t *wcstok_s(wchar_t *strToken, const wchar_t *strDelimit, wchar_t **context)
wchar_t **context) { {
wchar_t *orgToken = strToken; wchar_t *orgToken = strToken;
/* Validation section */ /* Validation section */
if (context == NULL || strDelimit == NULL) { if (context == NULL || strDelimit == NULL) {
return NULL; return NULL;
} }
if (orgToken == NULL && *context == NULL) { if (orgToken == NULL && *context == NULL) {
return NULL; return NULL;
} }
/* If string==NULL, continue with previous string */ /* If string==NULL, continue with previous string */
if (orgToken == NULL) { if (orgToken == NULL) {
orgToken = *context; orgToken = *context;
} }
orgToken = SecFindBeginW(orgToken, strDelimit); orgToken = SecFindBeginW(orgToken, strDelimit);
return SecUpdateTokenW(orgToken, strDelimit, context); return SecUpdateTokenW(orgToken, strDelimit, context);
} }
@@ -6,9 +6,8 @@
*/ */
/* /*
* [Standardize-exceptions] Use unsafe function: Portability * [Standardize-exceptions] Use unsafe function: Portability
* [reason] Use unsafe function to implement security function to maintain * [reason] Use unsafe function to implement security function to maintain platform compatibility.
* platform compatibility. And sufficient input validation is performed before * And sufficient input validation is performed before calling
* calling
*/ */
#include "securecutil.h" #include "securecutil.h"
@@ -29,36 +28,37 @@
* *
* <RETURN VALUE> * <RETURN VALUE>
* EOK Success * EOK Success
* EINVAL dest is NULL and destMax != 0 and count <= * EINVAL dest is NULL and destMax != 0 and count <= destMax
* destMax and destMax <= SECUREC_WCHAR_MEM_MAX_LEN EINVAL_AND_RESET dest * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN
* != NULL and src is NULLL and destMax != 0 and destMax <= * EINVAL_AND_RESET dest != NULL and src is NULLL and destMax != 0
* SECUREC_WCHAR_MEM_MAX_LEN and count <= destMax ERANGE destMax * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN and count <= destMax
* > SECUREC_WCHAR_MEM_MAX_LEN or destMax is 0 or (count > destMax and dest is * ERANGE destMax > SECUREC_WCHAR_MEM_MAX_LEN or destMax is 0 or
* NULL and destMax != 0 and destMax <= SECUREC_WCHAR_MEM_MAX_LEN) * (count > destMax and dest is NULL and destMax != 0
* and destMax <= SECUREC_WCHAR_MEM_MAX_LEN)
* ERANGE_AND_RESET count > destMax and dest != NULL and destMax != 0 * ERANGE_AND_RESET count > destMax and dest != NULL and destMax != 0
* and destMax <= SECUREC_WCHAR_MEM_MAX_LEN * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN
* EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and
* count <= destMax destMax != 0 and destMax <= * count <= destMax destMax != 0 and destMax <= SECUREC_WCHAR_MEM_MAX_LEN
* SECUREC_WCHAR_MEM_MAX_LEN and dest != NULL and src != NULL and dest != src * and dest != NULL and src != NULL and dest != src
* *
* if an error occured, dest will be filled with 0 when dest and destMax * if an error occured, dest will be filled with 0 when dest and destMax valid .
* valid . If the source and destination overlap, the behavior of wmemcpy_s is * If the source and destination overlap, the behavior of wmemcpy_s is undefined.
* undefined. Use wmemmove_s to handle overlapping regions. * Use wmemmove_s to handle overlapping regions.
*/ */
errno_t wmemcpy_s(wchar_t *dest, size_t destMax, const wchar_t *src, errno_t wmemcpy_s(wchar_t *dest, size_t destMax, const wchar_t *src, size_t count)
size_t count) { {
if (destMax == 0 || destMax > SECUREC_WCHAR_MEM_MAX_LEN) { if (destMax == 0 || destMax > SECUREC_WCHAR_MEM_MAX_LEN) {
SECUREC_ERROR_INVALID_PARAMTER("wmemcpy_s"); SECUREC_ERROR_INVALID_PARAMTER("wmemcpy_s");
return ERANGE; return ERANGE;
}
if (count > destMax) {
SECUREC_ERROR_INVALID_PARAMTER("wmemcpy_s");
if (dest != NULL) {
(void)memset(dest, 0, destMax * sizeof(wchar_t));
return ERANGE_AND_RESET;
} }
return ERANGE; if (count > destMax) {
} SECUREC_ERROR_INVALID_PARAMTER("wmemcpy_s");
return memcpy_s(dest, destMax * sizeof(wchar_t), src, if (dest != NULL) {
count * sizeof(wchar_t)); (void)memset(dest, 0, destMax * sizeof(wchar_t));
return ERANGE_AND_RESET;
}
return ERANGE;
}
return memcpy_s(dest, destMax * sizeof(wchar_t), src, count * sizeof(wchar_t));
} }
@@ -6,17 +6,16 @@
*/ */
/* /*
* [Standardize-exceptions] Use unsafe function: Portability * [Standardize-exceptions] Use unsafe function: Portability
* [reason] Use unsafe function to implement security function to maintain * [reason] Use unsafe function to implement security function to maintain platform compatibility.
* platform compatibility. And sufficient input validation is performed before * And sufficient input validation is performed before calling
* calling
*/ */
#include "securecutil.h" #include "securecutil.h"
/* /*
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The wmemmove_s function copies n successive wide characters from the object * The wmemmove_s function copies n successive wide characters from the object pointed
* pointed to by src into the object pointed to by dest. * to by src into the object pointed to by dest.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* dest Destination buffer. * dest Destination buffer.
@@ -29,35 +28,36 @@
* *
* <RETURN VALUE> * <RETURN VALUE>
* EOK Success * EOK Success
* EINVAL dest is NULL and destMax != 0 and count <= * EINVAL dest is NULL and destMax != 0 and count <= destMax
* destMax and destMax <= SECUREC_WCHAR_MEM_MAX_LEN EINVAL_AND_RESET dest != * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN
* NULL and src is NULLL and destMax != 0 and destMax <= * EINVAL_AND_RESET dest != NULL and src is NULLL and destMax != 0
* SECUREC_WCHAR_MEM_MAX_LEN and count <= destMax ERANGE destMax > * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN and count <= destMax
* SECUREC_WCHAR_MEM_MAX_LEN or destMax is 0 or (count > destMax and dest is * ERANGE destMax > SECUREC_WCHAR_MEM_MAX_LEN or destMax is 0 or
* NULL and destMax != 0 and destMax <= SECUREC_WCHAR_MEM_MAX_LEN) * (count > destMax and dest is NULL and destMax != 0
* ERANGE_AND_RESET count > destMax and dest != NULL and destMax != * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN)
* 0 and destMax <= SECUREC_WCHAR_MEM_MAX_LEN * ERANGE_AND_RESET count > destMax and dest != NULL and destMax != 0
* and destMax <= SECUREC_WCHAR_MEM_MAX_LEN
* *
* *
* If an error occured, dest will be filled with 0 when dest and destMax * If an error occured, dest will be filled with 0 when dest and destMax valid.
* valid. If some regions of the source area and the destination overlap, * If some regions of the source area and the destination overlap, wmemmove_s
* wmemmove_s ensures that the original source bytes in the overlapping region * ensures that the original source bytes in the overlapping region are copied
* are copied before being overwritten * before being overwritten
*/ */
errno_t wmemmove_s(wchar_t *dest, size_t destMax, const wchar_t *src, errno_t wmemmove_s(wchar_t *dest, size_t destMax, const wchar_t *src, size_t count)
size_t count) { {
if (destMax == 0 || destMax > SECUREC_WCHAR_MEM_MAX_LEN) { if (destMax == 0 || destMax > SECUREC_WCHAR_MEM_MAX_LEN) {
SECUREC_ERROR_INVALID_PARAMTER("wmemmove_s"); SECUREC_ERROR_INVALID_PARAMTER("wmemmove_s");
return ERANGE; return ERANGE;
}
if (count > destMax) {
SECUREC_ERROR_INVALID_PARAMTER("wmemmove_s");
if (dest != NULL) {
(void)memset(dest, 0, destMax * sizeof(wchar_t));
return ERANGE_AND_RESET;
} }
return ERANGE; if (count > destMax) {
} SECUREC_ERROR_INVALID_PARAMTER("wmemmove_s");
return memmove_s(dest, destMax * sizeof(wchar_t), src, if (dest != NULL) {
count * sizeof(wchar_t)); (void)memset(dest, 0, destMax * sizeof(wchar_t));
return ERANGE_AND_RESET;
}
return ERANGE;
}
return memmove_s(dest, destMax * sizeof(wchar_t), src, count * sizeof(wchar_t));
} }
@@ -10,20 +10,19 @@
/* /*
* <NAME> * <NAME>
* <FUNCTION DESCRIPTION> * <FUNCTION DESCRIPTION>
* The wscanf_s function is the wide-character equivalent of the * The wscanf_s function is the wide-character equivalent of the scanf_s function
* scanf_s function The wscanf_s function reads data from the standard input * The wscanf_s function reads data from the standard input stream stdin and
* stream stdin and writes the data into the location that's given by argument. * writes the data into the location that's given by argument. Each argument
* Each argument must be a pointer to a variable of a type that corresponds to a * must be a pointer to a variable of a type that corresponds to a type specifier
* type specifier in format. If copying occurs between strings that overlap, the * in format. If copying occurs between strings that overlap, the behavior is
* behavior is undefined. * undefined.
* *
* <INPUT PARAMETERS> * <INPUT PARAMETERS>
* format Format control string. * format Format control string.
* ... Optional arguments. * ... Optional arguments.
* *
* <OUTPUT PARAMETERS> * <OUTPUT PARAMETERS>
* ... the converted value stored in user assigned * ... the converted value stored in user assigned address
* address
* *
* <RETURN VALUE> * <RETURN VALUE>
* Returns the number of fields successfully converted and assigned; * Returns the number of fields successfully converted and assigned;
@@ -31,15 +30,16 @@
* A return value of 0 indicates that no fields were assigned. * A return value of 0 indicates that no fields were assigned.
* return -1 if an error occurs. * return -1 if an error occurs.
*/ */
int wscanf_s(const wchar_t *format, ...) { int wscanf_s(const wchar_t *format, ...)
int ret; /* If initialization causes e838 */ {
va_list argList; int ret; /* If initialization causes e838 */
va_list argList;
va_start(argList, format); va_start(argList, format);
ret = vwscanf_s(format, argList); ret = vwscanf_s(format, argList);
va_end(argList); va_end(argList);
(void)argList; /* To clear e438 last value assigned not used , the compiler (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
will optimize this code */
return ret; return ret;
} }
File diff suppressed because it is too large Load Diff
@@ -9,9 +9,9 @@
#ifndef CONFIG_FILE_H #ifndef CONFIG_FILE_H
#define CONFIG_FILE_H #define CONFIG_FILE_H
struct hostapd_config *hostapd_config_read(const char *fname); struct hostapd_config * hostapd_config_read(const char *fname);
int hostapd_set_iface(struct hostapd_config *conf, int hostapd_set_iface(struct hostapd_config *conf,
struct hostapd_bss_config *bss, const char *field, struct hostapd_bss_config *bss, const char *field,
char *value); char *value);
#endif /* CONFIG_FILE_H */ #endif /* CONFIG_FILE_H */
File diff suppressed because it is too large Load Diff
@@ -14,20 +14,26 @@ int hostapd_ctrl_iface_init(struct hostapd_data *hapd);
void hostapd_ctrl_iface_deinit(struct hostapd_data *hapd); void hostapd_ctrl_iface_deinit(struct hostapd_data *hapd);
int hostapd_global_ctrl_iface_init(struct hapd_interfaces *interface); int hostapd_global_ctrl_iface_init(struct hapd_interfaces *interface);
void hostapd_global_ctrl_iface_deinit(struct hapd_interfaces *interface); void hostapd_global_ctrl_iface_deinit(struct hapd_interfaces *interface);
#else /* CONFIG_NO_CTRL_IFACE */ #else /* CONFIG_NO_CTRL_IFACE */
static inline int hostapd_ctrl_iface_init(struct hostapd_data *hapd) { static inline int hostapd_ctrl_iface_init(struct hostapd_data *hapd)
return 0; {
return 0;
} }
static inline void hostapd_ctrl_iface_deinit(struct hostapd_data *hapd) {} static inline void hostapd_ctrl_iface_deinit(struct hostapd_data *hapd)
{
}
static inline int static inline int
hostapd_global_ctrl_iface_init(struct hapd_interfaces *interface) { hostapd_global_ctrl_iface_init(struct hapd_interfaces *interface)
return 0; {
return 0;
} }
static inline void static inline void
hostapd_global_ctrl_iface_deinit(struct hapd_interfaces *interface) {} hostapd_global_ctrl_iface_deinit(struct hapd_interfaces *interface)
{
}
#endif /* CONFIG_NO_CTRL_IFACE */ #endif /* CONFIG_NO_CTRL_IFACE */
#endif /* CTRL_IFACE_H */ #endif /* CTRL_IFACE_H */
@@ -9,8 +9,9 @@
#include "includes.h" #include "includes.h"
#include "common.h" #include "common.h"
#include "eap_register.h"
#include "eap_server/eap_methods.h" #include "eap_server/eap_methods.h"
#include "eap_register.h"
/** /**
* eap_server_register_methods - Register statically linked EAP server methods * eap_server_register_methods - Register statically linked EAP server methods
@@ -19,130 +20,131 @@
* This function is called at program initialization to register all EAP * This function is called at program initialization to register all EAP
* methods that were linked in statically. * methods that were linked in statically.
*/ */
int eap_server_register_methods(void) { int eap_server_register_methods(void)
int ret = 0; {
int ret = 0;
#ifdef EAP_SERVER_IDENTITY #ifdef EAP_SERVER_IDENTITY
if (ret == 0) if (ret == 0)
ret = eap_server_identity_register(); ret = eap_server_identity_register();
#endif /* EAP_SERVER_IDENTITY */ #endif /* EAP_SERVER_IDENTITY */
#ifdef EAP_SERVER_MD5 #ifdef EAP_SERVER_MD5
if (ret == 0) if (ret == 0)
ret = eap_server_md5_register(); ret = eap_server_md5_register();
#endif /* EAP_SERVER_MD5 */ #endif /* EAP_SERVER_MD5 */
#ifdef EAP_SERVER_TLS #ifdef EAP_SERVER_TLS
if (ret == 0) if (ret == 0)
ret = eap_server_tls_register(); ret = eap_server_tls_register();
#endif /* EAP_SERVER_TLS */ #endif /* EAP_SERVER_TLS */
#ifdef EAP_SERVER_UNAUTH_TLS #ifdef EAP_SERVER_UNAUTH_TLS
if (ret == 0) if (ret == 0)
ret = eap_server_unauth_tls_register(); ret = eap_server_unauth_tls_register();
#endif /* EAP_SERVER_TLS */ #endif /* EAP_SERVER_TLS */
#ifdef EAP_SERVER_TLS #ifdef EAP_SERVER_TLS
#ifdef CONFIG_HS20 #ifdef CONFIG_HS20
if (ret == 0) if (ret == 0)
ret = eap_server_wfa_unauth_tls_register(); ret = eap_server_wfa_unauth_tls_register();
#endif /* CONFIG_HS20 */ #endif /* CONFIG_HS20 */
#endif /* EAP_SERVER_TLS */ #endif /* EAP_SERVER_TLS */
#ifdef EAP_SERVER_MSCHAPV2 #ifdef EAP_SERVER_MSCHAPV2
if (ret == 0) if (ret == 0)
ret = eap_server_mschapv2_register(); ret = eap_server_mschapv2_register();
#endif /* EAP_SERVER_MSCHAPV2 */ #endif /* EAP_SERVER_MSCHAPV2 */
#ifdef EAP_SERVER_PEAP #ifdef EAP_SERVER_PEAP
if (ret == 0) if (ret == 0)
ret = eap_server_peap_register(); ret = eap_server_peap_register();
#endif /* EAP_SERVER_PEAP */ #endif /* EAP_SERVER_PEAP */
#ifdef EAP_SERVER_TLV #ifdef EAP_SERVER_TLV
if (ret == 0) if (ret == 0)
ret = eap_server_tlv_register(); ret = eap_server_tlv_register();
#endif /* EAP_SERVER_TLV */ #endif /* EAP_SERVER_TLV */
#ifdef EAP_SERVER_GTC #ifdef EAP_SERVER_GTC
if (ret == 0) if (ret == 0)
ret = eap_server_gtc_register(); ret = eap_server_gtc_register();
#endif /* EAP_SERVER_GTC */ #endif /* EAP_SERVER_GTC */
#ifdef EAP_SERVER_TTLS #ifdef EAP_SERVER_TTLS
if (ret == 0) if (ret == 0)
ret = eap_server_ttls_register(); ret = eap_server_ttls_register();
#endif /* EAP_SERVER_TTLS */ #endif /* EAP_SERVER_TTLS */
#ifdef EAP_SERVER_SIM #ifdef EAP_SERVER_SIM
if (ret == 0) if (ret == 0)
ret = eap_server_sim_register(); ret = eap_server_sim_register();
#endif /* EAP_SERVER_SIM */ #endif /* EAP_SERVER_SIM */
#ifdef EAP_SERVER_AKA #ifdef EAP_SERVER_AKA
if (ret == 0) if (ret == 0)
ret = eap_server_aka_register(); ret = eap_server_aka_register();
#endif /* EAP_SERVER_AKA */ #endif /* EAP_SERVER_AKA */
#ifdef EAP_SERVER_AKA_PRIME #ifdef EAP_SERVER_AKA_PRIME
if (ret == 0) if (ret == 0)
ret = eap_server_aka_prime_register(); ret = eap_server_aka_prime_register();
#endif /* EAP_SERVER_AKA_PRIME */ #endif /* EAP_SERVER_AKA_PRIME */
#ifdef EAP_SERVER_PAX #ifdef EAP_SERVER_PAX
if (ret == 0) if (ret == 0)
ret = eap_server_pax_register(); ret = eap_server_pax_register();
#endif /* EAP_SERVER_PAX */ #endif /* EAP_SERVER_PAX */
#ifdef EAP_SERVER_PSK #ifdef EAP_SERVER_PSK
if (ret == 0) if (ret == 0)
ret = eap_server_psk_register(); ret = eap_server_psk_register();
#endif /* EAP_SERVER_PSK */ #endif /* EAP_SERVER_PSK */
#ifdef EAP_SERVER_SAKE #ifdef EAP_SERVER_SAKE
if (ret == 0) if (ret == 0)
ret = eap_server_sake_register(); ret = eap_server_sake_register();
#endif /* EAP_SERVER_SAKE */ #endif /* EAP_SERVER_SAKE */
#ifdef EAP_SERVER_GPSK #ifdef EAP_SERVER_GPSK
if (ret == 0) if (ret == 0)
ret = eap_server_gpsk_register(); ret = eap_server_gpsk_register();
#endif /* EAP_SERVER_GPSK */ #endif /* EAP_SERVER_GPSK */
#ifdef EAP_SERVER_VENDOR_TEST #ifdef EAP_SERVER_VENDOR_TEST
if (ret == 0) if (ret == 0)
ret = eap_server_vendor_test_register(); ret = eap_server_vendor_test_register();
#endif /* EAP_SERVER_VENDOR_TEST */ #endif /* EAP_SERVER_VENDOR_TEST */
#ifdef EAP_SERVER_FAST #ifdef EAP_SERVER_FAST
if (ret == 0) if (ret == 0)
ret = eap_server_fast_register(); ret = eap_server_fast_register();
#endif /* EAP_SERVER_FAST */ #endif /* EAP_SERVER_FAST */
#ifdef EAP_SERVER_WSC #ifdef EAP_SERVER_WSC
if (ret == 0) if (ret == 0)
ret = eap_server_wsc_register(); ret = eap_server_wsc_register();
#endif /* EAP_SERVER_WSC */ #endif /* EAP_SERVER_WSC */
#ifdef EAP_SERVER_IKEV2 #ifdef EAP_SERVER_IKEV2
if (ret == 0) if (ret == 0)
ret = eap_server_ikev2_register(); ret = eap_server_ikev2_register();
#endif /* EAP_SERVER_IKEV2 */ #endif /* EAP_SERVER_IKEV2 */
#ifdef EAP_SERVER_TNC #ifdef EAP_SERVER_TNC
if (ret == 0) if (ret == 0)
ret = eap_server_tnc_register(); ret = eap_server_tnc_register();
#endif /* EAP_SERVER_TNC */ #endif /* EAP_SERVER_TNC */
#ifdef EAP_SERVER_PWD #ifdef EAP_SERVER_PWD
if (ret == 0) if (ret == 0)
ret = eap_server_pwd_register(); ret = eap_server_pwd_register();
#endif /* EAP_SERVER_PWD */ #endif /* EAP_SERVER_PWD */
#ifdef EAP_SERVER_EKE #ifdef EAP_SERVER_EKE
if (ret == 0) if (ret == 0)
ret = eap_server_eke_register(); ret = eap_server_eke_register();
#endif /* EAP_SERVER_EKE */ #endif /* EAP_SERVER_EKE */
return ret; return ret;
} }
@@ -11,7 +11,8 @@
#include "utils/common.h" #include "utils/common.h"
#include "utils/module_tests.h" #include "utils/module_tests.h"
int hapd_module_tests(void) { int hapd_module_tests(void)
wpa_printf(MSG_INFO, "hostapd module tests"); {
return 0; wpa_printf(MSG_INFO, "hostapd module tests");
return 0;
} }
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -11,35 +11,37 @@
#include "common.h" #include "common.h"
#include "crypto/ms_funcs.h" #include "crypto/ms_funcs.h"
int main(int argc, char *argv[]) {
unsigned char password_hash[16];
size_t i;
char *password, buf[64], *pos;
if (argc > 1) int main(int argc, char *argv[])
password = argv[1]; {
else { unsigned char password_hash[16];
if (fgets(buf, sizeof(buf), stdin) == NULL) { size_t i;
printf("Failed to read password\n"); char *password, buf[64], *pos;
return 1;
}
buf[sizeof(buf) - 1] = '\0';
pos = buf;
while (*pos != '\0') {
if (*pos == '\r' || *pos == '\n') {
*pos = '\0';
break;
}
pos++;
}
password = buf;
}
if (nt_password_hash((u8 *)password, strlen(password), password_hash)) if (argc > 1)
return -1; password = argv[1];
for (i = 0; i < sizeof(password_hash); i++) else {
printf("%02x", password_hash[i]); if (fgets(buf, sizeof(buf), stdin) == NULL) {
printf("\n"); printf("Failed to read password\n");
return 1;
}
buf[sizeof(buf) - 1] = '\0';
pos = buf;
while (*pos != '\0') {
if (*pos == '\r' || *pos == '\n') {
*pos = '\0';
break;
}
pos++;
}
password = buf;
}
return 0; if (nt_password_hash((u8 *) password, strlen(password), password_hash))
return -1;
for (i = 0; i < sizeof(password_hash); i++)
printf("%02x", password_hash[i]);
printf("\n");
return 0;
} }
@@ -8,18 +8,19 @@
#include "utils/includes.h" #include "utils/includes.h"
#include "accounting.h"
#include "ap_config.h"
#include "ap_drv_ops.h"
#include "eapol_auth/eapol_auth_sm.h"
#include "eapol_auth/eapol_auth_sm_i.h"
#include "hostapd.h"
#include "ieee802_1x.h"
#include "radius/radius.h"
#include "radius/radius_client.h"
#include "sta_info.h"
#include "utils/common.h" #include "utils/common.h"
#include "utils/eloop.h" #include "utils/eloop.h"
#include "eapol_auth/eapol_auth_sm.h"
#include "eapol_auth/eapol_auth_sm_i.h"
#include "radius/radius.h"
#include "radius/radius_client.h"
#include "hostapd.h"
#include "ieee802_1x.h"
#include "ap_config.h"
#include "sta_info.h"
#include "ap_drv_ops.h"
#include "accounting.h"
/* Default interval in seconds for polling TX/RX octets from the driver if /* Default interval in seconds for polling TX/RX octets from the driver if
* STA is not using interim accounting. This detects wrap arounds for * STA is not using interim accounting. This detects wrap arounds for
@@ -27,331 +28,374 @@
#define ACCT_DEFAULT_UPDATE_INTERVAL 300 #define ACCT_DEFAULT_UPDATE_INTERVAL 300
static void accounting_sta_interim(struct hostapd_data *hapd, static void accounting_sta_interim(struct hostapd_data *hapd,
struct sta_info *sta); struct sta_info *sta);
static struct radius_msg *accounting_msg(struct hostapd_data *hapd,
struct sta_info *sta,
int status_type) {
struct radius_msg *msg;
char buf[128];
u8 *val;
size_t len;
int i;
struct wpabuf *b;
struct os_time now;
msg = radius_msg_new(RADIUS_CODE_ACCOUNTING_REQUEST, static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
radius_client_get_id(hapd->radius)); struct sta_info *sta,
if (msg == NULL) { int status_type)
wpa_printf(MSG_INFO, "Could not create new RADIUS packet"); {
return NULL; struct radius_msg *msg;
} char buf[128];
u8 *val;
size_t len;
int i;
struct wpabuf *b;
struct os_time now;
if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_STATUS_TYPE, msg = radius_msg_new(RADIUS_CODE_ACCOUNTING_REQUEST,
status_type)) { radius_client_get_id(hapd->radius));
wpa_printf(MSG_INFO, "Could not add Acct-Status-Type"); if (msg == NULL) {
goto fail; wpa_printf(MSG_INFO, "Could not create new RADIUS packet");
} return NULL;
}
if (sta) { if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_STATUS_TYPE,
if (!hostapd_config_get_radius_attr(hapd->conf->radius_acct_req_attr, status_type)) {
RADIUS_ATTR_ACCT_AUTHENTIC) && wpa_printf(MSG_INFO, "Could not add Acct-Status-Type");
!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_AUTHENTIC, goto fail;
hapd->conf->ieee802_1x }
? RADIUS_ACCT_AUTHENTIC_RADIUS
: RADIUS_ACCT_AUTHENTIC_LOCAL)) {
wpa_printf(MSG_INFO, "Could not add Acct-Authentic");
goto fail;
}
/* Use 802.1X identity if available */ if (sta) {
val = ieee802_1x_get_identity(sta->eapol_sm, &len); if (!hostapd_config_get_radius_attr(
hapd->conf->radius_acct_req_attr,
RADIUS_ATTR_ACCT_AUTHENTIC) &&
!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_AUTHENTIC,
hapd->conf->ieee802_1x ?
RADIUS_ACCT_AUTHENTIC_RADIUS :
RADIUS_ACCT_AUTHENTIC_LOCAL)) {
wpa_printf(MSG_INFO, "Could not add Acct-Authentic");
goto fail;
}
/* Use RADIUS ACL identity if 802.1X provides no identity */ /* Use 802.1X identity if available */
if (!val && sta->identity) { val = ieee802_1x_get_identity(sta->eapol_sm, &len);
val = (u8 *)sta->identity;
len = os_strlen(sta->identity);
}
/* Use STA MAC if neither 802.1X nor RADIUS ACL provided /* Use RADIUS ACL identity if 802.1X provides no identity */
* identity */ if (!val && sta->identity) {
if (!val) { val = (u8 *) sta->identity;
os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT, MAC2STR(sta->addr)); len = os_strlen(sta->identity);
val = (u8 *)buf; }
len = os_strlen(buf);
}
if (!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, val, len)) { /* Use STA MAC if neither 802.1X nor RADIUS ACL provided
wpa_printf(MSG_INFO, "Could not add User-Name"); * identity */
goto fail; if (!val) {
} os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT,
} MAC2STR(sta->addr));
val = (u8 *) buf;
len = os_strlen(buf);
}
if (add_common_radius_attr(hapd, hapd->conf->radius_acct_req_attr, sta, msg) < if (!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, val,
0) len)) {
goto fail; wpa_printf(MSG_INFO, "Could not add User-Name");
goto fail;
}
}
if (sta) { if (add_common_radius_attr(hapd, hapd->conf->radius_acct_req_attr, sta,
for (i = 0;; i++) { msg) < 0)
val = ieee802_1x_get_radius_class(sta->eapol_sm, &len, i); goto fail;
if (val == NULL)
break;
if (!radius_msg_add_attr(msg, RADIUS_ATTR_CLASS, val, len)) { if (sta) {
wpa_printf(MSG_INFO, "Could not add Class"); for (i = 0; ; i++) {
goto fail; val = ieee802_1x_get_radius_class(sta->eapol_sm, &len,
} i);
} if (val == NULL)
break;
b = ieee802_1x_get_radius_cui(sta->eapol_sm); if (!radius_msg_add_attr(msg, RADIUS_ATTR_CLASS,
if (b && !radius_msg_add_attr(msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, val, len)) {
wpabuf_head(b), wpabuf_len(b))) { wpa_printf(MSG_INFO, "Could not add Class");
wpa_printf(MSG_ERROR, "Could not add CUI"); goto fail;
goto fail; }
} }
if (!b && sta->radius_cui && b = ieee802_1x_get_radius_cui(sta->eapol_sm);
!radius_msg_add_attr(msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, if (b &&
(u8 *)sta->radius_cui, !radius_msg_add_attr(msg,
os_strlen(sta->radius_cui))) { RADIUS_ATTR_CHARGEABLE_USER_IDENTITY,
wpa_printf(MSG_ERROR, "Could not add CUI from ACL"); wpabuf_head(b), wpabuf_len(b))) {
goto fail; wpa_printf(MSG_ERROR, "Could not add CUI");
} goto fail;
}
if (sta->ipaddr && if (!b && sta->radius_cui &&
!radius_msg_add_attr_int32(msg, RADIUS_ATTR_FRAMED_IP_ADDRESS, !radius_msg_add_attr(msg,
be_to_host32(sta->ipaddr))) { RADIUS_ATTR_CHARGEABLE_USER_IDENTITY,
wpa_printf(MSG_ERROR, "Could not add Framed-IP-Address"); (u8 *) sta->radius_cui,
goto fail; os_strlen(sta->radius_cui))) {
} wpa_printf(MSG_ERROR, "Could not add CUI from ACL");
} goto fail;
}
os_get_time(&now); if (sta->ipaddr &&
if (now.sec > 1000000000 && !radius_msg_add_attr_int32(msg,
!radius_msg_add_attr_int32(msg, RADIUS_ATTR_EVENT_TIMESTAMP, now.sec)) { RADIUS_ATTR_FRAMED_IP_ADDRESS,
wpa_printf(MSG_INFO, "Could not add Event-Timestamp"); be_to_host32(sta->ipaddr))) {
goto fail; wpa_printf(MSG_ERROR,
} "Could not add Framed-IP-Address");
goto fail;
}
}
/* os_get_time(&now);
* Add Acct-Delay-Time with zero value for the first transmission. This if (now.sec > 1000000000 &&
* will be updated within radius_client.c when retransmitting the frame. !radius_msg_add_attr_int32(msg, RADIUS_ATTR_EVENT_TIMESTAMP,
*/ now.sec)) {
if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_DELAY_TIME, 0)) { wpa_printf(MSG_INFO, "Could not add Event-Timestamp");
wpa_printf(MSG_INFO, "Could not add Acct-Delay-Time"); goto fail;
goto fail; }
}
return msg; /*
* Add Acct-Delay-Time with zero value for the first transmission. This
* will be updated within radius_client.c when retransmitting the frame.
*/
if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_DELAY_TIME, 0)) {
wpa_printf(MSG_INFO, "Could not add Acct-Delay-Time");
goto fail;
}
fail: return msg;
radius_msg_free(msg);
return NULL; fail:
radius_msg_free(msg);
return NULL;
} }
static int accounting_sta_update_stats(struct hostapd_data *hapd, static int accounting_sta_update_stats(struct hostapd_data *hapd,
struct sta_info *sta, struct sta_info *sta,
struct hostap_sta_driver_data *data) { struct hostap_sta_driver_data *data)
if (hostapd_drv_read_sta_data(hapd, data, sta->addr)) {
return -1; if (hostapd_drv_read_sta_data(hapd, data, sta->addr))
return -1;
if (!data->bytes_64bit) { if (!data->bytes_64bit) {
/* Extend 32-bit counters from the driver to 64-bit counters */ /* Extend 32-bit counters from the driver to 64-bit counters */
if (sta->last_rx_bytes_lo > data->rx_bytes) if (sta->last_rx_bytes_lo > data->rx_bytes)
sta->last_rx_bytes_hi++; sta->last_rx_bytes_hi++;
sta->last_rx_bytes_lo = data->rx_bytes; sta->last_rx_bytes_lo = data->rx_bytes;
if (sta->last_tx_bytes_lo > data->tx_bytes) if (sta->last_tx_bytes_lo > data->tx_bytes)
sta->last_tx_bytes_hi++; sta->last_tx_bytes_hi++;
sta->last_tx_bytes_lo = data->tx_bytes; sta->last_tx_bytes_lo = data->tx_bytes;
} }
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_DEBUG, hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
"updated TX/RX stats: rx_bytes=%llu [%u:%u] tx_bytes=%llu " HOSTAPD_LEVEL_DEBUG,
"[%u:%u] bytes_64bit=%d", "updated TX/RX stats: rx_bytes=%llu [%u:%u] tx_bytes=%llu [%u:%u] bytes_64bit=%d",
data->rx_bytes, sta->last_rx_bytes_hi, sta->last_rx_bytes_lo, data->rx_bytes, sta->last_rx_bytes_hi,
data->tx_bytes, sta->last_tx_bytes_hi, sta->last_tx_bytes_lo, sta->last_rx_bytes_lo,
data->bytes_64bit); data->tx_bytes, sta->last_tx_bytes_hi,
sta->last_tx_bytes_lo,
data->bytes_64bit);
return 0; return 0;
} }
static void accounting_interim_update(void *eloop_ctx, void *timeout_ctx) {
struct hostapd_data *hapd = eloop_ctx;
struct sta_info *sta = timeout_ctx;
int interval;
if (sta->acct_interim_interval) { static void accounting_interim_update(void *eloop_ctx, void *timeout_ctx)
accounting_sta_interim(hapd, sta); {
interval = sta->acct_interim_interval; struct hostapd_data *hapd = eloop_ctx;
} else { struct sta_info *sta = timeout_ctx;
struct hostap_sta_driver_data data; int interval;
accounting_sta_update_stats(hapd, sta, &data);
interval = ACCT_DEFAULT_UPDATE_INTERVAL;
}
eloop_register_timeout(interval, 0, accounting_interim_update, hapd, sta); if (sta->acct_interim_interval) {
accounting_sta_interim(hapd, sta);
interval = sta->acct_interim_interval;
} else {
struct hostap_sta_driver_data data;
accounting_sta_update_stats(hapd, sta, &data);
interval = ACCT_DEFAULT_UPDATE_INTERVAL;
}
eloop_register_timeout(interval, 0, accounting_interim_update,
hapd, sta);
} }
/** /**
* accounting_sta_start - Start STA accounting * accounting_sta_start - Start STA accounting
* @hapd: hostapd BSS data * @hapd: hostapd BSS data
* @sta: The station * @sta: The station
*/ */
void accounting_sta_start(struct hostapd_data *hapd, struct sta_info *sta) { void accounting_sta_start(struct hostapd_data *hapd, struct sta_info *sta)
struct radius_msg *msg; {
int interval; struct radius_msg *msg;
int interval;
if (sta->acct_session_started) if (sta->acct_session_started)
return; return;
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_INFO, hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
"starting accounting session %016llX", HOSTAPD_LEVEL_INFO,
(unsigned long long)sta->acct_session_id); "starting accounting session %016llX",
(unsigned long long) sta->acct_session_id);
os_get_reltime(&sta->acct_session_start); os_get_reltime(&sta->acct_session_start);
sta->last_rx_bytes_hi = 0; sta->last_rx_bytes_hi = 0;
sta->last_rx_bytes_lo = 0; sta->last_rx_bytes_lo = 0;
sta->last_tx_bytes_hi = 0; sta->last_tx_bytes_hi = 0;
sta->last_tx_bytes_lo = 0; sta->last_tx_bytes_lo = 0;
hostapd_drv_sta_clear_stats(hapd, sta->addr); hostapd_drv_sta_clear_stats(hapd, sta->addr);
if (!hapd->conf->radius->acct_server) if (!hapd->conf->radius->acct_server)
return; return;
if (sta->acct_interim_interval) if (sta->acct_interim_interval)
interval = sta->acct_interim_interval; interval = sta->acct_interim_interval;
else else
interval = ACCT_DEFAULT_UPDATE_INTERVAL; interval = ACCT_DEFAULT_UPDATE_INTERVAL;
eloop_register_timeout(interval, 0, accounting_interim_update, hapd, sta); eloop_register_timeout(interval, 0, accounting_interim_update,
hapd, sta);
msg = accounting_msg(hapd, sta, RADIUS_ACCT_STATUS_TYPE_START); msg = accounting_msg(hapd, sta, RADIUS_ACCT_STATUS_TYPE_START);
if (msg && radius_client_send(hapd->radius, msg, RADIUS_ACCT, sta->addr) < 0) if (msg &&
radius_msg_free(msg); radius_client_send(hapd->radius, msg, RADIUS_ACCT, sta->addr) < 0)
radius_msg_free(msg);
sta->acct_session_started = 1; sta->acct_session_started = 1;
} }
static void accounting_sta_report(struct hostapd_data *hapd, static void accounting_sta_report(struct hostapd_data *hapd,
struct sta_info *sta, int stop) { struct sta_info *sta, int stop)
struct radius_msg *msg; {
int cause = sta->acct_terminate_cause; struct radius_msg *msg;
struct hostap_sta_driver_data data; int cause = sta->acct_terminate_cause;
struct os_reltime now_r, diff; struct hostap_sta_driver_data data;
u64 bytes; struct os_reltime now_r, diff;
u64 bytes;
if (!hapd->conf->radius->acct_server) if (!hapd->conf->radius->acct_server)
return; return;
msg = accounting_msg(hapd, sta, msg = accounting_msg(hapd, sta,
stop ? RADIUS_ACCT_STATUS_TYPE_STOP stop ? RADIUS_ACCT_STATUS_TYPE_STOP :
: RADIUS_ACCT_STATUS_TYPE_INTERIM_UPDATE); RADIUS_ACCT_STATUS_TYPE_INTERIM_UPDATE);
if (!msg) { if (!msg) {
wpa_printf(MSG_INFO, "Could not create RADIUS Accounting message"); wpa_printf(MSG_INFO, "Could not create RADIUS Accounting message");
return; return;
} }
os_get_reltime(&now_r); os_get_reltime(&now_r);
os_reltime_sub(&now_r, &sta->acct_session_start, &diff); os_reltime_sub(&now_r, &sta->acct_session_start, &diff);
if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_SESSION_TIME, if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_SESSION_TIME,
diff.sec)) { diff.sec)) {
wpa_printf(MSG_INFO, "Could not add Acct-Session-Time"); wpa_printf(MSG_INFO, "Could not add Acct-Session-Time");
goto fail; goto fail;
} }
if (accounting_sta_update_stats(hapd, sta, &data) == 0) { if (accounting_sta_update_stats(hapd, sta, &data) == 0) {
if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_INPUT_PACKETS, if (!radius_msg_add_attr_int32(msg,
data.rx_packets)) { RADIUS_ATTR_ACCT_INPUT_PACKETS,
wpa_printf(MSG_INFO, "Could not add Acct-Input-Packets"); data.rx_packets)) {
goto fail; wpa_printf(MSG_INFO, "Could not add Acct-Input-Packets");
} goto fail;
if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_OUTPUT_PACKETS, }
data.tx_packets)) { if (!radius_msg_add_attr_int32(msg,
wpa_printf(MSG_INFO, "Could not add Acct-Output-Packets"); RADIUS_ATTR_ACCT_OUTPUT_PACKETS,
goto fail; data.tx_packets)) {
} wpa_printf(MSG_INFO, "Could not add Acct-Output-Packets");
if (data.bytes_64bit) goto fail;
bytes = data.rx_bytes; }
else if (data.bytes_64bit)
bytes = ((u64)sta->last_rx_bytes_hi << 32) | sta->last_rx_bytes_lo; bytes = data.rx_bytes;
if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_INPUT_OCTETS, else
(u32)bytes)) { bytes = ((u64) sta->last_rx_bytes_hi << 32) |
wpa_printf(MSG_INFO, "Could not add Acct-Input-Octets"); sta->last_rx_bytes_lo;
goto fail; if (!radius_msg_add_attr_int32(msg,
} RADIUS_ATTR_ACCT_INPUT_OCTETS,
if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_INPUT_GIGAWORDS, (u32) bytes)) {
(u32)(bytes >> 32))) { wpa_printf(MSG_INFO, "Could not add Acct-Input-Octets");
wpa_printf(MSG_INFO, "Could not add Acct-Input-Gigawords"); goto fail;
goto fail; }
} if (!radius_msg_add_attr_int32(msg,
if (data.bytes_64bit) RADIUS_ATTR_ACCT_INPUT_GIGAWORDS,
bytes = data.tx_bytes; (u32) (bytes >> 32))) {
else wpa_printf(MSG_INFO, "Could not add Acct-Input-Gigawords");
bytes = ((u64)sta->last_tx_bytes_hi << 32) | sta->last_tx_bytes_lo; goto fail;
if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_OUTPUT_OCTETS, }
(u32)bytes)) { if (data.bytes_64bit)
wpa_printf(MSG_INFO, "Could not add Acct-Output-Octets"); bytes = data.tx_bytes;
goto fail; else
} bytes = ((u64) sta->last_tx_bytes_hi << 32) |
if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_OUTPUT_GIGAWORDS, sta->last_tx_bytes_lo;
(u32)(bytes >> 32))) { if (!radius_msg_add_attr_int32(msg,
wpa_printf(MSG_INFO, "Could not add Acct-Output-Gigawords"); RADIUS_ATTR_ACCT_OUTPUT_OCTETS,
goto fail; (u32) bytes)) {
} wpa_printf(MSG_INFO, "Could not add Acct-Output-Octets");
} goto fail;
}
if (!radius_msg_add_attr_int32(msg,
RADIUS_ATTR_ACCT_OUTPUT_GIGAWORDS,
(u32) (bytes >> 32))) {
wpa_printf(MSG_INFO, "Could not add Acct-Output-Gigawords");
goto fail;
}
}
if (eloop_terminated()) if (eloop_terminated())
cause = RADIUS_ACCT_TERMINATE_CAUSE_ADMIN_REBOOT; cause = RADIUS_ACCT_TERMINATE_CAUSE_ADMIN_REBOOT;
if (stop && cause && if (stop && cause &&
!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_TERMINATE_CAUSE, !radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_TERMINATE_CAUSE,
cause)) { cause)) {
wpa_printf(MSG_INFO, "Could not add Acct-Terminate-Cause"); wpa_printf(MSG_INFO, "Could not add Acct-Terminate-Cause");
goto fail; goto fail;
} }
if (radius_client_send(hapd->radius, msg, if (radius_client_send(hapd->radius, msg,
stop ? RADIUS_ACCT : RADIUS_ACCT_INTERIM, stop ? RADIUS_ACCT : RADIUS_ACCT_INTERIM,
sta->addr) < 0) sta->addr) < 0)
goto fail; goto fail;
return; return;
fail: fail:
radius_msg_free(msg); radius_msg_free(msg);
} }
/** /**
* accounting_sta_interim - Send a interim STA accounting report * accounting_sta_interim - Send a interim STA accounting report
* @hapd: hostapd BSS data * @hapd: hostapd BSS data
* @sta: The station * @sta: The station
*/ */
static void accounting_sta_interim(struct hostapd_data *hapd, static void accounting_sta_interim(struct hostapd_data *hapd,
struct sta_info *sta) { struct sta_info *sta)
if (sta->acct_session_started) {
accounting_sta_report(hapd, sta, 0); if (sta->acct_session_started)
accounting_sta_report(hapd, sta, 0);
} }
/** /**
* accounting_sta_stop - Stop STA accounting * accounting_sta_stop - Stop STA accounting
* @hapd: hostapd BSS data * @hapd: hostapd BSS data
* @sta: The station * @sta: The station
*/ */
void accounting_sta_stop(struct hostapd_data *hapd, struct sta_info *sta) { void accounting_sta_stop(struct hostapd_data *hapd, struct sta_info *sta)
if (sta->acct_session_started) { {
accounting_sta_report(hapd, sta, 1); if (sta->acct_session_started) {
eloop_cancel_timeout(accounting_interim_update, hapd, sta); accounting_sta_report(hapd, sta, 1);
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_INFO, eloop_cancel_timeout(accounting_interim_update, hapd, sta);
"stopped accounting session %016llX", hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
(unsigned long long)sta->acct_session_id); HOSTAPD_LEVEL_INFO,
sta->acct_session_started = 0; "stopped accounting session %016llX",
} (unsigned long long) sta->acct_session_id);
sta->acct_session_started = 0;
}
} }
int accounting_sta_get_id(struct hostapd_data *hapd, struct sta_info *sta) {
return radius_gen_session_id((u8 *)&sta->acct_session_id, int accounting_sta_get_id(struct hostapd_data *hapd, struct sta_info *sta)
sizeof(sta->acct_session_id)); {
return radius_gen_session_id((u8 *) &sta->acct_session_id,
sizeof(sta->acct_session_id));
} }
/** /**
* accounting_receive - Process the RADIUS frames from Accounting Server * accounting_receive - Process the RADIUS frames from Accounting Server
* @msg: RADIUS response message * @msg: RADIUS response message
@@ -361,133 +405,140 @@ int accounting_sta_get_id(struct hostapd_data *hapd, struct sta_info *sta) {
* @data: Context data (struct hostapd_data *) * @data: Context data (struct hostapd_data *)
* Returns: Processing status * Returns: Processing status
*/ */
static RadiusRxResult accounting_receive(struct radius_msg *msg, static RadiusRxResult
struct radius_msg *req, accounting_receive(struct radius_msg *msg, struct radius_msg *req,
const u8 *shared_secret, const u8 *shared_secret, size_t shared_secret_len,
size_t shared_secret_len, void *data) { void *data)
if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCOUNTING_RESPONSE) { {
wpa_printf(MSG_INFO, "Unknown RADIUS message code"); if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCOUNTING_RESPONSE) {
return RADIUS_RX_UNKNOWN; wpa_printf(MSG_INFO, "Unknown RADIUS message code");
} return RADIUS_RX_UNKNOWN;
}
if (radius_msg_verify(msg, shared_secret, shared_secret_len, req, 0)) { if (radius_msg_verify(msg, shared_secret, shared_secret_len, req, 0)) {
wpa_printf( wpa_printf(MSG_INFO, "Incoming RADIUS packet did not have correct Authenticator - dropped");
MSG_INFO, return RADIUS_RX_INVALID_AUTHENTICATOR;
"Incoming RADIUS packet did not have correct Authenticator - dropped"); }
return RADIUS_RX_INVALID_AUTHENTICATOR;
}
return RADIUS_RX_PROCESSED; return RADIUS_RX_PROCESSED;
} }
static void accounting_report_state(struct hostapd_data *hapd, int on) {
struct radius_msg *msg;
if (!hapd->conf->radius->acct_server || hapd->radius == NULL) static void accounting_report_state(struct hostapd_data *hapd, int on)
return; {
struct radius_msg *msg;
/* Inform RADIUS server that accounting will start/stop so that the if (!hapd->conf->radius->acct_server || hapd->radius == NULL)
* server can close old accounting sessions. */ return;
msg = accounting_msg(hapd, NULL,
on ? RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_ON
: RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_OFF);
if (!msg)
return;
if (hapd->acct_session_id) { /* Inform RADIUS server that accounting will start/stop so that the
char buf[20]; * server can close old accounting sessions. */
msg = accounting_msg(hapd, NULL,
on ? RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_ON :
RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_OFF);
if (!msg)
return;
os_snprintf(buf, sizeof(buf), "%016llX", if (hapd->acct_session_id) {
(unsigned long long)hapd->acct_session_id); char buf[20];
if (!radius_msg_add_attr(msg, RADIUS_ATTR_ACCT_SESSION_ID, (u8 *)buf,
os_strlen(buf)))
wpa_printf(MSG_ERROR, "Could not add Acct-Session-Id");
}
if (radius_client_send(hapd->radius, msg, RADIUS_ACCT, NULL) < 0) os_snprintf(buf, sizeof(buf), "%016llX",
radius_msg_free(msg); (unsigned long long) hapd->acct_session_id);
if (!radius_msg_add_attr(msg, RADIUS_ATTR_ACCT_SESSION_ID,
(u8 *) buf, os_strlen(buf)))
wpa_printf(MSG_ERROR, "Could not add Acct-Session-Id");
}
if (radius_client_send(hapd->radius, msg, RADIUS_ACCT, NULL) < 0)
radius_msg_free(msg);
} }
static void accounting_interim_error_cb(const u8 *addr, void *ctx) {
struct hostapd_data *hapd = ctx;
struct sta_info *sta;
unsigned int i, wait_time;
int res;
sta = ap_get_sta(hapd, addr); static void accounting_interim_error_cb(const u8 *addr, void *ctx)
if (!sta) {
return; struct hostapd_data *hapd = ctx;
sta->acct_interim_errors++; struct sta_info *sta;
if (sta->acct_interim_errors > 10 /* RADIUS_CLIENT_MAX_RETRIES */) { unsigned int i, wait_time;
wpa_printf(MSG_DEBUG, int res;
"Interim RADIUS accounting update failed for " MACSTR
" - too many errors, abandon this interim accounting update",
MAC2STR(addr));
sta->acct_interim_errors = 0;
/* Next update will be tried after normal update interval */
return;
}
/* sta = ap_get_sta(hapd, addr);
* Use a shorter update interval as an improved retransmission mechanism if (!sta)
* for failed interim accounting updates. This allows the statistics to return;
* be updated for each retransmission. sta->acct_interim_errors++;
* if (sta->acct_interim_errors > 10 /* RADIUS_CLIENT_MAX_RETRIES */) {
* RADIUS client code has already waited RADIUS_CLIENT_FIRST_WAIT. wpa_printf(MSG_DEBUG,
* Schedule the first retry attempt immediately and every following one "Interim RADIUS accounting update failed for " MACSTR
* with exponential backoff. " - too many errors, abandon this interim accounting update",
*/ MAC2STR(addr));
if (sta->acct_interim_errors == 1) { sta->acct_interim_errors = 0;
wait_time = 0; /* Next update will be tried after normal update interval */
} else { return;
wait_time = 3; /* RADIUS_CLIENT_FIRST_WAIT */ }
for (i = 1; i < sta->acct_interim_errors; i++)
wait_time *= 2; /*
} * Use a shorter update interval as an improved retransmission mechanism
res = * for failed interim accounting updates. This allows the statistics to
eloop_deplete_timeout(wait_time, 0, accounting_interim_update, hapd, sta); * be updated for each retransmission.
if (res == 1) *
wpa_printf(MSG_DEBUG, * RADIUS client code has already waited RADIUS_CLIENT_FIRST_WAIT.
"Interim RADIUS accounting update failed for " MACSTR * Schedule the first retry attempt immediately and every following one
" (error count: %u) - schedule next update in %u seconds", * with exponential backoff.
MAC2STR(addr), sta->acct_interim_errors, wait_time); */
else if (res == 0) if (sta->acct_interim_errors == 1) {
wpa_printf(MSG_DEBUG, wait_time = 0;
"Interim RADIUS accounting update failed for " MACSTR } else {
" (error count: %u)", wait_time = 3; /* RADIUS_CLIENT_FIRST_WAIT */
MAC2STR(addr), sta->acct_interim_errors); for (i = 1; i < sta->acct_interim_errors; i++)
else wait_time *= 2;
wpa_printf(MSG_DEBUG, }
"Interim RADIUS accounting update failed for " MACSTR res = eloop_deplete_timeout(wait_time, 0, accounting_interim_update,
" (error count: %u) - no timer found", hapd, sta);
MAC2STR(addr), sta->acct_interim_errors); if (res == 1)
wpa_printf(MSG_DEBUG,
"Interim RADIUS accounting update failed for " MACSTR
" (error count: %u) - schedule next update in %u seconds",
MAC2STR(addr), sta->acct_interim_errors, wait_time);
else if (res == 0)
wpa_printf(MSG_DEBUG,
"Interim RADIUS accounting update failed for " MACSTR
" (error count: %u)", MAC2STR(addr),
sta->acct_interim_errors);
else
wpa_printf(MSG_DEBUG,
"Interim RADIUS accounting update failed for " MACSTR
" (error count: %u) - no timer found", MAC2STR(addr),
sta->acct_interim_errors);
} }
/** /**
* accounting_init: Initialize accounting * accounting_init: Initialize accounting
* @hapd: hostapd BSS data * @hapd: hostapd BSS data
* Returns: 0 on success, -1 on failure * Returns: 0 on success, -1 on failure
*/ */
int accounting_init(struct hostapd_data *hapd) { int accounting_init(struct hostapd_data *hapd)
if (radius_gen_session_id((u8 *)&hapd->acct_session_id, {
sizeof(hapd->acct_session_id)) < 0) if (radius_gen_session_id((u8 *) &hapd->acct_session_id,
return -1; sizeof(hapd->acct_session_id)) < 0)
return -1;
if (radius_client_register(hapd->radius, RADIUS_ACCT, accounting_receive, if (radius_client_register(hapd->radius, RADIUS_ACCT,
hapd)) accounting_receive, hapd))
return -1; return -1;
radius_client_set_interim_error_cb(hapd->radius, accounting_interim_error_cb, radius_client_set_interim_error_cb(hapd->radius,
hapd); accounting_interim_error_cb, hapd);
accounting_report_state(hapd, 1); accounting_report_state(hapd, 1);
return 0; return 0;
} }
/** /**
* accounting_deinit: Deinitialize accounting * accounting_deinit: Deinitialize accounting
* @hapd: hostapd BSS data * @hapd: hostapd BSS data
*/ */
void accounting_deinit(struct hostapd_data *hapd) { void accounting_deinit(struct hostapd_data *hapd)
accounting_report_state(hapd, 0); {
accounting_report_state(hapd, 0);
} }
@@ -11,20 +11,30 @@
#ifdef CONFIG_NO_ACCOUNTING #ifdef CONFIG_NO_ACCOUNTING
static inline int accounting_sta_get_id(struct hostapd_data *hapd, static inline int accounting_sta_get_id(struct hostapd_data *hapd,
struct sta_info *sta) { struct sta_info *sta)
return 0; {
return 0;
} }
static inline void accounting_sta_start(struct hostapd_data *hapd, static inline void accounting_sta_start(struct hostapd_data *hapd,
struct sta_info *sta) {} struct sta_info *sta)
{
}
static inline void accounting_sta_stop(struct hostapd_data *hapd, static inline void accounting_sta_stop(struct hostapd_data *hapd,
struct sta_info *sta) {} struct sta_info *sta)
{
}
static inline int accounting_init(struct hostapd_data *hapd) { return 0; } static inline int accounting_init(struct hostapd_data *hapd)
{
return 0;
}
static inline void accounting_deinit(struct hostapd_data *hapd) {} static inline void accounting_deinit(struct hostapd_data *hapd)
#else /* CONFIG_NO_ACCOUNTING */ {
}
#else /* CONFIG_NO_ACCOUNTING */
int accounting_sta_get_id(struct hostapd_data *hapd, struct sta_info *sta); int accounting_sta_get_id(struct hostapd_data *hapd, struct sta_info *sta);
void accounting_sta_start(struct hostapd_data *hapd, struct sta_info *sta); void accounting_sta_start(struct hostapd_data *hapd, struct sta_info *sta);
void accounting_sta_stop(struct hostapd_data *hapd, struct sta_info *sta); void accounting_sta_stop(struct hostapd_data *hapd, struct sta_info *sta);
File diff suppressed because it is too large Load Diff
@@ -16,10 +16,10 @@ enum hostapd_chan_status acs_init(struct hostapd_iface *iface);
#else /* CONFIG_ACS */ #else /* CONFIG_ACS */
static inline enum hostapd_chan_status acs_init(struct hostapd_iface *iface) { static inline enum hostapd_chan_status acs_init(struct hostapd_iface *iface)
wpa_printf(MSG_ERROR, "ACS was disabled on your build, rebuild hostapd with " {
"CONFIG_ACS=y or set channel"); wpa_printf(MSG_ERROR, "ACS was disabled on your build, rebuild hostapd with CONFIG_ACS=y or set channel");
return HOSTAPD_CHAN_INVALID; return HOSTAPD_CHAN_INVALID;
} }
#endif /* CONFIG_ACS */ #endif /* CONFIG_ACS */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -18,299 +18,333 @@ struct hostapd_freq_params;
u32 hostapd_sta_flags_to_drv(u32 flags); u32 hostapd_sta_flags_to_drv(u32 flags);
int hostapd_build_ap_extra_ies(struct hostapd_data *hapd, int hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
struct wpabuf **beacon, struct wpabuf **beacon,
struct wpabuf **proberesp, struct wpabuf **proberesp,
struct wpabuf **assocresp); struct wpabuf **assocresp);
void hostapd_free_ap_extra_ies(struct hostapd_data *hapd, struct wpabuf *beacon, void hostapd_free_ap_extra_ies(struct hostapd_data *hapd, struct wpabuf *beacon,
struct wpabuf *proberesp, struct wpabuf *proberesp,
struct wpabuf *assocresp); struct wpabuf *assocresp);
int hostapd_reset_ap_wps_ie(struct hostapd_data *hapd); int hostapd_reset_ap_wps_ie(struct hostapd_data *hapd);
int hostapd_set_ap_wps_ie(struct hostapd_data *hapd); int hostapd_set_ap_wps_ie(struct hostapd_data *hapd);
int hostapd_set_authorized(struct hostapd_data *hapd, struct sta_info *sta, int hostapd_set_authorized(struct hostapd_data *hapd,
int authorized); struct sta_info *sta, int authorized);
int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta); int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta);
int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname, int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname,
int enabled); int enabled);
int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname); int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname);
int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname); int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname);
int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds, int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds,
const u8 *addr, int aid, int val); const u8 *addr, int aid, int val);
int hostapd_sta_add(struct hostapd_data *hapd, const u8 *addr, u16 aid, int hostapd_sta_add(struct hostapd_data *hapd,
u16 capability, const u8 *supp_rates, size_t supp_rates_len, const u8 *addr, u16 aid, u16 capability,
u16 listen_interval, const u8 *supp_rates, size_t supp_rates_len,
const struct ieee80211_ht_capabilities *ht_capab, u16 listen_interval,
const struct ieee80211_vht_capabilities *vht_capab, const struct ieee80211_ht_capabilities *ht_capab,
u32 flags, u8 qosinfo, u8 vht_opmode, int supp_p2p_ps, const struct ieee80211_vht_capabilities *vht_capab,
int set); u32 flags, u8 qosinfo, u8 vht_opmode, int supp_p2p_ps,
int set);
int hostapd_set_privacy(struct hostapd_data *hapd, int enabled); int hostapd_set_privacy(struct hostapd_data *hapd, int enabled);
int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem, int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem,
size_t elem_len); size_t elem_len);
int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len); int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len);
int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len); int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len);
int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type, int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
const char *ifname, const u8 *addr, void *bss_ctx, const char *ifname, const u8 *addr, void *bss_ctx,
void **drv_priv, char *force_ifname, u8 *if_addr, void **drv_priv, char *force_ifname, u8 *if_addr,
const char *bridge, int use_existing); const char *bridge, int use_existing);
int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type, int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
const char *ifname); const char *ifname);
int hostapd_set_ieee8021x(struct hostapd_data *hapd, int hostapd_set_ieee8021x(struct hostapd_data *hapd,
struct wpa_bss_params *params); struct wpa_bss_params *params);
int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd, int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
const u8 *addr, int idx, u8 *seq); const u8 *addr, int idx, u8 *seq);
int hostapd_flush(struct hostapd_data *hapd); int hostapd_flush(struct hostapd_data *hapd);
int hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode, int hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode,
int freq, int channel, int ht_enabled, int vht_enabled, int freq, int channel, int ht_enabled, int vht_enabled,
int sec_channel_offset, int vht_oper_chwidth, int sec_channel_offset, int vht_oper_chwidth,
int center_segment0, int center_segment1); int center_segment0, int center_segment1);
int hostapd_set_rts(struct hostapd_data *hapd, int rts); int hostapd_set_rts(struct hostapd_data *hapd, int rts);
int hostapd_set_frag(struct hostapd_data *hapd, int frag); int hostapd_set_frag(struct hostapd_data *hapd, int frag);
int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr, int total_flags, int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
int flags_or, int flags_and); int total_flags, int flags_or, int flags_and);
int hostapd_set_country(struct hostapd_data *hapd, const char *country); int hostapd_set_country(struct hostapd_data *hapd, const char *country);
int hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs, int hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
int cw_min, int cw_max, int burst_time); int cw_min, int cw_max, int burst_time);
struct hostapd_hw_modes *hostapd_get_hw_feature_data(struct hostapd_data *hapd, struct hostapd_hw_modes *
u16 *num_modes, hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
u16 *flags); u16 *flags);
int hostapd_driver_commit(struct hostapd_data *hapd); int hostapd_driver_commit(struct hostapd_data *hapd);
int hostapd_drv_none(struct hostapd_data *hapd); int hostapd_drv_none(struct hostapd_data *hapd);
int hostapd_driver_scan(struct hostapd_data *hapd, int hostapd_driver_scan(struct hostapd_data *hapd,
struct wpa_driver_scan_params *params); struct wpa_driver_scan_params *params);
struct wpa_scan_results * struct wpa_scan_results * hostapd_driver_get_scan_results(
hostapd_driver_get_scan_results(struct hostapd_data *hapd); struct hostapd_data *hapd);
int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start, int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
int duration); int duration);
int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd, int hostapd_drv_set_key(const char *ifname,
enum wpa_alg alg, const u8 *addr, int key_idx, struct hostapd_data *hapd,
int set_tx, const u8 *seq, size_t seq_len, enum wpa_alg alg, const u8 *addr,
const u8 *key, size_t key_len); int key_idx, int set_tx,
int hostapd_drv_send_mlme(struct hostapd_data *hapd, const void *msg, const u8 *seq, size_t seq_len,
size_t len, int noack); const u8 *key, size_t key_len);
int hostapd_drv_send_mlme_csa(struct hostapd_data *hapd, const void *msg, int hostapd_drv_send_mlme(struct hostapd_data *hapd,
size_t len, int noack, const u16 *csa_offs, const void *msg, size_t len, int noack);
size_t csa_offs_len); int hostapd_drv_send_mlme_csa(struct hostapd_data *hapd,
int hostapd_drv_sta_deauth(struct hostapd_data *hapd, const u8 *addr, const void *msg, size_t len, int noack,
int reason); const u16 *csa_offs, size_t csa_offs_len);
int hostapd_drv_sta_disassoc(struct hostapd_data *hapd, const u8 *addr, int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
int reason); const u8 *addr, int reason);
int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
const u8 *addr, int reason);
int hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq, int hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
unsigned int wait, const u8 *dst, const u8 *data, unsigned int wait, const u8 *dst, const u8 *data,
size_t len); size_t len);
int hostapd_drv_send_action_addr3_ap(struct hostapd_data *hapd, int hostapd_drv_send_action_addr3_ap(struct hostapd_data *hapd,
unsigned int freq, unsigned int wait, unsigned int freq,
const u8 *dst, const u8 *data, size_t len); unsigned int wait, const u8 *dst,
const u8 *data, size_t len);
int hostapd_add_sta_node(struct hostapd_data *hapd, const u8 *addr, int hostapd_add_sta_node(struct hostapd_data *hapd, const u8 *addr,
u16 auth_alg); u16 auth_alg);
int hostapd_sta_auth(struct hostapd_data *hapd, const u8 *addr, u16 seq, int hostapd_sta_auth(struct hostapd_data *hapd, const u8 *addr,
u16 status, const u8 *ie, size_t len); u16 seq, u16 status, const u8 *ie, size_t len);
int hostapd_sta_assoc(struct hostapd_data *hapd, const u8 *addr, int reassoc, int hostapd_sta_assoc(struct hostapd_data *hapd, const u8 *addr,
u16 status, const u8 *ie, size_t len); int reassoc, u16 status, const u8 *ie, size_t len);
int hostapd_add_tspec(struct hostapd_data *hapd, const u8 *addr, u8 *tspec_ie, int hostapd_add_tspec(struct hostapd_data *hapd, const u8 *addr,
size_t tspec_ielen); u8 *tspec_ie, size_t tspec_ielen);
int hostapd_start_dfs_cac(struct hostapd_iface *iface, int hostapd_start_dfs_cac(struct hostapd_iface *iface,
enum hostapd_hw_mode mode, int freq, int channel, enum hostapd_hw_mode mode, int freq,
int ht_enabled, int vht_enabled, int channel, int ht_enabled, int vht_enabled,
int sec_channel_offset, int vht_oper_chwidth, int sec_channel_offset, int vht_oper_chwidth,
int center_segment0, int center_segment1); int center_segment0, int center_segment1);
int hostapd_drv_do_acs(struct hostapd_data *hapd); int hostapd_drv_do_acs(struct hostapd_data *hapd);
#include "drivers/driver.h" #include "drivers/driver.h"
int hostapd_drv_wnm_oper(struct hostapd_data *hapd, enum wnm_oper oper, int hostapd_drv_wnm_oper(struct hostapd_data *hapd,
const u8 *peer, u8 *buf, u16 *buf_len); enum wnm_oper oper, const u8 *peer,
u8 *buf, u16 *buf_len);
int hostapd_drv_set_qos_map(struct hostapd_data *hapd, const u8 *qos_map_set, int hostapd_drv_set_qos_map(struct hostapd_data *hapd, const u8 *qos_map_set,
u8 qos_map_set_len); u8 qos_map_set_len);
void hostapd_get_ext_capa(struct hostapd_iface *iface); void hostapd_get_ext_capa(struct hostapd_iface *iface);
static inline int hostapd_drv_set_countermeasures(struct hostapd_data *hapd, static inline int hostapd_drv_set_countermeasures(struct hostapd_data *hapd,
int enabled) { int enabled)
if (hapd->driver == NULL || hapd->driver->hapd_set_countermeasures == NULL) {
return 0; if (hapd->driver == NULL ||
return hapd->driver->hapd_set_countermeasures(hapd->drv_priv, enabled); hapd->driver->hapd_set_countermeasures == NULL)
return 0;
return hapd->driver->hapd_set_countermeasures(hapd->drv_priv, enabled);
} }
static inline int hostapd_drv_set_sta_vlan(const char *ifname, static inline int hostapd_drv_set_sta_vlan(const char *ifname,
struct hostapd_data *hapd, struct hostapd_data *hapd,
const u8 *addr, int vlan_id) { const u8 *addr, int vlan_id)
if (hapd->driver == NULL || hapd->driver->set_sta_vlan == NULL) {
return 0; if (hapd->driver == NULL || hapd->driver->set_sta_vlan == NULL)
return hapd->driver->set_sta_vlan(hapd->drv_priv, addr, ifname, vlan_id); return 0;
return hapd->driver->set_sta_vlan(hapd->drv_priv, addr, ifname,
vlan_id);
} }
static inline int hostapd_drv_get_inact_sec(struct hostapd_data *hapd, static inline int hostapd_drv_get_inact_sec(struct hostapd_data *hapd,
const u8 *addr) { const u8 *addr)
if (hapd->driver == NULL || hapd->driver->get_inact_sec == NULL) {
return 0; if (hapd->driver == NULL || hapd->driver->get_inact_sec == NULL)
return hapd->driver->get_inact_sec(hapd->drv_priv, addr); return 0;
return hapd->driver->get_inact_sec(hapd->drv_priv, addr);
} }
static inline int hostapd_drv_sta_remove(struct hostapd_data *hapd, static inline int hostapd_drv_sta_remove(struct hostapd_data *hapd,
const u8 *addr) { const u8 *addr)
if (!hapd->driver || !hapd->driver->sta_remove || !hapd->drv_priv) {
return 0; if (!hapd->driver || !hapd->driver->sta_remove || !hapd->drv_priv)
return hapd->driver->sta_remove(hapd->drv_priv, addr); return 0;
return hapd->driver->sta_remove(hapd->drv_priv, addr);
} }
static inline int hostapd_drv_hapd_send_eapol(struct hostapd_data *hapd, static inline int hostapd_drv_hapd_send_eapol(struct hostapd_data *hapd,
const u8 *addr, const u8 *data, const u8 *addr, const u8 *data,
size_t data_len, int encrypt, size_t data_len, int encrypt,
u32 flags) { u32 flags)
if (hapd->driver == NULL || hapd->driver->hapd_send_eapol == NULL) {
return 0; if (hapd->driver == NULL || hapd->driver->hapd_send_eapol == NULL)
return hapd->driver->hapd_send_eapol(hapd->drv_priv, addr, data, data_len, return 0;
encrypt, hapd->own_addr, flags); return hapd->driver->hapd_send_eapol(hapd->drv_priv, addr, data,
data_len, encrypt,
hapd->own_addr, flags);
} }
static inline int hostapd_drv_read_sta_data(struct hostapd_data *hapd, static inline int hostapd_drv_read_sta_data(
struct hostap_sta_driver_data *data, struct hostapd_data *hapd, struct hostap_sta_driver_data *data,
const u8 *addr) { const u8 *addr)
if (hapd->driver == NULL || hapd->driver->read_sta_data == NULL) {
return -1; if (hapd->driver == NULL || hapd->driver->read_sta_data == NULL)
return hapd->driver->read_sta_data(hapd->drv_priv, data, addr); return -1;
return hapd->driver->read_sta_data(hapd->drv_priv, data, addr);
} }
static inline int hostapd_drv_sta_clear_stats(struct hostapd_data *hapd, static inline int hostapd_drv_sta_clear_stats(struct hostapd_data *hapd,
const u8 *addr) { const u8 *addr)
if (hapd->driver == NULL || hapd->driver->sta_clear_stats == NULL) {
return 0; if (hapd->driver == NULL || hapd->driver->sta_clear_stats == NULL)
return hapd->driver->sta_clear_stats(hapd->drv_priv, addr); return 0;
return hapd->driver->sta_clear_stats(hapd->drv_priv, addr);
} }
static inline int hostapd_drv_set_acl(struct hostapd_data *hapd, static inline int hostapd_drv_set_acl(struct hostapd_data *hapd,
struct hostapd_acl_params *params) { struct hostapd_acl_params *params)
if (hapd->driver == NULL || hapd->driver->set_acl == NULL) {
return 0; if (hapd->driver == NULL || hapd->driver->set_acl == NULL)
return hapd->driver->set_acl(hapd->drv_priv, params); return 0;
return hapd->driver->set_acl(hapd->drv_priv, params);
} }
static inline int hostapd_drv_set_ap(struct hostapd_data *hapd, static inline int hostapd_drv_set_ap(struct hostapd_data *hapd,
struct wpa_driver_ap_params *params) { struct wpa_driver_ap_params *params)
if (hapd->driver == NULL || hapd->driver->set_ap == NULL) {
return 0; if (hapd->driver == NULL || hapd->driver->set_ap == NULL)
return hapd->driver->set_ap(hapd->drv_priv, params); return 0;
return hapd->driver->set_ap(hapd->drv_priv, params);
} }
static inline int hostapd_drv_set_radius_acl_auth(struct hostapd_data *hapd, static inline int hostapd_drv_set_radius_acl_auth(struct hostapd_data *hapd,
const u8 *mac, int accepted, const u8 *mac, int accepted,
u32 session_timeout) { u32 session_timeout)
if (hapd->driver == NULL || hapd->driver->set_radius_acl_auth == NULL) {
return 0; if (hapd->driver == NULL || hapd->driver->set_radius_acl_auth == NULL)
return hapd->driver->set_radius_acl_auth(hapd->drv_priv, mac, accepted, return 0;
session_timeout); return hapd->driver->set_radius_acl_auth(hapd->drv_priv, mac, accepted,
session_timeout);
} }
static inline int hostapd_drv_set_radius_acl_expire(struct hostapd_data *hapd, static inline int hostapd_drv_set_radius_acl_expire(struct hostapd_data *hapd,
const u8 *mac) { const u8 *mac)
if (hapd->driver == NULL || hapd->driver->set_radius_acl_expire == NULL) {
return 0; if (hapd->driver == NULL ||
return hapd->driver->set_radius_acl_expire(hapd->drv_priv, mac); hapd->driver->set_radius_acl_expire == NULL)
return 0;
return hapd->driver->set_radius_acl_expire(hapd->drv_priv, mac);
} }
static inline int hostapd_drv_set_authmode(struct hostapd_data *hapd, static inline int hostapd_drv_set_authmode(struct hostapd_data *hapd,
int auth_algs) { int auth_algs)
if (hapd->driver == NULL || hapd->driver->set_authmode == NULL) {
return 0; if (hapd->driver == NULL || hapd->driver->set_authmode == NULL)
return hapd->driver->set_authmode(hapd->drv_priv, auth_algs); return 0;
return hapd->driver->set_authmode(hapd->drv_priv, auth_algs);
} }
static inline void hostapd_drv_poll_client(struct hostapd_data *hapd, static inline void hostapd_drv_poll_client(struct hostapd_data *hapd,
const u8 *own_addr, const u8 *addr, const u8 *own_addr, const u8 *addr,
int qos) { int qos)
if (hapd->driver == NULL || hapd->driver->poll_client == NULL) {
return; if (hapd->driver == NULL || hapd->driver->poll_client == NULL)
hapd->driver->poll_client(hapd->drv_priv, own_addr, addr, qos); return;
hapd->driver->poll_client(hapd->drv_priv, own_addr, addr, qos);
} }
static inline int hostapd_drv_get_survey(struct hostapd_data *hapd, static inline int hostapd_drv_get_survey(struct hostapd_data *hapd,
unsigned int freq) { unsigned int freq)
if (hapd->driver == NULL) {
return -1; if (hapd->driver == NULL)
if (!hapd->driver->get_survey) return -1;
return -1; if (!hapd->driver->get_survey)
return hapd->driver->get_survey(hapd->drv_priv, freq); return -1;
return hapd->driver->get_survey(hapd->drv_priv, freq);
} }
static inline int hostapd_get_country(struct hostapd_data *hapd, char *alpha2) { static inline int hostapd_get_country(struct hostapd_data *hapd, char *alpha2)
if (hapd->driver == NULL || hapd->driver->get_country == NULL) {
return -1; if (hapd->driver == NULL || hapd->driver->get_country == NULL)
return hapd->driver->get_country(hapd->drv_priv, alpha2); return -1;
return hapd->driver->get_country(hapd->drv_priv, alpha2);
} }
static inline const char * static inline const char * hostapd_drv_get_radio_name(struct hostapd_data *hapd)
hostapd_drv_get_radio_name(struct hostapd_data *hapd) { {
if (hapd->driver == NULL || hapd->drv_priv == NULL || if (hapd->driver == NULL || hapd->drv_priv == NULL ||
hapd->driver->get_radio_name == NULL) hapd->driver->get_radio_name == NULL)
return NULL; return NULL;
return hapd->driver->get_radio_name(hapd->drv_priv); return hapd->driver->get_radio_name(hapd->drv_priv);
} }
static inline int hostapd_drv_switch_channel(struct hostapd_data *hapd, static inline int hostapd_drv_switch_channel(struct hostapd_data *hapd,
struct csa_settings *settings) { struct csa_settings *settings)
if (hapd->driver == NULL || hapd->driver->switch_channel == NULL) {
return -ENOTSUP; if (hapd->driver == NULL || hapd->driver->switch_channel == NULL)
return -ENOTSUP;
return hapd->driver->switch_channel(hapd->drv_priv, settings); return hapd->driver->switch_channel(hapd->drv_priv, settings);
} }
static inline int hostapd_drv_status(struct hostapd_data *hapd, char *buf, static inline int hostapd_drv_status(struct hostapd_data *hapd, char *buf,
size_t buflen) { size_t buflen)
if (!hapd->driver || !hapd->driver->status || !hapd->drv_priv) {
return -1; if (!hapd->driver || !hapd->driver->status || !hapd->drv_priv)
return hapd->driver->status(hapd->drv_priv, buf, buflen); return -1;
return hapd->driver->status(hapd->drv_priv, buf, buflen);
} }
static inline int hostapd_drv_br_add_ip_neigh(struct hostapd_data *hapd, static inline int hostapd_drv_br_add_ip_neigh(struct hostapd_data *hapd,
int version, const u8 *ipaddr, int version, const u8 *ipaddr,
int prefixlen, const u8 *addr) { int prefixlen, const u8 *addr)
if (hapd->driver == NULL || hapd->drv_priv == NULL || {
hapd->driver->br_add_ip_neigh == NULL) if (hapd->driver == NULL || hapd->drv_priv == NULL ||
return -1; hapd->driver->br_add_ip_neigh == NULL)
return hapd->driver->br_add_ip_neigh(hapd->drv_priv, version, ipaddr, return -1;
prefixlen, addr); return hapd->driver->br_add_ip_neigh(hapd->drv_priv, version, ipaddr,
prefixlen, addr);
} }
static inline int hostapd_drv_br_delete_ip_neigh(struct hostapd_data *hapd, static inline int hostapd_drv_br_delete_ip_neigh(struct hostapd_data *hapd,
u8 version, const u8 *ipaddr) { u8 version, const u8 *ipaddr)
if (hapd->driver == NULL || hapd->drv_priv == NULL || {
hapd->driver->br_delete_ip_neigh == NULL) if (hapd->driver == NULL || hapd->drv_priv == NULL ||
return -1; hapd->driver->br_delete_ip_neigh == NULL)
return hapd->driver->br_delete_ip_neigh(hapd->drv_priv, version, ipaddr); return -1;
return hapd->driver->br_delete_ip_neigh(hapd->drv_priv, version,
ipaddr);
} }
static inline int hostapd_drv_br_port_set_attr(struct hostapd_data *hapd, static inline int hostapd_drv_br_port_set_attr(struct hostapd_data *hapd,
enum drv_br_port_attr attr, enum drv_br_port_attr attr,
unsigned int val) { unsigned int val)
if (hapd->driver == NULL || hapd->drv_priv == NULL || {
hapd->driver->br_port_set_attr == NULL) if (hapd->driver == NULL || hapd->drv_priv == NULL ||
return -1; hapd->driver->br_port_set_attr == NULL)
return hapd->driver->br_port_set_attr(hapd->drv_priv, attr, val); return -1;
return hapd->driver->br_port_set_attr(hapd->drv_priv, attr, val);
} }
static inline int hostapd_drv_br_set_net_param(struct hostapd_data *hapd, static inline int hostapd_drv_br_set_net_param(struct hostapd_data *hapd,
enum drv_br_net_param param, enum drv_br_net_param param,
unsigned int val) { unsigned int val)
if (hapd->driver == NULL || hapd->drv_priv == NULL || {
hapd->driver->br_set_net_param == NULL) if (hapd->driver == NULL || hapd->drv_priv == NULL ||
return -1; hapd->driver->br_set_net_param == NULL)
return hapd->driver->br_set_net_param(hapd->drv_priv, param, val); return -1;
return hapd->driver->br_set_net_param(hapd->drv_priv, param, val);
} }
static inline int hostapd_drv_vendor_cmd(struct hostapd_data *hapd, static inline int hostapd_drv_vendor_cmd(struct hostapd_data *hapd,
int vendor_id, int subcmd, int vendor_id, int subcmd,
const u8 *data, size_t data_len, const u8 *data, size_t data_len,
struct wpabuf *buf) { struct wpabuf *buf)
if (hapd->driver == NULL || hapd->driver->vendor_cmd == NULL) {
return -1; if (hapd->driver == NULL || hapd->driver->vendor_cmd == NULL)
return hapd->driver->vendor_cmd(hapd->drv_priv, vendor_id, subcmd, data, return -1;
data_len, buf); return hapd->driver->vendor_cmd(hapd->drv_priv, vendor_id, subcmd, data,
data_len, buf);
} }
static inline int hostapd_drv_stop_ap(struct hostapd_data *hapd) { static inline int hostapd_drv_stop_ap(struct hostapd_data *hapd)
if (!hapd->driver || !hapd->driver->stop_ap || !hapd->drv_priv) {
return 0; if (!hapd->driver || !hapd->driver->stop_ap || !hapd->drv_priv)
return hapd->driver->stop_ap(hapd->drv_priv); return 0;
return hapd->driver->stop_ap(hapd->drv_priv);
} }
#endif /* AP_DRV_OPS */ #endif /* AP_DRV_OPS */
+230 -199
View File
@@ -10,272 +10,303 @@
#include "utils/includes.h" #include "utils/includes.h"
#include "ap_config.h"
#include "ap_list.h"
#include "beacon.h"
#include "common/ieee802_11_common.h"
#include "common/ieee802_11_defs.h"
#include "hostapd.h"
#include "ieee802_11.h"
#include "sta_info.h"
#include "utils/common.h" #include "utils/common.h"
#include "utils/eloop.h" #include "utils/eloop.h"
#include "common/ieee802_11_defs.h"
#include "common/ieee802_11_common.h"
#include "hostapd.h"
#include "ap_config.h"
#include "ieee802_11.h"
#include "sta_info.h"
#include "beacon.h"
#include "ap_list.h"
/* AP list is a double linked list with head->prev pointing to the end of the /* AP list is a double linked list with head->prev pointing to the end of the
* list and tail->next = NULL. Entries are moved to the head of the list * list and tail->next = NULL. Entries are moved to the head of the list
* whenever a beacon has been received from the AP in question. The tail entry * whenever a beacon has been received from the AP in question. The tail entry
* in this link will thus be the least recently used entry. */ * in this link will thus be the least recently used entry. */
static int ap_list_beacon_olbc(struct hostapd_iface *iface,
struct ap_info *ap) {
int i;
if (iface->current_mode == NULL || static int ap_list_beacon_olbc(struct hostapd_iface *iface, struct ap_info *ap)
iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G || {
iface->conf->channel != ap->channel) int i;
return 0;
if (ap->erp != -1 && (ap->erp & ERP_INFO_NON_ERP_PRESENT)) if (iface->current_mode == NULL ||
return 1; iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G ||
iface->conf->channel != ap->channel)
return 0;
for (i = 0; i < WLAN_SUPP_RATES_MAX; i++) { if (ap->erp != -1 && (ap->erp & ERP_INFO_NON_ERP_PRESENT))
int rate = (ap->supported_rates[i] & 0x7f) * 5; return 1;
if (rate == 60 || rate == 90 || rate > 110)
return 0;
}
return 1; for (i = 0; i < WLAN_SUPP_RATES_MAX; i++) {
int rate = (ap->supported_rates[i] & 0x7f) * 5;
if (rate == 60 || rate == 90 || rate > 110)
return 0;
}
return 1;
} }
static struct ap_info *ap_get_ap(struct hostapd_iface *iface, const u8 *ap) {
struct ap_info *s;
s = iface->ap_hash[STA_HASH(ap)]; static struct ap_info * ap_get_ap(struct hostapd_iface *iface, const u8 *ap)
while (s != NULL && os_memcmp(s->addr, ap, ETH_ALEN) != 0) {
s = s->hnext; struct ap_info *s;
return s;
s = iface->ap_hash[STA_HASH(ap)];
while (s != NULL && os_memcmp(s->addr, ap, ETH_ALEN) != 0)
s = s->hnext;
return s;
} }
static void ap_ap_list_add(struct hostapd_iface *iface, struct ap_info *ap) {
if (iface->ap_list) { static void ap_ap_list_add(struct hostapd_iface *iface, struct ap_info *ap)
ap->prev = iface->ap_list->prev; {
iface->ap_list->prev = ap; if (iface->ap_list) {
} else ap->prev = iface->ap_list->prev;
ap->prev = ap; iface->ap_list->prev = ap;
ap->next = iface->ap_list; } else
iface->ap_list = ap; ap->prev = ap;
ap->next = iface->ap_list;
iface->ap_list = ap;
} }
static void ap_ap_list_del(struct hostapd_iface *iface, struct ap_info *ap) {
if (iface->ap_list == ap)
iface->ap_list = ap->next;
else
ap->prev->next = ap->next;
if (ap->next) static void ap_ap_list_del(struct hostapd_iface *iface, struct ap_info *ap)
ap->next->prev = ap->prev; {
else if (iface->ap_list) if (iface->ap_list == ap)
iface->ap_list->prev = ap->prev; iface->ap_list = ap->next;
else
ap->prev->next = ap->next;
if (ap->next)
ap->next->prev = ap->prev;
else if (iface->ap_list)
iface->ap_list->prev = ap->prev;
} }
static void ap_ap_hash_add(struct hostapd_iface *iface, struct ap_info *ap) {
ap->hnext = iface->ap_hash[STA_HASH(ap->addr)]; static void ap_ap_hash_add(struct hostapd_iface *iface, struct ap_info *ap)
iface->ap_hash[STA_HASH(ap->addr)] = ap; {
ap->hnext = iface->ap_hash[STA_HASH(ap->addr)];
iface->ap_hash[STA_HASH(ap->addr)] = ap;
} }
static void ap_ap_hash_del(struct hostapd_iface *iface, struct ap_info *ap) {
struct ap_info *s;
s = iface->ap_hash[STA_HASH(ap->addr)]; static void ap_ap_hash_del(struct hostapd_iface *iface, struct ap_info *ap)
if (s == NULL) {
return; struct ap_info *s;
if (os_memcmp(s->addr, ap->addr, ETH_ALEN) == 0) {
iface->ap_hash[STA_HASH(ap->addr)] = s->hnext;
return;
}
while (s->hnext != NULL && os_memcmp(s->hnext->addr, ap->addr, ETH_ALEN) != 0) s = iface->ap_hash[STA_HASH(ap->addr)];
s = s->hnext; if (s == NULL) return;
if (s->hnext != NULL) if (os_memcmp(s->addr, ap->addr, ETH_ALEN) == 0) {
s->hnext = s->hnext->hnext; iface->ap_hash[STA_HASH(ap->addr)] = s->hnext;
else return;
wpa_printf(MSG_INFO, "AP: could not remove AP " MACSTR " from hash table", }
MAC2STR(ap->addr));
while (s->hnext != NULL &&
os_memcmp(s->hnext->addr, ap->addr, ETH_ALEN) != 0)
s = s->hnext;
if (s->hnext != NULL)
s->hnext = s->hnext->hnext;
else
wpa_printf(MSG_INFO, "AP: could not remove AP " MACSTR
" from hash table", MAC2STR(ap->addr));
} }
static void ap_free_ap(struct hostapd_iface *iface, struct ap_info *ap) {
ap_ap_hash_del(iface, ap);
ap_ap_list_del(iface, ap);
iface->num_ap--; static void ap_free_ap(struct hostapd_iface *iface, struct ap_info *ap)
os_free(ap); {
ap_ap_hash_del(iface, ap);
ap_ap_list_del(iface, ap);
iface->num_ap--;
os_free(ap);
} }
static void hostapd_free_aps(struct hostapd_iface *iface) {
struct ap_info *ap, *prev;
ap = iface->ap_list; static void hostapd_free_aps(struct hostapd_iface *iface)
{
struct ap_info *ap, *prev;
while (ap) { ap = iface->ap_list;
prev = ap;
ap = ap->next;
ap_free_ap(iface, prev);
}
iface->ap_list = NULL; while (ap) {
prev = ap;
ap = ap->next;
ap_free_ap(iface, prev);
}
iface->ap_list = NULL;
} }
static struct ap_info *ap_ap_add(struct hostapd_iface *iface, const u8 *addr) {
struct ap_info *ap;
ap = os_zalloc(sizeof(struct ap_info)); static struct ap_info * ap_ap_add(struct hostapd_iface *iface, const u8 *addr)
if (ap == NULL) {
return NULL; struct ap_info *ap;
/* initialize AP info data */ ap = os_zalloc(sizeof(struct ap_info));
os_memcpy(ap->addr, addr, ETH_ALEN); if (ap == NULL)
ap_ap_list_add(iface, ap); return NULL;
iface->num_ap++;
ap_ap_hash_add(iface, ap);
if (iface->num_ap > iface->conf->ap_table_max_size && ap != ap->prev) { /* initialize AP info data */
wpa_printf(MSG_DEBUG, os_memcpy(ap->addr, addr, ETH_ALEN);
"Removing the least recently used AP " MACSTR " from AP table", ap_ap_list_add(iface, ap);
MAC2STR(ap->prev->addr)); iface->num_ap++;
ap_free_ap(iface, ap->prev); ap_ap_hash_add(iface, ap);
}
return ap; if (iface->num_ap > iface->conf->ap_table_max_size && ap != ap->prev) {
wpa_printf(MSG_DEBUG, "Removing the least recently used AP "
MACSTR " from AP table", MAC2STR(ap->prev->addr));
ap_free_ap(iface, ap->prev);
}
return ap;
} }
void ap_list_process_beacon(struct hostapd_iface *iface, void ap_list_process_beacon(struct hostapd_iface *iface,
const struct ieee80211_mgmt *mgmt, const struct ieee80211_mgmt *mgmt,
struct ieee802_11_elems *elems, struct ieee802_11_elems *elems,
struct hostapd_frame_info *fi) { struct hostapd_frame_info *fi)
struct ap_info *ap; {
int new_ap = 0; struct ap_info *ap;
int set_beacon = 0; int new_ap = 0;
int set_beacon = 0;
if (iface->conf->ap_table_max_size < 1) if (iface->conf->ap_table_max_size < 1)
return; return;
ap = ap_get_ap(iface, mgmt->bssid); ap = ap_get_ap(iface, mgmt->bssid);
if (!ap) { if (!ap) {
ap = ap_ap_add(iface, mgmt->bssid); ap = ap_ap_add(iface, mgmt->bssid);
if (!ap) { if (!ap) {
wpa_printf(MSG_INFO, "Failed to allocate AP information entry"); wpa_printf(MSG_INFO,
return; "Failed to allocate AP information entry");
} return;
new_ap = 1; }
} new_ap = 1;
}
merge_byte_arrays(ap->supported_rates, WLAN_SUPP_RATES_MAX, elems->supp_rates, merge_byte_arrays(ap->supported_rates, WLAN_SUPP_RATES_MAX,
elems->supp_rates_len, elems->ext_supp_rates, elems->supp_rates, elems->supp_rates_len,
elems->ext_supp_rates_len); elems->ext_supp_rates, elems->ext_supp_rates_len);
if (elems->erp_info) if (elems->erp_info)
ap->erp = elems->erp_info[0]; ap->erp = elems->erp_info[0];
else else
ap->erp = -1; ap->erp = -1;
if (elems->ds_params) if (elems->ds_params)
ap->channel = elems->ds_params[0]; ap->channel = elems->ds_params[0];
else if (elems->ht_operation) else if (elems->ht_operation)
ap->channel = elems->ht_operation[0]; ap->channel = elems->ht_operation[0];
else if (fi) else if (fi)
ap->channel = fi->channel; ap->channel = fi->channel;
if (elems->ht_capabilities) if (elems->ht_capabilities)
ap->ht_support = 1; ap->ht_support = 1;
else else
ap->ht_support = 0; ap->ht_support = 0;
os_get_reltime(&ap->last_beacon); os_get_reltime(&ap->last_beacon);
if (!new_ap && ap != iface->ap_list) { if (!new_ap && ap != iface->ap_list) {
/* move AP entry into the beginning of the list so that the /* move AP entry into the beginning of the list so that the
* oldest entry is always in the end of the list */ * oldest entry is always in the end of the list */
ap_ap_list_del(iface, ap); ap_ap_list_del(iface, ap);
ap_ap_list_add(iface, ap); ap_ap_list_add(iface, ap);
} }
if (!iface->olbc && ap_list_beacon_olbc(iface, ap)) { if (!iface->olbc &&
iface->olbc = 1; ap_list_beacon_olbc(iface, ap)) {
wpa_printf(MSG_DEBUG, iface->olbc = 1;
"OLBC AP detected: " MACSTR " (channel %d) - enable protection", wpa_printf(MSG_DEBUG, "OLBC AP detected: " MACSTR
MAC2STR(ap->addr), ap->channel); " (channel %d) - enable protection",
set_beacon++; MAC2STR(ap->addr), ap->channel);
} set_beacon++;
}
#ifdef CONFIG_IEEE80211N #ifdef CONFIG_IEEE80211N
if (!iface->olbc_ht && !ap->ht_support && if (!iface->olbc_ht && !ap->ht_support &&
(ap->channel == 0 || ap->channel == iface->conf->channel || (ap->channel == 0 ||
ap->channel == ap->channel == iface->conf->channel ||
iface->conf->channel + iface->conf->secondary_channel * 4)) { ap->channel == iface->conf->channel +
iface->olbc_ht = 1; iface->conf->secondary_channel * 4)) {
hostapd_ht_operation_update(iface); iface->olbc_ht = 1;
wpa_printf(MSG_DEBUG, hostapd_ht_operation_update(iface);
"OLBC HT AP detected: " MACSTR wpa_printf(MSG_DEBUG, "OLBC HT AP detected: " MACSTR
" (channel %d) - enable protection", " (channel %d) - enable protection",
MAC2STR(ap->addr), ap->channel); MAC2STR(ap->addr), ap->channel);
set_beacon++; set_beacon++;
} }
#endif /* CONFIG_IEEE80211N */ #endif /* CONFIG_IEEE80211N */
if (set_beacon) if (set_beacon)
ieee802_11_update_beacons(iface); ieee802_11_update_beacons(iface);
} }
void ap_list_timer(struct hostapd_iface *iface) {
struct os_reltime now;
struct ap_info *ap;
int set_beacon = 0;
if (!iface->ap_list) void ap_list_timer(struct hostapd_iface *iface)
return; {
struct os_reltime now;
struct ap_info *ap;
int set_beacon = 0;
os_get_reltime(&now); if (!iface->ap_list)
return;
while (iface->ap_list) { os_get_reltime(&now);
ap = iface->ap_list->prev;
if (!os_reltime_expired(&now, &ap->last_beacon,
iface->conf->ap_table_expiration_time))
break;
ap_free_ap(iface, ap); while (iface->ap_list) {
} ap = iface->ap_list->prev;
if (!os_reltime_expired(&now, &ap->last_beacon,
iface->conf->ap_table_expiration_time))
break;
if (iface->olbc || iface->olbc_ht) { ap_free_ap(iface, ap);
int olbc = 0; }
int olbc_ht = 0;
ap = iface->ap_list; if (iface->olbc || iface->olbc_ht) {
while (ap && (olbc == 0 || olbc_ht == 0)) { int olbc = 0;
if (ap_list_beacon_olbc(iface, ap)) int olbc_ht = 0;
olbc = 1;
if (!ap->ht_support) ap = iface->ap_list;
olbc_ht = 1; while (ap && (olbc == 0 || olbc_ht == 0)) {
ap = ap->next; if (ap_list_beacon_olbc(iface, ap))
} olbc = 1;
if (!olbc && iface->olbc) { if (!ap->ht_support)
wpa_printf(MSG_DEBUG, "OLBC not detected anymore"); olbc_ht = 1;
iface->olbc = 0; ap = ap->next;
set_beacon++; }
} if (!olbc && iface->olbc) {
wpa_printf(MSG_DEBUG, "OLBC not detected anymore");
iface->olbc = 0;
set_beacon++;
}
#ifdef CONFIG_IEEE80211N #ifdef CONFIG_IEEE80211N
if (!olbc_ht && iface->olbc_ht) { if (!olbc_ht && iface->olbc_ht) {
wpa_printf(MSG_DEBUG, "OLBC HT not detected anymore"); wpa_printf(MSG_DEBUG, "OLBC HT not detected anymore");
iface->olbc_ht = 0; iface->olbc_ht = 0;
hostapd_ht_operation_update(iface); hostapd_ht_operation_update(iface);
set_beacon++; set_beacon++;
} }
#endif /* CONFIG_IEEE80211N */ #endif /* CONFIG_IEEE80211N */
} }
if (set_beacon) if (set_beacon)
ieee802_11_update_beacons(iface); ieee802_11_update_beacons(iface);
} }
int ap_list_init(struct hostapd_iface *iface) { return 0; }
void ap_list_deinit(struct hostapd_iface *iface) { hostapd_free_aps(iface); } int ap_list_init(struct hostapd_iface *iface)
{
return 0;
}
void ap_list_deinit(struct hostapd_iface *iface)
{
hostapd_free_aps(iface);
}
@@ -12,40 +12,47 @@
#define AP_LIST_H #define AP_LIST_H
struct ap_info { struct ap_info {
/* Note: next/prev pointers are updated whenever a new beacon is /* Note: next/prev pointers are updated whenever a new beacon is
* received because these are used to find the least recently used * received because these are used to find the least recently used
* entries. */ * entries. */
struct ap_info *next; /* next entry in AP list */ struct ap_info *next; /* next entry in AP list */
struct ap_info *prev; /* previous entry in AP list */ struct ap_info *prev; /* previous entry in AP list */
struct ap_info *hnext; /* next entry in hash table list */ struct ap_info *hnext; /* next entry in hash table list */
u8 addr[6]; u8 addr[6];
u8 supported_rates[WLAN_SUPP_RATES_MAX]; u8 supported_rates[WLAN_SUPP_RATES_MAX];
int erp; /* ERP Info or -1 if ERP info element not present */ int erp; /* ERP Info or -1 if ERP info element not present */
int channel; int channel;
int ht_support; int ht_support;
struct os_reltime last_beacon; struct os_reltime last_beacon;
}; };
struct ieee802_11_elems; struct ieee802_11_elems;
struct hostapd_frame_info; struct hostapd_frame_info;
void ap_list_process_beacon(struct hostapd_iface *iface, void ap_list_process_beacon(struct hostapd_iface *iface,
const struct ieee80211_mgmt *mgmt, const struct ieee80211_mgmt *mgmt,
struct ieee802_11_elems *elems, struct ieee802_11_elems *elems,
struct hostapd_frame_info *fi); struct hostapd_frame_info *fi);
#ifdef NEED_AP_MLME #ifdef NEED_AP_MLME
int ap_list_init(struct hostapd_iface *iface); int ap_list_init(struct hostapd_iface *iface);
void ap_list_deinit(struct hostapd_iface *iface); void ap_list_deinit(struct hostapd_iface *iface);
void ap_list_timer(struct hostapd_iface *iface); void ap_list_timer(struct hostapd_iface *iface);
#else /* NEED_AP_MLME */ #else /* NEED_AP_MLME */
static inline int ap_list_init(struct hostapd_iface *iface) { return 0; } static inline int ap_list_init(struct hostapd_iface *iface)
{
return 0;
}
static inline void ap_list_deinit(struct hostapd_iface *iface) {} static inline void ap_list_deinit(struct hostapd_iface *iface)
{
}
static inline void ap_list_timer(struct hostapd_iface *iface) {} static inline void ap_list_timer(struct hostapd_iface *iface)
{
}
#endif /* NEED_AP_MLME */ #endif /* NEED_AP_MLME */
#endif /* AP_LIST_H */ #endif /* AP_LIST_H */
@@ -10,29 +10,32 @@
#include "utils/includes.h" #include "utils/includes.h"
#include "ap_mlme.h"
#include "common/ieee802_11_defs.h"
#include "hostapd.h"
#include "ieee802_11.h"
#include "sta_info.h"
#include "utils/common.h" #include "utils/common.h"
#include "common/ieee802_11_defs.h"
#include "ieee802_11.h"
#include "wpa_auth.h" #include "wpa_auth.h"
#include "sta_info.h"
#include "ap_mlme.h"
#include "hostapd.h"
#ifndef CONFIG_NO_HOSTAPD_LOGGER #ifndef CONFIG_NO_HOSTAPD_LOGGER
static const char *mlme_auth_alg_str(int alg) { static const char * mlme_auth_alg_str(int alg)
switch (alg) { {
case WLAN_AUTH_OPEN: switch (alg) {
return "OPEN_SYSTEM"; case WLAN_AUTH_OPEN:
case WLAN_AUTH_SHARED_KEY: return "OPEN_SYSTEM";
return "SHARED_KEY"; case WLAN_AUTH_SHARED_KEY:
case WLAN_AUTH_FT: return "SHARED_KEY";
return "FT"; case WLAN_AUTH_FT:
} return "FT";
}
return "unknown"; return "unknown";
} }
#endif /* CONFIG_NO_HOSTAPD_LOGGER */ #endif /* CONFIG_NO_HOSTAPD_LOGGER */
/** /**
* mlme_authenticate_indication - Report the establishment of an authentication * mlme_authenticate_indication - Report the establishment of an authentication
* relationship with a specific peer MAC entity * relationship with a specific peer MAC entity
@@ -48,15 +51,18 @@ static const char *mlme_auth_alg_str(int alg) {
* AuthenticationType = sta->auth_alg (WLAN_AUTH_OPEN / WLAN_AUTH_SHARED_KEY) * AuthenticationType = sta->auth_alg (WLAN_AUTH_OPEN / WLAN_AUTH_SHARED_KEY)
*/ */
void mlme_authenticate_indication(struct hostapd_data *hapd, void mlme_authenticate_indication(struct hostapd_data *hapd,
struct sta_info *sta) { struct sta_info *sta)
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_MLME, HOSTAPD_LEVEL_DEBUG, {
"MLME-AUTHENTICATE.indication(" MACSTR ", %s)", hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_MLME,
MAC2STR(sta->addr), mlme_auth_alg_str(sta->auth_alg)); HOSTAPD_LEVEL_DEBUG,
if (sta->auth_alg != WLAN_AUTH_FT && !(sta->flags & WLAN_STA_MFP)) "MLME-AUTHENTICATE.indication(" MACSTR ", %s)",
mlme_deletekeys_request(hapd, sta); MAC2STR(sta->addr), mlme_auth_alg_str(sta->auth_alg));
ap_sta_clear_disconnect_timeouts(hapd, sta); if (sta->auth_alg != WLAN_AUTH_FT && !(sta->flags & WLAN_STA_MFP))
mlme_deletekeys_request(hapd, sta);
ap_sta_clear_disconnect_timeouts(hapd, sta);
} }
/** /**
* mlme_deauthenticate_indication - Report the invalidation of an * mlme_deauthenticate_indication - Report the invalidation of an
* authentication relationship with a specific peer MAC entity * authentication relationship with a specific peer MAC entity
@@ -70,14 +76,17 @@ void mlme_authenticate_indication(struct hostapd_data *hapd,
* PeerSTAAddress = sta->addr * PeerSTAAddress = sta->addr
*/ */
void mlme_deauthenticate_indication(struct hostapd_data *hapd, void mlme_deauthenticate_indication(struct hostapd_data *hapd,
struct sta_info *sta, u16 reason_code) { struct sta_info *sta, u16 reason_code)
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_MLME, HOSTAPD_LEVEL_DEBUG, {
"MLME-DEAUTHENTICATE.indication(" MACSTR ", %d)", hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_MLME,
MAC2STR(sta->addr), reason_code); HOSTAPD_LEVEL_DEBUG,
if (!hapd->iface->driver_ap_teardown) "MLME-DEAUTHENTICATE.indication(" MACSTR ", %d)",
mlme_deletekeys_request(hapd, sta); MAC2STR(sta->addr), reason_code);
if (!hapd->iface->driver_ap_teardown)
mlme_deletekeys_request(hapd, sta);
} }
/** /**
* mlme_associate_indication - Report the establishment of an association with * mlme_associate_indication - Report the establishment of an association with
* a specific peer MAC entity * a specific peer MAC entity
@@ -90,15 +99,18 @@ void mlme_deauthenticate_indication(struct hostapd_data *hapd,
* *
* PeerSTAAddress = sta->addr * PeerSTAAddress = sta->addr
*/ */
void mlme_associate_indication(struct hostapd_data *hapd, void mlme_associate_indication(struct hostapd_data *hapd, struct sta_info *sta)
struct sta_info *sta) { {
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_MLME, HOSTAPD_LEVEL_DEBUG, hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_MLME,
"MLME-ASSOCIATE.indication(" MACSTR ")", MAC2STR(sta->addr)); HOSTAPD_LEVEL_DEBUG,
if (sta->auth_alg != WLAN_AUTH_FT) "MLME-ASSOCIATE.indication(" MACSTR ")",
mlme_deletekeys_request(hapd, sta); MAC2STR(sta->addr));
ap_sta_clear_disconnect_timeouts(hapd, sta); if (sta->auth_alg != WLAN_AUTH_FT)
mlme_deletekeys_request(hapd, sta);
ap_sta_clear_disconnect_timeouts(hapd, sta);
} }
/** /**
* mlme_reassociate_indication - Report the establishment of an reassociation * mlme_reassociate_indication - Report the establishment of an reassociation
* with a specific peer MAC entity * with a specific peer MAC entity
@@ -112,14 +124,18 @@ void mlme_associate_indication(struct hostapd_data *hapd,
* PeerSTAAddress = sta->addr * PeerSTAAddress = sta->addr
*/ */
void mlme_reassociate_indication(struct hostapd_data *hapd, void mlme_reassociate_indication(struct hostapd_data *hapd,
struct sta_info *sta) { struct sta_info *sta)
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_MLME, HOSTAPD_LEVEL_DEBUG, {
"MLME-REASSOCIATE.indication(" MACSTR ")", MAC2STR(sta->addr)); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_MLME,
if (sta->auth_alg != WLAN_AUTH_FT) HOSTAPD_LEVEL_DEBUG,
mlme_deletekeys_request(hapd, sta); "MLME-REASSOCIATE.indication(" MACSTR ")",
ap_sta_clear_disconnect_timeouts(hapd, sta); MAC2STR(sta->addr));
if (sta->auth_alg != WLAN_AUTH_FT)
mlme_deletekeys_request(hapd, sta);
ap_sta_clear_disconnect_timeouts(hapd, sta);
} }
/** /**
* mlme_disassociate_indication - Report disassociation with a specific peer * mlme_disassociate_indication - Report disassociation with a specific peer
* MAC entity * MAC entity
@@ -133,24 +149,33 @@ void mlme_reassociate_indication(struct hostapd_data *hapd,
* PeerSTAAddress = sta->addr * PeerSTAAddress = sta->addr
*/ */
void mlme_disassociate_indication(struct hostapd_data *hapd, void mlme_disassociate_indication(struct hostapd_data *hapd,
struct sta_info *sta, u16 reason_code) { struct sta_info *sta, u16 reason_code)
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_MLME, HOSTAPD_LEVEL_DEBUG, {
"MLME-DISASSOCIATE.indication(" MACSTR ", %d)", hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_MLME,
MAC2STR(sta->addr), reason_code); HOSTAPD_LEVEL_DEBUG,
mlme_deletekeys_request(hapd, sta); "MLME-DISASSOCIATE.indication(" MACSTR ", %d)",
MAC2STR(sta->addr), reason_code);
mlme_deletekeys_request(hapd, sta);
} }
void mlme_michaelmicfailure_indication(struct hostapd_data *hapd, void mlme_michaelmicfailure_indication(struct hostapd_data *hapd,
const u8 *addr) { const u8 *addr)
hostapd_logger(hapd, addr, HOSTAPD_MODULE_MLME, HOSTAPD_LEVEL_DEBUG, {
"MLME-MichaelMICFailure.indication(" MACSTR ")", hostapd_logger(hapd, addr, HOSTAPD_MODULE_MLME,
MAC2STR(addr)); HOSTAPD_LEVEL_DEBUG,
"MLME-MichaelMICFailure.indication(" MACSTR ")",
MAC2STR(addr));
} }
void mlme_deletekeys_request(struct hostapd_data *hapd, struct sta_info *sta) {
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_MLME, HOSTAPD_LEVEL_DEBUG,
"MLME-DELETEKEYS.request(" MACSTR ")", MAC2STR(sta->addr));
if (sta->wpa_sm) void mlme_deletekeys_request(struct hostapd_data *hapd, struct sta_info *sta)
wpa_remove_ptk(sta->wpa_sm); {
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_MLME,
HOSTAPD_LEVEL_DEBUG,
"MLME-DELETEKEYS.request(" MACSTR ")",
MAC2STR(sta->addr));
if (sta->wpa_sm)
wpa_remove_ptk(sta->wpa_sm);
} }
@@ -12,21 +12,22 @@
#define MLME_H #define MLME_H
void mlme_authenticate_indication(struct hostapd_data *hapd, void mlme_authenticate_indication(struct hostapd_data *hapd,
struct sta_info *sta); struct sta_info *sta);
void mlme_deauthenticate_indication(struct hostapd_data *hapd, void mlme_deauthenticate_indication(struct hostapd_data *hapd,
struct sta_info *sta, u16 reason_code); struct sta_info *sta, u16 reason_code);
void mlme_associate_indication(struct hostapd_data *hapd, struct sta_info *sta); void mlme_associate_indication(struct hostapd_data *hapd,
struct sta_info *sta);
void mlme_reassociate_indication(struct hostapd_data *hapd, void mlme_reassociate_indication(struct hostapd_data *hapd,
struct sta_info *sta); struct sta_info *sta);
void mlme_disassociate_indication(struct hostapd_data *hapd, void mlme_disassociate_indication(struct hostapd_data *hapd,
struct sta_info *sta, u16 reason_code); struct sta_info *sta, u16 reason_code);
void mlme_michaelmicfailure_indication(struct hostapd_data *hapd, void mlme_michaelmicfailure_indication(struct hostapd_data *hapd,
const u8 *addr); const u8 *addr);
void mlme_deletekeys_request(struct hostapd_data *hapd, struct sta_info *sta); void mlme_deletekeys_request(struct hostapd_data *hapd, struct sta_info *sta);
+163 -145
View File
@@ -8,214 +8,232 @@
#include "utils/includes.h" #include "utils/includes.h"
#include "ap_config.h" #include "utils/common.h"
#include "authsrv.h"
#include "crypto/tls.h" #include "crypto/tls.h"
#include "eap_server/eap.h" #include "eap_server/eap.h"
#include "eap_server/eap_sim_db.h" #include "eap_server/eap_sim_db.h"
#include "eapol_auth/eapol_auth_sm.h" #include "eapol_auth/eapol_auth_sm.h"
#include "hostapd.h"
#include "radius/radius_server.h" #include "radius/radius_server.h"
#include "hostapd.h"
#include "ap_config.h"
#include "sta_info.h" #include "sta_info.h"
#include "utils/common.h" #include "authsrv.h"
#if defined(EAP_SERVER_SIM) || defined(EAP_SERVER_AKA) #if defined(EAP_SERVER_SIM) || defined(EAP_SERVER_AKA)
#define EAP_SIM_DB #define EAP_SIM_DB
#endif /* EAP_SERVER_SIM || EAP_SERVER_AKA */ #endif /* EAP_SERVER_SIM || EAP_SERVER_AKA */
#ifdef EAP_SIM_DB #ifdef EAP_SIM_DB
static int hostapd_sim_db_cb_sta(struct hostapd_data *hapd, static int hostapd_sim_db_cb_sta(struct hostapd_data *hapd,
struct sta_info *sta, void *ctx) { struct sta_info *sta, void *ctx)
if (eapol_auth_eap_pending_cb(sta->eapol_sm, ctx) == 0) {
return 1; if (eapol_auth_eap_pending_cb(sta->eapol_sm, ctx) == 0)
return 0; return 1;
return 0;
} }
static void hostapd_sim_db_cb(void *ctx, void *session_ctx) {
struct hostapd_data *hapd = ctx; static void hostapd_sim_db_cb(void *ctx, void *session_ctx)
if (ap_for_each_sta(hapd, hostapd_sim_db_cb_sta, session_ctx) == 0) { {
struct hostapd_data *hapd = ctx;
if (ap_for_each_sta(hapd, hostapd_sim_db_cb_sta, session_ctx) == 0) {
#ifdef RADIUS_SERVER #ifdef RADIUS_SERVER
radius_server_eap_pending_cb(hapd->radius_srv, session_ctx); radius_server_eap_pending_cb(hapd->radius_srv, session_ctx);
#endif /* RADIUS_SERVER */ #endif /* RADIUS_SERVER */
} }
} }
#endif /* EAP_SIM_DB */ #endif /* EAP_SIM_DB */
#ifdef RADIUS_SERVER #ifdef RADIUS_SERVER
static int hostapd_radius_get_eap_user(void *ctx, const u8 *identity, static int hostapd_radius_get_eap_user(void *ctx, const u8 *identity,
size_t identity_len, int phase2, size_t identity_len, int phase2,
struct eap_user *user) { struct eap_user *user)
const struct hostapd_eap_user *eap_user; {
int i; const struct hostapd_eap_user *eap_user;
int rv = -1; int i;
int rv = -1;
eap_user = hostapd_get_eap_user(ctx, identity, identity_len, phase2); eap_user = hostapd_get_eap_user(ctx, identity, identity_len, phase2);
if (eap_user == NULL) if (eap_user == NULL)
goto out; goto out;
if (user == NULL) if (user == NULL)
return 0; return 0;
os_memset(user, 0, sizeof(*user)); os_memset(user, 0, sizeof(*user));
for (i = 0; i < EAP_MAX_METHODS; i++) { for (i = 0; i < EAP_MAX_METHODS; i++) {
user->methods[i].vendor = eap_user->methods[i].vendor; user->methods[i].vendor = eap_user->methods[i].vendor;
user->methods[i].method = eap_user->methods[i].method; user->methods[i].method = eap_user->methods[i].method;
} }
if (eap_user->password) { if (eap_user->password) {
user->password = os_malloc(eap_user->password_len); user->password = os_malloc(eap_user->password_len);
if (user->password == NULL) if (user->password == NULL)
goto out; goto out;
os_memcpy(user->password, eap_user->password, eap_user->password_len); os_memcpy(user->password, eap_user->password,
user->password_len = eap_user->password_len; eap_user->password_len);
user->password_hash = eap_user->password_hash; user->password_len = eap_user->password_len;
} user->password_hash = eap_user->password_hash;
user->force_version = eap_user->force_version; }
user->macacl = eap_user->macacl; user->force_version = eap_user->force_version;
user->ttls_auth = eap_user->ttls_auth; user->macacl = eap_user->macacl;
user->remediation = eap_user->remediation; user->ttls_auth = eap_user->ttls_auth;
user->accept_attr = eap_user->accept_attr; user->remediation = eap_user->remediation;
rv = 0; user->accept_attr = eap_user->accept_attr;
rv = 0;
out: out:
if (rv) if (rv)
wpa_printf(MSG_DEBUG, "%s: Failed to find user", __func__); wpa_printf(MSG_DEBUG, "%s: Failed to find user", __func__);
return rv; return rv;
} }
static int hostapd_setup_radius_srv(struct hostapd_data *hapd) {
struct radius_server_conf srv; static int hostapd_setup_radius_srv(struct hostapd_data *hapd)
struct hostapd_bss_config *conf = hapd->conf; {
os_memset(&srv, 0, sizeof(srv)); struct radius_server_conf srv;
srv.client_file = conf->radius_server_clients; struct hostapd_bss_config *conf = hapd->conf;
srv.auth_port = conf->radius_server_auth_port; os_memset(&srv, 0, sizeof(srv));
srv.acct_port = conf->radius_server_acct_port; srv.client_file = conf->radius_server_clients;
srv.conf_ctx = hapd; srv.auth_port = conf->radius_server_auth_port;
srv.eap_sim_db_priv = hapd->eap_sim_db_priv; srv.acct_port = conf->radius_server_acct_port;
srv.ssl_ctx = hapd->ssl_ctx; srv.conf_ctx = hapd;
srv.msg_ctx = hapd->msg_ctx; srv.eap_sim_db_priv = hapd->eap_sim_db_priv;
srv.pac_opaque_encr_key = conf->pac_opaque_encr_key; srv.ssl_ctx = hapd->ssl_ctx;
srv.eap_fast_a_id = conf->eap_fast_a_id; srv.msg_ctx = hapd->msg_ctx;
srv.eap_fast_a_id_len = conf->eap_fast_a_id_len; srv.pac_opaque_encr_key = conf->pac_opaque_encr_key;
srv.eap_fast_a_id_info = conf->eap_fast_a_id_info; srv.eap_fast_a_id = conf->eap_fast_a_id;
srv.eap_fast_prov = conf->eap_fast_prov; srv.eap_fast_a_id_len = conf->eap_fast_a_id_len;
srv.pac_key_lifetime = conf->pac_key_lifetime; srv.eap_fast_a_id_info = conf->eap_fast_a_id_info;
srv.pac_key_refresh_time = conf->pac_key_refresh_time; srv.eap_fast_prov = conf->eap_fast_prov;
srv.eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind; srv.pac_key_lifetime = conf->pac_key_lifetime;
srv.tnc = conf->tnc; srv.pac_key_refresh_time = conf->pac_key_refresh_time;
srv.wps = hapd->wps; srv.eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
srv.ipv6 = conf->radius_server_ipv6; srv.tnc = conf->tnc;
srv.get_eap_user = hostapd_radius_get_eap_user; srv.wps = hapd->wps;
srv.eap_req_id_text = conf->eap_req_id_text; srv.ipv6 = conf->radius_server_ipv6;
srv.eap_req_id_text_len = conf->eap_req_id_text_len; srv.get_eap_user = hostapd_radius_get_eap_user;
srv.pwd_group = conf->pwd_group; srv.eap_req_id_text = conf->eap_req_id_text;
srv.server_id = conf->server_id ? conf->server_id : "hostapd"; srv.eap_req_id_text_len = conf->eap_req_id_text_len;
srv.sqlite_file = conf->eap_user_sqlite; srv.pwd_group = conf->pwd_group;
srv.server_id = conf->server_id ? conf->server_id : "hostapd";
srv.sqlite_file = conf->eap_user_sqlite;
#ifdef CONFIG_RADIUS_TEST #ifdef CONFIG_RADIUS_TEST
srv.dump_msk_file = conf->dump_msk_file; srv.dump_msk_file = conf->dump_msk_file;
#endif /* CONFIG_RADIUS_TEST */ #endif /* CONFIG_RADIUS_TEST */
#ifdef CONFIG_HS20 #ifdef CONFIG_HS20
srv.subscr_remediation_url = conf->subscr_remediation_url; srv.subscr_remediation_url = conf->subscr_remediation_url;
srv.subscr_remediation_method = conf->subscr_remediation_method; srv.subscr_remediation_method = conf->subscr_remediation_method;
#endif /* CONFIG_HS20 */ #endif /* CONFIG_HS20 */
srv.erp = conf->eap_server_erp; srv.erp = conf->eap_server_erp;
srv.erp_domain = conf->erp_domain; srv.erp_domain = conf->erp_domain;
srv.tls_session_lifetime = conf->tls_session_lifetime; srv.tls_session_lifetime = conf->tls_session_lifetime;
hapd->radius_srv = radius_server_init(&srv); hapd->radius_srv = radius_server_init(&srv);
if (hapd->radius_srv == NULL) { if (hapd->radius_srv == NULL) {
wpa_printf(MSG_ERROR, "RADIUS server initialization failed."); wpa_printf(MSG_ERROR, "RADIUS server initialization failed.");
return -1; return -1;
} }
return 0; return 0;
} }
#endif /* RADIUS_SERVER */ #endif /* RADIUS_SERVER */
int authsrv_init(struct hostapd_data *hapd) {
int authsrv_init(struct hostapd_data *hapd)
{
#ifdef EAP_TLS_FUNCS #ifdef EAP_TLS_FUNCS
if (hapd->conf->eap_server && if (hapd->conf->eap_server &&
(hapd->conf->ca_cert || hapd->conf->server_cert || (hapd->conf->ca_cert || hapd->conf->server_cert ||
hapd->conf->private_key || hapd->conf->dh_file)) { hapd->conf->private_key || hapd->conf->dh_file)) {
struct tls_config conf; struct tls_config conf;
struct tls_connection_params params; struct tls_connection_params params;
os_memset(&conf, 0, sizeof(conf)); os_memset(&conf, 0, sizeof(conf));
conf.tls_session_lifetime = hapd->conf->tls_session_lifetime; conf.tls_session_lifetime = hapd->conf->tls_session_lifetime;
hapd->ssl_ctx = tls_init(&conf); hapd->ssl_ctx = tls_init(&conf);
if (hapd->ssl_ctx == NULL) { if (hapd->ssl_ctx == NULL) {
wpa_printf(MSG_ERROR, "Failed to initialize TLS"); wpa_printf(MSG_ERROR, "Failed to initialize TLS");
authsrv_deinit(hapd); authsrv_deinit(hapd);
return -1; return -1;
} }
os_memset(&params, 0, sizeof(params)); os_memset(&params, 0, sizeof(params));
params.ca_cert = hapd->conf->ca_cert; params.ca_cert = hapd->conf->ca_cert;
params.client_cert = hapd->conf->server_cert; params.client_cert = hapd->conf->server_cert;
params.private_key = hapd->conf->private_key; params.private_key = hapd->conf->private_key;
params.private_key_passwd = hapd->conf->private_key_passwd; params.private_key_passwd = hapd->conf->private_key_passwd;
params.dh_file = hapd->conf->dh_file; params.dh_file = hapd->conf->dh_file;
params.openssl_ciphers = hapd->conf->openssl_ciphers; params.openssl_ciphers = hapd->conf->openssl_ciphers;
params.ocsp_stapling_response = hapd->conf->ocsp_stapling_response; params.ocsp_stapling_response =
params.ocsp_stapling_response_multi = hapd->conf->ocsp_stapling_response;
hapd->conf->ocsp_stapling_response_multi; params.ocsp_stapling_response_multi =
hapd->conf->ocsp_stapling_response_multi;
if (tls_global_set_params(hapd->ssl_ctx, &params)) { if (tls_global_set_params(hapd->ssl_ctx, &params)) {
wpa_printf(MSG_ERROR, "Failed to set TLS parameters"); wpa_printf(MSG_ERROR, "Failed to set TLS parameters");
authsrv_deinit(hapd); authsrv_deinit(hapd);
return -1; return -1;
} }
if (tls_global_set_verify(hapd->ssl_ctx, hapd->conf->check_crl)) { if (tls_global_set_verify(hapd->ssl_ctx,
wpa_printf(MSG_ERROR, "Failed to enable check_crl"); hapd->conf->check_crl)) {
authsrv_deinit(hapd); wpa_printf(MSG_ERROR, "Failed to enable check_crl");
return -1; authsrv_deinit(hapd);
} return -1;
} }
}
#endif /* EAP_TLS_FUNCS */ #endif /* EAP_TLS_FUNCS */
#ifdef EAP_SIM_DB #ifdef EAP_SIM_DB
if (hapd->conf->eap_sim_db) { if (hapd->conf->eap_sim_db) {
hapd->eap_sim_db_priv = hapd->eap_sim_db_priv =
eap_sim_db_init(hapd->conf->eap_sim_db, hapd->conf->eap_sim_db_timeout, eap_sim_db_init(hapd->conf->eap_sim_db,
hostapd_sim_db_cb, hapd); hapd->conf->eap_sim_db_timeout,
if (hapd->eap_sim_db_priv == NULL) { hostapd_sim_db_cb, hapd);
wpa_printf(MSG_ERROR, "Failed to initialize EAP-SIM " if (hapd->eap_sim_db_priv == NULL) {
"database interface"); wpa_printf(MSG_ERROR, "Failed to initialize EAP-SIM "
authsrv_deinit(hapd); "database interface");
return -1; authsrv_deinit(hapd);
} return -1;
} }
}
#endif /* EAP_SIM_DB */ #endif /* EAP_SIM_DB */
#ifdef RADIUS_SERVER #ifdef RADIUS_SERVER
if (hapd->conf->radius_server_clients && hostapd_setup_radius_srv(hapd)) if (hapd->conf->radius_server_clients &&
return -1; hostapd_setup_radius_srv(hapd))
return -1;
#endif /* RADIUS_SERVER */ #endif /* RADIUS_SERVER */
return 0; return 0;
} }
void authsrv_deinit(struct hostapd_data *hapd) {
void authsrv_deinit(struct hostapd_data *hapd)
{
#ifdef RADIUS_SERVER #ifdef RADIUS_SERVER
radius_server_deinit(hapd->radius_srv); radius_server_deinit(hapd->radius_srv);
hapd->radius_srv = NULL; hapd->radius_srv = NULL;
#endif /* RADIUS_SERVER */ #endif /* RADIUS_SERVER */
#ifdef EAP_TLS_FUNCS #ifdef EAP_TLS_FUNCS
if (hapd->ssl_ctx) { if (hapd->ssl_ctx) {
tls_deinit(hapd->ssl_ctx); tls_deinit(hapd->ssl_ctx);
hapd->ssl_ctx = NULL; hapd->ssl_ctx = NULL;
} }
#endif /* EAP_TLS_FUNCS */ #endif /* EAP_TLS_FUNCS */
#ifdef EAP_SIM_DB #ifdef EAP_SIM_DB
if (hapd->eap_sim_db_priv) { if (hapd->eap_sim_db_priv) {
eap_sim_db_deinit(hapd->eap_sim_db_priv); eap_sim_db_deinit(hapd->eap_sim_db_priv);
hapd->eap_sim_db_priv = NULL; hapd->eap_sim_db_priv = NULL;
} }
#endif /* EAP_SIM_DB */ #endif /* EAP_SIM_DB */
} }
File diff suppressed because it is too large Load Diff
@@ -13,20 +13,21 @@
struct ieee80211_mgmt; struct ieee80211_mgmt;
void handle_probe_req(struct hostapd_data *hapd, void handle_probe_req(struct hostapd_data *hapd,
const struct ieee80211_mgmt *mgmt, size_t len, const struct ieee80211_mgmt *mgmt, size_t len,
int ssi_signal); int ssi_signal);
int ieee802_11_set_beacon(struct hostapd_data *hapd); int ieee802_11_set_beacon(struct hostapd_data *hapd);
int ieee802_11_set_beacons(struct hostapd_iface *iface); int ieee802_11_set_beacons(struct hostapd_iface *iface);
int ieee802_11_update_beacons(struct hostapd_iface *iface); int ieee802_11_update_beacons(struct hostapd_iface *iface);
int ieee802_11_build_ap_params(struct hostapd_data *hapd, int ieee802_11_build_ap_params(struct hostapd_data *hapd,
struct wpa_driver_ap_params *params); struct wpa_driver_ap_params *params);
void ieee802_11_free_ap_params(struct wpa_driver_ap_params *params); void ieee802_11_free_ap_params(struct wpa_driver_ap_params *params);
void sta_track_add(struct hostapd_iface *iface, const u8 *addr); void sta_track_add(struct hostapd_iface *iface, const u8 *addr);
void sta_track_del(struct hostapd_sta_info *info); void sta_track_del(struct hostapd_sta_info *info);
void sta_track_expire(struct hostapd_iface *iface, int force); void sta_track_expire(struct hostapd_iface *iface, int force);
struct hostapd_data *sta_track_seen_on(struct hostapd_iface *iface, struct hostapd_data *
const u8 *addr, const char *ifname); sta_track_seen_on(struct hostapd_iface *iface, const u8 *addr,
const char *ifname);
void sta_track_claim_taxonomy_info(struct hostapd_iface *iface, const u8 *addr, void sta_track_claim_taxonomy_info(struct hostapd_iface *iface, const u8 *addr,
struct wpabuf **probe_ie_taxonomy); struct wpabuf **probe_ie_taxonomy);
#endif /* BEACON_H */ #endif /* BEACON_H */
@@ -8,50 +8,58 @@
#include "utils/includes.h" #include "utils/includes.h"
#include "ap_drv_ops.h"
#include "beacon.h"
#include "bss_load.h"
#include "hostapd.h"
#include "utils/common.h" #include "utils/common.h"
#include "utils/eloop.h" #include "utils/eloop.h"
#include "hostapd.h"
#include "bss_load.h"
#include "ap_drv_ops.h"
#include "beacon.h"
static void update_channel_utilization(void *eloop_data, void *user_data) {
struct hostapd_data *hapd = eloop_data;
unsigned int sec, usec;
int err;
if (!(hapd->beacon_set_done && hapd->started)) static void update_channel_utilization(void *eloop_data, void *user_data)
return; {
struct hostapd_data *hapd = eloop_data;
unsigned int sec, usec;
int err;
err = hostapd_drv_get_survey(hapd, hapd->iface->freq); if (!(hapd->beacon_set_done && hapd->started))
if (err) { return;
wpa_printf(MSG_ERROR, "BSS Load: Failed to get survey data");
return;
}
ieee802_11_set_beacon(hapd); err = hostapd_drv_get_survey(hapd, hapd->iface->freq);
if (err) {
wpa_printf(MSG_ERROR, "BSS Load: Failed to get survey data");
return;
}
sec = ((hapd->bss_load_update_timeout / 1000) * 1024) / 1000; ieee802_11_set_beacon(hapd);
usec = (hapd->bss_load_update_timeout % 1000) * 1024;
eloop_register_timeout(sec, usec, update_channel_utilization, hapd, NULL); sec = ((hapd->bss_load_update_timeout / 1000) * 1024) / 1000;
usec = (hapd->bss_load_update_timeout % 1000) * 1024;
eloop_register_timeout(sec, usec, update_channel_utilization, hapd,
NULL);
} }
int bss_load_update_init(struct hostapd_data *hapd) {
struct hostapd_bss_config *conf = hapd->conf;
struct hostapd_config *iconf = hapd->iconf;
unsigned int sec, usec;
if (!conf->bss_load_update_period || !iconf->beacon_int) int bss_load_update_init(struct hostapd_data *hapd)
return -1; {
struct hostapd_bss_config *conf = hapd->conf;
struct hostapd_config *iconf = hapd->iconf;
unsigned int sec, usec;
hapd->bss_load_update_timeout = if (!conf->bss_load_update_period || !iconf->beacon_int)
conf->bss_load_update_period * iconf->beacon_int; return -1;
sec = ((hapd->bss_load_update_timeout / 1000) * 1024) / 1000;
usec = (hapd->bss_load_update_timeout % 1000) * 1024; hapd->bss_load_update_timeout = conf->bss_load_update_period *
eloop_register_timeout(sec, usec, update_channel_utilization, hapd, NULL); iconf->beacon_int;
return 0; sec = ((hapd->bss_load_update_timeout / 1000) * 1024) / 1000;
usec = (hapd->bss_load_update_timeout % 1000) * 1024;
eloop_register_timeout(sec, usec, update_channel_utilization, hapd,
NULL);
return 0;
} }
void bss_load_update_deinit(struct hostapd_data *hapd) {
eloop_cancel_timeout(update_channel_utilization, hapd, NULL); void bss_load_update_deinit(struct hostapd_data *hapd)
{
eloop_cancel_timeout(update_channel_utilization, hapd, NULL);
} }
@@ -9,7 +9,9 @@
#ifndef BSS_LOAD_UPDATE_H #ifndef BSS_LOAD_UPDATE_H
#define BSS_LOAD_UPDATE_H #define BSS_LOAD_UPDATE_H
int bss_load_update_init(struct hostapd_data *hapd); int bss_load_update_init(struct hostapd_data *hapd);
void bss_load_update_deinit(struct hostapd_data *hapd); void bss_load_update_deinit(struct hostapd_data *hapd);
#endif /* BSS_LOAD_UPDATE_H */ #endif /* BSS_LOAD_UPDATE_H */
File diff suppressed because it is too large Load Diff
@@ -9,25 +9,28 @@
#ifndef CTRL_IFACE_AP_H #ifndef CTRL_IFACE_AP_H
#define CTRL_IFACE_AP_H #define CTRL_IFACE_AP_H
int hostapd_ctrl_iface_sta_first(struct hostapd_data *hapd, char *buf, int hostapd_ctrl_iface_sta_first(struct hostapd_data *hapd,
size_t buflen); char *buf, size_t buflen);
int hostapd_ctrl_iface_sta(struct hostapd_data *hapd, const char *txtaddr, int hostapd_ctrl_iface_sta(struct hostapd_data *hapd, const char *txtaddr,
char *buf, size_t buflen); char *buf, size_t buflen);
int hostapd_ctrl_iface_sta_next(struct hostapd_data *hapd, const char *txtaddr, int hostapd_ctrl_iface_sta_next(struct hostapd_data *hapd, const char *txtaddr,
char *buf, size_t buflen); char *buf, size_t buflen);
int hostapd_ctrl_iface_deauthenticate(struct hostapd_data *hapd, int hostapd_ctrl_iface_deauthenticate(struct hostapd_data *hapd,
const char *txtaddr); const char *txtaddr);
int hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd, int hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd,
const char *txtaddr); const char *txtaddr);
int hostapd_ctrl_iface_signature(struct hostapd_data *hapd, const char *txtaddr, int hostapd_ctrl_iface_signature(struct hostapd_data *hapd,
char *buf, size_t buflen); const char *txtaddr,
int hostapd_ctrl_iface_poll_sta(struct hostapd_data *hapd, const char *txtaddr); char *buf, size_t buflen);
int hostapd_ctrl_iface_poll_sta(struct hostapd_data *hapd,
const char *txtaddr);
int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf, int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf,
size_t buflen); size_t buflen);
int hostapd_parse_csa_settings(const char *pos, struct csa_settings *settings); int hostapd_parse_csa_settings(const char *pos,
struct csa_settings *settings);
int hostapd_ctrl_iface_stop_ap(struct hostapd_data *hapd); int hostapd_ctrl_iface_stop_ap(struct hostapd_data *hapd);
int hostapd_ctrl_iface_pmksa_list(struct hostapd_data *hapd, char *buf, int hostapd_ctrl_iface_pmksa_list(struct hostapd_data *hapd, char *buf,
size_t len); size_t len);
void hostapd_ctrl_iface_pmksa_flush(struct hostapd_data *hapd); void hostapd_ctrl_iface_pmksa_flush(struct hostapd_data *hapd);
#endif /* CTRL_IFACE_AP_H */ #endif /* CTRL_IFACE_AP_H */
File diff suppressed because it is too large Load Diff
+10 -8
View File
@@ -12,17 +12,19 @@
int hostapd_handle_dfs(struct hostapd_iface *iface); int hostapd_handle_dfs(struct hostapd_iface *iface);
int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq, int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
int ht_enabled, int chan_offset, int chan_width, int ht_enabled, int chan_offset, int chan_width,
int cf1, int cf2); int cf1, int cf2);
int hostapd_dfs_radar_detected(struct hostapd_iface *iface, int freq, int hostapd_dfs_radar_detected(struct hostapd_iface *iface, int freq,
int ht_enabled, int chan_offset, int chan_width, int ht_enabled,
int cf1, int cf2); int chan_offset, int chan_width,
int cf1, int cf2);
int hostapd_dfs_nop_finished(struct hostapd_iface *iface, int freq, int hostapd_dfs_nop_finished(struct hostapd_iface *iface, int freq,
int ht_enabled, int chan_offset, int chan_width, int ht_enabled,
int cf1, int cf2); int chan_offset, int chan_width, int cf1, int cf2);
int hostapd_is_dfs_required(struct hostapd_iface *iface); int hostapd_is_dfs_required(struct hostapd_iface *iface);
int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq, int ht_enabled, int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
int chan_offset, int chan_width, int cf1, int cf2); int ht_enabled, int chan_offset, int chan_width,
int cf1, int cf2);
int hostapd_handle_dfs_offload(struct hostapd_iface *iface); int hostapd_handle_dfs_offload(struct hostapd_iface *iface);
#endif /* DFS_H */ #endif /* DFS_H */
@@ -10,158 +10,170 @@
#include <netinet/ip.h> #include <netinet/ip.h>
#include <netinet/udp.h> #include <netinet/udp.h>
#include "ap_drv_ops.h"
#include "dhcp_snoop.h"
#include "hostapd.h"
#include "l2_packet/l2_packet.h"
#include "sta_info.h"
#include "utils/common.h" #include "utils/common.h"
#include "l2_packet/l2_packet.h"
#include "hostapd.h"
#include "sta_info.h"
#include "ap_drv_ops.h"
#include "x_snoop.h" #include "x_snoop.h"
#include "dhcp_snoop.h"
struct bootp_pkt { struct bootp_pkt {
struct iphdr iph; struct iphdr iph;
struct udphdr udph; struct udphdr udph;
u8 op; u8 op;
u8 htype; u8 htype;
u8 hlen; u8 hlen;
u8 hops; u8 hops;
be32 xid; be32 xid;
be16 secs; be16 secs;
be16 flags; be16 flags;
be32 client_ip; be32 client_ip;
be32 your_ip; be32 your_ip;
be32 server_ip; be32 server_ip;
be32 relay_ip; be32 relay_ip;
u8 hw_addr[16]; u8 hw_addr[16];
u8 serv_name[64]; u8 serv_name[64];
u8 boot_file[128]; u8 boot_file[128];
u8 exten[312]; u8 exten[312];
} STRUCT_PACKED; } STRUCT_PACKED;
#define DHCPACK 5 #define DHCPACK 5
static const u8 ic_bootp_cookie[] = {99, 130, 83, 99}; static const u8 ic_bootp_cookie[] = { 99, 130, 83, 99 };
static const char *ipaddr_str(u32 addr) {
static char buf[17];
os_snprintf(buf, sizeof(buf), "%u.%u.%u.%u", (addr >> 24) & 0xff, static const char * ipaddr_str(u32 addr)
(addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff); {
return buf; static char buf[17];
os_snprintf(buf, sizeof(buf), "%u.%u.%u.%u",
(addr >> 24) & 0xff, (addr >> 16) & 0xff,
(addr >> 8) & 0xff, addr & 0xff);
return buf;
} }
static void handle_dhcp(void *ctx, const u8 *src_addr, const u8 *buf, static void handle_dhcp(void *ctx, const u8 *src_addr, const u8 *buf,
size_t len) { size_t len)
struct hostapd_data *hapd = ctx; {
const struct bootp_pkt *b; struct hostapd_data *hapd = ctx;
struct sta_info *sta; const struct bootp_pkt *b;
int exten_len; struct sta_info *sta;
const u8 *end, *pos; int exten_len;
int res, msgtype = 0, prefixlen = 32; const u8 *end, *pos;
u32 subnet_mask = 0; int res, msgtype = 0, prefixlen = 32;
u16 tot_len; u32 subnet_mask = 0;
u16 tot_len;
exten_len = len - ETH_HLEN - (sizeof(*b) - sizeof(b->exten)); exten_len = len - ETH_HLEN - (sizeof(*b) - sizeof(b->exten));
if (exten_len < 4) if (exten_len < 4)
return; return;
b = (const struct bootp_pkt *)&buf[ETH_HLEN]; b = (const struct bootp_pkt *) &buf[ETH_HLEN];
tot_len = ntohs(b->iph.tot_len); tot_len = ntohs(b->iph.tot_len);
if (tot_len > (unsigned int)(len - ETH_HLEN)) if (tot_len > (unsigned int) (len - ETH_HLEN))
return; return;
if (os_memcmp(b->exten, ic_bootp_cookie, ARRAY_SIZE(ic_bootp_cookie))) if (os_memcmp(b->exten, ic_bootp_cookie, ARRAY_SIZE(ic_bootp_cookie)))
return; return;
/* Parse DHCP options */ /* Parse DHCP options */
end = (const u8 *)b + tot_len; end = (const u8 *) b + tot_len;
pos = &b->exten[4]; pos = &b->exten[4];
while (pos < end && *pos != 0xff) { while (pos < end && *pos != 0xff) {
const u8 *opt = pos++; const u8 *opt = pos++;
if (*opt == 0) /* padding */ if (*opt == 0) /* padding */
continue; continue;
pos += *pos + 1; pos += *pos + 1;
if (pos >= end) if (pos >= end)
break; break;
switch (*opt) { switch (*opt) {
case 1: /* subnet mask */ case 1: /* subnet mask */
if (opt[1] == 4) if (opt[1] == 4)
subnet_mask = WPA_GET_BE32(&opt[2]); subnet_mask = WPA_GET_BE32(&opt[2]);
if (subnet_mask == 0) if (subnet_mask == 0)
return; return;
while (!(subnet_mask & 0x1)) { while (!(subnet_mask & 0x1)) {
subnet_mask >>= 1; subnet_mask >>= 1;
prefixlen--; prefixlen--;
} }
break; break;
case 53: /* message type */ case 53: /* message type */
if (opt[1]) if (opt[1])
msgtype = opt[2]; msgtype = opt[2];
break; break;
default: default:
break; break;
} }
} }
if (msgtype == DHCPACK) { if (msgtype == DHCPACK) {
if (b->your_ip == 0) if (b->your_ip == 0)
return; return;
/* DHCPACK for DHCPREQUEST */ /* DHCPACK for DHCPREQUEST */
sta = ap_get_sta(hapd, b->hw_addr); sta = ap_get_sta(hapd, b->hw_addr);
if (!sta) if (!sta)
return; return;
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG, "dhcp_snoop: Found DHCPACK for " MACSTR
"dhcp_snoop: Found DHCPACK for " MACSTR " @ IPv4 address %s/%d", " @ IPv4 address %s/%d",
MAC2STR(sta->addr), ipaddr_str(be_to_host32(b->your_ip)), MAC2STR(sta->addr),
prefixlen); ipaddr_str(be_to_host32(b->your_ip)),
prefixlen);
if (sta->ipaddr == b->your_ip) if (sta->ipaddr == b->your_ip)
return; return;
if (sta->ipaddr != 0) { if (sta->ipaddr != 0) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"dhcp_snoop: Removing IPv4 address %s from the ip neigh table", "dhcp_snoop: Removing IPv4 address %s from the ip neigh table",
ipaddr_str(be_to_host32(sta->ipaddr))); ipaddr_str(be_to_host32(sta->ipaddr)));
hostapd_drv_br_delete_ip_neigh(hapd, 4, (u8 *)&sta->ipaddr); hostapd_drv_br_delete_ip_neigh(hapd, 4,
} (u8 *) &sta->ipaddr);
}
res = hostapd_drv_br_add_ip_neigh(hapd, 4, (u8 *)&b->your_ip, prefixlen, res = hostapd_drv_br_add_ip_neigh(hapd, 4, (u8 *) &b->your_ip,
sta->addr); prefixlen, sta->addr);
if (res) { if (res) {
wpa_printf(MSG_DEBUG, "dhcp_snoop: Adding ip neigh table failed: %d", wpa_printf(MSG_DEBUG,
res); "dhcp_snoop: Adding ip neigh table failed: %d",
return; res);
} return;
sta->ipaddr = b->your_ip; }
} sta->ipaddr = b->your_ip;
}
if (hapd->conf->disable_dgaf && is_broadcast_ether_addr(buf)) { if (hapd->conf->disable_dgaf && is_broadcast_ether_addr(buf)) {
for (sta = hapd->sta_list; sta; sta = sta->next) { for (sta = hapd->sta_list; sta; sta = sta->next) {
if (!(sta->flags & WLAN_STA_AUTHORIZED)) if (!(sta->flags & WLAN_STA_AUTHORIZED))
continue; continue;
x_snoop_mcast_to_ucast_convert_send(hapd, sta, (u8 *)buf, len); x_snoop_mcast_to_ucast_convert_send(hapd, sta,
} (u8 *) buf, len);
} }
}
} }
int dhcp_snoop_init(struct hostapd_data *hapd) {
hapd->sock_dhcp =
x_snoop_get_l2_packet(hapd, handle_dhcp, L2_PACKET_FILTER_DHCP);
if (hapd->sock_dhcp == NULL) {
wpa_printf(MSG_DEBUG,
"dhcp_snoop: Failed to initialize L2 packet processing for DHCP "
"packet: %s",
strerror(errno));
return -1;
}
return 0; int dhcp_snoop_init(struct hostapd_data *hapd)
{
hapd->sock_dhcp = x_snoop_get_l2_packet(hapd, handle_dhcp,
L2_PACKET_FILTER_DHCP);
if (hapd->sock_dhcp == NULL) {
wpa_printf(MSG_DEBUG,
"dhcp_snoop: Failed to initialize L2 packet processing for DHCP packet: %s",
strerror(errno));
return -1;
}
return 0;
} }
void dhcp_snoop_deinit(struct hostapd_data *hapd) {
l2_packet_deinit(hapd->sock_dhcp); void dhcp_snoop_deinit(struct hostapd_data *hapd)
{
l2_packet_deinit(hapd->sock_dhcp);
} }

Some files were not shown because too many files have changed in this diff Show More