Fisrst commit:电力设备多状态量一体化智能在线监测装置主控代码;

main
wangbo 4 months ago
commit 1fb9a4bff5

@ -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,181 @@
/******************************************************************************
* 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_CMD_LEN 512
#define LOG_STR_LEN 256
#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_NET,
LOG_STORAGE,
LOG_DEBUG,
LOG_UPGRADE,
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数据库指针. */
int32_t log_fifo_id; /* log fifo id. */
char *filename; /* log数据库名字. */
int32_t timestamp_precision; /* 默认log时间戳精度. */
pthread_mutex_t log_db_mutex; /* 数据库读写互斥锁 */
} log_sys_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_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,336 @@
/******************************************************************************
* 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 2023-2025 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 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_NET,
CONFIG_PRI_COUNT
} CONFIG_PRI_E;
/* Host configuration variable */
typedef struct{
uint8_t type_m; // 主设备号
uint8_t type_s; // 次设备号
uint8_t reserved1[2]; // 保留
uint32_t dev_id; // 设备ID
char hostname[FILE_NAME_LEN]; // 设备名 128byte
uint32_t factory_date; // 出厂日期.
uint32_t deployment_date; // 部署日期.
uint8_t app_version[32]; // 软件版本
uint8_t app_compile_time[32]; // 软件编译时间
uint8_t hardware_version[32]; // 硬件版本
uint8_t FPGA_version[32]; // fpga版本
uint32_t ip; // 本机 IP.
uint32_t mask; // 本机 MASK.
uint32_t gw; // 本机网关
uint8_t mac[6]; // MAC地址.
uint16_t server_port; // 服务器端口号.
uint32_t server_ipv4; // 服务器 IP.
} 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 *hardversion; /* 硬件版本号. */
char *FPGAversion; /* PFGA版本号. */
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;
/* 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);
extern void vtycmd_init(void);
extern void vtycmd_cmd_init(void);
extern bool vtycmd_connect(void);
extern void vtycmd_print(const char *format, va_list va);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,161 @@
/******************************************************************************
* 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;
typedef void* (*thread_func_t)(void*);
typedef struct
{
void *arg;
int priority;
int log_module;
char *thread_name;
} thread_param_t;
/* 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))
#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 void buf_print_16(uint16_t *buf, int32_t len);
extern int32_t mac_generate_from_ip(uint32_t ip, 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 unsigned int crc32(unsigned int crc, char *buf, unsigned long len);
extern void speed_detection_stat(void);
extern void speed_detection_end(void);
extern int printh(const char *format, ...);
extern char* softversion_get();
extern char* softversion_date_get();
extern char* hardware_version_get();
extern char* fpga_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 int32_t create_thread(thread_func_t func, thread_param_t *pParam);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,115 @@
/******************************************************************************
* 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_PD_NET_ERR,
DBG_M_STORAGE_ERR,
DBG_M_DEBUG,
DBG_M_PD_UPGRADE,
DBG_M_PD_DATA,
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,74 @@
/******************************************************************************
* 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_WATCHDONG 915
/* 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_WATCHDOG(_v_) gpio_val_set(gpio_watcdog_idx, _v_)
/* Extern global variables ---------------------------------------------------*/
extern int32_t gpio_watcdog_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);
extern void feed_dog(void);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,701 @@
#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)
/**
* 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,87 @@
/*****************************************************************************
* file include/main.h
* author YuLiang
* version 1.0.0
* date 26-Sep-2021
* brief This file provides all the headers of the main 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;
/* 系统复位类型 */
typedef enum _REBOOT_MSG
{
REBOOT_NONE = 0,
REBOOT_LOCAL_SERVER_IP_CHANGE,
REBOOT_LOCAL_IP_CHANGE,
REBOOT_LOCAL_HOST_NAME_CHANGE,
REBOOT_LOCAL_RESET,
REBOOT_LOCAL_ARM_UPGRADE,
REBOOT_REMOTE_SERVER_IP_CHANGE,
REBOOT_REMOTE_IP_CHANGE,
REBOOT_REMOTE_HOST_NAME_CHANGE,
REBOOT_REMOTE_RESET,
REBOOT_UPGRADE_ALL,
REBOOT_SYSTEM_RESET,
REBOOT_4G_ERROR,
REBOOT_NET_ERROR,
REBOOT_MAX,
} REBOOT_MSG;
typedef struct
{
REBOOT_MSG type; // 重启类型
char *msg; // 重启日志
} reboot_msg_t;
/* Extern global variables ---------------------------------------------------*/
extern int32_t recv_qid;
extern uint16_t version_hex;
extern uint32_t start_time;
/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
extern void reboot_system(int module, REBOOT_MSG type);
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

@ -0,0 +1,123 @@
/******************************************************************************
* 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_UPGRADE,
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,384 @@
/******************************************************************************
* 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"
#include <semaphore.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/* Define --------------------------------------------------------------------*/
#define CSG_HEAD_LEN (32)
#define CSG_TOTLE_LEN (26)
#define CSG_PKT_LEN (1300)
#define MAX_FILES (128)
#define MAX_PATH_LEN (256)
#define THRESHOLD_MS 10 // 时间差阈值
#define UDP_SEND_TIMEOUT (2)
#define CSG_SEND_ERR_CNT (3)
/* 配置文件结构体 */
#define FILE_FIFO_PATH_LEN 256
/* 命令类型. */
enum CSG_CMD_TYPE
{
CSG_REQUEST = 1,
CSG_REPLY = 2,
CSG_PRV_REQUEST = 121,
CSG_PRV_REPLY = 122
};
/* 共有命令字. */
enum CSG_CMD
{
CSG_C_CONTACT = 1,
CSG_C_ADD_DAU = 2,
CSG_C_RESET = 3,
CSG_C_UPDATE = 5,
CSG_C_DEV_INFO_SET = 6, /* 设备基本信息设置 */
CSG_C_DEV_INFO_GET = 7, /* 设备基本信息获取 */
CSG_C_UPDATE_RESULT = 9,
CSG_C_HEARTBEAT = 10,
CSG_C_MAX
};
/* 私有命令字. */
enum DEBUG_CM_CMD
{
CSG_PRV_CONFIG_GLOBAL_SET = 1, /* 设备全局参数设置 */
CSG_PRV_CONFIG_GLOBAL_GET = 2, /* 设备全局参数获取 */
CSG_PRV_CONFIG_PORT_SET = 3, /* 设备端口参数设置 */
CSG_PRV_CONFIG_PORT_GET = 4, /* 设备端口参数获取 */
CSG_PRV_CONFIG_REAL_WAVE = 5, /* 实时波形配置 */
CSG_PRV_TREND = 10,
CSG_PRV_REAL_PRPS = 11,
CSG_PRV_EVENT = 12
};
// 定义命令字常量
typedef enum {
//CMD_CONTACT = 0x00,
CMD_INVALID
} command_type;
// 定义函数指针类型
typedef void (*command_handler)(int slot, char *data);
// 定义命令结构体
typedef struct {
command_type cmd; // 命令字
command_handler handler; // 处理函数
} command_entry;
/* 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 {
uint32_t port; /* 端口号 0 ~ 7 */
uint32_t length; /* 端口数据长度 */
}port_info_t;
/* . */
typedef struct
{
int skfd; // 后台通讯使用的 socket.
uint32_t pkt_index; // 报文索引.
char buf_send[1500];
char buf_recv[1500];
char event_booster_buf[1500];
char trend_booster_buf[1500];
struct sockaddr_in server;
int32_t server_ip; // server ip.
uint16_t server_port; // server port.
uint8_t is_connect; // 是否连接上服务器.
int32_t communication_time; // 最后通讯时间.
time_t heartbeat_timeout;
time_t heartbeat_timeout_cnt;
pthread_mutex_t mutex;
pthread_mutex_t lock;
} csg_t;
/* 报文头结构. */
typedef struct{
uint16_t len;
uint8_t dev_type_m;
uint8_t dev_type_s;
uint32_t dev_id;
uint8_t cmd_type;
uint8_t cmd;
uint16_t pkt_id;
uint8_t version;
uint8_t reserve1[2];
uint8_t slot; // 槽位
uint32_t sdev_id; // 从设备id
uint8_t reserve2[12];
} csg_pkt_head_t;
typedef struct {
uint8_t result; // 应答结果. 0:成功 1:失败
uint8_t reserved[3]; // 保留
}csg_ack_t;
/* 心跳报文. */
typedef struct
{
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]; // 通道传感器连接状态 断线告警.
uint8_t dau_port_num[4]; // 采集板端口数量.
} csg_heartbeat_t;
typedef struct{
uint8_t type_m; // 主设备号
uint8_t type_s; // 次设备号
uint8_t reserved1[2]; // 保留
uint32_t dev_id; // 设备ID
char hostname[FILE_NAME_LEN]; // 设备名 128byte
uint32_t factory_date; // 出厂日期.
uint32_t deployment_date; // 部署日期.
uint8_t app_version[32]; // 软件版本
uint8_t app_compile_time[32]; // 软件编译时间
uint8_t hardware_version[32]; // 硬件版本
uint8_t FPGA_version[32]; // fpga版本
uint32_t ip; // 本机 IP.
uint32_t mask; // 本机 MASK.
uint32_t gw; // 本机网关
uint8_t mac[6]; // MAC地址.
uint16_t server_port; // 服务器端口号.
uint32_t server_ipv4; // 服务器 IP.
} csg_dev_info_t;
typedef struct{
uint16_t power_frequency; // 工频频率, 单位: 0.1Hz
uint16_t trend_period; // 趋势数据上送周期, 单位: 秒.
uint8_t sync_mode; // 同步方式 1: PT 同步 2: 内同步(默认) 3: 外接信号同步.
uint8_t heartbeat_period; // 心跳包周期, 单位: 分钟.
uint8_t pps_mode; // pps 主从模式 PD_PPS_XXX.
uint8_t protocol_type; // 0:朗德协议 1:南网协议
uint16_t trend_storage; //趋势存储文件数量阈值
uint16_t event_storage; //事件存储文件数量阈值
} csg_config_global_t;
typedef struct {
uint8_t vport; // 通道编号.
uint8_t port_type; // 采集通道类型 , 1 表示特高频局放 2 表示超声局放 3 表示 TEV 4 表示高频.
uint8_t filter; // 滤波器类型 1: 低频段 2: 全频段 3: 窄频段 4: 高频段
uint8_t sensor_type; // 0: 无配置; 1: UHF信号传感器; 2: UHF噪声传感器 ; 3: UHF信号传感器, 关联噪声降噪.
uint8_t is_auto_noise; // 是否自动调整降噪等级.
uint8_t denoise_type; // 0-无配置 1-自动 2-手动降噪
uint16_t denoise_variance; // 方差降噪系数, 单位: 1%
uint32_t event_counter_h; // 事件次数阀值高.
uint16_t event_sec_h; // 事件每秒次数阀值高.
uint16_t event_thr_h; // 事件值阈值高.
uint32_t event_counter_thr_h; // 事件值阈值高的次数.
uint32_t event_counter_l; // 事件次数阀值低.
uint16_t event_sec_l; // 事件每秒次数阀值低.
uint16_t event_thr_l; // 事件值阈值低.
uint32_t event_counter_thr_l; // 事件值阈值低的次数.
uint8_t burst_time; // 事件突发计算时间
uint8_t reserved1[1];
uint16_t burst_thr; // 事件突发阈值
int16_t denoise_manual; // 手动底噪等级
int16_t denoise_auto; // 自动降噪水平
}csg_config_port_t;
typedef struct
{
uint8_t vport; // 通道编号 1 ~ 8
uint8_t is_concern; // 关注 1: 关注 0: 取消关注
uint8_t filter; // 滤波器类型
uint8_t denoise_correlation; // 关联降噪 1: 关联噪声去噪
uint8_t denoise_type; // 0-无配置 1-自动 2-手动降噪
uint8_t reserved; // 保留
uint16_t denoise_manual; // 手动降噪等级
} csg_real_image_get_t;
/* 实时图谱报文头 28Byte. */
typedef struct{
uint16_t index; // 每10包传完之后自动自加用于区分当前包结束.
uint8_t pkt_sum; // 总包数 10.
uint8_t pkt_index; // 当前包数 0 ~ 9.
uint16_t fre_cnt; // 工频周期计数.
uint8_t vport; // 通道编号.
uint8_t reserved1[1];
int16_t max;
int16_t avg;
uint32_t cnt;
uint32_t utc;
float freq; // 频率.
uint32_t len;
} csg_real_image_t;
typedef struct{
uint16_t index; // 包索引
uint16_t sum; // 总包数
uint8_t type; // 数据类型 0prpd 1:原始波形 210秒prps 3:统计数据
uint8_t vport; // 通道号
uint8_t boosterpack; // 是否补包 0否 1
uint8_t reserved[1]; // 保留
uint32_t identifier; // 数据编号
uint32_t utc; // 同步时间
uint32_t len; // 当前包长度
} csg_trend_t;
typedef struct{
uint16_t data_cnt; // 数据计数.
int16_t max; // 通道的最大值.
uint16_t reserved; // 保留
uint16_t avg; // 通道的平均值.
uint32_t cnt; // 通道的计数值.
uint32_t phase; // 放电相位 .
uint32_t noise; // 趋势数据中的底噪值: 单位 dBm .
uint32_t event_cnt; // 趋势数据中的的事件数量记录.
} csg_trend_stat;
typedef struct {
uint16_t index; // 包索引
uint16_t sum; // 总包数
uint8_t vport; // 通道号
uint8_t boosterpack; // 是否补包 0否 1
int16_t max; // 通道的最大值.
uint32_t power_fre; // 工频周期.
uint8_t type; // 事件类型.
uint8_t reserved[3]; // 保留
uint32_t identifier; // 数据编号: 0 - (2^32-1) 循环.
uint32_t utc; // UTC 时标.
uint32_t cnt; // 通道每秒脉冲计数值.
uint16_t avg_o; // 通道原始信号 (降噪前) 的平均值.
uint16_t avg; // 脉冲平均值.
uint32_t point_cnt; // 数据累计点数
uint32_t len; // 当前包长度
} csg_event_t;
/* 升级文件包结构体 */
typedef struct {
uint8_t type; // 升级类型
uint8_t resverd[3];
uint16_t index; // 报文索引
uint16_t sum; // 总包数.
uint32_t len; // 数据包长度.
} csg_upgrade_data_t;
/* 应答升级结构体 */
typedef struct {
uint16_t index; // 应答包序号.
uint8_t result; // 应答结果. 0:成功 1:失败
uint8_t reserve; // 保留
} upgrade_ack_t;
/* 升级结果通知 */
typedef struct
{
uint8_t result; // 升级结果
uint8_t reserved[3];
char context[128];
} upgrade_res_t;
typedef struct
{
uint8_t type_m; // 主设备号
uint8_t type_s; // 次设备号
uint8_t reserved1[2]; // 保留
uint32_t dev_id; // 设备ID
char hostname[FILE_NAME_LEN]; // 设备名 128byte
uint32_t factory_date; // 出厂日期.
uint32_t deployment_date; // 部署日期.
uint8_t app_version[32]; // 软件版本
uint8_t app_compile_time[32]; // 软件编译时间
uint8_t hardware_version[32]; // 硬件版本
uint8_t FPGA_version[32]; // fpga版本
uint32_t ip; // 本机 IP.
uint32_t mask; // 本机 MASK.
uint32_t gw; // 本机网关
uint8_t mac[6]; // MAC地址.
uint16_t server_port; // 服务器端口号.
uint32_t server_ipv4; // 服务器 IP.
uint8_t port[8];
uint8_t port_type[8];
} csg_contact_t;
typedef struct
{
uint32_t dev_id;
uint8_t slot;
uint8_t status;
uint8_t reserved[2];
uint8_t port[8];
uint8_t port_type[8];
} csg_add_dau_t;
typedef struct
{
uint32_t dev_id;
uint8_t slot;
uint8_t reserved[2];
uint8_t result;
} csg_add_dau_ack_t;
/* Exported macro ------------------------------------------------------------*/
/* Extern global variables ---------------------------------------------------*/
extern csg_t csg;
/* Extern functions ----------------------------------------------------------*/
extern int32_t _csg_pkt_check(char *pkt);
extern int32_t csg_handle_init(void);
extern int32_t csg_handle_init_after(void);
extern void csg_upgrade_result_send(int32_t rv, char *buf);
extern void _print_sockaddr_in(const struct sockaddr_in *addr);
extern command_handler _csg_get_table_handle(command_entry *ptable, command_type cmd);
extern void _csg_send_data(uint8_t cmd_type, uint8_t cmd, char *pkt, int32_t len);
#endif
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,213 @@
/*****************************************************************************
* 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 <semaphore.h>
#include <termios.h>
#include <unistd.h>
#include "pd_main.h"
#include "common.h"
/* Define --------------------------------------------------------------------*/
#define MAX_SLOTS 6
#define BUFFER_SIZE 2048
#define UDP_SLOTS 4
#define RS485_SLOTS 2
#define UHF "UDP_UHF"
#define HF "UDP_HF"
#define ULTRASONIC "UDP_ULTRASONIC"
#define IRONCORE "RS485_IRONCORE"
#define UDP_PORT 5000
/* Exported types ------------------------------------------------------------*/
// 板卡类型枚举
typedef enum {
DAU_TYPE_UDP,
DAU_TYPE_RS485,
DAU_TYPE_NONE
} DauType;
// 板卡状态枚举
typedef enum {
DAU_STATE_DISCONNECTED,
DAU_STATE_CONNECTED,
DAU_STATE_REGISTERED
} DauState;
// 通信回调函数类型
//typedef void (*data_recv_callback)(void* priv_data, const void* data, size_t len);
//typedef void (*data_send_callback)(void* priv_data, void* data, size_t len);
// 板卡私有数据结构
typedef struct
{
DauType type;
union
{
struct
{
int sockfd;
struct sockaddr_in addr;
} udp;
struct
{
int fd;
char port[20];
struct termios options;
} rs485;
} comm;
char board_id[32];
void *rx_buffer;
size_t buffer_size;
uint8_t cmd_type;
uint8_t cmd;
} dau_private_data_t;
// 板卡操作回调函数结构
typedef struct
{
int (*init)(dau_private_data_t *data, const char *config);
int (*receive)(dau_private_data_t *data, void *buf, size_t len);
int (*transmit)(dau_private_data_t *data, const void *buf, size_t len);
void (*cleanup)(dau_private_data_t *data);
} dau_operations_t;
// UDP客户端信息
typedef struct {
struct sockaddr_in addr;
char board_id[32];
} udp_client_data;
// RS485设备信息
typedef struct {
int fd; // 串口文件描述符
char board_id[32];
uint8_t address; // 从机地址
} rs485_device_data;
typedef struct
{
uint8_t type_m; // 主设备号
uint8_t type_s; // 次设备号
uint8_t reserved1[2]; // 保留
uint32_t dev_id; // 设备ID
char hostname[FILE_NAME_LEN]; // 设备名 128byte
uint32_t factory_date; // 出厂日期.
uint32_t deployment_date; // 部署日期.
uint8_t app_version[32]; // 软件版本
uint8_t app_compile_time[32]; // 软件编译时间
uint8_t hardware_version[32]; // 硬件版本
uint8_t FPGA_version[32]; // fpga版本
uint32_t ip; // 本机 IP.
uint32_t mask; // 本机 MASK.
uint32_t gw; // 本机网关
uint8_t mac[6]; // MAC地址.
uint16_t server_port; // 服务器端口号.
uint32_t server_ipv4; // 服务器 IP.
uint8_t port[8];
uint8_t port_type[8];
} dau_info_t;
// 板卡管理器结构
typedef struct
{
//dau_private_data_t *private_data;
dau_operations_t ops;
// udp
int sockfd;
struct sockaddr_in addr;
// rs485
int fd;
char port[20];
struct termios options;
char board_id[32];
void *rx_buffer;
size_t buffer_size;
uint8_t cmd_type;
uint8_t cmd;
pthread_t thread_id;
int slot;
bool occupied; // 槽位占用标志
dau_info_t info;
} dau_manager_t;
typedef struct {
int slot;
DauType type;
DauState state;
void *private_data;
dau_info_t info;
} dau_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) << 8)
/* Extern global variables ---------------------------------------------------*/
extern dau_t daus[MAX_SLOTS];
/* Extern functions ----------------------------------------------------------*/
extern int32_t dau_handle_init(void);
extern int32_t dau_handle_init_after(void);
extern int _dau_response(int slot, char *buf, int len);
#endif
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

@ -0,0 +1,243 @@
/*****************************************************************************
* 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_DAU_FILE_UPGRADE "/lib/firmware/system_wrapper.bin.upgrade"
#define DEBUG_DAU_FILE_BAK "./bak/system_wrapper_bak.bin.bak"
#define DEBUG_DAU_FILE "/lib/firmware/system_wrapper.bin"
#define DEBUG_BUG_SIZE 1512
#define DEBUG_CJSON_BUG_SIZE 1512
//#define DEBUG_NOISE_CAREFOR (0x0007) // 关注对应通道的底噪原始值, 校准底噪值.
//#define DEBUG_NOISE_POST (0x0008) // 获取底噪原始值, 校准底噪值 服务端主动提交每秒刷新一次.
enum DebugCommand
{
DEBUG_CONFIG_FACTORY_GET = 1, // 获取配置
DEBUG_CONFIG_FACTORY_SET = 2, // 设置配置
DEBUG_CONFIG_GLOBAL_SET = 3, /* 设备全局参数设置 */
DEBUG_CONFIG_GLOBAL_GET = 4, /* 设备全局参数获取 */
DEBUG_CONFIG_PORT_SET = 5, /* 设备端口参数设置 */
DEBUG_CONFIG_PORT_GET = 6, /* 设备端口参数获取 */
DEBUG_REBOOT = 7, // 重启
DEBUG_TIME_SET = 8, // 对时
DEBUG_ADJSUT_COEFFICIENT_GET = 9, // 获取校准系数
DEBUG_ADJSUT_COEFFICIENT_SET = 10, // 设置校准系数
DEBUG_NOISE_POST = 11, // 自动获取采样值
DEBUG_NOISE_CAREFOR = 12, // 使能自动获取采样值功能
DEBUG_DEVICE_STATUS = 13, // 查询设备状态后台连接、4G连接
DEBUG_ARM_UPGRADE = 0x0050, // ARM 升级
DEBUG_FPGA1_UPGRADE = 0x0051, // FPGA 板卡升级
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;
/* 报文头结构. */
typedef struct{
uint16_t head; // 0x55aa.
uint32_t len;
uint8_t dev_type_m;
uint8_t dev_type_s;
uint16_t dev_id;
uint8_t cmd_type;
uint8_t cmd;
uint16_t pkt_id;
uint8_t reserve[18];
} dbg_pkt_head_t;
/* 基础信息 */
typedef struct{
uint8_t type_m; // 主设备号
uint8_t type_s; // 次设备号
uint8_t reserved1[2]; // 保留
uint32_t dev_id; // 设备ID
char hostname[FILE_NAME_LEN]; // 设备名 128byte
uint32_t factory_date; // 出厂日期.
uint32_t deployment_date; // 部署日期.
uint8_t app_version[32]; // 软件版本
uint8_t app_compile_time[32]; // 软件编译时间
uint8_t hardware_version[32]; // 硬件版本
uint8_t FPGA_version[32]; // fpga版本
uint32_t ip; // 本机(服务器) IP.
uint32_t mask; // 本机(服务器) MASK.
uint32_t gw; // 本机(服务器)网关
uint8_t mac[6]; // MAC地址.
uint16_t csg_port; // 后台端口号.
uint32_t csg_ipv4; // 后台 IP.
uint32_t running_time; //运行时间
} dbg_device_info_t;
/* 全局配置 */
#pragma pack(push, 1)
typedef struct{
uint16_t power_frequency; // 工频频率, 单位: 0.1Hz
uint16_t trend_period; // 趋势数据上送周期, 单位: 秒.
uint8_t sync_mode; // 同步方式 1: PT 同步 2: 内同步(默认) 3: 外接信号同步.
uint8_t heartbeat_period; // 心跳包周期, 单位: 分钟.
uint8_t pps_mode; // pps 主从模式 PD_PPS_XXX.
uint8_t reserved[1];
uint16_t trend_storage; // 趋势存储文件数量阈值.
uint16_t event_storage; // 事件存储文件数量阈值
uint8_t is_4G_enable; // 是否使用 4G 模块
char APN[PD_4G_APN_LEN]; // 4G 模块 APN
} dbg_global_config_t;
#pragma pack(pop)
/* 端口配置. */
typedef struct {
uint8_t vport; // 通道编号.
uint8_t port_type; // 采集通道类型 , 1 表示特高频局放 2 表示超声局放 3 表示 TEV 4 表示高频.
uint8_t filter; // 滤波器类型 1: 低频段 2: 全频段 3: 窄频段 4: 高频段
uint8_t sensor_type; // 0: 无配置; 1: UHF信号传感器; 2: UHF噪声传感器 ; 3: UHF信号传感器, 关联噪声降噪.
uint8_t is_auto_noise; // 是否自动调整降噪等级.
uint8_t denoise_type; // 0-无配置 1-自动 2-手动降噪
uint8_t reserved0[2];
uint32_t event_counter_h; // 事件次数阀值高.
uint16_t event_sec_h; // 事件每秒次数阀值高.
uint16_t event_thr_h; // 事件值阈值高.
uint32_t event_counter_thr_h; // 事件值阈值高的次数.
uint32_t event_counter_l; // 事件次数阀值低.
uint16_t event_sec_l; // 事件每秒次数阀值低.
uint16_t event_thr_l; // 事件值阈值低.
uint32_t event_counter_thr_l; // 事件值阈值低的次数.
uint8_t burst_time; // 事件突发计算时间
uint8_t reserved1[1];
uint16_t burst_thr; // 事件突发阈值
int16_t denoise_manual; // 手动底噪等级
int16_t denoise_auto; // 自动降噪水平
}dbg_port_config_t;
/* 高频通道校准系数 */
typedef struct {
uint16_t param_a[PD_PORT_SUM]; // 通道线性度校准系数 a.
uint16_t param_b[PD_PORT_SUM]; // 通道线性度校准系数 b.
} debug_hf_pkt_adj_vport_t;
/* 设备状态. */
typedef struct {
uint8_t csg_connect_status; // 后台连接状态.
uint8_t ec20_connect_status; // 4g模块连接状态
} debug_pkt_dev_connect_status_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_handle_init_after(void);
extern int32_t debug_pkt_port_state_post(void);
extern void debug_upgrade_result_send(int32_t rv, char *buf);
#endif
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

@ -0,0 +1,36 @@
#ifndef __PD_HF_H__
#define __PD_HF_H__
#ifdef CFG_DEV_TYPE_LAND_PD
/* Includes ------------------------------------------------------------------*/
typedef struct
{
uint8_t slot; // 槽位号
uint8_t type_m; // 主设备号
uint8_t type_s; // 次设备号
uint8_t reserved1[1]; // 保留
uint32_t dev_id; // 设备ID
char hostname[FILE_NAME_LEN]; // 设备名 128byte
uint32_t factory_date; // 出厂日期.
uint32_t deployment_date; // 部署日期.
uint8_t app_version[32]; // 软件版本
uint8_t app_compile_time[32]; // 软件编译时间
uint8_t hardware_version[32]; // 硬件版本
uint8_t FPGA_version[32]; // fpga版本
uint32_t ip; // 本机 IP.
uint32_t mask; // 本机 MASK.
uint32_t gw; // 本机网关
uint8_t mac[6]; // MAC地址.
uint16_t server_port; // 服务器端口号.
uint32_t server_ipv4; // 服务器 IP.
uint8_t port[8];
uint8_t port_type[8];
} hf_dev_info_t;
extern int32_t _hf_recv_process(int slot, char *pkt);
#endif
#endif

