Compare commits

...

1 Commits

Author SHA1 Message Date
jacky_chang
7df000f08c support EC platform 2023-10-26 11:11:14 +08:00
36 changed files with 2883 additions and 5 deletions

View File

@@ -7,7 +7,8 @@ IMG_ID := "ucentral-client-build-env"
IMG_TAG := $(shell cat Dockerfile | sha1sum | awk '{print substr($$1,0,11);}')
CONTAINER_NAME := "ucentral_client_build_env"
.PHONY: all clean build-host-env build-final-deb build-ucentral-docker-img run-host-env run-ucentral-docker-img
.PHONY: all clean build-host-env build-final-deb build-ucentral-docker-img run-host-env run-ucentral-docker-img \
plat-ec plat-ec-clean
all: build-host-env build-ucentral-app build-ucentral-docker-img build-final-deb
@@ -80,6 +81,9 @@ build-final-deb: build-ucentral-docker-img
@echo
@echo "ucentral client deb pkg is available under ./output/ dir"
plat-ec:
src/ec-private/build.sh
clean:
docker container stop ${CONTAINER_NAME} > /dev/null 2>&1 || true;
docker container rm ${CONTAINER_NAME} > /dev/null 2>&1 || true;
@@ -96,3 +100,13 @@ clean:
rm -rf src/debian/shasta-ucentral-client* 2>/dev/null || true;
rm -rf src/debian/debhelper-build-stamp* 2>/dev/null || true;
rm -rf src/debian/files shasta_1.0_amd64.changes shasta_1.0_amd64.buildinfo 2>/dev/null || true;
plat-ec-clean:
rm -rf src/ec-private/cjson
rm -rf src/ec-private/curl
rm -rf src/ec-private/libwebsockets
rm -rf src/ec-private/openssl
rm -rf src/ec-private/openssl
rm -rf src/ec-private/ecapi/build
rm -rf src/ec-private/ucentral
rm -rf output

33
src/ec-private/README.md Executable file
View File

@@ -0,0 +1,33 @@
# Ucentral for EC
Ucentral solution for EC is made of the following parts:
* `ecapi`: a library to communicate with EC via SNMP
# Compiling
## EC Build for Target Device
First build the full EC image for your target device:
* `cd EC_VOB/project_build_environment/<target device>`
* `./make_all`
If this is successful, you can proceed to the next step.
## Build Environment
To successfully build required components the build environments variables must be prepared:
* `cd EC_VOB/project_build_environment/<target device>`
* `cd utils`
* `. build_env_init`
## Building All Components
Presumably you have checked out the [ols-ucentral-src]:
* `cd [ols-ucentral-src]`
* Run `make plat-ec`, which should successfully compile all components
## Creating EC Firmware with Ucentral
After building everything up:
* Check the `output` directory, it should contain all required binaries in appropriate subdirectories
* Copy over these directories to your `EC_VOB/project_build_environment/<target device>/user/thirdpty/ucentral`

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

141
src/ec-private/build.sh Executable file
View File

@@ -0,0 +1,141 @@
#!/bin/bash
UCENTRAL_DIR=${PWD}
EC_BUILD_DIR=${PWD}/src/ec-private
OUT_DIR=${UCENTRAL_DIR}/output
BIN_DIR=${OUT_DIR}/usr/sbin
LIB_DIR=${OUT_DIR}/lib
LIB_OPENSSL=openssl-1.1.1q
LIB_WEBSOCKETS=libwebsockets-4.1.4
LIB_CURL=curl-7.83.1
LIB_CJSON=cJSON-1.7.15
echo "+++++++++++++++++ check EC build environment +++++++++++++++++"
if [ ! "${PROJECT_NAME}" ] || [ ! "${SOURCE_PATH}" ]; then
echo "Error! Please source 'build_env_init' for your build environment."
exit
fi
cp -af ${UCENTRAL_DIR}/src/ucentral-client/* ${EC_BUILD_DIR}/ucentral-client
rm -rf ${OUT_DIR}
if [ ! -d output ]; then
mkdir -p ${BIN_DIR}
mkdir -p ${LIB_DIR}
fi
C_COMPILER="${TOOLCHAIN_PATH}/${CROSS_COMPILE}gcc ."
echo "+++++++++++++++++ openssl +++++++++++++++++"
cd ${EC_BUILD_DIR}
if [ ! -d openssl ]; then
tar -xf ./archive/${LIB_OPENSSL}.tar.gz
mv ${LIB_OPENSSL} openssl
fi
model_name=${D_MODEL_NAME}
if [ "$model_name" == 'ECS4130_AC5' ]; then
platform=linux-aarch64
elif [ "$model_name" == 'ECS4125_10P' ]; then
platform=linux-mips32
else
echo "Error! The model ${model_name} is not in the support lists, please check."
exit 1
fi
cd openssl
./Configure ${platform} --cross-compile-prefix=${CROSS_COMPILE} no-idea no-mdc2 no-rc5 no-ssl2 no-ssl3
make -j${nproc}
if [ "$?" -eq "0" ]; then
cp -af libssl.so.1.1 libcrypto.so.1.1 ${LIB_DIR}
fi
echo "+++++++++++++++++ libwebsockets +++++++++++++++++"
cd ${EC_BUILD_DIR}
if [ ! -d libwebsockets ]; then
tar -xf ./archive/${LIB_WEBSOCKETS}.tar.gz
mv ${LIB_WEBSOCKETS} libwebsockets
patch -s -N -p1 -d libwebsockets/lib < ./patch/libwebsockets/${LIB_WEBSOCKETS}.patch
fi
cd libwebsockets
cmake \
-DOPENSSL_ROOT_DIR=${EC_BUILD_DIR}/openssl \
-DCMAKE_C_COMPILER=${C_COMPILER}
make -j${nproc}
if [ "$?" -eq "0" ]; then
cp -af lib/libwebsockets.so.17 ${LIB_DIR}
fi
echo "+++++++++++++++++ curl +++++++++++++++++"
cd ${EC_BUILD_DIR}
if [ ! -d curl ]; then
tar -xf ./archive/${LIB_CURL}.tar.xz
mv ${LIB_CURL} curl
patch -s -N -p1 -d curl < ./patch/curl/${LIB_CURL}.patch
fi
cd curl
cmake -DCMAKE_C_COMPILER=${C_COMPILER} -DCMAKE_SHARED_LINKER_FLAGS=-L${EC_BUILD_DIR}/openssl
make
if [ "$?" -eq "0" ]; then
cp -af ./lib/libcurl.so ${LIB_DIR}
cp -af ./src/curl ${BIN_DIR}
fi
echo "+++++++++++++++++ cjson +++++++++++++++++"
cd ${EC_BUILD_DIR}
if [ ! -d cjson ]; then
tar -xf ./archive/${LIB_CJSON}.tar.gz
mv ${LIB_CJSON} cjson
fi
cd cjson
cmake -DCMAKE_C_COMPILER=${C_COMPILER}
make
if [ "$?" -eq "0" ]; then
cp -af ./libcjson.so.1.7.15 ${LIB_DIR}
cd ${LIB_DIR}
mv libcjson.so.1.7.15 libcjson.so.1
fi
echo "+++++++++++++++++ ecapi +++++++++++++++++"
cd ${EC_BUILD_DIR}/ecapi
mkdir ${EC_BUILD_DIR}/ecapi/build
cd ${EC_BUILD_DIR}/ecapi/build
cmake -DCMAKE_C_COMPILER=${C_COMPILER} ..
make
if [ "$?" -eq "0" ]; then
cp -af libecapi.so ${LIB_DIR}
fi
echo "+++++++++++++++++ ucentral-client +++++++++++++++++"
if [ ! -d ucentral ]; then
mkdir -p ${EC_BUILD_DIR}/ucentral
fi
cp -af ${UCENTRAL_DIR}/src/ucentral-client ${EC_BUILD_DIR}/ucentral/ucentral-client
cp -af ${EC_BUILD_DIR}/patch/ucentral/* ${EC_BUILD_DIR}/ucentral
mkdir -p ${EC_BUILD_DIR}/ucentral/build
cd ${EC_BUILD_DIR}/ucentral/build
cmake -DCMAKE_C_COMPILER=${C_COMPILER} ..
make
if [ "$?" -eq "0" ]; then
cp -af ucentral-client ${BIN_DIR}
fi
echo "+++++++++++++++++ Strip target binaries +++++++++++++++++"
${TOOLCHAIN_PATH}/${CROSS_COMPILE}strip ${BIN_DIR}/*
${TOOLCHAIN_PATH}/${CROSS_COMPILE}strip ${LIB_DIR}/*

View File

@@ -0,0 +1,31 @@
cmake_minimum_required(VERSION 2.6)
PROJECT(ecapi C)
ADD_DEFINITIONS(-Os -ggdb -Wall -Werror --std=gnu99 -Wmissing-declarations)
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
INCLUDE_DIRECTORIES($ENV{SOURCE_PATH}/sysinclude)
INCLUDE_DIRECTORIES($ENV{SOURCE_PATH}/sysinclude/mibconstants)
INCLUDE_DIRECTORIES($ENV{SOURCE_PATH}/sysinclude/oem/$ENV{PROJECT_NAME})
INCLUDE_DIRECTORIES($ENV{PROJECT_PATH}/user/thirdpty/lua/net-snmp-5.4.4/include)
INCLUDE_DIRECTORIES($ENV{PROJECT_PATH}/user/thirdpty/lua/net-snmp-5.4.4/agent/mibgroup)
#LINK_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src/snmp)
FIND_LIBRARY(netsnmp_library netsnmp $ENV{PROJECT_PATH}/user/thirdpty/lua/net-snmp-5.4.4/snmplib/.libs)
#INCLUDE (CheckSymbolExists)
#CHECK_SYMBOL_EXISTS(SYS_getrandom syscall.h getrandom)
if ($ENV{D_MODEL_NAME} STREQUAL ECS4130_AC5)
add_definitions(-DENDIANNESS_ADJUST)
endif()
INCLUDE(snmp/CMakeLists.txt)
INCLUDE(generic/CMakeLists.txt)
ADD_LIBRARY(ecapi SHARED ${LIB_SOURCES})
TARGET_LINK_LIBRARIES(ecapi ${netsnmp_library})

View File

@@ -0,0 +1,3 @@
list(APPEND LIB_SOURCES
${CMAKE_CURRENT_LIST_DIR}/api_print.c
)

View File

@@ -0,0 +1,27 @@
// #include <stdarg.h>
#include "api_print.h"
static bool debug_on = false;
void print_set_debug(bool on) {
debug_on = on;
}
bool print_is_debug(void) {
return debug_on;
}
/*
void print_debug(char *fmt, ...) {
if (print_is_debug()) {
va_list args; va_start(args, fmt);
vfprintf(stdout, fmt, args);
va_end(args);
}
}
void print_err(char *fmt, ...) {
va_list args; va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}*/

