Fisrst commit:电力设备多状态量一体化智能在线监测装置主控代码;
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>© 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,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>© 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>© 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>© 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>© 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>© 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>© 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>© 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>© 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,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>© 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,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>© 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>© 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>© 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>© 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>© 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,3 @@
|
||||
local_src := $(patsubst $(SOURCE_DIR)/%,%,$(wildcard $(SOURCE_DIR)/$(subdirectory)/*.c))
|
||||
|
||||
$(eval $(call make-library,$(subdirectory)/liba_process.a,$(local_src)))
|
||||
@ -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, ¶m);
|
||||
|
||||
param.priority = 45;
|
||||
param.thread_name = "DAU_RECV";
|
||||
create_thread(_dau_udp_receive_handle, ¶m);
|
||||
|
||||
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>© 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>© 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, ¶m);
|
||||
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, ¶m);
|
||||
}
|
||||
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>© 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, ¶m);
|
||||
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 ****/
|
||||
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>© 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, ¶m);
|
||||
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, ¶m);
|
||||
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,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>© 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>© 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,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>© 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, ¶m);
|
||||
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>© 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>© 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>© 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…
Reference in New Issue