ADD| new 远程命令行;

master
wangbo 2 years ago
commit f9066d94a9

@ -0,0 +1,3 @@
操作方法:
cd build
make sshcmd

@ -0,0 +1,75 @@
/*****************************************************************************
* file include/array.h
* author YuLiang
* version 1.0.0
* date 22-Sep-2021
* brief This file provides all the headers of the array functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef _ARRAY_H_
#define _ARRAY_H_
/* Includes ------------------------------------------------------------------*/
/* Define --------------------------------------------------------------------*/
#define ARRAY_MIN_SIZE 1
/* Exported types ------------------------------------------------------------*/
typedef struct
{
uint32_t active; /* 当前可使用的索引位置. */
uint32_t alloced; /* 申请的内存大小. */
void **index; /* 数组元素. */
} array_t;
/* Extern global variables ---------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* 获取数组A索引I的数据. */
#define array_get(A, I) ((A)->index[(I)])
/* 获取数组A目前激活的索引. */
#define array_active(A) ((A)->active)
/* Exported functions --------------------------------------------------------*/
extern array_t *array_init(uint32_t size, int32_t mem_type);
extern void array_set(array_t *a, uint32_t i, void *val, int32_t mem_type);
extern void array_unset(array_t *v, uint32_t i);
extern uint32_t array_append(array_t *a, void *val, int32_t mem_type);
extern void array_free_wrapper(array_t *a, int32_t mem_type);
extern void array_free_index(array_t *a, int32_t mem_type);
extern void array_free(array_t *a, int32_t mem_type);
extern array_t *array_copy(array_t *a, int32_t mem_type);
extern void array_merge(array_t *a, array_t *b, int32_t mem_type);
extern void *array_lookup(array_t *a, uint32_t i);
extern uint32_t array_count(array_t *a);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