@ -0,0 +1,393 @@
/*****************************************************************************
* 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 1
#define PD_DAU_PORT_SUM 8
#define PD_PORT_SUM 8
#define PD_PORT_PROMPT_LEN 64 // DAU 端口节点前标长度.
#define PD_DEV_NUM_LEN 16
#define PD_DEV_TYPE_LEN 8
#define PD_POWER_FRE_MAX 384
#define PD_PHASE_NUM 256
#define PD_VAULE_NUM 256
#define PD_PRPS_NUM 12800
#define PD_PRPS_NUM_MAX 98304
#define PD_EVENT_POINT_MAX 983040
#define PD_TREND_PHASE_POINT_CNT 256
#define PD_TREND_POINT_MAX 983040
#define PD_TREND_ORIGINAL_NUM 65536
#define PD_PORT_ORIGINAL_NUM 2560000 // 100M采样率, 最大40Hz
#define PD_4G_APN_LEN 64
/* Exported types ------------------------------------------------------------*/
/* 用于命令行模式节点注册配置保存函数 */
typedef int pd_port_cmd_save_config_f(vty_t*, uint8_t, uint8_t);
/* 向服务器发送消息的类型. */
typedef enum
{
PD_DEV_TYPE_HF = 1,
PD_DEV_TYPE_UHF
} PD_DEV_TYPE_E;
/* 向服务器发送消息的类型. */
typedef enum
{
PD_SEND_TYPE_PRPS = 1,
PD_SEND_TYPE_TREND,
PD_SEND_TYPE_EVENT,
PD_SEND_TYPE_POINT,
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_DENOISE_TYPE_NONE = 0,
PD_DENOISE_TYPE_AOTU,
PD_DENOISE_TYPE_MANUAL,
PD_DENOISE_TYPE_VARIANCE,
PD_DENOISE_TYPE_COUNT
} PD_NOISE_TYPE_E;
/* 设备配置的滤波类型. */
typedef enum
{
PD_SYNC_PT = 1,
PD_SYNC_INSIDE,
PD_SYNC_OUTSIDE
} PD_SYNC_MODE_E;
/* 设备配置的 PPS 同步模式. */
typedef enum
{
PD_PPS_AUTO = 0,
PD_PPS_MASTER,
PD_PPS_SLAVE,
} PD_PPS_MODE_E;
/* 协议类型. */
typedef enum
{
PD_PROTOCOL_LAND = 0,
PD_PROTOCOL_CSG = 1
} PD_PROTOCOL_TYPE;
/* 事件类型. */
typedef enum
{
PD_EVENT_TYPE_NONE = 0,
PD_EVENT_TYPE_CNTH, // 计数高
PD_EVENT_TYPE_THRH, // 阈值要
PD_EVENT_TYPE_THRL, // 计数阈值低
PD_EVENT_TYPE_BURST, // 突发
PD_EVENT_TYPE_COUNT
} PD_EVENT_TYPE_E;
/* 端口节点配置优先级 */
typedef enum
{
PD_PORT_CMD_PRI_DAU = 0,
PD_PORT_CMD_PRI_COUNT
} PD_PORT_CMD_PRI_E;
typedef struct {
uint16_t index; // 点位
int16_t data; // 数据
} pd_data_point_t;
/* 1s prps 数据结构体. */
typedef struct {
uint16_t fre_cnt; // 工频周期计数.
uint16_t max; // 通道的最大值.
uint16_t avg_o; // 通道原始信号 (降噪前) 的平均值.
uint16_t avg; // 通道脉冲的平均值.
uint32_t cnt; // 通道脉冲的计数值.
uint32_t phase_sum[PD_PHASE_NUM]; // 通道的周波放电相位累加值.
uint16_t phase_max[PD_PHASE_NUM]; // 通道的周波相位最大值.
uint16_t phase_avg[PD_PHASE_NUM]; // 通道的周波相位平均值.
uint16_t phase_cnt[PD_PHASE_NUM]; // 通道的周波相位计数值
int16_t prps[PD_PRPS_NUM_MAX]; // 1s prps 降噪数据.
pd_data_point_t point[PD_PRPS_NUM_MAX]; // 通道数据.
uint32_t point_cnt; // 通道点数.
uint8_t is_event; // 是否产生事件.
uint8_t is_timing; // 是否产生定时数据.
uint16_t cnt_h; // 高于指定高阈值的脉冲个数.
uint16_t cnt_l; // 高于指定低阈值的脉冲个数.
} pd_prps_data_point_t;
typedef struct {
uint32_t index; // 数据编号.
uint32_t utc; // UTC 时标.
uint32_t ms; // UTC 时标.
pd_prps_data_point_t data[PD_DAU_SUM][PD_DAU_PORT_SUM]; // 16 个通道的数据.
} pd_prps_point_t;
typedef struct {
uint8_t vport; // 通道编号.
uint8_t reserved[3]; // 预留.
uint32_t index; // 数据编号: 0 - (2^32-1) 循环.
uint32_t utc; // UTC 时标.
uint16_t max; // 通道的最大值.
int16_t avg_o; // 通道原始信号 (降噪前) 的平均值.
int16_t avg; // 通道的平均值.
int16_t cnt; // 通道的计数值.
} pd_event_old_t;
typedef struct {
uint32_t power_fre; // 工频周期.
uint8_t data_cnt; // 数据计数
uint8_t event_cnt; // 上次处理的事件计数
uint8_t is_sec_h; // 每秒脉冲高触发.
uint8_t is_sec_l; // 每秒脉冲低触发.
uint8_t is_burst; // 是否产生突变.
uint8_t type; // 事件类型.
uint16_t max; // 通道的最大值.
uint32_t index; // 数据编号: 0 - (2^32-1) 循环.
uint32_t utc; // UTC 时标.
uint32_t cnt; // 通道每秒脉冲计数值.
uint32_t cnt_h; // 高于指定高阈值的脉冲个数.
uint32_t cnt_l; // 高于指定低阈值的脉冲个数.
uint32_t point_cnt; // 数据累计点数.
uint64_t avg_o; // 通道原始信号 (降噪前) 的平均值.
uint64_t avg; // 脉冲平均值.
pd_data_point_t point[PD_EVENT_POINT_MAX]; // 事件累计数据.
} pd_event_port_t;
typedef struct {
pd_event_port_t port[PD_DAU_SUM][PD_DAU_PORT_SUM];
} pd_event_t;
typedef struct {
uint32_t trend_sec; // 上次处理的趋势计数
uint32_t utc; // UTC 时标.
uint16_t data_cnt; // 数据计数.
uint16_t max; // 通道的最大值.
uint64_t avg; // 通道的平均值.
uint32_t cnt; // 通道的计数值.
float phase; // 放电相位 .
float noise; // 趋势数据中的底噪值: 单位 dBm .
uint32_t event_cnt; // 趋势数据中的的事件数量记录.
uint64_t phase_sum[PD_PHASE_NUM]; // 通道的周波放电相位累加值.
uint16_t phase_max[PD_PHASE_NUM]; // 通道的周波相位最大值.
uint16_t phase_avg[PD_PHASE_NUM]; // 通道的周波相位平均值.
uint32_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_col_t;
typedef struct {
uint16_t data[PD_PHASE_NUM][PD_VAULE_NUM];
} pd_trend_prpd_port_t;
typedef struct {
pd_trend_prpd_port_t port[PD_DAU_SUM][PD_DAU_PORT_SUM];
} pd_trend_prpd_t;
typedef struct {
uint32_t point_cnt; // 数据累计点数.
pd_data_point_t point[PD_TREND_POINT_MAX];
} pd_trend_prps_port_t;
typedef struct {
pd_trend_prps_port_t port[PD_DAU_SUM][PD_DAU_PORT_SUM];
} pd_trend_prps_t;
typedef struct {
uint32_t point[PD_PHASE_NUM]; // 最大值出现的位置
int16_t data[PD_PHASE_NUM][PD_TREND_PHASE_POINT_CNT]; // 每个相位中有 256 个点
} pd_trend_original_port_t;
typedef struct {
pd_trend_original_port_t port[PD_DAU_SUM][PD_DAU_PORT_SUM];
} pd_trend_original_t;
typedef struct {
pd_trend_col_t col;
pd_trend_prpd_t *prpd;
pd_trend_prps_t prps;
pd_trend_original_t original;
} pd_trend_t;
typedef struct {
pd_prps_point_t *real; // 实时数据指针
pd_event_t *event; // 事件
pd_trend_col_t trend_col; // 趋势统计数据
pd_trend_prpd_t *trend_prpd; // 趋势 PRPD
pd_trend_t trend; // 趋势完整数据
} pd_data_t;
typedef struct {
uint32_t type;
void *data;
} pd_csg_msg_t;
typedef struct{
uint16_t power_frequency; // 工频频率, 单位: 0.1Hz
uint16_t trend_period; // 趋势数据上送周期, 单位: 秒
uint8_t sync_mode; // 同步方式 1: PT 同步 2: 内同步(默认) 3: 外接信号同步
uint8_t heartbeat_period; // 心跳包周期, 单位: 分钟
uint8_t pps_mode; // pps 主从模式 PD_PPS_XXX
uint8_t protocol_type; // 0:朗德协议 1:南网协议
uint16_t trend_storage; // 趋势存储文件数量阈值
uint16_t event_storage; // 事件存储文件数量阈值
uint8_t is_4G_enable; // 是否使用 4G 模块
char APN[PD_4G_APN_LEN]; // 4G 模块 APN
} pd_config_global_t;
/* 端口配置. */
typedef struct {
uint8_t vport; // 通道编号.
uint8_t port_type; // 采集通道类型 , 1 表示特高频局放 2 表示超声局放 3 表示 TEV 4 表示高频.
uint8_t filter; // 滤波器类型 1: 低频段 2: 全频段 3: 窄频段 4: 高频段
uint8_t sensor_type; // 0: 无配置; 1: UHF信号传感器; 2: UHF噪声传感器 ; 3: UHF信号传感器, 关联噪声降噪.
uint8_t is_auto_noise; // 是否自动调整降噪等级.
uint8_t denoise_type; // 0-无配置 1-自动 2-手动降噪
uint16_t denoise_variance; // 方差降噪系数, 单位: 1%
uint32_t event_counter_h; // 事件次数阀值高.
uint16_t event_sec_h; // 事件每秒次数阀值高.
uint16_t event_thr_h; // 事件值阈值高.
uint32_t event_counter_thr_h; // 事件值阈值高的次数.
uint32_t event_counter_l; // 事件次数阀值低.
uint16_t event_sec_l; // 事件每秒次数阀值低.
uint16_t event_thr_l; // 事件值阈值低.
uint32_t event_counter_thr_l; // 事件值阈值低的次数.
uint8_t burst_time; // 事件突发计算时间
uint8_t reserved0[1];
uint16_t burst_thr; // 事件突发阈值
int16_t denoise_manual; // 手动底噪等级
int16_t denoise_auto; // 自动降噪水平
uint8_t reserved1[2];
uint16_t auto_noise_cnt; // 自动调整降噪等级时脉冲计数阈值.
} pd_config_port_t;
/* 实时波形配置. */
typedef struct {
uint8_t is_concern; // 是否被关注, 在实时波形中使用.
uint8_t filter_cfg; // 端口配置的滤波类型, 在实时波形中使用.
uint8_t denoise_correlation; // 是否启动关联降噪, 在实时波形中使用.
uint8_t denoise_type; // 0-无配置 1-自动 2-手动降噪
uint16_t denoise_manual; // 手动降噪等级
} pd_config_real_t;
typedef struct {
pd_config_global_t config; // 全局配置
pd_config_port_t config_port[PD_DAU_SUM][PD_DAU_PORT_SUM]; // 端口配置
pd_config_real_t config_real[PD_DAU_SUM][PD_DAU_PORT_SUM]; // 实时波形配置
} pd_config_t;
typedef struct
{
uint8_t state;
uint8_t sync;
uint8_t is_4G_connect;
} 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_main_after(void);
extern int32_t pd_port_cmd_config_register(int32_t pri, pd_port_cmd_save_config_f *func);
extern void pd_sync_state_get(void);
extern void pd_pps_mode_set(void);
extern void pd_prps_show(void);
extern void pd_show(void);
#endif
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

@ -0,0 +1,104 @@
/*****************************************************************************
* file include/pd_upgrade.h
* author Wangbo
* version 1.0.0
* date 07-Feb-2023
* brief This file provides all the headers of the softwave upgrade functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2024 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_UPGRADE_H__
#define __PD_UPGRADE_H__
#ifdef CFG_DEV_TYPE_LAND_PD
/* Includes ------------------------------------------------------------------*/
/* Define --------------------------------------------------------------------*/
#define PD_UPG_MAGICNUM 0xEACFA6A6
#define PD_UPG_AREA_MAX 2 // 最多升级区域
#define PD_UPG_VERSION_LEN 16
#define PD_UPG_BLOCK_SIZE (128*1024)
#define PD_UPG_SOFTWARE "upgrade.sw"
#define PD_UPG_CMU_FILE "PDMonitor"
#define PD_UPG_CMU_FILE_BAK "PDMonitor.bak"
#define PD_UPG_SEL_ALL 0
#define PD_UPG_SEL_CMU 1
#define PD_UPG_SEL_DAU 2
#define PD_UPG_SEL_MAX 3
/* Exported types ------------------------------------------------------------*/
enum PD_UPG_TYPE
{
PD_UPG_TYPE_CMU,
PD_UPG_TYPE_DAU,
PD_UPG_TYPE_MAX,
};
enum PD_UPG_FROM
{
PD_UPG_FROM_CSG,
PD_UPG_FROM_DBG,
PD_UPG_FROM_MAX,
};
/*升级文件头*/
typedef struct
{
uint32_t magic; // 结构体幻数 PD_UPG_MAGICNUM
uint32_t crc; // 这里的 CRC 值只包括程序数据的 CRC 校验值 (不包含头)
uint32_t version; // 结构体版本
char hard_ver[PD_UPG_VERSION_LEN]; // hardware version
struct
{
char version[PD_UPG_VERSION_LEN];
uint32_t type; // PD_UPG_TYPE_XXX
uint32_t start; // 文件内的偏移量
uint32_t len; // 升级数据的长度
} arr_info[PD_UPG_AREA_MAX]; // 分段信息
} pd_upg_head_t;
typedef struct
{
uint8_t is_start; // 是否开始升级
uint8_t upg_from; // 是谁在升级 PD_UPG_FROM_xxx
uint8_t upg_type; // 升级类型 PD_UPG_TYPE_xxx
pd_upg_head_t head; // 报文头信息
void (*upgrade_result)(int32_t rv, char *msg); // 升级结果回调函数
char msg[128]; // 返回结果字符串
} pd_upg_ctrl_t;
/* Exported macro ------------------------------------------------------------*/
/* Extern global variables ---------------------------------------------------*/
/* Extern functions ----------------------------------------------------------*/
extern int pd_upg_start(uint8_t from, uint8_t type);
#endif
#endif

@ -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,154 @@
/*************************************************
Copyright (C), 2023--
: typedef.h
: wangbo
: 2023-08-24
:
:
:
1:
: 2023-08-24
: wangbo
:
*************************************************/
#ifndef _TPYEDEF_H
#define _TPYEDEF_H
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <fcntl.h>
//#include <stdint.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <time.h>
#include <signal.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <ctype.h>
#include <math.h>
#include <fnmatch.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/file.h> // flock函数
/************************************************************************
************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <sys/utsname.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h> // tcp keepalive
#include <netinet/ip_icmp.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <net/if_arp.h>
#include <netdb.h>
#include <arpa/inet.h>
#define ZERO_INIT {}
#define NFDS_FOR_SELECT(sock) ((sock) + 1)
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef SUCCESS
#define SUCCESS 0
#endif
#ifndef FAILURE
#define FAILURE -1
#endif
// 整型环境, 内核使用的类型
typedef char s8;
typedef unsigned char u8;
typedef short s16;
typedef unsigned short u16;
typedef int s32;
typedef unsigned int u32;
#if defined WIN32
typedef __int64 s64;
typedef unsigned __int64 u64;
#else
typedef long long s64;
typedef unsigned long long u64;
#endif
typedef int TIMER_T;
typedef int socket_t;
typedef pid_t ThreadId_T;
typedef pid_t ProcessId_T; /// < 进程id
typedef pthread_t Thread_T;
typedef pid_t Process_T;
typedef void * ThreadResult_T;
typedef void * ThreadParam_T;
typedef unsigned int TimeTick_T;
typedef int DevHandle_T;
typedef int Semaphore_T;
#define ThreadProcSpec
#define INVALID_THREAD (Thread_T)(~0)
#define INVALID_SOCKET (~0)
#define INVALID_TIMER (-1)
typedef pthread_mutex_t Mutex_T;
/// @brief 线程函数指针类型
typedef ThreadResult_T (ThreadProcSpec* ThreadProc_T)(ThreadParam_T param);
// max / min
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
#ifndef MIN
#define MIN(a,b) ((a) > (b) ? (b) : (a))
#endif
#ifndef setbitEx
#ifndef NBBYTE //the BSD family defines NBBY
#define NBBYTE 8 //8 bits per byte
#endif
#define setbit(a, i) (((unsigned char *)a)[(i)/NBBYTE] |= 1<<((i)%NBBYTE))
#define clrbit(a, i) (((unsigned char *)a)[(i)/NBBYTE] &= ~(1<<((i)%NBBYTE)))
#define isset(a, i) (((const unsigned char *)a)[(i)/NBBYTE] & (1<<((i)%NBBYTE)))
#define isclr(a, i) ((((const unsigned char *)a)[(i)/NBBYTE] & (1<<((i)%NBBYTE))) == 0)
#endif
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /*_TPYEDEF_H*/

@ -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 || vty->type == VTY_CMD) ? "\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_CMD} 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,339 @@
/*****************************************************************************
* file lib/process/main.c
* author YuLiang
* version 1.0.0
* date 26-Sep-2021
* brief This file provides all the main 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/rtc.h>
#include <time.h>
#include "cmd.h"
#include "mtimer.h"
#include "main.h"
#include "hwgpio.h"
#include "fifo.h"
#include "pd_main.h"
#include "hwgpio.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
int32_t recv_qid;
uint16_t version_hex;
uint32_t start_time;
static int8_t is_system_reboot;
static reboot_msg_t _reboot_msg[] =
{
{REBOOT_NONE, "Reboot none."},
{REBOOT_LOCAL_SERVER_IP_CHANGE, "Reboot by debug tool has changed server."},
{REBOOT_LOCAL_IP_CHANGE, "Reboot by debug tool has changed device ip."},
{REBOOT_LOCAL_HOST_NAME_CHANGE, "Reboot by debug tool has changed device id."},
{REBOOT_LOCAL_RESET, "Reboot by debug tool reset."},
{REBOOT_LOCAL_ARM_UPGRADE, "Reboot by debug tool softwave upgrade."},
{REBOOT_REMOTE_SERVER_IP_CHANGE, "Reboot by remote has changed server."},
{REBOOT_REMOTE_IP_CHANGE, "Reboot by remote has changed device ip."},
{REBOOT_REMOTE_HOST_NAME_CHANGE, "Reboot by remote has changed device id."},
{REBOOT_REMOTE_RESET, "Reboot by remote reset."},
{REBOOT_UPGRADE_ALL, "Reboot by softwave upgrade."},
{REBOOT_SYSTEM_RESET, "Reboot by command."},
{REBOOT_4G_ERROR, "Reboot by 4G error."},
{REBOOT_NET_ERROR, "Reboot by CSG platform connection time out."},
{REBOOT_MAX, NULL}
};
/* 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);
}
/* description: 设备重启函数
param: module -- log
type --
return: */
void reboot_system(int module, REBOOT_MSG type)
{
char *pmsg = NULL;
is_system_reboot = TRUE;
for (REBOOT_MSG i = REBOOT_NONE; i < REBOOT_MAX; i++)
{
if (_reboot_msg[i].type == type)
{
pmsg = _reboot_msg[i].msg;
break;
}
}
if (pmsg)
{
log_out(module, LOG_LVL_WARN, pmsg);
system("sync");
}
sleep(3);
system("reboot -f");
}
//通过RTC-pcf8563系统驱动读写寄存器
int32_t rtc_time_set(struct tm tm)
{
int rtc_fd;
struct tm rtc_tm = tm;
// 打开 RTC 设备
rtc_fd = open("/dev/rtc0", O_RDWR);
if (rtc_fd == -1) {
DBG(DBG_M_DBG, "Unable to open RTC device\n");
return -1;
}
if (ioctl(rtc_fd, RTC_SET_TIME, &rtc_tm) == -1) {
DBG(DBG_M_DBG, "Unable to set RTC time\n");
close(rtc_fd);
return -1;
}
DBG(DBG_M_DBG, "RTC time set successfully\n");
close(rtc_fd);
return 0;
}
int32_t rtc_time_get(struct tm tm)
{
time_t timestamp;
// 定义存储时间的结构体
struct tm rtc_tm;
memset(&rtc_tm, 0, sizeof(struct rtc_time));
//DBG(DBG_M_DBG, "rtc_time_get start!!!!!!!!\r\n");
int fd = open("/dev/rtc0", O_RDONLY);
if (fd == -1) {
DBG(DBG_M_DBG, "打开设备文件失败 errno: %d\r\n", errno);
char * mesg = strerror(errno);
printf("Mesg:%s\n",mesg);
return -1;
}
// 使用 ioctl 调用 RTC_RD_TIME 命令读取时间
if (ioctl(fd, RTC_RD_TIME, &rtc_tm) == -1) {
DBG(DBG_M_DBG, "读取时间失败errno: %d\r\n", errno);
char * mesg = strerror(errno);
printf("Mesg:%s\n",mesg);
close(fd);
return -1;
} else {
memcpy(&tm, &rtc_tm, sizeof(rtc_tm));
// 转换为 Unix 时间戳
timestamp = mktime(&rtc_tm);
if (timestamp == -1) {
DBG(DBG_M_DBG, "make Unix time failed\n");
}
// 输出读取到的时间
#if 0
DBG(DBG_M_DBG, "当前时间: %04d-%02d-%02d %02d:%02d:%02d\n",
rtc_tm.tm_year + 1900, rtc_tm.tm_mon + 1, rtc_tm.tm_mday,
rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
//DBG(DBG_M_DBG, "Unix timestamp: %ld\n", timestamp);
#endif
}
// 关闭设备文件
close(fd);
return 0;
}
/* description: 数据处理预初始化.
param:
return: (E_NONE),() */
int32_t process_init(void)
{
int32_t rv = E_NONE;
/* 创建消息队列. */
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));
}
/* 初始化局放应用. */
rv |= pd_main();
return rv;
}
/* description: 数据处理初始化.
param:
return: (E_NONE),() */
int32_t process_init_after(void)
{
int32_t rv = E_NONE;
rv = pd_main_after();
return rv;
}
/* 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_out(LOG_DEFAULT, LOG_LVL_WARN, "System start!");
#if 0
system("/etc/ppp/peers/quectel-ppp-kill");
sleep(2);
#endif
/* 设置信号处理的回调函数 */
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();
vtycmd_init();
gpio_init();
fifo_init();
log_handle_init();
/* 主处理函数预初始化 */
process_init();
/* 配置恢复命令行启动 */
vtysh_config_recovery();
/* 主处理函数初始化 */
process_init_after();
/* 启动命令行 */
vtysh_shell_init();
vtycmd_cmd_init();
/* 初始化完成 */
version_hex = version_str_to_int();
is_system_init = TRUE;
#if 1
struct tm rtc_tm;
// 设置当前时间设置为2025年2月24日 12:00:00
rtc_tm.tm_year = 2025 - 1900; // 年份需要减去1900
rtc_tm.tm_mon = 1; // 2月
rtc_tm.tm_mday = 24; // 24号
rtc_tm.tm_wday = 1; //星期一
rtc_tm.tm_hour = 12;
rtc_tm.tm_min = 5;
rtc_tm.tm_sec = 30;
rtc_time_set(rtc_tm);
#endif
/* 主循环, 点灯喂狗. */
for(;;)
{
sleep(1);
start_time++;
cnt++;
/* 喂狗. */
if (0 == (cnt & 0x1F))
{
feed_dog();
//rtc_time_get(rtc_tm);
}
}
return 0;
}
/************************ (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,955 @@
/******************************************************************************
* file lib/process/pd_csg.c
* author YuLiang
* version 1.0.0
* date 27-Feb-2023
* brief This file provides all the csg server 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/stat.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sys/prctl.h>
#include <sys/types.h>
#include <dirent.h>
#include <ctype.h>
#include <sys/statvfs.h>
/* 用户代码头文件. */
#include "main.h"
#include "cmd.h"
#include "fifo.h"
#include "pd_main.h"
#include "pd_csg.h"
#include "pd_upgrade.h"
#include "pd_dau.h"
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
csg_t csg;
/* Private function prototypes -----------------------------------------------*/
extern void _csg_server_set(int32_t ip, uint16_t port);
void _csg_show();
/* Internal functions --------------------------------------------------------*/
/* 服务器地址设置 */
CMD(csg_server_set,
csg_server_set_cmd,
"csg server A.B.C.D <1-65535>",
"Csg\n"
"Server\n"
"IPv4 address\n"
"UDP port\n")
{
_csg_server_set(inet_addr((char*)argv[0]), strtol((char*)argv[1], NULL, 10));
return CMD_SUCCESS;
}
/* 显示模块状态 */
CMD(csg_show,
csg_show_cmd,
"show csg",
"Show\n"
"CSG\n")
{
_csg_show();
return CMD_SUCCESS;
}
void _print_sockaddr_in(const struct sockaddr_in *addr)
{
// 将IP地址从网络字节序转换为点分十进制格式
char ip_str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &addr->sin_addr, ip_str, sizeof(ip_str));
// 将端口号从网络字节序转换为主机字节序并打印
unsigned short port = ntohs(addr->sin_port);
DBG(DBG_M_PD_CSG, "IP Address: %s, Port: %u\r\n", ip_str, port);
}
void _csg_show()
{
printh("CSG connect: %s \n", (csg.is_connect == 1)? "OK" : "FAIL");
}
void _csg_server_set(int32_t ip, uint16_t port)
{
/* 比较配置 */
if (csg.server_ip != ip
|| csg.server_port != port)
{
csg.server_ip = ip;
csg.server_port = port;
bzero(&csg.server, sizeof(csg.server));
csg.server.sin_family = AF_INET;
csg.server.sin_addr.s_addr = csg.server_ip;
csg.server.sin_port = htons(csg.server_port);
}
}
/* 校验收到包的包头, 长度, 校验码. */
int32_t _csg_pkt_check(char *pkt)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
/* 对主次设备号进行识别, 次设备号可以是广播. */
if ((head->dev_type_m != device_info.type_m))
{
DBG(DBG_M_PD_CSG_ERR, "@1 type_m=%d %d \r\n", head->dev_type_m, device_info.type_m);
return E_ERROR;
}
if (head->len > 1500)
{
DBG(DBG_M_PD_CSG_ERR, "@2 receive packet len(%d) is out of range\r\n", head->len);
return E_ERROR;
}
return E_NONE;
}
/* 包头填充. */
void _csg_head_init(char *buf, uint16_t len, uint8_t cmdType, uint8_t cmd)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)buf;
/* 封装报文头. */
head->len = len;
head->dev_type_m = device_info.type_m;
head->dev_type_s= device_info.type_s;
head->dev_id = device_info.dev_id;
head->cmd_type = cmdType;
head->cmd = cmd;
head->version = 1;
head->pkt_id = csg.pkt_index++;
}
/* 数据发送 */
void _csg_send_data(uint8_t cmd_type, uint8_t cmd, char *pkt, int32_t len)
{
int32_t rv = 0;
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
/* 封装报文头. */
_csg_head_init(pkt, sizeof(csg_pkt_head_t) + len, cmd_type, cmd);
rv = sendto(csg.skfd, pkt, head->len, 0, (struct sockaddr*)&csg.server, sizeof(csg.server));
if (rv < 0)
{
DBG(DBG_M_PD_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno));
}
}
/* 与后台连接断开 */
void _csg_disconnect_set(const char *message)
{
if (csg.is_connect)
{
csg.is_connect = FALSE;
log_warn(LOG_CSG, "[%s]CSG Connection lost!!!\n", message);
}
}
/* 主动连接请求. */
int32_t _csg_connect_send(void)
{
char *pkt = csg.buf_send;
csg_contact_t *pinfo = (csg_contact_t *)(pkt + sizeof(csg_pkt_head_t));
uint8_t unit = 0;
uint8_t port = 0;
pinfo->type_m = device_info.type_m;
pinfo->type_s = device_info.type_s;
pinfo->dev_id = device_info.dev_id;
strncpy(pinfo->hostname, host.name, sizeof(pinfo->hostname)-1);
pinfo->factory_date = device_info.factory_date;
pinfo->deployment_date = device_info.deployment_date;
strncpy((char *)pinfo->app_version, host.version, sizeof(pinfo->app_version)-1);
strncpy((char *)pinfo->app_compile_time, host.compile, sizeof(pinfo->app_compile_time)-1);
strncpy((char *)pinfo->hardware_version, host.hardversion, 31);
strncpy((char *)pinfo->FPGA_version, host.FPGAversion, 31);
pinfo->ip = device_info.ip;
pinfo->mask = device_info.mask;
pinfo->gw = device_info.gw;
memcpy(pinfo->mac, device_info.mac, sizeof(pinfo->mac));
pinfo->server_port = csg.server_port;
pinfo->server_ipv4 = csg.server_ip;
memset(pinfo->port, 0, sizeof(pinfo->port));
memset(pinfo->port, 0, sizeof(pinfo->port_type));
for(unit = 0; unit < PD_DAU_SUM; unit++)
{
//if (!dau_is_valid(dau[unit]))
{
continue;
}
//for(port = 0; port < dau[unit]->port_num; port++)
{
pinfo->port[port] = pd_config.config_port[unit][port].vport;
pinfo->port_type[port] = pd_config.config_port[unit][port].port_type;;
}
}
_csg_send_data(CSG_REPLY, CSG_C_CONTACT, pkt, sizeof(csg_contact_t));
return E_NONE;
}
/* 心跳包 */
int32_t _csg_heartbeat_send(void)
{
char *pkt = csg.buf_send;
csg_heartbeat_t *pinfo = (csg_heartbeat_t *)(pkt + sizeof(csg_pkt_head_t));
uint16_t i = 0;
for(i = 0; i < PD_DAU_SUM; i++)
{
//if (dau_is_valid(dau[i]))
{
//pinfo->dau_state[i] = dau[i]->is_connect;
//pinfo->dau_port_num[i] = dau[i]->port_num;
}
//else
{
pinfo->dau_state[i] = 0;
pinfo->dau_port_num[i] = 0;
}
}
pinfo->freq = 50;
pinfo->out_sync = 0;
pinfo->pt_sync = 0;
pinfo->in_sync = 0;
if (pd_state.sync)
{
if (PD_SYNC_PT == pd_config.config.sync_mode)
{
pinfo->pt_sync = 1;
}
else if (PD_SYNC_INSIDE == pd_config.config.sync_mode)
{
pinfo->in_sync = 1;
}
else if (PD_SYNC_OUTSIDE == pd_config.config.sync_mode)
{
pinfo->out_sync = 1;
}
}
for(i = 0; i < PD_PORT_SUM; i++)
{
pinfo->port_link_alarm[i] = 0;
}
_csg_send_data(CSG_REPLY, CSG_C_HEARTBEAT, pkt, sizeof(csg_heartbeat_t));
return E_NONE;
}
/* 解析连接报文 */
void _csg_connect_recv(void)
{
csg.is_connect = TRUE;
log_warn(LOG_CSG, "CSG connection OK!");
}
void _csg_add_dau_recv(char *pkt)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
int slot = head->slot;
printf("_csg_add_dau_recv slot = %d\n", head->slot);
head->dev_id = head->sdev_id;
head->cmd_type = CSG_REQUEST;
head->cmd = CSG_C_CONTACT;
head->len = CSG_HEAD_LEN + 4;
//(uint32_t *)(pkt + CSG_HEAD_LEN) = time(NULL);
uint32_t *timestamp = (uint32_t *)(pkt + CSG_HEAD_LEN);
*timestamp = time(NULL);
//_dau_response(slot, pkt, head->len);
_dau_response(slot, pkt, head->len);
}
/* 解析心跳报文. */
void _csg_heartbeat_recv(char *pkt)
{
uint32_t server_time = *(uint32_t*)(pkt + sizeof(csg_pkt_head_t));
//printf("server_time:%d now:%ld\n", server_time, time(NULL));
if (abs(server_time - time(NULL)) > 3)
{
time_set(server_time); //北京时间
}
}
/* 设备重启报文. */
void _csg_reboot_recv(char *pkt)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
csg_ack_t ack = {0};
ack.result = TRUE;
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_ack_t));
_csg_send_data(CSG_REPLY, head->cmd, pkt, sizeof(csg_ack_t));
sleep(3);
reboot_system(LOG_CSG, REBOOT_REMOTE_RESET);
}
/* 厂家参数设置报文处理.
ip ID
*/
int32_t _csg_dev_info_set_recv(char *pkt)
{
int change_ip = 0;
REBOOT_MSG boottype = REBOOT_NONE;
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
csg_dev_info_t *pinfo = (csg_dev_info_t *)(pkt + CSG_HEAD_LEN);
device_info.dev_id = pinfo->dev_id;
device_info.mask = pinfo->mask;
device_info.gw = pinfo->gw;
if (strncmp((char *)(pinfo->hostname), device_info.hostname, sizeof(device_info.hostname)))
{
snprintf((char*)device_info.hostname, PD_DEV_NUM_LEN, "%s", pinfo->hostname);
boottype = REBOOT_REMOTE_HOST_NAME_CHANGE;
}
if (device_info.ip != pinfo->ip)
{
device_info.ip = pinfo->ip;
change_ip++;
boottype = REBOOT_REMOTE_IP_CHANGE;
}
if (csg.server_ip != pinfo->server_ipv4)
{
csg.server_ip = pinfo->server_ipv4;
boottype = REBOOT_REMOTE_SERVER_IP_CHANGE;
}
if (csg.server_port != pinfo->server_port)
{
csg.server_port = pinfo->server_port;
boottype = REBOOT_REMOTE_SERVER_IP_CHANGE;
}
csg_ack_t ack = {0};
ack.result = TRUE;
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_ack_t));
_csg_send_data(CSG_REPLY, head->cmd, pkt, sizeof(csg_ack_t));
vtysh_config_save();
if (change_ip)
{
uint8_t mac[MAC_ADDR_LEN] = {0};
mac_generate_from_ip(device_info.ip, mac);
memcpy(device_info.mac, mac, MAC_ADDR_LEN);
vtysh_eth0_save();
}
vtysh_device_save();
if (boottype)
{
reboot_system(LOG_CSG, boottype);
}
return 0;
}
/* 厂家参数查询报文处理. */
int32_t _csg_dev_info_get_recv(char *pkt)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
csg_dev_info_t *pinfo = (csg_dev_info_t *)(pkt + sizeof(csg_pkt_head_t));
pinfo->type_m = device_info.type_m;
pinfo->type_s = device_info.type_s;
pinfo->dev_id = device_info.dev_id;
strcpy(pinfo->hostname, device_info.hostname);
pinfo->factory_date = device_info.factory_date;
pinfo->deployment_date = device_info.deployment_date;
strncpy((char *)pinfo->app_compile_time, host.compile, 31);
strncpy((char *)pinfo->app_version, host.version, 31);
strncpy((char *)pinfo->hardware_version, host.hardversion, 31);
strncpy((char *)pinfo->FPGA_version, host.FPGAversion, 31);
pinfo->ip = device_info.ip;
pinfo->mask = device_info.mask;
pinfo->gw = device_info.gw;
memcpy(pinfo->mac, device_info.mac, sizeof(pinfo->mac));
//info.server_port = device_info.server_port;
//info.server_ipv4 = device_info.server_ipv4;
pinfo->server_port = csg.server_port;
pinfo->server_ipv4 = csg.server_ip;
_csg_send_data(CSG_REPLY, head->cmd, pkt, sizeof(csg_dev_info_t));
return E_NONE;
}
/* 配置用户参数报文报文处理. */
int32_t _csg_config_set_recv(char *pkt)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
csg_config_global_t *pnet = (csg_config_global_t *)(pkt + CSG_HEAD_LEN);
pd_config.config.power_frequency = pnet->power_frequency;
pd_config.config.trend_period = pnet->trend_period * 60;
pd_config.config.sync_mode = pnet->sync_mode;
pd_config.config.heartbeat_period = pnet->heartbeat_period;
pd_config.config.pps_mode = pnet->pps_mode;
pd_config.config.protocol_type = pnet->protocol_type;
pd_config.config.event_storage = pnet->event_storage;
pd_config.config.trend_storage = pnet->trend_storage;
vtysh_config_save();
csg_ack_t ack = {0};
ack.result = TRUE;
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_ack_t));
_csg_send_data(CSG_PRV_REPLY, head->cmd, pkt, sizeof(csg_ack_t));
return E_NONE;
}
/* 查询用户参数查询报文处理. */
int32_t _csg_config_get_recv(char *pkt)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
csg_config_global_t config = {0};
config.power_frequency = pd_config.config.power_frequency;
config.sync_mode = pd_config.config.sync_mode;
config.heartbeat_period = pd_config.config.heartbeat_period;
config.pps_mode = pd_config.config.pps_mode;
config.protocol_type = pd_config.config.protocol_type;
config.trend_period = pd_config.config.trend_period / 60;
config.trend_storage = pd_config.config.trend_storage;
config.event_storage = pd_config.config.event_storage;
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&config, sizeof(csg_config_global_t));
_csg_send_data(CSG_PRV_REPLY, head->cmd, pkt, sizeof(csg_config_global_t));
return E_NONE;
}
/* 通道提交端口参数设置. */
int32_t _csg_port_config_set_recv(char *pkt)
{
uint8_t vport = *(uint8_t*)(pkt + CSG_HEAD_LEN);
uint8_t unit = 0;
uint8_t port = 0;
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
csg_config_port_t *pnet = (csg_config_port_t *)(pkt + CSG_HEAD_LEN);
pd_config.config_port[unit][port].vport = pnet->vport;
pd_config.config_port[unit][port].port_type = pnet->port_type;
pd_config.config_port[unit][port].filter = pnet->filter;
pd_config.config_port[unit][port].sensor_type = pnet->sensor_type;
pd_config.config_port[unit][port].is_auto_noise = pnet->is_auto_noise;
pd_config.config_port[unit][port].denoise_type = pnet->denoise_type;
pd_config.config_port[unit][port].denoise_variance = pnet->denoise_variance;
pd_config.config_port[unit][port].event_counter_h = pnet->event_counter_h;
pd_config.config_port[unit][port].event_sec_h = pnet->event_sec_h;
pd_config.config_port[unit][port].event_thr_h = pnet->event_thr_h;
pd_config.config_port[unit][port].event_counter_thr_h = pnet->event_counter_thr_h;
pd_config.config_port[unit][port].event_counter_l = pnet->event_counter_l;
pd_config.config_port[unit][port].event_sec_l = pnet->event_sec_l;
pd_config.config_port[unit][port].event_thr_l = pnet->event_thr_l;
pd_config.config_port[unit][port].event_counter_thr_l = pnet->event_counter_thr_l;
pd_config.config_port[unit][port].burst_time = pnet->burst_time;
pd_config.config_port[unit][port].burst_thr = pnet->burst_thr;
pd_config.config_port[unit][port].denoise_manual = pnet->denoise_manual;
pd_config.config_port[unit][port].denoise_auto = pnet->denoise_auto;
pd_config.config_real[unit][port].filter_cfg = pd_config.config_port[unit][port].filter;
//dau_port_filter_set(unit, port);
vtysh_config_save();
//csg_config_port_ack_t ack = {0};
//ack.vport = pnet->vport;
//ack.result = TRUE;
//memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_config_port_ack_t));
//_csg_send_data(CSG_PRV_REPLY, head->cmd, pkt, sizeof(csg_config_port_ack_t));
return E_NONE;
}
/* 按通道提交端口参数查询结果. */
int32_t _csg_port_config_get_recv(char *pkt)
{
uint8_t vport = *(uint8_t*)(pkt + CSG_HEAD_LEN);
uint8_t unit = 0;
uint8_t port = 0;
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
csg_config_port_t *pnet = (csg_config_port_t *)(pkt + CSG_HEAD_LEN);
//if (dau_vport_to_port(pnet->vport, &unit, &port) != E_NONE)
{
DBG(DBG_M_PD_CSG_ERR, "Pkt port %d error!\r\n", vport);
return E_ERROR;
}
csg_config_port_t config = {0};
config.vport = pd_config.config_port[unit][port].vport;
config.port_type = pd_config.config_port[unit][port].port_type;
config.filter = pd_config.config_port[unit][port].filter;
config.sensor_type = pd_config.config_port[unit][port].sensor_type;
config.is_auto_noise = pd_config.config_port[unit][port].is_auto_noise;
config.denoise_type = pd_config.config_port[unit][port].denoise_type;
config.denoise_variance = pd_config.config_port[unit][port].denoise_variance;
config.event_counter_h = pd_config.config_port[unit][port].event_counter_h;
config.event_sec_h = pd_config.config_port[unit][port].event_sec_h;
config.event_thr_h = pd_config.config_port[unit][port].event_thr_h;
config.event_counter_thr_h = pd_config.config_port[unit][port].event_counter_thr_h;
config.event_counter_l = pd_config.config_port[unit][port].event_counter_l;
config.event_sec_l = pd_config.config_port[unit][port].event_sec_l;
config.event_thr_l = pd_config.config_port[unit][port].event_thr_l;
config.event_counter_thr_l = pd_config.config_port[unit][port].event_counter_thr_l;
config.burst_time = pd_config.config_port[unit][port].burst_time;
config.burst_thr = pd_config.config_port[unit][port].burst_thr;
config.denoise_manual = pd_config.config_port[unit][port].denoise_manual;
config.denoise_auto = pd_config.config_port[unit][port].denoise_auto;
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&config, sizeof(csg_config_port_t));
_csg_send_data(CSG_PRV_REPLY, head->cmd, pkt, sizeof(pd_config_port_t));
return E_NONE;
}
/* 升级文件接收 */
int32_t _csg_upgrade_recv(char *pkt)
{
static int fd = -1;
static uint32_t fix_len = 0;
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
csg_upgrade_data_t *head_msg = (csg_upgrade_data_t*)(pkt + CSG_HEAD_LEN);
char *pdata = pkt + CSG_HEAD_LEN + sizeof(csg_upgrade_data_t);
upgrade_ack_t ack = {0};
int32_t size = 0;
int32_t len_wr = 0;
int32_t rv = E_NONE;
uint32_t offset = 0;
/* 首保处理, 打开文件描述符, 初始化变量 */
if (head_msg->index == 0)
{
if (fd > 0)
{
close(fd);
fd = -1;
}
fd = open(PD_UPG_SOFTWARE, O_WRONLY | O_CREAT | O_TRUNC, 0777);
if (fd < 0)
{
DBG(DBG_M_PD_CSG_ERR, "Open file " PD_UPG_SOFTWARE " error!\n");
return E_SYS_CALL;
}
fix_len = head_msg->len;
DBG(DBG_M_PD_CSG, "Receive upgrade file start.\n");
}
DBG(DBG_M_PD_CSG_ERR,"type=%d,sum=%d,index=%d,len=%d,fix_len=%d\n", head_msg->type, head_msg->sum, head_msg->index, head_msg->len, fix_len);
/* 收包流程 */
size = head_msg->len;
offset = head_msg->index * fix_len;
if (lseek(fd, offset, SEEK_SET) < 0)
{
DBG(DBG_M_PD_CSG_ERR, "lseek file " PD_UPG_SOFTWARE " error!\n");
return E_SYS_CALL;
}
len_wr = write(fd, pdata, size);
if (len_wr != size)
{
DBG(DBG_M_PD_CSG_ERR, "Write file " PD_UPG_SOFTWARE " error!\n");
return E_SYS_CALL;
}
/* 最后一个报文处理 */
if (head_msg->sum - 1 == head_msg->index)
{
close(fd);
fd = -1;
DBG(DBG_M_PD_CSG, "Receive upgrade file end.\n");
rv = pd_upg_start(PD_UPG_FROM_CSG, head_msg->type);
}
ack.index = head_msg->index;
ack.result = TRUE;
DBG(DBG_M_PD_CSG_ERR," send ack\n");
/* 发送应答 */
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_ack_t));
_csg_send_data(CSG_REPLY, head->cmd, pkt, sizeof(ack));
/* 如果升级线程开启失败返回错误信息. */
if (rv != E_NONE)
{
printf("Upgrade start failed.\n");
csg_upgrade_result_send(0, "Upgrade start failed.");
}
return E_NONE;
}
int32_t _csg_event_recv(char *pkt)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
int slot = head->slot;
printf("_csg_event_recv slot = %d\n", head->slot);
head->dev_id = head->sdev_id;
head->cmd = CSG_PRV_EVENT;
_dau_response(slot, pkt, head->len);
return E_NONE;
}
int32_t _csg_recv_process(char *pkt, uint32_t len)
{
csg_pkt_head_t *head = (csg_pkt_head_t *)pkt;
/* 报文头和 CRC 校验. */
LD_E_RETURN(DBG_M_PD_CSG_ERR, _csg_pkt_check(pkt));
csg.heartbeat_timeout_cnt = 0;
if (CSG_REQUEST == head->cmd_type)
{
switch (head->cmd)
{
case CSG_C_CONTACT:
_csg_connect_recv();
break;
case CSG_C_ADD_DAU:
_csg_add_dau_recv(pkt);
break;
case CSG_C_RESET:
_csg_reboot_recv(pkt);
break;
case CSG_C_UPDATE:
_csg_upgrade_recv(pkt);
break;
case CSG_C_HEARTBEAT:
_csg_heartbeat_recv(pkt);
break;
case CSG_C_DEV_INFO_SET:
_csg_dev_info_set_recv(pkt);
break;
case CSG_C_DEV_INFO_GET:
_csg_dev_info_get_recv(pkt);
break;
default:
break;
}
}
else if (CSG_PRV_REQUEST == head->cmd_type)
{
switch (head->cmd)
{
case CSG_PRV_CONFIG_GLOBAL_SET:
_csg_config_set_recv(pkt);
break;
case CSG_PRV_CONFIG_GLOBAL_GET:
_csg_config_get_recv(pkt);
break;
case CSG_PRV_CONFIG_PORT_SET:
_csg_port_config_set_recv(pkt);
break;
case CSG_PRV_CONFIG_PORT_GET:
_csg_port_config_get_recv(pkt);
break;
case CSG_PRV_CONFIG_REAL_WAVE:
break;
case CSG_PRV_TREND:
break;
case CSG_PRV_REAL_PRPS:
break;
case CSG_PRV_EVENT:
_csg_event_recv(pkt);
break;
default:
break;
}
}
return E_NONE;
}
/* 心跳和连接处理函数. */
void *_csg_recv_handle(void *arg)
{
struct sockaddr_in server;
socklen_t server_len;
int32_t addr = 0;
uint16_t data_len = 0;
/* 等待初始化完成 */
while(!is_system_init)
{
sleep(1);
}
prctl(PR_SET_NAME, "CSG_RCVE", 0, 0, 0);
while(1)
{
/* 读取数据. */
memset(csg.buf_recv, 0, sizeof(csg.buf_recv));
data_len = recvfrom(csg.skfd, csg.buf_recv, CSG_PKT_LEN, 0, (struct sockaddr*)&server, &server_len);
if (data_len <= 0)
{
DBG(DBG_M_PD_CSG_ERR, "Recvfrom return ERROR %s!\r\n", safe_strerror(errno));
continue;
}
addr = server.sin_addr.s_addr;
if (addr != csg.server_ip)
{
continue;
}
_csg_recv_process(csg.buf_recv, data_len);
}
return NULL;
}
/* 心跳和连接处理函数. */
void *_csg_heartbeat_handle(void *arg)
{
time_t now = 0;
time_t t_connect = 0;
time_t t_heartbeat = 0;
/* 等待初始化完成 */
while(!is_system_init)
{
sleep(1);
}
while(1)
{
sleep(1);
now = time(NULL);
/* 发送连接报文. */
if (!csg.is_connect)
{
if (abs(now - t_connect) >= 3)
{
_csg_connect_send();
t_connect = now;
}
continue;
}
/* 发送心跳包. */
if (abs(now - t_heartbeat) >= pd_config.config.heartbeat_period * 60)
{
_csg_heartbeat_send();
t_heartbeat = now;
csg.heartbeat_timeout_cnt++;
/* 等待回复报文后再进行连接判断 */
sleep(3);
if (csg.heartbeat_timeout_cnt > 3)
{
csg.heartbeat_timeout_cnt = 0;
_csg_disconnect_set(__FUNCTION__);
}
}
}
return NULL;
}
/* 配置保存函数. */
int _csg_config_save(vty_t* vty)
{
int16_t i = 0;
struct in_addr addr;
addr.s_addr = csg.server_ip;
vty_out(vty, "csg server %s %d%s", inet_ntoa(addr), csg.server_port, VTY_NEWLINE);
i++;
return i;
}
/* Interface functions -------------------------------------------------------*/
/* 后台通讯模块预初始化. */
int32_t csg_handle_init(void)
{
int32_t rv = 0;
memset(&csg, 0, sizeof(csg_t));
/* 发送数据. */
csg.server_ip = inet_addr("192.168.1.161");
csg.server_port = 1885;
bzero(&csg.server, sizeof(csg.server));
csg.server.sin_family = AF_INET;
csg.server.sin_addr.s_addr = csg.server_ip;
csg.server.sin_port = htons(csg.server_port);
cmd_install_element(CONFIG_NODE, &csg_server_set_cmd);
cmd_install_element(COMMON_NODE, &csg_show_cmd);
/* 注册配置保存函数 */
rv = cmd_config_node_config_register(CONFIG_PRI_CSG, _csg_config_save);
if (rv != E_NONE)
{
log_err(LOG_CSG, "Command save register ERROR %d!", rv);
return rv;
}
return E_NONE;
}
/* 后台通讯模块初始化. */
int32_t csg_handle_init_after(void)
{
struct sockaddr_in server;
int fd = 0;
thread_param_t param = {0};
if (pd_config.config.protocol_type != PD_PROTOCOL_LAND)
{
return E_NONE;
}
/* 创建协议 socket. */
if (0 == csg.skfd)
{
/* 创建socket */
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
{
log_err(LOG_CSG, "ERROR at socket create return %s!", safe_strerror(errno));
return E_SYS_CALL;
}
/* 绑定端口 */
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(7777);
if(bind(fd, (struct sockaddr*)&server, sizeof(server)) < 0)
{
log_err(LOG_CSG, "ERROR at socket bind return %s!", safe_strerror(errno));
close(fd);
return E_SYS_CALL;
}
/* 保存数据. */
csg.skfd = fd;
}
param.arg = NULL;
param.log_module = LOG_CSG;
param.priority = 45;
param.thread_name = "CSG_RCVE";
create_thread(_csg_recv_handle, &param);
param.priority = 45;
param.thread_name = "CSG_HEARTBEAT";
create_thread(_csg_heartbeat_handle, &param);
return E_NONE;
}
/* description: 远程升级结果返回回调函数
param: rv --
buf --
return: */
void csg_upgrade_result_send(int32_t rv, char *buf)
{
upgrade_res_t ack = {0};
char *pkt = csg.buf_send;
ack.result = rv;
strcpy(ack.context, buf);
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_ack_t));
_csg_send_data(CSG_REPLY, CSG_C_UPDATE_RESULT, pkt, sizeof(upgrade_res_t));
}
command_handler _csg_get_table_handle(command_entry *ptable, command_type cmd)
{
if (NULL == ptable)
{
return NULL;
}
for (;CMD_INVALID != ptable->cmd; ptable++)
{
if (cmd == ptable->cmd)
{
return ptable->handler;
}
}
return ptable->handler;
}
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,754 @@
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef CFG_DEV_TYPE_LAND_PD
/* 标准C库头文件. */
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/prctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <termios.h>
#include <fcntl.h>
/* 用户代码头文件. */
#include "main.h"
#include "cmd.h"
#include "pd_dau.h"
#include "pd_hf.h"
#include "pd_csg.h"
/* Private variables ---------------------------------------------------------*/
//dau_t dau;
pthread_mutex_t board_mutex = PTHREAD_MUTEX_INITIALIZER;
int udp_socket;
dau_t daus[MAX_SLOTS];
// 上传平台回调函数类型
typedef void (*UploadCallback)(int slot, const void *data, size_t len);
/* Private function prototypes -----------------------------------------------*/
int _dau_insert(int slot, DauType type);
int _dau_remove(int slot);
extern void _print_sockaddr_in(const struct sockaddr_in *addr);
/* Internal functions --------------------------------------------------------*/
CMD(dau_add,
dau_add_cmd,
"dau <1-6>",
"DAU\n"
"Dau number\n")
{
uint8_t unit = 0;
unit = strtol(argv[0], NULL, 10) - 1;
_dau_insert(unit, DAU_TYPE_UDP);
return CMD_SUCCESS;
}
CMD(no_dau_add,
no_dau_add_cmd,
"no dau <1-6>",
"DAU\n"
"Dau number\n")
{
uint8_t unit = 0;
unit = strtol(argv[0], NULL, 10) - 1;
_dau_remove(unit);
return CMD_SUCCESS;
}
#if 0
// ================== UDP 操作函数 ==================
static int _dau_udp_init(dau_private_data_t *data, const char *config)
{
// 解析配置: "ip:port:board_id"
char ip[32], board_id[32];
int port;
struct sockaddr_in server_addr;
int sockfd;
if (sscanf(config, "%[^:]:%d:%s", ip, &port, board_id) != 3)
{
return -1;
}
// 创建socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
log_err(LOG_DAU, "ERROR at socket create return %s!", safe_strerror(errno));
return E_SYS_CALL;
}
// 设置地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//inet_pton(AF_INET, ip, &server_addr.sin_addr);
// 绑定套接字
if (bind(sockfd, (const struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
{
log_err(LOG_DAU, "ERROR at socket create return %s!", safe_strerror(errno));
close(sockfd);
return E_SYS_CALL;
}
strncpy(data->board_id, board_id, sizeof(data->board_id));
// 配置缓冲区 (示例)
data->buffer_size = 4096;
data->rx_buffer = malloc(data->buffer_size);
if (!data->rx_buffer)
{
close(sockfd);
return E_SYS_CALL;;
}
//data->comm.udp.addr = server_addr;
data->comm.udp.sockfd = sockfd;
printf("UDP board %s initialized at %s:%d\n",
board_id, ip, port);
return 0;
}
static int _dau_udp_receive(dau_private_data_t *data, void *buf, size_t len)
{
struct sockaddr_in client_addr;
socklen_t addr_len = sizeof(client_addr);
int data_len = 0;
do
{
data_len = recvfrom(data->comm.udp.sockfd, buf, len, 0,
(struct sockaddr*)&client_addr, &addr_len);
if (data_len <= 0)
{
DBG(DBG_M_PD_DAU_ERR, "Recvfrom return ERROR %s!\r\n", safe_strerror(errno));
continue;
}
// 获取客户端IP和端口
char client_ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, INET_ADDRSTRLEN);
int client_port = ntohs(client_addr.sin_port);
//memcpy(&data->comm.add, &client_addr, sizeof(client_addr));
data->comm.udp.addr = client_addr;
printf("Received from %s:%d:\n", client_ip, client_port);
} while(0);
return data_len;
}
static int _dau_udp_transmit(dau_private_data_t *data, const void *buf, size_t len)
{
printf("sockfd=%d\n", data->comm.udp.sockfd);
_print_sockaddr_in(&data->comm.udp.addr);
return sendto(data->comm.udp.sockfd, buf, len, 0,
(struct sockaddr*)&data->comm.udp.addr,
sizeof(data->comm.udp.addr));
}
static void _dau_udp_cleanup(dau_private_data_t *data)
{
if (data->comm.udp.sockfd >= 0)
{
close(data->comm.udp.sockfd);
data->comm.udp.sockfd = -1;
}
if (data->rx_buffer)
{
free(data->rx_buffer);
data->rx_buffer = NULL;
}
printf("UDP board %s cleaned up\n", data->board_id);
}
#endif
#if 0
// ================== RS485 操作函数 ==================
static int _dau_rs485_init(dau_private_data_t *data, const char *config)
{
// 解析配置: "port:baudrate:board_id"
char port[32], board_id[32];
int baudrate;
if (sscanf(config, "%[^:]:%d:%s", port, &baudrate, board_id) != 3) {
return -1;
}
// 打开串口
data->comm.rs485.fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
if (data->comm.rs485.fd < 0)
{
perror("RS485 open failed");
return -1;
}
// 获取当前串口设置
tcgetattr(data->comm.rs485.fd, &data->comm.rs485.options);
// 设置波特率
cfsetispeed(&data->comm.rs485.options, baudrate);
cfsetospeed(&data->comm.rs485.options, baudrate);
// 设置8N1
data->comm.rs485.options.c_cflag &= ~PARENB;
data->comm.rs485.options.c_cflag &= ~CSTOPB;
data->comm.rs485.options.c_cflag &= ~CSIZE;
data->comm.rs485.options.c_cflag |= CS8;
// 应用设置
tcsetattr(data->comm.rs485.fd, TCSANOW, &data->comm.rs485.options);
strncpy(data->board_id, board_id, sizeof(data->board_id));
strncpy(data->comm.rs485.port, port, sizeof(data->comm.rs485.port));
// 配置缓冲区
data->buffer_size = 1024;
data->rx_buffer = malloc(data->buffer_size);
if (!data->rx_buffer) {
close(data->comm.rs485.fd);
return -1;
}
printf("RS485 board %s initialized on %s@%d\n",
board_id, port, baudrate);
return 0;
}
static int _dau_rs485_receive(dau_private_data_t *data, void *buf, size_t len)
{
return read(data->comm.rs485.fd, buf, len);
}
static int _dau_rs485_transmit(dau_private_data_t *data, const void *buf, size_t len)
{
return write(data->comm.rs485.fd, buf, len);
}
static void _dau_rs485_cleanup(dau_private_data_t *data)
{
if (data->comm.rs485.fd >= 0)
{
close(data->comm.rs485.fd);
data->comm.rs485.fd = -1;
}
if (data->rx_buffer)
{
free(data->rx_buffer);
data->rx_buffer = NULL;
}
printf("RS485 board %s cleaned up\n", data->board_id);
}
// ================== 板卡管理函数 ==================
static void _dau_seek_proper_function(int slot, dau_private_data_t *data)
{
if (strncmp(data->board_id, UHF, strlen(UHF)) == 0)
{
}
else if (strncmp(data->board_id, HF, strlen(HF)) == 0)
{
_hf_recv_process(slot, data->rx_buffer);
}
else if (strncmp(data->board_id, ULTRASONIC, strlen(ULTRASONIC)) == 0)
{
}
else if (strncmp(data->board_id, IRONCORE, strlen(IRONCORE)) == 0)
{
}
}
#endif
static int32_t _dau_find_proper_function(char *pkt)
{
int flag = 0;
csg_pkt_head_t *head = (csg_pkt_head_t *)pkt;
for (int i = 0; i < MAX_SLOTS; i++)
{
if (daus[i].slot != head->slot)
continue;
if (daus[i].state == DAU_STATE_REGISTERED)
{
flag = 1;
}
}
if (!flag)
return E_NONE;
if (head->dev_type_m == 0x03)
{
if (head->dev_type_s == 0x01)
{
_hf_recv_process(head->slot, pkt);
}
else if (head->dev_type_s == 0x02)
{}
else if (head->dev_type_s == 0x03)
{}
}
return E_NONE;
}
// 申请板卡私有数据
void* _dau_alloc_private_data(DauType type, int slot)
{
if (type == DAU_TYPE_UDP)
{
udp_client_data *data = malloc(sizeof(udp_client_data));
memset(data, 0, sizeof(udp_client_data));
return data;
}
else if (type == DAU_TYPE_RS485)
{
rs485_device_data *data = malloc(sizeof(rs485_device_data));
memset(data, 0, sizeof(rs485_device_data));
// 根据槽位分配串口设备
const char *device = (slot == 4) ? "/dev/ttyS0" : "/dev/ttyS1";
//data->fd = init_rs485(device);
data->address = (slot == 4) ? 0x01 : 0x02;
if (data->fd < 0)
{
free(data);
return NULL;
}
return data;
}
return NULL;
}
// 释放板卡私有数据
void _dau_free_private_data(DauType type, void *data)
{
if (!data)
{
return;
}
if (type == DAU_TYPE_UDP)
{
free(data);
}
else if (type == DAU_TYPE_RS485)
{
rs485_device_data *dev = (rs485_device_data*)data;
if (dev->fd >= 0)
{
close(dev->fd);
}
free(data);
}
}
// ================== 板卡管理函数 ==================
#if 0
static void *_dau_thread_func(void *arg)
{
dau_manager_t *manager = (dau_manager_t *)arg;
dau_private_data_t *data = manager->private_data;
prctl(PR_SET_NAME, (unsigned long)data->board_id, 0, 0, 0);
printf("Board thread started for slot %d (%s)\n",
manager->slot, data->board_id);
while (manager->occupied)
{
// 接收数据
ssize_t bytes = manager->ops.receive(data, data->rx_buffer, data->buffer_size);
if (bytes > 0)
{
// 处理数据
printf("Slot %d received %zd bytes\n", manager->slot, bytes);
_dau_seek_proper_function(manager->slot, data);
}
else if (bytes < 0)
{
perror("Receive error");
usleep(100000); // 100ms 延迟后重试
}
}
printf("Board thread exiting for slot %d\n", manager->slot);
return NULL;
}
int _dau_insert(int slot, DauType type, const char *config)
{
if (slot < 0 || slot >= MAX_SLOTS) return -1;
pthread_mutex_lock(&dau.mutex);
if (dau.mgr[slot].occupied)
{
pthread_mutex_unlock(&dau.mutex);
return -2; // 槽位已被占用
}
// 创建私有数据
dau_private_data_t *data = malloc(sizeof(dau_private_data_t));
if (!data)
{
pthread_mutex_unlock(&dau.mutex);
return -3;
}
memset(data, 0, sizeof(dau_private_data_t));
data->type = type;
// 设置操作函数
dau_operations_t ops;
switch (type)
{
case DAU_UDP:
ops.init = _dau_udp_init;
ops.receive = _dau_udp_receive;
ops.transmit = _dau_udp_transmit;
ops.cleanup = _dau_udp_cleanup;
break;
case DAU_RS485:
ops.init = _dau_rs485_init;
ops.receive = _dau_rs485_receive;
ops.transmit = _dau_rs485_transmit;
ops.cleanup = _dau_rs485_cleanup;
break;
default:
free(data);
pthread_mutex_unlock(&dau.mutex);
return -4;
}
// 初始化板卡
if (ops.init(data, config) != 0)
{
free(data);
pthread_mutex_unlock(&dau.mutex);
return -5;
}
// 配置管理器
dau.mgr[slot].private_data = data;
dau.mgr[slot].ops = ops;
dau.mgr[slot].slot = slot + 1;
dau.mgr[slot].occupied = TRUE;
// 创建线程
if (pthread_create(&dau.mgr[slot].thread_id, NULL,
_dau_thread_func, &dau.mgr[slot]) != 0)
{
ops.cleanup(data);
free(data);
memset(&dau.mgr[slot], 0, sizeof(dau_manager_t));
pthread_mutex_unlock(&dau.mutex);
return -6;
}
pthread_mutex_unlock(&dau.mutex);
return 0;
}
int _dau_remove(int slot)
{
if (slot < 0 || slot >= MAX_SLOTS) return -1;
pthread_mutex_lock(&dau.mutex);
if (!dau.mgr[slot].occupied)
{
pthread_mutex_unlock(&dau.mutex);
return -2; // 槽位空闲
}
// 设置停止标志
dau.mgr[slot].occupied = FALSE;
// 等待线程结束
pthread_join(dau.mgr[slot].thread_id, NULL);
// 清理资源
dau.mgr[slot].ops.cleanup(dau.mgr[slot].private_data);
free(dau.mgr[slot].private_data);
memset(&dau.mgr[slot], 0, sizeof(dau_manager_t));
pthread_mutex_unlock(&dau.mutex);
return 0;
}
#endif
int _dau_insert(int slot, DauType type)
{
if (slot < 0 || slot >= MAX_SLOTS)
{
return E_BAD_PARAM;
}
pthread_mutex_lock(&board_mutex);
if (daus[slot].state != DAU_STATE_DISCONNECTED)
{
pthread_mutex_unlock(&board_mutex);
return E_ERROR;
}
// 分配私有数据
void *priv_data = _dau_alloc_private_data(type, slot);
if (!priv_data)
{
pthread_mutex_unlock(&board_mutex);
return E_ERROR;
}
// 更新板卡信息
daus[slot].type = type;
daus[slot].state = DAU_STATE_CONNECTED;
daus[slot].private_data = priv_data;
daus[slot].slot = slot;
pthread_mutex_unlock(&board_mutex);
printf("Board inserted in slot %d (Type: %s)\n",
slot, (type == DAU_TYPE_UDP) ? "UDP" : "RS485");
return E_NONE;
}
int _dau_remove(int slot)
{
pthread_mutex_lock(&board_mutex);
if (daus[slot].state == DAU_STATE_DISCONNECTED)
{
pthread_mutex_unlock(&board_mutex);
return;
}
// 释放资源
_dau_free_private_data(daus[slot].type, daus[slot].private_data);
// 重置板卡信息
daus[slot].type = DAU_TYPE_NONE;
daus[slot].state = DAU_STATE_DISCONNECTED;
daus[slot].private_data = NULL;
pthread_mutex_unlock(&board_mutex);
printf("Board removed from slot %d\n", slot);
}
int _dau_response(int slot, char *buf, int len)
{
printf("_dau_response: slot=%d len=%d\n", slot, len);
if (slot >= 0 && slot < MAX_SLOTS)
{
if (daus[slot].type == DAU_TYPE_UDP)
{
udp_client_data *client = (udp_client_data*)daus[slot].private_data;
sendto(udp_socket, buf, len, 0,
(struct sockaddr*)&client->addr, sizeof(client->addr));
}
else if (daus[slot].type == DAU_TYPE_RS485)
{
rs485_device_data *dev = (rs485_device_data*)daus[slot].private_data;
write(dev->fd, buf, len);
}
}
}
#if 0
int main() {
_board_init_system();
register_upload_callback(example_upload_callback);
// 插入UDP板卡
_board_insert(0, BOARD_UDP, "192.168.1.100:5000:UDP_CARD_1");
_board_insert(1, BOARD_UDP, "192.168.1.101:5000:UDP_CARD_2");
_board_insert(2, BOARD_UDP, "192.168.1.102:5000:UDP_CARD_3");
_board_insert(3, BOARD_UDP, "192.168.1.103:5000:UDP_CARD_4");
// 插入RS485板卡
_board_insert(4, BOARD_RS485, "/dev/ttyS0:115200:RS485_CARD_1");
_board_insert(5, BOARD_RS485, "/dev/ttyS1:115200:RS485_CARD_2");
// 模拟运行
sleep(5);
// 拔出板卡示例
_board_remove(2);
sleep(2);
// 重新插入板卡
_board_insert(2, BOARD_UDP, "192.168.1.104:5000:UDP_CARD_NEW");
sleep(5);
_board_shutdown_system();
return 0;
}
#endif
// 初始化UDP服务器
int _dau_init_udp_server()
{
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
{
perror("UDP socket creation failed");
return -1;
}
struct sockaddr_in server_addr =
{
.sin_family = AF_INET,
.sin_port = htons(UDP_PORT),
.sin_addr.s_addr = INADDR_ANY
};
if (bind(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)))
{
perror("UDP bind failed");
close(sock);
return -1;
}
return sock;
}
void *_dau_manager_handle(void *arg)
{
prctl(PR_SET_NAME, "CSG_RCVE", 0, 0, 0);
while(1)
{
sleep(1);
}
return NULL;
}
void *_dau_udp_receive_handle(void *arg)
{
prctl(PR_SET_NAME, "DAU_RCVE", 0, 0, 0);
struct sockaddr_in client_addr;
socklen_t addr_len = sizeof(client_addr);
char buffer[2048];
while(1)
{
ssize_t len = recvfrom(udp_socket, buffer, sizeof(buffer), 0,
(struct sockaddr*)&client_addr, &addr_len);
if (len <= 0) continue;
buffer[len] = '\0';
_print_sockaddr_in(&client_addr);
// 查找匹配的UDP板卡
pthread_mutex_lock(&board_mutex);
for (int i = 0; i < UDP_SLOTS; i++)
{
//printf("state=%d\n", daus[i].state);
if (daus[i].state == DAU_STATE_DISCONNECTED)
continue;
udp_client_data *client = (udp_client_data *)daus[i].private_data;
if (memcmp(&client->addr, &client_addr, sizeof(client_addr)) == 0)
{
break;
}
// 如果是新连接
if (daus[i].state == DAU_STATE_CONNECTED &&
client->addr.sin_port == 0)
{
memcpy(&client->addr, &client_addr, sizeof(client_addr));
daus[i].state = DAU_STATE_REGISTERED;
break;
}
}
pthread_mutex_unlock(&board_mutex);
// 处理数据
if (!csg.is_connect)
continue;
_dau_find_proper_function(buffer);
usleep(1000);
}
return NULL;
}
int32_t dau_handle_init(void)
{
int32_t rv = 0;
memset(&daus, 0, sizeof(dau_t)*MAX_SLOTS);
//cmd_install_element(CONFIG_NODE, &csg_server_set_cmd);
cmd_install_element(COMMON_NODE, &dau_add_cmd);
cmd_install_element(COMMON_NODE, &no_dau_add_cmd);
//cmd_install_element(COMMON_NODE, &csg_file_cmd);
/* 注册配置保存函数 */
//rv = cmd_config_node_config_register(CONFIG_PRI_CSG, _csg_config_save);
if (rv != E_NONE)
{
log_err(LOG_CSG, "Command save register ERROR %d!", rv);
return rv;
}
return E_NONE;
}
/* 后台通讯模块初始化. */
int32_t dau_handle_init_after(void)
{
if (0 == udp_socket)
{
udp_socket = _dau_init_udp_server();
}
printf("udp_socket=%d\n", udp_socket);
/* 初始化模块. */
thread_param_t param = {0};
param.priority = 45;
param.thread_name = "DAU_MANAGER";
create_thread(_dau_manager_handle, &param);
param.priority = 45;
param.thread_name = "DAU_RECV";
create_thread(_dau_udp_receive_handle, &param);
return E_NONE;
}
#endif