View File

@@ -0,0 +1,40 @@
#ifndef API_CONFIG_H
#define API_CONFIG_H
#include <stdbool.h>
#include <stdint.h>
typedef enum {
DPX_HALF = 0,
DPX_FULL,
} duplex_t;
typedef enum {
M_NONE = 1,
M_SFP_FORCED_1000 = 7,
M_SFP_FORCED_10G = 8,
} media_t;
typedef enum {
VL_NONE = 0,
VL_TAGGED,
VL_UNTAGGED,
VL_FORBIDDEN
} vlan_membership_t;
void *open_config_transaction();
void commit_config_transaction(void *tr);
void add_eth_speed(void *tr, uint16_t eth_num, uint32_t speed, duplex_t duplex);
void add_eth_media(void *tr, uint16_t eth_num, media_t media);
void add_l2_vlan(void *tr, uint16_t vlan_id,
uint16_t *tagged_members, // NULL terminated array / NULL if not required
uint16_t *un_tagged_members, // NULL terminated array / NULL if not required
uint16_t *forbidden_members, // NULL terminated array / NULL if not required
uint16_t *pvid_ports // NULL terminated array / NULL if not required
);
#endif

View File

@@ -0,0 +1,8 @@
#ifndef API_CONSTS_H
#define API_CONSTS_H
#define STATUS_SUCCESS 0
#define STATUS_ERROR 1
#define STATUS_TIMEOUT 2
#endif

View File

@@ -0,0 +1,15 @@
#ifndef API_DEVICEID_H
#define API_DEVICEID_H
#include <stdint.h>
#include "api_consts.h"
int dev_get_main_mac(char *mac, int mac_len);
int dev_get_serial(char *serial, int serial_len);
int dev_get_fw_version(char *fw, int fw_len);
int dev_get_uptime(uint32_t *up);
int dev_get_vlan_list(int *vlan_arr, int *num);
int dev_get_vlan_mask_len(int *len);
int dev_get_poe_port_num(int *num);
int dev_get_port_capabilities_val_len(int *len);
#endif

View File

@@ -0,0 +1,13 @@
#ifndef API_PRINT_H
#define API_PRINT_H
#include <stdio.h>
#include <stdbool.h>
void print_set_debug(bool on);
bool print_is_debug(void);
#define print_debug(...) if (print_is_debug()) { fprintf(stdout, __VA_ARGS__); }
#define print_err(...) fprintf(stderr, __VA_ARGS__)
#endif

View File

@@ -0,0 +1,9 @@
#ifndef API_SESSION_H
#define API_SESSION_H
#include "api_consts.h"
int session_start(void);
void session_close(void);
#endif

View File

@@ -0,0 +1,36 @@
#ifndef API_STATS_H
#define API_STATS_H
#include <stdint.h>
#include <stdbool.h>
#include "api_consts.h"
#define IF_LOCATION_SIZE 16
#define IF_NAME_SIZE 32
typedef struct {
uint32_t collisions;
uint64_t multicast ;
uint64_t rx_bytes;
uint32_t rx_dropped;
uint32_t rx_errors;
uint64_t rx_packets;
uint64_t tx_bytes;
uint32_t tx_dropped;
uint32_t tx_errors;
uint64_t tx_packets;
} counters_t;
typedef struct {
char location[IF_LOCATION_SIZE];
char name[IF_NAME_SIZE];
uint32_t uptime;
uint32_t speed_dpx_status;
counters_t counters;
} interface_t;
int get_ethernet_count(int *eth_count);
int get_ethernet_stats(interface_t *eths, int eth_count);
int get_vlans(uint16_t **vlans, int *vlan_count);
#endif

View File

@@ -0,0 +1,41 @@
#ifndef OID_DEFINE_H
#define OID_DEFINE_H
#include <sys_adpt.h>
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
const static oid O_MAIN_MAC[] = { SYS_ADPT_PRIVATEMIB_OID, 1, 5, 6, 1, 0 };
const static oid O_SERIAL[] = { SYS_ADPT_PRIVATEMIB_OID, 1, 1, 3, 1, 10, 1 };
const static oid O_OPCODE_VERSION[] = { SYS_ADPT_PRIVATEMIB_OID, 1, 1, 5, 4, 0 };
const static oid O_SYS_UPTIME[] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
const static oid O_VLAN_STATUS[] = { 1, 3, 6, 1, 2, 1, 17, 7, 1, 4, 3, 1, 5};
const static oid O_POE_PORT_ENABLE[] ={1, 3, 6, 1, 2, 1, 105, 1, 1, 1, 3, 1};
const static oid O_PORT_CPAPBILITIES[] = { SYS_ADPT_PRIVATEMIB_OID, 1, 2, 1, 1, 6, 1 };
#define O_FACTORY_DEFAULT SYSTEM_OID"1.24.2.1.1.4.1.70.97.99.116.111.114.121.95.68.101.102.97.117.108.116.95.67.111.110.102.105.103.46.99.102.103"
#define O_FW_UPGRADE_MGMT SYSTEM_OID"1.24.6.1.0"
#define O_DEVICE_MODEL SYSTEM_OID"1.1.5.1.0"
#define O_DEVICE_COMPANY SYSTEM_OID"1.1.5.2.0"
#define O_STR_POE_PORT_ENABLE "1.3.6.1.2.1.105.1.1.1.3.1"
#define O_STR_POE_MAX_POWER SYSTEM_OID"1.28.6.1.13.1"
#define O_STR_POE_USAGE_THRESHOLD "1.3.6.1.2.1.105.1.3.1.1.5.1"
#define O_STR_IF_ADMIN_STATUS "1.3.6.1.2.1.2.2.1.7"
#define O_STR_PORT_CPAPBILITIES SYSTEM_OID"1.2.1.1.6"
#define O_STR_PVID "1.3.6.1.2.1.17.7.1.4.5.1.1"
#define O_STR_VLAN_NAME "1.3.6.1.2.1.17.7.1.4.3.1.1"
#define O_STR_VLAN_EGRESS "1.3.6.1.2.1.17.7.1.4.3.1.2"
#define O_STR_VLAN_STATUS "1.3.6.1.2.1.17.7.1.4.3.1.5"
#define O_STR_VLAN_UNTAGGED "1.3.6.1.2.1.17.7.1.4.3.1.4"
#define O_STR_COPY_SRC_TYPE SYSTEM_OID"1.24.1.1.0"
#define O_STR_COPY_DST_TYPE SYSTEM_OID"1.24.1.3.0"
#define O_STR_COPY_DST_NAME SYSTEM_OID"1.24.1.4.0"
#define O_STR_COPY_FILE_TYPE SYSTEM_OID"1.24.1.5.0"
#define O_STR_COPY_ACTION SYSTEM_OID"1.24.1.8.0"
#define O_NTP_STATUS SYSTEM_OID"1.23.5.1.0"
#define O_SNTP_STATUS SYSTEM_OID"1.23.1.1.0"
#define O_SNTP_INTERVAL SYSTEM_OID"1.23.1.3.0"
#define O_SNTP_SERVER_TYPE SYSTEM_OID"1.23.1.4.1.4"
#define O_SNTP_SERVER_ADDR SYSTEM_OID"1.23.1.4.1.5"
#endif

View File

@@ -0,0 +1,25 @@
#ifndef SNMP_HELPER_H
#define SNMP_HELPER_H
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include "oid_define.h"
int snmph_session_start(void);
void snmph_session_close(void);
int snmph_get(const oid *req_oid, size_t req_oid_len, struct snmp_pdu **response);
int snmph_get_argstr(const char *oid_str, struct snmp_pdu **response);
int snmph_get_single_string(const oid *req_oid, size_t req_oid_len, char *buf, int buf_len);
int snmph_get_bulk(const oid *req_oid, size_t req_oid_len, int max, struct snmp_pdu **response);
int snmph_set(const char *oid_str, char type, char *value);
int snmph_set_array(const char *oid_str, char type, const u_char *value, size_t len);
int snmph_walk(const char *oid_str, void *buf, int *num);
enum snmp_walk_node {
SNMP_WALK_NODE_NONE,
SNMP_WALK_NODE_VLAN_STATUS,
SNMP_WALK_NODE_POE_PORT_ENABLE,
};
#endif

View File