@ -0,0 +1,183 @@
/******************************************************************************
* file include/better_log.h
* author YuLiang
* version 1.0.0
* date 14-Sep-2021
* brief This file provides all the headers of the log functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef _BETTER_LOG_H_
#define _BETTER_LOG_H_
/* Includes ------------------------------------------------------------------*/
#include <sqlite3.h>
/* Define --------------------------------------------------------------------*/
#define LOG_FILE "PowerIoT.db"
#define LOG_STR_LEN 512
#define LOG_TABLE_NAME "better_log"
#define LOG_MAX_DECORD 5000
#define LOG_DEFAULT_SHOW_CNT 100
#define LOG_DB_FIFO "LOG_DB_FIFO"
#define LOG_STR "Display default most 100 logs\n"
#define LOG_LEVELS "(errors|warnings|notifications|informational|debug)"
#define LOG_LEVEL_DESC \
"Error messages\n" \
"Warning messages\n" \
"Normal but significant messages\n" \
"Informational messages\n" \
"Debug messages\n"
/* Exported types ------------------------------------------------------------*/
typedef enum
{
LOG_LVL_ERR,
LOG_LVL_WARN,
LOG_LVL_NOTIF,
LOG_LVL_INFO,
LOG_LVL_DBG,
LOG_LVL_MAX
} LOG_LVL_E;
typedef enum
{
LOG_MODE_STDOUT,
LOG_MODE_FILE,
LOG_MODE_MONITOR,
LOG_MODE_MAX
} LOG_MODE_E;
typedef enum
{
LOG_DEFAULT,
LOG_CLI,
LOG_MEMORY,
LOG_FIFO,
LOG_GPIO,
LOG_PD,
LOG_DAU,
LOG_CSG,
LOG_STORAGE,
LOG_DEBUG,
LOG_MAX
} LOG_MODULE_E;
typedef enum
{
LOG_SHOW_CNT,
LOG_SHOW_LVL,
LOG_SHOW_KEYWORD,
LOG_SHOW_MAX
} LOG_SHOW_E;
typedef struct _log_lvl
{
int32_t lvl;
char *describe;
} log_lvl_t;
typedef struct _log_module
{
int32_t module;
char *describe;
} log_module_t;
/* log全局数据结构体. */
typedef struct _log_sys
{
int32_t enable_lvl[LOG_MODE_MAX]; /* log模块使能等级位图表示. */
int32_t default_lvl; /* 默认log模块使能等级位图表示. */
sqlite3 *db; /* log数据库指针. */
char *filename; /* log数据库名字. */
int32_t timestamp_precision; /* 默认log时间戳精度. */
pthread_mutex_t log_mutex;
pthread_mutex_t log_out_mutex;
pthread_mutex_t log_db_mutex; /* 数据库读写互斥锁 */
} log_sys_t;
typedef struct
{
int32_t log_fifo_id;
pthread_mutex_t mutex; /* log fifo mutex */
} _log_fifo_t;
typedef struct
{
LOG_SHOW_E type;
int32_t param;
char log_show_str[LOG_STR_LEN];
} _log_show_t;
typedef struct
{
LOG_MODULE_E module;
LOG_LVL_E lvl;
char log_out_str[LOG_STR_LEN];
} _log_out_t;
typedef struct
{
uint32_t type;
void *data;
} _log_msg_t;
/* Exported macro ------------------------------------------------------------*/
/* Extern global variables ---------------------------------------------------*/
extern log_sys_t *log_sys;
/* Extern functions ----------------------------------------------------------*/
/* 配置函数属性,让gcc按printf一样检查函数参数,第b个参数为可变参数. */
#define BTLOG_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
extern void log_out(LOG_MODULE_E module, LOG_LVL_E priority, const char *format, ...)
BTLOG_ATTRIBUTE(3, 4);
extern void log_err(LOG_MODULE_E module, const char *format, ...)
BTLOG_ATTRIBUTE(2, 3);
extern void log_warn(LOG_MODULE_E module, const char *format, ...)
BTLOG_ATTRIBUTE(2, 3);
extern void log_info(LOG_MODULE_E module, const char *format, ...)
BTLOG_ATTRIBUTE(2, 3);
extern void log_notice(LOG_MODULE_E module, const char *format, ...)
BTLOG_ATTRIBUTE(2, 3);
extern void log_debug(LOG_MODULE_E module, const char *format, ...)
BTLOG_ATTRIBUTE(2, 3);
extern int32_t log_open();
extern void log_set_level(LOG_MODE_E mode, LOG_LVL_E log_level);
extern void log_unset_level(LOG_MODE_E mode, LOG_LVL_E log_level);
extern int32_t log_level_get_by_name(const char *lvl_name);
extern int32_t log_module_get_by_name( const char *module_name );
extern void log_backtrace(int32_t priority);
extern void log_clean(void);
extern void log_show( int32_t cnt, LOG_LVL_E priority, const char *key_word );
extern int32_t log_handle_init(void);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,300 @@
/*
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef cJSON__h
#define cJSON__h
#ifdef __cplusplus
extern "C"
{
#endif
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__
#endif
#ifdef __WINDOWS__
/* 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:
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
For *nix builds that support visibility attribute, you can define similar behavior by
setting default visibility to hidden by adding
-fvisibility=hidden (for gcc)
or
-xldscope=hidden (for sun cc)
to CFLAGS
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
*/
#define CJSON_CDECL __cdecl
#define CJSON_STDCALL __stdcall
/* export symbols by default, this is necessary for copy pasting the C and header file */
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_EXPORT_SYMBOLS
#endif
#if defined(CJSON_HIDE_SYMBOLS)
#define CJSON_PUBLIC(type) type CJSON_STDCALL
#elif defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
#elif defined(CJSON_IMPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
#endif
#else /* !__WINDOWS__ */
#define CJSON_CDECL
#define CJSON_STDCALL
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#else
#define CJSON_PUBLIC(type) type
#endif
#endif
/* project version */
#define CJSON_VERSION_MAJOR 1
#define CJSON_VERSION_MINOR 7
#define CJSON_VERSION_PATCH 15
#include <stddef.h>
/* cJSON Types: */
#define cJSON_Invalid (0)
#define cJSON_False (1 << 0)
#define cJSON_True (1 << 1)
#define cJSON_NULL (1 << 2)
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5)
#define cJSON_Object (1 << 6)
#define cJSON_Raw (1 << 7) /* raw json */
#define cJSON_IsReference 256
#define cJSON_StringIsConst 512
/* The cJSON structure: */
typedef struct cJSON
{
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *next;
struct cJSON *prev;
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
struct cJSON *child;
/* The type of the item, as above. */
int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint;
/* The item's number, if type==cJSON_Number */
double valuedouble;
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
char *string;
} cJSON;
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 functions directly. */
void *(CJSON_CDECL *malloc_fn)(size_t sz);
void (CJSON_CDECL *free_fn)(void *ptr);
} cJSON_Hooks;
typedef int cJSON_bool;
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
* This is to prevent stack overflows. */
#ifndef CJSON_NESTING_LIMIT
#define CJSON_NESTING_LIMIT 1000
#endif
/* returns the version of cJSON as a string */
CJSON_PUBLIC(const char*) cJSON_Version(void);
/* Supply malloc, realloc and free functions to cJSON */
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
/* 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. */
/* 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_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. */
/* 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(). */
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. */
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. */
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
/* 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 */
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
/* 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. */
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
/* Returns the number of items in an array (or object). */
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
/* Get item "string" from object. Case insensitive. */
CJSON_PUBLIC(cJSON *) 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_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);
/* Check item type and return its value */
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
/* These functions check the type of an 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_IsTrue(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_IsNumber(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_IsObject(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
/* These calls create a cJSON item of the appropriate type. */
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
/* raw json */
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
/* Create a string where valuestring references a string so
* it will not be freed by cJSON_Delete */
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
/* Create an object/array that only references it's elements so
* they will not be freed by cJSON_Delete */
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
/* These utilities create an Array of count items.
* The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *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_CreateStringArray(const char *const *strings, int count);
/* Append item to the specified array/object. */
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(cJSON_bool) 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.
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
* writing to `item->string` */
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(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. */
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(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. */
CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
CJSON_PUBLIC(cJSON_bool) 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 */
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 memory that will
* need to be released. With recurse!=0, it will duplicate any children connected to the item.
* The item->next and ->prev pointers are always 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.
* case_sensitive determines if object 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 strings.
* The input pointer json cannot point to a read-only address area, such as a string constant,
* but should point to a readable and writable address area. */
CJSON_PUBLIC(void) cJSON_Minify(char *json);
/* Helper functions for creating and adding items to an object at the same time.
* They return the added item or NULL on failure. */
CJSON_PUBLIC(cJSON*) 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_AddFalseToObject(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_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 too. */
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
/* helper for the cJSON_SetNumberValue macro */
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
#define cJSON_SetNumberValue(object, 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 */
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
/* If the object is not a boolean type this does nothing and returns cJSON_Invalid else it returns the new type*/
#define cJSON_SetBoolValue(object, boolValue) ( \
(object != NULL && ((object)->type & (cJSON_False|cJSON_True))) ? \
(object)->type=((object)->type &(~(cJSON_False|cJSON_True)))|((boolValue)?cJSON_True:cJSON_False) : \
cJSON_Invalid\
)
/* Macro for iterating over an array or object */
#define cJSON_ArrayForEach(element, array) 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 cJSON_InitHooks */
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
CJSON_PUBLIC(void) cJSON_free(void *object);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,139 @@
/******************************************************************************
* file include/cli.h
* author LandPower
* version 1.0.0
* date 10-Sep-2021
* brief This file provides all the headers of the cli functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef _CLI_H_
#define _CLI_H_
/* Includes ------------------------------------------------------------------*/
#include "list.h"
/* Define --------------------------------------------------------------------*/
#define CLI_NODE_MAME_LEN 32
#define CLI_USERNAME_LEN 64
#define CLI_PARAM_LEN 32
#define CLI_USERNAME_DEFAULT "ld"
#define CLI_PASSWORD_DEFAULT "1"
/* Exported types ------------------------------------------------------------*/
/* The prototype to which callback functions used to process command line
commands must comply. buf is a buffer into which the output from
executing the command can be written, xWriteBufferLen is the length, in bytes of
the buf buffer, and pcCommandString is the entire string as input by
the user (from which parameters can be extracted). */
typedef int32_t (*CLI_COMMAND_CALLBACK)(const char *cmd_str);
/* 节点类型. */
typedef enum
{
CLI_NODE_COMMON = 0,
CLI_NODE_PASSWORD,
CLI_NODE_CONFIG,
CLI_NODE_COUNT,
} CLI_NODE_E;
/* The structure that defines command line commands. A command line command
should be defined by declaring a const structure of this type. */
typedef struct _cli_command_t
{
const char * const cmd_str; /* The command that causes pxCommandInterpreter to be executed. For example "help". Must be all lower case. */
const char * const help_str; /* 帮助字符串,解释命令的用途. */
const CLI_COMMAND_CALLBACK function; /* A pointer to the callback function that will return the output generated by the command. */
int8_t param_num; /* Commands expect a fixed number of parameters, which may be zero. */
} cli_command_t;
/* 命令保存链表结构体. */
typedef struct _cli_list_item_t
{
const cli_command_t *cmd;
struct list_head list;
} cli_list_item_t;
/* 命令行节点结构体. */
typedef struct _cli_node_t
{
char name[CLI_NODE_MAME_LEN];
uint16_t index;
uint16_t upper_node;
struct list_head list;
} cli_node_t;
/* 命令行节点结构体. */
typedef struct _cli_user_t
{
char username[CLI_USERNAME_LEN];
char password[CLI_USERNAME_LEN];
struct list_head list;
} cli_user_t;
/* Exported macro ------------------------------------------------------------*/
/* Extern global variables ---------------------------------------------------*/
/* Extern functions ----------------------------------------------------------*/
/* Register the command passed in using the pxCommandToRegister parameter.
Registering a command adds the command to the list of commands that are
handled by the command interpreter. Once a command has been registered it
can be executed from the command line. */
int32_t cli_register_command(const cli_command_t* const cmd, CLI_NODE_E node);
/* Runs the command interpreter for the command string "pcCommandInput". Any
output generated by running the command will be placed into buf.
xWriteBufferLen must indicate the size, in bytes, of the buffer pointed to
by buf.
FreeRTOS_CLIProcessCommand should be called repeatedly until it returns pdFALSE.
pcCmdIntProcessCommand is not reentrant. It must not be called from more
than one task - or at least - by more than one task at a time. */
int32_t cli_process_command(const char * const cmd_str);
/* Return a pointer to the xParameterNumber'th word in pcCommandString. */
const char *cli_parameter_get(const char *cmd_str, int32_t param_index, int32_t *param_len);
/* 进入命令行节点. */
int32_t cli_entry_node(CLI_NODE_E node, int16_t index);
/* 退出命令行当前节点 */
void cli_quit_node(void);
/* 从shell终端读取一行命. */
char *cli_shell_gets(void);
int32_t cli_init(void);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,341 @@
/******************************************************************************
* file include/cmd.h
* author YuLiang
* version 1.0.0
* date 09-Oct-2021
* brief This file provides all the headers of the command functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef _CMD_H_
#define _CMD_H_
/* Includes ------------------------------------------------------------------*/
#include "array.h"
#include "vty.h"
/* Define --------------------------------------------------------------------*/
/* 命令行最大参数个数. */
#define CMD_ARGC_MAX 16
/* rang检查数字最大位数. */
#define DECIMAL_STRLEN_MAX 10
#define INIT_MATCHARR_SIZE 10
#define COMPLETE_BUF_SIZE 256
#define IPV6_ADDR_STR "0123456789abcdefABCDEF:.%"
#define IPV6_PREFIX_STR "0123456789abcdefABCDEF:.%/"
#define STATE_START 1
#define STATE_COLON 2
#define STATE_DOUBLE 3
#define STATE_ADDR 4
#define STATE_DOT 5
#define STATE_SLASH 6
#define STATE_MASK 7
/* 命令行返回值. */
#define CMD_SUCCESS 0
#define CMD_WARNING 1
#define CMD_ERR_NO_MATCH 2
#define CMD_ERR_AMBIGUOUS 3
#define CMD_ERR_INCOMPLETE 4
#define CMD_ERR_EXEED_ARGC_MAX 5
#define CMD_ERR_NOTHING_TODO 6
#define CMD_COMPLETE_FULL_MATCH 7
#define CMD_COMPLETE_MATCH 8
#define CMD_COMPLETE_LIST_MATCH 9
#define CMD_SUCCESS_DAEMON 10
#define CONF_BACKUP_EXT ".sav"
#define CL_COPYRIGHT "Copyright 2017-2018 LandPower."
/* Common descriptions. */
#define SHOW_STR "Show running system information\n"
#define IP_STR "IP information\n"
#define IPV6_STR "IPv6 information\n"
#define NO_STR "Negate a command or set its defaults\n"
#define REDIST_STR "Redistribute information from another routing protocol\n"
#define CLEAR_STR "Reset functions\n"
#define RIP_STR "RIP information\n"
#define BGP_STR "BGP information\n"
#define OSPF_STR "OSPF information\n"
#define NEIGHBOR_STR "Specify neighbor router\n"
#define DEBUG_STR "Debugging functions (see also 'undebug')\n"
#define UNDEBUG_STR "Disable debugging functions (see also 'debug')\n"
#define ROUTER_STR "Enable a routing process\n"
#define AS_STR "AS number\n"
#define MBGP_STR "MBGP information\n"
#define MATCH_STR "Match values from routing table\n"
#define SET_STR "Set values in destination routing protocol\n"
#define OUT_STR "Filter outgoing routing updates\n"
#define IN_STR "Filter incoming routing updates\n"
#define V4NOTATION_STR "specify by IPv4 address notation(e.g. 0.0.0.0)\n"
#define OSPF6_NUMBER_STR "Specify by number\n"
#define INTERFACE_STR "Interface infomation\n"
#define IFNAME_STR "Interface name(e.g. ep0)\n"
#define IP6_STR "IPv6 Information\n"
#define OSPF6_STR "Open Shortest Path First (OSPF) for IPv6\n"
#define OSPF6_ROUTER_STR "Enable a routing process\n"
#define OSPF6_INSTANCE_STR "<1-65535> Instance ID\n"
#define SECONDS_STR "<1-65535> Seconds\n"
#define ROUTE_STR "Routing Table\n"
#define PREFIX_LIST_STR "Build a prefix list\n"
/* Some macroes */
#define CMD_OPTION(S) ('[' == (S[0]))
#define CMD_VARIABLE(S) (((S[0]) >= 'A' && (S[0]) <= 'Z') || ('<' == (S[0])))
#define CMD_VARARG(S) ('.' ==(S[0]))
#define CMD_RANGE(S) ('<' == (S[0]))
#define CMD_IPV4(S) (0 == strcmp((S), "A.B.C.D"))
#define CMD_IPV4_PREFIX(S) (0 == strcmp((S), "A.B.C.D/M"))
#define CMD_IPV6(S) (0 == strcmp((S), "X:X::X:X"))
#define CMD_IPV6_PREFIX(S) (0 == strcmp((S), "X:X::X:X/M"))
#define DEV_INFO_DEFAULT_IP "192.168.1.110"
#define DEV_INFO_DEFAULT_MASK "255.255.255.0"
#define DEV_INFO_DEFAULT_GW "192.168.1.1"
#define DEVICE_RUN_PATH "/home/gis"
#define SAVE_STA_CFG_BAK_FILE 1
#define SAVE_DEV_CFG_BAK_FILE 2
/* Exported types ------------------------------------------------------------*/
enum
{
CMD_ATTR_DEPRECATED = 1,
CMD_ATTR_HIDDEN,
};
/* 匹配结果类型. */
typedef enum
{
no_match,
extend_match,
ipv4_prefix_match,
ipv4_match,
ipv6_prefix_match,
ipv6_match,
range_match,
vararg_match,
partly_match,
exact_match
} MATCH_TYPE_E;
/* 用于定义命令的宏. */
#define CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \
cmd_element_t cmdname = \
{ \
.string = cmdstr, \
.func = funcname, \
.doc = helpstr, \
.attr = attrs, \
.daemon = dnum, \
};
#define CMD_FUNC_DECL(funcname) \
static int funcname(cmd_element_t *, vty_t *, int, const char *[]);
#define CMD_FUNC_TEXT(funcname) \
static int funcname \
(cmd_element_t *self __attribute__ ((unused)), \
vty_t *vty __attribute__ ((unused)), \
int argc __attribute__ ((unused)), \
const char *argv[] __attribute__ ((unused)))
/* CMD for vty command interafce. Little bit hacky ;-). */
#define CMD(funcname, cmdname, cmdstr, helpstr) \
CMD_FUNC_DECL(funcname) \
CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \
CMD_FUNC_TEXT(funcname)
#define CMD_ATTR(funcname, cmdname, cmdstr, helpstr, attr) \
CMD_FUNC_DECL(funcname) \
CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0) \
CMD_FUNC_TEXT(funcname)
#define CMD_HIDDEN(funcname, cmdname, cmdstr, helpstr) \
CMD_ATTR(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN)
#define CMD_DEPRECATED(funcname, cmdname, cmdstr, helpstr) \
CMD_ATTR(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED) \
/* ALIAS macro which define existing command's alias. */
#define ALIAS(funcname, cmdname, cmdstr, helpstr) \
CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0)
#define ALIAS_ATTR(funcname, cmdname, cmdstr, helpstr, attr) \
CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0)
#define ALIAS_HIDDEN(funcname, cmdname, cmdstr, helpstr) \
CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN, 0)
#define ALIAS_DEPRECATED(funcname, cmdname, cmdstr, helpstr) \
CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED, 0)
/* 命令行模式节点宏 */
typedef enum
{
USERNAME_NODE, /* Username node. Default mode of vty interface. */
PASSWORD_NODE, /* Password node. */
ENABLE_NODE, /* Enable node. */
CONFIG_NODE, /* Config node. Default mode of config file. */
PORT_NODE, /* Port node. */
COMMON_NODE, /* Common node. Cmd is common to other node. */
NODES_COUNT
} NODE_TYPE_E;
/* config节点配置优先级 */
typedef enum
{
CONFIG_PRI_CSG = 0,
CONFIG_PRI_DAU,
CONFIG_PRI_PD,
CONFIG_PRI_COUNT
} CONFIG_PRI_E;
/* Host configuration variable */
typedef struct
{
uint32_t id_minor; /* 设备id */
uint16_t id_major; /* 设备型号代码. */
uint8_t mac[MAC_ADDR_LEN]; /* System mac. */
char host_ip[INET_ADDRSTRLEN]; /* host ip string. */
char host_mask[INET_ADDRSTRLEN];/* host mask string. */
char host_gw[INET_ADDRSTRLEN]; /* host gw string. */
uint32_t factory_date; /* 出厂日期. */
uint32_t deployment_date; /* 部署日期. */
char dev_type[FILE_NAME_LEN]; /* 设备型号字符串. */
} device_info_t;
/* Host configuration variable */
typedef struct
{
char name[FILE_NAME_LEN]; /* Host name of this router. */
int lines; /* System wide terminal lines. */
char *version; /* 版本号. */
char *compile; /* 编译时间. */
char configfile[FILE_NAME_LEN]; /* config file name of this host */
char bannerfile[FILE_NAME_LEN]; /* Banner configuration file name. */
} host_t;
/* Structure of command element. */
typedef struct _cmd_element
{
const char *string; /* Command specification by string */
const char *doc; /* Documentation of this command */
array_t *strs; /* Pointing out each description array */
unsigned int str_size; /* Command index count */
int (*func)(struct _cmd_element*, vty_t*, int, const char *[]);
int daemon; /* Daemon to which this command belong */
char *config; /* Configuration string */
array_t *sub_cfg; /* Sub configuration string */
unsigned char attr; /* Command attributes */
} cmd_element_t;
/* Command description structure. */
typedef struct
{
char *cmd; /* Command string. */
char *str; /* Command's description. */
} desc_t;
/* 用于命令行模式节点注册配置保存函数 */
typedef int cmd_save_config_f(vty_t*);
/* 命令行模式节点结构体 */
typedef struct
{
uint32_t node; /* Node index. */
uint32_t up_node; /* Upper level node index. */
uint8_t param_num; /* Prompt param num. */
char *prompt; /* Prompt character at vty interface. */
cmd_save_config_f *func; /* Node's configuration write function */
array_t *cmds; /* Array of this node's command list. */
array_t *configs; /* 配置函数数组. */
} cmd_node_t;
typedef struct
{
uint32_t node; /* Node index. */
uint32_t param_num; /* Prompt param num. */
char cmd[504]; /* 结构体正好是 512byte. */
} vtycmd_head_t;
typedef struct
{
vtycmd_head_t buf_read;
vtycmd_head_t buf_write;
int socket;
pthread_mutex_t wr_mutex; /* buf of mutex*/
pthread_mutex_t rd_mutex; /* buf of mutex*/
} vtycmd_t;
/* Exported macro ------------------------------------------------------------*/
/* Extern global variables ---------------------------------------------------*/
extern host_t host;
extern device_info_t device_info;
extern array_t *cmd_nodes;
extern int8_t is_system_init;
/* Extern functions ----------------------------------------------------------*/
static inline cmd_node_t *cmd_node_get(NODE_TYPE_E ntype)
{
return (cmd_node_t *)array_lookup(cmd_nodes, ntype);
}
extern void cmd_init(void);
extern int32_t cmd_execute(vty_t *vty);
extern const char *cmd_prompt(NODE_TYPE_E ntype);
extern array_t *cmd_strs_create(const char *string);
extern void cmd_strs_free(array_t *a);
extern void cmd_sort_node(void);
extern void cmd_install_node(cmd_node_t *node, cmd_save_config_f *func);
extern array_t *cmd_describe_command (array_t *cmd_line, vty_t *vty, int32_t *status);
extern char **cmd_complete_command(array_t *vline, vty_t *vty, int32_t *status);
extern void cmd_install_element(NODE_TYPE_E ntype, cmd_element_t *cmd);
extern int32_t cmd_config_node_config_register(int32_t pri, cmd_save_config_f *func);
extern void vtysh_init(void);
extern char *vtysh_prompt (void);
extern int vtysh_rl_question(void);
extern int vtysh_rl_completion(void);
extern char *vtysh_completion_entry_function(const char *ignore, int invoking_key);
extern void vtysh_config_recovery(void);
extern void vtysh_device_save(void);
extern void vtysh_eth0_save(void);
extern int32_t vtysh_config_save(void);
extern int32_t vtysh_host_addr_set(char *addr, char *mask);
extern int32_t vtysh_gateway_set(char *gateway);
extern void vtysh_shell_init(void);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,167 @@
/******************************************************************************
* file include/common.h
* author YuLiang
* version 1.0.0
* date 10-Sep-2021
* brief This file provides all the headers of the common functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef _COMMON_H_
#define _COMMON_H_
/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include "array.h"
#include "better_log.h"
#include "dbg.h"
#include "memory.h"
#include "thread_monitor.h"
/* Define --------------------------------------------------------------------*/
#define FALSE 0
#define TRUE 1
#define E_NONE 0
#define E_ERROR -1
#define E_BAD_PARAM -2
#define E_MEM -3
#define E_SYS_CALL -4
#define E_NULL -5
#define E_NOT_FOUND -6
#define E_NOT_IDENTIFY -7
#define E_TIMEOUT -8
#define E_SAME -9
#define OUT
#define BACKTRACE_SIZE 20
#define TIME_STR_LEN 64
#define RECV_MSG_LEN 1536
#define DEVICE_INVALID 255
#define FILE_NAME_LEN 128
#define DIR_PATH_LEN 512
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46
#define ETH_GIS_DEV_ID_LEN 16
#define ETH_GIS_CMD_PARAM_LEN 16
#define DEVICE_ID_LEN 6
#define MAC_ADDR_LEN 6
#define IP_ADDR_LEN 4
#define DEV_DATA_LEN 1000
#define DEV_DATA_BITMAP_LEN 8
#define DEV_NAME_STR_LEN 32
/* Does the I/O error indicate that the operation should be retried later? */
#define ERRNO_IO_RETRY(EN) \
(((EN) == EAGAIN) || ((EN) == EWOULDBLOCK) || ((EN) == EINTR))
/* Exported types ------------------------------------------------------------*/
typedef int8_t bool;
/* Exported macro ------------------------------------------------------------*/
#define BITMAP_SET(t, b) ((t) |= 1 << (b))
#define BITMAP_RESET(t, b) ((t) &= ~(1 << (b)))
#define IS_BITMAP_SET(t, b) ((t) & (1 << b))
typedef enum _BOOT_MSG
{
BOOT_NONE = 0,
BOOT_LOCAL_SERVER_IP_CHANGE,
BOOT_LOCAL_SERVER_PORT_CHANGE,
BOOT_LOCAL_IP_CHANGE,
BOOT_LOCAL_HOST_NAME_CHANGE,
BOOT_LOCAL_RESET,
BOOT_LOCAL_ARM_UPGRADE,
BOOT_LOCAL_FPGA_UPGRADE,
BOOT_REMOTE_SERVER_IP_CHANGE,
BOOT_REMOTE_SERVER_PORT_CHANGE,
BOOT_REMOTE_IP_CHANGE,
BOOT_REMOTE_HOST_NAME_CHANGE,
BOOT_REMOTE_RESET,
BOOT_SYSTEM_RESET,
BOOT_MAX,
} BOOT_MSG;
#define LD_E_RETURN(_module_, _f_) \
do { \
int _rv_ = E_ERROR; \
if ((_rv_ = _f_) != E_NONE) \
{ \
DBG(_module_, "ERROR return %d!\r\n", _rv_); \
return _rv_; \
} \
} while(0)
#define LD_NULL_RETURN(_module_, _f_) \
do { \
if (NULL == (_f_)) \
{ \
DBG(_module_, "ERROR return %d!\r\n", _rv_); \
return E_NULL; \
} \
} while(0)
/* Extern global variables ---------------------------------------------------*/
/* Extern functions ----------------------------------------------------------*/
extern char *str_to_lower(char *str);
extern char *str_omit_space(char *str, bool omit_end);
extern size_t time_string(int32_t timestamp_precision, char *buf, size_t buflen);
extern const char *safe_strerror(int errnum);
extern void buf_print(char *buf, int32_t len);
extern int32_t mac_generate_from_ip(char *ip_str, uint8_t *mac);
extern uint16_t crc16(uint8_t *data, uint16_t size);
extern uint16_t crc16_modbus(uint8_t *data, uint16_t size);
extern void speed_detection_stat(void);
extern void speed_detection_end(void);
extern int printh(const char *format, ...);
extern char* version_get();
extern char* version_date_get();
extern uint16_t sofrware_version_get(void);
extern int32_t str_to_mac(char *mac_str, OUT uint8_t *mac);
extern int32_t str_to_id(char *id_str, OUT uint32_t *id);
extern int32_t bitmap_set(uint8_t *buf, int32_t nbit, int32_t buf_len);
extern int32_t bitmap_reset(uint8_t *buf, int32_t nbit, int32_t buf_len);
extern int32_t is_bitmap_set(uint8_t *buf, int32_t nbit, int32_t buf_len);
extern int32_t time_str_to_long(char *date, char *time, uint32_t *t);
extern uint16_t version_str_to_int(void);
extern void time_set(time_t timestamp);
extern void reboot_system(int module, BOOT_MSG type);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,113 @@
/******************************************************************************
* file include/common.h
* author YuLiang
* version 1.0.0
* date 10-Sep-2021
* brief This file provides all the headers of the debug functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef _DBG_H_
#define _DBG_H_
/* Includes ------------------------------------------------------------------*/
/* Define --------------------------------------------------------------------*/
#define DBG_HELP_STR_MAX 32
#define DBG_INVALID_MODULE 0xffffffff
/* Exported types ------------------------------------------------------------*/
/* debug模块. */
typedef enum
{
DBG_M_DBG = 0,
DBG_M_CLI,
DBG_M_MTIMER,
DBG_M_PROCESS,
DBG_M_GPIO,
DBG_M_PD,
DBG_M_PD_ERR,
DBG_M_PD_DAU,
DBG_M_PD_DAU_SEND,
DBG_M_PD_DAU_RECV,
DBG_M_PD_DAU_ERR,
DBG_M_FIFO,
DBG_M_FIFO_ERR,
DBG_M_PD_CSG,
DBG_M_PD_CSG_ERR,
DBG_M_STORAGE_ERR,
DBG_M_DEBUG,
DBG_M_PD_CPLD,
DBG_M_COUNT
} DBG_MODULE_E;
/* debug命令字. */
typedef enum
{
DBG_CMD_ON = 0,
DBG_CMD_OFF,
DBG_CMD_ALL_OFF
} DBG_CMD_E;
/* debug结构体,每个结构体代表一个模块. */
typedef struct
{
int32_t num;
int32_t stat;
char desc[DBG_HELP_STR_MAX];
} dbg_module_t;
/* Exported macro ------------------------------------------------------------*/
#ifdef CFG_DBG_ON
#define DBG(_MODULE_, _format_, _msg_...) \
do { \
if (dbg_stat_get(_MODULE_)) printh("%s(%d): " _format_, __FUNCTION__, __LINE__, ##_msg_); \
} while(0)
#define DBG_Q(_MODULE_, _format_, _msg_...) \
do { \
if (_dbg_module[_MODULE_].stat) printh(_format_, ##_msg_); \
} while(0)
#else
#define DBG(_MODULE_, _msg_...)
//#define DBG(_MODULE_, _format_, _msg_...)
#endif
/* Extern global variables ---------------------------------------------------*/
#ifdef CFG_DBG_ON
extern dbg_module_t _dbg_module[DBG_M_COUNT];
#endif
/* Extern functions ----------------------------------------------------------*/
extern int32_t dbg_stat_get(DBG_MODULE_E module);
extern int dbg_cmd_hander(DBG_CMD_E cmd, int32_t module);
extern void dbg_init(void);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,73 @@
/******************************************************************************
* file include/fifo.h
* author YuLiang
* version 1.0.0
* date 21-Feb-2023
* brief This file provides all the headers of the fifo functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef _FIFO_H_
#define _FIFO_H_
/* Includes ------------------------------------------------------------------*/
#include <semaphore.h>
/* Define --------------------------------------------------------------------*/
#define FIFO_NAME_LEN 32
/* Exported types ------------------------------------------------------------*/
/* . */
typedef struct _fifo_t
{
char name[FIFO_NAME_LEN]; // fifo 名字.
uint32_t size; // fifo 大小.
uint32_t cur; // 当前的数据位置.
uint32_t valid; // 当前读取的数据位置.
uint32_t used; // fifo 使用数量.
uint32_t max; // fifo 最大使用数量.
pthread_mutex_t mutex; // 多线程同时操作的信号量.
sem_t sem; // 读取有效互斥锁.
void **data; // 数据数组.
} fifo_t;
/* Exported macro ------------------------------------------------------------*/
/* Extern global variables ---------------------------------------------------*/
/* Extern functions ----------------------------------------------------------*/
extern int32_t fifo_init(void);
extern int32_t fifo_create(char* name, uint32_t size);
extern int32_t fifo_write(uint32_t id, void *data, int32_t len);
extern int32_t fifo_read(uint32_t id, void **data);
extern int32_t fifo_push(uint32_t id);
extern void fifo_show(uint32_t id);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,97 @@
/******************************************************************************
* file include/common.h
* author YuLiang
* version 1.0.0
* date 24-Nov-2021
* brief This file provides all the headers of the gpio functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef _HWGPIO_H_
#define _HWGPIO_H_
/* Includes ------------------------------------------------------------------*/
/* Define --------------------------------------------------------------------*/
#define GPIO_DIR_IN 1
#define GPIO_DIR_OUT 2
#define GPIO_RUN 124
#define GPIO_SYNC 22
#define GPIO_SYNC_PPS 119
#define GPIO_ERR1 123
#define GPIO_ERR2 88
#define GPIO_ALARM 18
#define GPIO_DAU1_POW 114
#define GPIO_DAU2_POW 0
#define GPIO_CPLD_CS 86
#define GPIO_CPLD_SCLK 85
#define GPIO_CPLD_MOSI 4
#define GPIO_CPLD_MISO 5
/* Exported types ------------------------------------------------------------*/
/* 记录每个打开的gpio信息 */
typedef struct
{
uint16_t index; /* gpio在数组中的索引 */
uint16_t gpio; /* gpio号 gpio2-15 = (2 - 1) * 32 + 15 = 47 */
uint8_t is_export; /* 是否已导出 */
uint8_t curr_dir; /* 方向当前值 1-in 2-out */
uint8_t curr_val; /* 电平当前值 针对dir==out时 ,当dir为in时,每次都需要读文件 */
} gpio_node_t;
/* Exported macro ------------------------------------------------------------*/
#define GPIO_DAU1_POW_ON gpio_val_set(gpio_dau1_pow_idx, 1)
#define GPIO_DAU1_POW_OFF gpio_val_set(gpio_dau1_pow_idx, 0)
#define GPIO_DAU2_POW_ON gpio_val_set(gpio_dau2_pow_idx, 1)
#define GPIO_DAU2_POW_OFF gpio_val_set(gpio_dau2_pow_idx, 0)
#define GPIO_RUN_LED(_v_) gpio_val_set(gpio_run_idx, _v_)
#define GPIO_SYNC_LED(_v_) gpio_val_set(gpio_sync_idx, _v_)
#define GPIO_ERR1_LED(_v_) gpio_val_set(gpio_err1_idx, _v_)
/* Extern global variables ---------------------------------------------------*/
extern int32_t gpio_dau1_pow_idx;
extern int32_t gpio_dau2_pow_idx;
extern int32_t gpio_run_idx;
extern int32_t gpio_sync_idx;
extern int32_t gpio_err1_idx;
/* Extern functions ----------------------------------------------------------*/
extern int32_t gpio_val_set(uint16_t gpio, uint8_t value);
extern int32_t gpio_val_get(uint16_t gpio, uint8_t *value);
extern int32_t gpio_dir_set(uint16_t gpio, uint8_t dir);
extern int32_t gpio_export(uint16_t gpio);
extern int32_t gpio_init(void);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,702 @@
#ifndef _LIST_H_
#define _LIST_H_
/*
* Simple doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
#define l_offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
/**
* container_of - cast a member of a structure out to the containing structure
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - l_offsetof(type,member) );})
static inline void prefetch(const void *x) {;}
static inline void prefetchw(const void *x) {;}
#define LIST_POISON1 ((void *) 0x00100100)
#define LIST_POISON2 ((void *) 0x00200200)
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty() on entry does not return true after this, the entry is
* in an undefined state.
*/
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}
/**
* list_replace - replace old entry by new one
* @old : the element to be replaced
* @new : the new element to insert
*
* If @old was empty, it will be overwritten.
*/
static inline void list_replace(struct list_head *old,
struct list_head *new)
{
new->next = old->next;
new->next->prev = new;
new->prev = old->prev;
new->prev->next = new;
}
static inline void list_replace_init(struct list_head *old,
struct list_head *new)
{
list_replace(old, new);
INIT_LIST_HEAD(old);
}
/**
* list_del_init - deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
*/
static inline void list_del_init(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
/**
* list_move - delete from one list and add as another's head
* @list: the entry to move
* @head: the head that will precede our entry
*/
static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del(list->prev, list->next);
list_add(list, head);
}
/**
* list_move_tail - delete from one list and add as another's tail
* @list: the entry to move
* @head: the head that will follow our entry
*/
static inline void list_move_tail(struct list_head *list,
struct list_head *head)
{
__list_del(list->prev, list->next);
list_add_tail(list, head);
}
/**
* list_is_last - tests whether @list is the last entry in list @head
* @list: the entry to test
* @head: the head of the list
*/
static inline int list_is_last(const struct list_head *list,
const struct list_head *head)
{
return list->next == head;
}
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
/**
* list_empty_careful - tests whether a list is empty and not being modified
* @head: the list to test
*
* Description:
* tests whether a list is empty _and_ checks that no other CPU might be
* in the process of modifying either member (next or prev)
*
* NOTE: using list_empty_careful() without synchronization
* can only be safe if the only activity that can happen
* to the list entry is list_del_init(). Eg. it cannot be used
* if another CPU could re-list_add() it.
*/
static inline int list_empty_careful(const struct list_head *head)
{
struct list_head *next = head->next;
return (next == head) && (next == head->prev);
}
/**
* list_is_singular - tests whether a list has just one entry.
* @head: the list to test.
*/
static inline int list_is_singular(const struct list_head *head)
{
return !list_empty(head) && (head->next == head->prev);
}
static inline void __list_cut_position(struct list_head *list,
struct list_head *head, struct list_head *entry)
{
struct list_head *new_first = entry->next;
list->next = head->next;
list->next->prev = list;
list->prev = entry;
entry->next = list;
head->next = new_first;
new_first->prev = head;
}
/**
* list_cut_position - cut a list into two
* @list: a new list to add all removed entries
* @head: a list with entries
* @entry: an entry within head, could be the head itself
* and if so we won't cut the list
*
* This helper moves the initial part of @head, up to and
* including @entry, from @head to @list. You should
* pass on @entry an element you know is on @head. @list
* should be an empty list or a list you do not care about
* losing its data.
*
*/
static inline void list_cut_position(struct list_head *list,
struct list_head *head, struct list_head *entry)
{
if (list_empty(head))
return;
if (list_is_singular(head) &&
(head->next != entry && head != entry))
return;
if (entry == head)
INIT_LIST_HEAD(list);
else
__list_cut_position(list, head, entry);
}
static inline void __list_splice(const struct list_head *list,
struct list_head *prev,
struct list_head *next)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
first->prev = prev;
prev->next = first;
last->next = next;
next->prev = last;
}
/**
* list_splice - join two lists, this is designed for stacks
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice(const struct list_head *list,
struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head, head->next);
}
/**
* list_splice_tail - join two lists, each list being a queue
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice_tail(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head->prev, head);
}
/**
* list_splice_init - join two lists and reinitialise the emptied list.
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* The list at @list is reinitialised
*/
static inline void list_splice_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head, head->next);
INIT_LIST_HEAD(list);
}
}
/**
* list_splice_tail_init - join two lists and reinitialise the emptied list
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* Each of the lists is a queue.
* The list at @list is reinitialised
*/
static inline void list_splice_tail_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head->prev, head);
INIT_LIST_HEAD(list);
}
}
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
/**
* list_first_entry - get the first element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*
* Note, that list is expected to be not empty.
*/
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
pos = pos->next)
/**
* __list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*
* This variant differs from list_for_each() in that it's the
* simplest possible list iteration code, no prefetching is done.
* Use this for code that knows the list to be very short (empty
* or 1 entry) most of the time.
*/
#define __list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
/**
* list_for_each_prev - iterate over a list backwards
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
pos = pos->prev)
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop cursor.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/**
* list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
* @pos: the &struct list_head to use as a loop cursor.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_prev_safe(pos, n, head) \
for (pos = (head)->prev, n = pos->prev; \
prefetch(pos->prev), pos != (head); \
pos = n, n = pos->prev)
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
prefetch(pos->member.next), &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member); \
prefetch(pos->member.prev), &pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member))
/**
* list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
* @pos: the type * to use as a start point
* @head: the head of the list
* @member: the name of the list_struct within the struct.
*
* Prepares a pos entry for use as a start point in list_for_each_entry_continue().
*/
#define list_prepare_entry(pos, head, member) \
((pos) ? : list_entry(head, typeof(*pos), member))
/**
* list_for_each_entry_continue - continue iteration over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Continue to iterate over list of given type, continuing after
* the current position.
*/
#define list_for_each_entry_continue(pos, head, member) \
for (pos = list_entry(pos->member.next, typeof(*pos), member); \
prefetch(pos->member.next), &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_continue_reverse - iterate backwards from the given point
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Start to iterate over list of given type backwards, continuing after
* the current position.
*/
#define list_for_each_entry_continue_reverse(pos, head, member) \
for (pos = list_entry(pos->member.prev, typeof(*pos), member); \
prefetch(pos->member.prev), &pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member))
/**
* list_for_each_entry_from - iterate over list of given type from the current point
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Iterate over list of given type, continuing from current position.
*/
#define list_for_each_entry_from(pos, head, member) \
for (; prefetch(pos->member.next), &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
* list_for_each_entry_safe_continue
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Iterate over list of given type, continuing after current point,
* safe against removal of list entry.
*/
#define list_for_each_entry_safe_continue(pos, n, head, member) \
for (pos = list_entry(pos->member.next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
* list_for_each_entry_safe_from
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Iterate over list of given type from current point, safe against
* removal of list entry.
*/
#define list_for_each_entry_safe_from(pos, n, head, member) \
for (n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
* list_for_each_entry_safe_reverse
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Iterate backwards over list of given type, safe against removal
* of list entry.
*/
#define list_for_each_entry_safe_reverse(pos, n, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member), \
n = list_entry(pos->member.prev, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.prev, typeof(*n), member))
/*
* Double linked lists with a single pointer list head.
* Mostly useful for hash tables where the two pointer list head is
* too wasteful.
* You lose the ability to access the tail in O(1).
*/
struct hlist_head {
struct hlist_node *first;
};
struct hlist_node {
struct hlist_node *next, **pprev;
};
#define HLIST_HEAD_INIT { .first = NULL }
#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
static inline void INIT_HLIST_NODE(struct hlist_node *h)
{
h->next = NULL;
h->pprev = NULL;
}
static inline int hlist_unhashed(const struct hlist_node *h)
{
return !h->pprev;
}
static inline int hlist_empty(const struct hlist_head *h)
{
return !h->first;
}
static inline void __hlist_del(struct hlist_node *n)
{
struct hlist_node *next = n->next;
struct hlist_node **pprev = n->pprev;
*pprev = next;
if (next)
next->pprev = pprev;
}
static inline void hlist_del(struct hlist_node *n)
{
__hlist_del(n);
n->next = LIST_POISON1;
n->pprev = LIST_POISON2;
}
static inline void hlist_del_init(struct hlist_node *n)
{
if (!hlist_unhashed(n)) {
__hlist_del(n);
INIT_HLIST_NODE(n);
}
}
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
{
struct hlist_node *first = h->first;
n->next = first;
if (first)
first->pprev = &n->next;
h->first = n;
n->pprev = &h->first;
}
/* next must be != NULL */
static inline void hlist_add_before(struct hlist_node *n,
struct hlist_node *next)
{
n->pprev = next->pprev;
n->next = next;
next->pprev = &n->next;
*(n->pprev) = n;
}
static inline void hlist_add_after(struct hlist_node *n,
struct hlist_node *next)
{
next->next = n->next;
n->next = next;
next->pprev = &n->next;
if(next->next)
next->next->pprev = &next->next;
}
/*
* Move a list from one list head to another. Fixup the pprev
* reference of the first entry if it exists.
*/
static inline void hlist_move_list(struct hlist_head *old,
struct hlist_head *new)
{
new->first = old->first;
if (new->first)
new->first->pprev = &new->first;
old->first = NULL;
}
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
#define hlist_for_each(pos, head) \
for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
pos = pos->next)
#define hlist_for_each_safe(pos, n, head) \
for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
pos = n)
/**
* hlist_for_each_entry - iterate over list of given type
* @tpos: the type * to use as a loop cursor.
* @pos: the &struct hlist_node to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry(tpos, pos, head, member) \
for (pos = (head)->first; \
pos && ({ prefetch(pos->next); 1;}) && \
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
pos = pos->next)
/**
* hlist_for_each_entry_continue - iterate over a hlist continuing after current point
* @tpos: the type * to use as a loop cursor.
* @pos: the &struct hlist_node to use as a loop cursor.
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry_continue(tpos, pos, member) \
for (pos = (pos)->next; \
pos && ({ prefetch(pos->next); 1;}) && \
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
pos = pos->next)
/**
* hlist_for_each_entry_from - iterate over a hlist continuing from current point
* @tpos: the type * to use as a loop cursor.
* @pos: the &struct hlist_node to use as a loop cursor.
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry_from(tpos, pos, member) \
for (; pos && ({ prefetch(pos->next); 1;}) && \
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
pos = pos->next)
/**
* hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @tpos: the type * to use as a loop cursor.
* @pos: the &struct hlist_node to use as a loop cursor.
* @n: another &struct hlist_node to use as temporary storage
* @head: the head for your list.
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
for (pos = (head)->first; \
pos && ({ n = pos->next; 1; }) && \
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
pos = n)
#endif

@ -0,0 +1,122 @@
/******************************************************************************
* file include/memory.h
* author YuLiang
* version 1.0.0
* date 10-Sep-2021
* brief This file provides all the headers of the memory functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef _MEMORY_H_
#define _MEMORY_H_
/* Includes ------------------------------------------------------------------*/
#define MTYPE_MEMSTR_LEN 20
/* Define --------------------------------------------------------------------*/
enum
{
MTYPE_CLI = 1,
MTYPE_BUF,
MTYPE_BUF_DATA,
MTYPE_BUF_TMP,
MTYPE_VTY,
MTYPE_VTY_TMP,
MTYPE_VTY_OUT_BUF,
MTYPE_VTY_HIST,
MTYPE_LOG,
MTYPE_PREFIX,
MTYPE_THREAD_MONITOR,
MTYPE_MTIMER,
MTYPE_HASH,
MTYPE_HASH_BACKET,
MTYPE_HASH_INDEX,
MTYPE_THREAD,
MTYPE_THREAD_STATS,
MTYPE_THREAD_MASTER,
MTYPE_THREAD_FUNCNAME,
MTYPE_FIFO,
MTYPE_GPIO,
MTYPE_RECV,
MTYPE_SENT,
MTYPE_USART,
MTYPE_ETH,
MTYPE_GIS,
MTYPE_DAU,
MTYPE_CSG,
MTYPE_STORAGE,
MTYPE_DEBUG,
MTYPE_MAX,
};
/* Exported types ------------------------------------------------------------*/
/* For pretty printing of memory allocate information. */
typedef struct _mem_node
{
int32_t index;
const char *format;
} mem_node_t;
typedef struct _mem_list
{
mem_node_t *nodes;
const char *name;
} mem_list_t;
/* Exported macro ------------------------------------------------------------*/
#define XMALLOC(mtype, size) \
mtype_x_malloc (__FILE__, __LINE__, (mtype), (size))
#define XMALLOC_Q(mtype, size) \
mtype_x_malloc_q (__FILE__, __LINE__, (mtype), (size))
#define XCALLOC(mtype, size) \
mtype_x_calloc (__FILE__, __LINE__, (mtype), (size))
#define XREALLOC(mtype, ptr, size) \
mtype_x_realloc (__FILE__, __LINE__, (mtype), (ptr), (size))
#define XFREE(mtype, ptr) \
do { \
mtype_x_free (__FILE__, __LINE__, (mtype), (ptr)); \
ptr = NULL; } \
while (0)
#define XSTRDUP(mtype, str) \
mtype_x_strdup (__FILE__, __LINE__, (mtype), (str))
/* Extern global variables ---------------------------------------------------*/
/* Extern functions ----------------------------------------------------------*/
extern void *mtype_x_malloc(const char *file, int32_t line, int32_t type, size_t size);
extern void *mtype_x_malloc_q(const char *file, int32_t line, int32_t type, size_t size);
extern void *mtype_x_calloc(const char *file, int32_t line, int32_t type, size_t size);
extern void *mtype_x_realloc(const char *file, int32_t line, int32_t type, void *ptr, size_t size);
extern void mtype_x_free(const char *file, int32_t line, int32_t type, void *ptr);
extern char *mtype_x_strdup(const char *file, int32_t line, int32_t type, const char *str);
extern void mtype_init(void);
extern void mtype_init_befor(void);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,72 @@
/*****************************************************************************
* file include/mtimer.h
* author YuLiang
* version 1.0.0
* date 22-Sep-2021
* brief This file provides all the headers of the timer functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef __MTIMER_H__
#define __MTIMER_H__
/* Includes ------------------------------------------------------------------*/
#include <pthread.h>
/* Define --------------------------------------------------------------------*/
/* 以太网连接类型类型. */
typedef enum
{
MTIMER_S_STOP = 0,
MTIMER_S_RUN,
} MTIMER_STATE_E;
/* Exported types ------------------------------------------------------------*/
typedef void* (*MTIMER_CALLBACK)(void *arg);
/* 定时器属性结构体. */
typedef struct _mtimer_t
{
MTIMER_CALLBACK handle; /* 回调函数 */
void *arg; /* 运行参数 */
char name[DEV_NAME_STR_LEN]; /* 定时器名字 */
uint16_t interval; /* 间隔时间s */
uint32_t time; /* 加入定时器的时间 */
} mtimer_t;
/* Extern global variables ---------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
extern int32_t mtimer_add(MTIMER_CALLBACK func, void *arg, uint16_t interval, char *name);
extern int32_t mtimer_init(void);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

@ -0,0 +1,76 @@
/******************************************************************************
* file include/pd_cpld.h
* author YuLiang
* version 1.0.0
* date 31-July-2023
* brief This file provides all the headers of the cpld functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2023 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef _PD_CPLD_H_
#define _PD_CPLD_H_
/* Includes ------------------------------------------------------------------*/
/* Define --------------------------------------------------------------------*/
#define CPLD_REG_V0 0x0
#define CPLD_REG_V1 0x1
#define CPLD_REG_STAT 0x3
#define CPLD_REG_SYNC 0xb
#define CPLD_REG_WDG_EN 0xd
#define CPLD_REG_WDG_TM 0xe
#define CPLD_REG_WDG_CLR 0xf
#define CPLD_REG_MAX CPLD_REG_WDG_CLR
/* Exported types ------------------------------------------------------------*/
/* 设备配置的滤波类型. */
typedef enum
{
CPLD_SYNC_PT = 0,
CPLD_SYNC_OUTSIDE = 2
} CPLD_SYNC_E;
/* CPLD 版本结构体. */
typedef struct
{
uint16_t year;
uint8_t month;
uint8_t day;
} cpld_version_t;
/* Exported macro ------------------------------------------------------------*/
/* Extern global variables ---------------------------------------------------*/
/* Extern functions ----------------------------------------------------------*/
extern int32_t cpld_handle_init(void);
extern int32_t cpld_read(uint16_t addr, uint16_t len, uint16_t *data);
extern int32_t cpld_write(uint16_t addr, uint16_t len, uint16_t *data);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,215 @@
/******************************************************************************
* file include/pd_csg.h
* author YuLiang
* version 1.0.0
* date 21-Feb-2023
* brief This file provides all the headers of the csg server functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef _PD_CSG_H_
#define _PD_CSG_H_
#ifdef CFG_DEV_TYPE_LAND_PD
/* Includes ------------------------------------------------------------------*/
#include "pd_main.h"
/* Define --------------------------------------------------------------------*/
#define CSG_DATA_FIFO "CSG_DATA_FIFO"
#define CSG_HEAD_LEN (22)
#define CSG_TAIL_LEN (4)
#define CSG_TOTLE_LEN (26)
#define CSG_PKT_LEN (1536)
#define CSG_SHIQUCHA (28800) // 8 * 3600.
#define CSG_CONNECT_REQ (0xA000) // 开机联络信息.
#define CSG_CONNECT_ACK (0xC000) // 开机联络信息应答.
#define CSG_HEARTBEAT_REQ (0xA001) // 心跳信息.
#define CSG_HEARTBEAT_ACK (0xC001) // 心跳信息应答.
#define CSG_ACITVE_CONNECT_REQ (0xC002) // 主站主动连接设备 .
#define CSG_REBOOT_REQ (0xC015) // 装置重启.
#define CSG_FACTORY_SET_ACK (0xA010) // 生产初始化信息配置应答.
#define CSG_FACTORY_SET_REQ (0xC010) // 生产初始化信息配置.
#define CSG_FACTORY_GET_ACK (0xA020) // 生产初始化信息查询应答.
#define CSG_FACTORY_GET_REQ (0xC020) // 生产初始化信息查询.
#define CSG_CONFIG_SET_ACK (0xA013) // 下发参数配置应答.
#define CSG_CONFIG_SET_REQ (0xC013) // 下发参数配置.
#define CSG_CONFIG_GET_ACK (0xA023) // 查询参数配置应答.
#define CSG_CONFIG_GET_REQ (0xC023) // 查询参数配置.
#define CSG_PORT_CONFIG_SET_REQ (0xC111) // 端口参数配置.
#define CSG_PORT_CONFIG_SET_ACK (0xA111) // 端口参数配置应答.
#define CSG_PORT_CONFIG_GET_REQ (0xC121) // 端口参数查询.
#define CSG_PORT_CONFIG_GET_ACK (0xA121) // 端口参数查询应答.
#define CSG_EVENT_REQ (0xA130) // 事件主动上传.
#define CSG_EVENT_ACK (0xC136) // 事件回复确认.
#define CSG_TREND_REQ (0xC132) // 趋势数据查询.
#define CSG_TREND_ACK (0xA132) // 趋势数据主动上传.
#define CSG_REAL_IMAGE_REQ (0xC135) // 实时图谱数据平台召唤.
#define CSG_REAL_IMAGE_ACK (0xA135) // 实时图谱数据上传.
/* Exported types ------------------------------------------------------------*/
/* 设备配置的滤波类型. */
typedef enum
{
CSG_FILTER_TYPE_FF = 1,
CSG_FILTER_TYPE_FR,
CSG_FILTER_TYPE_LF,
CSG_FILTER_TYPE_HF
} CSG_FILTER_TYPE_E;
/* . */
typedef struct
{
int fd; // 后台通讯使用的 socket.
uint32_t pkt_index; // 报文索引.
int32_t data_fifo_id; // 数据处理线程发向后台发送线程的 fifo.
char buf_send[CSG_PKT_LEN];
char buf_reply[CSG_PKT_LEN];
char buf_recv[CSG_PKT_LEN];
struct sockaddr_in server;
int32_t server_ip; // server ip.
uint16_t server_port; // server port.
uint8_t is_connect; // 是否连接上服务器.
uint8_t heartbeat; // 心跳发送后没有收到回复的次数.
int32_t communication_time; // 最后通讯时间.
pthread_mutex_t mutex;
} csg_t;
/* 报文头结构. */
typedef struct{
uint16_t head;
uint16_t cmd;
uint8_t dev_num[PD_DEV_NUM_LEN];
uint16_t len;
} csg_pkt_head_t;
/* 报文尾结构.*/
typedef struct{
uint16_t checksum;
uint16_t tail;
} csg_pkt_tail_t;
/* 心跳报文. */
typedef struct{
uint8_t port_alarm[PD_PORT_SUM]; // 通道报警状态 0: 没有报警 1: 报警.
uint32_t event_num[PD_PORT_SUM]; // 通道的最新事件编号.
uint32_t fault_num[PD_PORT_SUM]; // 通道的最新原始数据编号.
uint32_t utc;
float freq; // 实测同步源工频频率.
uint8_t dau_state[4]; // 采集模块的状态.
uint8_t out_sync; // 外接调频同步 1: 有效 0: 无效.
uint8_t pt_sync; // PT同步 1: 有效 0: 无效.
uint8_t in_sync; // 内同步 1: 有效 0: 无效.
uint8_t reserved1; // 预留 字节对齐.
uint8_t port_link_alarm[PD_PORT_SUM]; // 通道传感器连接状态 断线告警.
float voltage; // 设备电压, 预留.
float temperature; // 设备温度, 预留.
uint8_t heartbeat; // 心跳发送后没有收到回复的次数.
uint8_t bat; // 电池电量 预留, 单位 %.
uint8_t reserved2[18];
} csg_pkt_heartbeat_t;
typedef struct
{
uint8_t vport; // 通道编号 1 ~ 16.
uint8_t is_concern; // 关注 1: 关注 0: 取消关注.
uint8_t r_noise_reduction; // 关联降噪 1: 关联噪声去噪.
uint8_t auto_noise_reduction; // 自适应降噪 自适应降噪.
uint8_t manual_noise_reduction; // 手动降噪 0 ~ 80 手动降噪.
uint8_t filter; // 滤波器类型.
uint8_t reserved[2]; //保留.
} csg_real_image_get_t;
/* 实时图谱报文头 36Byte. */
typedef struct{
uint16_t index; // 每10包传完之后自动自加用于区分当前包结束.
uint8_t pkt_sum; // 总包数 10.
uint8_t pkt_index; // 当前包数 0 ~ 9.
uint8_t vport; // 通道编号.
uint8_t reserved1[3];
int16_t max;
int16_t avg;
uint32_t cnt;
uint32_t utc;
uint32_t is_sub; // 0: 定时数据主动上传 , 1: 定时数据 UTC 召唤.
uint32_t interval; // 上传间隔, 单位分钟.
uint8_t reserved2[8];
} csg_real_image_t;
typedef struct{
uint32_t is_valid; // 1 有效 0 无效.
int16_t max;
int16_t avg;
uint32_t cnt;
float phase; // 放电相位.
uint32_t event_cnt; // 趋势数据中的的事件数量记录.
float noise; // 底噪平均值.
uint8_t reserved[16];
} csg_trend_t;
typedef struct{
uint32_t idx; // 数据编号.
uint32_t utc;
uint32_t is_sub; // 是否是补包.
uint32_t interval; // 上传间隔 单位分钟.
csg_trend_t data[PD_PORT_SUM];
uint8_t reserved[144];
} csg_trend_head_t;
typedef struct{
uint16_t idx; // 每 10 包传完之后自动++, 用于区分当前包结束.
uint8_t pkt_sum; // 总包数 10.
uint8_t pkt_idx; // 当前包数 0 ~ 9.
uint8_t vport; // 通道编号.
uint8_t type; // 事件类型.
int16_t max; // 事件幅值最大值.
uint32_t level; // 事件等级.
uint32_t pd_Type; // 放电类型.
float type_per[8]; // 放电概率.
float PositionDistance; // 距离本传感器的距离.
uint32_t utc; // utc.
uint32_t event_idx; // 事件编号.
uint32_t cnt; // 脉冲频次计数值.
} csg_event_head_t;
/* Exported macro ------------------------------------------------------------*/
/* Extern global variables ---------------------------------------------------*/
extern csg_t csg;
/* Extern functions ----------------------------------------------------------*/
extern int32_t csg_handle_init(void);
#endif
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,297 @@
/*****************************************************************************
* file include/pd_dau.h
* author YuLiang
* version 1.0.0
* date 03-Feb-2023
* brief This file provides all the headers of the dau functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef __PD_DAU_H__
#define __PD_DAU_H__
#ifdef CFG_DEV_TYPE_LAND_PD
/* Includes ------------------------------------------------------------------*/
#include "pd_main.h"
/* Define --------------------------------------------------------------------*/
#define DAU_ADJ_POINT_SUM 10
#define DAU_PKT_LEN 1536 // DAU 发包最大数据长度.
#define DAU_PKT_PRPS_LEN 640
#define DAU_PKT_PRPS_DATA_LEN 1280
#define DAU_REG_ADDR_GSCR 0x0000 // 全局寄存器 - 软件特征寄存器.
#define DAU_REG_ADDR_GSVR 0x0001 // 全局寄存器 - 软件版本寄存器.
#define DAU_REG_ADDR_GCR 0x0002 // 全局寄存器 - 控制寄存器.
#define DAU_REG_ADDR_GSR 0x0003 // 全局寄存器 - 状态寄存器.
#define DAU_REG_ADDR_GPFPCCR 0x0004 // 全局寄存器 - 工频周期时钟计数寄存器.
#define DAU_REG_ADDR_GPFPCR 0x0006 // 全局寄存器 - 工频周期计数寄存器.
#define DAU_REG_ADDR_GNSCR 0x0008 // 全局寄存器 - 纳秒级时钟计数寄存器.
#define DAU_REG_PORT_ADDR_MSRR 0x9000 // 端口状态寄存器 - 通道周波的原始采样值的均方根.
#define DAU_REG_PORT_ADDR_AVR 0x9008 // 端口状态寄存器 - 通道周波校准后的数值.
#define DAU_GSVR_SECONDARY_Pos (0)
#define DAU_GSVR_SECONDARY_Msk (0xFF << DAU_GSVR_SECONDARY_Pos) /*!< 0x00FF */
#define DAU_GSVR_PRIMARY_Pos (8)
#define DAU_GSVR_PRIMARY_Msk (0xFF << DAU_GSVR_PRIMARY_Pos) /*!< 0xFF00 */
#define DAU_GSR_SYNC_Pos (0)
#define DAU_GSR_SYNC_Msk (0x1 << DAU_GSR_SYNC_Pos) /*!< 0x0001 */
#define DAU_GSR_MODE_Pos (1)
#define DAU_GSR_MODE_Msk (0x1 << DAU_GSR_MODE_Pos) /*!< 0x0002 */
#define DAU_GCR_MODE_Pos (0)
#define DAU_GCR_MODE_Msk (0x3 << DAU_GCR_MODE_Pos) /*!< 0x0003 */
#define DAU_REG_PORT_BASE 0x1000 // 端口寄存器基地址.
#define DAU_REG_PORT_OFFSET 0x1000 // 每个端口寄存器偏移地址.
#define DAU_CR_SR_Pos (0)
#define DAU_CR_SR_Msk (0xFF << DAU_CR_SR_Pos) /*!< 0x00FF */
#define DAU_CR_PT_Pos (12)
#define DAU_CR_PT_Msk (0xF << DAU_CR_PT_Pos) /*!< 0xF000 */
#define DAU_FTR_FT_Pos (0)
#define DAU_FTR_FT_Msk (0xF << DAU_FTR_FT_Pos) /*!< 0x000F */
/* Exported types ------------------------------------------------------------*/
typedef void dau_prps_default_f(int16_t*);
typedef void dau_prps_process_f(uint8_t, uint8_t);
typedef void dau_trend_process_f(uint8_t, uint8_t, uint16_t);
/* 消息队列类型. */
typedef enum
{
DAU_SEND_TYPE_REG_RD = 1, // 读取寄存器.
DAU_SEND_TYPE_REG_WR, // 写入寄存器.
DAU_SEND_TYPE_UPDATE, // FPGA 升级.
DAU_SEND_TYPE_COUNT
} DAU_SEND_TYPE_E;
/* 共有命令字. */
typedef enum
{
DAU_PKT_CMD_RD = 0x01,
DAU_PKT_CMD_WR = 0x02,
DAU_PKT_CMD_SAV = 0x03,
DAU_PKT_CMD_UPD = 0x04,
DAU_PKT_CMD_PRPS = 0x81,
} DAU_PKT_CMD_E;
/* 共有命令字. */
typedef enum
{
DAU_UPD_PROCESS = 0,
DAU_UPD_OK = 1,
} DAU_UPD_ERR_E;
/* 和 DAU 通讯使用的报文结构体. */
typedef struct
{
uint8_t slave_id;
uint8_t func;
uint16_t addr;
uint16_t len;
uint16_t data[DAU_PKT_LEN];
} dau_pkt_t;
/* 和 DAU 通讯使用的报文结构体. */
typedef struct
{
uint32_t power_fre_cnt;
int16_t data[DAU_PKT_PRPS_LEN];
} dau_pkt_prps_t;
/* DAU 全局寄存器. */
typedef struct
{
uint16_t GSCR; // 全局软件特征寄存器 (Global Softwave Characteristic Register).
uint16_t GSVR; // 全局软件版本寄存器 (Global Softwave Version Register).
uint16_t GCR; // 全局控制寄存器 (Global Control Register).
uint16_t GSR; // 全局状态寄存器 (Global Status Register).
uint32_t GPFPCCR; // 全局工频周期时钟计数寄存器 (Global Power Frequency Period Clock Count Register).
uint32_t GPFPCR; // 全局工频周期计数寄存器 (Global Power Frequency Period Count Register).
uint32_t GNSCR; // 全局纳秒级时钟计数寄存器 (Global ns Count Register).
} dau_reg_t;
/* DAU 通道寄存器. */
typedef struct
{
uint16_t CR; // 控制寄存器 (Control Register).
uint16_t NR; // 底噪寄存器 (Noise Register).
uint16_t ASPR[DAU_ADJ_POINT_SUM]; // 校准分段点寄存器 (Adjust Segmentation Register).
uint16_t AFAR[DAU_ADJ_POINT_SUM]; // 校准系数 a 寄存器 (Adjust Factor A Register).
uint16_t AFBR[DAU_ADJ_POINT_SUM]; // 校准系数 b 寄存器 (Adjust Factor B Register).
uint16_t FTR; // 滤波类型寄存器 (Filtering type Register).
uint16_t WTDR; // 波形触发延时间隔寄存器 (Waveform Trigger Delay Register).
uint16_t WTTR; // 波形触发阈值寄存器 (Waveform Trigger Threshold Register).
uint16_t WTPSR; // 波形触发记录采样点寄存器 (Waveform Trigger Ponit Sum Register).
uint16_t WTBPR; // 波形触发前记录采样点寄存器 (Waveform Trigger Befor Ponit Register).
} dau_port_reg_t;
/* DAU 通道状态寄存器. */
typedef struct
{
uint16_t MSRR[PD_DAU_PORT_SUM]; // 通道周波的原始采样值的均方根 (Mean Square Root Register).
uint16_t AVR[PD_DAU_PORT_SUM]; // 通道周波校准后的数值 (Adjust Value Register).
} dau_port_state_reg_t;
/* DAU 通道寄存器. */
typedef struct
{
uint32_t prps_cnt; // prps 工频周期计数.
uint32_t prps_index; // prps 计数.
int16_t prps[PD_PRPS_NUM]; // 1s prps 原始数据.
int16_t noise_level[PD_POWER_FRE]; // prps 计算使用的每个工频周期的噪声等级.
uint8_t is_complete; // prps 数据是否完整.
} dau_port_state_t;
/* DAU 通道数据处理函数. */
typedef struct
{
dau_prps_default_f *data_default; // PRPS buffer 还原默认值.
dau_prps_process_f *denoise; // PRPS 自动 / 手动降噪.
dau_prps_process_f *denoise_r; // PRPS 关联降噪.
dau_prps_process_f *denoise_state; // PRPS 降噪数据统计.
dau_prps_process_f *denoise_real; // 实时数据自动 / 手动降噪.
dau_prps_process_f *denoise_real_r; // 实时数据关联降噪.
dau_prps_process_f *denoise_real_state; // PRPS 降噪数据统计.
dau_prps_process_f *event; // 事件计算.
dau_trend_process_f *trend; // 趋势数据.
} dau_port_func_t;
/* DAU 板卡全局结构 */
typedef struct{
uint8_t unit; // FPGA 板卡号.
uint8_t port_num; // FPGA 板卡端口数量.
uint16_t ip_port; // 端口号.
int32_t ip_addr; // IP 地址.
uint16_t msg_send_type; // 发包线程需要处理的消息队列类型.
uint16_t send_type; // 当前发送的数据类型 DAU_SEND_TYPE_XXX.
uint8_t is_valid; // 用于配置保存.
uint8_t is_connect; // 记录 DAU 是否通讯正常.
dau_port_state_t port_state[PD_DAU_PORT_SUM]; // 端口状态.
dau_port_func_t *port_func[PD_DAU_PORT_SUM]; // 端口数据处理函数.
pthread_mutex_t mutex; // 收发线程同步使用.
dau_reg_t reg; // DAU 全局寄存器软标.
dau_reg_t reg_dau; // DAU 全局寄存器硬表.
dau_port_reg_t port_reg[PD_DAU_PORT_SUM]; // 通道寄存器软表.
dau_port_reg_t port_reg_dau[PD_DAU_PORT_SUM]; // 通道寄存器硬表.
dau_port_state_reg_t port_state_reg; // 通道状态寄存器.
} dau_t;
/* DAU 全局结构 */
typedef struct{
int fd; // DAU 通讯使用的 socket.
int32_t recv_fifo_id; // 数据从接收线程发送到数据处理线程的 fifo.
uint32_t real_idx;
uint32_t trend_idx;
uint32_t event_index[PD_DAU_SUM][PD_DAU_PORT_SUM]; // 每个端口的事件索引.
uint32_t trend_event_index[PD_DAU_SUM][PD_DAU_PORT_SUM]; // 每个端口的趋势事件索引.
char recv_buf[DAU_PKT_LEN]; // DAU 收包 buffer.
int8_t is_update; // 是否开始升级.
int8_t update_ret; // 升级结果, 0 - 进行中, 1 - 成功, <0 - 失败.
uint16_t update_idx; // 升级报文索引.
uint32_t recv_cnt;
uint32_t recv_cnt_old;
uint32_t recv_err_cnt;
uint32_t recv_err_cnt_old;
uint32_t data_err_cnt;
uint32_t data_err_cnt_old;
uint32_t send_err_cnt;
uint32_t send_err_cnt_old;
} dau_ctrl_t;
/* DAU 发送报文数据. */
typedef struct _dau_send_msg_data_t
{
uint16_t send_type; // 发送的数据类型.
uint16_t send_len; // 发送的数据长度.
void *data; // 数据的内存地址.
} dau_send_msg_data_t;
/* DAU 消息队列要求的结构体样式. */
typedef struct _dau_send_msg_t
{
long type; // 消息类型, 用于收报文过滤.
dau_send_msg_data_t data; // 消息数据.
} dau_send_msg_t;
/* DAU 接收报文数据. */
typedef struct _dau_recv_msg_data_t
{
uint32_t ip_addr; // 收包数据的源 IP 地址.
uint32_t recv_len; // 收包数据长度.
void *data; // 数据的内存地址.
} dau_recv_msg_data_t;
/* DAU 消息队列要求的结构体样式. */
typedef struct _dau_recv_msg_t
{
long type; // 消息类型, 用于收报文过滤.
dau_recv_msg_data_t data; // 消息数据.
} dau_recv_msg_t;
/* Exported macro ------------------------------------------------------------*/
#define SET_BIT(REG, BIT) ((REG) |= (BIT))
#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
#define READ_BIT(REG, BIT) ((REG) & (BIT))
#define WRITE_REG(REG, VAL) ((REG) = (VAL))
#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((REG) & (~(CLEARMASK))) | (SETMASK)))
#define DAU_REG_PORT_ADDR_GET(port) ((port + 1) << 12)
/* Extern global variables ---------------------------------------------------*/
extern dau_t *dau[PD_DAU_SUM];
extern dau_ctrl_t dau_ctrl;
/* Extern functions ----------------------------------------------------------*/
extern int32_t dau_port_to_vport(uint8_t unit, uint8_t port);
extern int32_t dau_vport_to_port(uint8_t vport, uint8_t *unit, uint8_t *port);
extern int32_t dau_port_config_set(uint8_t unit, uint8_t port);
extern int32_t dau_port_type_set(uint8_t unit, uint8_t port, uint8_t type);
extern int32_t dau_handle_init(void);
extern uint8_t dau_power_frequency_state_get(void);
extern float dau_power_frequency_get(void);
extern uint8_t dau_connect_get(void);
extern void* dau_port_state_get(void *arg);
extern int32_t dau_reg_global_write(uint8_t unit);
extern int32_t dau_reg_port_write(uint8_t unit, uint8_t port);
extern int32_t dau_param_save(uint8_t unit);
extern void dau_shutdown(void);
extern int32_t dau_start(void);
extern int32_t dau_update(void);
extern void dau_show(uint8_t unit);
extern void dau_show_adj(uint8_t unit);
extern void dau_show_reg(uint8_t unit);
extern void dau_show_reg_port(uint8_t unit, uint8_t port);
#endif
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

@ -0,0 +1,134 @@
/*****************************************************************************
* file include/pd_dbg.h
* author YuLiang
* version 1.0.0
* date 01-June-2023
* brief This file provides all the headers of the debug server functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef __PD_DBG_H__
#define __PD_DBG_H__
#ifdef CFG_DEV_TYPE_LAND_PD
/* Includes ------------------------------------------------------------------*/
#include "pd_main.h"
/* Define --------------------------------------------------------------------*/
#define DEBUG_BUG_SIZE 1512
#define DEBUG_CJSON_BUG_SIZE 1512
#define DEBUG_CONFIG_GET (0x0001) // 获取配置.
#define DEBUG_CONFIG_SET (0x0002) // 设置配置.
#define DEBUG_ALARM_CONFIG_GET (0x0003) // 获取事件告警二进制文件配置.
#define DEBUG_ALARM_CONFIG_SET (0x0004) // 设置事件告警二进制文件配置.
#define DEBUG_REBOOT (0x0005) // 重启.
#define DEBUG_TIME_SET (0x0006) // 对时.
#define DEBUG_NOISE_CAREFOR (0x0007) // 关注对应通道的底噪原始值, 校准底噪值.
#define DEBUG_NOISE_POST (0x0008) // 获取底噪原始值, 校准底噪值 服务端主动提交每秒刷新一次.
#define DEBUG_ADJSUT_COEFFICIENT_GET (0x0009) // 获取校准系数.
#define DEBUG_ADJSUT_COEFFICIENT_SET (0x000a) // 设置校准系数.
#define DEBUG_RUN_STATUS_GET (0x000b) // 获取运行状态数据.
#define DEBUG_ARM_UPGRADE (0x0050) // ARM 升级.
#define DEBUG_FPGA1_UPGRADE (0x0051) // FPGA 板卡升级.
#define DEBUG_FPGA2_UPGRADE (0x0052) // FPGA 板卡升级.
#define DEBUG_FPGA3_UPGRADE (0x0053) // FPGA 板卡升级.
#define DEBUG_FPGA4_UPGRADE (0x0054) // FPGA 板卡升级.
#define DEBUG_FPGA_UPGRADE (0x0055) // FPGA 板卡升级.
#define DEBUG_UPGRADE_ALL (0x0056) // ARM和FPGA板卡升级
#define BITMAP_SAVE_FILE (1 << 0)
#define BITMAP_IP_CHANGE (1 << 1)
#define DEBUG_MANAGE_TOOL_PORT (10050)
/* Exported types ------------------------------------------------------------*/
/* 端口校准系数. */
typedef struct {
uint16_t point[4]; // 通道分段点.
uint16_t param_a[5]; // 通道线性度校准系数 a.
uint16_t param_b[5]; // 通道线性度校准系数 b.
uint16_t alarm_ref; // 断线告警比较值.
uint16_t reserve;
} debug_pkt_adj_vport_t;
typedef struct {
debug_pkt_adj_vport_t vport[PD_PORT_SUM];
} debug_pkt_adj_t;
/* 端口状态, 主要是 ADC 原始值和校准后的值.*/
typedef struct {
uint16_t value_adc;
int16_t value_adj;
} debug_pkt_port_state_t;
typedef struct {
debug_pkt_port_state_t vport[PD_PORT_SUM];
} debug_pkt_port_t;
/* 设备状态. */
typedef struct {
uint32_t idx; // 编号.
uint32_t UTC_TimeScale; // UTC 时标
float F50Hz_Frequency; // 同步 50Hz 频率.
uint8_t F50Hz_SynStatus; // 同步状态.
uint8_t dau_status; // 插件状态.
uint16_t sensor_status; // 传感器断线状态.
uint16_t is_server_link; // 是否连接上后台.
uint16_t version; // 软件版本
uint32_t communication_time; // 上一次通讯的时间
uint32_t run_time; // 设备运行时间
} debug_pkt_status_t;
/* 报文头. */
typedef struct{
uint16_t head; // 0x55aa.
uint16_t cmd; // 命令.
uint32_t len; // 包长.
} debug_pkt_head_t;
/* 调试工具全局结构 */
typedef struct{
int fd; // TCP server 监听使用的 socket.
int fd_client; // TCP client 通讯使用的 socket.
char buf[DEBUG_BUG_SIZE]; // 通讯使用收法包 buffer.
char buf_post[DEBUG_BUG_SIZE]; // 主动上传通讯使用收法包 buffer.
int is_manual_col; // 是否手动采集.
} debug_ctrl_t;
/* Exported macro ------------------------------------------------------------*/
/* Extern global variables ---------------------------------------------------*/
extern debug_ctrl_t debug_ctrl;
/* Extern functions ----------------------------------------------------------*/
extern int32_t debug_handle_init(void);
extern int32_t debug_pkt_port_state_post(void);
#endif
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

@ -0,0 +1,339 @@
/*****************************************************************************
* file include/pd_main.h
* author YuLiang
* version 1.0.0
* date 07-Feb-2023
* brief This file provides all the headers of the partial discharge functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef __PD_MAIN_H__
#define __PD_MAIN_H__
#ifdef CFG_DEV_TYPE_LAND_PD
/* Includes ------------------------------------------------------------------*/
#include "cmd.h"
/* Define --------------------------------------------------------------------*/
#define PD_DAU_SUM 2
#define PD_DAU_PORT_SUM 8
#define PD_PORT_SUM 16
#define PD_PORT_PROMPT_LEN 64 // DAU 端口节点前标长度.
#define PD_DEV_NUM_LEN 16
#define PD_DEV_TYPE_LEN 8
#define PD_POWER_FRE 50
#define PD_PHASE_NUM 128
#define PD_PRPS_NUM 6400
#define PD_PRPS_DATA_LEN 12800
#define PD_GIS_MIN_VALUE (-800) // 特高频局放的采集数值下限 -800 (-80.0dBm).
#define DEBUG_DAU_FILE "PDMonitor_DAU"
#define UPGRADE_SOFTWARE "upgrade.sw"
/* Exported types ------------------------------------------------------------*/
/* 用于命令行模式节点注册配置保存函数 */
typedef int pd_port_cmd_save_config_f(vty_t*, uint8_t, uint8_t);
/* 向服务器发送消息的类型. */
typedef enum
{
PD_SEND_TYPE_PRPS = 1,
PD_SEND_TYPE_TREND,
PD_SEND_TYPE_EVENT,
PD_SEND_TYPE_COUNT
} PD_SEND_TYPE_E;
/* 端口类型. */
typedef enum
{
PD_PORT_TYPE_UHF = 1,
PD_PORT_TYPE_AE,
PD_PORT_TYPE_TEV,
PD_PORT_TYPE_HF,
PD_PORT_TYPE_COUNT
} PD_PORT_TYPE_E;
/* 设备配置的主备类型. */
typedef enum
{
PD_DAU_MODE_AUTO = 0,
PD_DAU_MODE_MASTER,
PD_DAU_MODE_SLAVE,
PD_DAU_MODE_COUNT
} PD_DAU_MODE_E;
/* 设备配置的滤波类型. */
typedef enum
{
PD_FILTER_TYPE_HF = 3,
PD_FILTER_TYPE_LF = 6,
PD_FILTER_TYPE_FR = 9,
PD_FILTER_TYPE_FF = 12
} PD_FILTER_TYPE_E;
/* 端口类型. */
typedef enum
{
PD_SEN_TYPE_NONE = 0,
PD_SEN_TYPE_SIG,
PD_SEN_TYPE_NOISE,
PD_SEN_TYPE_SIG_NOISE,
PD_SEN_TYPE_COUNT
} PD_SEN_TYPE_E;
/* 设备配置的滤波类型. */
typedef enum
{
PD_SYNC_PT = 1,
PD_SYNC_POWER = 2,
PD_SYNC_OUTSIDE = 4,
} PD_SYNC_MODE_E;
/* 端口节点配置优先级 */
typedef enum
{
PD_PORT_CMD_PRI_DAU = 0,
PD_PORT_CMD_PRI_COUNT
} PD_PORT_CMD_PRI_E;
/* 1s prps 数据结构体. */
typedef struct {
int16_t avg_o; // 通道原始信号 (降噪前) 的平均值.
int16_t max; // 通道的最大值.
int16_t avg; // 通道的平均值.
uint32_t cnt; // 通道的计数值.
int32_t phase_sum[PD_PHASE_NUM]; // 通道的周波放电相位累加值.
int16_t phase_max[PD_PHASE_NUM]; // 通道的周波相位最大值.
int16_t phase_avg[PD_PHASE_NUM]; // 通道的周波相位平均值.
uint16_t phase_cnt[PD_PHASE_NUM]; // 通道的周波相位计数值 .
int16_t data[PD_PRPS_NUM]; // 通道数据.
uint8_t is_valid; // prps 数据是否有效.
} pd_prps_data_t;
typedef struct {
uint32_t index; // 数据编号.
uint32_t utc; // UTC 时标.
uint32_t is_denoise; // 是否降噪的标记: 1-已经降噪 0-原始没有降噪.
void *reserve; // 与 GIS5.0 设备的结构体同步.
pd_prps_data_t data[PD_DAU_SUM][PD_DAU_PORT_SUM]; // 16 个通道的数据.
} pd_prps_t;
typedef struct {
uint32_t index; // 数据编号: 0 - (2^32-1) 循环.
uint32_t utc; // UTC 时标.
uint8_t vport; // 通道编号.
uint8_t level; // 事件等级.
uint8_t type; // 放电类型识别结果: 每种放电类型的比较的概率.
uint8_t second; // 当前事件记录的时间秒数.
int16_t max; // 通道的最大值.
int32_t avg; // 通道的平均值.
int32_t cnt; // 通道的计数值.
float type_per[8]; // 放电类型识别结果.
uint16_t PositionEfficiency; // 定位信息: 有效性 0: 无效 1有效.
uint16_t PositionOtherChNum; // 定位信息: 对端传感器通道号 范围 [1-16].
uint32_t PositionDistance; // 定位信息: 距离本传感器的距离.
uint32_t RatioOutValue; // 定位信息: 实际比率 配对上 / 超过阀值的计数.
int32_t phase_sum[PD_PHASE_NUM]; // 通道的周波相位累加值.
int16_t phase_max[PD_PHASE_NUM]; // 通道的周波相位最大值.
int16_t phase_avg[PD_PHASE_NUM]; // 通道的周波相位平均值.
int32_t phase_cnt[PD_PHASE_NUM]; // 通道的周波相位计数值.
int16_t data[PD_PRPS_NUM]; // 通道 n 的测量数据.
} pd_event_t;
typedef struct {
int16_t max; // 通道的最大值.
int64_t avg; // 通道的平均值.
int32_t cnt; // 通道的计数值.
float phase; // 放电相位 .
float noise; // 趋势数据中的底噪值: 单位 dBm .
uint32_t event_cnt; // 趋势数据中的的事件数量记录.
int64_t phase_sum[PD_PHASE_NUM]; // 通道的周波放电相位累加值.
int16_t phase_max[PD_PHASE_NUM]; // 通道的周波相位最大值.
int16_t phase_avg[PD_PHASE_NUM]; // 通道的周波相位平均值.
int32_t phase_cnt[PD_PHASE_NUM]; // 通道的周波相位计数值.
} pd_trend_data_t;
typedef struct {
uint32_t index; // 数据编号: 0 - (2^32-1) 循环.
uint32_t utc; // UTC 时标.
pd_trend_data_t data[PD_DAU_SUM][PD_DAU_PORT_SUM]; // 通道 0 - 15 的计算及测量数据.
} pd_trend_t;
typedef struct {
pd_prps_t *denoise; // PRPS 数据指针.
pd_prps_t real; // 实时数据指针.
pd_event_t event[PD_DAU_SUM][PD_DAU_PORT_SUM]; // 端口事件指针.
pd_trend_t trend; // 趋势数据.
} pd_data_t;
typedef struct {
uint32_t type;
void *data;
} pd_csg_msg_t;
typedef struct {
uint8_t vport; // 通道编号.
uint8_t filter; // 滤波器类型 1: 低频段 2: 全频段 3: 窄频段 4: 高频段
uint8_t sensor_type; // 0: 无配置; 1: UHF信号传感器; 2: UHF噪声传感器 ; 3: UHF信号传感器, 关联噪声降噪.
uint8_t phase_sequence; // 对应相序 1A 2B 3C.
uint16_t NearSensor1_Number; //关联监测点1
uint16_t NearSensor1_Distance; //与监测点1距离
uint16_t Signal1_AttenuationRatio; //衰减 dBm/m 20200717
uint16_t NearSensor2_Number; //关联监测点2
uint16_t NearSensor2_Distance; //与监测点2距离
uint16_t Signal2_AttenuationRatio; //衰减 dBm/m 20200717
uint16_t NearSensor3_Number; //关联监测点3
uint16_t NearSensor3_Distance; //与监测点3距离
uint16_t Signal3_AttenuationRatio; //衰减 dBm/m 20200717
uint16_t NearSensor4_Number; //关联监测点4
uint16_t NearSensor4_Distance; //与监测点4距离
uint16_t Signal4_AttenuationRatio; //衰减 dBm/m 20200717
int16_t event_threshold; // 事件触发阀值 0.1dBm.
uint16_t event_counter; // 事件次数阀值.
int16_t env_noise; // 环境底噪, 单位: dBm 0~100 100-自动降噪.
int16_t noise_reduction; // 降噪水平, 单位: 0.1dBm.
int16_t UpperLimitOfDischargeAmplitude; //放电幅值上限 未使用
int16_t WaveTriggerThreshold; //波形触发阀值 -32768~32768
uint16_t PrescalerSampleValue; //通道采样抽点数值 未使用
uint16_t reserved1;
uint32_t SamplePointsTotalTriggered; //脉冲波形一次完整记录的采样点数 未使用
uint32_t RecordStartAdr; //波形记录本通道的SDR/DDR的缓冲区起始地址 未使用
uint32_t RecordStopAdr; //波形记录本通道的SDR/DDR的缓冲区结束地址 未使用
uint32_t sample_rate; //数据采样频率 Hz
uint32_t BeforeTriggerTime; //触发前采样时间 10ns
uint32_t AfterTriggerTime; //触发后采样时间 10ns
uint32_t storage_event; //事件存储文件数量阈值
uint32_t storage_wave; //波形存储文件数量阈值
uint8_t reserved[4]; //预留
}pd_port_config_old_t;
typedef struct{
uint8_t power_frequency; // 工频频率 未使用
uint8_t sync_mode; // 同步方式 1: PT 同步 2: 电源同步(默认) 4: 外接信号同步.
uint8_t TimingSyncMode; // 对时方式 1:网卡对时 2:GPS对时 4:外部对时 8:FPGA内部对时
uint8_t real_period; // 定时数据上送周期, 单位: 分钟.
uint8_t trend_period; // 趋势数据上送周期, 单位: 分钟.
uint8_t heartbeat_period; // 心跳包周期.
uint16_t NumberWindowsOfPhase; // 相位窗数 //未使用
uint32_t SyncTime; // 对时数据 //未使用
uint16_t AlarmPeriod; // 报警观察周期 //未使用
uint16_t TimePrpsStrategy; // 定时数据存储策略 0 全部存储 1 未上传存储.
uint32_t storage_trend; // 趋势存储文件数量阈值.
uint32_t StorageAlarm; // 告警存储文件数量阈值.
uint32_t StorageRun; // 运行状态存储文件数量阈值.
uint32_t storage_real; // 定时PRPS存储文件数量阈值.
uint32_t limit_event_time; // 事件频繁判断时间.
uint32_t limit_event_cnt; // 事件频繁判断个数.
uint32_t limit_event_interval; // 事件频繁后存储间隔.
uint32_t is_prps_save; // 实时PRPS存储使能.
uint8_t Reserved[52]; // 预留 .
}pd_config_old_t;
/* 局放配置. */
typedef struct {
pd_port_config_old_t config; // 为了兼容原先的协议.
uint8_t is_concern; // 是否被关注, 在实时波形中使用..
uint8_t r_noise_reduction; // 是否启动关联降噪, 在实时波形中使用..
uint8_t auto_noise_reduction; // 是否自动降噪, 在实时波形中使用..
uint8_t manual_noise_reduction; // 手动降噪, 单位: 0.1dBm, 在实时波形中使用..
uint8_t filter_cfg; // 端口配置的滤波类型, 在实时波形中使用.
} pd_port_config_t;
typedef struct{
uint8_t dev_num[PD_DEV_NUM_LEN]; // 设备编号.
uint8_t dev_type[PD_DEV_TYPE_LEN]; // 设备型号.
uint32_t factory_date; // 出厂日期.
uint32_t deployment_date; // 部署日期.
uint32_t ipv4; // 本机 IP.
uint8_t ipv6[16]; // 预留 IPV6 , 未使用.
uint8_t mac[MAC_ADDR_LEN]; // MAC地址.
uint8_t LocalIP2[4]; // 本机 IP, 未使用.
uint8_t LocalIP2_V6[16]; // 预留 IPV6 , 未使用.
uint8_t LocalMacAddress2[6]; // MAC 地址, 未使用.
uint32_t server_ipv4; // 服务器 IP.
uint8_t server_ipv6[16]; // 预留 IPV6, 未使用.
uint8_t ServerIP2[4]; // 服务器 IP, 未使用.
uint8_t ServerIP2_V6[16]; // 预留 IPV6 , 未使用.
uint16_t server_port; // 服务器端口号.
uint16_t ServerIP2_Port; // 服务器端口号, 未使用.
uint8_t port_type[PD_PORT_SUM]; // 采集通道类型 , 1 表示特高频局放 2 表示超声局放 3 表示 TEV 4 表示高频.
uint8_t Reserved[12]; // 预留.
uint32_t runTime; // 运行时间, 未使用.
uint32_t devVoltage; // 设备电压, 未使用.
uint32_t devTemperature; // 设备温度, 未使用.
uint32_t devSleepTime; // 设备休眠时长, 未使用.
uint32_t devPasswd; // 设备密码, 未使用.
uint8_t batteryVoltage; // 电池电压, 未使用.
uint8_t linkStatus; // 通讯状态, 未使用.
}pd_factory_old_t;
typedef struct {
pd_factory_old_t factory;
pd_config_old_t config;
pd_port_config_t port_config[PD_DAU_SUM][PD_DAU_PORT_SUM]; // 端口配置.
uint32_t concern_bitmap;
} pd_config_t;
typedef struct {
uint8_t sync;
} pd_state_t;
/* Exported macro ------------------------------------------------------------*/
/* Extern global variables ---------------------------------------------------*/
extern pd_data_t pd_data;
extern pd_config_t pd_config;
extern pd_state_t pd_state;
extern cmd_node_t pd_port_node;
/* Extern functions ----------------------------------------------------------*/
extern int32_t pd_main(void);
extern int32_t pd_port_cmd_config_register(int32_t pri, pd_port_cmd_save_config_f *func);
extern void pd_sync_mode_set(void);
extern void pd_sync_state_get(void);
extern void pd_wdg_clr(void);
extern void pd_prps_show(void);
extern void pd_show(void);
#endif
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

@ -0,0 +1,54 @@
#ifndef __PD_STORAGE_H_
#define __PD_STORAGE_H_
/* Includes ------------------------------------------------------------------*/
/* Define --------------------------------------------------------------------*/
#define STORAGE_DATA_FIFO "STORAGE_DATA_FIFO"
/* Exported types ------------------------------------------------------------*/
/*本地存储类型*/
typedef enum
{
STORAGE_TYPE_EVENT = 1,
STORAGE_TYPE_TREND,
STORAGE_TYPE_ALARM,
STORAGE_TYPE_RUNSTATUS,
STORAGE_TYPE_FIXEDTIMERPRPS
}LOCAL_STORAGE_TYPE_E;
/* */
typedef struct
{
int32_t storage_fifo_id; // 存储FIFO ID
pthread_mutex_t mutex;
} storage_t;
typedef struct {
uint32_t type;
void *data;
} pd_storage_msg_t;
typedef struct {
uint16_t event_cnt[PD_DAU_SUM][PD_DAU_PORT_SUM]; //事件文件已存储数
uint16_t trend_cnt; //趋势文件已存储数
uint16_t fixedtimePRPS_cnt; //定时PRPS文件已存储数
uint32_t event_max_utc[PD_DAU_SUM][PD_DAU_PORT_SUM];
uint32_t event_min_utc[PD_DAU_SUM][PD_DAU_PORT_SUM];
uint32_t trend_max_utc;
uint32_t trend_min_utc;
uint32_t fixedtimePRPS_max_utc;
uint32_t fixedtimePRPS_min_utc;
uint32_t utc_base[PD_DAU_SUM][PD_DAU_PORT_SUM]; //事件文件存储频繁判断基准值
uint32_t limit_cnt[PD_DAU_SUM][PD_DAU_PORT_SUM]; //事件文件存储频繁判断个数
} storage_arg_t;
/* Exported macro ------------------------------------------------------------*/
/* Extern global variables ---------------------------------------------------*/
extern storage_t storage;
/* Extern functions ----------------------------------------------------------*/
extern int32_t localstorage_handle_init(void);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,60 @@
/*****************************************************************************
* file include/process.h
* author YuLiang
* version 1.0.0
* date 26-Sep-2021
* brief This file provides all the headers of the process functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef __PROCESS_H__
#define __PROCESS_H__
/* Includes ------------------------------------------------------------------*/
/* Define --------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* 消息队列类型. */
typedef enum
{
MSG_TYPE_DAU_RECV = 5, /* 1-4 固定被 DAU 发送线程使用, 这里从 5 开始. */
MSG_TYPE_COUNT,
} MSG_TYPE_E;
/* Extern global variables ---------------------------------------------------*/
extern int32_t recv_qid;
extern uint16_t version_hex;
extern uint32_t start_time;
/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

@ -0,0 +1,230 @@
/******************************************************************************
* file include/sockunion.h
* author YuLiang
* version 1.0.0
* date 09-Oct-2021
* brief This file provides all the headers of the sockunion functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef _SOCKUNION_H_
#define _SOCKUNION_H_
/* Includes ------------------------------------------------------------------*/
/* Define --------------------------------------------------------------------*/
#define IPV4_MAX_BITLEN 32
#define IPV6_MAX_BITLEN 128
#define PNBBY 8
#define AFI_IP 1
#define AFI_IP6 2
#define AFI_MAX 3
#define SU_ADDRSTRLEN 46
/* Default address family. */
#ifdef HAVE_IPV6
#define AF_INET_UNION AF_INET6
#else
#define AF_INET_UNION AF_INET
#endif
/* Exported types ------------------------------------------------------------*/
/* IPv4 and IPv6 unified prefix structure. */
typedef struct _prefix
{
uint8_t family;
uint8_t prefixlen;
union
{
uint8_t prefix;
struct in_addr prefix4;
#ifdef HAVE_IPV6
struct in6_addr prefix6;
#endif /* HAVE_IPV6 */
struct
{
struct in_addr id;
struct in_addr adv_router;
} lp;
uint8_t val[8];
} u __attribute__ ((aligned (8)));
} prefix_t;
/* IPv4 prefix structure. */
typedef struct _prefix_ipv4
{
uint8_t family;
uint8_t prefixlen;
struct in_addr prefix __attribute__ ((aligned (8)));
} prefix_ipv4_t;
/* IPv6 prefix structure. */
#ifdef HAVE_IPV6
typedef struct _prefix_ipv6
{
uint8_t family;
uint8_t prefixlen;
struct in6_addr prefix __attribute__ ((aligned (8)));
} prefix_ipv6_t;
#endif /* HAVE_IPV6 */
typedef enum
{
ACCESS_TYPE_STRING,
ACCESS_TYPE_NUMBER
} ACCESS_TYPE_E;
/* Filter type is made by `permit', `deny' and `dynamic'. */
typedef enum
{
FILTER_DENY,
FILTER_PERMIT,
FILTER_DYNAMIC
} FILTER_TYPE_E;
/* List of access_list. */
typedef struct
{
struct _access_list *head;
struct _access_list *tail;
} access_list_list_t;
/* Master structure of access_list. */
typedef struct
{
/* List of access_list which name is number. */
access_list_list_t num;
/* List of access_list which name is string. */
access_list_list_t str;
/* Hook function which is executed when new access_list is added. */
void (*add_hook)(struct _access_list *);
/* Hook function which is executed when access_list is deleted. */
void (*delete_hook)(struct _access_list *);
} access_master_t;
typedef struct
{
/* Cisco access-list */
int extended;
struct in_addr addr;
struct in_addr addr_mask;
struct in_addr mask;
struct in_addr mask_mask;
} filter_cisco_t;
typedef struct
{
/* If this filter is "exact" match then this flag is set. */
int exact;
/* Prefix information. */
prefix_t prefix;
} filter_zebra_t;
/* Filter element of access list */
typedef struct _filter
{
/* For doubly linked list. */
struct _filter *next;
struct _filter *prev;
/* Filter type information. */
FILTER_TYPE_E type;
/* Cisco access-list */
int cisco;
union
{
filter_cisco_t cfilter;
filter_zebra_t zfilter;
} u;
} filter_t;
/* Access list */
typedef struct _access_list
{
char *name;
char *remark;
access_master_t *master;
ACCESS_TYPE_E type;
struct _access_list *next;
struct _access_list *prev;
filter_t *head;
filter_t *tail;
} access_list_t;
typedef union
{
struct sockaddr sa;
struct sockaddr_in sin;
#ifdef HAVE_IPV6
struct sockaddr_in6 sin6;
#endif /* HAVE_IPV6 */
} SOCKUNION_U;
/* Exported macro ------------------------------------------------------------*/
/* Extern global variables ---------------------------------------------------*/
/* Extern functions ----------------------------------------------------------*/
extern void prefix_free(prefix_t *p);
extern prefix_ipv4_t *prefix_ipv4_new(void);
#ifdef HAVE_IPV6
extern prefix_ipv6_t *prefix_ipv6_new(void);
#endif /* HAVE_IPV6 */
extern access_list_t *access_list_lookup(uint16_t afi, const char *name);
extern FILTER_TYPE_E access_list_apply(access_list_t *access, void *object);
extern void masklen2ip(int masklen, struct in_addr *netmask);
extern int prefix_match(const prefix_t *n, const prefix_t *p);
extern int str2sockunion(const char *str, SOCKUNION_U *su);
extern const char *sockunion2str(SOCKUNION_U *su, char *buf, size_t len);
extern int sockunion_accept(int sock, SOCKUNION_U *su);
extern int set_nonblocking(int fd);
extern prefix_t *sockunion2hostprefix(const SOCKUNION_U *su);
extern char *sockunion_su2str(SOCKUNION_U *su);
extern int sockunion_stream_socket(SOCKUNION_U *su);
extern int sockunion_reuseaddr(int sock);
extern int sockunion_bind(int sock, SOCKUNION_U *su, unsigned short port, SOCKUNION_U *su_addr);
extern int sockunion_ip_set(char *name, unsigned int addr);
extern int sockunion_mask_set(char *name, unsigned int mask);
extern int sockunion_gw_set(char *name, unsigned int gateway, unsigned int gateway_old);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,64 @@
/*****************************************************************************
* file include/thread_monitor.h
* author YuLiang
* version 1.0.0
* date 08-Oct-2021
* brief This file provides all the headers of the thread monitor functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef __THREAD_M_H__
#define __THREAD_M_H__
/* Includes ------------------------------------------------------------------*/
#include <pthread.h>
/* Define --------------------------------------------------------------------*/
#define THREAD_M_NAME_LEN 32
/* Exported types ------------------------------------------------------------*/
/* 线程监控结构体. */
typedef struct _thread_m_t
{
char name[THREAD_M_NAME_LEN]; /* 线程名字 */
pthread_t pid; /* 线程pid */
int8_t alive; /* 是否活着 */
} thread_m_t;
/* Extern global variables ---------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
extern int32_t thread_m_add(char *str, pthread_t pid);
extern int32_t thread_m_init(void);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

@ -0,0 +1,331 @@
/******************************************************************************
* file include/vty.h
* author YuLiang
* version 1.0.0
* date 10-Sep-2021
* brief This file provides all the headers of the vty functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef _VTY_H_
#define _VTY_H_
/* Includes ------------------------------------------------------------------*/
#include <sys/resource.h>
#include "array.h"
/* Define --------------------------------------------------------------------*/
/* Thread types. */
#define THREAD_READ 0
#define THREAD_WRITE 1
#define THREAD_TIMER 2
#define THREAD_EVENT 3
#define THREAD_READY 4
#define THREAD_BACKGROUND 5
#define THREAD_UNUSED 6
#define THREAD_PERFORM 7
/* Struct timeval's tv_usec one second value. */
#define TIMER_SECOND_MICRO 1000000L
#define RUSAGE_T rusage_t
#define GETRUSAGE(X) thread_getrusage(X)
#define THREAD_ADD_READ(m,f,a,v) thread_add_read(m,f,a,v,#f)
#define THREAD_ADD_WRITE(m,f,a,v) thread_add_write(m,f,a,v,#f)
#define THREAD_ADD_TIMER(m,f,a,v) thread_add_timer(m,f,a,v,#f)
#define THREAD_ADD_TIMER_MSEC(m,f,a,v) thread_add_timer_msec(m,f,a,v,#f)
#define THREAD_ADD_EVENT(m,f,a,v) thread_add_event(m,f,a,v,#f)
#define THREAD_EXECUTE(m,f,a,v) thread_execute(m,f,a,v,#f)
/* Macros. */
#define THREAD_ARG(X) ((X)->arg)
#define THREAD_FD(X) ((X)->u.fd)
#define THREAD_VAL(X) ((X)->u.val)
#define VTY_BUFSIZ 512
#define VTY_TMP_BUFSIZ 1024
#define VTY_MAXHIST 20
#define TELNET_NAWS_SB_LEN 5
#define VTY_TIMEOUT_VAL 600
/* Vty read buffer size. */
#define VTY_READ_BUFSIZ 512
/* Small macro to determine newline is newline only or linefeed needed. */
#define VTY_NEWLINE ((vty->type == VTY_TERM) ? "\r\n" : "\n")
#define CONTROL(X) ((X) - '@')
#define VTY_NO_ESCAPE 0
#define VTY_PRE_ESCAPE 1
#define VTY_ESCAPE 2
#define VTY_USERNAME_LEN 32
#define VTY_USERNAME_DEFAULT "ld"
#define VTY_PASSWORD_DEFAULT "1"
/* Exported types ------------------------------------------------------------*/
/* buffer数据结构体. 必须保证: 0 <= sp <= cp <= size. */
typedef struct _buf_data
{
struct _buf_data *next; /* 数据链表. */
size_t cp; /* 当前可以添加的数据索引. */
size_t sp; /* 等待数据发送的数据索引. */
unsigned char data[]; /* 数据空间. */
} buf_data_t;
/* Buffer结构体. */
typedef struct _buf
{
buf_data_t *head; /* 数据块头. */
buf_data_t *tail; /* 数据块尾. */
size_t size; /* 每个数据块的大小. */
} buf_t;
typedef int hash_key_f(void*);
typedef void* hash_alloc_f(void *);
typedef int hash_cmp_f(const void*, const void*);
typedef struct _hash_backet
{
struct _hash_backet *next; /* Linked list. */
unsigned int key; /* Hash key. */
void *data; /* Data. */
} hash_backet_t;
typedef struct _hash
{
hash_backet_t **index; /* Hash backet. */
unsigned int size; /* Hash table size. */
hash_key_f *hash_key; /* Key make function. */
hash_cmp_f *hash_cmp; /* Data compare function. */
unsigned long count; /* Backet alloc. */
} hash_t;
typedef unsigned char thread_type;
typedef struct _rusage
{
struct rusage cpu;
struct timeval real;
} rusage_t;
typedef struct _time_stats
{
unsigned long total, max;
} time_stats_t;
typedef struct _cpu_thread_history
{
int (*func)(void*);
char *funcname;
unsigned int total_calls;
time_stats_t real;
time_stats_t cpu;
thread_type types;
} cpu_thread_history_t;
/* Linked list of thread. */
typedef struct _thread_list
{
struct _thread *head;
struct _thread *tail;
int count;
} thread_list_t;
/* Master of the theads. */
typedef struct _thread_master
{
thread_list_t read;
thread_list_t write;
thread_list_t timer;
thread_list_t event;
thread_list_t ready;
thread_list_t unuse;
thread_list_t background;
fd_set readfd;
fd_set writefd;
fd_set exceptfd;
unsigned long alloc;
} thread_master_t;
/* Thread itself. */
typedef struct _thread
{
thread_type type; /* thread type */
thread_type add_type; /* thread type */
struct _thread *next; /* next pointer of the thread */
struct _thread *prev; /* previous pointer of the thread */
thread_master_t *master; /* pointer to the struct thread_master. */
int (*func)(struct _thread*); /* event function */
void *arg; /* event argument */
union
{
int val; /* second argument of the event. */
int fd; /* file descriptor in case of read/write. */
struct timeval sands; /* rest of time sands value. */
} u;
RUSAGE_T ru; /* Indepth usage info. */
cpu_thread_history_t *hist; /* cache pointer to cpu_history */
char* funcname;
} thread_t;
typedef int thread_func_f(thread_t*);
typedef enum {VTY_TERM, VTY_FILE, VTY_SHELL, VTY_SHELL_SERV} VTY_TYPE_E;
typedef enum {VTY_NORMAL, VTY_CLOSE, VTY_MORE, VTY_MORELINE} VTY_STAT_E;
/* Vty events */
typedef enum
{
VTY_SERV,
VTY_READ,
VTY_WRITE,
VTY_TIMEOUT_RESET,
#if 0
VTYSH_SERV,
VTYSH_READ,
VTYSH_WRITE
#endif /* VTYSH */
} VTY_EVENT_E;
/* 用户结构体 */
typedef struct
{
char username[VTY_USERNAME_LEN];
char password[VTY_USERNAME_LEN];
uint8_t level; /* 用户等级 */
} vty_user_t;
/* VTY struct. */
typedef struct
{
int fd; /* File descripter of this vty. */
VTY_TYPE_E type; /* Is this vty connect to file or not */
uint32_t node; /* Node status of this vty */
char *address; /* What address is this vty comming from. */
uint32_t fail_count; /* Failure count */
buf_t *out_buf; /* Output buffer. */
char *buf; /* Command input buffer */
uint32_t cp; /* Command cursor point */
uint32_t length; /* Command length */
uint32_t max; /* Command max length. */
char *hist[VTY_MAXHIST]; /* Histry of command */
uint32_t hp; /* History lookup current point */
uint32_t hindex; /* History insert end point */
void *index; /* For current referencing point of interface, route-map, access-list etc... */
void *index_sub; /* For multiple level index treatment such as key chain and key. */
unsigned char escape; /* For escape character. */
VTY_STAT_E status; /* Current vty status. */
/* IAC handling: was the last character received the
IAC (interpret-as-command) escape character (and therefore the next
character will be the command code)? Refer to Telnet RFC 854. */
unsigned char iac;
unsigned char iac_sb_in_progress; /* IAC SB (option subnegotiation) handling */
/* At the moment, we care only about the NAWS (window size) negotiation,
and that requires just a 5-character buffer (RFC 1073):
<NAWS char> <16-bit width> <16-bit height> */
unsigned char sb_buf[TELNET_NAWS_SB_LEN];
/* How many subnegotiation characters have we received? We just drop
those that do not fit in the buffer. */
size_t sb_len;
uint32_t width; /* Window width/height. */
uint32_t height;
int32_t lines; /* Configure lines. */
int32_t monitor; /* Terminal monitor. */
int config; /* In configure mode. */
/* Read and write thread. */
thread_t *t_read;
thread_t *t_write;
/* Timeout seconds and thread. */
unsigned long v_timeout;
thread_t *t_timeout;
/* Timeout seconds and thread. */
vty_user_t user;
} vty_t;
/* Exported macro ------------------------------------------------------------*/
/* Extern global variables ---------------------------------------------------*/
/* Extern functions ----------------------------------------------------------*/
extern void *hash_get(hash_t *hash, void *data, hash_alloc_f alloc_func);
extern unsigned long thread_consumed_time(RUSAGE_T *now,RUSAGE_T *start, unsigned long *cputime);
extern thread_master_t *thread_master_create();
extern void thread_call(thread_t *thread);
extern thread_t *thread_add_read(thread_master_t *m, thread_func_f *func, void *arg, int fd, const char* funcname);
extern thread_t *thread_add_write(thread_master_t *m, thread_func_f *func, void *arg, int fd, const char* funcname);
extern thread_t *thread_add_timer(thread_master_t *m, thread_func_f *func, void *arg, long timer, const char* funcname);
extern thread_t *thread_add_timer_msec(thread_master_t *m, thread_func_f *func, void *arg, long timer, const char* funcname);
extern thread_t *thread_add_background(thread_master_t *m, thread_func_f *func, void *arg, long delay, const char *funcname);
extern thread_t *thread_add_event(thread_master_t *m, thread_func_f *func, void *arg, int val, const char* funcname);
extern thread_t *thread_execute(thread_master_t *m, thread_func_f *func, void *arg, int val, const char* funcname);
extern void thread_cancel(thread_t *thread);
extern thread_t *thread_fetch(thread_master_t *m, thread_t *fetch);
extern int vty_out(vty_t *vty, const char *format, ...);
extern vty_t *vty_create();
extern int vty_execute(vty_t *vty);
extern int vty_config_lock(vty_t *vty);
extern int vty_config_unlock(vty_t *vty);
extern void vty_question(vty_t *vty, array_t *cmd_line);
extern void vty_print_word(vty_t *vty, char *strs[]);
extern void vty_free_match_strs(char *match_strs[]);
extern void vty_will_echo(vty_t *vty);
extern void vty_will_suppress_go_ahead(vty_t *vty);
extern void vty_dont_linemode(vty_t *vty);
extern void vty_do_window_size(vty_t *vty);
extern void vty_prompt(vty_t *vty);
extern void vty_close(vty_t *vty);
extern void vty_init(void);
extern void vty_event(VTY_EVENT_E event, int sock, vty_t *vty);
extern void vty_log(const char *level, const char *proto_str, const char *format, char *time_str, va_list va);
extern void vty_print(const char *format, va_list va);
extern void vty_serv_sock_family(const char* addr, unsigned short port, int family);
extern void vty_reset(void);
extern void vty_version_print(vty_t *vty);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,3 @@
local_src := $(patsubst $(SOURCE_DIR)/%,%,$(wildcard $(SOURCE_DIR)/$(subdirectory)/*.c))
$(eval $(call make-library,$(subdirectory)/liba_process.a,$(local_src)))

@ -0,0 +1,305 @@
/******************************************************************************
* file lib/process/pd_cpld.c
* author YuLiang
* version 1.0.0
* date 31-July-2023
* brief This file provides all the CPLD operation functions.
*
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2023 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* 标准C库头文件. */
/* 用户代码头文件. */
#include "cmd.h"
#include "hwgpio.h"
#include "pd_cpld.h"
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
#define CPLD_CS_1 gpio_val_set(cpld_cs_idx, 1)
#define CPLD_CS_0 gpio_val_set(cpld_cs_idx, 0)
#define CPLD_SCLK_1 gpio_val_set(cpld_sclk_idx, 1)
#define CPLD_SCLK_0 gpio_val_set(cpld_sclk_idx, 0)
#define CPLD_MOSI_1 gpio_val_set(cpld_mosi_idx, 1)
#define CPLD_MOSI_0 gpio_val_set(cpld_mosi_idx, 0)
#define CPLD_MISO_READ(_val_) gpio_val_get(cpld_miso_idx, _val_)
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
cpld_version_t cpld_version;
static pthread_mutex_t cpld_mutex; // 多线程同时操作的信号量.
static int32_t cpld_cs_idx;
static int32_t cpld_sclk_idx;
static int32_t cpld_mosi_idx;
static int32_t cpld_miso_idx;
/* Private function prototypes -----------------------------------------------*/
/* 读取 CPLD 寄存器. */
CMD(cpld_reg_read,
cpld_reg_read_cmd,
"cpld read WORD",
"CPLD\n"
"CPLD register read.\n"
"Register address (HH)\n")
{
return CMD_SUCCESS;
uint16_t reg = 0;
uint16_t temp = 0;
char* str = NULL;
reg = strtol(argv[0], &str, 16);
if (*str != '\0')
{
return CMD_ERR_NO_MATCH;
}
cpld_read(reg, 1, &temp);
vty_out(vty, "Read reg 0x%02x value: 0x%04x%s\n", reg, temp, VTY_NEWLINE);
return CMD_SUCCESS;
}
/* 写 CPLD 寄存器. */
CMD(cpld_reg_write,
cpld_reg_write_cmd,
"cpld write WORD WORD",
"CPLD\n"
"CPLD register write\n"
"Register address (HH)\n"
"Value (HHHH)\n")
{
return CMD_SUCCESS;
uint16_t reg = 0;
uint16_t temp = 0;
char* str = NULL;
reg = strtol(argv[0], &str, 16);
if (*str != '\0')
{
return CMD_ERR_NO_MATCH;
}
temp = strtol(argv[1], &str, 16);
if (*str != '\0')
{
return CMD_ERR_NO_MATCH;
}
cpld_write(reg, 1, &temp);
vty_out(vty, "Write reg 0x%02x value: 0x%04x%s", reg, temp, VTY_NEWLINE);
cpld_read(reg, 1, &temp);
vty_out(vty, "Read reg 0x%02x value: 0x%04x%s\n", reg, temp, VTY_NEWLINE);
return CMD_SUCCESS;
}
/* 显示 CPLD 信息. */
CMD(show_cpld,
show_cpld_cmd,
"show cpld",
SHOW_STR
"CPLD\n")
{
return CMD_SUCCESS;
vty_out(vty, "Version: %04x-%02x-%02x%s\n", cpld_version.year, cpld_version.month, cpld_version.day, VTY_NEWLINE);
return CMD_SUCCESS;
}
//SPI可以同时读取和写入数据因此一个函数即可满足要求
int32_t _cpld_half_word_write(uint16_t data)
{
uint8_t i = 0;
for(i = 0; i < 16; i++)
{
if(data & 0x8000)
{
CPLD_MOSI_1;
}
else
{
CPLD_MOSI_0;
}
data <<= 1;
CPLD_SCLK_1;
CPLD_SCLK_0;
}
return E_NONE;
}
//SPI可以同时读取和写入数据因此一个函数即可满足要求
int32_t _cpld_half_word_read(uint16_t *data)
{
uint8_t i = 0;
uint8_t gpio_val = 0;
uint16_t data_rx = 0;
for(i = 0; i < 16; i++)
{
CPLD_SCLK_1;
data_rx <<= 1;
CPLD_MISO_READ(&gpio_val);
if (gpio_val)
{
data_rx |= 0x01;
}
CPLD_SCLK_0;
}
*data = data_rx;
return E_NONE;
}
/* Internal functions --------------------------------------------------------*/
/* Interface functions -------------------------------------------------------*/
/* CPLD 模块初始化代码. */
int32_t cpld_handle_init(void)
{
uint16_t temp = 0;
#if 0
/* 申请信号量, 防止多个线程同时操作 fifo. */
if (pthread_mutex_init(&cpld_mutex, NULL) != 0)
{
DBG(DBG_M_FIFO_ERR, "ERROR at mutex init return %s!\r\n", safe_strerror(errno));
return E_SYS_CALL;
}
/* 申请 GPIO. */
cpld_cs_idx = gpio_export(GPIO_CPLD_CS);
if (cpld_cs_idx < 0)
{
DBG(DBG_M_PD_CPLD, "ERROR return %d!\r\n", cpld_cs_idx);
return E_BAD_PARAM;
}
LD_E_RETURN(DBG_M_PD_CPLD, gpio_dir_set(cpld_cs_idx, GPIO_DIR_OUT));
cpld_sclk_idx = gpio_export(GPIO_CPLD_SCLK);
if (cpld_sclk_idx < 0)
{
DBG(DBG_M_PD_CPLD, "ERROR return %d!\r\n", cpld_sclk_idx);
return E_BAD_PARAM;
}
LD_E_RETURN(DBG_M_PD_CPLD, gpio_dir_set(cpld_sclk_idx, GPIO_DIR_OUT));
cpld_mosi_idx = gpio_export(GPIO_CPLD_MOSI);
if (cpld_mosi_idx < 0)
{
DBG(DBG_M_PD_CPLD, "ERROR return %d!\r\n", cpld_mosi_idx);
return E_BAD_PARAM;
}
LD_E_RETURN(DBG_M_PD_CPLD, gpio_dir_set(cpld_mosi_idx, GPIO_DIR_OUT));
cpld_miso_idx = gpio_export(GPIO_CPLD_MISO);
if (cpld_miso_idx < 0)
{
DBG(DBG_M_PD_CPLD, "ERROR return %d!\r\n", cpld_miso_idx);
return E_BAD_PARAM;
}
LD_E_RETURN(DBG_M_PD_CPLD, gpio_dir_set(cpld_miso_idx, GPIO_DIR_IN));
CPLD_CS_1;
CPLD_SCLK_0;
/* 获取版本号. */
cpld_read(CPLD_REG_V0, 1, &temp);
cpld_version.year = temp;
cpld_read(CPLD_REG_V1, 1, &temp);
cpld_version.month = temp >> 8;
cpld_version.day = temp & 0x00ff;
#endif
/* 注册命令. */
cmd_install_element(COMMON_NODE, &show_cpld_cmd);
cmd_install_element(ENABLE_NODE, &cpld_reg_read_cmd);
cmd_install_element(ENABLE_NODE, &cpld_reg_write_cmd);
return E_NONE;
}
int32_t cpld_read(uint16_t addr, uint16_t len, uint16_t *data)
{
int32_t i = 0;
pthread_mutex_lock(&cpld_mutex);
CPLD_CS_0;
_cpld_half_word_write(0x8000 | addr);
for(i = 0; i < len; i++)
{
_cpld_half_word_read(data + i);
}
CPLD_CS_1;
pthread_mutex_unlock(&cpld_mutex);
return E_NONE;
}
int32_t cpld_write(uint16_t addr, uint16_t len, uint16_t *data)
{
int32_t i = 0;
pthread_mutex_lock(&cpld_mutex);
CPLD_CS_0;
_cpld_half_word_write(0x7fff & addr);
for(i = 0; i < len; i++)
{
_cpld_half_word_write(data[i]);
}
CPLD_CS_1;
pthread_mutex_unlock(&cpld_mutex);
return E_NONE;
}
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

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

@ -0,0 +1,795 @@
/******************************************************************************
* file lib/process/gis.c
* author YuLiang
* version 1.0.0
* date 23-Feb-2023
* brief This file provides all the gis operation functions.
*
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2023 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef CFG_DEV_TYPE_LAND_PD
/* 标准C库头文件. */
/* 用户代码头文件. */
#include "pd_dau.h"
#include "pd_main.h"
/* Private define ------------------------------------------------------------*/
#define GIS_MIN_VALUE PD_GIS_MIN_VALUE // 特高频局放的采集数值下限 -800 (-80.0dBm).
/* Private macro -------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
extern void _gis_prps_default(int16_t *prps);
extern void _gis_prps_denoise(uint8_t unit, uint8_t port);
extern void _gis_prps_denoise_relevance(uint8_t unit, uint8_t port);
extern void _gis_prps_denoise_statistics(uint8_t unit, uint8_t port);
extern void _gis_denoise(uint8_t unit, uint8_t port);
extern void _gis_denoise_relevance(uint8_t unit, uint8_t port);
extern void _gis_denoise_statistics(uint8_t unit, uint8_t port);
extern void _gis_event(uint8_t unit, uint8_t port);
extern void _gis_trend(uint8_t unit, uint8_t port, uint16_t trend_sec);
dau_port_func_t gis_func =
{
_gis_prps_default,
_gis_prps_denoise,
_gis_prps_denoise_relevance,
_gis_prps_denoise_statistics,
_gis_denoise,
_gis_denoise_relevance,
_gis_denoise_statistics,
_gis_event,
_gis_trend
};
/* Internal functions --------------------------------------------------------*/
void _gis_prps_default(int16_t *prps)
{
uint16_t i = 0;
for(i = 0; i < PD_PRPS_NUM; i++)
{
prps[i] = GIS_MIN_VALUE;
}
}
/* 通道的实时数据 (自动 / 手动) 降噪的计算处理 (用于实时PRPS的临时显示使用). */
void _gis_prps_denoise(uint8_t unit, uint8_t port)
{
pd_prps_t *data = pd_data.denoise;
int16_t *buf = NULL;
int16_t *buf_prps = NULL;
uint8_t pf_cnt = 0;
uint8_t i = 0;
uint16_t manual_noise_reduction = 0;
int16_t manual_noise_level = 0;
int16_t noise_level = 0;
int32_t phase_avg = 0;
int32_t temp = 0;
/* 噪声传感器在关联降噪中运算. */
if (PD_SEN_TYPE_NOISE == pd_config.port_config[unit][port].config.sensor_type
|| !pd_config.port_config[unit][port].is_concern
|| !dau[unit]->port_state[port].is_complete)
{
return;
}
/* 非噪声通道处理. */
for(pf_cnt = 0; pf_cnt < PD_POWER_FRE; pf_cnt++)
{
/* 左移 7 位正好是乘以 128(PD_PHASE_NUM). */
buf = &data->data[unit][port].data[pf_cnt << 7];
buf_prps = &dau[unit]->port_state[port].prps[pf_cnt << 7];
phase_avg = 0;
for(i = 0; i < PD_PHASE_NUM; i++)
{
if (buf_prps[i] < GIS_MIN_VALUE)
{
buf[i] = GIS_MIN_VALUE;
}
else
{
buf[i] = buf_prps[i];
}
phase_avg += buf[i];
}
phase_avg = (phase_avg / PD_PHASE_NUM);
noise_level = phase_avg + pd_config.port_config[unit][port].config.noise_reduction; // 普通降噪水平 默认30 单位0.1dBm
dau[unit]->port_state[port].noise_level[pf_cnt] = noise_level; // 局放计数时的比较幅值.
/* 未配置通道类型的不再进行下去. */
if (pd_config.port_config[unit][port].config.sensor_type != PD_SEN_TYPE_SIG
&& pd_config.port_config[unit][port].config.sensor_type != PD_SEN_TYPE_SIG_NOISE)
{
continue;
}
if (pd_config.port_config[unit][port].auto_noise_reduction)
{
/* 自适应降噪. */
temp = phase_avg - GIS_MIN_VALUE;
/* 低于平均值的不显示, 低于普通降噪水平的减去平均值, 余下的原值显示. */
for(i = 0; i < PD_PHASE_NUM; i++)
{
if (buf[i] <= phase_avg)
{
buf[i] = GIS_MIN_VALUE;
}
else if(buf[i] <= noise_level)
{
buf[i] -= temp;
}
}
}
else if(pd_config.port_config[unit][port].manual_noise_reduction)
{
/* 手动降噪. */
manual_noise_reduction = pd_config.port_config[unit][port].manual_noise_reduction;
if (manual_noise_reduction > 800)
{
manual_noise_reduction = 800;
manual_noise_level = 0;
}
else
{
manual_noise_level = GIS_MIN_VALUE + manual_noise_reduction;
}
for(i = 0; i < PD_PHASE_NUM; i++)
{
/* 手动降噪水平小于普通降噪水平, 需要考虑降噪水平, 否则不考虑普通降噪水平. */
if (manual_noise_level < noise_level)
{
/* 低于手动降噪水平的不显示, 低于普通降噪水平的减去手动降噪水平, 余下的原值显示. */
if (buf[i] <= manual_noise_level)
{
buf[i] = GIS_MIN_VALUE;
}
else if( buf[i] <= noise_level)
{
buf[i] -= manual_noise_reduction;
}
}
else
{
/* 低于手动降噪水平的不显示, 余下的原值显示. */
if (buf[i] <= manual_noise_level)
{
buf[i] = GIS_MIN_VALUE;
}
}
}
}
}
}
/* 通道的实时数据关联降噪的计算处理 (用于实时PRPS的临时显示使用). */
void _gis_prps_denoise_relevance(uint8_t unit, uint8_t port)
{
pd_prps_t *data = pd_data.denoise;
int16_t *buf = NULL;
int16_t *buf_prps = NULL;
int16_t *buf_noise = NULL;
uint8_t unit_r = 0; // 关联降噪的单元.
uint8_t port_r = 0; // 关联降噪的端口.
uint8_t pf_cnt = 0;
uint8_t i = 0;
int16_t noise_level = 0;
int32_t phase_avg = 0;
if (pd_config.port_config[unit][port].config.sensor_type != PD_SEN_TYPE_NOISE
|| !dau[unit]->port_state[port].is_complete)
{
return;
}
/* 噪声通道处理. */
for(pf_cnt = 0; pf_cnt < PD_POWER_FRE; pf_cnt++)
{
/* 左移 7 位正好是乘以 128(PD_PHASE_NUM). */
buf = &data->data[unit][port].data[pf_cnt << 7];
buf_prps = &dau[unit]->port_state[port].prps[pf_cnt << 7];
phase_avg = 0;
for(i = 0; i < PD_PHASE_NUM; i++)
{
if (buf_prps[i] < GIS_MIN_VALUE)
{
buf[i] = GIS_MIN_VALUE;
}
else
{
buf[i] = buf_prps[i];
}
phase_avg += buf[i];
}
phase_avg = (phase_avg / PD_PHASE_NUM);
noise_level = phase_avg + pd_config.port_config[unit][port].config.noise_reduction; // 普通降噪水平 默认30 单位0.1dBm
dau[unit]->port_state[port].noise_level[pf_cnt] = noise_level; // 局放计数时的比较幅值.
for(unit_r = 0; unit_r < PD_DAU_SUM; unit_r++)
{
if (!dau[unit_r])
{
continue;
}
for(port_r = 0; port_r < dau[unit_r]->port_num; port_r++)
{
if (!pd_config.port_config[unit_r][port_r].r_noise_reduction
|| !dau[unit_r]->port_state[port_r].is_complete
|| (pd_config.port_config[unit_r][port_r].config.sensor_type != PD_SEN_TYPE_SIG
&& pd_config.port_config[unit_r][port_r].config.sensor_type != PD_SEN_TYPE_SIG_NOISE))
{
continue;
}
buf_noise = &data->data[unit][port].data[pf_cnt << 7];
buf = &data->data[unit_r][port_r].data[pf_cnt << 7];
/* 噪声通道工频内的第一值比噪声通道的平均降噪等级还要大. */
if (buf_noise[0] > noise_level)
{
if (pf_cnt > 0)
{
data->data[unit_r][port_r].data[(pf_cnt << 7) - 1] = GIS_MIN_VALUE;
}
buf[0] = GIS_MIN_VALUE;
buf[1] = GIS_MIN_VALUE;
}
if (buf_noise[PD_PHASE_NUM - 1] > noise_level)
{
if (pf_cnt < 49)
{
buf[PD_PHASE_NUM] = GIS_MIN_VALUE;
}
buf[PD_PHASE_NUM - 1] = GIS_MIN_VALUE;
buf[PD_PHASE_NUM - 2] = GIS_MIN_VALUE;
}
for(i = 1; i < PD_PHASE_NUM - 1; i++)
{
if (buf_noise[i] > noise_level)
{
buf[i-1] = GIS_MIN_VALUE;
buf[i ] = GIS_MIN_VALUE;
buf[i+1] = GIS_MIN_VALUE;
}
}
}
}
}
}
/* 通道的实时数据统计信息 (用于实时 PRPS 的临时显示使用). */
void _gis_prps_denoise_statistics(uint8_t unit, uint8_t port)
{
pd_prps_t *data = pd_data.denoise;
int16_t *buf = NULL;
uint8_t pf_cnt = 0;
uint8_t i = 0;
int16_t noise_level = 0;
uint16_t cnt = 0;
int16_t max = GIS_MIN_VALUE;
int32_t avg = 0;
if (!pd_config.port_config[unit][port].is_concern)
{
return;
}
data->data[unit][port].is_valid = dau[unit]->port_state[port].is_complete;
if (!dau[unit]->port_state[port].is_complete)
{
return;
}
/* 数值的计算 最大值, 平均值, 放电次数. */
for(pf_cnt = 0; pf_cnt < PD_POWER_FRE; pf_cnt++)
{
buf = &data->data[unit][port].data[pf_cnt << 7];
noise_level = dau[unit]->port_state[port].noise_level[pf_cnt];
for(i = 0; i < PD_PHASE_NUM; i++)
{
if (buf[i] > max )
{
max = buf[i];
}
if (buf[i] > noise_level)
{
avg += buf[i];
cnt++;
}
}
}
data->data[unit][port].max = max;
data->data[unit][port].cnt = cnt;
data->data[unit][port].avg = cnt ? avg / cnt : GIS_MIN_VALUE;
}
/* 通道的实时数据 (自动 / 手动) 降噪的计算处理. */
void _gis_denoise(uint8_t unit, uint8_t port)
{
pd_prps_t *data = &pd_data.real;
int16_t *buf = NULL;
int16_t *buf_real = NULL;
uint8_t pf_cnt = 0;
uint8_t i = 0;
uint16_t manual_noise_reduction = 0;
int16_t manual_noise_level = 0;
int16_t noise_level = 0;
int32_t avg = 0;
int32_t phase_avg = 0;
int32_t temp = 0;
/* 噪声传感器在关联降噪中运算. */
if (PD_SEN_TYPE_NOISE == pd_config.port_config[unit][port].config.sensor_type)
{
return;
}
for(pf_cnt = 0; pf_cnt < PD_POWER_FRE; pf_cnt++)
{
/* 计算平均值. */
buf = &dau[unit]->port_state[port].prps[pf_cnt << 7];
buf_real = &data->data[unit][port].data[pf_cnt << 7];
phase_avg = 0;
for(i = 0; i < PD_PHASE_NUM; i++)
{
if (buf[i] < GIS_MIN_VALUE)
{
buf_real[i] = GIS_MIN_VALUE;
}
else
{
buf_real[i] = buf[i];
}
phase_avg += buf_real[i];
}
avg += phase_avg;
phase_avg = (phase_avg / PD_PHASE_NUM);
noise_level = phase_avg + pd_config.port_config[unit][port].config.noise_reduction; // 普通降噪水平 默认30 单位0.1dBm
/* 未配置通道类型的不再进行下去. */
if (pd_config.port_config[unit][port].config.sensor_type != PD_SEN_TYPE_SIG
&& pd_config.port_config[unit][port].config.sensor_type != PD_SEN_TYPE_SIG_NOISE)
{
continue;
}
/* 降噪处理. */
if (100 == pd_config.port_config[unit][port].config.env_noise) // 自动降噪.
{
temp = phase_avg - GIS_MIN_VALUE;
/* 低于平均值的不显示, 低于普通降噪水平的减去平均值, 余下的原值显示. */
for(i = 0; i < PD_PHASE_NUM; i++)
{
if (buf_real[i] <= phase_avg)
{
buf_real[i] = GIS_MIN_VALUE;
}
else if(buf_real[i] <= noise_level)
{
buf_real[i] -= temp;
}
}
}
else if(0 == pd_config.port_config[unit][port].config.env_noise) // 不降噪.
{
NULL;
}
else // 人工降噪.
{
manual_noise_reduction = pd_config.port_config[unit][port].config.env_noise;
if (manual_noise_reduction > 800)
{
manual_noise_reduction = 800;
manual_noise_level = 0;
}
else
{
manual_noise_level = GIS_MIN_VALUE + manual_noise_reduction;
}
for(i = 0; i < PD_PHASE_NUM; i++)
{
/* 手动降噪水平小于普通降噪水平, 需要考虑降噪水平, 否则不考虑普通降噪水平. */
if (manual_noise_level < noise_level)
{
/* 低于手动降噪水平的不显示, 低于普通降噪水平的减去手动降噪水平, 余下的原值显示. */
if (buf_real[i] <= manual_noise_level)
{
buf_real[i] = GIS_MIN_VALUE;
}
else if( buf_real[i] <= noise_level)
{
buf_real[i] -= manual_noise_reduction;
}
}
else
{
/* 低于手动降噪水平的不显示, 余下的原值显示. */
if (buf_real[i] <= manual_noise_level)
{
buf_real[i] = GIS_MIN_VALUE;
}
}
}
}
}
/* 数据统计. */
data->data[unit][port].avg_o = avg / PD_PRPS_NUM;
}
/* 通道的实时数据关联降噪的计算处理. */
void _gis_denoise_relevance(uint8_t unit, uint8_t port)
{
pd_prps_t *data = &pd_data.real;
int16_t *buf = NULL;
int16_t *buf_real = NULL;
int16_t *buf_noise = NULL;
uint8_t unit_r = 0; // 关联降噪的单元.
uint8_t port_r = 0; // 关联降噪的端口.
uint8_t pf_cnt = 0;
uint8_t i = 0;
int16_t noise_level = 0;
int32_t avg = 0;
int32_t phase_avg = 0;
if (pd_config.port_config[unit][port].config.sensor_type != PD_SEN_TYPE_NOISE)
{
return;
}
/* 噪声通道处理. */
for(pf_cnt = 0; pf_cnt < PD_POWER_FRE; pf_cnt++)
{
/* 左移 7 位正好是乘以 128(PD_PHASE_NUM). */
buf = &dau[unit]->port_state[port].prps[pf_cnt << 7];
buf_real = &data->data[unit][port].data[pf_cnt << 7];
phase_avg = 0;
for(i = 0; i < PD_PHASE_NUM; i++)
{
if (buf[i] < GIS_MIN_VALUE)
{
buf_real[i] = GIS_MIN_VALUE;
}
else
{
buf_real[i] = buf[i];
}
phase_avg += buf[i];
}
avg += phase_avg;
phase_avg = (phase_avg / PD_PHASE_NUM);
noise_level = phase_avg + pd_config.port_config[unit][port].config.noise_reduction; // 普通降噪水平 默认30 单位0.1dBm
for(unit_r = 0; unit_r < PD_DAU_SUM; unit_r++)
{
if (!dau[unit_r])
{
continue;
}
for(port_r = 0; port_r < dau[unit_r]->port_num; port_r++)
{
if (pd_config.port_config[unit_r][port_r].config.sensor_type != PD_SEN_TYPE_SIG_NOISE)
{
continue;
}
buf_noise = &data->data[unit][port].data[pf_cnt << 7];
buf = &data->data[unit_r][port_r].data[pf_cnt << 7];
/* 噪声通道工频内的第一值比噪声通道的平均降噪等级还要大. */
if (buf_noise[0] > noise_level)
{
if (pf_cnt > 0)
{
data->data[unit_r][port_r].data[(pf_cnt << 7) - 1] = GIS_MIN_VALUE;
}
buf[0] = GIS_MIN_VALUE;
buf[1] = GIS_MIN_VALUE;
}
if (buf_noise[PD_PHASE_NUM - 1] > noise_level)
{
if (pf_cnt < 49)
{
buf[PD_PHASE_NUM] = GIS_MIN_VALUE;
}
buf[PD_PHASE_NUM - 1] = GIS_MIN_VALUE;
buf[PD_PHASE_NUM - 2] = GIS_MIN_VALUE;
}
for(i = 1; i < PD_PHASE_NUM - 1; i++)
{
if (buf_noise[i] > noise_level)
{
buf[i-1] = GIS_MIN_VALUE;
buf[i ] = GIS_MIN_VALUE;
buf[i+1] = GIS_MIN_VALUE;
}
}
}
}
}
/* 数据统计. */
data->data[unit][port].avg_o = avg / PD_PRPS_NUM;
}
/* 通道的实时数据统计信息. */
void _gis_denoise_statistics(uint8_t unit, uint8_t port)
{
pd_prps_data_t *real_data = &pd_data.real.data[unit][port];
int16_t *buf = NULL;
int16_t noise_level = 0;
int32_t avg = 0;
uint8_t pf_cnt = 0;
uint8_t i = 0;
/* 初始化原始值. */
if (pd_config.port_config[unit][port].config.env_noise > 0)
{
noise_level = GIS_MIN_VALUE + pd_config.port_config[unit][port].config.noise_reduction;
}
else
{
noise_level = -790;
}
real_data->max = GIS_MIN_VALUE;
real_data->cnt = 0;
for(i = 0; i < PD_PHASE_NUM; i++)
{
real_data->phase_max[i] = GIS_MIN_VALUE;
real_data->phase_sum[i] = 0;
real_data->phase_cnt[i] = 0;
}
/* 数值的计算 最大值, 平均值, 放电次数. */
for(pf_cnt = 0; pf_cnt < PD_POWER_FRE; pf_cnt++)
{
buf = &real_data->data[pf_cnt << 7];
for(i = 0; i < PD_PHASE_NUM; i++)
{
if (buf[i] > real_data->phase_max[i])
{
real_data->phase_max[i] = buf[i];
}
if (buf[i] > noise_level)
{
real_data->phase_sum[i] += buf[i];
real_data->phase_cnt[i]++;
}
}
}
for(i = 0; i < PD_PHASE_NUM; i++)
{
if (real_data->phase_max[i] > real_data->max)
{
real_data->max = real_data->phase_max[i];
}
if (real_data->phase_cnt[i])
{
avg += real_data->phase_sum[i];
real_data->cnt += real_data->phase_cnt[i];
}
real_data->phase_avg[i] = real_data->phase_cnt[i] ? real_data->phase_sum[i] / real_data->phase_cnt[i] : GIS_MIN_VALUE;
}
real_data->avg = real_data->cnt ? avg / real_data->cnt : GIS_MIN_VALUE;
}
/* 通道事件计算. */
void _gis_event(uint8_t unit, uint8_t port)
{
pd_prps_data_t *real_data = &pd_data.real.data[unit][port];
pd_event_t *event = &pd_data.event[unit][port];
int16_t *buf = NULL;
int16_t event_thr = 0;
uint8_t pf_cnt = 0;
uint8_t i = 0;
/* 只处理信号传感器. */
if (pd_config.port_config[unit][port].config.sensor_type != PD_SEN_TYPE_SIG
&& pd_config.port_config[unit][port].config.sensor_type != PD_SEN_TYPE_SIG_NOISE)
{
return;
}
event_thr = pd_config.port_config[unit][port].config.event_threshold + real_data->avg_o;
event->max = GIS_MIN_VALUE;
event->avg = 0;
event->cnt = 0;
for(i = 0; i < PD_PHASE_NUM; i++)
{
event->phase_max[i] = GIS_MIN_VALUE;
event->phase_sum[i] = 0;
event->phase_cnt[i] = 0;
}
/* 计算超过阈值的放电次数. */
for(pf_cnt = 0; pf_cnt < PD_POWER_FRE; pf_cnt++)
{
buf = &real_data->data[pf_cnt << 7];
for(i = 0; i < PD_PHASE_NUM; i++)
{
if (buf[i] > event->phase_max[i])
{
event->phase_max[i] = buf[i];
}
if (buf[i] > event_thr)
{
event->phase_sum[i] += buf[i];
event->phase_cnt[i]++;
}
}
}
for(i = 0; i < PD_PHASE_NUM; i++)
{
if (event->phase_max[i] > event->max)
{
event->max = event->phase_max[i];
}
event->avg += event->phase_sum[i];
event->cnt += event->phase_cnt[i];
event->phase_avg[i] = event->phase_cnt[i] ? event->phase_sum[i] / event->phase_cnt[i] : GIS_MIN_VALUE;
}
event->avg = event->cnt ? event->avg / event->cnt : GIS_MIN_VALUE;
}
void _gis_trend(uint8_t unit, uint8_t port, uint16_t trend_sec)
{
pd_trend_data_t *trend_data = &pd_data.trend.data[unit][port];
pd_prps_data_t *real_data = &pd_data.real.data[unit][port];
dau_t *dau_node = dau[unit];
int64_t phase_cmp = 0x8000000000000000;
uint8_t phase_cmp_idx = 0;
uint8_t i = 0;
/* 初始化数据. */
if (1 == trend_sec)
{
pd_data.trend.index = dau_ctrl.trend_idx++;
pd_data.trend.utc = pd_data.real.utc;
trend_data->noise = 0;
trend_data->max = GIS_MIN_VALUE;
trend_data->avg = 0;
trend_data->cnt = 0;
for(i = 0; i < PD_PHASE_NUM; i++)
{
trend_data->phase_sum[i] = 0;
trend_data->phase_max[i] = GIS_MIN_VALUE;
trend_data->phase_cnt[i] = 0;
}
}
/* 填充数据. */
for(i = 0; i < PD_PHASE_NUM; i++)
{
if (real_data->phase_cnt[i])
{
trend_data->phase_sum[i] += real_data->phase_sum[i];
trend_data->phase_cnt[i] += real_data->phase_cnt[i];
trend_data->avg += real_data->phase_sum[i];
trend_data->cnt += real_data->phase_cnt[i];
}
if (real_data->phase_max[i] > trend_data->phase_max[i])
{
trend_data->phase_max[i] = real_data->phase_max[i];
}
if (real_data->phase_max[i] > trend_data->max)
{
trend_data->max = real_data->phase_max[i];
}
}
trend_data->noise += real_data->avg_o;
/* 计算数据. */
if (trend_sec >= pd_config.config.trend_period * 60)
{
for(i = 0; i < PD_PHASE_NUM; i++)
{
trend_data->phase_avg[i] = trend_data->phase_cnt[i] ? trend_data->phase_sum[i] / trend_data->phase_cnt[i] : GIS_MIN_VALUE;
/* 查找最大放电周期. */
if (trend_data->phase_cnt[i] && trend_data->phase_sum[i] > phase_cmp)
{
phase_cmp_idx = i;
phase_cmp = trend_data->phase_sum[i];
}
}
trend_data->phase = 360 * phase_cmp_idx / PD_PHASE_NUM ; // 放电相位
trend_data->avg = trend_data->cnt ? trend_data->avg / trend_data->cnt : GIS_MIN_VALUE;
trend_data->cnt = trend_data->cnt / trend_sec; // 每秒钟的脉冲计数值
trend_data->noise = trend_data->noise / (10 * trend_sec) ; // 趋势数据中的底噪值: 单位 dBm.
trend_data->event_cnt = dau_ctrl.event_index[unit][port] - dau_ctrl.trend_event_index[unit][port];
/* 更新索引. */
dau_ctrl.trend_event_index[unit][port] = dau_ctrl.event_index[unit][port];
}
}
/* Interface functions -------------------------------------------------------*/
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,649 @@
/*****************************************************************************
* file lib/process/pd_main.c
* author YuLiang
* version 1.0.0
* date 07-Feb-2023
* brief This file provides all the partial discharge related operation functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef CFG_DEV_TYPE_LAND_PD
/* 标准C库头文件. */
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "pd_cpld.h"
#include "pd_dau.h"
#include "pd_csg.h"
#include "pd_main.h"
#include "pd_storage.h"
#include "pd_dbg.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
pd_data_t pd_data;
pd_config_t pd_config;
pd_state_t pd_state;
cmd_node_t pd_port_node =
{
PORT_NODE,
CONFIG_NODE,
1,
NULL,
};
/* DAU 端口类型分类. */
static const char *pd_sen_type_str[PD_SEN_TYPE_COUNT] =
{
"",
"sig",
"noise",
"sig-noise"
};
/* Private function prototypes -----------------------------------------------*/
extern int32_t _pd_port_str_to_unit_port(const char *port_str, uint8_t *unit, uint8_t *port);
/* Internal functions --------------------------------------------------------*/
/* 进入 DAU 端口模式. */
CMD(pd_port_terminal,
pd_port_terminal_cmd,
"interface port WORD",
"Interface\n"
"Port\n"
"Port id: Ex: 1/1\n")
{
return CMD_SUCCESS;
uint8_t unit = 0;
uint8_t port = 0;
int32_t vport = 0;
/* 取出端口号. */
if (_pd_port_str_to_unit_port(argv[0], &unit, &port) != E_NONE)
{
return CMD_ERR_NO_MATCH;
}
/* 计算虚拟端口. */
vport = dau_port_to_vport(unit, port);
if (vport <= 0)
{
return CMD_ERR_NO_MATCH;
}
pd_port_node.param_num = vport;
snprintf(pd_port_node.prompt, PD_PORT_PROMPT_LEN, "%%s(interface port %d/%d)# ", unit + 1, port + 1);
vty->node = PORT_NODE;
return CMD_SUCCESS;
}
/* 配置端口类型. */
CMD(pd_sensor_type,
pd_sensor_type_cmd,
"sensor-type (sig|noise|sig-noise)",
"Sensor type\n"
"Signal\n"
"Noise\n"
"Signal associate noise\n")
{
return CMD_SUCCESS;
uint8_t sen_type = 0;
uint8_t unit = 0;
uint8_t port = 0;
/* 取出端口号. */
if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE)
{
return CMD_ERR_NO_MATCH;
}
for(sen_type = PD_SEN_TYPE_SIG; sen_type < PD_SEN_TYPE_COUNT; sen_type++)
{
if (strncmp(argv[0], pd_sen_type_str[sen_type], strlen(pd_sen_type_str[sen_type])))
{
continue;
}
pd_config.port_config[unit][port].config.sensor_type = sen_type;
}
return CMD_SUCCESS;
}
/* 配置端口降噪等级. */
CMD(pd_noise_reduction,
pd_noise_reduction_cmd,
"noise-reduction <0-800>",
"Noise reduction\n"
"Noise reduction unit: 0.1dBm\n")
{
return CMD_SUCCESS;
uint8_t unit = 0;
uint8_t port = 0;
/* 取出端口号. */
if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE)
{
return CMD_ERR_NO_MATCH;
}
pd_config.port_config[unit][port].config.noise_reduction = strtol(argv[0], NULL, 10);
return CMD_SUCCESS;
}
/* 配置端口降噪等级. */
CMD(pd_noise_env,
pd_noise_env_cmd,
"noise-env <0-100>",
"Noise environment\n"
"Noise environment unit: dBm\n")
{
return CMD_SUCCESS;
uint8_t unit = 0;
uint8_t port = 0;
/* 取出端口号. */
if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE)
{
return CMD_ERR_NO_MATCH;
}
pd_config.port_config[unit][port].config.env_noise = strtol(argv[0], NULL, 10);
return CMD_SUCCESS;
}
/* 事件阈值. */
CMD(pd_evnet_thr,
pd_evnet_thr_cmd,
"evnet-thr <0-800>",
"Event threshold\n"
"Threshold: 0.1dBm\n")
{
return CMD_SUCCESS;
uint8_t unit = 0;
uint8_t port = 0;
/* 取出端口号. */
if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE)
{
return CMD_ERR_NO_MATCH;
}
pd_config.port_config[unit][port].config.event_threshold = strtol(argv[0], NULL, 10);
return CMD_SUCCESS;
}
/* 通道滤波类型. */
CMD(pd_evnet_cnt,
pd_evnet_cnt_cmd,
"evnet-cnt <1-1000>",
"Event conut threshold\n"
"Conut threshold\n")
{
return CMD_SUCCESS;
uint8_t unit = 0;
uint8_t port = 0;
/* 取出端口号. */
if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE)
{
return CMD_ERR_NO_MATCH;
}
pd_config.port_config[unit][port].config.event_counter = strtol(argv[0], NULL, 10);;
return CMD_SUCCESS;
}
/* 实时数据上传间隔. */
CMD(pd_real_interval,
pd_real_interval_cmd,
"real-interval <1-60>",
"Real data interval\n"
"Interval time: min\n")
{
return CMD_SUCCESS;
pd_config.config.real_period = strtol(argv[0], NULL, 10);
return CMD_SUCCESS;
}
/* 趋势数据上传间隔. */
CMD(pd_trend_interval,
pd_trend_interval_cmd,
"trend-interval <1-60>",
"Trend data interval\n"
"Interval time: min\n")
{
return CMD_SUCCESS;
pd_config.config.trend_period = strtol(argv[0], NULL, 10);
return CMD_SUCCESS;
}
/* 心跳上传间隔. */
CMD(pd_heartbeat_interval,
pd_heartbeat_interval_cmd,
"heartbeat-interval <1-60>",
"heartbeat interval\n"
"Interval time: min\n")
{
return CMD_SUCCESS;
pd_config.config.heartbeat_period = strtol(argv[0], NULL, 10);
return CMD_SUCCESS;
}
/* 同步模式. */
CMD(pd_sync_mode,
pd_sync_mode_cmd,
"sync-mode (pt|power|outside)",
"Synchronize mode\n"
"PT\n"
"Power\n"
"Outside")
{
return CMD_SUCCESS;
uint8_t mode = 0;
if (0 == strncmp(argv[0], "pt", 2))
{
mode = PD_SYNC_PT;
}
else if (0 == strncmp(argv[0], "power", 5))
{
mode = PD_SYNC_POWER;
}
else if (0 == strncmp(argv[0], "outside", 5))
{
mode = PD_SYNC_OUTSIDE;
}
else
{
mode = 0;
}
pd_config.config.sync_mode = mode;
pd_sync_mode_set();
return CMD_SUCCESS;
}
/* 显示 DAU 状态. */
CMD(show_prps,
show_prps_cmd,
"show prps",
"Show\n"
"PRPS\n")
{
return CMD_SUCCESS;
pd_prps_show();
return CMD_SUCCESS;
}
/* 显示 DAU 状态. */
CMD(show_pd,
show_pd_cmd,
"show pd",
"Show\n"
"Partial discharge\n")
{
return CMD_SUCCESS;
pd_show();
return CMD_SUCCESS;
}
/* 配置保存函数. */
int _pd_config_save(vty_t* vty)
{
int16_t i = 0;
vty_out(vty, "trend-interval %d%s", pd_config.config.trend_period, VTY_NEWLINE);
i++;
vty_out(vty, "real-interval %d%s", pd_config.config.real_period, VTY_NEWLINE);
i++;
vty_out(vty, "heartbeat-interval %d%s", pd_config.config.heartbeat_period, VTY_NEWLINE);
i++;
switch(pd_config.config.sync_mode)
{
case PD_SYNC_PT:
vty_out(vty, "sync-mode pt%s", VTY_NEWLINE);
i++;
break;
case PD_SYNC_POWER:
vty_out(vty, "sync-mode power%s", VTY_NEWLINE);
i++;
break;
case PD_SYNC_OUTSIDE:
vty_out(vty, "sync-mode outside%s", VTY_NEWLINE);
i++;
break;
default:
break;
}
return i;
}
/* config模式配置保存函数: vty -- 相应的终端 */
int32_t _pd_port_config_save(vty_t *vty)
{
array_t *configs = pd_port_node.configs;
pd_port_cmd_save_config_f *func = NULL;
uint8_t i = 0;
uint8_t unit = 0;
uint8_t port = 0;
uint16_t field = 0;
/* 其他配置保存 */
for(unit = 0; unit < PD_DAU_SUM; unit++)
{
if (!dau[unit])
{
continue;
}
if (!dau[unit]->is_valid)
{
continue;
}
for(port = 0; port < dau[unit]->port_num; port++)
{
vty_out(vty, "interface port %d/%d%s", unit + 1, port + 1, VTY_NEWLINE);
for(i = 0; i < array_active(configs); i++)
{
func = array_lookup(configs, i);
if (!func)
{
continue;
}
func(vty, unit, port);
}
field = pd_config.port_config[unit][port].config.sensor_type;
vty_out(vty, " sensor-type %s%s", pd_sen_type_str[field], VTY_NEWLINE);
vty_out(vty, " noise-reduction %d%s", pd_config.port_config[unit][port].config.noise_reduction, VTY_NEWLINE);
vty_out(vty, " noise-env %d%s", pd_config.port_config[unit][port].config.env_noise, VTY_NEWLINE);
vty_out(vty, " evnet-thr %d%s", pd_config.port_config[unit][port].config.event_threshold, VTY_NEWLINE);
vty_out(vty, " evnet-cnt %d%s", pd_config.port_config[unit][port].config.event_counter, VTY_NEWLINE);
vty_out(vty, "!%s", VTY_NEWLINE);
}
}
return E_NONE;
}
/* 将端口字符串, 转换成 unit port 格式. */
int32_t _pd_port_str_to_unit_port(const char *port_str, uint8_t *unit, uint8_t *port)
{
char *str = NULL;
char *p = NULL;
char temp[8];
uint8_t len = 0;
uint8_t i = 0;
snprintf(temp, 8, "%s", port_str);
str = strtok_r(temp, "/", &p);
while(str != NULL)
{
/* 检查长度. */
if (len >= 2)
{
return E_BAD_PARAM;
}
/* 检查字符串 */
for(i = 0; str[i] && str[i] != '\0'; i++)
{
if (!(str[i] >= '0' && str[i] <= '9'))
{
return E_BAD_PARAM;
}
}
/* 检查数据长度 */
if (i != 1)
{
return E_BAD_PARAM;
}
/* 读取板卡和端口号. */
if (0 == len)
{
*unit = strtol(str, NULL, 10) - 1;
}
else
{
*port = strtol(str, NULL, 10) - 1;
}
len++;
/* 获取下个数据 */
str = strtok_r(NULL, "/", &p);
}
return E_NONE;
}
/* Interface functions -------------------------------------------------------*/
/* description: 局放程序入口函数.
param:
return: */
int32_t pd_main(void)
{
uint8_t i = 0;
uint8_t j = 0;
int32_t rv = 0;
#if 0
/* 初始化基本参数. */
for(i = 0; i < PD_DAU_SUM; i++)
{
for(j = 0; j < PD_DAU_PORT_SUM; j++)
{
pd_config.port_config[i][j].config.sensor_type = PD_SEN_TYPE_SIG;
pd_config.port_config[i][j].config.filter = CSG_FILTER_TYPE_FR;
pd_config.port_config[i][j].config.phase_sequence = 1;
pd_config.port_config[i][j].config.event_threshold = 400;
pd_config.port_config[i][j].config.event_counter = 10;
pd_config.port_config[i][j].config.env_noise = 100;
pd_config.port_config[i][j].config.noise_reduction = 30;
pd_config.port_config[i][j].config.sample_rate = 50000000;
pd_config.port_config[i][j].config.storage_event = 1000;
pd_config.port_config[i][j].config.storage_wave = 1000;
}
}
pd_config.config.sync_mode = PD_SYNC_OUTSIDE;
pd_config.config.real_period = 1;
pd_config.config.storage_real = 1000;
pd_config.config.trend_period = 1;
pd_config.config.storage_trend = 1000;
pd_config.config.heartbeat_period = 1;
pd_config.config.limit_event_time = 300;
pd_config.config.limit_event_cnt = 5;
pd_config.config.limit_event_interval = 60;
/* 注册配置保存函数 */
rv = cmd_config_node_config_register(CONFIG_PRI_PD, _pd_config_save);
if (rv != E_NONE)
{
log_err(LOG_PD, "Command save register ERROR %d!", rv);
return rv;
}
#endif
/* 注册端口节点. */
cmd_install_node(&pd_port_node, _pd_port_config_save);
pd_port_node.prompt = XMALLOC(MTYPE_DAU, PD_PORT_PROMPT_LEN);
pd_port_node.configs = array_init(PD_PORT_CMD_PRI_COUNT, MTYPE_DAU);
cmd_install_element(CONFIG_NODE, &pd_real_interval_cmd);
cmd_install_element(CONFIG_NODE, &pd_trend_interval_cmd);
cmd_install_element(CONFIG_NODE, &pd_heartbeat_interval_cmd);
cmd_install_element(CONFIG_NODE, &pd_sync_mode_cmd);
cmd_install_element(CONFIG_NODE, &pd_port_terminal_cmd);
cmd_install_element(PORT_NODE, &pd_port_terminal_cmd);
cmd_install_element(PORT_NODE, &pd_sensor_type_cmd);
cmd_install_element(PORT_NODE, &pd_noise_reduction_cmd);
cmd_install_element(PORT_NODE, &pd_noise_env_cmd);
cmd_install_element(PORT_NODE, &pd_evnet_thr_cmd);
cmd_install_element(PORT_NODE, &pd_evnet_cnt_cmd);
cmd_install_element(COMMON_NODE, &show_prps_cmd);
cmd_install_element(COMMON_NODE, &show_pd_cmd);
//LD_E_RETURN(DBG_M_PD_ERR, log_handle_init());
LD_E_RETURN(DBG_M_PD_ERR, csg_handle_init());
LD_E_RETURN(DBG_M_PD_ERR, dau_handle_init());
//LD_E_RETURN(DBG_M_PD_ERR, localstorage_handle_init());
//LD_E_RETURN(DBG_M_PD_ERR, debug_handle_init());
return E_NONE;
}
int32_t pd_port_cmd_config_register(int32_t pri, pd_port_cmd_save_config_f *func)
{
cmd_node_t *node = &pd_port_node;
/* 参数检查 */
if (pri >= PD_PORT_CMD_PRI_COUNT || !func)
{
return E_BAD_PARAM;
}
/* 加入列表 */
array_set(node->configs, pri, func, MTYPE_DAU);
return 0;
}
void pd_sync_mode_set(void)
{
uint16_t temp = 0;
if (PD_SYNC_OUTSIDE == pd_config.config.sync_mode)
{
temp = CPLD_SYNC_OUTSIDE;
}
else
{
temp = CPLD_SYNC_PT;
}
cpld_write(CPLD_REG_SYNC, 1, &temp);
}
void pd_wdg_clr(void)
{
uint16_t temp = 0;
temp = 0x01;
cpld_write(CPLD_REG_WDG_CLR, 1, &temp);
}
void pd_sync_state_get(void)
{
uint16_t temp = 0;
cpld_read(CPLD_REG_STAT, 1, &temp);
pd_state.sync = ((temp & 0x2) != 0);
}
void pd_prps_show(void)
{
uint8_t unit = 0;
uint8_t port = 0;
pd_port_config_t *config = NULL;
printh("Concern Bitmap: 0x%x\r\n", pd_config.concern_bitmap);
printh("UN PO CO RN AN MN FC\r\n");
for(unit = 0; unit < PD_DAU_SUM; unit++)
{
if (!dau[unit])
{
continue;
}
for(port = 0; port < dau[unit]->port_num; port++)
{
config = &pd_config.port_config[unit][port];
printh("%-02d %-02d %-02d %-02d %-02d %-02d %-02d\r\n", unit, port, config->is_concern,
config->r_noise_reduction, config->auto_noise_reduction, config->manual_noise_reduction / 10,
config->filter_cfg);
}
}
}
void pd_show(void)
{
printh("Synchronization: %s\r\n", pd_state.sync ? "valid" : "invalid");
printh("Receive count: %d %d\r\n", dau_ctrl.recv_cnt, dau_ctrl.recv_cnt_old);
printh("Receive error count: %d %d\r\n", dau_ctrl.recv_err_cnt, dau_ctrl.recv_err_cnt_old);
printh("Data error count: %d %d\r\n", dau_ctrl.data_err_cnt, dau_ctrl.data_err_cnt_old);
printh("Send error count: %d %d\r\n\n", dau_ctrl.send_err_cnt, dau_ctrl.send_err_cnt_old);
}
#else
int32_t PD_main(void)
{
return 0;
}
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