@ -0,0 +1,192 @@
/******************************************************************************
* file lib/process/pd_hf.c
* author YuLiang
* version 1.0.0
* date 05-March-2025
* brief This file provides all the HF operation functions.
*
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2025 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 <math.h>
/* 用户代码头文件. */
#include "pd_main.h"
#include "pd_csg.h"
#include "pd_dau.h"
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
void _hf_contact_recv(int slot, char *pkt);
void _hf_heartbeat_recv(int slot, char *pkt);
void _hf_real_image_recv(int slot, char *pkt);
void _hf_trend_recv(int slot, char *pkt);
void _hf_event_recv(int slot, char *pkt);
// 命令映射表
static command_entry hf_request_command_table[] =
{
{CSG_C_CONTACT, _hf_contact_recv},
{CSG_C_HEARTBEAT, _hf_heartbeat_recv},
{CMD_INVALID, NULL}
};
// 命令映射表
static command_entry hf_prv_request_command_table[] =
{
{CSG_PRV_TREND, _hf_event_recv},
{CSG_PRV_REAL_PRPS, _hf_event_recv},
{CSG_PRV_EVENT, _hf_event_recv},
{CMD_INVALID, NULL}
};
/* Interface functions -------------------------------------------------------*/
void _hf_contact_recv(int slot, char *pkt)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
csg_contact_t *pnet = (csg_contact_t *)(pkt + sizeof(csg_pkt_head_t));
csg_add_dau_t snd = {0} ;
dau_info_t *pinfo = &daus[slot].info;
memset(pinfo, 0, sizeof(dau_info_t));
pinfo->type_m = pnet->type_m;
pinfo->type_s = pnet->type_s;
pinfo->dev_id = pnet->dev_id;
strncpy(pinfo->hostname, pnet->hostname, sizeof(pinfo->hostname) - 1);
pinfo->factory_date = pnet->factory_date;
pinfo->deployment_date = pnet->deployment_date;
strncpy((char *)pinfo->app_version, (char *)pnet->app_version, sizeof(pinfo->app_version) -1);
strncpy((char *)pinfo->app_compile_time, (char *)pnet->app_compile_time, sizeof(pinfo->app_compile_time) -1);
strncpy((char *)pinfo->hardware_version, (char *)pnet->hardware_version, sizeof(pinfo->hardware_version) -1);
strncpy((char *)pinfo->FPGA_version, (char *)pnet->FPGA_version, sizeof(pinfo->FPGA_version) -1);
pinfo->ip = pnet->ip;
pinfo->mask = pnet->mask;
pinfo->gw = pnet->gw;
memcpy(pinfo->mac, pnet->mac, sizeof(pinfo->mac));
pinfo->server_port = pnet->server_port;
pinfo->server_ipv4 = pnet->server_ipv4;
memcpy(pinfo->port, pnet->port, sizeof(pinfo->port));
memcpy(pinfo->port_type, pnet->port_type, sizeof(pinfo->port_type));
snd.dev_id = pnet->dev_id;
snd.slot = slot;
snd.status = 1;
memcpy(snd.port, pnet->port, sizeof(pnet->port));
memcpy(snd.port_type, pnet->port_type, sizeof(pnet->port_type));
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&snd, sizeof(csg_add_dau_t));
head->slot = slot;
head->sdev_id = head->dev_id;
printf("recv contact dev_id = 0x%x slot = %d\n", snd.dev_id, snd.slot);
_csg_send_data(CSG_REPLY, CSG_C_ADD_DAU, pkt, sizeof(csg_add_dau_t));
}
void _hf_heartbeat_recv(int slot, char *pkt)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
printf("_hf_heartbeat_recv slot = %d\n", slot);
head->cmd_type = CSG_REQUEST;
head->cmd = CSG_C_HEARTBEAT;
head->len = CSG_HEAD_LEN + 4;
uint32_t *timestamp = (uint32_t *)(pkt + CSG_HEAD_LEN);
*timestamp = time(NULL);
_dau_response(slot, pkt, head->len);
}
void _hf_real_image_recv(int slot, char *pkt)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
head->slot = slot;
head->sdev_id = head->dev_id;
_csg_send_data(CSG_PRV_REPLY, CSG_PRV_REAL_PRPS, pkt, head->len - sizeof(csg_pkt_head_t));
}
void _hf_trend_recv(int slot, char *pkt)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
head->slot = slot;
head->sdev_id = head->dev_id;
_csg_send_data(CSG_PRV_REPLY, CSG_PRV_TREND, pkt, head->len - sizeof(csg_pkt_head_t));
}
void _hf_event_recv(int slot, char *pkt)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
head->slot = slot;
head->sdev_id = head->dev_id;
_csg_send_data(CSG_PRV_REPLY, CSG_PRV_EVENT, pkt, head->len - sizeof(csg_pkt_head_t));
}
int32_t _hf_recv_process(int slot, char *pkt)
{
csg_pkt_head_t *head = (csg_pkt_head_t *)pkt;
command_handler handle = NULL;
/* 报文头和 CRC 校验. */
LD_E_RETURN(DBG_M_PD_CSG_ERR, _csg_pkt_check(pkt));
if (CSG_REPLY == head->cmd_type)
{
handle = _csg_get_table_handle(hf_request_command_table, head->cmd);
if (handle)
{
handle(slot, pkt);
}
}
else if (CSG_PRV_REPLY == head->cmd_type)
{
handle = _csg_get_table_handle(hf_prv_request_command_table, head->cmd);
if (handle)
{
handle(slot, pkt);
}
}
return E_NONE;
}
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,632 @@
/*****************************************************************************
* 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 <ifaddrs.h>
#include "main.h"
#include "pd_csg.h"
#include "pd_main.h"
#include "pd_dau.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define PD_BOARD_PORT 12345
/* 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"
};
/* DAU 端口降噪类型分类. */
static const char *pd_noise_type_str[PD_DENOISE_TYPE_COUNT] =
{
"none",
"auto",
"manual",
"variance"
};
/* Private function prototypes -----------------------------------------------*/
extern int32_t _pd_port_str_to_unit_port(const char *port_str, uint8_t *unit, uint8_t *port);
/* Internal functions --------------------------------------------------------*/
/* 4G 模块是否使能. */
CMD(pd_4G_enable,
pd_4G_enable_cmd,
"wireless (enable|disable)",
"Wireless\n"
"Enable\n"
"Disable\n")
{
uint8_t enable = FALSE;
if (0 == strncmp(argv[0], "e", 1))
{
enable = TRUE;
}
else
{
enable = FALSE;
}
pd_config.config.is_4G_enable = enable;
return CMD_SUCCESS;
}
/* 4G 模块 APN. */
CMD(pd_4G_APN,
pd_4G_APN_cmd,
"wireless apn WORD",
"Wireless\n"
"APN\n"
"Enable\n"
"Disable\n")
{
snprintf(pd_config.config.APN, PD_4G_APN_LEN, "%s", argv[0]);
return CMD_SUCCESS;
}
/* 通信协议选择. */
CMD(pd_protocol_type,
pd_protocol_type_cmd,
"protocol-type (land|csg)",
"Protocol type\n"
"Land\n"
"Csg\n")
{
uint8_t type = 0;
if (0 == strncmp(argv[0], "land", 4))
{
type = PD_PROTOCOL_LAND;
}
else if (0 == strncmp(argv[0], "csg", 3))
{
type = PD_PROTOCOL_CSG;
}
else
{
type = PD_PROTOCOL_LAND;
}
pd_config.config.protocol_type = type;
return CMD_SUCCESS;
}
/* 显示 DAU 状态. */
CMD(show_pd,
show_pd_cmd,
"show pd",
"Show\n"
"Partial discharge\n")
{
pd_show();
return CMD_SUCCESS;
}
/* 配置保存函数. */
int _pd_config_save(vty_t* vty)
{
int16_t i = 0;
switch (pd_config.config.protocol_type)
{
case PD_PROTOCOL_LAND:
vty_out(vty, "protocol-type land%s", VTY_NEWLINE);
i++;
break;
case PD_PROTOCOL_CSG:
vty_out(vty, "protocol-type csg%s", VTY_NEWLINE);
i++;
break;
default:
break;
}
vty_out(vty, "evnet-amount %d%s", pd_config.config.event_storage, VTY_NEWLINE);
i++;
vty_out(vty, "trend-interval %d%s", pd_config.config.trend_period / 60, VTY_NEWLINE);
i++;
vty_out(vty, "trend-amount %d%s", pd_config.config.trend_storage, 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_INSIDE:
vty_out(vty, "sync-mode inside%s", VTY_NEWLINE);
i++;
break;
case PD_SYNC_OUTSIDE:
vty_out(vty, "sync-mode outside%s", VTY_NEWLINE);
i++;
break;
default:
break;
}
vty_out(vty, "sync-inside %d%s", pd_config.config.power_frequency, VTY_NEWLINE);
i++;
switch(pd_config.config.pps_mode)
{
case PD_PPS_AUTO:
vty_out(vty, "pps-mode auto%s", VTY_NEWLINE);
i++;
break;
case PD_PPS_MASTER:
vty_out(vty, "pps-mode master%s", VTY_NEWLINE);
i++;
break;
case PD_PPS_SLAVE:
vty_out(vty, "pps-mode slave%s", VTY_NEWLINE);
i++;
break;
default:
break;
}
vty_out(vty, "wireless %s%s", pd_config.config.is_4G_enable ? "enable" : "disable", VTY_NEWLINE);
i++;
vty_out(vty, "wireless apn %s%s", pd_config.config.APN, VTY_NEWLINE);
i++;
return i;
}
/* 将端口字符串, 转换成 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;
}
/* 广播接收程序 */
void *_pd_broadcast_handle(void *arg)
{
struct sockaddr_in broad_addr;
struct sockaddr_in peer_addr;
socklen_t addr_len = 0;
char packet[1024];
int fd = 0;
int len = 0;
int rv = -1;
/* 创建报文套接字 */
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (-1 == fd)
{
log_err(LOG_PD, "Fail to open broadcast socket.");
return NULL;
}
bzero(&broad_addr, sizeof(broad_addr));
broad_addr.sin_family = AF_INET;
broad_addr.sin_port = htons(PD_BOARD_PORT);
broad_addr.sin_addr.s_addr = INADDR_ANY;
rv = bind(fd, (struct sockaddr *)&broad_addr, sizeof(broad_addr));
if (-1 == rv)
{
log_err(LOG_PD, "Fail to bind broad socket.");
return NULL;
}
while (1)
{
/* 接收广播 */
len = recvfrom(fd, packet, sizeof(packet), 0, (struct sockaddr *)&peer_addr, &addr_len);
if (-1 == len)
{
continue;
}
packet[len] = '\0';
if (strncmp(packet, "hello", 5) == 0)
{
len = snprintf(packet, 1024, "world,GIS7.0_V%s,", softversion_get());
snprintf(packet + len, 1024 - len, "%s", device_info.hostname);
sendto(fd, packet, strlen(packet) + 1, 0, (struct sockaddr *)&peer_addr, sizeof(peer_addr));
}
}
/* 关闭套接字 */
close(fd);
return NULL;
}
int32_t _pd_broadcast_init(void)
{
struct sched_param param;
pthread_attr_t attr;
pthread_t pid;
int32_t rv = E_NONE;
/* 初始化广播报文处理线程. */
/* 配置线程RR调度, 优先级25 */
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, _pd_broadcast_handle, NULL);
if (rv != 0)
{
log_err(LOG_PD, "PD can't create broadcast pthread %d!", rv);
return E_SYS_CALL;
}
else
{
thread_m_add("PD_BROADCAST", pid);
}
pthread_attr_destroy(&attr);
return E_NONE;
}
/* 4G 模块服务程序 */
void *_pd_4G_handle(void *arg)
{
struct ifaddrs *ifa = NULL, *ifList = NULL;
int8_t err_cnt = 0;
bool is_found = FALSE;
char cmd[256];
/* 上电拨号 */
sleep(30);
snprintf(cmd, 256, "/etc/ppp/peers/quectel-pppd.sh /dev/ttyUSB3 %s", pd_config.config.APN);
system(cmd);
while(1)
{
sleep(40);
/* 查询 4G 是否连接 */
is_found = FALSE;
if (getifaddrs(&ifList) < 0)
{
//err_cnt++;
continue;
}
for(ifa = ifList; ifa != NULL; ifa = ifa->ifa_next)
{
if (ifa->ifa_addr == NULL)
{
continue;
}
if (ifa->ifa_addr->sa_family != AF_INET)
{
continue;
}
if (strncmp(ifa->ifa_name, "ppp0", 4))
{
continue;
}
is_found = TRUE;
break;
}
freeifaddrs(ifList);
/* 没有连接, 重新拨号 */
if (is_found)
{
pd_state.is_4G_connect = TRUE;
err_cnt = 0;
continue;
}
else
{
pd_state.is_4G_connect = FALSE;
DBG(DBG_M_PD, "4G connect start...\r\n");
err_cnt++;
if(err_cnt > 64)
{
/* 每 64 分钟没有拨号成功则重启 */
reboot_system(LOG_PD, REBOOT_4G_ERROR);
continue;
}
/* 每 8 分钟拨号一次 */
if (0 == (err_cnt & 0x7))
{
/* 重新拨号 */
log_warn(LOG_PD, "Wireless dialing restart!");
system("/etc/ppp/peers/quectel-ppp-kill");
sleep(20);
snprintf(cmd, 256, "/etc/ppp/peers/quectel-pppd.sh /dev/ttyUSB3 %s", pd_config.config.APN);
system(cmd);
}
}
}
return NULL;
}
int32_t _pd_main_init(void)
{
uint8_t i = 0;
uint8_t j = 0;
int32_t rv = 0;
/* 初始化基本参数. */
for(i = 0; i < PD_DAU_SUM; i++)
{
for(j = 0; j < PD_DAU_PORT_SUM; j++)
{
pd_config.config_port[i][j].port_type = PD_PORT_TYPE_HF;
pd_config.config_port[i][j].sensor_type = PD_SEN_TYPE_SIG;
pd_config.config_port[i][j].is_auto_noise = TRUE;
pd_config.config_port[i][j].filter = CSG_FILTER_TYPE_FR;
pd_config.config_real[i][j].filter_cfg = CSG_FILTER_TYPE_FR;
pd_config.config_real[i][j].denoise_type = PD_DENOISE_TYPE_AOTU;
pd_config.config_real[i][j].denoise_manual = 1000;
pd_config.config_port[i][j].denoise_type = PD_DENOISE_TYPE_AOTU;
pd_config.config_port[i][j].denoise_variance = 100;
pd_config.config_port[i][j].burst_time = 5;
pd_config.config_port[i][j].burst_thr = 800;
pd_config.config_port[i][j].event_counter_h = 8000;
pd_config.config_port[i][j].event_sec_h = 800;
pd_config.config_port[i][j].event_counter_thr_h = 8000;
pd_config.config_port[i][j].event_thr_h = 1000;
pd_config.config_port[i][j].event_counter_l = 8000;
pd_config.config_port[i][j].event_sec_l = 800;
pd_config.config_port[i][j].event_counter_thr_l = 8000;
pd_config.config_port[i][j].event_thr_l = 1000;
pd_config.config_port[i][j].denoise_manual = 100;
pd_config.config_port[i][j].denoise_auto = 100;
pd_config.config_port[i][j].auto_noise_cnt = 1600;
}
}
pd_config.config.protocol_type = PD_PROTOCOL_LAND;
pd_config.config.power_frequency = 500;
pd_config.config.sync_mode = PD_SYNC_PT;
pd_config.config.is_4G_enable = FALSE;
snprintf(pd_config.config.APN, PD_4G_APN_LEN, "3gnet");
pd_config.config.trend_period = 900;
pd_config.config.trend_storage = 10;
pd_config.config.event_storage = 500;
pd_config.config.heartbeat_period = 5;
/* 注册配置保存函数 */
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;
}
/* 注册端口节点. */
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_4G_enable_cmd);
cmd_install_element(CONFIG_NODE, &pd_4G_APN_cmd);
cmd_install_element(CONFIG_NODE, &pd_protocol_type_cmd);
cmd_install_element(COMMON_NODE, &show_pd_cmd);
return E_NONE;
}
int32_t _pd_main_init_after(void)
{
struct sockaddr_in addr;
thread_param_t param = {0};
uint8_t i = 0;
uint8_t j = 0;
char cmd[256];
/* 初始化基本参数 */
if (pd_config.config.is_4G_enable)
{
param.arg = NULL;
param.priority = 20;
param.thread_name = "4G";
param.log_module = LOG_PD;
create_thread(_pd_4G_handle, &param);
}
else
{
addr.sin_addr.s_addr = device_info.gw;
snprintf(cmd, 256, "route add default gw %s", inet_ntoa(addr.sin_addr));
printf("%s\r\n", cmd);
system(cmd);
}
return E_NONE;
}
/* Interface functions -------------------------------------------------------*/
/* description: 局放程序入口函数.
param:
return: */
int32_t pd_main(void)
{
int32_t rv = 0;
rv |= _pd_main_init();
rv |= dau_handle_init();
rv |= csg_handle_init();
//rv |= debug_handle_init();
return E_NONE;
}
int32_t pd_main_after(void)
{
int32_t rv = E_NONE;
rv |= _pd_main_init_after();
rv |= dau_handle_init_after();
rv |= csg_handle_init_after();
//rv |= debug_handle_init_after();
rv |= _pd_broadcast_init();
return rv;
}
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_show(void)
{
printh("Connect: %s\r\n", csg.is_connect ? "yes" : "no");
printh("Synchronization: %s\r\n", pd_state.sync ? "valid" : "invalid");
printh("PT: %s\r\n", (pd_state.state & 0x2) ? "valid" : "invalid");
printh("PPS: %s\r\n", (pd_state.state & 0x4) ? "valid" : "invalid");
printh("PPS mode: %s\r\n", (pd_state.state & 0x8) ? "slave" : "master");
}
#else
int32_t PD_main(void)
{
return 0;
}
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