@@ -0,0 +1,7 @@
list(APPEND LIB_SOURCES
${CMAKE_CURRENT_LIST_DIR}/device.c
${CMAKE_CURRENT_LIST_DIR}/helper.c
${CMAKE_CURRENT_LIST_DIR}/session.c
${CMAKE_CURRENT_LIST_DIR}/stats.c
)

View File

@@ -0,0 +1,96 @@
#include <sys_adpt.h>
#include "api_device.h"
#include "snmp_helper.h"
int dev_get_main_mac(char *mac, int mac_len) {
int status = snmph_get_single_string(O_MAIN_MAC, OID_LENGTH(O_MAIN_MAC), mac, mac_len);
if (status != STAT_SUCCESS) {
return status;
}
int i = 0, j = 2;
for (i = 3; i < 17; i += 3) {
mac[j++] = mac[i];
mac[j++] = mac[i + 1];
}
mac[12] = 0;
char *c;
for (c = mac; *c; c++) {
if (*c >= 'A' && *c <= 'Z') {
*c += 32;
}
}
return STAT_SUCCESS;
}
int dev_get_serial(char *serial, int serial_len) {
return snmph_get_single_string(O_SERIAL, OID_LENGTH(O_SERIAL), serial, serial_len);
}
int dev_get_fw_version(char *fw, int fw_len) {
return snmph_get_single_string(O_OPCODE_VERSION, OID_LENGTH(O_OPCODE_VERSION), fw, fw_len);
}
int dev_get_uptime(uint32_t *up) {
struct snmp_pdu *response = NULL;
int status = snmph_get(O_SYS_UPTIME, OID_LENGTH(O_SYS_UPTIME), &response);
if (status != STATUS_SUCCESS) return status;
*up = (uint32_t) (response->variables->val.integer[0] / 100 + 0.5);
snmp_free_pdu(response);
return STATUS_SUCCESS;
}
int dev_get_vlan_list(int *vlan_arr, int *num) {
int status;
status = snmph_walk(O_STR_VLAN_STATUS, vlan_arr, num);
return status;
}
int dev_get_vlan_mask_len(int *len) {
char oidstr[MAX_OID_LEN];
struct snmp_pdu *response;
sprintf(oidstr, "%s.%d", O_STR_VLAN_EGRESS, 1);
int status = snmph_get_argstr(oidstr, &response);
if (status != STAT_SUCCESS) {
fprintf(stderr, "Could not retrieve vlan mask length.\n");
return status;
}
*len = response->variables->val_len;
return STATUS_SUCCESS;
}
int dev_get_poe_port_num(int *num) {
int status;
status = snmph_walk(O_STR_POE_PORT_ENABLE, 0, num);
return status;
}
int dev_get_port_capabilities_val_len(int *len) {
int status;
struct snmp_pdu *response = NULL;
status = snmph_get(O_PORT_CPAPBILITIES, OID_LENGTH(O_PORT_CPAPBILITIES), &response);
if (status == STATUS_SUCCESS)
*len = response->variables->val_len;
snmp_free_pdu(response);
return status;
}

View File

@@ -0,0 +1,340 @@
/* MODULE NAME: snmp_helper.c
* PURPOSE:
* for ucentral middleware process.
*
* NOTES:
*
* REASON:
* Description:
* HISTORY
* 2023/02/03 - Saulius P., Created
*
* Copyright(C) Accton Corporation, 2023
*/
/* INCLUDE FILE DECLARATIONS
*/
#include <math.h>
#include "snmp_helper.h"
#include "api_print.h"
static struct snmp_session session, *ss;
int snmph_session_start(void) {
init_snmp("ucmw_snmp");
snmp_sess_init( &session );
session.peername = "127.0.0.1";
session.version = SNMP_VERSION_2c;
session.community = (unsigned char*)"private";
session.community_len = strlen((char*)session.community);
ss = snmp_open(&session);
if (ss) {
return STAT_SUCCESS;
} else {
return STAT_ERROR;
}
}
int snmph_set(const char *oid_str, char type, char *value) {
netsnmp_pdu *pdu, *response = NULL;
size_t name_length;
oid name[MAX_OID_LEN];
int status, exitval = 0;
pdu = snmp_pdu_create(SNMP_MSG_SET);
name_length = MAX_OID_LEN;
if (snmp_parse_oid(oid_str, name, &name_length) == NULL){
snmp_perror(oid_str);
return -1;
} else{
if (snmp_add_var(pdu, name, name_length, type, value)) {
snmp_perror(oid_str);
return -1;
}
}
status = snmp_synch_response(ss, pdu, &response);
if (status == STAT_SUCCESS) {
if (response->errstat != SNMP_ERR_NOERROR) {
fprintf(stderr, "Error in packet.\nReason: %s\n",
snmp_errstring(response->errstat));
exitval = 2;
}
} else if (status == STAT_TIMEOUT) {
fprintf(stderr, "Timeout: No Response from %s\n",
session.peername);
exitval = 1;
} else { /* status == STAT_ERROR */
snmp_sess_perror("snmpset", ss);
exitval = 1;
}
if (response)
snmp_free_pdu(response);
return exitval;
}
int snmph_set_array(const char *oid_str, char type, const u_char *value, size_t len) {
netsnmp_pdu *pdu, *response = NULL;
size_t name_length;
oid name[MAX_OID_LEN];
int status, exitval = 0;
pdu = snmp_pdu_create(SNMP_MSG_SET);
name_length = MAX_OID_LEN;
if (snmp_parse_oid(oid_str, name, &name_length) == NULL){
snmp_perror(oid_str);
return -1;
} else{
if (!snmp_pdu_add_variable(pdu, name, name_length, type, value, len)) {
snmp_perror(oid_str);
return -1;
}
}
status = snmp_synch_response(ss, pdu, &response);
if (status == STAT_SUCCESS) {
if (response->errstat != SNMP_ERR_NOERROR) {
fprintf(stderr, "Error in packet.\nReason: %s\n",
snmp_errstring(response->errstat));
exitval = 2;
}
} else if (status == STAT_TIMEOUT) {
fprintf(stderr, "Timeout: No Response from %s\n",
session.peername);
exitval = 1;
} else { /* status == STAT_ERROR */
snmp_sess_perror("snmpset", ss);
exitval = 1;
}
if (response)
snmp_free_pdu(response);
return exitval;
}
int snmph_get(const oid *req_oid, size_t req_oid_len, struct snmp_pdu **response) {
struct snmp_pdu *request = snmp_pdu_create(SNMP_MSG_GET);
snmp_add_null_var(request, req_oid, req_oid_len);
int status = snmp_synch_response(ss, request, response);
if (*response && (*response)->errstat != SNMP_ERR_NOERROR) {
print_err("Error 1, response with error: %d, %ld\n", status, (*response)->errstat);
snmp_free_pdu(*response);
return STAT_ERROR;
}
if (!(*response)) {
print_err("Error 2: empty SNMP response\n");
return STAT_ERROR;
}
if (status != STAT_SUCCESS) {
print_err("Error 3: bad response status: %d\n", status);
snmp_free_pdu(*response);
}
if (!(*response)->variables) {
print_err("Error 4: empty variable list in response\n");
snmp_free_pdu(*response);
return STAT_ERROR;
}
print_debug("Default return: %d\n", status);
return status;
}
int snmph_get_argstr(const char *oid_str, struct snmp_pdu **response) {
oid name[MAX_OID_LEN];
size_t name_length = MAX_OID_LEN;
if (snmp_parse_oid(oid_str, name, &name_length) == NULL) {
snmp_perror(oid_str);
return -1;
}
struct snmp_pdu *request = snmp_pdu_create(SNMP_MSG_GET);
snmp_add_null_var(request, name, name_length);
int status = snmp_synch_response(ss, request, response);
if (*response && (*response)->errstat != SNMP_ERR_NOERROR) {
print_err("Error 1, response with error: %d, %ld\n", status, (*response)->errstat);
snmp_free_pdu(*response);
return STAT_ERROR;
}
if (!(*response)) {
print_err("Error 2: empty SNMP response\n");
return STAT_ERROR;
}
if (status != STAT_SUCCESS) {
print_err("Error 3: bad response status: %d\n", status);
snmp_free_pdu(*response);
}
if (!(*response)->variables) {
print_err("Error 4: empty variable list in response\n");
snmp_free_pdu(*response);
return STAT_ERROR;
}
print_debug("Default return: %d\n", status);
return status;
}
int snmph_get_single_string(const oid *req_oid, size_t req_oid_len, char *buf, int buf_len) {
struct snmp_pdu *response = NULL;
int status = snmph_get(req_oid, req_oid_len, &response);
if (status != STAT_SUCCESS) {
return status;
}
memset(buf, 0, buf_len);
strncpy(buf, (char*)response->variables->val.string, (int) fmin(buf_len, response->variables->val_len));
// if (response)
snmp_free_pdu(response);
return STAT_SUCCESS;
}
int snmph_get_bulk(const oid *req_oid, size_t req_oid_len, int max, struct snmp_pdu **response) {
struct snmp_pdu *request = snmp_pdu_create(SNMP_MSG_GETBULK);
request->non_repeaters = 0;
request->max_repetitions = max;
snmp_add_null_var(request, req_oid, req_oid_len);
int status = snmp_synch_response(ss, request, response);
// printf("Bulk status: %d\n", status);
if (status == 1) {
snmp_sess_perror("snmpbulkget", ss);
}
if (*response && (*response)->errstat != SNMP_ERR_NOERROR) {
print_err("Error 1, bulk response error: %d, %ld\n", status, (*response)->errstat);
snmp_free_pdu(*response);
return STAT_ERROR;
}
if (!(*response)) {
print_err("Error 2: empty bulk response\n");
return STAT_ERROR;
}
if (status != STAT_SUCCESS) {
print_err("Error 3, bad bulk status: %d\n", status);
snmp_free_pdu(*response);
}
if (!(*response)->variables) {
print_err("Error 4, empty bulk variables\n");
snmp_free_pdu(*response);
return STAT_ERROR;
}
print_debug("Default bulk return: %d\n", status);
return status;
}
int snmph_walk(const char *oid_str, void *buf, int *num) {
netsnmp_pdu *pdu, *response = NULL;
netsnmp_variable_list *vars;
oid name[MAX_OID_LEN];
size_t name_length = MAX_OID_LEN;
int running = 1;
int status = 0;
enum snmp_walk_node node = SNMP_WALK_NODE_NONE;
if (snmp_parse_oid(oid_str, name, &name_length) == NULL) {
snmp_perror(oid_str);
return -1;
}
if (!strcmp(oid_str, O_STR_VLAN_STATUS))
node = SNMP_WALK_NODE_VLAN_STATUS;
else if (!strcmp(oid_str, O_STR_POE_PORT_ENABLE))
node = SNMP_WALK_NODE_POE_PORT_ENABLE;
*num = 0;
while (running) {
/*
* create PDU for GETNEXT request and add object name to request
*/
pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
snmp_add_null_var(pdu, name, name_length);
/*
* do the request
*/
status = snmp_synch_response(ss, pdu, &response);
if (status == STAT_SUCCESS) {
if (response->errstat == SNMP_ERR_NOERROR) {
/*
* check resulting variables
*/
for (vars = response->variables; vars;
vars = vars->next_variable) {
if (node == SNMP_WALK_NODE_VLAN_STATUS)
{
if ((vars->name[12]==O_VLAN_STATUS[12]) && (vars->name_length==(OID_LENGTH(O_VLAN_STATUS)+1)))
{
((int*)buf)[(*num)++] = vars->name[13];
}
else
running = 0;
}
else if (node == SNMP_WALK_NODE_POE_PORT_ENABLE)
{
if ((vars->name[10]==O_POE_PORT_ENABLE[10]) && (vars->name_length==(OID_LENGTH(O_POE_PORT_ENABLE)+1)))
{
(*num)++;
}
else
running = 0;
}
else
running = 0;
memmove((char *) name, (char *) vars->name, vars->name_length * sizeof(oid));
name_length = vars->name_length;
//print_variable(vars->name, vars->name_length, vars);
}
} else {
running = 0;
}
} else if (status == STAT_TIMEOUT) {
fprintf(stderr, "Timeout: No Response from %s\n",
session.peername);
running = 0;
status = 1;
} else { /* status == STAT_ERROR */
snmp_sess_perror("snmpwalk", ss);
running = 0;
status = 1;
}
if (response)
snmp_free_pdu(response);
}
return status;
}
void snmph_session_close(void) {
snmp_close(ss);
}