@ -0,0 +1,567 @@
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* 标准C库头文件. */
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <dirent.h>
/* 用户代码头文件. */
#include "cmd.h"
#include "fifo.h"
#include "pd_main.h"
#include "pd_dau.h"
#include "pd_storage.h"
/* Private define ------------------------------------------------------------*/
#define STORAGE_PATH "/run/media/mmcblk1p3/Data"
#define STORAGE_PATH_EVENT "/run/media/mmcblk1p3/Data/Event"
#define STORAGE_PATH_TREND "/run/media/mmcblk1p3/Data/Trend"
#define STORAGE_PATH_FIXEDTIMEPRPS "/run/media/mmcblk1p3/Data/FixedTimePRPS"
#define DEL_FILE_RATE_DEFAULT 10
/* Private macro -------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
storage_t storage;
storage_arg_t storage_arg;
/* Private function prototypes -----------------------------------------------*/
/* Internal functions --------------------------------------------------------*/
/* 以“wb”方式覆盖写入二进制文件 */
int32_t _storage_write_hex_file( const char *file_name, uint8_t *data, uint32_t len)
{
if (file_name == NULL || data == NULL || len < 1)
{
log_err( LOG_STORAGE, "Write file %s param ERROR!", file_name );
return E_BAD_PARAM;
}
usleep(1000);
FILE *file = fopen( file_name, "wb" );
if (file == NULL)
{
log_err( LOG_STORAGE, "Write file %s ERROR!", file_name );
return E_ERROR;
}
usleep(1000);
int32_t bytes_cnt;
bytes_cnt = fwrite( data, len, 1, file );
fclose( file );
return bytes_cnt;
}
/* 将文件名解析为UTC索引号 */
uint32_t _storage_filename_parse_utc( char *file_name )
{
uint32_t file_utc;
char date[FILE_NAME_LEN] = {0};
char time[FILE_NAME_LEN] = {0};
strncpy( date, file_name, 10 );
strncpy( time, file_name + 11, 8 );
time_str_to_long( date, time, &file_utc);
return file_utc;
}
/* 以UTC时间作为文件名 */
int32_t _storage_set_filename( char *file_name, uint32_t file_utc )
{
char time_str[FILE_NAME_LEN];
time_t file_time = file_utc;
struct tm *lt = localtime( &file_time );
strftime( time_str, FILE_NAME_LEN, "%Y-%m-%d %H:%M:%S", lt );
snprintf( file_name, FILE_NAME_LEN, "%s.dat", time_str );
return E_NONE;
}
/* 根据UTC的最大、最小值以及比重参数rate确定UTC基准值UTC小于该基准值的文件将被删除 */
uint32_t _storage_get_utc_base( uint32_t max_utc, uint32_t min_utc, int rate)
{
uint32_t utc_base;
utc_base = (max_utc - min_utc) / rate + min_utc;
return utc_base;
}
/* 创建存储文件夹 */
int32_t _storage_create_dir( void )
{
uint8_t unit;
uint8_t port;
char dir_path[DIR_PATH_LEN] = {0};
/* 创建父文件夹 */
for (int i = 0; i < 4; i++)
{
switch( i )
{
case 0:
snprintf( dir_path, DIR_PATH_LEN, "%s", STORAGE_PATH );
break;
case 1:
snprintf( dir_path, DIR_PATH_LEN, "%s", STORAGE_PATH_EVENT );
break;
case 2:
snprintf( dir_path, DIR_PATH_LEN, "%s", STORAGE_PATH_TREND );
break;
case 3:
snprintf( dir_path, DIR_PATH_LEN, "%s", STORAGE_PATH_FIXEDTIMEPRPS );
break;
default:
return E_NONE;
}
if( access( dir_path, 0 ) == -1 )
{
if (mkdir( dir_path, 0777 ))
{
log_err( LOG_STORAGE, "Create storage DIR %s failed!", dir_path );
return E_ERROR;
}
}
}
/* 创建事件数据通道子文件夹 */
for (unit = 0; unit < PD_DAU_SUM; unit++)
{
for (port = 0; port < PD_DAU_PORT_SUM; port++)
{
snprintf( dir_path, DIR_PATH_LEN, "%s/%02d", STORAGE_PATH_EVENT, (unit * PD_DAU_PORT_SUM + port + 1) );
if( access( dir_path, 0 ) == -1 )
{
if (mkdir( dir_path, 0777 ))
{
log_err( LOG_STORAGE, "Create storage DIR %s failed!", dir_path );
return E_ERROR;
}
}
}
}
return E_NONE;
}
/* 遍历文件夹以获得最小UTC值与文件数量 */
int32_t _storage_get_min_utc_file_cnt( char *dir_path, uint32_t *min_utc, uint16_t *file_count )
{
*file_count = 0;
*min_utc = time(NULL);
if (access( dir_path, 0 ) == -1) //文件夹不存在
{
if (mkdir( dir_path, 0777 ))
{
log_err( LOG_STORAGE, "Create storage DIR %s failed!", dir_path );
return E_ERROR;
}
return E_NONE;
}
DIR *dir;
struct dirent *ptr;
uint32_t file_utc = 0;
if( (dir = opendir( dir_path )) == NULL )
{
log_err( LOG_STORAGE, "ERROR! Can't open dir %s to get param!", dir_path );
return E_ERROR;
}
while( (ptr = readdir( dir )) != NULL )
{
if (ptr->d_type == DT_REG) //常规文件
{
file_utc = _storage_filename_parse_utc( ptr->d_name );
if (*min_utc > file_utc)
{
*min_utc = file_utc;
}
(*file_count)++;
}
}
closedir( dir );
return E_NONE;
}
/* 存储参数初始化包括已存储文件数UTC的最小值等 */
int32_t _storage_arg_init( void )
{
/* 事件存储参数初始化 */
uint8_t unit;
uint8_t port;
for (unit = 0; unit < PD_DAU_SUM; unit++)
{
for (port = 0; port < PD_DAU_PORT_SUM; port++)
{
/* 判断事件频繁参数初始化 */
storage_arg.utc_base[unit][port] = time(NULL);
storage_arg.limit_cnt[unit][port] = pd_config.config.limit_event_cnt;
char dir_path[DIR_PATH_LEN] = {0};
snprintf( dir_path, DIR_PATH_LEN, "%s/%02d", STORAGE_PATH_EVENT, (unit * PD_DAU_PORT_SUM + port + 1) );
_storage_get_min_utc_file_cnt( dir_path, &storage_arg.event_min_utc[unit][port], &storage_arg.event_cnt[unit][port] );
}
}
/* 趋势存储参数初始化 */
_storage_get_min_utc_file_cnt( STORAGE_PATH_TREND, &storage_arg.trend_min_utc, &storage_arg.trend_cnt );
/* 定时存储参数初始化 */
_storage_get_min_utc_file_cnt( STORAGE_PATH_FIXEDTIMEPRPS, &storage_arg.fixedtimePRPS_min_utc, &storage_arg.fixedtimePRPS_cnt );
return E_NONE;
}
/* 运行中无法访问文件夹,说明文件夹可能被删除,重新创建 */
int32_t _storage_recreate_dir( char *dir_path )
{
/* 若创建不成功,说明父文件夹可能被删除,此时从父文件夹开始创建并重新初始化参数 */
if (mkdir( dir_path, 0777 ))
{
_storage_create_dir();
_storage_arg_init();
return E_NONE;
}
return TRUE; //表示文件夹创建成功
}
/**
* @brief
* @param *dir_path:
* @param utc_base: UTCUTC
* @param *min_utc: UTCUTC
* @param *file_count:
*/
int32_t _storage_delete_file( char *dir_path, uint32_t utc_base, uint32_t *min_utc, uint16_t *file_count )
{
DIR *dir;
struct dirent *ptr;
char remove_path[DIR_PATH_LEN]; //删除文件的路径
int remove_ret; //remove函数的返回值
uint32_t file_utc;
*min_utc = time(NULL);
if( (dir = opendir( dir_path )) == NULL )
{
log_err( LOG_STORAGE, "ERROR! Can't open delete dir %s !", dir_path );
return E_ERROR;
}
while( (ptr = readdir( dir )) != NULL )
{
if (ptr->d_type == DT_REG) //常规文件
{
file_utc = _storage_filename_parse_utc( ptr->d_name );
if( (file_utc > utc_base) && (file_utc < *min_utc) )
{
*min_utc = file_utc;
}
if (file_utc <= utc_base) //需要被删除的文件
{
memset( remove_path, '\0', sizeof(remove_path) );
strcpy( remove_path, dir_path );
strcat( remove_path, "/" );
strcat( remove_path, ptr->d_name );
remove_ret = remove( remove_path );
if (remove_ret == 0) //成功删除,文件总数减一
{
(*file_count)--;
}
else if (remove_ret == -1)
{
log_warn( LOG_STORAGE, "WARN! Remove file %s failed!", ptr->d_name );
if (errno == EROFS)
{
printf( "File Only Read\r\n" );
}
else if (errno == EFAULT)
{
printf( "File Pointer to the overflow\r\n" );
}
else if (errno == ENAMETOOLONG)
{
printf( "File Name Over Long\r\n" );
}
}
}
}
}
closedir( dir );
return E_NONE;
}
/* 判断时间存储是否过于频繁返回E_NONE代表将存储该文件 */
int32_t _storage_event_frequently( uint32_t utc, uint8_t unit, uint8_t port )
{
/* 周期结束,判断是否频繁存储 */
if( storage_arg.limit_cnt[unit][port] <= 0 )
{
/* 上周期存储频繁,间隔存储直到限制时间到达 */
if( utc < (storage_arg.utc_base[unit][port] + pd_config.config.limit_event_time) )
{
/* 间隔存储 */
if( utc < (storage_arg.event_max_utc[unit][port] + pd_config.config.limit_event_interval) )
{
return E_TIMEOUT;
}
else
{
return E_NONE;
}
}
/* 间隔存储限时结束或上周期存储不频繁 */
else
{
storage_arg.limit_cnt[unit][port] = pd_config.config.limit_event_cnt - 1;
storage_arg.utc_base[unit][port] = utc;
return E_NONE;
}
}
/* 周期未结束 */
storage_arg.limit_cnt[unit][port]--;
return E_NONE;
}
/* 事件文件存储函数 */
int32_t _storage_event( pd_event_t *data )
{
uint8_t unit;
uint8_t port;
dau_vport_to_port( data->vport, &unit, &port );
if (_storage_event_frequently( data->utc, unit, port ))
{
return E_NONE;
}
int32_t bytes_cnt;
char file_name[FILE_NAME_LEN];
char dir_path[DIR_PATH_LEN];
char dir_file_write[DIR_PATH_LEN];
_storage_set_filename( file_name, data->utc );
snprintf( dir_path, DIR_PATH_LEN, "%s/%02d", STORAGE_PATH_EVENT, data->vport );
if (access( dir_path, 0 ) == -1) //文件夹不存在或被删除
{
if (_storage_recreate_dir( dir_path ))
{
storage_arg.event_min_utc[unit][port] = data->utc;
storage_arg.event_cnt[unit][port] = 0;
}
}
snprintf( dir_file_write, DIR_PATH_LEN, "%s/%s", dir_path, file_name );
bytes_cnt = _storage_write_hex_file( dir_file_write, (uint8_t*) data, sizeof(pd_event_t) );
if (bytes_cnt < 0)
{
DBG( DBG_M_STORAGE_ERR, "Local storage return %s!\r\n", safe_strerror(errno) );
return E_ERROR;
}
storage_arg.event_max_utc[unit][port] = data->utc;
storage_arg.event_cnt[unit][port]++;
if (storage_arg.event_cnt[unit][port] >= pd_config.port_config[unit][port].config.storage_event)
{
_storage_delete_file( dir_path,
_storage_get_utc_base( storage_arg.event_max_utc[unit][port], storage_arg.event_min_utc[unit][port], DEL_FILE_RATE_DEFAULT ),
&storage_arg.event_min_utc[unit][port],
&storage_arg.event_cnt[unit][port] );
}
return E_NONE;
}
/* 趋势文件存储函数 */
int32_t _storage_trend( pd_trend_t *data )
{
int32_t bytes_cnt;
char file_name[FILE_NAME_LEN];
char dir_path[DIR_PATH_LEN];
char dir_file_write[DIR_PATH_LEN];
_storage_set_filename( file_name, data->utc );
snprintf( dir_path, DIR_PATH_LEN, "%s", STORAGE_PATH_TREND );
if (access( dir_path, 0 ) == -1) //文件夹不存在
{
if (_storage_recreate_dir( dir_path ))
{
storage_arg.trend_min_utc = data->utc;
storage_arg.trend_cnt = 0;
}
}
snprintf( dir_file_write, DIR_PATH_LEN, "%s/%s", dir_path, file_name );
bytes_cnt = _storage_write_hex_file( dir_file_write, (uint8_t*) data, sizeof(pd_trend_t) );
if (bytes_cnt < 0)
{
DBG( DBG_M_STORAGE_ERR, "Local storage return %s!\r\n", safe_strerror(errno) );
return E_ERROR;
}
storage_arg.trend_max_utc = data->utc;
storage_arg.trend_cnt++;
if (storage_arg.trend_cnt >= pd_config.config.storage_trend)
{
_storage_delete_file( dir_path,
_storage_get_utc_base( storage_arg.trend_max_utc, storage_arg.trend_min_utc, DEL_FILE_RATE_DEFAULT ),
&storage_arg.trend_min_utc,
&storage_arg.trend_cnt );
}
return E_NONE;
}
/* 定时PRPS文件存储函数 */
int32_t _storage_fixedtimePRPS( pd_prps_t *data )
{
int32_t bytes_cnt;
char file_name[FILE_NAME_LEN];
char dir_path[DIR_PATH_LEN];
char dir_file_write[DIR_PATH_LEN];
_storage_set_filename( file_name, data->utc );
snprintf( dir_path, DIR_PATH_LEN, "%s", STORAGE_PATH_FIXEDTIMEPRPS );
if (access( dir_path, 0 ) == -1) //文件夹不存在
{
if (_storage_recreate_dir( dir_path ))
{
storage_arg.fixedtimePRPS_min_utc = data->utc;
storage_arg.fixedtimePRPS_cnt = 0;
}
}
snprintf( dir_file_write, DIR_PATH_LEN, "%s/%s", dir_path, file_name );
bytes_cnt = _storage_write_hex_file( dir_file_write, (uint8_t*) data, sizeof(pd_prps_t) );
if (bytes_cnt < 0)
{
DBG( DBG_M_STORAGE_ERR, "Local storage return %s!\r\n", safe_strerror(errno) );
return E_ERROR;
}
storage_arg.fixedtimePRPS_max_utc = data->utc;
storage_arg.fixedtimePRPS_cnt++;
if (storage_arg.fixedtimePRPS_cnt >= pd_config.config.storage_real)
{
_storage_delete_file( dir_path,
_storage_get_utc_base( storage_arg.fixedtimePRPS_max_utc, storage_arg.fixedtimePRPS_min_utc, DEL_FILE_RATE_DEFAULT ),
&storage_arg.fixedtimePRPS_min_utc,
&storage_arg.fixedtimePRPS_cnt );
}
return E_NONE;
}
/* 本地存储处理句柄 */
void *_local_storage_handle(void *arg)
{
pd_storage_msg_t *recv_msg = NULL;
while(1)
{
if(fifo_read(storage.storage_fifo_id,(void **)&recv_msg) != 0)
{
DBG(DBG_M_STORAGE_ERR,"ERROR at fifo %d read!\r\n",storage.storage_fifo_id);
continue;
}
/* 数据存储处理 */
switch(recv_msg->type)
{
case STORAGE_TYPE_EVENT:
_storage_event( (pd_event_t*) recv_msg->data );
break;
case STORAGE_TYPE_TREND:
_storage_trend( (pd_trend_t*) recv_msg->data );
break;
case STORAGE_TYPE_ALARM:
break;
case STORAGE_TYPE_RUNSTATUS:
break;
case STORAGE_TYPE_FIXEDTIMERPRPS:
_storage_fixedtimePRPS( (pd_prps_t*) recv_msg->data );
break;
default:
break;
}
/* 释放存储数据内存 */
XFREE(MTYPE_STORAGE,recv_msg->data);
fifo_push(storage.storage_fifo_id);
}
return NULL;
}
/* 本地存储公共部分初始化 */
int32_t _local_storage_init_common(void)
{
struct sched_param param;
pthread_attr_t attr;
pthread_t pid;
int rv = 0;
_storage_create_dir();
_storage_arg_init();
storage.storage_fifo_id = fifo_create(STORAGE_DATA_FIFO, 32);
if(storage.storage_fifo_id < 0)
{
log_err(LOG_STORAGE,"Open fifo " STORAGE_DATA_FIFO " error!");
return E_ERROR;
}
pthread_mutex_init(&storage.mutex, NULL);
/* 配置线程RR调度优先级50 */
pthread_attr_init(&attr);
param.sched_priority = 50;
pthread_attr_setschedpolicy(&attr, SCHED_RR);
pthread_attr_setschedparam(&attr, &param);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
rv = pthread_create(&pid, &attr, _local_storage_handle, NULL);
if(rv != 0)
{
log_err(LOG_STORAGE, "PD can't create storage pthread %d!", rv);
return E_SYS_CALL;
}
else
{
thread_m_add("LOCAL_STORAGE", pid);
}
pthread_attr_destroy(&attr);
return E_NONE;
}
/* 本地存储模块初始化 */
int32_t localstorage_handle_init(void)
{
/* 初始化模块 */
LD_E_RETURN(DBG_M_STORAGE_ERR,_local_storage_init_common());
return E_NONE;
}
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,260 @@
/*****************************************************************************
* file lib/process/process.c
* author YuLiang
* version 1.0.0
* date 26-Sep-2021
* brief This file provides all the process related operation functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* 标准C库头文件. */
#include <locale.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/watchdog.h>
#include "cmd.h"
#include "mtimer.h"
#include "process.h"
#include "hwgpio.h"
#include "fifo.h"
#include "pd_main.h"
#include "pd_dau.h"
#include "pd_cpld.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
int32_t recv_qid;
uint16_t version_hex;
uint32_t start_time;
/* Private function prototypes -----------------------------------------------*/
/* Internal functions --------------------------------------------------------*/
/* 信号处理函数 */
void _signal_handler(int sig)
{
if (SIGSEGV == sig)
{
log_backtrace(LOG_LVL_ERR);
}
//else if(SIGINT == sig
// || SIGTSTP == sig)
//{
/* 屏蔽信号 */
// return;
//}
exit(-1);
}
/* 看门狗初始化. */
void _wdg_init(void)
{
uint16_t temp = 0;
/* 初始化看门狗计数器, 单位 ms. */
temp = 0xffff;
cpld_write(CPLD_REG_WDG_TM, 1, &temp);
temp = 0x01;
cpld_write(CPLD_REG_WDG_EN, 1, &temp);
cpld_write(CPLD_REG_WDG_CLR, 1, &temp);
}
/* 喂狗. */
void _wdg_clr(void)
{
uint16_t temp = 0;
/* 喂狗, 1 - 喂狗. */
temp = 0x01;
cpld_write(CPLD_REG_WDG_CLR, 1, &temp);
}
/* Interface functions -------------------------------------------------------*/
/* description: 数据处理初始化.
param:
return: (E_NONE),() */
int32_t process_init(void)
{
#if 0
/* 创建消息队列. */
if ((recv_qid = msgget(0x4321, IPC_CREAT | 0666)) == -1)
{
log_err(LOG_DEFAULT, "message ERROR at msgget return %s!", safe_strerror(errno));
}
/* 清空消息队列. */
msgctl(recv_qid, IPC_RMID, NULL);
if ((recv_qid = msgget(0x4321, IPC_CREAT | 0666)) == -1)
{
log_err(LOG_DEFAULT, "message ERROR at msgget return %s!", safe_strerror(errno));
}
#endif
/* 初始化局放应用. */
pd_main();
return E_NONE;
}
/* description: 程序入口函数.
param:
return: */
int32_t main(int32_t argc, char **argv)
{
struct sigaction act;
uint32_t cnt = 0;
/* 设置本地化信息为默认值. */
setlocale(LC_ALL, "");
/* 必须最前面, 初始化内存管理模块的基本参数. */
mtype_init_befor();
/* log初始化 */
//log_open();
/* 初始化时定量清除 log */
//log_clean();
//log_out(LOG_DEFAULT, LOG_LVL_WARN, "System start!");
/* 设置信号处理的回调函数 */
act.sa_handler = _signal_handler;
sigemptyset(&act.sa_mask);
sigaction(SIGINT, &act, NULL);
sigaction(SIGSEGV, &act, NULL);
sigaction(SIGTSTP, &act, NULL);
/* 初始化cli等公共模块. */
cmd_init();
thread_m_init();
mtype_init();
dbg_init();
mtimer_init();
vtysh_init();
gpio_init();
fifo_init();
/* 初始化 DAU 复位, 并不采集数据. 这里必须等待, 不然 gpio 模拟 spi 会失败. */
cpld_handle_init();
//_wdg_init();
//dau_shutdown();
/* 主处理函数初始化 */
process_init();
/* 配置恢复命令行启动 */
//vtysh_config_recovery();
//dau_start();
/* 启动命令行 */
vtysh_shell_init();
/* 初始化完成 */
version_hex = version_str_to_int();
is_system_init = TRUE;
start_time = time(NULL);
//GPIO_ERR1_LED(1);
/* 启动ssh命令行 */
vtycmd_init();
/* 主循环, 点灯喂狗. */
for(;;)
{
sleep(1);
#if 0
/* 获取同步状态, 更新收报计数. */
if (0 == (cnt & 0x7))
{
pd_sync_state_get();
GPIO_SYNC_LED(!pd_state.sync);
if (dau_ctrl.recv_cnt > 2000)
{
printh("ERROR recv_cnt %d\r\n", dau_ctrl.recv_cnt);
}
dau_ctrl.recv_cnt_old = dau_ctrl.recv_cnt;
dau_ctrl.recv_cnt = 0;
}
/* 点 RUN 灯. */
if (cnt & 0x1)
{
GPIO_RUN_LED(0);
}
else
{
GPIO_RUN_LED(1);
}
sleep(1);
cnt++;
/* 更新数据处理计数. */
if (0 == (cnt & 0x3f))
{
dau_ctrl.recv_err_cnt_old = dau_ctrl.recv_err_cnt;
dau_ctrl.recv_err_cnt = 0;
dau_ctrl.data_err_cnt_old = dau_ctrl.data_err_cnt;
dau_ctrl.data_err_cnt = 0;
dau_ctrl.send_err_cnt_old = dau_ctrl.send_err_cnt;
dau_ctrl.send_err_cnt = 0;
}
/* 喂狗. */
if (0 == (cnt & 0x1f))
{
_wdg_clr();
}
#endif
}
return 0;
}
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