@ -0,0 +1,550 @@
/*****************************************************************************
* file lib/process/pd_upgrade.c
* author WangBo
* version 1.0.0
* date 07-Feb-2023
* brief This file provides all the softwave upgrade related operation functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2024 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/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <fcntl.h>
#include <string.h>
#include <typedef.h>
/* 第三方头文件 */
/* 私有头文件 */
#include "main.h"
#include "pd_upgrade.h"
#include "pd_dau.h"
#include "pd_csg.h"
#include "pd_dbg.h"
/* Private define ------------------------------------------------------------*/
#define PD_UPG_READ_SIZE (1024*1024)
#define PD_UPG_HARDWARE_VERSON "GIS6.0"
/* Private macro -------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
typedef void (*pd_upg_sighandler)(int);
/* Private variables ---------------------------------------------------------*/
static pd_upg_ctrl_t pd_upg_ctrl;
static const char *pd_upg_type_str[PD_UPG_SEL_MAX] =
{
"all",
"cmu",
"dau"
};
/* Private function prototypes -----------------------------------------------*/
/* Internal functions --------------------------------------------------------*/
/* description: 调用 system 下发 shell 命令
param: cmd_line --
return: */
int _pd_upg_system(const char *cmd_line)
{
int ret = 0;
pd_upg_sighandler old_handler;
old_handler = signal(SIGCHLD, SIG_DFL);
ret = system(cmd_line);
signal(SIGCHLD, old_handler);
return ret;
}
/* description: 提取升级数据写成文件
param: addr --
len --
name --
return: E_NONE - , E_XXXX - */
int32_t _pd_upg_write_file(int32_t addr, int32_t size, const char *name)
{
int fp_wr = -1;
int fp_rd = -1;
char *buf = NULL;
int32_t len = 0;
int32_t len_wr = 0;
int32_t len_rd = 0;
int32_t rv = E_NONE;
/* 打开文件 */
fp_wr = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0777);
if (fp_wr <= 0)
{
DBG(DBG_M_PD_UPGRADE, "Open %s failed!\n", name);
return E_SYS_CALL;
}
fp_rd = open(PD_UPG_SOFTWARE, O_RDONLY);
if (fp_rd <= 0)
{
close(fp_wr);
DBG(DBG_M_PD_UPGRADE, "Open " PD_UPG_SOFTWARE " failed!\n");
return E_SYS_CALL;
}
/* 偏移到读取位置 */
if (lseek(fp_rd, addr, SEEK_SET) < 0)
{
close(fp_wr);
close(fp_rd);
rv = E_SYS_CALL;
DBG(DBG_M_PD_UPGRADE, "Fseek %d failed!\n", addr);
return E_SYS_CALL;
}
/* 申请 buf */
buf = (char*)XMALLOC_Q(MTYPE_UPGRADE, PD_UPG_READ_SIZE);
if (!buf)
{
close(fp_wr);
close(fp_rd);
DBG(DBG_M_PD_UPGRADE, "Malloc failed!\n");
return E_MEM;
}
while (len < size)
{
len_rd = read(fp_rd, buf, PD_UPG_READ_SIZE);
if (len_rd > 0)
{
len_wr = write(fp_wr, buf, len_rd);
if(len_wr != len_rd)
{
DBG(DBG_M_PD_UPGRADE, "Write %s error!\n", name);
rv = E_SYS_CALL;
break;
}
}
else if(0 == len_rd)
{
break;
}
else
{
DBG(DBG_M_PD_UPGRADE, "Read " PD_UPG_SOFTWARE " error!\n");
rv = E_SYS_CALL;
break;
}
len += len_rd;
}
close(fp_rd);
close(fp_wr);
XFREE(MTYPE_UPGRADE, buf);
_pd_upg_system("sync");
sleep(1);
return rv;
}
/* description: 升级 CMU
param:
return: E_NONE - , E_XXXX - */
int32_t _pd_upg_upgrade_dau(void)
{
uint8_t i = 0;
int32_t offset = 0;
int32_t lenth = 0;
int32_t rv = E_ERROR;
/* 查找升级文件 */
for (i = 0; i < PD_UPG_AREA_MAX; i++)
{
if (0 == pd_upg_ctrl.head.arr_info[i].len)
{
continue;
}
if (PD_UPG_TYPE_DAU == pd_upg_ctrl.head.arr_info[i].type)
{
offset = pd_upg_ctrl.head.arr_info[i].start;
lenth = pd_upg_ctrl.head.arr_info[i].len;
break;
}
}
/* 没有找到 */
if (0 == lenth)
{
snprintf(pd_upg_ctrl.msg, 128, "DAU file is not found.");
DBG(DBG_M_PD_UPGRADE, "DAU file is not found.\n");
return E_NOT_FOUND;
}
/* 读取并写升级文件 */
rv = _pd_upg_write_file(offset, lenth, DEBUG_DAU_FILE);
if (rv != E_NONE)
{
snprintf(pd_upg_ctrl.msg, 128, "DAU write file error.");
return E_NOT_FOUND;
}
return E_NONE;
}
/* description: 升级 CMU
param:
return: E_NONE - , E_XXXX - */
int32_t _pd_upg_upgrade_cmu(void)
{
char cmd[128] = {0};
uint8_t i = 0;
int32_t offset = 0;
int32_t lenth = 0;
int32_t rv = E_ERROR;
/* 查找升级文件 */
for (i = 0; i < PD_UPG_AREA_MAX; i++)
{
if (0 == pd_upg_ctrl.head.arr_info[i].len)
{
continue;
}
if (PD_UPG_TYPE_CMU == pd_upg_ctrl.head.arr_info[i].type)
{
offset = pd_upg_ctrl.head.arr_info[i].start;
lenth = pd_upg_ctrl.head.arr_info[i].len;
break;
}
}
/* 没有找到 */
if (0 == lenth)
{
snprintf(pd_upg_ctrl.msg, 128, "CMU file is not found.");
DBG(DBG_M_PD_UPGRADE, "CMU file is not found.\n");
return E_NOT_FOUND;
}
/* 先备份原始文件 */
snprintf(cmd, 128, "cp -rf %s bak", PD_UPG_CMU_FILE);
_pd_upg_system(cmd);
_pd_upg_system("sync");
sleep(1);
/* 读取并写升级文件 */
rv = _pd_upg_write_file(offset, lenth, PD_UPG_CMU_FILE_BAK);
if (rv != E_NONE)
{
snprintf(pd_upg_ctrl.msg, 128, "CMU write file error.");
return E_NOT_FOUND;
}
if (rename(PD_UPG_CMU_FILE_BAK, PD_UPG_CMU_FILE) != 0)
{
snprintf(pd_upg_ctrl.msg, 128, "CMU file rename error.");
DBG(DBG_M_PD_UPGRADE, "Can't rename file %s!\n", PD_UPG_CMU_FILE_BAK);
return E_SYS_CALL;
}
DBG(DBG_M_PD_UPGRADE, "Upgrade CMU Ok.\n");
return E_NONE;
}
/* description: 升级系统
param:
return: E_NONE - , E_XXXX - */
int32_t _pd_upg_upgrade(void)
{
if (PD_UPG_SEL_ALL == pd_upg_ctrl.upg_type || PD_UPG_SEL_CMU == pd_upg_ctrl.upg_type)
{
LD_E_RETURN(DBG_M_PD_UPGRADE, _pd_upg_upgrade_cmu());
}
if (PD_UPG_SEL_ALL == pd_upg_ctrl.upg_type || PD_UPG_SEL_DAU == pd_upg_ctrl.upg_type)
{
LD_E_RETURN(DBG_M_PD_UPGRADE, _pd_upg_upgrade_dau());
}
return E_NONE;
}
/* description: 检测硬件版本号是否匹配
param:
return: E_NONE - , E_XXXX - */
int32_t _pd_upg_hardware_check(void)
{
if (strncmp(pd_upg_ctrl.head.hard_ver, PD_UPG_HARDWARE_VERSON, strlen(PD_UPG_HARDWARE_VERSON)))
{
DBG(DBG_M_PD_UPGRADE, "Hardware version(%s) not match\n", pd_upg_ctrl.head.hard_ver);
return E_ERROR;
}
return E_NONE;
}
/* description: 验证升级文件, CRC 校验升级文件并对比每段分区确定是否需要升级
param:
return: E_NONE - , E_XXXX - */
int32_t _pd_upg_verify_file(void)
{
int32_t rv = 0;
int fd = 0;
unsigned int crc = 0;
char *buf = NULL;
/*读取升级文件头信息*/
fd = open(PD_UPG_SOFTWARE, O_RDONLY);
if (fd < 0)
{
DBG(DBG_M_PD_UPGRADE, "Open file "PD_UPG_SOFTWARE" failed!\n");
return E_SYS_CALL;
}
rv = read(fd, &pd_upg_ctrl.head, sizeof(pd_upg_head_t));
if (rv != sizeof(pd_upg_head_t) || pd_upg_ctrl.head.magic != PD_UPG_MAGICNUM)
{
close(fd);
DBG(DBG_M_PD_UPGRADE, "Read len %d(%d), magic %x(%x)\n",
rv, sizeof(pd_upg_head_t), pd_upg_ctrl.head.magic, PD_UPG_MAGICNUM);
return E_NOT_IDENTIFY;
}
/*crc校验*/
buf = (char*)XMALLOC_Q(MTYPE_UPGRADE, PD_UPG_BLOCK_SIZE);
if (!buf)
{
close(fd);
DBG(DBG_M_PD_UPGRADE, "Malloc error!\n");
return E_MEM;
}
while (1)
{
rv = read(fd, buf, PD_UPG_BLOCK_SIZE);
if (rv < 0)
{
DBG(DBG_M_PD_UPGRADE, "Read failed!\n");
rv = E_SYS_CALL;
break;
}
else if(rv == 0)
{
rv = E_NONE;
break;
}
crc = crc32(crc, buf, (unsigned long)rv);
}
if (E_NONE == rv)
{
if (crc != pd_upg_ctrl.head.crc)
{
DBG(DBG_M_PD_UPGRADE, "CRC error!\n");
rv = E_ERROR;;
}
}
/* 释放资源 */
XFREE(MTYPE_UPGRADE, buf);
close(fd);
DBG(DBG_M_PD_UPGRADE, "Verfiy upgrade success.\n");
return rv;
}
/* description: 检测是否存在满足升级的条件
param:
return: E_NONE - , E_XXXX - */
int32_t _pd_upg_file_check(void)
{
int32_t rv = 0;
/* 读取升级文件并校验 */
rv = _pd_upg_verify_file();
if (rv != E_NONE)
{
snprintf(pd_upg_ctrl.msg, 128, "App CRC verify error.");
return rv;
}
/* 硬件版本号检查 */
rv = _pd_upg_hardware_check();
if (rv != E_NONE)
{
snprintf(pd_upg_ctrl.msg, 128, "Hardware is not match.");
return rv;
}
return rv;
}
/* description: 软件升级处理线程
param: parm --
return: */
void *_pd_upg_handle(void *parm)
{
char cmd[128] = {0};
int32_t rv = E_ERROR;
while(1)
{
/* 文件检查 */
rv = _pd_upg_file_check();
if (rv != E_NONE)
{
break;
}
/* 升级系统 */
rv = _pd_upg_upgrade();
if (rv != E_NONE)
{
break;
}
break;
}
/* 保存升级原始文件 */
snprintf(cmd, 128, "mv " PD_UPG_SOFTWARE " bak");
_pd_upg_system(cmd);
_pd_upg_system("sync");
sleep(1);
/* 处理升级结果 */
if (E_NONE == rv)
{
DBG(DBG_M_PD_UPGRADE, "Upgrade ok.\n");
if (pd_upg_ctrl.upgrade_result)
{
pd_upg_ctrl.upgrade_result(1, "App and dua update successful.");
}
/* 升级成功, 主动重启 */
log_notice(LOG_UPGRADE, "Upgrade %s ok.", pd_upg_type_str[pd_upg_ctrl.upg_type]);
reboot_system(LOG_UPGRADE, REBOOT_UPGRADE_ALL);
}
else
{
DBG(DBG_M_PD_UPGRADE, "Upgrade failed.\n");
if (pd_upg_ctrl.upgrade_result)
{
pd_upg_ctrl.upgrade_result(0, pd_upg_ctrl.msg);
}
}
pd_upg_ctrl.is_start = FALSE;
pthread_exit(NULL);
return NULL;
}
/* description: 启动升级线程
param:
return: E_NONE - , E_XXXX - */
int32_t _pd_upg_start(void)
{
struct sched_param param;
pthread_attr_t attr;
pthread_t pid;
int32_t rv = 0;
/* 创建线程 配置线程 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);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
rv = pthread_create(&pid, &attr, _pd_upg_handle, NULL);
if (rv != 0)
{
log_err(LOG_UPGRADE, "PD can't create pthread %d!", rv);
return E_SYS_CALL;
}
else
{
thread_m_add("UPGRADE", pid);
}
pthread_attr_destroy(&attr);
return E_NONE;
}
/* Interface functions -------------------------------------------------------*/
/* description: 软件升级开始
param: from -- PD_UPG_FROM_xxx
type -- PD_UPG_SEL_xxx
return: E_NONE - , E_XXXX - */
int32_t pd_upg_start(uint8_t from, uint8_t type)
{
int32_t rv = E_NONE;
if (pd_upg_ctrl.is_start == FALSE)
{
DBG(DBG_M_PD_UPGRADE, "Start upgrade system.\n");
pd_upg_ctrl.is_start = TRUE;
pd_upg_ctrl.upg_from = from;
pd_upg_ctrl.upg_type = type;
if (PD_UPG_FROM_CSG == from)
{
pd_upg_ctrl.upgrade_result = csg_upgrade_result_send;
}
else if(PD_UPG_FROM_DBG == from)
{
//pd_upg_ctrl.upgrade_result = debug_upgrade_result_send;
}
else
{
pd_upg_ctrl.upgrade_result = NULL;
}
/* 初始化模块. */
LD_E_RETURN(DBG_M_PD_UPGRADE, _pd_upg_start());
}
else
{
DBG(DBG_M_PD_UPGRADE, "Upgrade is busy!\n");
rv = E_TIMEOUT;
}
return rv;
}
#endif
/************************ (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,535 @@
/******************************************************************************
* 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_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_sys_t *log_sys;
static char *log_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_NET, "NET"},
{LOG_STORAGE, "STORAGE"},
{LOG_DEBUG, "DEBUG"},
{LOG_UPGRADE, "UPGRADE"},
{-1, NULL}
};
/* Private function prototypes -----------------------------------------------*/
/* Internal functions --------------------------------------------------------*/
/* 删除多余的 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输出底层函数. */
void _log_out_db(LOG_MODULE_E module, LOG_LVL_E priority, const char *va_str)
{
static uint16_t cnt = 0;
log_sys_t *log = log_sys;
char time_str[TIME_STR_LEN] = {0};
char *zErrMsg = NULL;
time_string(log->timestamp_precision, time_str, sizeof(time_str));
LOG_DB_LOCK;
snprintf(log_str, LOG_CMD_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*/
cnt++;
if (cnt >= 500)
{
clock_t begin,end;
begin = clock();
_log_clean();
end = clock();
printh("Log clean runtimer : %lf\r\n",(double)(end-begin)/CLOCKS_PER_SEC);
cnt = 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_CMD_LEN);
switch (data->type)
{
case LOG_SHOW_CNT: //打印指定数量的日志
snprintf(log_str, LOG_CMD_LEN, "SELECT * FROM better_log ORDER BY id DESC LIMIT %d;", data->param);
break;
case LOG_SHOW_LVL: //打印指定等级的日志
snprintf(log_str, LOG_CMD_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_CMD_LEN, "SELECT * FROM better_log WHERE LOG GLOB \'*%s*\' ORDER BY id DESC;",
data->log_show_str);
}
else
{
snprintf(log_str, LOG_CMD_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_CMD_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_sys->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)
{
_log_out_t *log_data = NULL;
log_data = XMALLOC_Q(MTYPE_LOG, sizeof(_log_out_t));
if (!log_data)
{
return;
}
log_data->module = module;
log_data->lvl = priority;
snprintf(log_data->log_out_str, LOG_STR_LEN, va_str);
_log_msg_send(LOG_OUT, log_data);
}
/* 读取log fifo数据循环线程 */
void *_log_handle(void *arg)
{
_log_msg_t *recv_msg = NULL;
while(1)
{
if (fifo_read(log_sys->log_fifo_id, (void **)&recv_msg) != 0)
{
DBG(DBG_M_FIFO, "ERROR at fifo %d read!\r\n", log_sys->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);
}
XFREE(MTYPE_LOG, recv_msg->data);
fifo_push(log_sys->log_fifo_id);
}
return NULL;
}
/* Interface functions -------------------------------------------------------*/
/* log打印输出函数. */
#define BLOG_FUNC(FUNCNAME,PRIORITY) \
void FUNCNAME(LOG_MODULE_E module, const char *format, ...) \
{ \
char str[LOG_STR_LEN] = {0}; \
log_sys_t *log = log_sys; \
if (NULL == log) return; \
va_list args; \
va_start(args, format); \
vsnprintf(str, LOG_STR_LEN, format, args); \
va_end(args); \
if ((1 << PRIORITY) & log->enable_lvl[LOG_MODE_STDOUT]) \
_log_out_std(module, PRIORITY, str); \
if (((1 << PRIORITY) & log->enable_lvl[LOG_MODE_FILE]) && log->db){ \
if (log_sys->log_fifo_id) \
_log_fifo_out(module, PRIORITY, str); \
else \
_log_out_db(module, PRIORITY, str);} \
}
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, ...)
{
char str[LOG_STR_LEN] = {0}; \
log_sys_t *log = log_sys;
if (NULL == log) return;
va_list args;
va_start(args, format);
vsnprintf(str, LOG_STR_LEN, format, args);
va_end (args);
/* 串口log. */
if ((1 << priority) & log->enable_lvl[LOG_MODE_STDOUT])
_log_out_std(module, priority, str);
/* 判断是否是文件输出 */
if (((1 << priority) & log->enable_lvl[LOG_MODE_FILE]) && log->db)
_log_out_db(module, priority, str);
}
/* 打印日志函数 */
void log_show(int32_t show_cnt, LOG_LVL_E priority, const char *key_word)
{
_log_show_t *log_data = NULL;
log_data = XMALLOC_Q(MTYPE_LOG, sizeof(_log_show_t));
if (!log_data)
{
return;
}
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;
snprintf(log_data->log_show_str, LOG_STR_LEN, key_word);
}
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_CMD_LEN);
log_sys = XMALLOC(MTYPE_LOG, sizeof(log_sys_t));
if (NULL == log_sys)
{
return E_MEM;
}
log = log_sys;
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;
/* 清除多余的日志 */
_log_clean();
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);
}
}
int32_t log_handle_init(void)
{
struct sched_param param;
pthread_attr_t attr;
pthread_t pid;
int rv = 0;
/* 初始化log fifo */
log_sys->log_fifo_id = fifo_create(LOG_DB_FIFO, 32);
if (log_sys->log_fifo_id < 0)
{
log_out(LOG_DEFAULT, LOG_LVL_ERR, "Open fifo " LOG_DB_FIFO " error.");
return E_ERROR;
}
/* 配置线程RR调度优先级25 */
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;
}
/************************ (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

@ -0,0 +1,722 @@
/*****************************************************************************
* file lib/management/cmd_SSH2.c
* author YuLiang
* version 1.0.0
* date 20-Mar-2025
* brief This file provides all the SSH2 cmd related operation functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2025 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 <ctype.h>
#include <libssh/libssh.h>
#include <libssh/server.h>
#include <libssh/callbacks.h>
/* 用户代码头文件. */
#include "main.h"
#include "vty.h"
#include "cmd.h"
#include "mtimer.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define VTYCMD_PORT "2222"
#define VTYCMD_RSA_PATH "/home/root/ssh/ssh_host_rsa_key"
#define VTYCMD_HOSTKEY_PATH "/home/root/ssh/ssh_host_ed25519_key"
#define VTYCMD_BUF_OUT_LEN 32768
typedef struct _vtycmd_ctrl
{
vty_t *vtycmd;
ssh_bind sshbind;
ssh_session session;
ssh_channel channel;
struct ssh_server_callbacks_struct server_cb;
struct ssh_channel_callbacks_struct channel_cb;
uint8_t is_connect;
uint8_t is_recv;
uint16_t cmd_idx;
char cmd[VTY_BUFSIZ];
uint16_t out_buf_start;
uint16_t out_buf_end;
char out_buf[VTYCMD_BUF_OUT_LEN];
} vtycmd_ctrl_t;
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* cmd vty结构体. */
static vtycmd_ctrl_t vtycmd_ctrl;
/* Private function prototypes -----------------------------------------------*/
/* 在终端上显示当前配置信息. */
CMD(show_sshcmd,
show_sshcmd_cmd,
"show sshcmd",
SHOW_STR
"SSHCMD\n")
{
vty_out(vty, "Connect: %s\r\n\n", vtycmd_ctrl.is_connect ? "yes" : "no");
return CMD_SUCCESS;
}
#if 0
/* Insert a word into vty interface with overwrite mode. */
void _vtycmd_insert_word(char *str)
{
int len = strlen(str);
ssh_channel_write(vtycmd_ctrl.channel, str, len);
strcpy(&vtycmd_ctrl.cmd[vtycmd_ctrl.cmd_idx], str);
vtycmd_ctrl.cmd_idx += len;
vtycmd_ctrl.cmd[vtycmd_ctrl.cmd_idx] = 0;
}
/* commandLine '?'响应函数. */
int _vtycmd_question(void)
{
array_t *cmd_line = NULL;
cmd_line = cmd_strs_create(vtycmd_ctrl.cmd);
if (NULL == cmd_line)
{
cmd_line = array_init(1, MTYPE_CLI);
array_append(cmd_line, '\0', MTYPE_CLI);
}
else
if (vtycmd_ctrl.cmd_idx && isspace((int)vtycmd_ctrl.cmd[vtycmd_ctrl.cmd_idx - 1]))
array_append(cmd_line, '\0', MTYPE_CLI);
vty_question(vtycmd_ctrl.vtycmd, cmd_line);
cmd_strs_free(cmd_line);
vty_prompt(vtycmd_ctrl.vtycmd);
vty_out(vtycmd_ctrl.vtycmd, "%s", vtycmd_ctrl.cmd);
return 0;
}
/* 用于自动补齐命令行关键字. */
void _vtycmd_completion_append(array_t *cmd_line, char *word, int32_t status)
{
uint32_t index = array_active(cmd_line) - 1;
uint32_t len = 0;
uint32_t i = 0;
if (NULL == array_get(cmd_line, index))
{
_vtycmd_insert_word(word);
}
else
{
len = strlen(array_get(cmd_line, index));
for(i = 0; i < len; i++)
{
if (vtycmd_ctrl.cmd_idx)
{
vtycmd_ctrl.cmd_idx--;
vty_out(vtycmd_ctrl.vtycmd, "%c%c%c", 8, ' ', 8);
}
}
_vtycmd_insert_word(word);
}
if (CMD_COMPLETE_FULL_MATCH == status)
_vtycmd_insert_word(" ");
}
/* commandLine 'TAB'响应函数. */
int _vtycmd_completion(void)
{
array_t *cmd_line = NULL;
char **match_strs = NULL;
int32_t complete_status = CMD_ERR_NO_MATCH;
cmd_line = cmd_strs_create(vtycmd_ctrl.cmd);
if (NULL == cmd_line)
{
cmd_line = array_init(1, MTYPE_CLI);
array_append(cmd_line, '\0', MTYPE_CLI);
}
else
if (vtycmd_ctrl.cmd_idx && isspace((int)vtycmd_ctrl.cmd[vtycmd_ctrl.cmd_idx - 1]))
array_append(cmd_line, '\0', MTYPE_CLI);
match_strs = cmd_complete_command(cmd_line, vtycmd_ctrl.vtycmd, &complete_status);
if (NULL == match_strs)
{
cmd_strs_free(cmd_line);
return 0;
}
if (CMD_COMPLETE_MATCH == complete_status ||
CMD_COMPLETE_FULL_MATCH == complete_status)
_vtycmd_completion_append(cmd_line, match_strs[0], complete_status);
else
{
vty_print_word(vtycmd_ctrl.vtycmd, match_strs);
vty_prompt(vtycmd_ctrl.vtycmd);
vty_out(vtycmd_ctrl.vtycmd, "%s", vtycmd_ctrl.cmd);
}
vty_free_match_strs(match_strs);
cmd_strs_free(cmd_line);
return 0;
}
/* Internal functions --------------------------------------------------------*/
/* Print command line history. This function is called from
vty_next_line and vty_previous_line. */
static void _vtycmd_history_print(vty_t *vty)
{
uint16_t i= 0;
for(i = 0; i < vtycmd_ctrl.cmd_idx; i++)
{
vty_out(vtycmd_ctrl.vtycmd, "%c%c%c", 8, ' ', 8);
}
vtycmd_ctrl.cmd_idx = 0;
/* Get previous line from history buffer */
vtycmd_ctrl.cmd_idx = strlen(vty->hist[vty->hp]);
memcpy(vtycmd_ctrl.cmd, vty->hist[vty->hp], vtycmd_ctrl.cmd_idx);
vtycmd_ctrl.cmd[vtycmd_ctrl.cmd_idx] = 0;
/* Redraw current line */
vty_out(vtycmd_ctrl.vtycmd, "%s", vtycmd_ctrl.cmd);
}
/* Show previous command line history. */
static void _vtycmd_previous_line(vty_t *vty)
{
unsigned int try_index = 0;
try_index = vty->hp;
if (try_index == 0)
try_index = VTY_MAXHIST - 1;
else
try_index--;
if (vty->hist[try_index] == NULL)
return;
else
vty->hp = try_index;
_vtycmd_history_print(vty);
}
/* Show next command line history. */
static void _vtycmd_next_line(vty_t *vty)
{
unsigned int try_index = 0;
if (vty->hp == vty->hindex)
return;
/* Try is there history exist or not. */
try_index = vty->hp;
if (try_index == (VTY_MAXHIST - 1))
try_index = 0;
else
try_index++;
/* If there is not history return. */
if (vty->hist[try_index] == NULL)
return;
else
vty->hp = try_index;
_vtycmd_history_print(vty);
}
int _vtycmd_cmd(char *buf, uint32_t len)
{
uint16_t i = 0;
vty_t *vty = vtycmd_ctrl.vtycmd;
for (i = 0; i < len; i++)
{
switch (buf[i])
{
case '\033':
if (i + 2 < len && buf[i + 1] == '[')
{
if (buf[i + 2] == 'A')
{
_vtycmd_previous_line(vty);
}
else if (buf[i + 2] == 'B')
{
_vtycmd_next_line(vty);
}
i += 2;
}
break;
case CONTROL('H'):
case 0x7f:
if (vtycmd_ctrl.cmd_idx)
{
vtycmd_ctrl.cmd_idx--;
vtycmd_ctrl.cmd[vtycmd_ctrl.cmd_idx] = 0;
vty_out(vty, "%c%c%c", 8, ' ', 8);
}
break;
case '\n':
case '\r':
vty_out(vty, "%s", VTY_NEWLINE);
/* 执行命令 */
vtycmd_ctrl.cmd[vtycmd_ctrl.cmd_idx] = 0;
vty->length = vtycmd_ctrl.cmd_idx;
snprintf(vty->buf, VTY_BUFSIZ, "%s", vtycmd_ctrl.cmd);
vty_execute(vty);
vtycmd_ctrl.cmd_idx = 0;
vtycmd_ctrl.cmd[vtycmd_ctrl.cmd_idx] = 0;
break;
case '\t':
_vtycmd_completion();
break;
case '?':
_vtycmd_question();
break;
default:
if (buf[i] > 31 && buf[i] < 127)
{
vtycmd_ctrl.cmd[vtycmd_ctrl.cmd_idx] = buf[i];
vtycmd_ctrl.cmd_idx++;
vtycmd_ctrl.cmd[vtycmd_ctrl.cmd_idx] = 0;
vty_out(vty, "%c", buf[i]);
}
break;
}
}
return E_NONE;
}
/* 客户端通讯相关的回调 */
int _vtycmd_channel_pty_request(ssh_session session, ssh_channel channel,
const char *term, int cols, int rows, int py, int px,
void *userdata)
{
ssh_channel_write(vtycmd_ctrl.channel, "Username: ", 10);
ssh_channel_request_pty_size(channel, term, cols, rows);
return SSH_OK;
}
int _vtycmd_channel_pty_resize(ssh_session session, ssh_channel channel, int cols,
int rows, int py, int px, void *userdata)
{
return ssh_channel_change_pty_size(channel, cols, rows);
}
int _vtycmd_channel_shell_request(ssh_session session, ssh_channel channel,
void *userdata)
{
return SSH_OK;
}
int _vtycmd_channel_exec_request(ssh_session session, ssh_channel channel,
const char *command, void *userdata)
{
return ssh_channel_request_exec(channel, command);
}
int _vtycmd_channel_subsystem_request(ssh_session session, ssh_channel channel,
const char *subsystem, void *userdata)
{
return SSH_OK;
}
int _vtycmd_channel_env_request_function(ssh_session session, ssh_channel channel, const char *env_name,
const char *env_value, void *userdata)
{
return ssh_channel_request_env(channel, env_name, env_value);
}
/* 数据处理 */
int _vtycmd_channel_data_function(ssh_session session, ssh_channel channel, void *data,
uint32_t len, int is_stderr, void *userdata)
{
vtycmd_ctrl.is_recv = TRUE;
_vtycmd_cmd((char*)data, len);
return len;
}
void _vtycmd_channel_close(ssh_session session, ssh_channel channel, void *userdata)
{
vtycmd_ctrl.is_connect = FALSE;
}
/* 服务端认证通道相关回调 */
int _vtycmd_server_auth_pass(ssh_session session, const char *user, const char *password, void *userdata)
{
if (strcmp("root", user) == 0 && strcmp("123456", password) == 0)
{
return SSH_AUTH_SUCCESS;
}
else
{
return SSH_AUTH_DENIED;
}
}
/* 空认证方法 */
int _vtycmd_server_auth_none_callback(ssh_session session, const char *user, void *userdata)
{
return SSH_AUTH_SUCCESS;
}
/* pubkey 认证方法 */
int _vtycmd_server_auth_pubkey(ssh_session session, const char *user, struct ssh_key_struct *pubkey,
char signature_state, void *userdata)
{
return SSH_AUTH_SUCCESS;
}
int _vtycmd_server_request_callback(ssh_session session, const char *service, void *userdata)
{
return SSH_OK;
}
ssh_channel _vtycmd_server_open_channel(ssh_session session, void *userdata)
{
vtycmd_ctrl.channel = ssh_channel_new(session);
ssh_callbacks_init(&vtycmd_ctrl.channel_cb);
ssh_set_channel_callbacks(vtycmd_ctrl.channel, &vtycmd_ctrl.channel_cb);
return vtycmd_ctrl.channel;
}
/* SSH2 命令行主函数 */
void *_vtycmd_handle(void *arg)
{
/* 初始化 libssh */
if (ssh_init() < 0)
{
log_err(LOG_CLI, "ssh_init failed\r\n");
return NULL;
}
/* 初始化结构体 */
vtycmd_ctrl.server_cb.auth_password_function = _vtycmd_server_auth_pass;
vtycmd_ctrl.server_cb.auth_none_function = _vtycmd_server_auth_none_callback;
vtycmd_ctrl.server_cb.auth_pubkey_function = _vtycmd_server_auth_pubkey;
vtycmd_ctrl.server_cb.service_request_function = _vtycmd_server_request_callback;
vtycmd_ctrl.server_cb.channel_open_request_session_function = _vtycmd_server_open_channel;
vtycmd_ctrl.channel_cb.channel_data_function = _vtycmd_channel_data_function;
vtycmd_ctrl.channel_cb.channel_close_function = _vtycmd_channel_close;
vtycmd_ctrl.channel_cb.channel_pty_request_function = _vtycmd_channel_pty_request;
vtycmd_ctrl.channel_cb.channel_shell_request_function = _vtycmd_channel_shell_request;
vtycmd_ctrl.channel_cb.channel_pty_window_change_function = _vtycmd_channel_pty_resize;
vtycmd_ctrl.channel_cb.channel_exec_request_function = _vtycmd_channel_exec_request;
vtycmd_ctrl.channel_cb.channel_env_request_function = _vtycmd_channel_env_request_function;
vtycmd_ctrl.channel_cb.channel_subsystem_request_function = _vtycmd_channel_subsystem_request;
/* 创建 SSH2 接口 */
vtycmd_ctrl.sshbind = ssh_bind_new();
ssh_bind_options_set(vtycmd_ctrl.sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, VTYCMD_PORT);
ssh_bind_options_set(vtycmd_ctrl.sshbind, SSH_BIND_OPTIONS_RSAKEY, VTYCMD_RSA_PATH);
ssh_bind_options_set(vtycmd_ctrl.sshbind, SSH_BIND_OPTIONS_HOSTKEY, VTYCMD_HOSTKEY_PATH);
if (ssh_bind_listen(vtycmd_ctrl.sshbind) < 0)
{
log_err(LOG_CLI, "Error listening to socket: %s", ssh_get_error(vtycmd_ctrl.sshbind));
return NULL;
}
while(1)
{
/* 等待连接 */
ssh_session session = ssh_new();
if (ssh_bind_accept(vtycmd_ctrl.sshbind, session) != SSH_OK)
{
DBG(DBG_M_CLI, "Error accept to socket: %s\n", ssh_get_error(vtycmd_ctrl.sshbind));
continue;
}
/* 只能接收一个连接 */
if (vtycmd_ctrl.is_connect)
{
ssh_disconnect(session);
ssh_free(session);
continue;
}
/* 初始化连接 */
log_notice(LOG_CLI, "SSH2 command is connect.\n");
vtycmd_ctrl.is_connect = TRUE;
ssh_callbacks_init(&vtycmd_ctrl.server_cb);
ssh_set_server_callbacks(session, &vtycmd_ctrl.server_cb);
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD);
if (ssh_handle_key_exchange(session) != SSH_OK)
{
DBG(DBG_M_CLI, "Error performing key exchange: %s\n", ssh_get_error(session));
ssh_disconnect(session);
ssh_free(session);
continue;
}
ssh_set_blocking(session, 0);
ssh_event event = ssh_event_new();
ssh_event_add_session(event, session);
/* 处理连接断开 */
while(1)
{
if (ssh_event_dopoll(event, 3000) == SSH_ERROR
|| !vtycmd_ctrl.is_connect)
{
/* 终端断开处理 */
log_notice(LOG_CLI, "SSH2 command is disconnect.\n");
ssh_channel_close(vtycmd_ctrl.channel);
ssh_channel_free(vtycmd_ctrl.channel);
ssh_disconnect(session);
ssh_event_free(event);
ssh_free(session);
vtycmd_ctrl.is_connect = FALSE;
if (CONFIG_NODE == vtycmd_ctrl.vtycmd->node)
{
vty_config_unlock(vtycmd_ctrl.vtycmd);
}
vtycmd_ctrl.vtycmd->node = USERNAME_NODE;
break;
}
}
}
return NULL;
}
/* 用于判断终端是否超时 */
void* _vtycmd_timer(void *arg)
{
if (!vtycmd_ctrl.is_recv && vtycmd_ctrl.is_connect)
{
vtycmd_ctrl.is_connect = FALSE;
}
vtycmd_ctrl.is_recv = FALSE;
/* 重新加入定时器. */
mtimer_add(_vtycmd_timer, NULL, 120, "VTYCMD_TIMER");
return NULL;
}
/* SSH2 命令行发送数据 */
void *_vtycmd_send_handle(void *arg)
{
char *buf = NULL;
uint16_t end = 0;
while(1)
{
usleep(100000);
if (!vtycmd_ctrl.is_connect)
{
continue;
}
end = vtycmd_ctrl.out_buf_end;
buf = vtycmd_ctrl.out_buf + vtycmd_ctrl.out_buf_start;
if (end == vtycmd_ctrl.out_buf_start)
{
continue;
}
if (end < vtycmd_ctrl.out_buf_start)
{
ssh_channel_write(vtycmd_ctrl.channel, buf, VTYCMD_BUF_OUT_LEN - vtycmd_ctrl.out_buf_start);
vtycmd_ctrl.out_buf_start = 0;
}
else
{
ssh_channel_write(vtycmd_ctrl.channel, buf, end - vtycmd_ctrl.out_buf_start);
vtycmd_ctrl.out_buf_start = end;
}
}
return NULL;
}
#endif
/* Interface functions -------------------------------------------------------*/
/* 初始化 SSH2 命令行 */
void vtycmd_init(void)
{
/* Make vty structure. */
vtycmd_ctrl.vtycmd = vty_create();
vtycmd_ctrl.vtycmd->type = VTY_CMD;
vtycmd_ctrl.vtycmd->node = USERNAME_NODE;
memset(vtycmd_ctrl.vtycmd->hist, 0, sizeof(vtycmd_ctrl.vtycmd->hist));
vtycmd_ctrl.vtycmd->hp = 0;
vtycmd_ctrl.vtycmd->hindex = 0;
cmd_install_element(COMMON_NODE, &show_sshcmd_cmd);
}
/* 启动 SSH2 命令行 */
void vtycmd_cmd_init(void)
{
return ;
#if 0
pthread_t pid;
struct sched_param param;
pthread_attr_t attr;
int32_t rv = 0;
/* 配置线程RR调度, 优先级75 */
pthread_attr_init(&attr);
param.sched_priority = 75;
pthread_attr_setschedpolicy(&attr, SCHED_RR);
pthread_attr_setschedparam(&attr, &param);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
rv = pthread_create(&pid, &attr, _vtycmd_handle, NULL);
if (rv != 0)
{
log_err(LOG_DEFAULT, "vtycmd_cmd_init can't create pthread %d!", rv);
}
else
{
thread_m_add("CMD", pid);
}
pthread_attr_destroy(&attr);
mtimer_add(_vtycmd_timer, NULL, 120, "VTYCMD_TIMER");
/* 配置线程RR调度, 优先级75 */
pthread_attr_init(&attr);
param.sched_priority = 75;
pthread_attr_setschedpolicy(&attr, SCHED_RR);
pthread_attr_setschedparam(&attr, &param);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
rv = pthread_create(&pid, &attr, _vtycmd_send_handle, NULL);
if (rv != 0)
{
log_err(LOG_DEFAULT, "vtycmd_cmd_init can't create pthread %d!", rv);
}
else
{
thread_m_add("CMD_SNED", pid);
}
pthread_attr_destroy(&attr);
#endif
}
/* cmd 是否连接 */
bool vtycmd_connect(void)
{
return vtycmd_ctrl.is_connect;
}
/* 命令行输出 */
void vtycmd_print(const char *format, va_list va)
{
char *buf = vtycmd_ctrl.out_buf + vtycmd_ctrl.out_buf_end;
char buf_temp[VTY_BUFSIZ];
char *buf_temp_p = buf_temp;
uint16_t start = 0;;
int len = 0;
int len_remain = 0;
int len_temp = 0;
if (!vtycmd_ctrl.is_connect)
{
vtycmd_ctrl.out_buf_start = 0;
vtycmd_ctrl.out_buf_end = 0;
return;
}
len = vsnprintf(buf_temp, VTY_BUFSIZ, format, va);
if (len <= 0)
{
return;
}
/* 计算可写入的数据量 */
start = vtycmd_ctrl.out_buf_start;
if (vtycmd_ctrl.out_buf_end >= start)
{
len_remain = VTYCMD_BUF_OUT_LEN - 1 - (vtycmd_ctrl.out_buf_end - start);
}
else
{
len_remain = start - vtycmd_ctrl.out_buf_end - 1;
}
if (len_remain <= 0)
{
return;
}
if (len > len_remain)
{
len = len_remain;
}
/* 超过 out_buf 需要分段存储 */
if (len + vtycmd_ctrl.out_buf_end > VTYCMD_BUF_OUT_LEN)
{
len_temp = VTYCMD_BUF_OUT_LEN - vtycmd_ctrl.out_buf_end;
memcpy(buf, buf_temp_p, len_temp);
vtycmd_ctrl.out_buf_end = 0;
buf = vtycmd_ctrl.out_buf;
buf_temp_p = buf_temp_p + len_temp;
len -= len_temp;
memcpy(buf, buf_temp_p, len);
vtycmd_ctrl.out_buf_end += len;
}
else
{
memcpy(buf, buf_temp_p, len);
len_temp = vtycmd_ctrl.out_buf_end + len;
if (VTYCMD_BUF_OUT_LEN == len_temp)
{
vtycmd_ctrl.out_buf_end = 0;
}
else
{
vtycmd_ctrl.out_buf_end = len_temp;
}
}
}
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