View File

@@ -0,0 +1,10 @@
#include "api_session.h"
#include "snmp_helper.h"
int session_start() {
return snmph_session_start();
}
void session_close() {
snmph_session_close();
}

250
src/ec-private/ecapi/snmp/stats.c Executable file
View File

@@ -0,0 +1,250 @@
#include <sys_adpt.h>
#include "api_device.h"
#include "api_stats.h"
#include "snmp_helper.h"
#include "if-mib/ifTable/ifTable_constants.h"
const static oid O_IF_COUNT[] = { 1, 3, 6, 1, 2, 1, 2, 1, 0 };
const static oid O_IF_TYPE[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 3 };
// const static oid O_IF_LAST_CHANGE[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 9 };
const static oid O_IF_UPTIME[] = { SYS_ADPT_PRIVATEMIB_OID, 1, 2, 1, 1, 19 };
const static oid O_SPEED_DPX_STATUS[] = { SYS_ADPT_PRIVATEMIB_OID, 1, 2, 1, 1, 8 };
const static oid OID_IF_NAME[] = { SYS_ADPT_PRIVATEMIB_OID, 1, 2, 1, 1, 2 };
const static oid O_IF_RX_BYTES_64[] = { 1, 3, 6, 1, 2, 1, 31, 1, 1, 1, 6 };
const static oid O_IF_RX_DISCARD_PKTS[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 13 };
const static oid O_IF_RX_ERROR_PKTS[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 14 };
const static oid O_IF_RX_U_PKTS_64[] = { 1, 3, 6, 1, 2, 1, 31, 1, 1, 1, 7 }; // Unicast packets
const static oid O_IF_RX_MUL_PKTS_64[] = { 1, 3, 6, 1, 2, 1, 31, 1, 1, 1, 8 }; // Multicast packets
const static oid O_IF_RX_BR_PKTS_64[] = { 1, 3, 6, 1, 2, 1, 31, 1, 1, 1, 9 };
const static oid O_IF_TX_BYTES_64[] = { 1, 3, 6, 1, 2, 1, 31, 1, 1, 1, 10 };
const static oid O_IF_TX_DISCARD_PKTS[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 19 };
const static oid O_IF_TX_ERROR_PKTS[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 20 };
const static oid O_IF_TX_U_PKTS_64[] = { 1, 3, 6, 1, 2, 1, 31, 1, 1, 1, 11 }; // Unicast packets
const static oid O_IF_TX_MUL_PKTS_64[] = { 1, 3, 6, 1, 2, 1, 31, 1, 1, 1, 12 }; // Multicast packets
const static oid O_IF_TX_BR_PKTS_64[] = { 1, 3, 6, 1, 2, 1, 31, 1, 1, 1, 13 };
int get_ethernet_count(int *eth_count) {
struct snmp_pdu *response;
// printf("Try to retrieve IF count...\n");
int status = snmph_get(O_IF_COUNT, OID_LENGTH(O_IF_COUNT), &response);
// printf("Retrieved: %d\n", status);
if (status != STAT_SUCCESS) {
// printf("Could not retrieve interfaces count\n");
return status;
}
// printf("Interfaces: %ld\n", response->variables->val.integer[0]);
long int max_if = response->variables->val.integer[0];
snmp_free_pdu(response);
struct variable_list *vars;
status = snmph_get_bulk(O_IF_TYPE, OID_LENGTH(O_IF_TYPE), max_if, &response);
if (status != STAT_SUCCESS) {
// printf("Could not retrieve types\n");
return STATUS_ERROR;
}
*eth_count = 0;
for(vars = response->variables; vars; vars = vars->next_variable) {
// print_variable(vars->name, vars->name_length, vars);
if (vars->val.integer[0] == IANAIFTYPE_ETHERNETCSMACD) {
(*eth_count)++;
} else {
break;
}
}
snmp_free_pdu(response);
return STATUS_SUCCESS;
}
static int fill_ethernet_stats_32(const oid *req_oid, size_t req_oid_len, int max, uint32_t *val, bool aggregate) {
struct snmp_pdu *response;
struct variable_list *vars;
int status = snmph_get_bulk(req_oid, req_oid_len, max, &response);
if (status != STATUS_SUCCESS) return status;
uint32_t *addr = val;
uint32_t local_val = 0;
int i = 0;
for(vars = response->variables; vars; vars = vars->next_variable) {
memcpy(&local_val, &vars->val.integer[0], sizeof(uint32_t));
addr = (uint32_t *) ((char *) val + (sizeof(interface_t) * (i++)));
if (aggregate) {
*addr += local_val;
} else {
*addr = local_val;
}
// addr = (uint32_t *) ((char *) addr + sizeof(interface_t));
}
snmp_free_pdu(response);
return STATUS_SUCCESS;
}
static int fill_ethernet_stats_64(const oid *req_oid, size_t req_oid_len, int max, uint64_t *val, bool aggregate) {
struct snmp_pdu *response;
struct variable_list *vars;
int status = snmph_get_bulk(req_oid, req_oid_len, max, &response);
if (status != STATUS_SUCCESS) return status;
uint64_t *addr = val;
uint64_t local_val = 0;
int i = 0;
for(vars = response->variables; vars; vars = vars->next_variable) {
#ifdef ENDIANNESS_ADJUST
memcpy(&local_val, &vars->val.counter64[0].low, sizeof(uint64_t));
#else
memcpy(&local_val, &vars->val.counter64[0], sizeof(uint64_t));
#endif
addr = (uint64_t *) ((char *) val + (sizeof(interface_t) * (i++)));
if (aggregate) {
*addr += local_val;
} else {
*addr = local_val;
}
// addr = (uint64_t *) ((char *) addr + sizeof(interface_t));
}
snmp_free_pdu(response);
return STATUS_SUCCESS;
}
int get_ethernet_stats(interface_t *eths, int eth_count) {
uint32_t uptime;
if (dev_get_uptime(&uptime) != STATUS_SUCCESS) return STATUS_ERROR;
/***************** Interface uptime *****************/
if (fill_ethernet_stats_32(O_IF_UPTIME, OID_LENGTH(O_IF_UPTIME), eth_count, &eths[0].uptime, false) != STATUS_SUCCESS) return STATUS_ERROR;
if (fill_ethernet_stats_32(O_SPEED_DPX_STATUS, OID_LENGTH(O_SPEED_DPX_STATUS), eth_count, &eths[0].speed_dpx_status, false) != STATUS_SUCCESS) return STATUS_ERROR;
int i;
for (i = 0; i < eth_count; i++) {
if (eths[i].uptime) {
eths[i].uptime /= 100;// uptime - (eths[i].uptime / 100);
}
snprintf(eths[i].location, IF_LOCATION_SIZE, "%d", i);
}
struct snmp_pdu *response;
struct variable_list *vars;
int status = snmph_get_bulk(OID_IF_NAME, OID_LENGTH(OID_IF_NAME), eth_count, &response);
if (status != STATUS_SUCCESS) return status;
i = 0;
for(vars = response->variables; vars || i < eth_count; vars = vars->next_variable) {
strncpy(eths[i].name, (char *)vars->val.string, IF_NAME_SIZE > vars->val_len ? vars->val_len : IF_NAME_SIZE);
i++;
}
snmp_free_pdu(response);
/***************** Bytes (octets) *****************/
if (fill_ethernet_stats_64(O_IF_RX_BYTES_64, OID_LENGTH(O_IF_RX_BYTES_64), eth_count, &eths[0].counters.rx_bytes, false) != STATUS_SUCCESS) return STATUS_ERROR;
if (fill_ethernet_stats_64(O_IF_TX_BYTES_64, OID_LENGTH(O_IF_TX_BYTES_64), eth_count, &eths[0].counters.tx_bytes, false) != STATUS_SUCCESS) return STATUS_ERROR;
/***************** Packets *****************/
if (fill_ethernet_stats_64(O_IF_RX_MUL_PKTS_64, OID_LENGTH(O_IF_RX_MUL_PKTS_64), eth_count, &eths[0].counters.rx_packets, false) != STATUS_SUCCESS) return STATUS_ERROR;
if (fill_ethernet_stats_64(O_IF_TX_MUL_PKTS_64, OID_LENGTH(O_IF_TX_MUL_PKTS_64), eth_count, &eths[0].counters.tx_packets, false) != STATUS_SUCCESS) return STATUS_ERROR;
// "Multicast is the sum of rx+tx multicast packets"
for (i = 0; i < eth_count; i++) {
eths[i].counters.multicast = eths[i].counters.rx_packets + eths[i].counters.tx_packets;
}
// All packets is a sum (aggregate == true) of unicast, multicast and broadcast packets
if (fill_ethernet_stats_64(O_IF_RX_U_PKTS_64, OID_LENGTH(O_IF_RX_U_PKTS_64), eth_count, &eths[0].counters.rx_packets, true) != STATUS_SUCCESS) return STATUS_ERROR;
if (fill_ethernet_stats_64(O_IF_RX_BR_PKTS_64, OID_LENGTH(O_IF_RX_BR_PKTS_64), eth_count, &eths[0].counters.rx_packets, true) != STATUS_SUCCESS) return STATUS_ERROR;
if (fill_ethernet_stats_64(O_IF_TX_U_PKTS_64, OID_LENGTH(O_IF_TX_U_PKTS_64), eth_count, &eths[0].counters.tx_packets, true) != STATUS_SUCCESS) return STATUS_ERROR;
if (fill_ethernet_stats_64(O_IF_TX_BR_PKTS_64, OID_LENGTH(O_IF_TX_BR_PKTS_64), eth_count, &eths[0].counters.tx_packets, true) != STATUS_SUCCESS) return STATUS_ERROR;
/***************** Errors *****************/
if (fill_ethernet_stats_32(O_IF_RX_ERROR_PKTS, OID_LENGTH(O_IF_RX_ERROR_PKTS), eth_count, &eths[0].counters.rx_errors, false) != STATUS_SUCCESS) return STATUS_ERROR;
if (fill_ethernet_stats_32(O_IF_TX_ERROR_PKTS, OID_LENGTH(O_IF_TX_ERROR_PKTS), eth_count, &eths[0].counters.tx_errors, false) != STATUS_SUCCESS) return STATUS_ERROR;
/***************** Dropped *****************/
if (fill_ethernet_stats_32(O_IF_RX_DISCARD_PKTS, OID_LENGTH(O_IF_RX_DISCARD_PKTS), eth_count, &eths[0].counters.rx_dropped, false) != STATUS_SUCCESS) return STATUS_ERROR;
if (fill_ethernet_stats_32(O_IF_TX_DISCARD_PKTS, OID_LENGTH(O_IF_TX_DISCARD_PKTS), eth_count, &eths[0].counters.tx_dropped, false) != STATUS_SUCCESS) return STATUS_ERROR;
return STATUS_SUCCESS;
}
int get_vlans(uint16_t **vlans, int *vlan_count) {
struct snmp_pdu *response;
struct variable_list *vars;
// printf("Try to retrieve IF count...\n");
int status = snmph_get(O_IF_COUNT, OID_LENGTH(O_IF_COUNT), &response);
// printf("Retrieved: %d\n", status);
if (status != STAT_SUCCESS) {
printf("Could not retrieve interfaces count\n");
return status;
}
// printf("Interfaces: %ld\n", response->variables->val.integer[0]);
long int max_if = response->variables->val.integer[0];
status = snmph_get_bulk(O_IF_TYPE, OID_LENGTH(O_IF_TYPE), max_if, &response);
if (status != STAT_SUCCESS) {
// printf("VLANS: could not retrieve types\n");
return STATUS_ERROR;
}
*vlan_count = 0;
for(vars = response->variables; vars; vars = vars->next_variable) {
// print_variable(vars->name, vars->name_length, vars);
if (vars->val.integer[0] == IANAIFTYPE_L2VLAN || vars->val.integer[0] == IANAIFTYPE_L3IPVLAN) {
// printf("Found VLAN: %d\n", (int) vars->name[vars->name_length - 1]);
(*vlan_count)++;
}
}
(*vlans) = malloc(sizeof(uint16_t) * (*vlan_count));
int i = 0;
for(vars = response->variables; vars; vars = vars->next_variable) {
// print_variable(vars->name, vars->name_length, vars);
if (vars->val.integer[0] == IANAIFTYPE_L2VLAN || vars->val.integer[0] == IANAIFTYPE_L3IPVLAN) {
(*vlans)[i++] = (uint16_t) ((int) vars->name[vars->name_length - 1] - 1000);
}
}
return STATUS_SUCCESS;
}