@ -0,0 +1,297 @@
/*****************************************************************************
* file lib/management/array.c
* author YuLiang
* version 1.0.0
* date 22-Sep-2021
* brief This file provides all the array related operation functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* 标准C库头文件. */
/* 用户代码头文件. */
#include "array.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Internal functions --------------------------------------------------------*/
/* 确保设置的数组成员没有内存越界如果超出数组长度则重新realloc:
a --
len --
mem_type -- 使
return: void */
static void _array_len_ensure(array_t *a, uint32_t len, int32_t mem_type)
{
if (a->alloced > len)
{
return;
}
a->index = XREALLOC(mem_type, a->index, sizeof(void *) * (a->alloced * 2));
memset(&a->index[a->alloced], 0, sizeof(void *) * a->alloced);
a->alloced *= 2;
if (a->alloced <= len)
{
_array_len_ensure(a, len, mem_type);
}
}
/* 查找数组a的第一个空位置.
a --
return: */
uint32_t _array_empty_slot(array_t *a)
{
uint32_t i = 0;
for(i = 0; i < a->active; i++)
{
if (NULL == a->index[i])
{
return i;
}
}
return i;
}
/* Interface functions -------------------------------------------------------*/
/* 初始化数组:
size --
mem_type -- 使
return: */
array_t *array_init(uint32_t size, int32_t mem_type)
{
array_t *a = XMALLOC(mem_type, sizeof(array_t));
/* 如果大小为0,设置默认大小. */
if (0 == size)
{
size = ARRAY_MIN_SIZE;
}
a->alloced = size;
a->active = 0;
a->index = XMALLOC(mem_type, sizeof(void *) * size);
return a;
}
/* 设置数组相应索引位置的值:
a --
i --
val --
mem_type -- 使
return: void */
void array_set(array_t *a, uint32_t i, void *val, int32_t mem_type)
{
_array_len_ensure(a, i, mem_type);
a->index[i] = val;
if (a->active <= i)
{
a->active = i + 1;
}
}
/* 删除数组相应索引位置的值:
a --
i --
return: void */
void array_unset(array_t *a, uint32_t i)
{
if (i >= a->alloced)
{
return;
}
a->index[i] = NULL;
/* 不是最后一个元素直接返回. */
if (i + 1 != a->active)
{
return;
}
/* 如果是最后一个元素,则将当前可使用指针前移. */
while(--a->active)
{
if (a->index[a->active - 1] != NULL)
{
break;
}
}
}
/* 将数据放入数组的第一个空位置:
a --
val --
mem_type -- 使
return: */
uint32_t array_append(array_t *a, void *val, int32_t mem_type)
{
uint32_t i = 0;
i = _array_empty_slot(a);
_array_len_ensure(a, i, mem_type);
a->index[i] = val;
if (a->active <= i)
{
a->active = i + 1;
}
return i;
}
/* 复制数组a:
a --
mem_type -- 使
return: */
array_t *array_copy(array_t *a, int32_t mem_type)
{
unsigned int size = 0;
array_t *array = XMALLOC(mem_type, sizeof(array_t));
array->active = a->active;
array->alloced = a->alloced;
size = sizeof(void *) * (a->alloced);
array->index = XMALLOC(mem_type, size);
memcpy(array->index, a->index, size);
return array;
}
/* 将数组a和数组b合并成数组a:
a -- 1
b -- 2
mem_type -- 使
return: void */
void array_merge(array_t *a, array_t *b, int32_t mem_type)
{
uint32_t size = 0;
if (0 == b->alloced)
{
return;
}
size = sizeof(void *) * (a->alloced + b->alloced);
a->index = XREALLOC(mem_type, a->index, size);
memcpy(&a->index[a->active], b->index, sizeof(void *) * b->active);
a->active = a->active + b->active;
a->alloced = a->alloced + b->alloced;
}
/* 释放array_t:
a --
mem_type -- 使
return: void */
void array_free_wrapper(array_t *a, int32_t mem_type)
{
XFREE(mem_type, a);
}
/* 释放array_t->index:
a --
mem_type -- 使
return: void */
void array_free_index(array_t *a, int32_t mem_type)
{
XFREE(mem_type, a->index);
}
/* 释放array_t和array_t->index:
a --
mem_type -- 使
return: void */
void array_free(array_t *a, int32_t mem_type)
{
XFREE(mem_type, a->index);
XFREE(mem_type, a);
}
/* 查询数组a的数据i:
a --
i --
return: */
void *array_lookup(array_t *a, uint32_t i)
{
return (i >= a->active) ? NULL : a->index[i];
}
/* 获取数组a中有效数据的个数:
a --
return: void */
uint32_t array_count(array_t *a)
{
uint32_t i = 0;
uint32_t count = 0;
for (i = 0; i < a->active; i++)
{
if (a->index[i] != NULL)
{
count++;
}
}
return count;
}
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