@ -0,0 +1,697 @@
/******************************************************************************
* 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;
static unsigned long Crc32Table[256] =
{
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
0x2d02ef8dL
};
/* Private function prototypes -----------------------------------------------*/
/* 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: 按16进制打印buf数据.
param: buf --
len --
return: */
void buf_print_16(uint16_t *buf, int32_t len)
{
int32_t i = 0;
for(i = 0; i < len;)
{
printh("%04x ", 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(uint32_t ip, uint8_t *mac)
{
uint32_t temp = 0;
if (NULL == mac)
{
return E_BAD_PARAM;
}
/* 产生 mac. */
srand(time(NULL));
temp = rand();
mac[0] = 0x68;
mac[1] = temp & 0xff;
mac[2] = (temp >> 8) & 0xff;
mac[3] = (ip >> 8) & 0xff;
mac[4] = (ip >> 16) & 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: 计算 CRC32
param: crc -- CRC32
buf --
len --
return: crc */
unsigned int crc32(unsigned int crc, char *buf, unsigned long len)
{
const char *s = (const char *)buf;
while (len)
{
crc = Crc32Table[(crc ^ *s++) & 0xff] ^ (crc >> 8);
len --;
}
return crc;
}
/* 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);
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", softversion_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 version_hm = 0;
uint32_t version_hs = 0;
uint32_t n = 0;
n = sscanf(softversion_get(), "%d.%d.%d.%d", &version_hm, &version_hs, &version_m, &version_s);
if (n != 4)
{
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);
}
int32_t create_thread(thread_func_t func, thread_param_t *pParam)
{
pthread_attr_t attr;
struct sched_param param;
pthread_t pid;
int32_t rv = 0;
/* 配置线程RR调度, 优先级40 */
pthread_attr_init(&attr);
param.sched_priority = pParam->priority;
pthread_attr_setschedpolicy(&attr, SCHED_RR);
pthread_attr_setschedparam(&attr, &param);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
rv = pthread_create(&pid, &attr, func, pParam->arg);
if (rv != 0)
{
log_err(pParam->log_module, "PD can't create %s pthread %d!", pParam->thread_name, rv);
return E_SYS_CALL;
}
else
{
thread_m_add(pParam->thread_name, pid);
}
pthread_attr_destroy(&attr);
return E_NONE;
}
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -0,0 +1,248 @@
/******************************************************************************
* 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, TRUE, "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, FALSE, "csg_err"},
{DBG_M_PD_NET_ERR, TRUE, "net_err"},
{DBG_M_STORAGE_ERR, FALSE, "stroage"},
{DBG_M_DEBUG, FALSE, "debug"},
{DBG_M_PD_UPGRADE, FALSE, "upgrade"},
{DBG_M_PD_DATA, FALSE, "pd_data"},
};
/* 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,273 @@
/******************************************************************************
* 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)
{
fifo = array_init(16, MTYPE_FIFO);
if (!fifo)
{
log_err(LOG_FIFO, "ERROR at array init!");
return E_MEM;
}
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,564 @@
/******************************************************************************
* 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"},
{MTYPE_UPGRADE, "UPGRADE"},
{ -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,243 @@
/*****************************************************************************
* 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)
{
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);
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("can'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,355 @@
/******************************************************************************
* 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_dog_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_WATCHDONG:
snprintf(name, DEV_NAME_STR_LEN, "watchdog");
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};
DBG(DBG_M_GPIO, "gpio index %d \r\n", index);
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};
DBG(DBG_M_GPIO, "[%s %s:%d]gpio is %d \r\n", __FILE__, __func__, __LINE__, gpio);
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)
{
gpios = array_init(ARRAY_MIN_SIZE, MTYPE_GPIO);
gpio_dog_idx = gpio_export(GPIO_WATCHDONG);
if (gpio_dog_idx < 0)
{
DBG(DBG_M_GPIO, "ERROR return %d!\r\n", gpio_dog_idx);
return E_BAD_PARAM;
}
LD_E_RETURN(DBG_M_GPIO, gpio_dir_set(gpio_dog_idx, GPIO_DIR_OUT));
return E_NONE;
}
void feed_dog(void)
{
static char dog = 1;
dog = (dog == 1)? 0 : 1;
int ret = gpio_val_set(gpio_dog_idx, dog);
if (ret != E_NONE) {
DBG(DBG_M_DBG, "Failed to feed dog, error %d\r\n", ret);
} else {
//DBG(DBG_M_DBG, "feed_dog %d\r\n", dog);
}
}
/************************ (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,141 @@
# $(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 -e "$$(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
SOFT_COMPILE_DATE := `date "+%Y.%m.%d %k:%M:%S"`
SOFT_VERSION := "8.0.1.0"
HARDWARE_VERSION := "A.1"
FPGA_VERSION := "1.0"
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)
CROSS_COMPILE = aarch64-buildroot-linux-gnu-
CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar
CFLAGS += -g -Wall -funwind-tables -rdynamic -DHAVE_CONFIG_H
endif
#LDLIB := -L./libother -lreadline -lncurses -pthread -lrt -lsqlite3 -lm -lssl -lcrypto -lz
LDLIB := -L./libother -lreadline -lncurses -pthread -lrt -lsqlite3 -lm -lssh -lssl -lcrypto -lz
# 这里如果是‘@’则隐藏具体的编译命令
#QUIET := @
ENULL := > /dev/null
INFO_C := "\\033[31mInfo\\033[0m "
ERROR_C := "\\033[31mInfo\\033[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 ./libother/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 SOFT_VERSION \"$(SOFT_VERSION)\"" >> $(VERSION_FILE)
@echo "#define SOFT_COMPILE_DATE \"$(SOFT_COMPILE_DATE)\"" >> $(VERSION_FILE)
@echo "#define HARDV_ERSION \"$(HARDWARE_VERSION)\"" >> $(VERSION_FILE)
@echo "#define FPGA_VERSION \"$(FPGA_VERSION)\"" >> $(VERSION_FILE)
@echo "" >> $(VERSION_FILE)
@echo "char* softversion_get();" >> $(VERSION_FILE)
@echo "char* softversion_date_get();" >> $(VERSION_FILE)
@echo "char* hardware_version_get();" >> $(VERSION_FILE)
@echo "char* fpga_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 -e "$(INFO_C)AR $@ done";echo
PDMonitor: $(CONFIG_FILE) $(libraries) $(VERSION_LIB)
# 使用两次$(libraries)避免库文件之间的交叉引用问题.
$(QUIET)$(LINK.o) -rdynamic $(libraries) $(libraries) $(VERSION_LIB) $(LDLIB) -o $@
@echo -e "$(INFO_C)LINK $@ done";echo
# $(QUIET)cp $@ //home//embed//LandPower//
.PHONY: libraries
libraries: $(libraries)
.PHONY: clean
clean:
$(RM) $(modules) $(CONFIG_FILE) $(VERSION_FILE) PDMonitor $(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,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,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 -e "$(INFO_C)Create $@ done";echo
$(VERSION_FILE): $(PRODUCT).cfg

@ -0,0 +1,989 @@
/*
* This file is part of the SSH Library
*
* Copyright (c) 2009 Aris Adamantiadis <aris@0xbadc0de.be>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* callback.h
* This file includes the public declarations for the libssh callback mechanism
*/
#ifndef _SSH_CALLBACK_H
#define _SSH_CALLBACK_H
#include <libssh/libssh.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup libssh_callbacks The libssh callbacks
* @ingroup libssh
*
* Callback which can be replaced in libssh.
*
* @{
*/
/** @internal
* @brief callback to process simple codes
* @param code value to transmit
* @param user Userdata to pass in callback
*/
typedef void (*ssh_callback_int) (int code, void *user);
/** @internal
* @brief callback for data received messages.
* @param data data retrieved from the socket or stream
* @param len number of bytes available from this stream
* @param user user-supplied pointer sent along with all callback messages
* @returns number of bytes processed by the callee. The remaining bytes will
* be sent in the next callback message, when more data is available.
*/
typedef int (*ssh_callback_data) (const void *data, size_t len, void *user);
typedef void (*ssh_callback_int_int) (int code, int errno_code, void *user);
typedef int (*ssh_message_callback) (ssh_session, ssh_message message, void *user);
typedef int (*ssh_channel_callback_int) (ssh_channel channel, int code, void *user);
typedef int (*ssh_channel_callback_data) (ssh_channel channel, int code, void *data, size_t len, void *user);
/**
* @brief SSH log callback. All logging messages will go through this callback
* @param session Current session handler
* @param priority Priority of the log, the smaller being the more important
* @param message the actual message
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_log_callback) (ssh_session session, int priority,
const char *message, void *userdata);
/**
* @brief SSH log callback.
*
* All logging messages will go through this callback.
*
* @param priority Priority of the log, the smaller being the more important.
*
* @param function The function name calling the the logging fucntions.
*
* @param message The actual message
*
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_logging_callback) (int priority,
const char *function,
const char *buffer,
void *userdata);
/**
* @brief SSH Connection status callback.
* @param session Current session handler
* @param status Percentage of connection status, going from 0.0 to 1.0
* once connection is done.
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_status_callback) (ssh_session session, float status,
void *userdata);
/**
* @brief SSH global request callback. All global request will go through this
* callback.
* @param session Current session handler
* @param message the actual message
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_global_request_callback) (ssh_session session,
ssh_message message, void *userdata);
/**
* @brief Handles an SSH new channel open X11 request. This happens when the server
* sends back an X11 connection attempt. This is a client-side API
* @param session current session handler
* @param userdata Userdata to be passed to the callback function.
* @returns a valid ssh_channel handle if the request is to be allowed
* @returns NULL if the request should not be allowed
* @warning The channel pointer returned by this callback must be closed by the application.
*/
typedef ssh_channel (*ssh_channel_open_request_x11_callback) (ssh_session session,
const char * originator_address, int originator_port, void *userdata);
/**
* @brief Handles an SSH new channel open "auth-agent" request. This happens when the server
* sends back an "auth-agent" connection attempt. This is a client-side API
* @param session current session handler
* @param userdata Userdata to be passed to the callback function.
* @returns a valid ssh_channel handle if the request is to be allowed
* @returns NULL if the request should not be allowed
* @warning The channel pointer returned by this callback must be closed by the application.
*/
typedef ssh_channel (*ssh_channel_open_request_auth_agent_callback) (ssh_session session,
void *userdata);
/**
* The structure to replace libssh functions with appropriate callbacks.
*/
struct ssh_callbacks_struct {
/** DON'T SET THIS use ssh_callbacks_init() instead. */
size_t size;
/**
* User-provided data. User is free to set anything he wants here
*/
void *userdata;
/**
* This functions will be called if e.g. a keyphrase is needed.
*/
ssh_auth_callback auth_function;
/**
* This function will be called each time a loggable event happens.
*/
ssh_log_callback log_function;
/**
* This function gets called during connection time to indicate the
* percentage of connection steps completed.
*/
void (*connect_status_function)(void *userdata, float status);
/**
* This function will be called each time a global request is received.
*/
ssh_global_request_callback global_request_function;
/** This function will be called when an incoming X11 request is received.
*/
ssh_channel_open_request_x11_callback channel_open_request_x11_function;
/** This function will be called when an incoming "auth-agent" request is received.
*/
ssh_channel_open_request_auth_agent_callback channel_open_request_auth_agent_function;
};
typedef struct ssh_callbacks_struct *ssh_callbacks;
/** These are callbacks used specifically in SSH servers.
*/
/**
* @brief SSH authentication callback.
* @param session Current session handler
* @param user User that wants to authenticate
* @param password Password used for authentication
* @param userdata Userdata to be passed to the callback function.
* @returns SSH_AUTH_SUCCESS Authentication is accepted.
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
* @returns SSH_AUTH_DENIED Authentication failed.
*/
typedef int (*ssh_auth_password_callback) (ssh_session session, const char *user, const char *password,
void *userdata);
/**
* @brief SSH authentication callback. Tries to authenticates user with the "none" method
* which is anonymous or passwordless.
* @param session Current session handler
* @param user User that wants to authenticate
* @param userdata Userdata to be passed to the callback function.
* @returns SSH_AUTH_SUCCESS Authentication is accepted.
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
* @returns SSH_AUTH_DENIED Authentication failed.
*/
typedef int (*ssh_auth_none_callback) (ssh_session session, const char *user, void *userdata);
/**
* @brief SSH authentication callback. Tries to authenticates user with the "gssapi-with-mic" method
* @param session Current session handler
* @param user Username of the user (can be spoofed)
* @param principal Authenticated principal of the user, including realm.
* @param userdata Userdata to be passed to the callback function.
* @returns SSH_AUTH_SUCCESS Authentication is accepted.
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
* @returns SSH_AUTH_DENIED Authentication failed.
* @warning Implementations should verify that parameter user matches in some way the principal.
* user and principal can be different. Only the latter is guaranteed to be safe.
*/
typedef int (*ssh_auth_gssapi_mic_callback) (ssh_session session, const char *user, const char *principal,
void *userdata);
/**
* @brief SSH authentication callback.
* @param session Current session handler
* @param user User that wants to authenticate
* @param pubkey public key used for authentication
* @param signature_state SSH_PUBLICKEY_STATE_NONE if the key is not signed (simple public key probe),
* SSH_PUBLICKEY_STATE_VALID if the signature is valid. Others values should be
* replied with a SSH_AUTH_DENIED.
* @param userdata Userdata to be passed to the callback function.
* @returns SSH_AUTH_SUCCESS Authentication is accepted.
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
* @returns SSH_AUTH_DENIED Authentication failed.
*/
typedef int (*ssh_auth_pubkey_callback) (ssh_session session, const char *user, struct ssh_key_struct *pubkey,
char signature_state, void *userdata);
/**
* @brief Handles an SSH service request
* @param session current session handler
* @param service name of the service (e.g. "ssh-userauth") requested
* @param userdata Userdata to be passed to the callback function.
* @returns 0 if the request is to be allowed
* @returns -1 if the request should not be allowed
*/
typedef int (*ssh_service_request_callback) (ssh_session session, const char *service, void *userdata);
/**
* @brief Handles an SSH new channel open session request
* @param session current session handler
* @param userdata Userdata to be passed to the callback function.
* @returns a valid ssh_channel handle if the request is to be allowed
* @returns NULL if the request should not be allowed
* @warning The channel pointer returned by this callback must be closed by the application.
*/
typedef ssh_channel (*ssh_channel_open_request_session_callback) (ssh_session session, void *userdata);
/*
* @brief handle the beginning of a GSSAPI authentication, server side.
* @param session current session handler
* @param user the username of the client
* @param n_oid number of available oids
* @param oids OIDs provided by the client
* @returns an ssh_string containing the chosen OID, that's supported by both
* client and server.
* @warning It is not necessary to fill this callback in if libssh is linked
* with libgssapi.
*/
typedef ssh_string (*ssh_gssapi_select_oid_callback) (ssh_session session, const char *user,
int n_oid, ssh_string *oids, void *userdata);
/*
* @brief handle the negociation of a security context, server side.
* @param session current session handler
* @param[in] input_token input token provided by client
* @param[out] output_token output of the gssapi accept_sec_context method,
* NULL after completion.
* @returns SSH_OK if the token was generated correctly or accept_sec_context
* returned GSS_S_COMPLETE
* @returns SSH_ERROR in case of error
* @warning It is not necessary to fill this callback in if libssh is linked
* with libgssapi.
*/
typedef int (*ssh_gssapi_accept_sec_ctx_callback) (ssh_session session,
ssh_string input_token, ssh_string *output_token, void *userdata);
/*
* @brief Verify and authenticates a MIC, server side.
* @param session current session handler
* @param[in] mic input mic to be verified provided by client
* @param[in] mic_buffer buffer of data to be signed.
* @param[in] mic_buffer_size size of mic_buffer
* @returns SSH_OK if the MIC was authenticated correctly
* @returns SSH_ERROR in case of error
* @warning It is not necessary to fill this callback in if libssh is linked
* with libgssapi.
*/
typedef int (*ssh_gssapi_verify_mic_callback) (ssh_session session,
ssh_string mic, void *mic_buffer, size_t mic_buffer_size, void *userdata);
/**
* This structure can be used to implement a libssh server, with appropriate callbacks.
*/
struct ssh_server_callbacks_struct {
/** DON'T SET THIS use ssh_callbacks_init() instead. */
size_t size;
/**
* User-provided data. User is free to set anything he wants here
*/
void *userdata;
/** This function gets called when a client tries to authenticate through
* password method.
*/
ssh_auth_password_callback auth_password_function;
/** This function gets called when a client tries to authenticate through
* none method.
*/
ssh_auth_none_callback auth_none_function;
/** This function gets called when a client tries to authenticate through
* gssapi-mic method.
*/
ssh_auth_gssapi_mic_callback auth_gssapi_mic_function;
/** this function gets called when a client tries to authenticate or offer
* a public key.
*/
ssh_auth_pubkey_callback auth_pubkey_function;
/** This functions gets called when a service request is issued by the
* client
*/
ssh_service_request_callback service_request_function;
/** This functions gets called when a new channel request is issued by
* the client
*/
ssh_channel_open_request_session_callback channel_open_request_session_function;
/** This function will be called when a new gssapi authentication is attempted.
*/
ssh_gssapi_select_oid_callback gssapi_select_oid_function;
/** This function will be called when a gssapi token comes in.
*/
ssh_gssapi_accept_sec_ctx_callback gssapi_accept_sec_ctx_function;
/* This function will be called when a MIC needs to be verified.
*/
ssh_gssapi_verify_mic_callback gssapi_verify_mic_function;
};
typedef struct ssh_server_callbacks_struct *ssh_server_callbacks;
/**
* @brief Set the session server callback functions.
*
* This functions sets the callback structure to use your own callback
* functions for user authentication, new channels and requests.
*
* @code
* struct ssh_server_callbacks_struct cb = {
* .userdata = data,
* .auth_password_function = my_auth_function
* };
* ssh_callbacks_init(&cb);
* ssh_set_server_callbacks(session, &cb);
* @endcode
*
* @param session The session to set the callback structure.
*
* @param cb The callback structure itself.
*
* @return SSH_OK on success, SSH_ERROR on error.
*/
LIBSSH_API int ssh_set_server_callbacks(ssh_session session, ssh_server_callbacks cb);
/**
* These are the callbacks exported by the socket structure
* They are called by the socket module when a socket event appears
*/
struct ssh_socket_callbacks_struct {
/**
* User-provided data. User is free to set anything he wants here
*/
void *userdata;
/**
* This function will be called each time data appears on socket. The data
* not consumed will appear on the next data event.
*/
ssh_callback_data data;
/** This function will be called each time a controlflow state changes, i.e.
* the socket is available for reading or writing.
*/
ssh_callback_int controlflow;
/** This function will be called each time an exception appears on socket. An
* exception can be a socket problem (timeout, ...) or an end-of-file.
*/
ssh_callback_int_int exception;
/** This function is called when the ssh_socket_connect was used on the socket
* on nonblocking state, and the connection successed.
*/
ssh_callback_int_int connected;
};
typedef struct ssh_socket_callbacks_struct *ssh_socket_callbacks;
#define SSH_SOCKET_FLOW_WRITEWILLBLOCK 1
#define SSH_SOCKET_FLOW_WRITEWONTBLOCK 2
#define SSH_SOCKET_EXCEPTION_EOF 1
#define SSH_SOCKET_EXCEPTION_ERROR 2
#define SSH_SOCKET_CONNECTED_OK 1
#define SSH_SOCKET_CONNECTED_ERROR 2
#define SSH_SOCKET_CONNECTED_TIMEOUT 3
/**
* @brief Initializes an ssh_callbacks_struct
* A call to this macro is mandatory when you have set a new
* ssh_callback_struct structure. Its goal is to maintain the binary
* compatibility with future versions of libssh as the structure
* evolves with time.
*/
#define ssh_callbacks_init(p) do {\
(p)->size=sizeof(*(p)); \
} while(0);
/**
* @internal
* @brief tests if a callback can be called without crash
* verifies that the struct size if big enough
* verifies that the callback pointer exists
* @param p callback pointer
* @param c callback name
* @returns nonzero if callback can be called
*/
#define ssh_callbacks_exists(p,c) (\
(p != NULL) && ( (char *)&((p)-> c) < (char *)(p) + (p)->size ) && \
((p)-> c != NULL) \
)
/**
* @internal
*
* @brief Iterate through a list of callback structures
*
* This tests for their validity and executes them. The userdata argument is
* automatically passed through.
*
* @param list list of callbacks
*
* @param cbtype type of the callback
*
* @param c callback name
*
* @param va_args parameters to be passed
*/
#define ssh_callbacks_execute_list(list, cbtype, c, ...) \
do { \
struct ssh_iterator *i = ssh_list_get_iterator(list); \
cbtype cb; \
while (i != NULL){ \
cb = ssh_iterator_value(cbtype, i); \
if (ssh_callbacks_exists(cb, c)) \
cb-> c (__VA_ARGS__, cb->userdata); \
i = i->next; \
} \
} while(0)
/**
* @internal
*
* @brief iterate through a list of callback structures.
*
* This tests for their validity and give control back to the calling code to
* execute them. Caller can decide to break the loop or continue executing the
* callbacks with different parameters
*
* @code
* ssh_callbacks_iterate(channel->callbacks, ssh_channel_callbacks,
* channel_eof_function){
* rc = ssh_callbacks_iterate_exec(session, channel);
* if (rc != SSH_OK){
* break;
* }
* }
* ssh_callbacks_iterate_end();
* @endcode
*/
#define ssh_callbacks_iterate(_cb_list, _cb_type, _cb_name) \
do { \
struct ssh_iterator *_cb_i = ssh_list_get_iterator(_cb_list); \
_cb_type _cb; \
for (; _cb_i != NULL; _cb_i = _cb_i->next) { \
_cb = ssh_iterator_value(_cb_type, _cb_i); \
if (ssh_callbacks_exists(_cb, _cb_name))
#define ssh_callbacks_iterate_exec(_cb_name, ...) \
_cb->_cb_name(__VA_ARGS__, _cb->userdata)
#define ssh_callbacks_iterate_end() \
} \
} while(0)
/** @brief Prototype for a packet callback, to be called when a new packet arrives
* @param session The current session of the packet
* @param type packet type (see ssh2.h)
* @param packet buffer containing the packet, excluding size, type and padding fields
* @param user user argument to the callback
* and are called each time a packet shows up
* @returns SSH_PACKET_USED Packet was parsed and used
* @returns SSH_PACKET_NOT_USED Packet was not used or understood, processing must continue
*/
typedef int (*ssh_packet_callback) (ssh_session session, uint8_t type, ssh_buffer packet, void *user);
/** return values for a ssh_packet_callback */
/** Packet was used and should not be parsed by another callback */
#define SSH_PACKET_USED 1
/** Packet was not used and should be passed to any other callback
* available */
#define SSH_PACKET_NOT_USED 2
/** @brief This macro declares a packet callback handler
* @code
* SSH_PACKET_CALLBACK(mycallback){
* ...
* }
* @endcode
*/
#define SSH_PACKET_CALLBACK(name) \
int name (ssh_session session, uint8_t type, ssh_buffer packet, void *user)
struct ssh_packet_callbacks_struct {
/** Index of the first packet type being handled */
uint8_t start;
/** Number of packets being handled by this callback struct */
uint8_t n_callbacks;
/** A pointer to n_callbacks packet callbacks */
ssh_packet_callback *callbacks;
/**
* User-provided data. User is free to set anything he wants here
*/
void *user;
};
typedef struct ssh_packet_callbacks_struct *ssh_packet_callbacks;
/**
* @brief Set the session callback functions.
*
* This functions sets the callback structure to use your own callback
* functions for auth, logging and status.
*
* @code
* struct ssh_callbacks_struct cb = {
* .userdata = data,
* .auth_function = my_auth_function
* };
* ssh_callbacks_init(&cb);
* ssh_set_callbacks(session, &cb);
* @endcode
*
* @param session The session to set the callback structure.
*
* @param cb The callback structure itself.
*
* @return SSH_OK on success, SSH_ERROR on error.
*/
LIBSSH_API int ssh_set_callbacks(ssh_session session, ssh_callbacks cb);
/**
* @brief SSH channel data callback. Called when data is available on a channel
* @param session Current session handler
* @param channel the actual channel
* @param data the data that has been read on the channel
* @param len the length of the data
* @param is_stderr is 0 for stdout or 1 for stderr
* @param userdata Userdata to be passed to the callback function.
* @returns number of bytes processed by the callee. The remaining bytes will
* be sent in the next callback message, when more data is available.
*/
typedef int (*ssh_channel_data_callback) (ssh_session session,
ssh_channel channel,
void *data,
uint32_t len,
int is_stderr,
void *userdata);
/**
* @brief SSH channel eof callback. Called when a channel receives EOF
* @param session Current session handler
* @param channel the actual channel
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_channel_eof_callback) (ssh_session session,
ssh_channel channel,
void *userdata);
/**
* @brief SSH channel close callback. Called when a channel is closed by remote peer
* @param session Current session handler
* @param channel the actual channel
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_channel_close_callback) (ssh_session session,
ssh_channel channel,
void *userdata);
/**
* @brief SSH channel signal callback. Called when a channel has received a signal
* @param session Current session handler
* @param channel the actual channel
* @param signal the signal name (without the SIG prefix)
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_channel_signal_callback) (ssh_session session,
ssh_channel channel,
const char *signal,
void *userdata);
/**
* @brief SSH channel exit status callback. Called when a channel has received an exit status
* @param session Current session handler
* @param channel the actual channel
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_channel_exit_status_callback) (ssh_session session,
ssh_channel channel,
int exit_status,
void *userdata);
/**
* @brief SSH channel exit signal callback. Called when a channel has received an exit signal
* @param session Current session handler
* @param channel the actual channel
* @param signal the signal name (without the SIG prefix)
* @param core a boolean telling wether a core has been dumped or not
* @param errmsg the description of the exception
* @param lang the language of the description (format: RFC 3066)
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_channel_exit_signal_callback) (ssh_session session,
ssh_channel channel,
const char *signal,
int core,
const char *errmsg,
const char *lang,
void *userdata);
/**
* @brief SSH channel PTY request from a client.
* @param channel the channel
* @param term The type of terminal emulation
* @param width width of the terminal, in characters
* @param height height of the terminal, in characters
* @param pxwidth width of the terminal, in pixels
* @param pxheight height of the terminal, in pixels
* @param userdata Userdata to be passed to the callback function.
* @returns 0 if the pty request is accepted
* @returns -1 if the request is denied
*/
typedef int (*ssh_channel_pty_request_callback) (ssh_session session,
ssh_channel channel,
const char *term,
int width, int height,
int pxwidth, int pwheight,
void *userdata);
/**
* @brief SSH channel Shell request from a client.
* @param channel the channel
* @param userdata Userdata to be passed to the callback function.
* @returns 0 if the shell request is accepted
* @returns 1 if the request is denied
*/
typedef int (*ssh_channel_shell_request_callback) (ssh_session session,
ssh_channel channel,
void *userdata);
/**
* @brief SSH auth-agent-request from the client. This request is
* sent by a client when agent forwarding is available.
* Server is free to ignore this callback, no answer is expected.
* @param channel the channel
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_channel_auth_agent_req_callback) (ssh_session session,
ssh_channel channel,
void *userdata);
/**
* @brief SSH X11 request from the client. This request is
* sent by a client when X11 forwarding is requested(and available).
* Server is free to ignore this callback, no answer is expected.
* @param channel the channel
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_channel_x11_req_callback) (ssh_session session,
ssh_channel channel,
int single_connection,
const char *auth_protocol,
const char *auth_cookie,
uint32_t screen_number,
void *userdata);
/**
* @brief SSH channel PTY windows change (terminal size) from a client.
* @param channel the channel
* @param width width of the terminal, in characters
* @param height height of the terminal, in characters
* @param pxwidth width of the terminal, in pixels
* @param pxheight height of the terminal, in pixels
* @param userdata Userdata to be passed to the callback function.
* @returns 0 if the pty request is accepted
* @returns -1 if the request is denied
*/
typedef int (*ssh_channel_pty_window_change_callback) (ssh_session session,
ssh_channel channel,
int width, int height,
int pxwidth, int pwheight,
void *userdata);
/**
* @brief SSH channel Exec request from a client.
* @param channel the channel
* @param command the shell command to be executed
* @param userdata Userdata to be passed to the callback function.
* @returns 0 if the exec request is accepted
* @returns 1 if the request is denied
*/
typedef int (*ssh_channel_exec_request_callback) (ssh_session session,
ssh_channel channel,
const char *command,
void *userdata);
/**
* @brief SSH channel environment request from a client.
* @param channel the channel
* @param env_name name of the environment value to be set
* @param env_value value of the environment value to be set
* @param userdata Userdata to be passed to the callback function.
* @returns 0 if the env request is accepted
* @returns 1 if the request is denied
* @warning some environment variables can be dangerous if changed (e.g.
* LD_PRELOAD) and should not be fulfilled.
*/
typedef int (*ssh_channel_env_request_callback) (ssh_session session,
ssh_channel channel,
const char *env_name,
const char *env_value,
void *userdata);
/**
* @brief SSH channel subsystem request from a client.
* @param channel the channel
* @param subsystem the subsystem required
* @param userdata Userdata to be passed to the callback function.
* @returns 0 if the subsystem request is accepted
* @returns 1 if the request is denied
*/
typedef int (*ssh_channel_subsystem_request_callback) (ssh_session session,
ssh_channel channel,
const char *subsystem,
void *userdata);
/**
* @brief SSH channel write will not block (flow control).
*
* @param channel the channel
*
* @param[in] bytes size of the remote window in bytes. Writing as much data
* will not block.
*
* @param[in] userdata Userdata to be passed to the callback function.
*
* @returns 0 default return value (other return codes may be added in future).
*/
typedef int (*ssh_channel_write_wontblock_callback) (ssh_session session,
ssh_channel channel,
size_t bytes,
void *userdata);
struct ssh_channel_callbacks_struct {
/** DON'T SET THIS use ssh_callbacks_init() instead. */
size_t size;
/**
* User-provided data. User is free to set anything he wants here
*/
void *userdata;
/**
* This functions will be called when there is data available.
*/
ssh_channel_data_callback channel_data_function;
/**
* This functions will be called when the channel has received an EOF.
*/
ssh_channel_eof_callback channel_eof_function;
/**
* This functions will be called when the channel has been closed by remote
*/
ssh_channel_close_callback channel_close_function;
/**
* This functions will be called when a signal has been received
*/
ssh_channel_signal_callback channel_signal_function;
/**
* This functions will be called when an exit status has been received
*/
ssh_channel_exit_status_callback channel_exit_status_function;
/**
* This functions will be called when an exit signal has been received
*/
ssh_channel_exit_signal_callback channel_exit_signal_function;
/**
* This function will be called when a client requests a PTY
*/
ssh_channel_pty_request_callback channel_pty_request_function;
/**
* This function will be called when a client requests a shell
*/
ssh_channel_shell_request_callback channel_shell_request_function;
/** This function will be called when a client requests agent
* authentication forwarding.
*/
ssh_channel_auth_agent_req_callback channel_auth_agent_req_function;
/** This function will be called when a client requests X11
* forwarding.
*/
ssh_channel_x11_req_callback channel_x11_req_function;
/** This function will be called when a client requests a
* window change.
*/
ssh_channel_pty_window_change_callback channel_pty_window_change_function;
/** This function will be called when a client requests a
* command execution.
*/
ssh_channel_exec_request_callback channel_exec_request_function;
/** This function will be called when a client requests an environment
* variable to be set.
*/
ssh_channel_env_request_callback channel_env_request_function;
/** This function will be called when a client requests a subsystem
* (like sftp).
*/
ssh_channel_subsystem_request_callback channel_subsystem_request_function;
/** This function will be called when the channel write is guaranteed
* not to block.
*/
ssh_channel_write_wontblock_callback channel_write_wontblock_function;
};
typedef struct ssh_channel_callbacks_struct *ssh_channel_callbacks;
/**
* @brief Set the channel callback functions.
*
* This functions sets the callback structure to use your own callback
* functions for channel data and exceptions
*
* @code
* struct ssh_channel_callbacks_struct cb = {
* .userdata = data,
* .channel_data = my_channel_data_function
* };
* ssh_callbacks_init(&cb);
* ssh_set_channel_callbacks(channel, &cb);
* @endcode
*
* @param channel The channel to set the callback structure.
*
* @param cb The callback structure itself.
*
* @return SSH_OK on success, SSH_ERROR on error.
* @warning this function will not replace existing callbacks but set the
* new one atop of them.
*/
LIBSSH_API int ssh_set_channel_callbacks(ssh_channel channel,
ssh_channel_callbacks cb);
/**
* @brief Add channel callback functions
*
* This function will add channel callback functions to the channel callback
* list.
* Callbacks missing from a callback structure will be probed in the next
* on the list.
*
* @param channel The channel to set the callback structure.
*
* @param cb The callback structure itself.
*
* @return SSH_OK on success, SSH_ERROR on error.
*
* @see ssh_set_channel_callbacks
*/
LIBSSH_API int ssh_add_channel_callbacks(ssh_channel channel,
ssh_channel_callbacks cb);
/**
* @brief Remove a channel callback.
*
* The channel has been added with ssh_add_channel_callbacks or
* ssh_set_channel_callbacks in this case.
*
* @param channel The channel to remove the callback structure from.
*
* @param cb The callback structure to remove
*
* @returns SSH_OK on success, SSH_ERROR on error.
*/
LIBSSH_API int ssh_remove_channel_callbacks(ssh_channel channel,
ssh_channel_callbacks cb);
/** @} */
/** @group libssh_threads
* @{
*/
typedef int (*ssh_thread_callback) (void **lock);
typedef unsigned long (*ssh_thread_id_callback) (void);
struct ssh_threads_callbacks_struct {
const char *type;
ssh_thread_callback mutex_init;
ssh_thread_callback mutex_destroy;
ssh_thread_callback mutex_lock;
ssh_thread_callback mutex_unlock;
ssh_thread_id_callback thread_id;
};
/**
* @brief Set the thread callbacks structure.
*
* This is necessary if your program is using libssh in a multithreaded fashion.
* This function must be called first, outside of any threading context (in your
* main() function for instance), before you call ssh_init().
*
* @param[in] cb A pointer to a ssh_threads_callbacks_struct structure, which
* contains the different callbacks to be set.
*
* @returns Always returns SSH_OK.
*
* @see ssh_threads_callbacks_struct
* @see SSH_THREADS_PTHREAD
* @bug libgcrypt 1.6 and bigger backend does not support custom callback.
* Using anything else than pthreads here will fail.
*/
LIBSSH_API int ssh_threads_set_callbacks(struct ssh_threads_callbacks_struct
*cb);
/**
* @brief returns a pointer on the pthread threads callbacks, to be used with
* ssh_threads_set_callbacks.
* @warning you have to link with the library ssh_threads.
* @see ssh_threads_set_callbacks
*/
LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_pthread(void);
/**
* @brief Get the noop threads callbacks structure
*
* This can be used with ssh_threads_set_callbacks. These callbacks do nothing
* and are being used by default.
*
* @return Always returns a valid pointer to the noop callbacks structure.
*
* @see ssh_threads_set_callbacks
*/
LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_noop(void);
/**
* @brief Set the logging callback function.
*
* @param[in] cb The callback to set.
*
* @return 0 on success, < 0 on errror.
*/
LIBSSH_API int ssh_set_log_callback(ssh_logging_callback cb);
/**
* @brief Get the pointer to the logging callback function.
*
* @return The pointer the the callback or NULL if none set.
*/
LIBSSH_API ssh_logging_callback ssh_get_log_callback(void);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /*_SSH_CALLBACK_H */
/* @} */

@ -0,0 +1,120 @@
/*
* This file is part of the SSH Library
*
* Copyright (c) 2010 by Aris Adamantiadis
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Since libssh.h includes legacy.h, it's important that libssh.h is included
* first. we don't define LEGACY_H now because we want it to be defined when
* included from libssh.h
* All function calls declared in this header are deprecated and meant to be
* removed in future.
*/
#ifndef LEGACY_H_
#define LEGACY_H_
typedef struct ssh_private_key_struct* ssh_private_key;
typedef struct ssh_public_key_struct* ssh_public_key;
LIBSSH_API int ssh_auth_list(ssh_session session);
LIBSSH_API int ssh_userauth_offer_pubkey(ssh_session session, const char *username, int type, ssh_string publickey);
LIBSSH_API int ssh_userauth_pubkey(ssh_session session, const char *username, ssh_string publickey, ssh_private_key privatekey);
#ifndef _WIN32
LIBSSH_API int ssh_userauth_agent_pubkey(ssh_session session, const char *username,
ssh_public_key publickey);
#endif
LIBSSH_API int ssh_userauth_autopubkey(ssh_session session, const char *passphrase);
LIBSSH_API int ssh_userauth_privatekey_file(ssh_session session, const char *username,
const char *filename, const char *passphrase);
SSH_DEPRECATED LIBSSH_API void buffer_free(ssh_buffer buffer);
SSH_DEPRECATED LIBSSH_API void *buffer_get(ssh_buffer buffer);
SSH_DEPRECATED LIBSSH_API uint32_t buffer_get_len(ssh_buffer buffer);
SSH_DEPRECATED LIBSSH_API ssh_buffer buffer_new(void);
SSH_DEPRECATED LIBSSH_API ssh_channel channel_accept_x11(ssh_channel channel, int timeout_ms);
SSH_DEPRECATED LIBSSH_API int channel_change_pty_size(ssh_channel channel,int cols,int rows);
SSH_DEPRECATED LIBSSH_API ssh_channel channel_forward_accept(ssh_session session, int timeout_ms);
SSH_DEPRECATED LIBSSH_API int channel_close(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_forward_cancel(ssh_session session, const char *address, int port);
SSH_DEPRECATED LIBSSH_API int channel_forward_listen(ssh_session session, const char *address, int port, int *bound_port);
SSH_DEPRECATED LIBSSH_API void channel_free(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_get_exit_status(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API ssh_session channel_get_session(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_is_closed(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_is_eof(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_is_open(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API ssh_channel channel_new(ssh_session session);
SSH_DEPRECATED LIBSSH_API int channel_open_forward(ssh_channel channel, const char *remotehost,
int remoteport, const char *sourcehost, int localport);
SSH_DEPRECATED LIBSSH_API int channel_open_session(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_poll(ssh_channel channel, int is_stderr);
SSH_DEPRECATED LIBSSH_API int channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr);
SSH_DEPRECATED LIBSSH_API int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count,
int is_stderr);
SSH_DEPRECATED LIBSSH_API int channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count,
int is_stderr);
SSH_DEPRECATED LIBSSH_API int channel_request_env(ssh_channel channel, const char *name, const char *value);
SSH_DEPRECATED LIBSSH_API int channel_request_exec(ssh_channel channel, const char *cmd);
SSH_DEPRECATED LIBSSH_API int channel_request_pty(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_request_pty_size(ssh_channel channel, const char *term,
int cols, int rows);
SSH_DEPRECATED LIBSSH_API int channel_request_shell(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_request_send_signal(ssh_channel channel, const char *signum);
SSH_DEPRECATED LIBSSH_API int channel_request_sftp(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_request_subsystem(ssh_channel channel, const char *subsystem);
SSH_DEPRECATED LIBSSH_API int channel_request_x11(ssh_channel channel, int single_connection, const char *protocol,
const char *cookie, int screen_number);
SSH_DEPRECATED LIBSSH_API int channel_send_eof(ssh_channel channel);
SSH_DEPRECATED LIBSSH_API int channel_select(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct
timeval * timeout);
SSH_DEPRECATED LIBSSH_API void channel_set_blocking(ssh_channel channel, int blocking);
SSH_DEPRECATED LIBSSH_API int channel_write(ssh_channel channel, const void *data, uint32_t len);
LIBSSH_API void privatekey_free(ssh_private_key prv);
LIBSSH_API ssh_private_key privatekey_from_file(ssh_session session, const char *filename,
int type, const char *passphrase);
LIBSSH_API void publickey_free(ssh_public_key key);
LIBSSH_API int ssh_publickey_to_file(ssh_session session, const char *file,
ssh_string pubkey, int type);
LIBSSH_API ssh_string publickey_from_file(ssh_session session, const char *filename,
int *type);
LIBSSH_API ssh_public_key publickey_from_privatekey(ssh_private_key prv);
LIBSSH_API ssh_string publickey_to_string(ssh_public_key key);
LIBSSH_API int ssh_try_publickey_from_file(ssh_session session, const char *keyfile,
ssh_string *publickey, int *type);
LIBSSH_API enum ssh_keytypes_e ssh_privatekey_type(ssh_private_key privatekey);
LIBSSH_API ssh_string ssh_get_pubkey(ssh_session session);
LIBSSH_API ssh_message ssh_message_retrieve(ssh_session session, uint32_t packettype);
LIBSSH_API ssh_public_key ssh_message_auth_publickey(ssh_message msg);
SSH_DEPRECATED LIBSSH_API void string_burn(ssh_string str);
SSH_DEPRECATED LIBSSH_API ssh_string string_copy(ssh_string str);
SSH_DEPRECATED LIBSSH_API void *string_data(ssh_string str);
SSH_DEPRECATED LIBSSH_API int string_fill(ssh_string str, const void *data, size_t len);
SSH_DEPRECATED LIBSSH_API void string_free(ssh_string str);
SSH_DEPRECATED LIBSSH_API ssh_string string_from_char(const char *what);
SSH_DEPRECATED LIBSSH_API size_t string_len(ssh_string str);
SSH_DEPRECATED LIBSSH_API ssh_string string_new(size_t size);
SSH_DEPRECATED LIBSSH_API char *string_to_char(ssh_string str);
#endif /* LEGACY_H_ */

@ -0,0 +1,823 @@
/*
* This file is part of the SSH Library
*
* Copyright (c) 2003-2009 by Aris Adamantiadis
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _LIBSSH_H
#define _LIBSSH_H
#if defined _WIN32 || defined __CYGWIN__
#ifdef LIBSSH_STATIC
#define LIBSSH_API
#else
#ifdef LIBSSH_EXPORTS
#ifdef __GNUC__
#define LIBSSH_API __attribute__((dllexport))
#else
#define LIBSSH_API __declspec(dllexport)
#endif
#else
#ifdef __GNUC__
#define LIBSSH_API __attribute__((dllimport))
#else
#define LIBSSH_API __declspec(dllimport)
#endif
#endif
#endif
#else
#if __GNUC__ >= 4 && !defined(__OS2__)
#define LIBSSH_API __attribute__((visibility("default")))
#else
#define LIBSSH_API
#endif
#endif
#ifdef _MSC_VER
/* Visual Studio hasn't inttypes.h so it doesn't know uint32_t */
typedef int int32_t;
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
typedef unsigned long long uint64_t;
typedef int mode_t;
#else /* _MSC_VER */
#include <unistd.h>
#include <inttypes.h>
#include <sys/types.h>
#endif /* _MSC_VER */
#ifdef _WIN32
#include <winsock2.h>
#else /* _WIN32 */
#include <sys/select.h> /* for fd_set * */
#include <netdb.h>
#endif /* _WIN32 */
#define SSH_STRINGIFY(s) SSH_TOSTRING(s)
#define SSH_TOSTRING(s) #s
/* libssh version macros */
#define SSH_VERSION_INT(a, b, c) ((a) << 16 | (b) << 8 | (c))
#define SSH_VERSION_DOT(a, b, c) a ##.## b ##.## c
#define SSH_VERSION(a, b, c) SSH_VERSION_DOT(a, b, c)
/* libssh version */
#define LIBSSH_VERSION_MAJOR 0
#define LIBSSH_VERSION_MINOR 8
#define LIBSSH_VERSION_MICRO 8
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
LIBSSH_VERSION_MINOR, \
LIBSSH_VERSION_MICRO)
#define LIBSSH_VERSION SSH_VERSION(LIBSSH_VERSION_MAJOR, \
LIBSSH_VERSION_MINOR, \
LIBSSH_VERSION_MICRO)
/* GCC have printf type attribute check. */
#ifdef __GNUC__
#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
#else
#define PRINTF_ATTRIBUTE(a,b)
#endif /* __GNUC__ */
#ifdef __GNUC__
#define SSH_DEPRECATED __attribute__ ((deprecated))
#else
#define SSH_DEPRECATED
#endif
#ifdef __cplusplus
extern "C" {
#endif
struct ssh_counter_struct {
uint64_t in_bytes;
uint64_t out_bytes;
uint64_t in_packets;
uint64_t out_packets;
};
typedef struct ssh_counter_struct *ssh_counter;
typedef struct ssh_agent_struct* ssh_agent;
typedef struct ssh_buffer_struct* ssh_buffer;
typedef struct ssh_channel_struct* ssh_channel;
typedef struct ssh_message_struct* ssh_message;
typedef struct ssh_pcap_file_struct* ssh_pcap_file;
typedef struct ssh_key_struct* ssh_key;
typedef struct ssh_scp_struct* ssh_scp;
typedef struct ssh_session_struct* ssh_session;
typedef struct ssh_string_struct* ssh_string;
typedef struct ssh_event_struct* ssh_event;
typedef struct ssh_connector_struct * ssh_connector;
typedef void* ssh_gssapi_creds;
/* Socket type */
#ifdef _WIN32
#ifndef socket_t
typedef SOCKET socket_t;
#endif /* socket_t */
#else /* _WIN32 */
#ifndef socket_t
typedef int socket_t;
#endif
#endif /* _WIN32 */
#define SSH_INVALID_SOCKET ((socket_t) -1)
/* the offsets of methods */
enum ssh_kex_types_e {
SSH_KEX=0,
SSH_HOSTKEYS,
SSH_CRYPT_C_S,
SSH_CRYPT_S_C,
SSH_MAC_C_S,
SSH_MAC_S_C,
SSH_COMP_C_S,
SSH_COMP_S_C,
SSH_LANG_C_S,
SSH_LANG_S_C
};
#define SSH_CRYPT 2
#define SSH_MAC 3
#define SSH_COMP 4
#define SSH_LANG 5
enum ssh_auth_e {
SSH_AUTH_SUCCESS=0,
SSH_AUTH_DENIED,
SSH_AUTH_PARTIAL,
SSH_AUTH_INFO,
SSH_AUTH_AGAIN,
SSH_AUTH_ERROR=-1
};
/* auth flags */
#define SSH_AUTH_METHOD_UNKNOWN 0
#define SSH_AUTH_METHOD_NONE 0x0001
#define SSH_AUTH_METHOD_PASSWORD 0x0002
#define SSH_AUTH_METHOD_PUBLICKEY 0x0004
#define SSH_AUTH_METHOD_HOSTBASED 0x0008
#define SSH_AUTH_METHOD_INTERACTIVE 0x0010
#define SSH_AUTH_METHOD_GSSAPI_MIC 0x0020
/* messages */
enum ssh_requests_e {
SSH_REQUEST_AUTH=1,
SSH_REQUEST_CHANNEL_OPEN,
SSH_REQUEST_CHANNEL,
SSH_REQUEST_SERVICE,
SSH_REQUEST_GLOBAL
};
enum ssh_channel_type_e {
SSH_CHANNEL_UNKNOWN=0,
SSH_CHANNEL_SESSION,
SSH_CHANNEL_DIRECT_TCPIP,
SSH_CHANNEL_FORWARDED_TCPIP,
SSH_CHANNEL_X11,
SSH_CHANNEL_AUTH_AGENT
};
enum ssh_channel_requests_e {
SSH_CHANNEL_REQUEST_UNKNOWN=0,
SSH_CHANNEL_REQUEST_PTY,
SSH_CHANNEL_REQUEST_EXEC,
SSH_CHANNEL_REQUEST_SHELL,
SSH_CHANNEL_REQUEST_ENV,
SSH_CHANNEL_REQUEST_SUBSYSTEM,
SSH_CHANNEL_REQUEST_WINDOW_CHANGE,
SSH_CHANNEL_REQUEST_X11
};
enum ssh_global_requests_e {
SSH_GLOBAL_REQUEST_UNKNOWN=0,
SSH_GLOBAL_REQUEST_TCPIP_FORWARD,
SSH_GLOBAL_REQUEST_CANCEL_TCPIP_FORWARD,
SSH_GLOBAL_REQUEST_KEEPALIVE
};
enum ssh_publickey_state_e {
SSH_PUBLICKEY_STATE_ERROR=-1,
SSH_PUBLICKEY_STATE_NONE=0,
SSH_PUBLICKEY_STATE_VALID=1,
SSH_PUBLICKEY_STATE_WRONG=2
};
/* Status flags */
/** Socket is closed */
#define SSH_CLOSED 0x01
/** Reading to socket won't block */
#define SSH_READ_PENDING 0x02
/** Session was closed due to an error */
#define SSH_CLOSED_ERROR 0x04
/** Output buffer not empty */
#define SSH_WRITE_PENDING 0x08
enum ssh_server_known_e {
SSH_SERVER_ERROR=-1,
SSH_SERVER_NOT_KNOWN=0,
SSH_SERVER_KNOWN_OK,
SSH_SERVER_KNOWN_CHANGED,
SSH_SERVER_FOUND_OTHER,
SSH_SERVER_FILE_NOT_FOUND
};
enum ssh_known_hosts_e {
/**
* There had been an error checking the host.
*/
SSH_KNOWN_HOSTS_ERROR = -2,
/**
* The known host file does not exist. The host is thus unknown. File will
* be created if host key is accepted.
*/
SSH_KNOWN_HOSTS_NOT_FOUND = -1,
/**
* The server is unknown. User should confirm the public key hash is
* correct.
*/
SSH_KNOWN_HOSTS_UNKNOWN = 0,
/**
* The server is known and has not changed.
*/
SSH_KNOWN_HOSTS_OK,
/**
* The server key has changed. Either you are under attack or the
* administrator changed the key. You HAVE to warn the user about a
* possible attack.
*/
SSH_KNOWN_HOSTS_CHANGED,
/**
* The server gave use a key of a type while we had an other type recorded.
* It is a possible attack.
*/
SSH_KNOWN_HOSTS_OTHER,
};
#ifndef MD5_DIGEST_LEN
#define MD5_DIGEST_LEN 16
#endif
/* errors */
enum ssh_error_types_e {
SSH_NO_ERROR=0,
SSH_REQUEST_DENIED,
SSH_FATAL,
SSH_EINTR
};
/* some types for keys */
enum ssh_keytypes_e{
SSH_KEYTYPE_UNKNOWN=0,
SSH_KEYTYPE_DSS=1,
SSH_KEYTYPE_RSA,
SSH_KEYTYPE_RSA1,
SSH_KEYTYPE_ECDSA,
SSH_KEYTYPE_ED25519,
SSH_KEYTYPE_DSS_CERT01,
SSH_KEYTYPE_RSA_CERT01
};
enum ssh_keycmp_e {
SSH_KEY_CMP_PUBLIC = 0,
SSH_KEY_CMP_PRIVATE
};
#define SSH_ADDRSTRLEN 46
struct ssh_knownhosts_entry {
char *hostname;
char *unparsed;
ssh_key publickey;
char *comment;
};
/* Error return codes */
#define SSH_OK 0 /* No error */
#define SSH_ERROR -1 /* Error of some kind */
#define SSH_AGAIN -2 /* The nonblocking call must be repeated */
#define SSH_EOF -127 /* We have already a eof */
/**
* @addtogroup libssh_log
*
* @{
*/
enum {
/** No logging at all
*/
SSH_LOG_NOLOG=0,
/** Only warnings
*/
SSH_LOG_WARNING,
/** High level protocol information
*/
SSH_LOG_PROTOCOL,
/** Lower level protocol infomations, packet level
*/
SSH_LOG_PACKET,
/** Every function path
*/
SSH_LOG_FUNCTIONS
};
/** @} */
#define SSH_LOG_RARE SSH_LOG_WARNING
/**
* @name Logging levels
*
* @brief Debug levels for logging.
* @{
*/
/** No logging at all */
#define SSH_LOG_NONE 0
/** Show only warnings */
#define SSH_LOG_WARN 1
/** Get some information what's going on */
#define SSH_LOG_INFO 2
/** Get detailed debuging information **/
#define SSH_LOG_DEBUG 3
/** Get trace output, packet information, ... */
#define SSH_LOG_TRACE 4
/** @} */
enum ssh_options_e {
SSH_OPTIONS_HOST,
SSH_OPTIONS_PORT,
SSH_OPTIONS_PORT_STR,
SSH_OPTIONS_FD,
SSH_OPTIONS_USER,
SSH_OPTIONS_SSH_DIR,
SSH_OPTIONS_IDENTITY,
SSH_OPTIONS_ADD_IDENTITY,
SSH_OPTIONS_KNOWNHOSTS,
SSH_OPTIONS_TIMEOUT,
SSH_OPTIONS_TIMEOUT_USEC,
SSH_OPTIONS_SSH1,
SSH_OPTIONS_SSH2,
SSH_OPTIONS_LOG_VERBOSITY,
SSH_OPTIONS_LOG_VERBOSITY_STR,
SSH_OPTIONS_CIPHERS_C_S,
SSH_OPTIONS_CIPHERS_S_C,
SSH_OPTIONS_COMPRESSION_C_S,
SSH_OPTIONS_COMPRESSION_S_C,
SSH_OPTIONS_PROXYCOMMAND,
SSH_OPTIONS_BINDADDR,
SSH_OPTIONS_STRICTHOSTKEYCHECK,
SSH_OPTIONS_COMPRESSION,
SSH_OPTIONS_COMPRESSION_LEVEL,
SSH_OPTIONS_KEY_EXCHANGE,
SSH_OPTIONS_HOSTKEYS,
SSH_OPTIONS_GSSAPI_SERVER_IDENTITY,
SSH_OPTIONS_GSSAPI_CLIENT_IDENTITY,
SSH_OPTIONS_GSSAPI_DELEGATE_CREDENTIALS,
SSH_OPTIONS_HMAC_C_S,
SSH_OPTIONS_HMAC_S_C,
SSH_OPTIONS_PASSWORD_AUTH,
SSH_OPTIONS_PUBKEY_AUTH,
SSH_OPTIONS_KBDINT_AUTH,
SSH_OPTIONS_GSSAPI_AUTH,
SSH_OPTIONS_GLOBAL_KNOWNHOSTS,
SSH_OPTIONS_NODELAY,
SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
};
enum {
/** Code is going to write/create remote files */
SSH_SCP_WRITE,
/** Code is going to read remote files */
SSH_SCP_READ,
SSH_SCP_RECURSIVE=0x10
};
enum ssh_scp_request_types {
/** A new directory is going to be pulled */
SSH_SCP_REQUEST_NEWDIR=1,
/** A new file is going to be pulled */
SSH_SCP_REQUEST_NEWFILE,
/** End of requests */
SSH_SCP_REQUEST_EOF,
/** End of directory */
SSH_SCP_REQUEST_ENDDIR,
/** Warning received */
SSH_SCP_REQUEST_WARNING
};
enum ssh_connector_flags_e {
/** Only the standard stream of the channel */
SSH_CONNECTOR_STDOUT = 1,
/** Only the exception stream of the channel */
SSH_CONNECTOR_STDERR = 2,
/** Merge both standard and exception streams */
SSH_CONNECTOR_BOTH = 3
};
LIBSSH_API int ssh_blocking_flush(ssh_session session, int timeout);
LIBSSH_API ssh_channel ssh_channel_accept_x11(ssh_channel channel, int timeout_ms);
LIBSSH_API int ssh_channel_change_pty_size(ssh_channel channel,int cols,int rows);
LIBSSH_API int ssh_channel_close(ssh_channel channel);
LIBSSH_API void ssh_channel_free(ssh_channel channel);
LIBSSH_API int ssh_channel_get_exit_status(ssh_channel channel);
LIBSSH_API ssh_session ssh_channel_get_session(ssh_channel channel);
LIBSSH_API int ssh_channel_is_closed(ssh_channel channel);
LIBSSH_API int ssh_channel_is_eof(ssh_channel channel);
LIBSSH_API int ssh_channel_is_open(ssh_channel channel);
LIBSSH_API ssh_channel ssh_channel_new(ssh_session session);
LIBSSH_API int ssh_channel_open_auth_agent(ssh_channel channel);
LIBSSH_API int ssh_channel_open_forward(ssh_channel channel, const char *remotehost,
int remoteport, const char *sourcehost, int localport);
LIBSSH_API int ssh_channel_open_session(ssh_channel channel);
LIBSSH_API int ssh_channel_open_x11(ssh_channel channel, const char *orig_addr, int orig_port);
LIBSSH_API int ssh_channel_poll(ssh_channel channel, int is_stderr);
LIBSSH_API int ssh_channel_poll_timeout(ssh_channel channel, int timeout, int is_stderr);
LIBSSH_API int ssh_channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr);
LIBSSH_API int ssh_channel_read_timeout(ssh_channel channel, void *dest, uint32_t count, int is_stderr, int timeout_ms);
LIBSSH_API int ssh_channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count,
int is_stderr);
LIBSSH_API int ssh_channel_request_env(ssh_channel channel, const char *name, const char *value);
LIBSSH_API int ssh_channel_request_exec(ssh_channel channel, const char *cmd);
LIBSSH_API int ssh_channel_request_pty(ssh_channel channel);
LIBSSH_API int ssh_channel_request_pty_size(ssh_channel channel, const char *term,
int cols, int rows);
LIBSSH_API int ssh_channel_request_shell(ssh_channel channel);
LIBSSH_API int ssh_channel_request_send_signal(ssh_channel channel, const char *signum);
LIBSSH_API int ssh_channel_request_send_break(ssh_channel channel, uint32_t length);
LIBSSH_API int ssh_channel_request_sftp(ssh_channel channel);
LIBSSH_API int ssh_channel_request_subsystem(ssh_channel channel, const char *subsystem);
LIBSSH_API int ssh_channel_request_x11(ssh_channel channel, int single_connection, const char *protocol,
const char *cookie, int screen_number);
LIBSSH_API int ssh_channel_request_auth_agent(ssh_channel channel);
LIBSSH_API int ssh_channel_send_eof(ssh_channel channel);
LIBSSH_API int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct
timeval * timeout);
LIBSSH_API void ssh_channel_set_blocking(ssh_channel channel, int blocking);
LIBSSH_API void ssh_channel_set_counter(ssh_channel channel,
ssh_counter counter);
LIBSSH_API int ssh_channel_write(ssh_channel channel, const void *data, uint32_t len);
LIBSSH_API int ssh_channel_write_stderr(ssh_channel channel,
const void *data,
uint32_t len);
LIBSSH_API uint32_t ssh_channel_window_size(ssh_channel channel);
LIBSSH_API char *ssh_basename (const char *path);
LIBSSH_API void ssh_clean_pubkey_hash(unsigned char **hash);
LIBSSH_API int ssh_connect(ssh_session session);
LIBSSH_API ssh_connector ssh_connector_new(ssh_session session);
LIBSSH_API void ssh_connector_free(ssh_connector connector);
LIBSSH_API int ssh_connector_set_in_channel(ssh_connector connector,
ssh_channel channel,
enum ssh_connector_flags_e flags);
LIBSSH_API int ssh_connector_set_out_channel(ssh_connector connector,
ssh_channel channel,
enum ssh_connector_flags_e flags);
LIBSSH_API void ssh_connector_set_in_fd(ssh_connector connector, socket_t fd);
LIBSSH_API void ssh_connector_set_out_fd(ssh_connector connector, socket_t fd);
LIBSSH_API const char *ssh_copyright(void);
LIBSSH_API void ssh_disconnect(ssh_session session);
LIBSSH_API char *ssh_dirname (const char *path);
LIBSSH_API int ssh_finalize(void);
/* REVERSE PORT FORWARDING */
LIBSSH_API ssh_channel ssh_channel_accept_forward(ssh_session session,
int timeout_ms,
int *destination_port);
LIBSSH_API int ssh_channel_cancel_forward(ssh_session session,
const char *address,
int port);
LIBSSH_API int ssh_channel_listen_forward(ssh_session session,
const char *address,
int port,
int *bound_port);
LIBSSH_API void ssh_free(ssh_session session);
LIBSSH_API const char *ssh_get_disconnect_message(ssh_session session);
LIBSSH_API const char *ssh_get_error(void *error);
LIBSSH_API int ssh_get_error_code(void *error);
LIBSSH_API socket_t ssh_get_fd(ssh_session session);
LIBSSH_API char *ssh_get_hexa(const unsigned char *what, size_t len);
LIBSSH_API char *ssh_get_issue_banner(ssh_session session);
LIBSSH_API int ssh_get_openssh_version(ssh_session session);
LIBSSH_API int ssh_get_server_publickey(ssh_session session, ssh_key *key);
enum ssh_publickey_hash_type {
SSH_PUBLICKEY_HASH_SHA1,
SSH_PUBLICKEY_HASH_MD5,
SSH_PUBLICKEY_HASH_SHA256
};
LIBSSH_API int ssh_get_publickey_hash(const ssh_key key,
enum ssh_publickey_hash_type type,
unsigned char **hash,
size_t *hlen);
/* DEPRECATED FUNCTIONS */
SSH_DEPRECATED LIBSSH_API int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash);
SSH_DEPRECATED LIBSSH_API ssh_channel ssh_forward_accept(ssh_session session, int timeout_ms);
SSH_DEPRECATED LIBSSH_API int ssh_forward_cancel(ssh_session session, const char *address, int port);
SSH_DEPRECATED LIBSSH_API int ssh_forward_listen(ssh_session session, const char *address, int port, int *bound_port);
SSH_DEPRECATED LIBSSH_API int ssh_get_publickey(ssh_session session, ssh_key *key);
LIBSSH_API int ssh_get_random(void *where,int len,int strong);
LIBSSH_API int ssh_get_version(ssh_session session);
LIBSSH_API int ssh_get_status(ssh_session session);
LIBSSH_API int ssh_get_poll_flags(ssh_session session);
LIBSSH_API int ssh_init(void);
LIBSSH_API int ssh_is_blocking(ssh_session session);
LIBSSH_API int ssh_is_connected(ssh_session session);
LIBSSH_API int ssh_is_server_known(ssh_session session);
/* KNOWN HOSTS */
LIBSSH_API void ssh_knownhosts_entry_free(struct ssh_knownhosts_entry *entry);
#define SSH_KNOWNHOSTS_ENTRY_FREE(e) do { \
if ((e) != NULL) { \
ssh_knownhosts_entry_free(e); \
e = NULL; \
} \
} while(0)
LIBSSH_API int ssh_known_hosts_parse_line(const char *host,
const char *line,
struct ssh_knownhosts_entry **entry);
LIBSSH_API enum ssh_known_hosts_e ssh_session_has_known_hosts_entry(ssh_session session);
LIBSSH_API int ssh_session_export_known_hosts_entry(ssh_session session,
char **pentry_string);
LIBSSH_API int ssh_session_update_known_hosts(ssh_session session);
LIBSSH_API enum ssh_known_hosts_e
ssh_session_get_known_hosts_entry(ssh_session session,
struct ssh_knownhosts_entry **pentry);
LIBSSH_API enum ssh_known_hosts_e ssh_session_is_known_server(ssh_session session);
/* LOGGING */
LIBSSH_API int ssh_set_log_level(int level);
LIBSSH_API int ssh_get_log_level(void);
LIBSSH_API void *ssh_get_log_userdata(void);
LIBSSH_API int ssh_set_log_userdata(void *data);
LIBSSH_API void _ssh_log(int verbosity,
const char *function,
const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
/* legacy */
SSH_DEPRECATED LIBSSH_API void ssh_log(ssh_session session,
int prioriry,
const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
LIBSSH_API ssh_channel ssh_message_channel_request_open_reply_accept(ssh_message msg);
LIBSSH_API int ssh_message_channel_request_reply_success(ssh_message msg);
LIBSSH_API void ssh_message_free(ssh_message msg);
LIBSSH_API ssh_message ssh_message_get(ssh_session session);
LIBSSH_API int ssh_message_subtype(ssh_message msg);
LIBSSH_API int ssh_message_type(ssh_message msg);
LIBSSH_API int ssh_mkdir (const char *pathname, mode_t mode);
LIBSSH_API ssh_session ssh_new(void);
LIBSSH_API int ssh_options_copy(ssh_session src, ssh_session *dest);
LIBSSH_API int ssh_options_getopt(ssh_session session, int *argcptr, char **argv);
LIBSSH_API int ssh_options_parse_config(ssh_session session, const char *filename);
LIBSSH_API int ssh_options_set(ssh_session session, enum ssh_options_e type,
const void *value);
LIBSSH_API int ssh_options_get(ssh_session session, enum ssh_options_e type,
char **value);
LIBSSH_API int ssh_options_get_port(ssh_session session, unsigned int * port_target);
LIBSSH_API int ssh_pcap_file_close(ssh_pcap_file pcap);
LIBSSH_API void ssh_pcap_file_free(ssh_pcap_file pcap);
LIBSSH_API ssh_pcap_file ssh_pcap_file_new(void);
LIBSSH_API int ssh_pcap_file_open(ssh_pcap_file pcap, const char *filename);
/**
* @brief SSH authentication callback.
*
* @param prompt Prompt to be displayed.
* @param buf Buffer to save the password. You should null-terminate it.
* @param len Length of the buffer.
* @param echo Enable or disable the echo of what you type.
* @param verify Should the password be verified?
* @param userdata Userdata to be passed to the callback function. Useful
* for GUI applications.
*
* @return 0 on success, < 0 on error.
*/
typedef int (*ssh_auth_callback) (const char *prompt, char *buf, size_t len,
int echo, int verify, void *userdata);
LIBSSH_API ssh_key ssh_key_new(void);
#define SSH_KEY_FREE(x) \
do { if ((x) != NULL) { ssh_key_free(x); x = NULL; } } while(0)
LIBSSH_API void ssh_key_free (ssh_key key);
LIBSSH_API enum ssh_keytypes_e ssh_key_type(const ssh_key key);
LIBSSH_API const char *ssh_key_type_to_char(enum ssh_keytypes_e type);
LIBSSH_API enum ssh_keytypes_e ssh_key_type_from_name(const char *name);
LIBSSH_API int ssh_key_is_public(const ssh_key k);
LIBSSH_API int ssh_key_is_private(const ssh_key k);
LIBSSH_API int ssh_key_cmp(const ssh_key k1,
const ssh_key k2,
enum ssh_keycmp_e what);
LIBSSH_API int ssh_pki_generate(enum ssh_keytypes_e type, int parameter,
ssh_key *pkey);
LIBSSH_API int ssh_pki_import_privkey_base64(const char *b64_key,
const char *passphrase,
ssh_auth_callback auth_fn,
void *auth_data,
ssh_key *pkey);
LIBSSH_API int ssh_pki_export_privkey_base64(const ssh_key privkey,
const char *passphrase,
ssh_auth_callback auth_fn,
void *auth_data,
char **b64_key);
LIBSSH_API int ssh_pki_import_privkey_file(const char *filename,
const char *passphrase,
ssh_auth_callback auth_fn,
void *auth_data,
ssh_key *pkey);
LIBSSH_API int ssh_pki_export_privkey_file(const ssh_key privkey,
const char *passphrase,
ssh_auth_callback auth_fn,
void *auth_data,
const char *filename);
LIBSSH_API int ssh_pki_copy_cert_to_privkey(const ssh_key cert_key,
ssh_key privkey);
LIBSSH_API int ssh_pki_import_pubkey_base64(const char *b64_key,
enum ssh_keytypes_e type,
ssh_key *pkey);
LIBSSH_API int ssh_pki_import_pubkey_file(const char *filename,
ssh_key *pkey);
LIBSSH_API int ssh_pki_import_cert_base64(const char *b64_cert,
enum ssh_keytypes_e type,
ssh_key *pkey);
LIBSSH_API int ssh_pki_import_cert_file(const char *filename,
ssh_key *pkey);
LIBSSH_API int ssh_pki_export_privkey_to_pubkey(const ssh_key privkey,
ssh_key *pkey);
LIBSSH_API int ssh_pki_export_pubkey_base64(const ssh_key key,
char **b64_key);
LIBSSH_API int ssh_pki_export_pubkey_file(const ssh_key key,
const char *filename);
LIBSSH_API const char *ssh_pki_key_ecdsa_name(const ssh_key key);
LIBSSH_API char *ssh_get_fingerprint_hash(enum ssh_publickey_hash_type type,
unsigned char *hash,
size_t len);
LIBSSH_API void ssh_print_hash(enum ssh_publickey_hash_type type, unsigned char *hash, size_t len);
LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len);
LIBSSH_API int ssh_send_ignore (ssh_session session, const char *data);
LIBSSH_API int ssh_send_debug (ssh_session session, const char *message, int always_display);
LIBSSH_API void ssh_gssapi_set_creds(ssh_session session, const ssh_gssapi_creds creds);
LIBSSH_API int ssh_scp_accept_request(ssh_scp scp);
LIBSSH_API int ssh_scp_close(ssh_scp scp);
LIBSSH_API int ssh_scp_deny_request(ssh_scp scp, const char *reason);
LIBSSH_API void ssh_scp_free(ssh_scp scp);
LIBSSH_API int ssh_scp_init(ssh_scp scp);
LIBSSH_API int ssh_scp_leave_directory(ssh_scp scp);
LIBSSH_API ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location);
LIBSSH_API int ssh_scp_pull_request(ssh_scp scp);
LIBSSH_API int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode);
LIBSSH_API int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int perms);
LIBSSH_API int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size, int perms);
LIBSSH_API int ssh_scp_read(ssh_scp scp, void *buffer, size_t size);
LIBSSH_API const char *ssh_scp_request_get_filename(ssh_scp scp);
LIBSSH_API int ssh_scp_request_get_permissions(ssh_scp scp);
LIBSSH_API size_t ssh_scp_request_get_size(ssh_scp scp);
LIBSSH_API uint64_t ssh_scp_request_get_size64(ssh_scp scp);
LIBSSH_API const char *ssh_scp_request_get_warning(ssh_scp scp);
LIBSSH_API int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len);
LIBSSH_API int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
fd_set *readfds, struct timeval *timeout);
LIBSSH_API int ssh_service_request(ssh_session session, const char *service);
LIBSSH_API int ssh_set_agent_channel(ssh_session session, ssh_channel channel);
LIBSSH_API int ssh_set_agent_socket(ssh_session session, socket_t fd);
LIBSSH_API void ssh_set_blocking(ssh_session session, int blocking);
LIBSSH_API void ssh_set_counters(ssh_session session, ssh_counter scounter,
ssh_counter rcounter);
LIBSSH_API void ssh_set_fd_except(ssh_session session);
LIBSSH_API void ssh_set_fd_toread(ssh_session session);
LIBSSH_API void ssh_set_fd_towrite(ssh_session session);
LIBSSH_API void ssh_silent_disconnect(ssh_session session);
LIBSSH_API int ssh_set_pcap_file(ssh_session session, ssh_pcap_file pcapfile);
/* USERAUTH */
LIBSSH_API int ssh_userauth_none(ssh_session session, const char *username);
LIBSSH_API int ssh_userauth_list(ssh_session session, const char *username);
LIBSSH_API int ssh_userauth_try_publickey(ssh_session session,
const char *username,
const ssh_key pubkey);
LIBSSH_API int ssh_userauth_publickey(ssh_session session,
const char *username,
const ssh_key privkey);
#ifndef _WIN32
LIBSSH_API int ssh_userauth_agent(ssh_session session,
const char *username);
#endif
LIBSSH_API int ssh_userauth_publickey_auto(ssh_session session,
const char *username,
const char *passphrase);
LIBSSH_API int ssh_userauth_password(ssh_session session,
const char *username,
const char *password);
LIBSSH_API int ssh_userauth_kbdint(ssh_session session, const char *user, const char *submethods);
LIBSSH_API const char *ssh_userauth_kbdint_getinstruction(ssh_session session);
LIBSSH_API const char *ssh_userauth_kbdint_getname(ssh_session session);
LIBSSH_API int ssh_userauth_kbdint_getnprompts(ssh_session session);
LIBSSH_API const char *ssh_userauth_kbdint_getprompt(ssh_session session, unsigned int i, char *echo);
LIBSSH_API int ssh_userauth_kbdint_getnanswers(ssh_session session);
LIBSSH_API const char *ssh_userauth_kbdint_getanswer(ssh_session session, unsigned int i);
LIBSSH_API int ssh_userauth_kbdint_setanswer(ssh_session session, unsigned int i,
const char *answer);
LIBSSH_API int ssh_userauth_gssapi(ssh_session session);
LIBSSH_API const char *ssh_version(int req_version);
LIBSSH_API int ssh_write_knownhost(ssh_session session);
LIBSSH_API char *ssh_dump_knownhost(ssh_session session);
LIBSSH_API void ssh_string_burn(ssh_string str);
LIBSSH_API ssh_string ssh_string_copy(ssh_string str);
LIBSSH_API void *ssh_string_data(ssh_string str);
LIBSSH_API int ssh_string_fill(ssh_string str, const void *data, size_t len);
#define SSH_STRING_FREE(x) \
do { if ((x) != NULL) { ssh_string_free(x); x = NULL; } } while(0)
LIBSSH_API void ssh_string_free(ssh_string str);
LIBSSH_API ssh_string ssh_string_from_char(const char *what);
LIBSSH_API size_t ssh_string_len(ssh_string str);
LIBSSH_API ssh_string ssh_string_new(size_t size);
LIBSSH_API const char *ssh_string_get_char(ssh_string str);
LIBSSH_API char *ssh_string_to_char(ssh_string str);
#define SSH_STRING_FREE_CHAR(x) \
do { if ((x) != NULL) { ssh_string_free_char(x); x = NULL; } } while(0)
LIBSSH_API void ssh_string_free_char(char *s);
LIBSSH_API int ssh_getpass(const char *prompt, char *buf, size_t len, int echo,
int verify);
typedef int (*ssh_event_callback)(socket_t fd, int revents, void *userdata);
LIBSSH_API ssh_event ssh_event_new(void);
LIBSSH_API int ssh_event_add_fd(ssh_event event, socket_t fd, short events,
ssh_event_callback cb, void *userdata);
LIBSSH_API int ssh_event_add_session(ssh_event event, ssh_session session);
LIBSSH_API int ssh_event_add_connector(ssh_event event, ssh_connector connector);
LIBSSH_API int ssh_event_dopoll(ssh_event event, int timeout);
LIBSSH_API int ssh_event_remove_fd(ssh_event event, socket_t fd);
LIBSSH_API int ssh_event_remove_session(ssh_event event, ssh_session session);
LIBSSH_API int ssh_event_remove_connector(ssh_event event, ssh_connector connector);
LIBSSH_API void ssh_event_free(ssh_event event);
LIBSSH_API const char* ssh_get_clientbanner(ssh_session session);
LIBSSH_API const char* ssh_get_serverbanner(ssh_session session);
LIBSSH_API const char* ssh_get_kex_algo(ssh_session session);
LIBSSH_API const char* ssh_get_cipher_in(ssh_session session);
LIBSSH_API const char* ssh_get_cipher_out(ssh_session session);
LIBSSH_API const char* ssh_get_hmac_in(ssh_session session);
LIBSSH_API const char* ssh_get_hmac_out(ssh_session session);
LIBSSH_API ssh_buffer ssh_buffer_new(void);
LIBSSH_API void ssh_buffer_free(ssh_buffer buffer);
#define SSH_BUFFER_FREE(x) \
do { if ((x) != NULL) { ssh_buffer_free(x); x = NULL; } } while(0)
LIBSSH_API int ssh_buffer_reinit(ssh_buffer buffer);
LIBSSH_API int ssh_buffer_add_data(ssh_buffer buffer, const void *data, uint32_t len);
LIBSSH_API uint32_t ssh_buffer_get_data(ssh_buffer buffer, void *data, uint32_t requestedlen);
LIBSSH_API void *ssh_buffer_get(ssh_buffer buffer);
LIBSSH_API uint32_t ssh_buffer_get_len(ssh_buffer buffer);
#ifndef LIBSSH_LEGACY_0_4
#include "libssh/legacy.h"
#endif
#ifdef __cplusplus
}
#endif
#endif /* _LIBSSH_H */