View File

@@ -0,0 +1,78 @@
diff -Nuar a/CMakeLists.txt b/CMakeLists.txt
--- a/CMakeLists.txt 2023-07-21 09:53:57.450424222 +0800
+++ b/CMakeLists.txt 2023-07-21 11:36:15.395258277 +0800
@@ -1,4 +1,4 @@
-#***************************************************************************
+#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
@@ -185,9 +185,9 @@
mark_as_advanced(CURL_DISABLE_HTTP_AUTH)
option(CURL_DISABLE_IMAP "disables IMAP" OFF)
mark_as_advanced(CURL_DISABLE_IMAP)
-option(CURL_DISABLE_LDAP "disables LDAP" OFF)
+option(CURL_DISABLE_LDAP "disables LDAP" ON)
mark_as_advanced(CURL_DISABLE_LDAP)
-option(CURL_DISABLE_LDAPS "disables LDAPS" OFF)
+option(CURL_DISABLE_LDAPS "disables LDAPS" ON)
mark_as_advanced(CURL_DISABLE_LDAPS)
option(CURL_DISABLE_LIBCURL_OPTION "disables --libcurl option from the curl tool" OFF)
mark_as_advanced(CURL_DISABLE_LIBCURL_OPTION)
@@ -433,7 +433,7 @@
endif()
if(CURL_USE_OPENSSL)
- find_package(OpenSSL REQUIRED)
+ #find_package(OpenSSL REQUIRED)
set(SSL_ENABLED ON)
set(USE_OPENSSL ON)
@@ -441,7 +441,7 @@
# version of CMake. This allows our dependents to get our dependencies
# transitively.
if(NOT CMAKE_VERSION VERSION_LESS 3.4)
- list(APPEND CURL_LIBS OpenSSL::SSL OpenSSL::Crypto)
+ #list(APPEND CURL_LIBS OpenSSL::SSL OpenSSL::Crypto)
else()
list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
include_directories(${OPENSSL_INCLUDE_DIR})
@@ -595,7 +595,7 @@
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
check_library_exists_concat(${CMAKE_LDAP_LIB} ldap_init HAVE_LIBLDAP)
check_library_exists_concat(${CMAKE_LBER_LIB} ber_init HAVE_LIBLBER)
-
+
set(CMAKE_REQUIRED_INCLUDES_BAK ${CMAKE_REQUIRED_INCLUDES})
set(CMAKE_LDAP_INCLUDE_DIR "" CACHE STRING "Path to LDAP include directory")
if(CMAKE_LDAP_INCLUDE_DIR)
@@ -1369,12 +1369,16 @@
add_subdirectory(docs)
endif()
+INCLUDE_DIRECTORIES(../openssl/include)
+FIND_LIBRARY(openssl ssl ../openssl)
+
add_subdirectory(lib)
if(BUILD_CURL_EXE)
add_subdirectory(src)
endif()
+
cmake_dependent_option(BUILD_TESTING "Build tests"
ON "PERL_FOUND;NOT CURL_DISABLE_TESTS"
OFF)
diff -Nuar a/src/CMakeLists.txt b/src/CMakeLists.txt
--- a/src/CMakeLists.txt 2023-07-21 13:47:10.160906907 +0800
+++ b/src/CMakeLists.txt 2023-07-21 13:49:45.205682320 +0800
@@ -98,6 +98,9 @@
#Build curl executable
target_link_libraries(${EXE_NAME} libcurl ${CURL_LIBS})
+target_link_libraries(${EXE_NAME} -lssl)
+target_link_libraries(${EXE_NAME} -lcrypto)
+target_link_libraries(${EXE_NAME} ${CMAKE_SHARED_LINKER_FLAGS})
################################################################################

View File