@ -0,0 +1,555 @@
/******************************************************************************
* file lib/management/better_log.c
* author YuLiang
* version 1.0.0
* date 14-Sep-2021
* brief This file provides all the log operation functions.
*
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* 标准C库头文件. */
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <execinfo.h>
/* 用户代码头文件. */
#include <fifo.h>
/* Private define ------------------------------------------------------------*/
#define LOG_LOCK pthread_mutex_lock( &log_sys->log_mutex )
#define LOG_UNLOCK pthread_mutex_unlock( &log_sys->log_mutex )
#define LOG_OUT_LOCK pthread_mutex_lock( &log_sys->log_out_mutex )
#define LOG_OUT_UNLOCK pthread_mutex_unlock( &log_sys->log_out_mutex )
#define LOG_DB_LOCK pthread_mutex_lock(&log_sys->log_db_mutex)
#define LOG_DB_UNLOCK pthread_mutex_unlock(&log_sys->log_db_mutex)
#define LOG_OUT 0
#define LOG_SHOW 1
/* Private macro -------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
_log_fifo_t log_fifo;
log_sys_t *log_sys;
_log_out_t *log_out_struct;
_log_show_t *log_show_struct;
static char *log_str = NULL;
static char *log_out_va_str = NULL;
static char *log_fifo_va_str = NULL;
/* log等级. */
static const log_lvl_t log_priority[] =
{
{LOG_LVL_ERR, "err"},
{LOG_LVL_WARN, "warn"},
{LOG_LVL_NOTIF, "notif"},
{LOG_LVL_INFO, "info"},
{LOG_LVL_DBG, "debug"},
{-1, NULL}
};
/* log模块. */
static const log_module_t log_module_names[] =
{
{LOG_DEFAULT, "DEFAULT"},
{LOG_CLI, "CLI"},
{LOG_MEMORY, "MEMORY"},
{LOG_FIFO, "FIFO"},
{LOG_GPIO, "GPIO"},
{LOG_PD, "PD"},
{LOG_DAU, "DAU"},
{LOG_CSG, "CSG"},
{LOG_STORAGE, "STORAGE"},
{LOG_DEBUG, "DEBUG"},
{-1, NULL}
};
/* Private function prototypes -----------------------------------------------*/
/* Internal functions --------------------------------------------------------*/
/* 文件log输出底层函数. */
static void _log_out_db( LOG_MODULE_E module, LOG_LVL_E priority, const char *va_str )
{
log_sys_t *log = log_sys;
char time_str[TIME_STR_LEN] = {0};
char *zErrMsg = NULL;
static uint64_t logCnt = 0;
time_string( log->timestamp_precision, time_str, sizeof(time_str) );
LOG_DB_LOCK;
memset( log_str, 0, LOG_STR_LEN );
snprintf( log_str, LOG_STR_LEN,
"INSERT INTO better_log (LEVEL,LOG) VALUES (%d, \"%s %s-%s: %s\"); ",
priority, time_str, log_priority[priority].describe, log_module_names[module].describe, va_str ); //id 已设为自增
if (sqlite3_exec( log->db, log_str, 0, 0, &zErrMsg ) != SQLITE_OK)
{
printh("SQL INSERT error: %s\r\n", zErrMsg);
sqlite3_free(zErrMsg);
}
/*定量清除log*/
logCnt++;
if (logCnt >= 100)
{
clock_t begin,end;
begin = clock();
log_clean();
end = clock();
printh("-------------------log_clean RunTimer : %lf----------------\r\n",(double)(end-begin)/CLOCKS_PER_SEC);
printh("-------------------log_clean RunTimer : %lf----------------\r\n",(double)(end-begin)/CLOCKS_PER_SEC);
printh("-------------------log_clean RunTimer : %lf----------------\r\n",(double)(end-begin)/CLOCKS_PER_SEC);
logCnt = 0;
}
LOG_DB_UNLOCK;
}
/* 解日志输出fifo数据封装 */
static void _log_out( _log_out_t *data )
{
_log_out_db( data->module, data->lvl, data->log_out_str );
}
/* 串口日志输出 */
static void _log_out_std( LOG_MODULE_E module, LOG_LVL_E priority, const char *va_str )
{
log_sys_t *log = log_sys;
char time_str[TIME_STR_LEN] = {0};
time_string(log->timestamp_precision, time_str, sizeof(time_str));
printh("%s %s-%s: %s\n", time_str, log_priority[priority].describe, log_module_names[module].describe, va_str);
}
/* 将日志按照格式串口打印 */
static int _log_show_print( void *data, int argc, char **argv, char **azColName )
{
printh("LOG id %s: %s\r\n", argv[0], argv[2]);
return 0;
}
/* log打印底层函数 */
static void _log_show( _log_show_t *data )
{
log_sys_t *log = log_sys;
char *zErrMsg = NULL;
LOG_DB_LOCK;
memset( log_str, 0, LOG_STR_LEN );
switch (data->type)
{
case LOG_SHOW_CNT: //打印指定数量的日志
snprintf( log_str, LOG_STR_LEN, "SELECT * FROM better_log ORDER BY id DESC LIMIT %d;", data->param );
break;
case LOG_SHOW_LVL: //打印指定等级的日志
snprintf( log_str, LOG_STR_LEN, "SELECT * FROM better_log WHERE LEVEL = %d ORDER BY id DESC LIMIT 100;", data->param );
break;
case LOG_SHOW_KEYWORD: //打印含关键词的日志
if (data->param <= 0)
{
snprintf( log_str, LOG_STR_LEN, "SELECT * FROM better_log WHERE LOG GLOB \'*%s*\' ORDER BY id DESC;",
data->log_show_str );
}
else
{
snprintf( log_str, LOG_STR_LEN, "SELECT * FROM better_log WHERE LOG GLOB \'*%s*\' ORDER BY id DESC LIMIT %d;",
data->log_show_str, data->param );
}
break;
default: //打印所有日志
snprintf( log_str, LOG_STR_LEN, "SELECT * FROM better_log ORDER BY id DESC;" );
break;
}
if (sqlite3_exec( log->db, log_str, _log_show_print, 0, &zErrMsg ) != SQLITE_OK)
{
printh("SQL show error: %s\r\n", zErrMsg);
sqlite3_free(zErrMsg);
}
LOG_DB_UNLOCK;
}
/* 封装数据并写fifo */
int32_t _log_msg_send(uint32_t type, void *data)
{
_log_msg_t log_msg;
/* 封装消息. */
log_msg.type = type;
log_msg.data = data;
/* 发送消息 */
if( fifo_write( log_fifo.log_fifo_id, (void*)(&log_msg), sizeof(_log_msg_t)) != sizeof(_log_msg_t) )
{
DBG( DBG_M_FIFO, "LOG write ERROR!\r\n" );
return E_ERROR;
}
return E_NONE;
}
/* 经由fifo输出日志 */
void _log_fifo_out( LOG_MODULE_E module, LOG_LVL_E priority, const char *va_str )
{
memset( log_out_struct, 0, sizeof(_log_out_t) );
_log_out_t *log_data = log_out_struct;
log_data->module = module;
log_data->lvl = priority;
memcpy( log_data->log_out_str, va_str, LOG_STR_LEN );
_log_msg_send( LOG_OUT, log_data );
}
/* Interface functions -------------------------------------------------------*/
/* log打印输出函数. */
#define BLOG_FUNC(FUNCNAME,PRIORITY) \
void FUNCNAME(LOG_MODULE_E module, const char *format, ...) \
{ \
log_sys_t *log = log_sys; \
if (NULL == log) return; \
LOG_LOCK; \
memset( log_fifo_va_str, 0, LOG_STR_LEN ); \
va_list args; \
va_start(args, format); \
vsnprintf(log_fifo_va_str, LOG_STR_LEN, format, args); \
va_end(args); \
if ((1 << PRIORITY) & log->enable_lvl[LOG_MODE_STDOUT]) \
_log_out_std(module, PRIORITY, log_fifo_va_str); \
if (((1 << PRIORITY) & log->enable_lvl[LOG_MODE_FILE]) && log->db){ \
if (log_fifo.log_fifo_id) \
_log_out_db(module, PRIORITY, log_fifo_va_str); \
else \
_log_fifo_out(module, PRIORITY, log_fifo_va_str);} \
LOG_UNLOCK; \
}
BLOG_FUNC(log_err, LOG_LVL_ERR)
BLOG_FUNC(log_warn, LOG_LVL_WARN)
BLOG_FUNC(log_info, LOG_LVL_INFO)
BLOG_FUNC(log_notice, LOG_LVL_NOTIF)
BLOG_FUNC(log_debug, LOG_LVL_DBG)
#undef BLOG_FUNC
/* description: log输出.
param: module --
priority --
return: */
void log_out(LOG_MODULE_E module, LOG_LVL_E priority, const char *format, ...)
{
log_sys_t *log = log_sys;
if (NULL == log) return;
LOG_OUT_LOCK;
memset( log_out_va_str, 0, LOG_STR_LEN );
va_list args;
va_start(args, format);
vsnprintf(log_out_va_str, LOG_STR_LEN, format, args);
va_end (args);
/* 串口log. */
if ((1 << priority) & log->enable_lvl[LOG_MODE_STDOUT])
_log_out_std(module, priority, log_out_va_str);
/* 判断是否是文件输出 */
if (((1 << priority) & log->enable_lvl[LOG_MODE_FILE]) && log->db)
_log_out_db(module, priority, log_out_va_str);
LOG_OUT_UNLOCK;
}
/* 打印日志函数 */
void log_show( int32_t show_cnt, LOG_LVL_E priority, const char *key_word )
{
memset( log_show_struct, 0, sizeof(_log_show_t) );
_log_show_t *log_data = log_show_struct;
if (priority != LOG_LVL_MAX) // 按等级打印日志
{
log_data->type = LOG_SHOW_LVL;
log_data->param = priority;
}
else if (key_word != NULL) // 高级打印功能
{
log_data->type = LOG_SHOW_KEYWORD;
log_data->param = show_cnt;
memcpy( log_data->log_show_str, key_word, LOG_STR_LEN );
}
else if (show_cnt > 0) // 按数量打印日志
{
log_data->type = LOG_SHOW_CNT;
log_data->param = show_cnt;
}
else
{
log_data->type = LOG_SHOW_MAX;
}
_log_msg_send( LOG_SHOW, log_data );
}
/* description: log系统初始化.
param:
return: (0),(-1) */
int32_t log_open()
{
log_sys_t *log = NULL;
int32_t i = 0;
int32_t rv = 0;
char *sql = NULL;
char *zErrMsg = NULL;
/* 申请内存. */
log_str = XMALLOC(MTYPE_LOG, LOG_STR_LEN);
log_out_va_str = XMALLOC(MTYPE_LOG, LOG_STR_LEN);
log_fifo_va_str = XMALLOC(MTYPE_LOG, LOG_STR_LEN);
log_out_struct = XMALLOC(MTYPE_LOG, sizeof(_log_out_t));
log_show_struct = XMALLOC(MTYPE_LOG, sizeof(_log_show_t));
log_sys = XMALLOC(MTYPE_LOG, sizeof(log_sys_t));
if (NULL == log_sys)
{
return E_MEM;
}
log = log_sys;
pthread_mutex_init(&log->log_mutex, NULL);
pthread_mutex_init(&log->log_out_mutex, NULL);
pthread_mutex_init(&log->log_db_mutex, NULL);
/* 打开 log 数据库. */
log->filename = XSTRDUP(MTYPE_LOG, LOG_FILE);
rv = sqlite3_open(log->filename, &log->db);
if (rv)
{
log->db = NULL;
printf("Can't open database: %s\r\n", sqlite3_errmsg(log->db));
return E_SYS_CALL;
}
/* 创建表. */
sql = "CREATE TABLE IF NOT EXISTS better_log(" \
"ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," \
"LEVEL INT8 NOT NULL," \
"LOG TEXT);";
if (sqlite3_exec(log->db, sql, 0, 0, &zErrMsg) != SQLITE_OK)
{
printf("SQL create error: %s\r\n", zErrMsg);
sqlite3_free(zErrMsg);
}
/* 设置默认log级别输出方式 */
for (i = 0; i < LOG_MODE_MAX; i++)
{
log->enable_lvl[i] = 0;
}
log->enable_lvl[LOG_MODE_FILE] = (1 << LOG_LVL_ERR) | (1 << LOG_LVL_WARN) | (1 << LOG_LVL_NOTIF);
log->enable_lvl[LOG_MODE_STDOUT] = (1 << LOG_LVL_ERR) | (1 << LOG_LVL_WARN) | (1 << LOG_LVL_NOTIF);
log->enable_lvl[LOG_MODE_MONITOR] = (1 << LOG_LVL_ERR) | (1 << LOG_LVL_WARN) | (1 << LOG_LVL_NOTIF);
log->default_lvl = 0;
return E_NONE;
}
/* description: 配置对应等级的log的输出方式.
param: mode --
log_level --
return: */
void log_set_level(LOG_MODE_E mode, LOG_LVL_E log_level)
{
log_sys->enable_lvl[mode] |= (1 << log_level);
}
/* description: 取消对应等级的log的输出方式.
param: mode --
log_level --
return: */
void log_unset_level(LOG_MODE_E mode, LOG_LVL_E log_level)
{
log_sys->enable_lvl[mode] &= ~(1 << log_level);
}
/* description: 根据传入的字符串返回相应的log优先级.
param: lvl_name --
return: (LOG_LVL_E) */
int32_t log_level_get_by_name(const char *lvl_name)
{
int32_t level = LOG_LVL_MAX;
for (level = 0 ; log_priority[level].describe != NULL ; level++)
if (!strncmp(lvl_name, log_priority[level].describe, 2))
return log_priority[level].lvl;
return LOG_LVL_MAX;
}
/* 打印堆栈使用情况: */
/* description: 根据传入的字符串返回相应的log优先级.
param: priority -- log
return: */
void log_backtrace(int32_t priority)
{
void *array[BACKTRACE_SIZE] = {NULL};
int32_t size = 0;
int32_t i = 0;
char **strings = NULL;
size = backtrace(array, BACKTRACE_SIZE);
if ((size <= 0) || ((size_t)size > BACKTRACE_SIZE))
{
log_err(LOG_DEFAULT, "Cannot get backtrace, returned invalid # of frames %d "
"(valid range is between 1 and %d)", size, BACKTRACE_SIZE);
return;
}
log_out(LOG_DEFAULT, priority, "Backtrace for %d stack frames:", size);
strings = backtrace_symbols(array, size);
if (!strings)
{
log_out(LOG_DEFAULT, priority, "Cannot get backtrace symbols (out of memory?)");
for (i = 0; i < size; i++)
log_out(LOG_DEFAULT, priority, "[bt %d] %p", i, array[i]);
}
else
{
for (i = 0; i < size; i++)
log_out(LOG_DEFAULT, priority, "[bt %d] %s",i,strings[i]);
free(strings);
}
}
/* 删除多余的 log 保留 5000 条. */
void log_clean(void)
{
log_sys_t *log = log_sys;
char *zErrMsg = NULL;
const char *sql = "delete from better_log where id<(select Max(id) from better_log)-5000;";
if (sqlite3_exec(log->db, sql, 0, 0, &zErrMsg) != SQLITE_OK)
{
printh("SQL delete error: %s\r\n", zErrMsg);
sqlite3_free(zErrMsg);
}
}
/* 读取log fifo数据循环线程 */
void *_log_handle( void *arg )
{
_log_msg_t *recv_msg = NULL;
while(1)
{
if (fifo_read( log_fifo.log_fifo_id, (void **)&recv_msg ) != 0)
{
DBG( DBG_M_FIFO, "ERROR at fifo %d read!\r\n", log_fifo.log_fifo_id );
continue;
}
if (recv_msg->type == LOG_OUT) //输出日志,写数据库
{
_log_out( (_log_out_t*) recv_msg->data );
}
else if (recv_msg->type == LOG_SHOW) //打印日志,读数据库
{
_log_show( (_log_show_t*) recv_msg->data );
}
fifo_push( log_fifo.log_fifo_id );
}
return NULL;
}
/* log线程初始化函数 */
int32_t _log_init_common( void )
{
struct sched_param param;
pthread_attr_t attr;
pthread_t pid;
int rv = 0;
/* 初始化log fifo */
log_fifo.log_fifo_id = fifo_create( LOG_DB_FIFO, 32 );
if (log_fifo.log_fifo_id < 0)
{
log_out( LOG_DEFAULT, LOG_LVL_ERR, "Open fifo " LOG_DB_FIFO " error." );
return E_ERROR;
}
pthread_mutex_init( &log_fifo.mutex, NULL );
/* 配置线程RR调度优先级50 */
pthread_attr_init( &attr );
param.sched_priority = 25;
pthread_attr_setschedpolicy( &attr, SCHED_RR );
pthread_attr_setschedparam( &attr, &param );
pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
rv = pthread_create( &pid, &attr, _log_handle, NULL );
if (rv != 0)
{
log_out( LOG_DEFAULT, LOG_LVL_ERR, "PD can't create log db pthread %d.", rv );
return E_SYS_CALL;
}
else
{
thread_m_add( "LOG_DB_THREAD", pid );
}
pthread_attr_destroy( &attr );
return E_NONE;
}
int32_t log_handle_init( void )
{
LD_E_RETURN( DBG_M_DBG, _log_init_common() );
return E_NONE;
}
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