@ -0,0 +1,369 @@
/* Public include file for server support */
/*
* This file is part of the SSH Library
*
* Copyright (c) 2003-2008 by Aris Adamantiadis
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @defgroup libssh_server The libssh server API
*
* @{
*/
#ifndef SERVER_H
#define SERVER_H
#include "libssh/libssh.h"
#define SERVERBANNER CLIENTBANNER
#ifdef __cplusplus
extern "C" {
#endif
enum ssh_bind_options_e {
SSH_BIND_OPTIONS_BINDADDR,
SSH_BIND_OPTIONS_BINDPORT,
SSH_BIND_OPTIONS_BINDPORT_STR,
SSH_BIND_OPTIONS_HOSTKEY,
SSH_BIND_OPTIONS_DSAKEY,
SSH_BIND_OPTIONS_RSAKEY,
SSH_BIND_OPTIONS_BANNER,
SSH_BIND_OPTIONS_LOG_VERBOSITY,
SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
SSH_BIND_OPTIONS_ECDSAKEY,
SSH_BIND_OPTIONS_IMPORT_KEY
};
typedef struct ssh_bind_struct* ssh_bind;
/* Callback functions */
/**
* @brief Incoming connection callback. This callback is called when a ssh_bind
* has a new incoming connection.
* @param sshbind Current sshbind session handler
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_bind_incoming_connection_callback) (ssh_bind sshbind,
void *userdata);
/**
* @brief These are the callbacks exported by the ssh_bind structure.
*
* They are called by the server module when events appear on the network.
*/
struct ssh_bind_callbacks_struct {
/** DON'T SET THIS use ssh_callbacks_init() instead. */
size_t size;
/** A new connection is available. */
ssh_bind_incoming_connection_callback incoming_connection;
};
typedef struct ssh_bind_callbacks_struct *ssh_bind_callbacks;
/**
* @brief Creates a new SSH server bind.
*
* @return A newly allocated ssh_bind session pointer.
*/
LIBSSH_API ssh_bind ssh_bind_new(void);
LIBSSH_API int ssh_bind_options_set(ssh_bind sshbind,
enum ssh_bind_options_e type, const void *value);
/**
* @brief Start listening to the socket.
*
* @param ssh_bind_o The ssh server bind to use.
*
* @return 0 on success, < 0 on error.
*/
LIBSSH_API int ssh_bind_listen(ssh_bind ssh_bind_o);
/**
* @brief Set the callback for this bind.
*
* @param[in] sshbind The bind to set the callback on.
*
* @param[in] callbacks An already set up ssh_bind_callbacks instance.
*
* @param[in] userdata A pointer to private data to pass to the callbacks.
*
* @return SSH_OK on success, SSH_ERROR if an error occured.
*
* @code
* struct ssh_callbacks_struct cb = {
* .userdata = data,
* .auth_function = my_auth_function
* };
* ssh_callbacks_init(&cb);
* ssh_bind_set_callbacks(session, &cb);
* @endcode
*/
LIBSSH_API int ssh_bind_set_callbacks(ssh_bind sshbind, ssh_bind_callbacks callbacks,
void *userdata);
/**
* @brief Set the session to blocking/nonblocking mode.
*
* @param ssh_bind_o The ssh server bind to use.
*
* @param blocking Zero for nonblocking mode.
*/
LIBSSH_API void ssh_bind_set_blocking(ssh_bind ssh_bind_o, int blocking);
/**
* @brief Recover the file descriptor from the session.
*
* @param ssh_bind_o The ssh server bind to get the fd from.
*
* @return The file descriptor.
*/
LIBSSH_API socket_t ssh_bind_get_fd(ssh_bind ssh_bind_o);
/**
* @brief Set the file descriptor for a session.
*
* @param ssh_bind_o The ssh server bind to set the fd.
*
* @param fd The file descriptssh_bind B
*/
LIBSSH_API void ssh_bind_set_fd(ssh_bind ssh_bind_o, socket_t fd);
/**
* @brief Allow the file descriptor to accept new sessions.
*
* @param ssh_bind_o The ssh server bind to use.
*/
LIBSSH_API void ssh_bind_fd_toaccept(ssh_bind ssh_bind_o);
/**
* @brief Accept an incoming ssh connection and initialize the session.
*
* @param ssh_bind_o The ssh server bind to accept a connection.
* @param session A preallocated ssh session
* @see ssh_new
* @return SSH_OK when a connection is established
*/
LIBSSH_API int ssh_bind_accept(ssh_bind ssh_bind_o, ssh_session session);
/**
* @brief Accept an incoming ssh connection on the given file descriptor
* and initialize the session.
*
* @param ssh_bind_o The ssh server bind to accept a connection.
* @param session A preallocated ssh session
* @param fd A file descriptor of an already established TCP
* inbound connection
* @see ssh_new
* @see ssh_bind_accept
* @return SSH_OK when a connection is established
*/
LIBSSH_API int ssh_bind_accept_fd(ssh_bind ssh_bind_o, ssh_session session,
socket_t fd);
LIBSSH_API ssh_gssapi_creds ssh_gssapi_get_creds(ssh_session session);
/**
* @brief Handles the key exchange and set up encryption
*
* @param session A connected ssh session
* @see ssh_bind_accept
* @return SSH_OK if the key exchange was successful
*/
LIBSSH_API int ssh_handle_key_exchange(ssh_session session);
/**
* @brief Initialize the set of key exchange, hostkey, ciphers, MACs, and
* compression algorithms for the given ssh_session.
*
* The selection of algorithms and keys used are determined by the
* options that are currently set in the given ssh_session structure.
* May only be called before the initial key exchange has begun.
*
* @param session The session structure to initialize.
*
* @see ssh_handle_key_exchange
* @see ssh_options_set
*
* @return SSH_OK if initialization succeeds.
*/
LIBSSH_API int ssh_server_init_kex(ssh_session session);
/**
* @brief Free a ssh servers bind.
*
* @param ssh_bind_o The ssh server bind to free.
*/
LIBSSH_API void ssh_bind_free(ssh_bind ssh_bind_o);
/**
* @brief Set the acceptable authentication methods to be sent to the client.
*
*
* @param[in] session The server session
*
* @param[in] auth_methods The authentication methods we will support, which
* can be bitwise-or'd.
*
* Supported methods are:
*
* SSH_AUTH_METHOD_PASSWORD
* SSH_AUTH_METHOD_PUBLICKEY
* SSH_AUTH_METHOD_HOSTBASED
* SSH_AUTH_METHOD_INTERACTIVE
* SSH_AUTH_METHOD_GSSAPI_MIC
*/
LIBSSH_API void ssh_set_auth_methods(ssh_session session, int auth_methods);
/**********************************************************
* SERVER MESSAGING
**********************************************************/
/**
* @brief Reply with a standard reject message.
*
* Use this function if you don't know what to respond or if you want to reject
* a request.
*
* @param[in] msg The message to use for the reply.
*
* @return 0 on success, -1 on error.
*
* @see ssh_message_get()
*/
LIBSSH_API int ssh_message_reply_default(ssh_message msg);
/**
* @brief Get the name of the authenticated user.
*
* @param[in] msg The message to get the username from.
*
* @return The username or NULL if an error occured.
*
* @see ssh_message_get()
* @see ssh_message_type()
*/
LIBSSH_API const char *ssh_message_auth_user(ssh_message msg);
/**
* @brief Get the password of the authenticated user.
*
* @param[in] msg The message to get the password from.
*
* @return The username or NULL if an error occured.
*
* @see ssh_message_get()
* @see ssh_message_type()
*/
LIBSSH_API const char *ssh_message_auth_password(ssh_message msg);
/**
* @brief Get the publickey of the authenticated user.
*
* If you need the key for later user you should duplicate it.
*
* @param[in] msg The message to get the public key from.
*
* @return The public key or NULL.
*
* @see ssh_key_dup()
* @see ssh_key_cmp()
* @see ssh_message_get()
* @see ssh_message_type()
*/
LIBSSH_API ssh_key ssh_message_auth_pubkey(ssh_message msg);
LIBSSH_API int ssh_message_auth_kbdint_is_response(ssh_message msg);
LIBSSH_API enum ssh_publickey_state_e ssh_message_auth_publickey_state(ssh_message msg);
LIBSSH_API int ssh_message_auth_reply_success(ssh_message msg,int partial);
LIBSSH_API int ssh_message_auth_reply_pk_ok(ssh_message msg, ssh_string algo, ssh_string pubkey);
LIBSSH_API int ssh_message_auth_reply_pk_ok_simple(ssh_message msg);
LIBSSH_API int ssh_message_auth_set_methods(ssh_message msg, int methods);
LIBSSH_API int ssh_message_auth_interactive_request(ssh_message msg,
const char *name, const char *instruction,
unsigned int num_prompts, const char **prompts, char *echo);
LIBSSH_API int ssh_message_service_reply_success(ssh_message msg);
LIBSSH_API const char *ssh_message_service_service(ssh_message msg);
LIBSSH_API int ssh_message_global_request_reply_success(ssh_message msg,
uint16_t bound_port);
LIBSSH_API void ssh_set_message_callback(ssh_session session,
int(*ssh_bind_message_callback)(ssh_session session, ssh_message msg, void *data),
void *data);
LIBSSH_API int ssh_execute_message_callbacks(ssh_session session);
LIBSSH_API const char *ssh_message_channel_request_open_originator(ssh_message msg);
LIBSSH_API int ssh_message_channel_request_open_originator_port(ssh_message msg);
LIBSSH_API const char *ssh_message_channel_request_open_destination(ssh_message msg);
LIBSSH_API int ssh_message_channel_request_open_destination_port(ssh_message msg);
LIBSSH_API ssh_channel ssh_message_channel_request_channel(ssh_message msg);
LIBSSH_API const char *ssh_message_channel_request_pty_term(ssh_message msg);
LIBSSH_API int ssh_message_channel_request_pty_width(ssh_message msg);
LIBSSH_API int ssh_message_channel_request_pty_height(ssh_message msg);
LIBSSH_API int ssh_message_channel_request_pty_pxwidth(ssh_message msg);
LIBSSH_API int ssh_message_channel_request_pty_pxheight(ssh_message msg);
LIBSSH_API const char *ssh_message_channel_request_env_name(ssh_message msg);
LIBSSH_API const char *ssh_message_channel_request_env_value(ssh_message msg);
LIBSSH_API const char *ssh_message_channel_request_command(ssh_message msg);
LIBSSH_API const char *ssh_message_channel_request_subsystem(ssh_message msg);
LIBSSH_API int ssh_message_channel_request_x11_single_connection(ssh_message msg);
LIBSSH_API const char *ssh_message_channel_request_x11_auth_protocol(ssh_message msg);
LIBSSH_API const char *ssh_message_channel_request_x11_auth_cookie(ssh_message msg);
LIBSSH_API int ssh_message_channel_request_x11_screen_number(ssh_message msg);
LIBSSH_API const char *ssh_message_global_request_address(ssh_message msg);
LIBSSH_API int ssh_message_global_request_port(ssh_message msg);
LIBSSH_API int ssh_channel_open_reverse_forward(ssh_channel channel, const char *remotehost,
int remoteport, const char *sourcehost, int localport);
LIBSSH_API int ssh_channel_open_x11(ssh_channel channel,
const char *orig_addr, int orig_port);
LIBSSH_API int ssh_channel_request_send_exit_status(ssh_channel channel,
int exit_status);
LIBSSH_API int ssh_channel_request_send_exit_signal(ssh_channel channel,
const char *signum,
int core,
const char *errmsg,
const char *lang);
LIBSSH_API int ssh_send_keepalive(ssh_session session);
/* deprecated functions */
SSH_DEPRECATED LIBSSH_API int ssh_accept(ssh_session session);
SSH_DEPRECATED LIBSSH_API int channel_write_stderr(ssh_channel channel,
const void *data, uint32_t len);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* SERVER_H */
/** @} */

File diff suppressed because it is too large Load Diff

@ -0,0 +1,81 @@
#ifndef __SSH2_H
#define __SSH2_H
#define SSH2_MSG_DISCONNECT 1
#define SSH2_MSG_IGNORE 2
#define SSH2_MSG_UNIMPLEMENTED 3
#define SSH2_MSG_DEBUG 4
#define SSH2_MSG_SERVICE_REQUEST 5
#define SSH2_MSG_SERVICE_ACCEPT 6
#define SSH2_MSG_EXT_INFO 7
#define SSH2_MSG_KEXINIT 20
#define SSH2_MSG_NEWKEYS 21
#define SSH2_MSG_KEXDH_INIT 30
#define SSH2_MSG_KEXDH_REPLY 31
#define SSH2_MSG_KEX_ECDH_INIT 30
#define SSH2_MSG_KEX_ECDH_REPLY 31
#define SSH2_MSG_ECMQV_INIT 30
#define SSH2_MSG_ECMQV_REPLY 31
#define SSH2_MSG_KEX_DH_GEX_REQUEST_OLD 30
#define SSH2_MSG_KEX_DH_GEX_GROUP 31
#define SSH2_MSG_KEX_DH_GEX_INIT 32
#define SSH2_MSG_KEX_DH_GEX_REPLY 33
#define SSH2_MSG_KEX_DH_GEX_REQUEST 34
#define SSH2_MSG_USERAUTH_REQUEST 50
#define SSH2_MSG_USERAUTH_FAILURE 51
#define SSH2_MSG_USERAUTH_SUCCESS 52
#define SSH2_MSG_USERAUTH_BANNER 53
#define SSH2_MSG_USERAUTH_PK_OK 60
#define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60
#define SSH2_MSG_USERAUTH_INFO_REQUEST 60
#define SSH2_MSG_USERAUTH_GSSAPI_RESPONSE 60
#define SSH2_MSG_USERAUTH_INFO_RESPONSE 61
#define SSH2_MSG_USERAUTH_GSSAPI_TOKEN 61
#define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE 63
#define SSH2_MSG_USERAUTH_GSSAPI_ERROR 64
#define SSH2_MSG_USERAUTH_GSSAPI_ERRTOK 65
#define SSH2_MSG_USERAUTH_GSSAPI_MIC 66
#define SSH2_MSG_GLOBAL_REQUEST 80
#define SSH2_MSG_REQUEST_SUCCESS 81
#define SSH2_MSG_REQUEST_FAILURE 82
#define SSH2_MSG_CHANNEL_OPEN 90
#define SSH2_MSG_CHANNEL_OPEN_CONFIRMATION 91
#define SSH2_MSG_CHANNEL_OPEN_FAILURE 92
#define SSH2_MSG_CHANNEL_WINDOW_ADJUST 93
#define SSH2_MSG_CHANNEL_DATA 94
#define SSH2_MSG_CHANNEL_EXTENDED_DATA 95
#define SSH2_MSG_CHANNEL_EOF 96
#define SSH2_MSG_CHANNEL_CLOSE 97
#define SSH2_MSG_CHANNEL_REQUEST 98
#define SSH2_MSG_CHANNEL_SUCCESS 99
#define SSH2_MSG_CHANNEL_FAILURE 100
#define SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1
#define SSH2_DISCONNECT_PROTOCOL_ERROR 2
#define SSH2_DISCONNECT_KEY_EXCHANGE_FAILED 3
#define SSH2_DISCONNECT_HOST_AUTHENTICATION_FAILED 4
#define SSH2_DISCONNECT_RESERVED 4
#define SSH2_DISCONNECT_MAC_ERROR 5
#define SSH2_DISCONNECT_COMPRESSION_ERROR 6
#define SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE 7
#define SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8
#define SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9
#define SSH2_DISCONNECT_CONNECTION_LOST 10
#define SSH2_DISCONNECT_BY_APPLICATION 11
#define SSH2_DISCONNECT_TOO_MANY_CONNECTIONS 12
#define SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER 13
#define SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14
#define SSH2_DISCONNECT_ILLEGAL_USER_NAME 15
#define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED 1
#define SSH2_OPEN_CONNECT_FAILED 2
#define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE 3
#define SSH2_OPEN_RESOURCE_SHORTAGE 4
#define SSH2_EXTENDED_DATA_STDERR 1
#endif

Binary file not shown.

@ -0,0 +1,23 @@
#include "version.h"
char* softversion_get()
{
return SOFT_VERSION;
}
char* softversion_date_get()
{
return SOFT_COMPILE_DATE;
}
char* hardware_version_get()
{
return HARDV_ERSION;
}
char* fpga_version_date_get()
{
return FPGA_VERSION;
}
Loading…
Cancel
Save