@@ -0,0 +1,14 @@
--- a/CMakeLists.txt 2020-10-26 04:31:31.000000000 -0700
+++ b/CMakeLists.txt 2023-04-10 20:15:13.399705011 -0700
@@ -102,8 +102,9 @@
# ideally we want to use pipe2()
-
-CHECK_C_SOURCE_COMPILES("#define _GNU_SOURCE\n#include <unistd.h>\nint main(void) {int fd[2];\n return pipe2(fd, 0);\n}\n" LWS_HAVE_PIPE2)
+# jacky
+# comment out this line, use pipe() instead of pipe2()
+#CHECK_C_SOURCE_COMPILES("#define _GNU_SOURCE\n#include <unistd.h>\nint main(void) {int fd[2];\n return pipe2(fd, 0);\n}\n" LWS_HAVE_PIPE2)
# tcp keepalive needs this on linux to work practically... but it only exists
# after kernel 2.6.37

View File

@@ -0,0 +1,49 @@
cmake_minimum_required(VERSION 2.6)
PROJECT(ucentral-client C)
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,--copy-dt-needed-entries")
SET(LDFLAGS -fopenmp -Wl,--copy-dt-needed-entries)
INCLUDE_DIRECTORIES(src/include)
INCLUDE_DIRECTORIES(../)
INCLUDE_DIRECTORIES(../curl/include)
INCLUDE_DIRECTORIES(../libwebsockets/include)
INCLUDE_DIRECTORIES(../openssl/include)
INCLUDE_DIRECTORIES(ucentral-client/include)
INCLUDE_DIRECTORIES(ucentral-client)
INCLUDE_DIRECTORIES(src/include)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_LIST_DIR}/../ecapi/include)
INCLUDE_DIRECTORIES($ENV{SOURCE_PATH}/sysinclude)
INCLUDE_DIRECTORIES($ENV{SOURCE_PATH}/sysinclude/mibconstants)
INCLUDE_DIRECTORIES($ENV{SOURCE_PATH}/sysinclude/oem/$ENV{PROJECT_NAME})
INCLUDE_DIRECTORIES($ENV{PROJECT_PATH}/user/thirdpty/lua/net-snmp-5.4.4/include)
add_definitions(-DPLAT_EC)
if ($ENV{D_MODEL_NAME} STREQUAL ECS4130_AC5)
add_definitions(-DENDIANNESS_ADJUST)
add_definitions(-DNOT_SUPPORT_CAP_2500)
add_definitions(-DNOT_SUPPORT_NTP_DOMAIN_NAME)
add_definitions(-DSYSTEM_OID="1.3.6.1.4.1.259.10.1.55.")
elseif ($ENV{D_MODEL_NAME} STREQUAL ECS4125_10P)
add_definitions(-DSYSTEM_OID="1.3.6.1.4.1.259.10.1.57.")
else()
message(FATAL_ERROR "not support $ENV{D_MODEL_NAME}")
endif()
INCLUDE(ucentral-client/CMakeLists.txt)
INCLUDE(ucentral-client/platform/ec/CMakeLists.txt)
FIND_LIBRARY(cjson cjson ../cjson)
FIND_LIBRARY(curl curl ../curl/lib)
FIND_LIBRARY(openssl ssl ../openssl)
FIND_LIBRARY(websockets websockets ../libwebsockets/lib)
FIND_LIBRARY(crypto crypto ../openssl)
FIND_LIBRARY(ecapi_library ecapi ../ecapi/build)
FIND_LIBRARY(netsnmp_library netsnmp $ENV{PROJECT_PATH}/user/thirdpty/lua/net-snmp-5.4.4/snmplib/.libs)
ADD_EXECUTABLE(ucentral-client ${UC_SOURCES} ${PLAT_SOURCES})
TARGET_LINK_LIBRARIES(ucentral-client ${cjson} ${curl} ${openssl} ${crypto} ${websockets} ${netsnmp_library} ${ecapi_library})

View File

@@ -0,0 +1,9 @@
list(APPEND UC_SOURCES
${CMAKE_CURRENT_LIST_DIR}/proto.c
${CMAKE_CURRENT_LIST_DIR}/router-utils.c
${CMAKE_CURRENT_LIST_DIR}/ucentral-json-parser.c
${CMAKE_CURRENT_LIST_DIR}/ucentral-log.c
${CMAKE_CURRENT_LIST_DIR}/ucentral-client.c
${CMAKE_CURRENT_LIST_DIR}/inet_net_pton.c
)

View File

@@ -0,0 +1,200 @@
/*
* Copyright (c) 1996,1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef SPRINTF_CHAR
# define SPRINTF(x) strlen(sprintf/**/x)
#else
# define SPRINTF(x) ((size_t)sprintf x)
#endif
static int inet_net_pton_ipv4 (const char *src, u_char *dst,
size_t size) __THROW;
# define __rawmemchr strchr
/*
* static int
* inet_net_pton(af, src, dst, size)
* convert network number from presentation to network format.
* accepts hex octets, hex strings, decimal octets, and /CIDR.
* "size" is in bytes and describes "dst".
* return:
* number of bits, either imputed classfully or specified with /CIDR,
* or -1 if some failure occurred (check errno). ENOENT means it was
* not a valid network specification.
* author:
* Paul Vixie (ISC), June 1996
*/
int
inet_net_pton (int af, const char *src, void *dst, size_t size)
{
switch (af) {
case AF_INET:
return (inet_net_pton_ipv4(src, dst, size));
default:
//__set_errno (EAFNOSUPPORT);
return (-1);
}
}
/*
* static int
* inet_net_pton_ipv4(src, dst, size)
* convert IPv4 network number from presentation to network format.
* accepts hex octets, hex strings, decimal octets, and /CIDR.
* "size" is in bytes and describes "dst".
* return:
* number of bits, either imputed classfully or specified with /CIDR,
* or -1 if some failure occurred (check errno). ENOENT means it was
* not an IPv4 network specification.
* note:
* network byte order assumed. this means 192.5.5.240/28 has
* 0b11110000 in its fourth octet.
* author:
* Paul Vixie (ISC), June 1996
*/
static int
inet_net_pton_ipv4 (const char *src, u_char *dst, size_t size)
{
static const char xdigits[] = "0123456789abcdef";
int n, ch, tmp, dirty, bits;
const u_char *odst = dst;
ch = *src++;
if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
&& isascii(src[1]) && isxdigit(src[1])) {
/* Hexadecimal: Eat nybble string. */
if (size <= 0)
goto emsgsize;
dirty = 0;
tmp = 0; /* To calm down gcc. */
src++; /* skip x or X. */
while (isxdigit((ch = *src++))) {
ch = _tolower(ch);
n = (const char *) __rawmemchr(xdigits, ch) - xdigits;
assert(n >= 0 && n <= 15);
if (dirty == 0)
tmp = n;
else
tmp = (tmp << 4) | n;
if (++dirty == 2) {
if (size-- <= 0)
goto emsgsize;
*dst++ = (u_char) tmp;
dirty = 0;
}
}
if (dirty) { /* Odd trailing nybble? */
if (size-- <= 0)
goto emsgsize;
*dst++ = (u_char) (tmp << 4);
}
} else if (isascii(ch) && isdigit(ch)) {
/* Decimal: eat dotted digit string. */
for (;;) {
tmp = 0;
do {
n = ((const char *) __rawmemchr(xdigits, ch)
- xdigits);
assert(n >= 0 && n <= 9);
tmp *= 10;
tmp += n;
if (tmp > 255)
goto enoent;
} while (isascii((ch = *src++)) && isdigit(ch));
if (size-- <= 0)
goto emsgsize;
*dst++ = (u_char) tmp;
if (ch == '\0' || ch == '/')
break;
if (ch != '.')
goto enoent;
ch = *src++;
if (!isascii(ch) || !isdigit(ch))
goto enoent;
}
} else
goto enoent;
bits = -1;
if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) {
/* CIDR width specifier. Nothing can follow it. */
ch = *src++; /* Skip over the /. */
bits = 0;
do {
n = (const char *) __rawmemchr(xdigits, ch) - xdigits;
assert(n >= 0 && n <= 9);
bits *= 10;
bits += n;
} while (isascii((ch = *src++)) && isdigit(ch));
if (ch != '\0')
goto enoent;
if (bits > 32)
goto emsgsize;
}
/* Firey death and destruction unless we prefetched EOS. */
if (ch != '\0')
goto enoent;
/* If nothing was written to the destination, we found no address. */
if (dst == odst)
goto enoent;
/* If no CIDR spec was given, infer width from net class. */
if (bits == -1) {
if (*odst >= 240) /* Class E */
bits = 32;
else if (*odst >= 224) /* Class D */
bits = 4;
else if (*odst >= 192) /* Class C */
bits = 24;
else if (*odst >= 128) /* Class B */
bits = 16;
else /* Class A */
bits = 8;
/* If imputed mask is narrower than specified octets, widen. */
if (bits >= 8 && bits < ((dst - odst) * 8))
bits = (dst - odst) * 8;
}
/* Extend network to cover the actual mask. */
while (bits > ((dst - odst) * 8)) {
if (size-- <= 0)
goto emsgsize;
*dst++ = '\0';
}
return (bits);
enoent:
//__set_errno (ENOENT);
return (-1);
emsgsize:
//__set_errno (EMSGSIZE);
return (-1);
}

View File