File diff suppressed because it is too large Load Diff

@ -0,0 +1,688 @@
/******************************************************************************
* file lib/management/cli.c
* author YuLiang
* version 1.0.0
* date 10-Sep-2021
* brief This file provides all the cli related operation functions.
*
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
/* Standard includes. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <termios.h>
#include <pthread.h>
/* 外部程序库头文件. */
#include <readline/readline.h>
#include <readline/history.h>
/* User includes. */
#include "cli.h"
#include "list.h"
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static int32_t _cli_help(const char *cmd_str);
static int32_t _cli_version(const char *cmd_str);
static int32_t _cli_exit(const char *cmd_str);
/* The definition of the "help" command. This command is always at the front
of the list of registered commands. */
static const cli_command_t _cli_cmd_help =
{
"help",
"List all command.",
_cli_help,
0
};
static const cli_command_t _cli_cmd_version =
{
"version",
"Show device version information.",
_cli_version,
0
};
static const cli_command_t _cli_cmd_exit =
{
"exit",
"Returns the upper-level node.",
_cli_exit,
0
};
/* The definition of the list of commands. Commands that are registered are
added to this list. */
static cli_node_t _cli_node[CLI_NODE_COUNT] =
{
{"common", 0xffff, CLI_NODE_COMMON, {NULL, NULL}},
{"Username: ", 0, CLI_NODE_PASSWORD, {NULL, NULL}},
{"config", 0xffff, CLI_NODE_PASSWORD, {NULL, NULL}},
};
/* 保存readline命令行历史的文件. */
static const char _cli_history_file[128] = "/home/embed/.command_line_history";
/* 保存readline命令行内容的buf. */
static char *_cli_cmd_inpurt = NULL;
/* 当前cli所在的节点. */
static CLI_NODE_E _cli_now = CLI_NODE_PASSWORD;
/* 命令行用户链表. */
static struct list_head _cli_user_list;
/* cli线程pid. */
static pthread_t _cli_pid;
/* Private function prototypes -----------------------------------------------*/
extern char* version_get();
extern char* version_date_get();
static int8_t _cli_param_num_get(const char *cmd_str);
static cli_list_item_t *_cli_cmd_search(const char *cmd_str, CLI_NODE_E node);
/* Internal functions --------------------------------------------------------*/
/* 将node节点下的命令复制到cmd_list_new链表中并排序. */
static int32_t _cli_cmd_copy_for_node(struct list_head *cmd_list_new, CLI_NODE_E node)
{
struct list_head *cmd_list = NULL;
cli_list_item_t *cmd_item = NULL;
cli_list_item_t *cmd_item_new = NULL;
cli_list_item_t *cmd_item_temp = NULL;
cli_list_item_t *cmd_item_next = NULL;
int32_t rv = E_NONE;
cmd_list = &_cli_node[node].list;
list_for_each_entry(cmd_item, cmd_list, list)
{
/* 复制命令 */
cmd_item_new = XMALLOC(MTYPE_CLI, sizeof(cli_list_item_t));
if (NULL == cmd_item_new)
{
goto CMD_COPY_FOR_NODE_ERROR;
}
memcpy(cmd_item_new, cmd_item, sizeof(cli_list_item_t));
/* 命令排序 */
list_for_each_entry_reverse(cmd_item_temp, cmd_list_new, list)
{
if (strcmp(cmd_item_new->cmd->cmd_str, cmd_item_temp->cmd->cmd_str) > 0)
{
list_add(&cmd_item_new->list, &cmd_item_temp->list);
break;
}
}
/* 最小的命令放在链表头 */
if (&cmd_item_temp->list == cmd_list_new)
{
list_add(&cmd_item_new->list, &cmd_item_temp->list);
}
}
return rv;
/* 错误回滚已经申请的内存 */
CMD_COPY_FOR_NODE_ERROR:
list_for_each_entry_safe(cmd_item_temp, cmd_item_next, cmd_list_new, list)
{
list_del(&cmd_item_temp->list);
XFREE(MTYPE_CLI, cmd_item_temp);
}
return rv;
}
/* The callback function tyhat is executed when "help" is entered. This is the
only default command that is always present. */
static int32_t _cli_help(const char *cmd_str)
{
struct list_head cmd_list_new;
cli_list_item_t *cmd_item_temp = NULL;
cli_list_item_t *cmd_item_next = NULL;
INIT_LIST_HEAD(&cmd_list_new);
/* 复制命令 */
LD_E_RETURN(DBG_M_CLI, _cli_cmd_copy_for_node(&cmd_list_new, _cli_now));
LD_E_RETURN(DBG_M_CLI, _cli_cmd_copy_for_node(&cmd_list_new, CLI_NODE_COMMON));
/* 打印信息 */
list_for_each_entry(cmd_item_temp, &cmd_list_new, list)
{
printf("%-32s", cmd_item_temp->cmd->cmd_str);
printf("%s\r\n", cmd_item_temp->cmd->help_str);
}
printf("\n");
/* 释放内存 */
list_for_each_entry_safe(cmd_item_temp, cmd_item_next, &cmd_list_new, list)
{
list_del(&cmd_item_temp->list);
XFREE(MTYPE_CLI, cmd_item_temp);
}
return E_NONE;
}
static int32_t _cli_version(const char *cmd_str)
{
printf("Welcome To Power IoT Application, By LandPower Embed Application Team.\r\n");
printf("Copyright(c) 2021 LandPower. All rights reserved.\r\n");
printf("Software version %s, compile time is %s.\r\n\n", version_get(), version_date_get());
return E_NONE;
}
static int32_t _cli_exit(const char *cmd_str)
{
cli_quit_node();
return E_NONE;
}
/* Return the number of parameters that follow the command name. */
static int8_t _cli_param_num_get(const char *cmd_str)
{
int8_t num = 0;
bool is_end = FALSE;
/* Count the number of space delimited words in pcCommandString. */
while(*cmd_str != 0)
{
if (' ' == (*cmd_str))
{
if (is_end != TRUE)
{
num++;
is_end = TRUE;
}
}
else
{
is_end = FALSE;
}
cmd_str++;
}
/* If the command string ended with spaces, then there will have been too
many parameters counted. */
if( is_end == TRUE )
{
num--;
}
/* The value returned is one less than the number of space delimited words,
as the first word should be the command itself. */
return num;
}
/* 命令行查找 */
static cli_list_item_t *_cli_cmd_search(const char *cmd_str, CLI_NODE_E node)
{
struct list_head *cmd_list = &_cli_node[node].list;
cli_list_item_t *cmd_item = NULL;
const char *cmd_str_register = NULL;
size_t cmd_str_len = 0;
/* Search for the command string in the list of registered commands. */
list_for_each_entry(cmd_item, cmd_list, list)
{
cmd_str_register = cmd_item->cmd->cmd_str;
cmd_str_len = strlen(cmd_str_register);
/* To ensure the string lengths match exactly, so as not to pick up
a sub-string of a longer command, check the byte after the expected
end of the string is either the end of the string or a space before
a parameter. */
if ((cmd_str[cmd_str_len] != ' ') && (cmd_str[cmd_str_len] != 0x00))
{
continue;
}
if (0 == strncmp(cmd_str, cmd_str_register, cmd_str_len))
{
return cmd_item;
}
}
return NULL;
}
/* 获取命令行前缀 */
char *_cli_prefix_get(char *host)
{
static char buf[100] = {0};
if (0xffff == _cli_node[_cli_now].index)
{
snprintf(buf, sizeof(buf), "%s(%s)> ", host, _cli_node[_cli_now].name);
}
else
{
snprintf(buf, sizeof(buf), "%s(%s-%d)> ", host, _cli_node[_cli_now].name, _cli_node[_cli_now].index);
}
return buf;
}
/* readline初始化 */
void _cli_readline_init(void)
{
/* 修改自己的按键操作. */
//rl_bind_key('?', (rl_command_func_t *)vtysh_rl_question);
//rl_bind_key('\t', (rl_command_func_t *)vtysh_rl_completion);
/* do not append space after completion. It will be appended
* in new_completion() function explicitly. */
rl_completion_append_character = '\0';
read_history(_cli_history_file);
}
/* 密码处理函数 */
static int32_t _cli_process_password(const char * const cmd_str)
{
static cli_user_t user_login;
cli_user_t *user = NULL;
/* 表示在输入username */
if (0 == _cli_node[_cli_now].index)
{
/* 保存username,并进入输入password模式 */
_cli_node[_cli_now].index = 1;
snprintf(_cli_node[_cli_now].name, CLI_NODE_MAME_LEN, "Password: ");
snprintf(user_login.username, CLI_USERNAME_LEN, "%s", cmd_str);
return E_NONE;
}
else
{
_cli_node[_cli_now].index = 0;
snprintf(_cli_node[_cli_now].name, CLI_NODE_MAME_LEN, "Username: ");
/* 保存password,比较输入正确性 */
snprintf(user_login.password, CLI_USERNAME_LEN, "%s", cmd_str);
list_for_each_entry(user, &_cli_user_list, list)
{
if (0 == strcmp(user_login.username, user->username)
&& 0 == strcmp(user_login.password, user->password))
{
/* 找到匹配 */
printf("\r\n\n");
cli_entry_node(CLI_NODE_CONFIG, 0xffff);
return E_NONE;
}
}
}
return E_NOT_FOUND;
}
/* 添加一个新用户 */
int32_t _cli_user_add(const cli_user_t* const user)
{
cli_user_t *user_new = NULL;
user_new = XMALLOC(MTYPE_CLI, sizeof(cli_user_t));
if (NULL == user_new)
{
return E_MEM;
}
memcpy(user_new, user, sizeof(cli_user_t));
list_add(&user_new->list, &_cli_user_list);
return E_NONE;
}
void *_cli_handle(void *arg)
{
char *cmd = NULL;
/* 主循环 */
for(;;)
{
/* 输入命令. */
cmd = cli_shell_gets();
if (NULL == cmd)
{
continue;
}
/* 执行命令. */
cli_process_command(cmd);
}
}
/* Interface functions -------------------------------------------------------*/
/* description: 命令行注册函数.
param: cmd -- 要注册的命令行结构体
node -- 要注册到的节点
return: E_NONE -- OK
其他 -- ERROR */
int32_t cli_register_command(const cli_command_t* const cmd, CLI_NODE_E node)
{
struct list_head *cmd_list = &_cli_node[node].list;
cli_list_item_t *cmd_item = NULL;
/* Check the parameter is not NULL. */
if (NULL == cmd)
{
return E_NULL;
}
/* Create a new list item that will reference the command being registered. */
cmd_item = XMALLOC(MTYPE_CLI, sizeof(cli_list_item_t));
if (NULL == cmd_item)
{
return E_MEM;
}
/* Reference the command being registered from the newly created list item. */
cmd_item->cmd = cmd;
/* The new list item will get added to the end of the list. */
list_add(&cmd_item->list, cmd_list);
return E_NONE;
}
/* description: 命令行注册函数.
param: cmd_str -- 要执行的命令行
return: E_NONE -- OK
其他 -- ERROR */
int32_t cli_process_command(const char * const cmd_str)
{
static const cli_list_item_t *cmd_item = NULL;
int32_t rv = E_NONE;
/* 输入密码的过程不同于执行命令的过程 */
if (CLI_NODE_PASSWORD == _cli_now)
{
if (_cli_process_password(cmd_str) != E_NONE)
{
printf("Username or password is not match!!!\r\n\n");
return E_NOT_FOUND;
}
return E_NONE;
}
cmd_item = _cli_cmd_search(cmd_str, (CLI_NODE_E)_cli_now);
if (NULL == cmd_item)
{
cmd_item = _cli_cmd_search(cmd_str, CLI_NODE_COMMON);
}
/* The command has been found. Check it has the expected
number of parameters. If cExpectedNumberOfParameters is -1,
then there could be a variable number of parameters and no
check is made. */
if (cmd_item != NULL)
{
if (cmd_item->cmd->param_num >= 0
&& _cli_param_num_get(cmd_str) > cmd_item->cmd->param_num )
{
rv = E_BAD_PARAM;
}
}
if ((cmd_item != NULL) && (rv != E_NONE))
{
/* The command was found, but the number of parameters with the command
was incorrect. */
printf("%s", cli_param_erro);
cmd_item = NULL;
}
else if(cmd_item != NULL)
{
/* Call the callback function that is registered to this command. */
rv = cmd_item->cmd->function(cmd_str);
if (rv != E_NONE)
{
printf("Command(%s) return %d.\r\n\n", cmd_item->cmd->cmd_str, rv);
}
}
else
{
/* pxCommand was NULL, the command was not found. */
printf("Command not recognised.\r\n\n");
rv = E_NOT_FOUND;
}
return rv;
}
/* description: 进入命令行节点.
param: cmd_str -- 命令字符串
param_index -- 需要获取的参数索引
param_len -- 获取的参数长度
return: char* -- 获取的参数字符串 */
const char *cli_parameter_get(const char *cmd_str, int32_t param_index, OUT int32_t *param_len)
{
int32_t index = 0;
const char *param_str = NULL;
*param_len = 0;
while(index < param_index)
{
/* Index the character pointer past the current word. If this is the start
of the command string then the first word is the command itself. */
while(((*cmd_str) != 0x00 ) && ((*cmd_str) != ' '))
{
cmd_str++;
}
/* Find the start of the next string. */
while(((*cmd_str) != 0x00) && (' ' == (*cmd_str)))
{
cmd_str++;
}
/* Was a string found? */
if (*cmd_str != 0x00)
{
/* Is this the start of the required parameter? */
index++;
if (index == param_index)
{
/* How long is the parameter? */
param_str = cmd_str;
while(((*cmd_str) != 0x00 ) && ((*cmd_str) != ' '))
{
(*param_len)++;
cmd_str++;
}
if (*param_len == 0 || *param_len >= CLI_PARAM_LEN)
{
param_str = NULL;
}
break;
}
}
else
{
break;
}
}
return param_str;
}
/* description: 进入命令行节点.
param: node -- 节点号
index -- 节点内部索引
return: E_NONE -- OK
其他 -- ERROR */
int32_t cli_entry_node(CLI_NODE_E node, int16_t index)
{
if (node >= CLI_NODE_COUNT)
{
return E_BAD_PARAM;
}
_cli_now = node;
_cli_node[_cli_now].index = index;
return E_NONE;
}
/* description: 返回上一级节点.
param:
return: */
void cli_quit_node(void)
{
_cli_now = _cli_node[_cli_now].upper_node;
}
/* description: 命令行读取.
param:
return: char* -- 读取的一行命令 */
char *cli_shell_gets(void)
{
HIST_ENTRY *last = NULL;
struct termios new_setting,init_setting;
/* readline要求自己释放其返回的buf. */
if (_cli_cmd_inpurt)
{
free(_cli_cmd_inpurt);
_cli_cmd_inpurt = NULL;
}
/* 获取一行命令. */
if (CLI_NODE_PASSWORD == _cli_now)
{
/* 如果是输入密码则关闭回显. */
if (1 == _cli_node[_cli_now].index)
{
tcgetattr(0, &init_setting);
new_setting = init_setting;
new_setting.c_lflag &= ~ECHO;
tcsetattr(0,TCSANOW,&new_setting);
}
_cli_cmd_inpurt = readline(_cli_node[_cli_now].name);
if (1 == _cli_node[_cli_now].index)
{
tcsetattr(0,TCSANOW,&init_setting);
}
}
else
{
_cli_cmd_inpurt = readline(_cli_prefix_get("Power_IoT"));
/* 如果命令有效记录历史. */
if (_cli_cmd_inpurt && *_cli_cmd_inpurt)
{
using_history();
last = previous_history();
if (!last || strcmp (last->line, _cli_cmd_inpurt) != 0)
{
add_history(_cli_cmd_inpurt);
append_history(1, _cli_history_file);
}
}
}
//if (strlen(_cli_cmd_inpurt) > 0)
//{
// log_warn(LOG_CLI, "\"%s\" is input.", _cli_cmd_inpurt);
//}
return _cli_cmd_inpurt;
}
/* description: 命令行初始函数.
param:
return: */
int32_t cli_init(void)
{
struct sched_param param;
pthread_attr_t attr;
cli_user_t user_default;
int32_t i = 0;
int32_t rv = 0;
/* 初始化readline */
_cli_readline_init();
/* 初始化命令节点数据链表 */
for(i = 0; i < CLI_NODE_COUNT; i++)
{
INIT_LIST_HEAD(&_cli_node[i].list);
}
/* 注册公有命令 */
cli_register_command(&_cli_cmd_help, CLI_NODE_COMMON);
cli_register_command(&_cli_cmd_version, CLI_NODE_COMMON);
cli_register_command(&_cli_cmd_exit, CLI_NODE_COMMON);
/* 初始化用户列表 */
INIT_LIST_HEAD(&_cli_user_list);
/* 添加默认用户 */
memset(&user_default, 0, sizeof(cli_user_t));
snprintf(user_default.username, CLI_USERNAME_LEN, CLI_USERNAME_DEFAULT);
snprintf(user_default.password, CLI_USERNAME_LEN, CLI_PASSWORD_DEFAULT);
_cli_user_add(&user_default);
/* 配置线程RR调度,优先级50 */
pthread_attr_init(&attr);
param.sched_priority = 10;
pthread_attr_setschedpolicy(&attr, SCHED_RR);
pthread_attr_setschedparam(&attr, &param);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
rv = pthread_create(&_cli_pid, &attr, _cli_handle, NULL);
if (rv != 0)
{
DBG(DBG_M_CLI, "Can't create pthread %d\r\n", rv);
}
else
{
thread_m_add("CLI", _cli_pid);
}
pthread_attr_destroy(&attr);
return E_NONE;
}
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

File diff suppressed because it is too large Load Diff

@ -0,0 +1,643 @@
/******************************************************************************
* file lib/management/common.c
* author YuLiang
* version 1.0.0
* date 14-Sep-2021
* brief This file provides all the common operation functions.
*
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* 标准C库头文件. */
#include <sys/time.h>
#include <ctype.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/* 用户代码头文件. */
#include "vty.h"
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* 时间缓存结构体. */
typedef struct _time_cache
{
time_t last; /* 最后一次时间缓存数据. */
size_t len; /* buf中数据的长度. */
char buf[TIME_STR_LEN]; /* 时间数据转化的字符串. */
} time_cache_t;
/* Private variables ---------------------------------------------------------*/
static struct timeval sd_start, sd_end;
/* Private function prototypes -----------------------------------------------*/
extern void pd_wdg_clr(void);
/* Internal functions --------------------------------------------------------*/
/* 在时间后面根据precision长度,添加更加精确的时间字符串. */
static size_t _time_string_prec_add(char *buf, size_t len, int32_t precision, struct timeval *clock)
{
static const int divisor[] = {0, 100000, 10000, 1000, 100, 10, 1};
char *p = NULL;
/* 最多统计到us */
if (precision > 6)
precision = 6;
p = buf + len + 1 + precision;
*p-- = '\0';
clock->tv_usec /= divisor[precision];
do
{
*p-- = '0' + (clock->tv_usec % 10);
clock->tv_usec /= 10;
}
while(--precision > 0);
*p = '.';
return len + 1 + precision;
}
/* Interface functions -------------------------------------------------------*/
/* description: 将字符串转为小写.
param: str --
return: */
char *str_to_lower(char *str)
{
uint32_t i = 0;
if (str != NULL)
{
for(i = 0; str[i] != '\0'; i++)
{
str[i] = tolower(str[i]);
}
}
return str;
}
/* description: 去掉字符串中的多余空格.
param: str --
omit_end -- omit_end(TRUE)
omit_end(FALSE)1
return: */
char *str_omit_space(char *str, bool omit_end)
{
char *front = str;
char *last = str;
if (NULL == str)
{
return NULL;
}
while(' ' == *front)
front++;
while((*front) != '\0')
{
if (' ' == *front)
{
while((*++front) == ' ');
if ('\0' == *front && omit_end)
;
else
{
*last = ' ';
last++;
}
}
else
{
*last = *front;
front++;
last++;
}
}
*last = '\0';
return str;
}
/* description: 根据传入的精度precision,将时间字符串填到buf.
param: precision -- ,
buf -- buffer
buflen -- buf
return: ,,0 */
size_t time_string(int32_t precision, char *buf, size_t buflen)
{
static time_cache_t cache;
struct timeval clock;
/* 获取时间数据clock. */
gettimeofday(&clock, NULL);
/* 更新时间到字符串,cache是静态的,如果两次time_string调用在1秒之内,将沿用上次的cache. */
if (cache.last != clock.tv_sec)
{
struct tm *tm = NULL;
cache.last = clock.tv_sec;
tm = localtime(&cache.last);
cache.len = strftime(cache.buf, sizeof(cache.buf), "%Y/%m/%d %H:%M:%S", tm);
}
if (buflen > cache.len)
{
memcpy(buf, cache.buf, cache.len);
/* 计算秒之后的精度. */
if ((precision > 0) && (buflen > cache.len + 1 + precision))
return _time_string_prec_add(buf, cache.len, precision, &clock);
buf[cache.len] = '\0';
return cache.len;
}
/* buf太小,无法生成字符串. */
if (buflen > 0)
buf[0] = '\0';
return 0;
}
/* description: 获取错误代码字符串.
param: errnum --
return: */
const char *safe_strerror(int errnum)
{
const char *s = strerror(errnum);
return (s != NULL) ? s : "Unknown error";
}
/* description: 按16进制打印buf数据.
param: buf --
len --
return: */
void buf_print(char *buf, int32_t len)
{
int32_t i = 0;
for(i = 0; i < len;)
{
printh("%02x ", (uint8_t)buf[i++]);
if(0 == i % 32)
{
printh("\r\n");
}
}
if(i % 32 != 0)
{
printh("\r\n");
}
return;
}
/* description: 通过 ip 生成 mac 地址.
param: ip_str -- ip
mac -- mac
return: E_XXXX */
int32_t mac_generate_from_ip(char *ip_str, uint8_t *mac)
{
struct sockaddr_in server;
uint32_t ip = 0;
uint32_t temp = 0;
if (NULL == ip_str || NULL == mac)
{
return E_BAD_PARAM;
}
/* 将 ip_str 转为数字. */
if (inet_aton(ip_str, &server.sin_addr) < 0)
{
DBG(DBG_M_CLI, "inet_aton ip is error!\r\n");
return E_BAD_PARAM;
}
ip = server.sin_addr.s_addr;
/* 产生 mac. */
srand(time(NULL));
temp = rand();
mac[0] = 0x68;
mac[1] = temp & 0xff;
mac[2] = (temp >> 8) & 0xff;
mac[3] = (temp >> 16) & 0xff;
mac[4] = (temp >> 24) & 0xff;
mac[5] = (ip >> 24) & 0xff;
return E_NONE;
}
/* description: 计算CRC16/MODBUS.
param: data --
size --
return: crc */
uint16_t crc16(uint8_t *data, uint16_t size)
{
uint16_t crc = 0xFFFF;
uint8_t i = 0;
while(size--)
{
crc = crc ^ *data++;
for(i = 0; i < 8; i++)
{
if ((crc & 0x0001) > 0)
{
crc = crc >> 1;
crc = crc ^ 0xa001;
}
else
crc = crc >> 1;
}
}
return crc;
}
void invert_uint8(unsigned char *dest_buf, unsigned char *src_buf)
{
int i;
unsigned char tmp[4];
tmp[0] = 0;
for (i = 0; i < 8; i++)
{
if (src_buf[0] & (1 << i))
tmp[0] |= 1 << (7 - i);
}
dest_buf[0] = tmp[0];
}
void invert_uint16(unsigned short *dest_buf, unsigned short *src_buf)
{
int i;
unsigned short tmp[4];
tmp[0] = 0;
for (i = 0; i < 16; i++)
{
if (src_buf[0] & (1 << i))
tmp[0] |= 1 << (15 - i);
}
dest_buf[0] = tmp[0];
}
uint16_t crc16_modbus(uint8_t *data, uint16_t size)
{
unsigned short wCRCin = 0xFFFF;
unsigned short wCPoly = 0x8005;
unsigned char wChar = 0;
while (size--)
{
wChar = *(data++);
invert_uint8(&wChar, &wChar);
wCRCin ^= (wChar << 8);
int i = 0;
for (i = 0; i < 8; i++)
{
if (wCRCin & 0x8000)
wCRCin = (wCRCin << 1) ^ wCPoly;
else
wCRCin = wCRCin << 1;
}
}
invert_uint16(&wCRCin, &wCRCin);
return (wCRCin);
}
/* description: 时间统计开始.
param:
return: */
void speed_detection_stat(void)
{
gettimeofday(&sd_start, NULL);
}
/* description: 时间统计结束.
param:
return: */
void speed_detection_end(void)
{
float timeuse;
gettimeofday(&sd_end, NULL);
timeuse = 1000000 * (sd_end.tv_sec - sd_start.tv_sec) + sd_end.tv_usec - sd_start.tv_usec;
timeuse /= 1000000;
printh("Used Time:%f\r\n", timeuse);
}
/* description: 通用打印函数.
param:
return: */
int printh(const char *format, ...)
{
va_list args;
va_start(args, format);
vprintf(format, args);
vty_print(format, args);
va_end(args);
return 0;
}
/* description: 获取int16_t类型的版本号.
param:
return: int16_t */
uint16_t sofrware_version_get(void)
{
char version_str[16];
char *str = NULL;
char *p = NULL;
uint16_t version = 0;
snprintf(version_str, 16, "%s", version_get());
str = strtok_r(version_str, ".", &p);
while(str != NULL)
{
version = version << 8;
version |= (uint8_t)(atoi(str));
str = strtok_r(NULL, ".", &p);
}
return version;
}
/* description: 根据传入的字符串转换成mac地址.
param:
return: */
int32_t str_to_mac(char *mac_str, OUT uint8_t *mac)
{
char *str = NULL;
char *p = NULL;
uint8_t len = 0;
uint8_t i = 0;
/* 按:分词 */
str = strtok_r(mac_str, ":", &p);
while(str != NULL)
{
/* 检查mac长度 */
if (len >= 6)
{
return E_BAD_PARAM;
}
/* 检查字符串 */
for(i = 0; str[i] && str[i] != '\0'; i++)
{
if (!((str[i] >= '0' && str[i] <= '9')
|| (str[i] >= 'a' && str[i] <= 'f')
|| (str[i] >= 'A' && str[i] <= 'F')))
{
return E_BAD_PARAM;
}
}
/* 检查数据长度 */
if (i != 2)
{
return E_BAD_PARAM;
}
mac[len++] = strtol(str, NULL, 16);
/* 获取下个数据 */
str = strtok_r(NULL, ":", &p);
}
return E_NONE;
}
/* description: 根据传入的字符串转换成设备id.
param:
return: */
int32_t str_to_id(char *id_str, OUT uint32_t *id)
{
char *str = NULL;
char *p = NULL;
uint8_t len = 0;
uint8_t i = 0;
/* 按:分词 */
str = strtok_r(id_str, ".", &p);
while(str != NULL && len < 2)
{
/* 检查id长度 */
if (len >= 2)
{
return E_BAD_PARAM;
}
/* 检查字符串 */
for(i = 0; str[i] && str[i] != '\0'; i++)
{
if (!(str[i] >= '0' && str[i] <= '9'))
{
return E_BAD_PARAM;
}
}
id[len++] = strtol(str, NULL, 10);
/* 获取下个数据 */
str = strtok_r(NULL, ".", &p);
}
return E_NONE;
}
int32_t bitmap_set(uint8_t *buf, int32_t nbit, int32_t buf_len)
{
if ((NULL == buf) || (nbit >= buf_len * 8))
{
return E_BAD_PARAM;
}
buf[nbit / 8] |= 1 << (nbit % 8);
return E_NONE;
}
int32_t bitmap_reset(uint8_t *buf, int32_t nbit, int32_t buf_len)
{
if ((NULL == buf) || (nbit >= buf_len * 8))
{
return E_BAD_PARAM;
}
buf[nbit / 8] &= ~(1 << (nbit % 8));
return E_NONE;
}
int32_t is_bitmap_set(uint8_t *buf, int32_t nbit, int32_t buf_len)
{
if ((NULL == buf) || (nbit >= buf_len * 8))
{
return FALSE;
}
return buf[nbit / 8] & (1 << (nbit % 8));
}
int32_t time_str_to_long(char *date, char *time, uint32_t *t)
{
struct tm stm;
int32_t year, month, day, hour, minute,second;
if (sscanf(date, "%d-%d-%d", &year, &month, &day) != 3)
{
return E_BAD_PARAM;
}
if (sscanf(time, "%d:%d:%d", &hour, &minute, &second) != 3)
{
return E_BAD_PARAM;
}
stm.tm_year = year - 1900;
stm.tm_mon = month - 1;
stm.tm_mday = day;
stm.tm_hour = hour;
stm.tm_min = minute;
stm.tm_sec = second;
stm.tm_isdst = 0;
*t = mktime(&stm);
return E_NONE;
}
uint16_t version_str_to_int(void)
{
uint32_t version_m = 0;
uint32_t version_s = 0;
uint32_t n = 0;
n = sscanf(version_get(), "%d.%d", &version_m, &version_s);
if (n != 2)
{
return 0xffff;
}
return (version_m << 8 | (version_s & 0xff)) & 0xffff;
}
void time_set(time_t timestamp)
{
struct tm *p =localtime(&timestamp);
struct tm tptr = {0};
struct timeval tv = {0};
tptr.tm_year = p->tm_year;
tptr.tm_mon = p->tm_mon;
tptr.tm_mday = p->tm_mday;
tptr.tm_hour = p->tm_hour;
tptr.tm_min = p->tm_min;
tptr.tm_sec = p->tm_sec;
tv.tv_sec = mktime(&tptr);
tv.tv_usec = 0;
settimeofday(&tv, NULL);
}
void reboot_system(int module, BOOT_MSG type)
{
char *pmsg = NULL;
switch (type)
{
case BOOT_LOCAL_SERVER_IP_CHANGE:
pmsg = "Debug Tool has changed server ip.";
break;
case BOOT_LOCAL_SERVER_PORT_CHANGE:
pmsg = "Debug Tool has changed server port.";
break;
case BOOT_LOCAL_IP_CHANGE:
pmsg = "Debug Tool has changed device ip.";
break;
case BOOT_LOCAL_HOST_NAME_CHANGE:
pmsg = "Debug Tool has changed hostname.";
break;
case BOOT_LOCAL_RESET:
pmsg = "Debug Tool send reset command.";
break;
case BOOT_LOCAL_ARM_UPGRADE:
pmsg = "Debug Tool send ARM upgrade command.";
break;
case BOOT_LOCAL_FPGA_UPGRADE:
pmsg = "Debug Tool send FPGA upgrade command.";
break;
case BOOT_REMOTE_SERVER_IP_CHANGE:
pmsg = "Remote has changed server ip.";
break;
case BOOT_REMOTE_SERVER_PORT_CHANGE:
pmsg = "Remote has changed server port.";
break;
case BOOT_REMOTE_IP_CHANGE:
pmsg = "Remote has changed device ip.";
break;
case BOOT_REMOTE_HOST_NAME_CHANGE:
pmsg = "Remote has changed hostname.";
break;
case BOOT_REMOTE_RESET:
pmsg = "Remote send reset command.";
break;
case BOOT_SYSTEM_RESET:
pmsg = "System reboot...";
break;
default:
break;
}
if (pmsg)
{
log_out(module, LOG_LVL_WARN, pmsg);
log_out(module, LOG_LVL_WARN, "Now,start reboot system...");
system("sync");
pd_wdg_clr();
sleep(3);
system("reboot -f");
}
}
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,246 @@
/******************************************************************************
* file lib/management/common.c
* author YuLiang
* version 1.0.0
* date 14-Sep-2021
* brief This file provides all the debug operation functions.
*
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "cmd.h"
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
#ifdef CFG_DBG_ON
dbg_module_t _dbg_module[DBG_M_COUNT] =
{
{DBG_M_DBG, FALSE, "debug"},
{DBG_M_CLI, FALSE, "cli"},
{DBG_M_MTIMER, FALSE, "timer"},
{DBG_M_PROCESS, FALSE, "process"},
{DBG_M_GPIO, FALSE, "gpio"},
{DBG_M_PD, FALSE, "pd"},
{DBG_M_PD_ERR, FALSE, "pd_err"},
{DBG_M_PD_DAU, FALSE, "pd_dau"},
{DBG_M_PD_DAU_SEND, FALSE, "pd_dau_send"},
{DBG_M_PD_DAU_RECV, FALSE, "pd_dau_recv"},
{DBG_M_PD_DAU_ERR, TRUE, "pd_dau_err"},
{DBG_M_FIFO, FALSE, "fifo"},
{DBG_M_FIFO_ERR, FALSE, "fifo_err"},
{DBG_M_PD_CSG, FALSE, "csg"},
{DBG_M_PD_CSG_ERR, TRUE, "csg_err"},
{DBG_M_STORAGE_ERR, TRUE, "stroage"},
{DBG_M_DEBUG, FALSE, "debug"},
{DBG_M_PD_CPLD, TRUE, "cpld"},
};
/* Private function prototypes -----------------------------------------------*/
CMD(debug_on,
debug_on_cmd,
"debug WORD",
"Debug\n"
"Debug module\n")
{
int32_t i = 0;
for(i = 0; i < DBG_M_COUNT; i++)
{
if (strncmp(argv[0], _dbg_module[i].desc, strlen(_dbg_module[i].desc)))
{
continue;
}
dbg_cmd_hander(DBG_CMD_ON, i);
}
return CMD_SUCCESS;
}
CMD(no_debug_on,
no_debug_on_cmd,
"no debug WORD",
NO_STR
"Debug\n"
"Debug module\n")
{
int32_t i = 0;
for(i = 0; i < DBG_M_COUNT; i++)
{
if (strncmp(argv[0], _dbg_module[i].desc, strlen(argv[0])))
{
continue;
}
dbg_cmd_hander(DBG_CMD_OFF, i);
}
return CMD_SUCCESS;
}
CMD(no_debug_all,
no_debug_all_cmd,
"no debug",
NO_STR
"Debug\n")
{
dbg_cmd_hander(DBG_CMD_ALL_OFF, 0);
return CMD_SUCCESS;
}
CMD(show_debug_all,
show_debug_all_cmd,
"show debug",
SHOW_STR
"Debug state\n")
{
int32_t i = 0;
for(i = 0; i < DBG_M_COUNT; i++)
{
vty_out(vty, "%03d | %-16s %s%s", i, _dbg_module[i].desc, _dbg_module[i].stat ? "on" : "off", VTY_NEWLINE);
}
return CMD_SUCCESS;
}
/* Internal functions --------------------------------------------------------*/
/* 开指定模块的debug */
static int32_t _dbg_on(DBG_MODULE_E module)
{
if (module >= DBG_M_COUNT)
{
return E_BAD_PARAM;
}
_dbg_module[module].stat = TRUE;
return E_NONE;
}
/* 关指定模块的debug */
static int32_t _dbg_off(DBG_MODULE_E module)
{
if (module >= DBG_M_COUNT)
{
return E_BAD_PARAM;
}
_dbg_module[module].stat = FALSE;
return E_NONE;
}
/* 关所有模块的debug */
static int32_t _dbg_all_off(void)
{
unsigned int i = 0;
for(i = 0; i < DBG_M_COUNT; i++)
{
_dbg_module[i].stat = FALSE;
}
return E_NONE;
}
/* Interface functions -------------------------------------------------------*/
/* description: 获取当前模块debug状态.
param: module -- ID
return: (TRUE),(FALSE) */
int32_t dbg_stat_get(DBG_MODULE_E module)
{
if (module >= DBG_M_COUNT)
{
return FALSE;
}
return _dbg_module[module].stat;
}
/* description: debug模块命令函数分发.
param: module -- ID
return: (E_NONE),() */
int32_t dbg_cmd_hander(DBG_CMD_E cmd, int32_t module)
{
switch(cmd)
{
case DBG_CMD_ON:
LD_E_RETURN(DBG_M_DBG, _dbg_on(module));
break;
case DBG_CMD_OFF:
LD_E_RETURN(DBG_M_DBG, _dbg_off(module));
break;
case DBG_CMD_ALL_OFF:
LD_E_RETURN(DBG_M_DBG, _dbg_all_off());
break;
default:
break;
}
return E_NONE;
}
/* description: debug模块初始化.
param:
return: */
void dbg_init(void)
{
cmd_install_element(COMMON_NODE, &show_debug_all_cmd);
cmd_install_element(ENABLE_NODE, &debug_on_cmd);
cmd_install_element(ENABLE_NODE, &no_debug_on_cmd);
cmd_install_element(ENABLE_NODE, &no_debug_all_cmd);
}
#else
int32_t dbg_stat_get(DBG_MODULE_E module)
{
return FALSE;
}
int dbg_cmd_hander(DBG_CMD_E cmd, int32_t module)
{
return E_NONE;
}
void dbg_init(void)
{
}
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,275 @@
/******************************************************************************
* file lib/management/fifo.c
* author YuLiang
* version 1.0.0
* date 21-Feb-2023
* brief This file provides all the fifo operation functions.
*
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* 标准C库头文件. */
/* 用户代码头文件. */
#include "cmd.h"
#include "fifo.h"
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static array_t *fifo = NULL;
/* Private function prototypes -----------------------------------------------*/
/* Internal functions --------------------------------------------------------*/
/* 显示 fifo 的使用情况. */
CMD(show_fifo,
show_fifo_cmd,
"show fifo",
"Show\n"
"Fifo\n")
{
uint32_t id = 0;
fifo_t *fifo_node = NULL;
for (id = 0; id < array_active(fifo); id++)
{
fifo_node = array_lookup(fifo, id);
if (NULL == fifo_node)
{
continue;
}
fifo_show(id);
}
return CMD_SUCCESS;
}
/* Interface functions -------------------------------------------------------*/
/* 初始化 fifo 全局结构 */
int32_t fifo_init(void)
{
#if 0
fifo = array_init(16, MTYPE_FIFO);
if (!fifo)
{
log_err(LOG_FIFO, "ERROR at array init!");
return E_MEM;
}
#endif
cmd_install_element(COMMON_NODE, &show_fifo_cmd);
return E_NONE;
}
/* 创建 1 个 fifo. */
int32_t fifo_create(char* name, uint32_t size)
{
fifo_t *fifo_node = NULL;
/* 初始化. */
fifo_node = XMALLOC(MTYPE_FIFO, sizeof(fifo_t));
if (!fifo_node)
{
return E_MEM;
}
snprintf(fifo_node->name, FIFO_NAME_LEN, "%s", name);
fifo_node->size = size;
/* 申请互斥锁, 用于通知读线程读取有效. */
if (sem_init(&fifo_node->sem, 0, 0) != 0)
{
XFREE(MTYPE_FIFO, fifo_node);
DBG(DBG_M_FIFO_ERR, "%s ERROR at sem init return %s!\r\n", name, safe_strerror(errno));
return E_SYS_CALL;
}
/* 申请信号量, 防止多个线程同时操作 fifo. */
if (pthread_mutex_init(&fifo_node->mutex, NULL) != 0)
{
XFREE(MTYPE_FIFO, fifo_node);
sem_destroy(&fifo_node->sem);
DBG(DBG_M_FIFO_ERR, "%s ERROR at sem init return %s!\r\n", name, safe_strerror(errno));
return E_SYS_CALL;
}
/* 申请 fifo 空间. */
fifo_node->data = XMALLOC(MTYPE_FIFO, sizeof(void *) * size);
if (!fifo_node->data)
{
XFREE(MTYPE_FIFO, fifo_node);
sem_destroy(&fifo_node->sem);
pthread_mutex_destroy(&fifo_node->mutex);
return E_MEM;
}
/* 添加到全局结构体. */
return array_append(fifo, fifo_node, MTYPE_FIFO);
}
/* 往 fifo 中写入一条数据. */
int32_t fifo_write(uint32_t id, void *data, int32_t len)
{
int32_t index = 0;
fifo_t *fifo_node = array_get(fifo, id);
void *temp = NULL;
/* 参数检查. */
if (!fifo_node)
{
DBG_Q(DBG_M_FIFO_ERR, "#7\r\n");
return E_NOT_FOUND;
}
/* 申请数据空间. */
temp = XMALLOC_Q(MTYPE_FIFO, len);
if (!temp)
{
return E_MEM;
}
memcpy(temp, data, len);
pthread_mutex_lock(&fifo_node->mutex);
/* 判断 fifo 是否满了. */
index = fifo_node->cur + 1;
if (index == fifo_node->size)
{
index = 0;
}
if (index == fifo_node->valid)
{
DBG_Q(DBG_M_FIFO_ERR, "#8 %d\r\n", id);
XFREE(MTYPE_FIFO, temp);
pthread_mutex_unlock(&fifo_node->mutex);
return E_MEM;
}
/* 数据加入 fifo. */
fifo_node->data[fifo_node->cur] = temp;
fifo_node->used++;
if (fifo_node->used > fifo_node->max)
{
fifo_node->max = fifo_node->used;
}
fifo_node->cur = index;
sem_post(&fifo_node->sem);
pthread_mutex_unlock(&fifo_node->mutex);
return len;
}
/* 从 fifo 中读取数据, 注意, 只能一个进程进行读取. */
int32_t fifo_read(uint32_t id, void **data)
{
fifo_t *fifo_node = array_get(fifo, id);
/* 参数检查. */
if (!fifo_node)
{
DBG(DBG_M_FIFO_ERR, "Fifo %d is not found!\r\n", id);
return E_NOT_FOUND;
}
/* 等待有效数据, 如果有效, 返回数据. */
while (fifo_node->valid == fifo_node->cur)
{
sem_wait(&fifo_node->sem);
}
*data = fifo_node->data[fifo_node->valid];
return E_NONE;
}
/* 释放 fifo 数据, 因为节省了一次内存申请, 所以必须手动释放 fifo 数据. */
int32_t fifo_push(uint32_t id)
{
uint32_t index = 0;
fifo_t *fifo_node = array_get(fifo, id);
/* 检查参数. */
if (!fifo_node)
{
DBG(DBG_M_FIFO_ERR, "Fifo %d is not found!\r\n", id);
return E_NOT_FOUND;
}
/* 释放数据. */
if (fifo_node->valid != fifo_node->cur)
{
pthread_mutex_lock(&fifo_node->mutex);
XFREE(MTYPE_FIFO, fifo_node->data[fifo_node->valid]);
fifo_node->data[fifo_node->valid] = NULL;
index = fifo_node->valid + 1;
if (index == fifo_node->size)
{
index = 0;
}
fifo_node->used--;
fifo_node->valid = index;
pthread_mutex_unlock(&fifo_node->mutex);
}
return E_NONE;
}
/* 显示 fifo 的使用情况. */
void fifo_show(uint32_t id)
{
fifo_t *fifo_node = NULL;
fifo_node = array_lookup(fifo, id);
if (NULL == fifo_node)
{
return;
}
printh("%-32s %-2d %-2d %-2d %-2d %-2d %-2d\r\n", fifo_node->name, id, fifo_node->size, fifo_node->cur,
fifo_node->valid, fifo_node->used, fifo_node->max);
}
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,563 @@
/******************************************************************************
* file lib/management/memory.c
* author YuLiang
* version 1.0.0
* date 14-Sep-2021
* brief This file provides all the memory operation functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* 标准C库头文件. */
#include <malloc.h>
#include <sys/resource.h>
/* 用户代码头文件. */
#include "cmd.h"
/* Private define ------------------------------------------------------------*/
#define MEM_LOCK pthread_mutex_lock(&mem_mutex)
#define MEM_UNLOCK pthread_mutex_unlock(&mem_mutex)
/* Private macro -------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static mem_node_t mem_list_management[] =
{
{MTYPE_CLI, "Cli"},
{MTYPE_BUF, "Buffer"},
{MTYPE_BUF_DATA, "Buffer data"},
{MTYPE_BUF_TMP, "Buffer temp"},
{MTYPE_VTY, "Vty"},
{MTYPE_VTY_TMP, "Vty temp"},
{MTYPE_VTY_OUT_BUF, "Vty output buffer"},
{MTYPE_VTY_HIST, "Vty history"},
{MTYPE_HASH, "Hash"},
{MTYPE_HASH_BACKET, "Hash Bucket"},
{MTYPE_HASH_INDEX, "Hash Index"},
{MTYPE_LOG, "Logging"},
{MTYPE_MTIMER, "Timer"},
{MTYPE_THREAD_MONITOR, "Thread monitor"},
{MTYPE_PREFIX, "Prefix"},
{MTYPE_THREAD, "Thread"},
{MTYPE_THREAD_STATS, "Thread stats"},
{MTYPE_THREAD_MASTER, "Thread master"},
{MTYPE_THREAD_FUNCNAME, "Thread function name"},
{MTYPE_FIFO, "fifo"},
{MTYPE_GPIO, "gpio"},
{ -1, NULL },
};
static mem_node_t mem_list_transceiver[] =
{
{MTYPE_RECV, "Receive"},
{MTYPE_SENT, "Sent"},
{MTYPE_USART, "Usart"},
{MTYPE_ETH, "Ethernet"},
{ -1, NULL },
};
static mem_node_t mem_list_process[] =
{
{MTYPE_GIS, "GIS"},
{MTYPE_DAU, "DAU"},
{MTYPE_CSG, "CSG"},
{MTYPE_STORAGE, "STORAGE"},
{MTYPE_DEBUG, "DEBUG"},
{ -1, NULL },
};
static mem_list_t mlists[] __attribute__ ((unused)) =
{
{mem_list_management, "MANAGEMENT"},
{mem_list_transceiver, "TRANSCEIVER"},
{mem_list_process, "PROCESS"},
{NULL, NULL},
};
/* 同于统计每个模块申请内存的次数. */
static struct
{
const char *name;
int32_t alloc;
uint32_t t_malloc;
uint32_t c_malloc;
uint32_t t_calloc;
uint32_t c_calloc;
uint32_t t_realloc;
uint32_t t_free;
uint32_t c_strdup;
} mstat[MTYPE_MAX];
static pthread_mutex_t mem_mutex;
/* Private function prototypes -----------------------------------------------*/
/* Internal functions --------------------------------------------------------*/
/* 查找模块相应的说明字符串: key -- 模块 */
static const char *_x_desc_lookup(uint32_t key)
{
const mem_list_t *list = NULL;
const mem_node_t *pnt = NULL;
for(list = mlists; list->nodes != NULL; list++)
{
for(pnt = list->nodes; pnt->index >= 0; pnt++)
{
if (pnt->index == key)
{
return pnt->format;
}
}
}
return "";
}
/* 打印每个模块的内存使用情况: pri -- log优先级 */
static void _x_memstats_print(int32_t pri)
{
mem_list_t *ml = NULL;
for (ml = mlists; ml->nodes; ml++)
{
mem_node_t *m = NULL;
log_out(LOG_MEMORY, pri, "Memory utilization in module %s:", ml->name);
for(m = ml->nodes; m->index >= 0; m++)
{
if (m->index && mstat[m->index].alloc)
{
log_out(LOG_MEMORY, pri, " %-30s: %10ld", m->format, (long)mstat[m->index].alloc);
}
}
}
}
/* 打印内存申请错误信息: fname -- 调用的函数type -- 模块, size -- 大小 */
static void __attribute__ ((noreturn)) _x_mem_error(const char *fname, int32_t type, size_t size)
{
log_err(LOG_MEMORY, "%s : can't allocate memory for '%s' size %d: %s!",
fname, _x_desc_lookup(type), (int)size, safe_strerror(errno));
/* 打印每个模块的内存使用请款 */
_x_memstats_print(LOG_LVL_WARN);
/* 打印堆栈信息 */
log_backtrace(LOG_LVL_WARN);
abort();
}
/* 增加内存alloc计数 */
static void _x_alloc_inc(int32_t type)
{
MEM_LOCK;
mstat[type].alloc++;
MEM_UNLOCK;
}
/* 减少内存alloc计数 */
static void _x_alloc_dec(int32_t type)
{
MEM_LOCK;
mstat[type].alloc--;
MEM_UNLOCK;
}
/* 打印内存申请释放的debug信息. */
static void _x_mtype_log(char *func, void *memory, const char *file, int32_t line, uint32_t type)
{
//log_debug(LOG_MEMORY, "%s: %s %p %s %d", func, _x_desc_lookup(type), memory, file, line);
log_out(LOG_MEMORY, LOG_LVL_DBG,"%s: %s %p %s %d", func, _x_desc_lookup(type), memory, file, line);
}
/* Stats querying from users */
/* Return a pointer to a human friendly string describing
* the byte count passed in. E.g:
* "0 bytes", "2048 bytes", "110kB", "500MiB", "11GiB", etc.
* Up to 4 significant figures will be given.
* The pointer returned may be NULL (indicating an error)
* or point to the given buffer, or point to static storage. */
static const char *_x_mtype_memstr(char *buf, size_t len, uint32_t bytes)
{
int32_t t = 0;
int32_t g = 0;
int32_t m = 0;
int32_t k = 0;
/* easy cases */
if (!bytes)
return "0 bytes";
if (1 == bytes)
return "1 byte";
#if 0
if (sizeof(unsigned long) >= 8)
/* Hacked to make it not warn on ILP32 machines
* Shift will always be 40 at runtime. See below too */
t = bytes >> (sizeof (unsigned long) >= 8 ? 40 : 0);
else
t = 0;
#endif
g = bytes >> 30;
m = bytes >> 20;
k = bytes >> 10;
if (t > 10)
{
/* The shift will always be 39 at runtime.
* Just hacked to make it not warn on 'smaller' machines.
* Static compiler analysis should mean no extra code */
if (bytes & (1UL << (sizeof(unsigned long) >= 8 ? 39 : 0)))
t++;
snprintf (buf, len, "%4d TiB", t);
}
else if (g > 10)
{
if (bytes & (1 << 29))
g++;
snprintf (buf, len, "%d GiB", g);
}
else if (m > 10)
{
if (bytes & (1 << 19))
m++;
snprintf (buf, len, "%d MiB", m);
}
else if (k > 10)
{
if (bytes & (1 << 9))
k++;
snprintf (buf, len, "%d KiB", k);
}
else
snprintf (buf, len, "%d bytes", bytes);
return buf;
}
/* 打印内存使用情况根据系统调用. */
static int32_t _x_show_memory_mallinfo(vty_t *vty)
{
struct mallinfo minfo = mallinfo();
char buf[MTYPE_MEMSTR_LEN] = {0};
vty_out(vty, "System allocator statistics:%s", VTY_NEWLINE);
vty_out(vty, " Total heap allocated: %s%s",
_x_mtype_memstr(buf, MTYPE_MEMSTR_LEN, minfo.arena), VTY_NEWLINE);
vty_out(vty, " Holding block headers: %s%s",
_x_mtype_memstr(buf, MTYPE_MEMSTR_LEN, minfo.hblkhd), VTY_NEWLINE);
vty_out(vty, " Used small blocks: %s%s",
_x_mtype_memstr(buf, MTYPE_MEMSTR_LEN, minfo.usmblks), VTY_NEWLINE);
vty_out(vty, " Used ordinary blocks: %s%s",
_x_mtype_memstr(buf, MTYPE_MEMSTR_LEN, minfo.uordblks), VTY_NEWLINE);
vty_out(vty, " Free small blocks: %s%s",
_x_mtype_memstr(buf, MTYPE_MEMSTR_LEN, minfo.fsmblks), VTY_NEWLINE);
vty_out(vty, " Free ordinary blocks: %s%s",
_x_mtype_memstr(buf, MTYPE_MEMSTR_LEN, minfo.fordblks), VTY_NEWLINE);
vty_out(vty, " Ordinary blocks: %ld%s", (unsigned long)minfo.ordblks, VTY_NEWLINE);
vty_out(vty, " Small blocks: %ld%s", (unsigned long)minfo.smblks, VTY_NEWLINE);
vty_out(vty, " Holding blocks: %ld%s", (unsigned long)minfo.hblks, VTY_NEWLINE);
vty_out(vty, "(see system documentation for 'mallinfo' for meaning)%s", VTY_NEWLINE);
return 1;
}
static void _x_show_separator(vty_t *vty)
{
vty_out(vty, "-----------------------------%s", VTY_NEWLINE);
}
int32_t _x_show_memory_vty(vty_t *vty, mem_node_t *list)
{
mem_node_t *m = NULL;
int32_t needsep = 0;
for (m = list; m->index >= 0; m++)
if (0 == m->index)
{
if (needsep)
{
_x_show_separator(vty);
needsep = 0;
}
}
else
{
vty_out(vty, "%-30s: %10d%s", m->format, mstat[m->index].alloc, VTY_NEWLINE);
needsep = 1;
}
return needsep;
}
/* 申请内存,并增加相应的模块的申请数: type -- 模块size -- 大小 */
static void *_x_malloc (int32_t type, size_t size)
{
void *memory = NULL;
memory = malloc(size);
if (NULL == memory)
_x_mem_error("malloc", type, size);
memset(memory, 0, size);
_x_alloc_inc(type);
return memory;
}
/* 申请内存,并增加相应的模块的申请数: type -- 模块size -- 大小 */
static void *_x_malloc_q (int32_t type, size_t size)
{
void *memory = NULL;
memory = malloc(size);
if (NULL == memory)
_x_mem_error("malloc", type, size);
_x_alloc_inc(type);
return memory;
}
/* Allocate memory as in zmalloc, and also clear the memory. */
static void *_x_calloc(int32_t type, size_t size)
{
void *memory = NULL;
memory = calloc(1, size);
if (NULL == memory)
_x_mem_error("calloc", type, size);
memset(memory, 0, size);
_x_alloc_inc(type);
return memory;
}
/* Given a pointer returned by zmalloc or zcalloc, free it and
* return a pointer to a new size, basically acting like realloc().
* Requires: ptr was returned by zmalloc, zcalloc, or zrealloc with the
* same type.
* Effects: Returns a pointer to the new memory, or aborts. */
static void *_x_realloc(int32_t type, void *ptr, size_t size)
{
void *memory = NULL;
memory = realloc(ptr, size);
if (NULL == memory)
_x_mem_error("realloc", type, size);
if (NULL == ptr)
_x_alloc_inc(type);
return memory;
}
/* Free memory allocated by z*alloc or zstrdup.
* Requires: ptr was returned by zmalloc, zcalloc, or zrealloc with the
* same type.
* Effects: The memory is freed and may no longer be referenced. */
static void _x_free(int32_t type, void *ptr)
{
if (ptr != NULL)
{
_x_alloc_dec(type);
free(ptr);
}
}
/* Duplicate a string, counting memory usage by type.
* Effects: The string is duplicated, and the return value must
* eventually be passed to zfree with the same type. The function will
* succeed or abort. */
static char *_x_strdup(int32_t type, const char *str)
{
void *dup = NULL;
dup = strdup(str);
if (dup == NULL)
_x_mem_error("strdup", type, strlen(str));
_x_alloc_inc(type);
return dup;
}
/* Interface functions -------------------------------------------------------*/
/* description: 申请内存.
param: file --
line --
type --
size --
return: */
void *mtype_x_malloc(const char *file, int32_t line, int32_t type, size_t size)
{
void *memory = NULL;
mstat[type].c_malloc++;
mstat[type].t_malloc++;
memory = _x_malloc(type, size);
_x_mtype_log("x_malloc", memory, file, line, type);
return memory;
}
void *mtype_x_malloc_q(const char *file, int32_t line, int32_t type, size_t size)
{
void *memory = NULL;
mstat[type].c_malloc++;
mstat[type].t_malloc++;
memory = _x_malloc_q(type, size);
_x_mtype_log("x_malloc_q", memory, file, line, type);
return memory;
}
/* 见mtype_x_malloc. */
void *mtype_x_calloc(const char *file, int32_t line, int32_t type, size_t size)
{
void *memory = NULL;
mstat[type].c_calloc++;
mstat[type].t_calloc++;
memory = _x_calloc(type, size);
_x_mtype_log("x_calloc", memory, file, line, type);
return memory;
}
/* 见mtype_x_malloc. */
void *mtype_x_realloc(const char *file, int32_t line, int32_t type, void *ptr, size_t size)
{
void *memory = NULL;
/* Realloc need before allocated pointer. */
mstat[type].t_realloc++;
memory = _x_realloc(type, ptr, size);
_x_mtype_log("x_realloc", memory, file, line, type);
return memory;
}
/* 见mtype_x_malloc. */
void mtype_x_free(const char *file, int32_t line, int32_t type, void *ptr)
{
mstat[type].t_free++;
_x_free(type, ptr);
_x_mtype_log("x_free", ptr, file, line, type);
}
/* 见mtype_x_malloc. */
char *mtype_x_strdup(const char *file, int32_t line, int32_t type, const char *str)
{
char *memory = NULL;
mstat[type].c_strdup++;
memory = _x_strdup(type, str);
_x_mtype_log("x_strdup", memory, file, line, type);
return memory;
}
CMD(show_memory_all,
show_memory_all_cmd,
"show memory",
SHOW_STR
"Memory statistics\n")
{
mem_list_t *ml = NULL;
int needsep = 0;
needsep = _x_show_memory_mallinfo(vty);
for (ml = mlists; ml->nodes; ml++)
{
if (needsep)
_x_show_separator(vty);
needsep = _x_show_memory_vty(vty, ml->nodes);
}
return CMD_SUCCESS;
}
void mem_show(vty_t *vty)
{
mem_list_t *ml = NULL;
int needsep = 0;
for (ml = mlists; ml->nodes; ml++)
{
if (needsep)
_x_show_separator(vty);
needsep = _x_show_memory_vty(vty, ml->nodes);
}
}
/* description: memory模块初始化.
param:
return: */
void mtype_init(void)
{
cmd_install_element(COMMON_NODE, &show_memory_all_cmd);
}
/* description: memory模块初始化.
param:
return: */
void mtype_init_befor(void)
{
/* 初始化线程锁. */
pthread_mutex_init(&mem_mutex, NULL);
}
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,3 @@
local_src := $(patsubst $(SOURCE_DIR)/%,%,$(wildcard $(SOURCE_DIR)/$(subdirectory)/*.c))
$(eval $(call make-library,$(subdirectory)/libm_management.a,$(local_src)))

@ -0,0 +1,245 @@
/*****************************************************************************
* file lib/management/mtimer.c
* author Yuliang
* version 1.0.0
* date 22-Sep-2021
* brief This file provides all the timer related operation functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/time.h>
#include <pthread.h>
#include <signal.h>
#include "array.h"
#include "mtimer.h"
#include "cmd.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static pthread_t mtimer_pid;
static array_t *mtimer_array;
static pthread_mutex_t mtimer_mutex;
/* Private function prototypes -----------------------------------------------*/
extern void _mtimer_lock(void);
extern void _mtimer_unlock(void);
/* 485设备显示. */
CMD(mtime_show,
mtime_show_cmd,
"show mtime",
SHOW_STR
"mtime\n")
{
mtimer_t *entry = NULL;
uint32_t i = 0;
/* 遍历所有外设 */
_mtimer_lock();
vty_out(vty, "ID %-32s INR%s", "NAME", VTY_NEWLINE);
for (i = 0; i < array_active(mtimer_array); i++)
{
entry = array_lookup(mtimer_array, i);
if (NULL == entry)
{
continue;
}
vty_out(vty, "%-02d %-32s %d%s", i, entry->name, entry->interval, VTY_NEWLINE);
}
_mtimer_unlock();
return CMD_SUCCESS;
}
/* Internal functions --------------------------------------------------------*/
void _mtimer_lock(void)
{
pthread_mutex_lock(&mtimer_mutex);
}
void _mtimer_unlock(void)
{
pthread_mutex_unlock(&mtimer_mutex);
}
/* 定时器线程. */
void *_mtimer_process(void *arg)
{
uint32_t i = 0;
uint32_t t = 0;
mtimer_t *entry = NULL;
while(1)
{
/* 最小粒度1s */
sleep(1);
/* 遍历所有定时器 */
_mtimer_lock();
t = time(NULL);
for (i = 0; i < array_active(mtimer_array); i++)
{
entry = array_lookup(mtimer_array, i);
if (NULL == entry)
{
continue;
}
/* 判断时间有没有到 */
if (abs(t - entry->time) < entry->interval)
{
continue;
}
/* 调用回调函数 */
entry->handle(entry->arg);
/* 删除定时器 */
array_unset(mtimer_array, i);
XFREE(MTYPE_MTIMER, entry);
}
_mtimer_unlock();
}
return NULL;
}
/* Interface functions -------------------------------------------------------*/
/* description: 添加定时器.
param:
return: (E_NONE),() */
int32_t mtimer_add(MTIMER_CALLBACK func, void *arg, uint16_t interval, char *name)
{
mtimer_t *timer = NULL;
_mtimer_lock();
timer = XMALLOC(MTYPE_MTIMER, sizeof(mtimer_t));
if (NULL == timer)
{
DBG(DBG_M_MTIMER, "Malloc error!\r\n");
_mtimer_unlock();
return E_MEM;
}
timer->handle = func;
timer->arg = arg;
snprintf(timer->name, DEV_NAME_STR_LEN, "%s", name);
timer->interval = interval;
timer->time = time(NULL);
array_append(mtimer_array, timer, MTYPE_MTIMER);
_mtimer_unlock();
return E_NONE;
}
/* description: 删除定时器.
param:
return: (E_NONE),() */
int32_t mtimer_del(MTIMER_CALLBACK func, void *arg)
{
uint32_t i = 0;
mtimer_t *entry = NULL;
_mtimer_lock();
/* 遍历数组 */
for (i = 0; i < array_active(mtimer_array); i++)
{
entry = array_lookup(mtimer_array, i);
if (NULL == entry)
{
continue;
}
/* 比较数据 */
if (entry->handle == func && entry->arg == arg)
{
/* 删除定时器 */
array_unset(mtimer_array, i);
XFREE(MTYPE_MTIMER, entry);
}
}
_mtimer_unlock();
return E_NONE;
}
/* description: 定时器初始化.
param:
return: (E_NONE),() */
int32_t mtimer_init(void)
{
#if 0
struct sched_param param;
pthread_attr_t attr;
pthread_mutexattr_t attr_m;
/* 初始化用户列表 */
mtimer_array = array_init(16, MTYPE_MTIMER);
/* 递归锁 */
pthread_mutexattr_init(&attr_m);
pthread_mutexattr_settype(&attr_m, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mtimer_mutex, &attr_m);
/* 配置线程RR调度,优先级50 */
pthread_attr_init(&attr);
param.sched_priority = 50;
pthread_attr_setschedpolicy(&attr, SCHED_RR);
pthread_attr_setschedparam(&attr, &param);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
/* 创建接收数据线程. */
if (pthread_create(&mtimer_pid, &attr, _mtimer_process, NULL) != 0)
{
log_err(LOG_DEFAULT, "mtimer_init can't create pthread!");
}
else
{
thread_m_add("TIMER", mtimer_pid);
}
pthread_attr_destroy(&attr);
#endif
cmd_install_element(COMMON_NODE, &mtime_show_cmd);
return E_NONE;
}
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

@ -0,0 +1,605 @@
/******************************************************************************
* file lib/management/sockunion.c
* author YuLiang
* version 1.0.0
* date 14-Sep-2021
* brief This file provides all the sockunion operation functions.
*
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <net/route.h>
#include <arpa/inet.h>
#include "memory.h"
#include "sockunion.h"
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Maskbit. */
static const u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
0xf8, 0xfc, 0xfe, 0xff};
/* Static structure for IPv4 access_list's master. */
static access_master_t access_master_ipv4 =
{
{NULL, NULL},
{NULL, NULL},
NULL,
NULL,
};
#ifdef HAVE_IPV6
/* Static structure for IPv6 access_list's master. */
static access_master_t access_master_ipv6 =
{
{NULL, NULL},
{NULL, NULL},
NULL,
NULL,
};
#endif /* HAVE_IPV6 */
/* Private function prototypes -----------------------------------------------*/
/* Internal functions --------------------------------------------------------*/
/* Malloc prefix structure. */
static prefix_t *_prefix_new(void)
{
prefix_t *p = NULL;
p = XMALLOC(MTYPE_PREFIX, sizeof(prefix_t));
return p;
}
/* Interface functions -------------------------------------------------------*/
/* Free prefix structure. */
void prefix_free(prefix_t *p)
{
XFREE(MTYPE_PREFIX, p);
}
/* Allocate new prefix_ipv4 structure. */
prefix_ipv4_t *prefix_ipv4_new(void)
{
prefix_ipv4_t *p = NULL;
/* Call prefix_new to allocate a full-size struct prefix to avoid problems
* where the prefix_ipv4_t is cast to struct prefix and unallocated
* bytes were being referenced (e.g. in structure assignments). */
p = (prefix_ipv4_t *)_prefix_new();
p->family = AF_INET;
return p;
}
#ifdef HAVE_IPV6
/* Allocate a new ip version 6 route */
prefix_ipv6_t *prefix_ipv6_new (void)
{
prefix_ipv6_t *p = NULL;
/* Allocate a full-size struct prefix to avoid problems with structure
* 8 size mismatches. */
p = (prefix_ipv6_t *)_prefix_new();
p->family = AF_INET6;
return p;
}
#endif
static access_master_t *_access_master_get(uint16_t afi)
{
if (AFI_IP == afi)
return &access_master_ipv4;
#ifdef HAVE_IPV6
else if (AFI_IP6 == afi)
return &access_master_ipv6;
#endif /* HAVE_IPV6 */
return NULL;
}
/* If filter match to the prefix then return 1. */
static int _filter_match_cisco(filter_t *mfilter, prefix_t *p)
{
filter_cisco_t *filter = NULL;
struct in_addr mask;
uint32_t check_addr = 0;
uint32_t check_mask = 0;
filter = &mfilter->u.cfilter;
check_addr = p->u.prefix4.s_addr & ~filter->addr_mask.s_addr;
if (filter->extended)
{
masklen2ip(p->prefixlen, &mask);
check_mask = mask.s_addr & ~filter->mask_mask.s_addr;
if (0 == memcmp(&check_addr, &filter->addr.s_addr, 4) &&
0 == memcmp(&check_mask, &filter->mask.s_addr, 4))
return 1;
}
else if (0 == memcmp(&check_addr, &filter->addr.s_addr, 4))
return 1;
return 0;
}
/* If filter match to the prefix then return 1. */
static int _filter_match_zebra(filter_t *mfilter, prefix_t *p)
{
filter_zebra_t *filter= NULL;
filter = &mfilter->u.zfilter;
if (filter->prefix.family == p->family)
{
if (filter->exact)
{
if (filter->prefix.prefixlen == p->prefixlen)
return prefix_match(&filter->prefix, p);
else
return 0;
}
else
return prefix_match(&filter->prefix, p);
}
else
return 0;
}
/* Lookup access_list from list of access_list by name. */
access_list_t *access_list_lookup(uint16_t afi, const char *name)
{
access_list_t *access = NULL;
access_master_t *master = NULL;
if (NULL == name)
return NULL;
master = _access_master_get(afi);
if (NULL== master)
return NULL;
for(access = master->num.head; access; access = access->next)
if (0 == strcmp(access->name, name))
return access;
for(access = master->str.head; access; access = access->next)
if (0 == strcmp(access->name, name))
return access;
return NULL;
}
/* Apply access list to object (which should be prefix_t *). */
FILTER_TYPE_E access_list_apply(access_list_t *access, void *object)
{
filter_t *filter = NULL;
prefix_t *p = NULL;
p = (prefix_t *)object;
if (NULL == access)
return FILTER_DENY;
for (filter = access->head; filter; filter = filter->next)
{
if (filter->cisco)
{
if (_filter_match_cisco(filter, p))
return filter->type;
}
else
{
if (_filter_match_zebra(filter, p))
return filter->type;
}
}
return FILTER_DENY;
}
/* Convert masklen into IP address's netmask. */
void masklen2ip(int masklen, struct in_addr *netmask)
{
uint8_t *pnt = NULL;
int32_t bit = 0;
int32_t offset = 0;
memset(netmask, 0, sizeof(struct in_addr));
pnt = (unsigned char *)netmask;
offset = masklen / 8;
bit = masklen % 8;
while(offset--)
*pnt++ = 0xff;
if (bit)
*pnt = maskbit[bit];
}
/* If n includes p prefix then return 1 else return 0. */
int prefix_match(const prefix_t *n, const prefix_t *p)
{
int32_t offset = 0;
int32_t shift = 0;
const uint8_t *np = NULL;
const uint8_t *pp = NULL;
/* If n's prefix is longer than p's one return 0. */
if (n->prefixlen > p->prefixlen)
return 0;
/* Set both prefix's head pointer. */
np = (const u_char *)&n->u.prefix;
pp = (const u_char *)&p->u.prefix;
offset = n->prefixlen / PNBBY;
shift = n->prefixlen % PNBBY;
if (shift)
if (maskbit[shift] & (np[offset] ^ pp[offset]))
return 0;
while (offset--)
if (np[offset] != pp[offset])
return 0;
return 1;
}
/* Convert IPv4 compatible IPv6 address to IPv4 address. */
static void _sockunion_normalise_mapped(SOCKUNION_U *su)
{
#ifdef HAVE_IPV6
struct sockaddr_in sin;
if (AF_INET6 == su->sa.sa_family &&
IN6_IS_ADDR_V4MAPPED(&su->sin6.sin6_addr))
{
memset(&sin, 0, sizeof(struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = su->sin6.sin6_port;
memcpy(&sin.sin_addr, ((char *)&su->sin6.sin6_addr) + 12, 4);
memcpy(su, &sin, sizeof(struct sockaddr_in));
}
#endif /* HAVE_IPV6 */
}
int str2sockunion(const char *str, SOCKUNION_U *su)
{
int ret = 0;
memset(su, 0, sizeof(SOCKUNION_U));
ret = inet_pton(AF_INET, str, &su->sin.sin_addr);
/* Valid IPv4 address format. */
if (ret > 0)
{
su->sin.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
su->sin.sin_len = sizeof(struct sockaddr_in);
#endif
return 0;
}
#ifdef HAVE_IPV6
ret = inet_pton(AF_INET6, str, &su->sin6.sin6_addr);
/* Valid IPv6 address format. */
if (ret > 0)
{
su->sin6.sin6_family = AF_INET6;
#ifdef SIN6_LEN
su->sin6.sin6_len = sizeof(struct sockaddr_in6);
#endif
return 0;
}
#endif
return -1;
}
const char *sockunion2str(SOCKUNION_U *su, char *buf, size_t len)
{
if (AF_INET == su->sa.sa_family)
return inet_ntop(AF_INET, &su->sin.sin_addr, buf, len);
#ifdef HAVE_IPV6
else if(AF_INET6 == su->sa.sa_family)
return inet_ntop(AF_INET6, &su->sin6.sin6_addr, buf, len);
#endif
return NULL;
}
/* Return accepted new socket file descriptor. */
int sockunion_accept(int sock, SOCKUNION_U *su)
{
socklen_t len;
int client_sock;
len = sizeof(SOCKUNION_U);
client_sock = accept(sock, (struct sockaddr*)su, &len);
_sockunion_normalise_mapped(su);
return client_sock;
}
int set_nonblocking(int fd)
{
int flags = 0;
/* According to the Single UNIX Spec, the return value for F_GETFL should
* never be negative. */
if ((flags = fcntl(fd, F_GETFL)) < 0)
{
printh("fcntl(F_GETFL) failed for fd %d: %s", fd, safe_strerror(errno));
return -1;
}
if (fcntl(fd, F_SETFL, (flags | O_NONBLOCK)) < 0)
{
printh("fcntl failed setting fd %d non-blocking: %s", fd, safe_strerror(errno));
return -1;
}
return 0;
}
/* Utility function of convert between struct prefix <=> union sockunion. */
prefix_t *sockunion2hostprefix(const SOCKUNION_U *su)
{
if (su->sa.sa_family == AF_INET)
{
prefix_ipv4_t *p = NULL;
p = prefix_ipv4_new();
p->family = AF_INET;
p->prefix = su->sin.sin_addr;
p->prefixlen = IPV4_MAX_BITLEN;
return (prefix_t*)p;
}
#ifdef HAVE_IPV6
if (su->sa.sa_family == AF_INET6)
{
prefix_ipv6_t *p = NULL;
p = prefix_ipv6_new();
p->family = AF_INET6;
p->prefixlen = IPV6_MAX_BITLEN;
memcpy(&p->prefix, &su->sin6.sin6_addr, sizeof(struct in6_addr));
return (prefix_t*)p;
}
#endif /* HAVE_IPV6 */
return NULL;
}
char *sockunion_su2str(SOCKUNION_U *su)
{
char str[SU_ADDRSTRLEN] = {0};
switch (su->sa.sa_family)
{
case AF_INET:
inet_ntop(AF_INET, &su->sin.sin_addr, str, sizeof(str));
break;
#ifdef HAVE_IPV6
case AF_INET6:
inet_ntop(AF_INET6, &su->sin6.sin6_addr, str, sizeof(str));
break;
#endif /* HAVE_IPV6 */
}
return XSTRDUP(MTYPE_PREFIX, str);
}
/* Make socket from sockunion union. */
int sockunion_stream_socket(SOCKUNION_U *su)
{
int32_t sock = 0;
if (0 == su->sa.sa_family)
su->sa.sa_family = AF_INET_UNION;
sock = socket(su->sa.sa_family, SOCK_STREAM, 0);
if (sock < 0)
printh("can't make socket sockunion_stream_socket");
return sock;
}
int sockunion_reuseaddr(int sock)
{
int ret;
int on = 1;
ret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on));
if (ret < 0)
{
printh("can't set sockopt SO_REUSEADDR to socket %d", sock);
return -1;
}
return 0;
}
/* Bind socket to specified address. */
int sockunion_bind(int sock, SOCKUNION_U *su, unsigned short port, SOCKUNION_U *su_addr)
{
int size = 0;
int ret = 0;
if (AF_INET == su->sa.sa_family)
{
size = sizeof(struct sockaddr_in);
su->sin.sin_port = htons(port);
if (NULL == su_addr)
su->sin.sin_addr.s_addr = htonl(INADDR_ANY);
}
#ifdef HAVE_IPV6
else if(AF_INET6 == su->sa.sa_family)
{
size = sizeof(struct sockaddr_in6);
su->sin6.sin6_port = htons(port);
if (NULL == su_addr)
memset (&su->sin6.sin6_addr, 0, sizeof(struct in6_addr));
}
#endif /* HAVE_IPV6 */
ret = bind(sock, (struct sockaddr *)su, size);
if (ret < 0)
printh("xxcan't bind socket : %s\n", safe_strerror(errno));
return ret;
}
int sockunion_ip_set(char *name, unsigned int addr)
{
int fd = 0;
struct ifreq ifr;
struct sockaddr_in *sin = NULL;
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
{
printh("Ip set socket error!\r\n");
return -1;
}
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, name);
sin = (struct sockaddr_in*)&ifr.ifr_addr;
sin->sin_family = AF_INET;
/* IP地址 */
sin->sin_addr.s_addr = addr;
if (ioctl(fd, SIOCSIFADDR, &ifr) < 0)
{
close(fd);
printh("Ip set ioctl SIOCSIFADDR error!\r\n");
return -2;
}
close(fd);
return 0;
}
int sockunion_mask_set(char *name, unsigned int mask)
{
int fd = 0;
struct ifreq ifr;
struct sockaddr_in *sin = NULL;
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
{
printh("socket error\r\n");
return -1;
}
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, name);
sin = (struct sockaddr_in*)&ifr.ifr_addr;
sin->sin_family = AF_INET;
/* 子网掩码 */
sin->sin_addr.s_addr = mask;
if (ioctl(fd, SIOCSIFNETMASK, &ifr) < 0)
{
close(fd);
printh("ioctl\r\n");
return -3;
}
close(fd);
return 0;
}
int sockunion_gw_set(char *name, unsigned int gateway, unsigned int gateway_old)
{
int fd = 0;
struct rtentry rt;
int rv = 0;
fd = socket(PF_INET, SOCK_DGRAM, 0);
if (fd < 0)
{
printh("Gateway set socket error!\r\n");
return -1;
}
/* Delete existing defalt gateway */
memset(&rt, 0, sizeof(rt));
rt.rt_dst.sa_family = AF_INET;
((struct sockaddr_in *)&rt.rt_dst)->sin_addr.s_addr = 0;
rt.rt_gateway.sa_family = AF_INET;
((struct sockaddr_in *)&rt.rt_gateway)->sin_addr.s_addr = gateway_old;
rt.rt_genmask.sa_family = AF_INET;
((struct sockaddr_in *)&rt.rt_genmask)->sin_addr.s_addr = 0;
rt.rt_flags = RTF_UP;
rv = ioctl(fd, SIOCDELRT, &rt);
/* Set default gateway */
if ((rv == 0 || errno == ESRCH) && gateway)
{
memset(&rt, 0, sizeof(rt));
rt.rt_dst.sa_family = AF_INET;
((struct sockaddr_in *)&rt.rt_dst)->sin_addr.s_addr = 0;
rt.rt_gateway.sa_family = AF_INET;
((struct sockaddr_in *)&rt.rt_gateway)->sin_addr.s_addr = gateway;
rt.rt_genmask.sa_family = AF_INET;
((struct sockaddr_in *)&rt.rt_genmask)->sin_addr.s_addr = 0;
rt.rt_flags = RTF_UP | RTF_GATEWAY;
rv = ioctl(fd, SIOCADDRT, &rt);
}
close(fd);
return rv;
}
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,125 @@
/*****************************************************************************
* file lib/management/thread_monitor.c
* author Yuliang
* version 1.0.0
* date 08-Oct-2021
* brief This file provides all the thread monitor related operation functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "array.h"
#include "cmd.h"
#include "thread_monitor.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define THREAD_M_SIZE 32
#define THREAD_LOCK pthread_mutex_lock(&thread_mutex)
#define THREAD_UNLOCK pthread_mutex_unlock(&thread_mutex)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static pthread_mutex_t thread_mutex;
static array_t *thread_a;
/* Private function prototypes -----------------------------------------------*/
extern int pthread_tryjoin_np(pthread_t thread, void **retval);
/* Internal functions --------------------------------------------------------*/
CMD(thread_show,
thread_show_cmd,
"show thread",
SHOW_STR
"thread\n")
{
thread_m_t *node = NULL;
int32_t i = 0;
for (i = 0; i < thread_a->active; i++)
{
if (thread_a->index[i] != NULL)
{
node = (thread_m_t*)thread_a->index[i];
/* 当返回不为EBUSY时说明线程退出或者出错了,但是再次查询又会变为EBUSY,
FALSE,TRUE. */
if (pthread_tryjoin_np(node->pid, NULL) != EBUSY)
{
node->alive = FALSE;
}
vty_out(vty, "%-32s %-2d%s", node->name, node->alive, VTY_NEWLINE);
}
}
vty_out(vty, "%s", VTY_NEWLINE);
return CMD_SUCCESS;
}
/* Interface functions -------------------------------------------------------*/
/* description: 添加需要监控的线程.
param:
return: (E_NONE),() */
int32_t thread_m_add(char *str, pthread_t pid)
{
thread_m_t *node = NULL;
node = XMALLOC(MTYPE_THREAD_MONITOR, sizeof(thread_m_t));
snprintf(node->name, THREAD_M_NAME_LEN, "%s", str);
node->pid = pid;
node->alive = TRUE;
THREAD_LOCK;
array_append(thread_a, node, MTYPE_THREAD_MONITOR);
THREAD_UNLOCK;
return E_NONE;
}
/* description: 线程监控初始化.
param:
return: (E_NONE),() */
int32_t thread_m_init(void)
{
/* 初始化线程锁. */
pthread_mutex_init(&thread_mutex, NULL);
thread_a = array_init(THREAD_M_SIZE, MTYPE_THREAD_MONITOR);
cmd_install_element(COMMON_NODE, &thread_show_cmd);
return E_NONE;
}
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