@@ -28,6 +28,37 @@ void uc_log_send_cb_register(void (*cb)(const char *, int sv));
void uc_log_severity_set(enum uc_log_component c, int sv);
void uc_log(enum uc_log_component c, int sv, const char *fmt, ...);
#ifdef PLAT_EC
#define UC_LOG_INFO(...) \
do { \
syslog(LOG_INFO, __VA_ARGS__); \
uc_log(UC_LOG_COMPONENT, UC_LOG_SV_INFO, __VA_ARGS__); \
} while (0)
#define UC_LOG_DBG(FMT, ...) \
do { \
syslog(LOG_DEBUG, "%s:%u: " FMT, __func__, \
(unsigned)__LINE__, ##__VA_ARGS__); \
uc_log(UC_LOG_COMPONENT, UC_LOG_SV_DEBUG, \
FMT, ##__VA_ARGS__); \
} while (0)
#define UC_LOG_ERR(FMT, ...) \
do { \
syslog(LOG_ERR, "%s:%u: " FMT, __func__, \
(unsigned)__LINE__, ##__VA_ARGS__); \
uc_log(UC_LOG_COMPONENT, UC_LOG_SV_ERR, \
FMT, ##__VA_ARGS__); \
} while (0)
#define UC_LOG_CRIT(FMT, ...) \
do { \
syslog(LOG_CRIT, "%s:%u: " FMT, __func__, \
(unsigned)__LINE__, ##__VA_ARGS__); \
uc_log(UC_LOG_COMPONENT, UC_LOG_SV_CRIT, \
FMT, ##__VA_ARGS__); \
} while (0)
#else
#define UC_LOG_INFO(...) \
do { \
syslog(LOG_INFO, __VA_ARGS__); \
@@ -57,5 +88,6 @@ void uc_log(enum uc_log_component c, int sv, const char *fmt, ...);
uc_log(UC_LOG_COMPONENT, UC_LOG_SV_CRIT, \
FMT __VA_OPT__(, ) __VA_ARGS__); \
} while (0)
#endif
#endif

View File

@@ -22,6 +22,9 @@ extern "C" {
#define MAX_NUM_OF_PORTS (100)
#define PORT_MAX_NAME_LEN (32)
#ifdef PLAT_EC
#define VLAN_MAX_NAME_LEN PORT_MAX_NAME_LEN
#endif
#define RTTY_CFG_FIELD_STR_MAX_LEN (64)
#define PLATFORM_INFO_STR_MAX_LEN (96)
#define SYSLOG_CFG_FIELD_STR_MAX_LEN (64)
@@ -256,6 +259,9 @@ struct plat_port_vlan {
struct plat_dhcp dhcp;
uint16_t id;
uint16_t mstp_instance;
#ifdef PLAT_EC
char name[VLAN_MAX_NAME_LEN];
#endif
};
struct plat_vlans_list {
@@ -269,6 +275,9 @@ struct plat_vlan_memberlist {
uint16_t fp_id;
} port;
bool tagged;
#ifdef PLAT_EC
bool pvid;
#endif
struct plat_vlan_memberlist *next;
};
@@ -448,6 +457,9 @@ typedef void (*plat_run_script_cb)(int err, struct plat_run_script_result *,
void *ctx);
enum {
#ifdef PLAT_EC
UCENTRAL_PORT_SPEED_NONE,
#endif
UCENTRAL_PORT_SPEED_10_E,
UCENTRAL_PORT_SPEED_100_E,
UCENTRAL_PORT_SPEED_1000_E,
@@ -460,6 +472,9 @@ enum {
};
enum {
#ifdef PLAT_EC
UCENTRAL_PORT_DUPLEX_NONE,
#endif
UCENTRAL_PORT_DUPLEX_HALF_E,
UCENTRAL_PORT_DUPLEX_FULL_E,
};
@@ -571,7 +586,11 @@ int plat_metrics_save(const struct plat_metrics_cfg *cfg);
int plat_metrics_restore(struct plat_metrics_cfg *cfg);
int plat_saved_config_id_get(uint64_t *id);
void plat_config_destroy(struct plat_cfg *cfg);
#ifdef PLAT_EC
int plat_factory_default(bool keep_redirector);
#else
int plat_factory_default(void);
#endif
int plat_rtty(struct plat_rtty_cfg *rtty_cfg);
int plat_upgrade(char *uri, char *signature);
@@ -607,6 +626,10 @@ plat_reboot_cause_get(struct plat_reboot_cause *cause);
int plat_diagnostic(char *res_path);
#ifdef PLAT_EC
void clean_stats();
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,3 @@
list(APPEND PLAT_SOURCES
${CMAKE_CURRENT_LIST_DIR}/plat-ec.c
)

File diff suppressed because it is too large Load Diff

View File

@@ -7,6 +7,10 @@
#include <cjson/cJSON.h>
#include <curl/curl.h>
#ifdef PLAT_EC
#include <inttypes.h>
#endif
#define UC_LOG_COMPONENT UC_LOG_COMPONENT_PROTO
#include "ucentral.h"
@@ -782,9 +786,19 @@ static int cfg_ethernet_poe_parse(cJSON *poe,
cJSON *do_reset;
admin_mode = cJSON_GetObjectItemCaseSensitive(poe, "admin-mode");
#ifdef PLAT_EC
/* When ucentralgw push configuration to client, it could modify key "admin-mode" to "poe.admin-mode" */
if (!admin_mode)
admin_mode = cJSON_GetObjectItemCaseSensitive(poe, "poe.admin-mode");
#endif
do_reset = cJSON_GetObjectItemCaseSensitive(poe, "do-reset");
detection = cJSON_GetObjectItemCaseSensitive(poe, "detection");
power_limit = cJSON_GetObjectItemCaseSensitive(poe, "power-limit");
#ifdef PLAT_EC
/* When ucentralgw push configuration to client, it could modify key "power-limit" to "poe.power-limit" */
if (!power_limit)
power_limit = cJSON_GetObjectItemCaseSensitive(poe, "poe.power-limit");
#endif
priority = cJSON_GetObjectItemCaseSensitive(poe, "priority");
if (admin_mode && !cJSON_IsBool(admin_mode)) {
@@ -917,8 +931,13 @@ static int cfg_ethernet_parse(cJSON *ethernet, struct plat_cfg *cfg)
struct plat_port tmp_port = {0};
size_t ports_selected = 0;
cJSON *select_ports;
#ifdef PLAT_EC
cJSON *duplex;
cJSON *speed;
#else
const char *duplex;
double speed = 0;
#endif
cJSON *ieee8021x;
bool enabled;
cJSON *poe;
@@ -928,10 +947,16 @@ static int cfg_ethernet_parse(cJSON *ethernet, struct plat_cfg *cfg)
select_ports = cJSON_GetObjectItemCaseSensitive(eth, "select-ports");
enabled =
cJSON_IsTrue(cJSON_GetObjectItemCaseSensitive(eth, "enabled"));
#ifdef PLAT_EC
duplex = cJSON_GetObjectItemCaseSensitive(eth, "duplex");
speed = cJSON_GetObjectItemCaseSensitive(eth, "speed");
#else
duplex =
cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(eth, "duplex"));
speed =
cJSON_GetNumberValue(cJSON_GetObjectItemCaseSensitive(eth, "speed"));
#endif
if (!duplex || !speed || !select_ports) {
UC_LOG_ERR("Ethernet obj doesn't hold duplex, speed or select-ports fields, parse failed\n");
@@ -962,9 +987,14 @@ static int cfg_ethernet_parse(cJSON *ethernet, struct plat_cfg *cfg)
}
}
#ifdef PLAT_EC
proto_port_duplex_to_num(cJSON_GetStringValue(duplex), &tmp_port.duplex);
proto_port_speed_to_num(cJSON_GetNumberValue(speed), &tmp_port.speed);
#else
proto_port_duplex_to_num(duplex, &tmp_port.duplex);
proto_port_state_to_num(enabled, &tmp_port.state);
proto_port_speed_to_num(speed, &tmp_port.speed);
#endif
proto_port_state_to_num(enabled, &tmp_port.state);
ret = cfg_ethernet_select_ports_parse(select_ports,
tmp_port_bmap,
@@ -1083,6 +1113,10 @@ static int cfg_vlan_interface_parse(cJSON *interface, struct plat_cfg *cfg)
cJSON *ipv4;
cJSON *dhcp;
cJSON *eth;
#ifdef PLAT_EC
cJSON *pvid;
cJSON *vid_name;
#endif
/* Ignore interface with l2 type: not vlan */
if (!cJSON_GetObjectItemCaseSensitive(interface, "vlan"))
@@ -1096,6 +1130,12 @@ static int cfg_vlan_interface_parse(cJSON *interface, struct plat_cfg *cfg)
BITMAP_SET_BIT(cfg->vlans_to_cfg, vid);
#ifdef PLAT_EC
vid_name = cJSON_GetObjectItemCaseSensitive(interface, "name");
if (vid_name && cJSON_IsString(vid_name))
snprintf(cfg->vlans[vid].name, sizeof(cfg->vlans[vid].name), "%s", cJSON_GetStringValue(vid_name));
#endif
ethernet = cJSON_GetObjectItemCaseSensitive(interface, "ethernet");
cJSON_ArrayForEach(eth, ethernet) {
select_ports = cJSON_GetObjectItem(eth, "select-ports");
@@ -1110,13 +1150,23 @@ static int cfg_vlan_interface_parse(cJSON *interface, struct plat_cfg *cfg)
vlan_tag = cJSON_GetObjectItemCaseSensitive(eth, "vlan-tag");
#ifdef PLAT_EC
if (!vlan_tag) {
#else
ret = proto_vlan_tagged_to_num(cJSON_GetStringValue(vlan_tag),
&tagged);
if (ret) {
#endif
UC_LOG_ERR("Ethernet doesn't hold 'vlan-tag' field, parse failed\n");
return -1;
}
#ifdef PLAT_EC
proto_vlan_tagged_to_num(cJSON_GetStringValue(vlan_tag), &tagged);
pvid = cJSON_GetObjectItemCaseSensitive(eth, "pvid");
#endif
BITMAP_FOR_EACH_BIT_SET(i, tmp_port_bmap, MAX_NUM_OF_PORTS) {
char port_name[PORT_MAX_NAME_LEN];
@@ -1132,6 +1182,11 @@ static int cfg_vlan_interface_parse(cJSON *interface, struct plat_cfg *cfg)
memberlist_node->tagged =
(tagged == UCENTRAL_VLAN_1Q_TAG_TAGGED_E);
#ifdef PLAT_EC
if (pvid)
memberlist_node->pvid = cJSON_IsTrue(pvid);
#endif
UCENTRAL_LIST_PUSH_MEMBER(&cfg->vlans[vid].members_list_head,
memberlist_node);
}
@@ -1683,6 +1738,10 @@ static int cfg_unit_parse(cJSON *unit, struct plat_cfg *cfg)
{
cJSON *usage_threshold;
cJSON *power_mgmt;
#ifdef PLAT_EC
power_mgmt = cJSON_GetObjectItemCaseSensitive(unit, "power-management");
usage_threshold = cJSON_GetObjectItemCaseSensitive(unit, "usage-threshold");
#else
cJSON *poe;
poe = cJSON_GetObjectItemCaseSensitive(unit, "poe");
@@ -1691,6 +1750,7 @@ static int cfg_unit_parse(cJSON *unit, struct plat_cfg *cfg)
power_mgmt = cJSON_GetObjectItemCaseSensitive(poe, "power-management");
usage_threshold = cJSON_GetObjectItemCaseSensitive(poe, "usage-threshold");
#endif
if (cJSON_GetStringValue(power_mgmt)) {
strcpy(cfg->unit.poe.power_mgmt, cJSON_GetStringValue(power_mgmt));
@@ -1899,7 +1959,11 @@ configure_handle(cJSON **rpc)
if (!tb[PARAMS_UUID] || !tb[PARAMS_SERIAL] || !tb[PARAMS_CONFIG]) {
UC_LOG_ERR("configure message is missing parameters\n");
#ifdef PLAT_EC
configure_reply(CONFIGURE_STATUS_PARTIALLY_APPLIED, "invalid parameters", 0, id);
#else
configure_reply(CONFIGURE_STATUS_REJECTED, "invalid parameters", 0, id);
#endif
return;
}
@@ -1917,7 +1981,11 @@ configure_handle(cJSON **rpc)
plat_cfg = cfg_parse(tb[PARAMS_CONFIG]);
if (!plat_cfg) {
UC_LOG_ERR("configure parse failed");
#ifdef PLAT_EC
configure_reply(CONFIGURE_STATUS_PARTIALLY_APPLIED,
#else
configure_reply(CONFIGURE_STATUS_REJECTED,
#endif
"Configure parse failed", 0, id);
return;
}
@@ -1965,7 +2033,15 @@ err_apply:
free(plat_cfg);
log_msg = plat_log_pop_concatenate();
#ifdef PLAT_EC
/* if error code return CONFIGURE_STATUS_REJECTED, ucentralgw will deliver configuration almost every 2 seconds.
* Changing error code to CONFIGURE_STATUS_PARTIALLY_APPLIED, ucentralgw will deliver configuration depending on
* health-check interval.
*/
configure_reply((ret ? CONFIGURE_STATUS_PARTIALLY_APPLIED :
#else
configure_reply((ret ? CONFIGURE_STATUS_REJECTED :
#endif
CONFIGURE_STATUS_APPLIED),
log_msg ? log_msg : "", uuid_latest, id);
free(log_msg);
@@ -2006,13 +2082,20 @@ factory_handle(cJSON **rpc)
{
cJSON *tb[__PARAMS_MAX] = {0};
double id = 0;
#ifdef PLAT_EC
bool keep_redirector = true;
#endif
tb[PARAMS_SERIAL] =
cJSON_GetObjectItemCaseSensitive(rpc[JSONRPC_PARAMS], "serial");
/* Currently unused; rework needed for <redirector parse>/ save logic */
tb[PARAMS_FACTORY_KEEP_REDIRECTOR] =
cJSON_GetObjectItemCaseSensitive(rpc[JSONRPC_PARAMS],
"keep_redirectory");
"keep_redirector");
#ifdef PLAT_EC
if (tb[PARAMS_FACTORY_KEEP_REDIRECTOR])
keep_redirector = (bool)cJSON_GetNumberValue(tb[PARAMS_FACTORY_KEEP_REDIRECTOR]);
#endif
if (rpc[JSONRPC_ID])
id = cJSON_GetNumberValue(rpc[JSONRPC_ID]);
@@ -2023,7 +2106,11 @@ factory_handle(cJSON **rpc)
return;
}
#ifdef PLAT_EC
if (plat_factory_default(keep_redirector)) {
#else
if (plat_factory_default()) {
#endif
UC_LOG_ERR("factory failed\n");
action_reply(1, "factory failed", 1, id);
return;

View File

@@ -29,6 +29,11 @@
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#ifdef PLAT_EC
#include "api_device.h"
#include "api_session.h"
#endif
struct per_vhost_data__minimal {
struct lws_context *context;
struct lws_vhost *vhost;
@@ -65,8 +70,13 @@ lws_protocols protocols[] = {
};
struct client_config client = {
#ifdef PLAT_EC
.redirector_file = "/etc/ucentral/redirector.json",
.redirector_file_dbg = "/etc/ucentral/firstcontact.hdr",
#else
.redirector_file = "/tmp/ucentral-redirector.json",
.redirector_file_dbg = "/tmp/firstcontact.hdr",
#endif
.server = NULL,
.port = 15002,
.path = "/",
@@ -374,8 +384,12 @@ static int gateway_cert_trust(void)
static int redirector_cert_trust(void)
{
#ifdef PLAT_EC
return 1;
#else
char *v = getenv("UC_REDIRECTOR_CERT_TRUST");
return v && *v && strcmp("0", v);
#endif
}
static int
@@ -696,6 +710,10 @@ int main(void)
struct stat st;
int ret;
#ifdef PLAT_EC
sleep(50); // wait for system ready
#endif
sigthread_create(); /* move signal handling to a dedicated thread */
openlog("ucentral-client", LOG_CONS | LOG_NDELAY | LOG_PERROR, LOG_DAEMON);
@@ -713,6 +731,17 @@ int main(void)
uc_log_severity_set(UC_LOG_COMPONENT_CLIENT, UC_LOG_SV_ERR);
uc_log_severity_set(UC_LOG_COMPONENT_PLAT, UC_LOG_SV_ERR);
#ifdef PLAT_EC
int status = session_start();
if (status == STATUS_SUCCESS) {
UC_LOG_INFO("Successfully connected to SNMP!\n");
} else {
UC_LOG_INFO("Could not connect to SNMP!\n");
exit(EXIT_FAILURE);;
}
#endif
if (client_config_read()) {
UC_LOG_CRIT("client_config_read failed");
exit(EXIT_FAILURE);
@@ -724,16 +753,37 @@ int main(void)
plat_running_img_name_get(client.firmware, sizeof(client.firmware));
#ifdef PLAT_EC
FILE *f = fopen(REDIRECTOR_USER_DEFINE_FILE, "r");
if (f) {
size_t cnt;
char redirector_url[256];
memset(redirector_url, 0, sizeof(redirector_url));
cnt = fread(redirector_url, 1, sizeof(redirector_url), f);
fclose(f);
client.server = redirector_url;
} else {
ret = ucentral_redirector_parse(&gw_host);
if (ret) {
/* parse failed by present redirector file, try to get redirector file from digicert */
#else
if ((gw_host = getenv("UC_GATEWAY_ADDRESS"))) {
gw_host = strdup(gw_host);
} else {
#endif
while (1) {
if (uc_loop_interrupted_get())
goto exit;
if (firstcontact()) {
UC_LOG_INFO(
"Firstcontact failed; trying again in 1 second...\n");
"Firstcontact failed; trying again in 30 second...\n");
#ifdef PLAT_EC
sleep(30);
#else
sleep(1);
#endif
continue;
}
@@ -748,6 +798,11 @@ int main(void)
} else {
client.server = gw_host;
}
#ifdef PLAT_EC
} else {
client.server = gw_host;
}
#endif
}
memset(&info, 0, sizeof info);
@@ -793,5 +848,9 @@ exit:
free(gw_host);
curl_global_cleanup();
#ifdef PLAT_EC
session_close();
clean_stats();
#endif
return 0;
}

View File

@@ -175,7 +175,12 @@ void uc_json_parser_init(struct uc_json_parser *uctx, uc_json_parse_cb cb,
void uc_json_parser_uninit(struct uc_json_parser *uctx)
{
/* The function lejp_destruct() cause segmentation fault on EC platform, comment out this line when building EC platform.
* The function lejp_destruct() describes "no allocations... just let callback know what it happening".
*/
#ifndef PLAT_EC
lejp_destruct(&uctx->ctx);
#endif
free(uctx->str);
cJSON_Delete(uctx->root);
*uctx = (struct uc_json_parser){ 0 };

View File

@@ -32,6 +32,10 @@ extern "C" {
#define UCENTRAL_TMP "/tmp/ucentral.cfg"
#define UCENTRAL_LATEST "/etc/ucentral/ucentral.active"
#ifdef PLAT_EC
#define REDIRECTOR_USER_DEFINE_FILE "/etc/ucentral/redirector-user-defined"
#endif
/* It's expected that dev-id format is the following:
* 11111111-1111-1111-1111-111111111111
* and the max size of such string is 36 symbols.