File diff suppressed because it is too large Load Diff

@ -0,0 +1,428 @@
/******************************************************************************
* file lib/hardware/hwgpio.c
* author YuLiang
* version 1.0.0
* date 24-Nov-2021
* brief This file provides all the gpio operation functions.
*
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* 标准C库头文件. */
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/* 用户代码头文件. */
#include "hwgpio.h"
#include "cmd.h"
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static array_t *gpios = NULL;
int32_t gpio_dau1_pow_idx;
int32_t gpio_dau2_pow_idx;
int32_t gpio_run_idx;
int32_t gpio_sync_idx;
int32_t gpio_err1_idx;
/* Private function prototypes -----------------------------------------------*/
/* Internal functions --------------------------------------------------------*/
int32_t _gpio_name_get(uint8_t gpio, char *name)
{
if (!name)
{
return E_NULL;
}
switch (gpio)
{
case GPIO_RUN:
snprintf(name, DEV_NAME_STR_LEN, "run");
break;
case GPIO_SYNC:
snprintf(name, DEV_NAME_STR_LEN, "syn");
break;
case GPIO_SYNC_PPS:
snprintf(name, DEV_NAME_STR_LEN, "syn_pps");
break;
case GPIO_ERR1:
snprintf(name, DEV_NAME_STR_LEN, "err1");
break;
case GPIO_ERR2:
snprintf(name, DEV_NAME_STR_LEN, "err2");
break;
case GPIO_ALARM:
snprintf(name, DEV_NAME_STR_LEN, "alarm");
break;
case GPIO_DAU1_POW:
snprintf(name, DEV_NAME_STR_LEN, "dau1");
break;
case GPIO_DAU2_POW:
snprintf(name, DEV_NAME_STR_LEN, "dau2");
break;
case GPIO_CPLD_CS:
snprintf(name, DEV_NAME_STR_LEN, "cpld_cs");
break;
case GPIO_CPLD_SCLK:
snprintf(name, DEV_NAME_STR_LEN, "cpld_sclk");
break;
case GPIO_CPLD_MOSI:
snprintf(name, DEV_NAME_STR_LEN, "cpld_mosi");
break;
case GPIO_CPLD_MISO:
snprintf(name, DEV_NAME_STR_LEN, "cpld_miso");
break;
default:
snprintf(name, DEV_NAME_STR_LEN, "default");
break;
}
return E_NONE;
}
CMD(gpio_show,
gpio_show_cmd,
"show gpio",
SHOW_STR
"Gpios\n")
{
uint16_t i = 0;
char gpio_name[DEV_NAME_STR_LEN] = {0};
gpio_node_t *gpio_node = NULL;
vty_out(vty, "GPIO NAME DIR VALUE%s", VTY_NEWLINE);
for(i = 0; i < array_active(gpios); i++)
{
gpio_node = array_lookup(gpios, i);
if (!gpio_node)
{
continue;
}
if (gpio_node->curr_dir == GPIO_DIR_IN)
{
gpio_val_get(gpio_node->index, &gpio_node->curr_val);
}
_gpio_name_get(gpio_node->gpio, gpio_name);
vty_out(vty, "%4d %-12s %-03s %d%s", gpio_node->gpio, gpio_name, gpio_node->curr_dir == GPIO_DIR_IN ? "in" : "out",
gpio_node->curr_val, VTY_NEWLINE);
}
return CMD_SUCCESS;
}
/* Interface functions -------------------------------------------------------*/
/* 根据 gpio 找到对应的结构体, 如果不存在, 返回NULL. */
gpio_node_t *gpio_get_by_gpio(uint16_t gpio)
{
uint16_t i = 0;
gpio_node_t *gpio_node = NULL;
for(i = 0; i < array_active(gpios); i++)
{
gpio_node = array_lookup(gpios, i);
if (!gpio_node)
{
continue;
}
if (gpio_node->gpio == gpio)
{
return gpio_node;
}
}
return NULL;
}
/* 根据数组 index 找到对应的结构体, 如果不存在, 返回 NULL. */
gpio_node_t *gpio_get_by_index(uint16_t index)
{
return (gpio_node_t*)array_lookup(gpios, index);
}
/* 设置gpio输出值 */
int32_t gpio_val_set(uint16_t index, uint8_t value)
{
int32_t fd = 0;
char buf[40] = {0};
gpio_node_t *gpio_node = gpio_get_by_index(index);
/* 参数检查 */
if (!gpio_node)
{
DBG(DBG_M_GPIO, "gpio index %d is not found\r\n", index);
return E_NOT_FOUND;
}
/* 只有out方向可以设置值 */
if (gpio_node->curr_dir != GPIO_DIR_OUT)
{
DBG(DBG_M_GPIO, "gpio %d direction is not out\r\n", gpio_node->gpio);
return E_BAD_PARAM;
}
/* 如果值相等就不需要再操作了 */
if (gpio_node->curr_val == value)
{
return E_NONE;
}
/* 打开文件 */
snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio_node->gpio);
fd = open(buf, O_WRONLY);
if (fd <= 0)
{
DBG(DBG_M_GPIO, "Open %s error", buf);
return E_SYS_CALL;
}
/* 设置值 */
snprintf(buf, sizeof(buf), "%d", (value == 0) ? 0 : 1);
if (write(fd, buf, 1) <= 0)
{
DBG(DBG_M_GPIO, "Write gpio %d value error", gpio_node->gpio);
return E_SYS_CALL;
}
close(fd);
gpio_node->curr_val = value;
return E_NONE;
}
/* 设置gpio输出值 */
int32_t gpio_val_get(uint16_t index, uint8_t *value)
{
int32_t fd = 0;
char buf[40] = {0};
gpio_node_t *gpio_node = gpio_get_by_index(index);
/* 参数检查 */
if (!gpio_node)
{
DBG(DBG_M_GPIO, "gpio index %d is not found\r\n", index);
return E_NOT_FOUND;
}
/* out方向直接读取 */
if (GPIO_DIR_OUT == gpio_node->curr_dir)
{
*value = gpio_node->curr_val;
return E_NONE;
}
/* 打开文件 */
snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio_node->gpio);
fd = open(buf, O_RDONLY);
if (fd <= 0)
{
DBG(DBG_M_GPIO, "Open %s error", buf);
return E_SYS_CALL;
}
/* 读取值 */
memset(buf, 0, sizeof(buf));
if (read(fd, buf, sizeof(buf) - 1) <= 0)
{
DBG(DBG_M_GPIO, "Read gpio %d value error", gpio_node->gpio);
return E_SYS_CALL;
}
close(fd);
*value = strtol(buf, NULL, 10);
return E_NONE;
}
/* 设置gpio方向 */
int32_t gpio_dir_set(uint16_t index, uint8_t dir)
{
int32_t fd = 0;
char buf[40] = {0};
gpio_node_t *gpio_node = gpio_get_by_index(index);
/* 参数检查 */
if (!gpio_node)
{
DBG(DBG_M_GPIO, "gpio index %d is not found\r\n", index);
return E_NOT_FOUND;
}
/* 如果方向相等,不用继续操作 */
if (gpio_node->curr_dir == dir)
{
return E_NONE;
}
/* 打开文件 */
snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio_node->gpio);
fd = open(buf, O_WRONLY);
if (fd <= 0)
{
DBG(DBG_M_GPIO, "Open %s error", buf);
return E_SYS_CALL;
}
/* 设置方向 */
snprintf(buf, sizeof(buf), "%s", (dir == GPIO_DIR_IN) ? "in" : "out");
if (write(fd, buf, strlen(buf)) <= 0)
{
DBG(DBG_M_GPIO, "Write gpio %d direction error", gpio_node->gpio);
return E_SYS_CALL;
}
close(fd);
gpio_node->curr_dir = dir;
return E_NONE;
}
/* 导出 GPIO, 返回值大于等于 0, 表示加入数组的 index; 小于 0 表示失败. */
int32_t gpio_export(uint16_t gpio)
{
int32_t fd = 0;
char buf[40] = {0};
gpio_node_t *gpio_node = gpio_get_by_gpio(gpio);
/* 如果找到表示已经 export. */
if (gpio_node)
{
return -1;
}
/* 文件不存在则导出, 存在不做操作. */
snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d", gpio);
if (access(buf, 0) < 0)
{
/* 打开文件描述符 */
fd = open("/sys/class/gpio/export", O_WRONLY);
if (fd <= 0)
{
log_err(LOG_GPIO, "Open /sys/class/gpio/export error!");
return -2;
}
/* 导出gpio */
snprintf(buf, sizeof(buf), "%d", gpio);
if (write(fd, buf, strlen(buf)) <= 0)
{
log_err(LOG_GPIO, "Write /sys/class/gpio/export(%d) error!", gpio);
return -3;
}
close(fd);
}
/* 添加结构体 */
gpio_node = XMALLOC_Q(MTYPE_GPIO, sizeof(gpio_node_t));
gpio_node->gpio = gpio;
/* 默认值是不确定的 */
gpio_node->curr_val = 0xff;
gpio_node->is_export = TRUE;
gpio_node->index = array_append(gpios, gpio_node, MTYPE_GPIO);
return gpio_node->index;
}
/* 初始化函数 */
int32_t gpio_init(void)
{
#if 0
gpios = array_init(ARRAY_MIN_SIZE, MTYPE_GPIO);
#endif
cmd_install_element(COMMON_NODE, &gpio_show_cmd);
#if 0
gpio_run_idx = gpio_export(GPIO_RUN);
if (gpio_run_idx < 0)
{
DBG(DBG_M_GPIO, "ERROR return %d!\r\n", gpio_run_idx);
return E_BAD_PARAM;
}
LD_E_RETURN(DBG_M_GPIO, gpio_dir_set(gpio_run_idx, GPIO_DIR_OUT));
gpio_sync_idx = gpio_export(GPIO_SYNC);
if (gpio_sync_idx < 0)
{
DBG(DBG_M_GPIO, "ERROR return %d!\r\n", gpio_sync_idx);
return E_BAD_PARAM;
}
LD_E_RETURN(DBG_M_GPIO, gpio_dir_set(gpio_sync_idx, GPIO_DIR_OUT));
gpio_dau1_pow_idx = gpio_export(GPIO_DAU1_POW);
if (gpio_dau1_pow_idx < 0)
{
DBG(DBG_M_GPIO, "ERROR return %d!\r\n", gpio_dau1_pow_idx);
return E_BAD_PARAM;
}
LD_E_RETURN(DBG_M_GPIO, gpio_dir_set(gpio_dau1_pow_idx, GPIO_DIR_OUT));
gpio_dau2_pow_idx = gpio_export(GPIO_DAU2_POW);
if (gpio_dau2_pow_idx < 0)
{
DBG(DBG_M_GPIO, "ERROR return %d!\r\n", gpio_dau2_pow_idx);
return E_BAD_PARAM;
}
LD_E_RETURN(DBG_M_GPIO, gpio_dir_set(gpio_dau2_pow_idx, GPIO_DIR_OUT));
gpio_err1_idx = gpio_export(GPIO_ERR2);
if (gpio_err1_idx < 0)
{
DBG(DBG_M_GPIO, "ERROR return %d!\r\n", gpio_err1_idx);
return E_BAD_PARAM;
}
LD_E_RETURN(DBG_M_GPIO, gpio_dir_set(gpio_err1_idx, GPIO_DIR_OUT));
#endif
return E_NONE;
}
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,3 @@
local_src := $(patsubst $(SOURCE_DIR)/%,%,$(wildcard $(SOURCE_DIR)/$(subdirectory)/*.c))
$(eval $(call make-library,$(subdirectory)/libz_hardware.a,$(local_src)))

@ -0,0 +1,131 @@
# $(call source-to-object,source-file-list($1))
source-to-object = $(subst .c,.o,$(filter %.c,$1))
# 产生库文件相对路径,被每个库程序的module.mk文件使用.
# $(subdirectory)
subdirectory = $(patsubst $(SOURCE_DIR)/%/module.mk,%, \
$(word \
$(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
# 产生库文件规则,被每个库程序的module.mk文件使用.
$(call make-library,library-name($1),source-file-list($2))
define make-library
libraries += $1
sources += $2
$1: $(call source-to-object,$2)
$(QUIET)$(AR) $(ARFLAGS) $$@ $$^ $(ENULL)
@echo "$$(INFO_C)AR $$@ done";echo
endef
# 产生依赖文件.
# $(call make-depend,source-file($1),object-file($2),depend-file($3))
define make-depend
$(CC) -MM -MF $3 -MP -MT $2 $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) $1
endef
SOURCE_DIR := ../app
PRODUCT := $(MAKECMDGOALS)
CONFIG_FILE := $(SOURCE_DIR)/include/config.h
VERSION_FILE := $(SOURCE_DIR)/include/version.h
VERSION_LIB := version.a
DATE_STRING := `date "+%Y.%m.%d %k:%M:%S"`
VERSION_STRING := "1.2"
MV := mv -f
RM := rm -rf
SED := sed
TEST := test
MKDIR := mkdir -p
# 交叉编译设置
#DEFARCH = PC
DEFARCH = MYiR
ifeq ($(DEFARCH), PC)
CROSS_COMPILE =
CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar
CFLAGS = -g -Wall -funwind-tables -rdynamic -DHAVE_CONFIG_H
else ifeq ($(DEFARCH), MYiR)
CFLAGS += -g -Wall -funwind-tables -rdynamic -DHAVE_CONFIG_H
endif
LDLIB := -lreadline -lncurses -pthread -lrt -lsqlite3
# 这里如果是‘@’则隐藏具体的编译命令
QUIET := @
ENULL := > /dev/null
INFO_C := "\\33[32mInfo\\33[0m "
ERROR_C := "\\33[31mInfo\\33[0m "
modules := $(patsubst $(SOURCE_DIR)/%/module.mk,%, \
$(shell find $(SOURCE_DIR) -name module.mk))
# 该变量仅用于产生输出目录,不做任何其他使用.
create-output-directories := $(shell for f in $(modules); \
do \
$(TEST) -d $$f || $(MKDIR) $$f; \
done)
programs :=
sources :=
libraries :=
objects = $(call source-to-object,$(sources))
dependencies = $(subst .o,.d,$(objects))
include_dirs := $(SOURCE_DIR)/include
CPPFLAGS += $(addprefix -I ,$(include_dirs))
vpath %.h $(include_dirs)
vpath %.c $(SOURCE_DIR)
.PHONY: empty
empty:
@echo "Please explicitly specify the Makefile target!!!Example \"make PDMonitor\"."
include $(patsubst %,$(SOURCE_DIR)/%/module.mk,$(modules))
$(VERSION_LIB): $(CONFIG_FILE) $(libraries) version.c
$(QUIET)$(RM) $(VERSION_FILE)
@echo "/* WARNING: Don't modify this file anywhere!!! */" >> $(VERSION_FILE)
@echo "#ifndef _VERSION_H_" >> $(VERSION_FILE)
@echo "#define _VERSION_H_" >> $(VERSION_FILE)
@echo "" >> $(VERSION_FILE)
@echo "#define VERSION \"$(VERSION_STRING)\"" >> $(VERSION_FILE)
@echo "#define DATE \"$(DATE_STRING)\"" >> $(VERSION_FILE)
@echo "" >> $(VERSION_FILE)
@echo "char* version_get();" >> $(VERSION_FILE)
@echo "char* version_date_get();" >> $(VERSION_FILE)
@echo "" >> $(VERSION_FILE)
@echo "#endif" >> $(VERSION_FILE)
@echo "/* WARNING: Don't modify this file anywhere!!! */" >> $(VERSION_FILE)
@echo "COMPILE version.o"
$(QUIET)$(COMPILE.c) -o version.o version.c
$(QUIET)$(AR) $(ARFLAGS) $(VERSION_LIB) version.o $(ENULL)
@echo "$(INFO_C)AR $@ done";echo
sshcmd: $(CONFIG_FILE) $(libraries) $(VERSION_LIB)
# 使用两次$(libraries)避免库文件之间的交叉引用问题.
$(QUIET)$(LINK.o) -rdynamic $(libraries) $(VERSION_LIB) $(LDLIB) -o $@
@echo "$(INFO_C)LINK $@ done";echo
# $(QUIET)cp $@ //home//embed//LandPower//
.PHONY: libraries
libraries: $(libraries)
.PHONY: clean
clean:
$(RM) $(modules) $(CONFIG_FILE) $(VERSION_FILE) sshcmd $(VERSION_LIB) version.o
ifneq "$(MAKECMDGOALS)" "clean"
-include $(dependencies)
include config.mk
endif
%.o: %.c
@echo "COMPILE $@"
$(QUIET)$(call make-depend,$<,$@,$(subst .o,.d,$@))
$(QUIET)$(COMPILE.c) -o $@ $<

@ -0,0 +1,40 @@
include $(PRODUCT).cfg
$(CONFIG_FILE): $(PRODUCT).cfg
$(QUIET)rm $(CONFIG_FILE) -rf
@echo "/* WARNING: Don't modify this file anywhere!!! */" >> $(CONFIG_FILE)
@echo "#ifndef _CONFIG_H_" >> $(CONFIG_FILE)
@echo "#define _CONFIG_H_" >> $(CONFIG_FILE)
@echo "" >> $(CONFIG_FILE)
@echo "#define PROGNAME \"$(PRODUCT)\"" >> $(CONFIG_FILE)
# debug开关
ifeq ($(CFG_DBG_ON), y)
@echo "#define CFG_DBG_ON" >> $(CONFIG_FILE)
endif
# 设备类型定义
ifeq ($(CFG_DEV_TYPE_LAND_PD), y)
@echo "#define CFG_DEV_TYPE_LAND_PD" >> $(CONFIG_FILE)
endif
# 朗德GIS协议开关
ifeq ($(CFG_PROTO_GIS), y)
@echo "#define CFG_PROTO_GIS" >> $(CONFIG_FILE)
endif
# 默认使能朗德GIS协议开关
ifeq ($(CFG_PROTO_GIS_DEFAULT), y)
@echo "#define CFG_PROTO_GIS_DEFAULT" >> $(CONFIG_FILE)
endif
@echo "" >> $(CONFIG_FILE)
@echo "#include \"common.h\"" >> $(CONFIG_FILE)
@echo "" >> $(CONFIG_FILE)
@echo "#endif" >> $(CONFIG_FILE)
@echo "/* WARNING: Don't modify this file anywhere!!! */" >> $(CONFIG_FILE)
@echo "$(INFO_C)Create $@ done";echo
$(VERSION_FILE): $(PRODUCT).cfg

@ -0,0 +1,7 @@
#include <unistd.h>
int main(void)
{
execlp("login", "login", "-f", "root", NULL);
return 0;
}

@ -0,0 +1,8 @@
# debug功能开启
CFG_DBG_ON := y
# GIS设备
CFG_DEV_TYPE_LAND_PD := y
# 是否有GIS通讯协议
CFG_PROTO_GIS := y
# 默认开启GIS通讯协议
CFG_PROTO_GIS_DEFAULT := y

@ -0,0 +1,12 @@
#include "version.h"
char* version_get()
{
return VERSION;
}
char* version_date_get()
{
return DATE;
}
Loading…
Cancel
Save