ucentral: development update

* update realtek kernel
* add new PoE tool
* improve CI

Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
John Crispin
2021-05-12 12:07:30 +02:00
parent f35ded1297
commit 893bc05661
12 changed files with 5825 additions and 113 deletions

View File

@@ -37,6 +37,7 @@ jobs:
tar cfz "$TAR_NAME" -C openwrt/bin/targets/ .
curl -u $GH_BUILD_USERNAME:$GH_BUILD_PASSWORD -T "$TAR_NAME" "https://tip.jfrog.io/artifactory/tip-wlan-ap-firmware/uCentral/$LOWERCASE_TARGET/"$TAR_NAME""
IMG_NAME="$(date +%Y%m%d)-$LOWERCASE_TARGET-$BRANCH-$HASH-upgrade.bin";
echo -e "{\n\t\"image\":\""${IMG_NAME}"\",\n\t\"revision\": \""${HASH}"\"\n}" > latest-upgrade.json
[ -f openwrt/image-file ] && curl -u $GH_BUILD_USERNAME:$GH_BUILD_PASSWORD -T "openwrt/$(cat openwrt/image-file)" "https://tip.jfrog.io/artifactory/tip-wlan-ap-firmware/uCentral/$LOWERCASE_TARGET/"$IMG_NAME""
[ -f openwrt/image-file ] && curl -u $GH_BUILD_USERNAME:$GH_BUILD_PASSWORD -T "latest-upgrade.json" "https://tip.jfrog.io/artifactory/tip-wlan-ap-firmware/uCentral/$LOWERCASE_TARGET/latest-upgrade.json"
TIP_VERSION="$(grep DISTRIB_TIP= openwrt/tmp/openwrt_release | cut -d\' -f2)"
echo -e "{\n\t\"image\":\""${IMG_NAME}"\",\n\t\"revision\": \""${TIP_VERSION}"\",\n\t\"timestamp\":\""$(date +%s)"\",\n\n\t\"compatible\": \""${LOWERCASE_TARGET}"\"\n}" > latest-upgrade.json
[ -f openwrt/tmp/image-file ] && curl -u $GH_BUILD_USERNAME:$GH_BUILD_PASSWORD -T "openwrt/$(cat openwrt/tmp/image-file)" "https://tip.jfrog.io/artifactory/tip-wlan-ap-firmware/uCentral/$LOWERCASE_TARGET/"$IMG_NAME""
[ -f openwrt/tmp/image-file ] && curl -u $GH_BUILD_USERNAME:$GH_BUILD_PASSWORD -T "latest-upgrade.json" "https://tip.jfrog.io/artifactory/tip-wlan-ap-firmware/uCentral/$LOWERCASE_TARGET/latest-upgrade.json"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=realtek-poe
PKG_RELEASE:=1
PKG_LICENSE:=GPL-2.0
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
define Package/realtek-poe
SECTION:=net
CATEGORY:=Network
TITLE:=Realtek PoE Switch Port daemon
DEPENDS:=+libubox +libubus +libuci
endef
define Package/realtek-poe/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/realtek-poe $(1)/usr/bin/
$(CP) ./files/* $(1)
endef
$(eval $(call BuildPackage,realtek-poe))

View File

@@ -0,0 +1,9 @@
config global
option budget '65'
config port
option enable '1'
option id '1'
option name 'lan1'
option poe_plus '1'
option priority '2'

View File

@@ -0,0 +1,20 @@
#!/bin/sh /etc/rc.common
START=80
USE_PROCD=1
PROG=/usr/bin/realtek-poe
reload_service() {
ubus call poe reload
}
service_triggers() {
procd_add_config_trigger "config.change" "poe" ubus call poe reload
}
start_service() {
procd_open_instance
procd_set_param command "$PROG"
procd_set_param respawn
procd_close_instance
}

View File

@@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 2.6)
PROJECT(realtek-poe C)
ADD_DEFINITIONS(-Os -ggdb -Wextra -Wall -Werror --std=gnu99 -Wmissing-declarations -Wno-unused-parameter)
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
SET(SOURCES main.c)
IF(DEBUG)
ADD_DEFINITIONS(-DDEBUG -g3)
ENDIF()
FIND_LIBRARY(ubus NAMES ubus)
FIND_LIBRARY(uci NAMES uci)
FIND_LIBRARY(ubox NAMES ubox)
FIND_PATH(uci_include_dir NAMES uci.h)
FIND_PATH(ubus_include_dir NAMES libubus.h)
FIND_PATH(ubox_include_dir NAMES libubox/usock.h)
INCLUDE_DIRECTORIES(${ubox_include_dir} ${ubus_include_dir} ${uci_include_dir})
ADD_EXECUTABLE(realtek-poe ${SOURCES})
TARGET_LINK_LIBRARIES(realtek-poe ${ubox} ${ubus} ${uci})
INSTALL(TARGETS realtek-poe
RUNTIME DESTINATION sbin
)

View File

@@ -0,0 +1,845 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <getopt.h>
#include <libubox/ustream.h>
#include <libubox/uloop.h>
#include <libubox/list.h>
#include <libubox/ulog.h>
#include <libubus.h>
#include <uci.h>
#include <uci_blob.h>
#define ULOG_DBG(fmt, ...) ulog(LOG_DEBUG, fmt, ## __VA_ARGS__)
typedef int (*poe_reply_handler)(unsigned char *reply);
#define MAX_PORT 8
#define GET_STR(a, b) (a < ARRAY_SIZE(b) ? b[a] : NULL)
struct port_config {
char name[16];
unsigned char enable;
unsigned char priority;
unsigned char power_up_mode;
unsigned char power_budget;
};
struct config {
int debug;
int budget;
int budget_guard;
int port_count;
struct port_config ports[MAX_PORT];
};
struct port_state {
char *status;
float watt;
char *poe_mode;
};
struct state {
char *sys_mode;
unsigned char sys_version;
char *sys_mcu;
char *sys_status;
unsigned char sys_ext_version;
float power_consumption;
struct port_state ports[MAX_PORT];
};
struct cmd {
struct list_head list;
unsigned char cmd[12];
};
static struct uloop_timeout state_timeout;
static struct ubus_auto_conn conn;
static struct ustream_fd stream;
static LIST_HEAD(cmd_pending);
static unsigned char cmd_seq;
static struct state state;
static struct blob_buf b;
static struct config config = {
.budget = 65,
.budget_guard = 7,
.port_count = 8,
};
static void
config_load_port(struct uci_section *s)
{
enum {
PORT_ATTR_ID,
PORT_ATTR_NAME,
PORT_ATTR_ENABLE,
PORT_ATTR_PRIO,
PORT_ATTR_POE_PLUS,
__PORT_ATTR_MAX,
};
static const struct blobmsg_policy port_attrs[__PORT_ATTR_MAX] = {
[PORT_ATTR_ID] = { .name = "id", .type = BLOBMSG_TYPE_INT32 },
[PORT_ATTR_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
[PORT_ATTR_ENABLE] = { .name = "enable", .type = BLOBMSG_TYPE_INT32 },
[PORT_ATTR_PRIO] = { .name = "priority", .type = BLOBMSG_TYPE_INT32 },
[PORT_ATTR_POE_PLUS] = { .name = "poe_plus", .type = BLOBMSG_TYPE_INT32 },
};
const struct uci_blob_param_list port_attr_list = {
.n_params = __PORT_ATTR_MAX,
.params = port_attrs,
};
struct blob_attr *tb[__PORT_ATTR_MAX] = { 0 };
unsigned int id;
blob_buf_init(&b, 0);
uci_to_blob(&b, s, &port_attr_list);
blobmsg_parse(port_attrs, __PORT_ATTR_MAX, tb, blob_data(b.head), blob_len(b.head));
if (!tb[PORT_ATTR_ID] || !tb[PORT_ATTR_NAME]) {
ULOG_ERR("invalid port settings");
return;
}
id = blobmsg_get_u32(tb[PORT_ATTR_ID]);
if (!id || id > MAX_PORT) {
ULOG_ERR("invalid port id");
return;
}
id--;
strncpy(config.ports[id].name, blobmsg_get_string(tb[PORT_ATTR_NAME]), 16);
if (tb[PORT_ATTR_ENABLE])
config.ports[id].enable = !!blobmsg_get_u32(tb[PORT_ATTR_ENABLE]);
if (tb[PORT_ATTR_PRIO])
config.ports[id].priority = blobmsg_get_u32(tb[PORT_ATTR_PRIO]);
if (config.ports[id].priority > 3)
config.ports[id].priority = 3;
if (tb[PORT_ATTR_POE_PLUS] && blobmsg_get_u32(tb[PORT_ATTR_POE_PLUS]))
config.ports[id].power_up_mode = 3;
}
static void
config_load_global(struct uci_section *s)
{
enum {
GLOBAL_ATTR_BUDGET,
GLOBAL_ATTR_GUARD,
__GLOBAL_ATTR_MAX,
};
static const struct blobmsg_policy global_attrs[__GLOBAL_ATTR_MAX] = {
[GLOBAL_ATTR_BUDGET] = { .name = "budget", .type = BLOBMSG_TYPE_INT32 },
[GLOBAL_ATTR_GUARD] = { .name = "guard", .type = BLOBMSG_TYPE_INT32 },
};
const struct uci_blob_param_list global_attr_list = {
.n_params = __GLOBAL_ATTR_MAX,
.params = global_attrs,
};
struct blob_attr *tb[__GLOBAL_ATTR_MAX] = { 0 };
blob_buf_init(&b, 0);
uci_to_blob(&b, s, &global_attr_list);
blobmsg_parse(global_attrs, __GLOBAL_ATTR_MAX, tb, blob_data(b.head), blob_len(b.head));
config.budget = 65;
if (tb[GLOBAL_ATTR_BUDGET])
config.budget = blobmsg_get_u32(tb[GLOBAL_ATTR_BUDGET]);
if (tb[GLOBAL_ATTR_GUARD])
config.budget_guard = blobmsg_get_u32(tb[GLOBAL_ATTR_GUARD]);
else
config.budget_guard = config.budget / 10;
}
static void
config_load(int init)
{
struct uci_context *uci = uci_alloc_context();
struct uci_package *package = NULL;
memset(config.ports, 0, sizeof(config.ports));
if (!uci_load(uci, "poe", &package)) {
struct uci_element *e;
if (init)
uci_foreach_element(&package->sections, e) {
struct uci_section *s = uci_to_section(e);
if (!strcmp(s->type, "global"))
config_load_global(s);
}
uci_foreach_element(&package->sections, e) {
struct uci_section *s = uci_to_section(e);
if (!strcmp(s->type, "port"))
config_load_port(s);
}
}
uci_unload(uci, package);
uci_free_context(uci);
}
static void
poe_cmd_dump(char *type, unsigned char *data)
{
int i;
if (!config.debug)
return;
fprintf(stderr, "%s ->", type);
for (i = 0; i < 12; i++)
fprintf(stderr, " 0x%02x", data[i]);
fprintf(stderr, "\n");
}
static int
poe_cmd_send(struct cmd *cmd)
{
poe_cmd_dump("TX", cmd->cmd);
ustream_write(&stream.stream, (char *)cmd->cmd, 12, false);
return 0;
}
static int
poe_cmd_next(void)
{
struct cmd *cmd;
if (list_empty(&cmd_pending))
return -1;
cmd = list_first_entry(&cmd_pending, struct cmd, list);
return poe_cmd_send(cmd);
}
static int
poe_cmd_queue(unsigned char *_cmd, int len)
{
int i, empty = list_empty(&cmd_pending);
struct cmd *cmd = malloc(sizeof(*cmd));
memset(cmd, 0, sizeof(*cmd));
memset(cmd->cmd, 0xff, 12);
memcpy(cmd->cmd, _cmd, len);
cmd_seq++;
cmd->cmd[1] = cmd_seq;
cmd->cmd[11] = 0;
for (i = 0; i < 11; i++)
cmd->cmd[11] += cmd->cmd[i];
list_add_tail(&cmd->list, &cmd_pending);
if (empty)
return poe_cmd_send(cmd);
return 0;
}
/* 0x00 - Set port enable
* 0: Disable
* 1: Enable
*/
static int
poe_cmd_port_enable(unsigned char port, unsigned char enable)
{
unsigned char cmd[] = { 0x00, 0x00, port, enable };
return poe_cmd_queue(cmd, sizeof(cmd));
}
/* 0x06 - Set global port enable
* 0: Disable PSE Functionality on all Ports
* 1: Enable PSE Functionality on all Ports
* 2: Enable Force power Functionality on all ports
* 3: Enable Force Power with Disconnect Functionality on all Ports
*/
static int
poe_cmd_global_port_enable(unsigned char enable)
{
unsigned char cmd[] = { 0x06, 0x00, enable };
return poe_cmd_queue(cmd, sizeof(cmd));
}
/* 0x10 - Set port detection type
* 1: Legacy Capacitive Detection only
* 2: IEEE 802.3af 4-Point Detection only (Default)
* 3: IEEE 802.3af 4-Point followed by Legacy
* 4: IEEE 802.3af 2-Point detection (Not Supported)
* 5: IEEE 802.3af 2-Point followed by Legacy
*/
static int
poe_cmd_port_detection_type(unsigned char port, unsigned char type)
{
unsigned char cmd[] = { 0x10, 0x00, port, type };
return poe_cmd_queue(cmd, sizeof(cmd));
}
/* 0x11 - Set port classification
* 0: Disable
* 1: Enable
*/
static int
poe_cmd_port_classification(unsigned char port, unsigned char classification)
{
unsigned char cmd[] = { 0x11, 0x00, port, classification };
return poe_cmd_queue(cmd, sizeof(cmd));
}
/* 0x13 - Set port disconnect type
* 0: none
* 1: AC-disconnect
* 2: DC-disconnect
* 3: DC with delay
*/
static int
poe_cmd_port_disconnect_type(unsigned char port, unsigned char type)
{
unsigned char cmd[] = { 0x13, 0x00, port, type };
return poe_cmd_queue(cmd, sizeof(cmd));
}
/* 0x15 - Set port power limit type
* 0: None. Power limit is 16.2W if the connected device is “low power”,
* or the set high power limit if the device is “high power”.
* 1: Class based. The power limit for class 4 devices is determined by the high power limit.
* 2: User defined
*/
static int
poe_cmd_port_power_limit_type(unsigned char port, unsigned char type)
{
unsigned char cmd[] = { 0x15, 0x00, port, type };
return poe_cmd_queue(cmd, sizeof(cmd));
}
/* 0x16 - Set port power budget
* values in 0.2W increments
*/
static int
poe_cmd_port_power_budget(unsigned char port, unsigned char budget)
{
unsigned char cmd[] = { 0x16, 0x00, port, budget };
return poe_cmd_queue(cmd, sizeof(cmd));
}
/* 0x17 - Set power management mode
* 0: None (No Power Management mode) (Default in Semi-Auto mode)
* 1: Static Power Management with Port Priority(Default in Automode)
* 2: Dynamic Power Management with Port Priority
* 3: Static Power Management without Port Priority
* 4: Dynamic Power Management without Port Priority
*/
static int
poe_cmd_power_mgmt_mode(unsigned char mode)
{
unsigned char cmd[] = { 0x18, 0x00, mode };
return poe_cmd_queue(cmd, sizeof(cmd));
}
/* 0x18 - Set global power budget */
static int
poe_cmd_global_power_budget(int budget, int guard)
{
unsigned char cmd[] = { 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
cmd[3] = budget * 10 / 256;
cmd[4] = budget * 10 % 256;
cmd[5] = guard * 10 / 256;
cmd[6] = guard * 10 % 256;
return poe_cmd_queue(cmd, sizeof(cmd));
}
/* 0x1a - Set port priority
* 0: Low
* 1: Normal
* 2: High
* 3: Critical
*/
static int
poe_set_port_priority(unsigned char port, unsigned char priority)
{
unsigned char cmd[] = { 0x1a, 0x00, port, priority };
return poe_cmd_queue(cmd, sizeof(cmd));
}
/* 0x1c - Set port power-up mode
* 0: PoE
* 1: legacy
* 2: pre-PoE+
* 3: PoE+
*/
static int
poe_set_port_power_up_mode(unsigned char port, unsigned char mode)
{
unsigned char cmd[] = { 0x1c, 0x00, port, mode };
return poe_cmd_queue(cmd, sizeof(cmd));
}
/* 0x20 - Get system info */
static int
poe_cmd_status(void)
{
unsigned char cmd[] = { 0x20 };
return poe_cmd_queue(cmd, sizeof(cmd));
}
static int
poe_reply_status(unsigned char *reply)
{
static char *mode[]={
"Semi-auto I2C",
"Semi-auto UART",
"Auto I2C",
"Auto UART"
};
static char *mcu[]={
"ST Micro ST32F100 Microcontroller",
"Nuvoton M05xx LAN Microcontroller",
"ST Micro STF030C8 Microcontroller",
"Nuvoton M058SAN Microcontroller",
"Nuvoton NUC122 Microcontroller"
};
static char *status[]={
"Global Disable pin is de-asserted:No system reset from the previous query cmd:Configuration saved",
"Global Disable pin is de-asserted:No system reset from the previous query cmd:Configuration Dirty",
"Global Disable pin is de-asserted:System reseted:Configuration saved",
"Global Disable pin is de-asserted:System reseted:Configuration Dirty",
"Global Disable Pin is asserted:No system reset from the previous query cmd:Configuration saved",
"Global Disable Pin is asserted:No system reset from the previous query cmd:Configuration Dirty",
"Global Disable Pin is asserted:System reseted:Configuration saved",
"Global Disable Pin is asserted:System reseted:Configuration Dirty"
};
state.sys_mode = GET_STR(reply[2], mode);
config.port_count = reply[3];
state.sys_version = reply[7];
state.sys_mcu = GET_STR(reply[8], mcu);
state.sys_status = GET_STR(reply[9], status);
state.sys_ext_version = reply[10];
return 0;
}
/* 0x23 - Get power statistics */
static int
poe_cmd_power_stats(void)
{
unsigned char cmd[] = { 0x23 };
return poe_cmd_queue(cmd, sizeof(cmd));
}
static int
poe_reply_power_stats(unsigned char *reply)
{
state.power_consumption = reply[2];
state.power_consumption *= 256;
state.power_consumption += reply[3];
state.power_consumption /= 10;
return 0;
}
/* 0x26 - Get extended port config */
static int
poe_cmd_port_ext_config(unsigned char port)
{
unsigned char cmd[] = { 0x26, 0x00, port };
return poe_cmd_queue(cmd, sizeof(cmd));
}
static int
poe_reply_port_ext_config(unsigned char *reply)
{
static char *mode[] = {
"PoE",
"Legacy",
"pre-PoE+",
"PoE+"
};
state.ports[reply[2]].poe_mode = GET_STR(reply[3], mode);
return 0;
}
/* 0x2a - Get all port status */
static int
poe_cmd_port_overview(void)
{
unsigned char cmd[] = { 0x2a, 0x00, 0x00 };
return poe_cmd_queue(cmd, sizeof(cmd));
}
static int
poe_reply_port_overview(unsigned char *reply)
{
static char *status[]={
"Disabled",
"Searching",
"Delivering power",
"Fault",
"Other fault",
"Requesting power",
};
int i;
for (i = 0; i < 8; i++)
state.ports[i].status = GET_STR((reply[3 + i] & 0xf), status);
return 0;
}
/* 0x30 - Get port power statistics */
static int
poe_cmd_port_power_stats(unsigned char port)
{
unsigned char cmd[] = { 0x30, 0x00, port };
return poe_cmd_queue(cmd, sizeof(cmd));
}
static int
poe_reply_port_power_stats(unsigned char *reply)
{
float watt;
watt = reply[9];
watt *= 256;
watt += reply[10];
watt /= 10;
state.ports[reply[2]].watt = watt;
return 0;
}
static poe_reply_handler reply_handler[] = {
[0x20] = poe_reply_status,
[0x23] = poe_reply_power_stats,
[0x26] = poe_reply_port_ext_config,
[0x2a] = poe_reply_port_overview,
[0x30] = poe_reply_port_power_stats,
};
static int
poe_reply_consume(unsigned char *reply)
{
struct cmd *cmd = NULL;
unsigned char sum = 0, i;
poe_cmd_dump("RX", reply);
if (list_empty(&cmd_pending)) {
ULOG_ERR("received unsolicited reply\n");
return -1;
}
cmd = list_first_entry(&cmd_pending, struct cmd, list);
list_del(&cmd->list);
for (i = 0; i < 11; i++)
sum += reply[i];
if (reply[11] != sum) {
ULOG_DBG("received reply with bad checksum\n");
return -1;
}
if (reply[0] != cmd->cmd[0]) {
ULOG_DBG("received reply with bad command id\n");
return -1;
}
if (reply[1] != cmd->cmd[1]) {
ULOG_DBG("received reply with bad sequence number\n");
return -1;
}
free(cmd);
if (reply_handler[reply[0]])
return reply_handler[reply[0]](reply);
return 0;
}
static void
poe_stream_msg_cb(struct ustream *s, int bytes)
{
int len;
unsigned char *reply = (unsigned char *)ustream_get_read_buf(s, &len);
if (len < 12)
return;
poe_reply_consume(reply);
ustream_consume(s, 12);
poe_cmd_next();
}
static void
poe_stream_notify_cb(struct ustream *s)
{
if (!s->eof)
return;
ULOG_ERR("tty error, shutting down\n");
exit(-1);
}
static int
poe_stream_open(char *dev, struct ustream_fd *s, speed_t speed)
{
struct termios tio;
int tty;
tty = open(dev, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (tty < 0) {
ULOG_ERR("%s: device open failed: %s\n", dev, strerror(errno));
return -1;
}
tcgetattr(tty, &tio);
tio.c_cflag |= CREAD;
tio.c_cflag |= CS8;
tio.c_iflag |= IGNPAR;
tio.c_lflag &= ~(ICANON);
tio.c_lflag &= ~(ECHO);
tio.c_lflag &= ~(ECHOE);
tio.c_lflag &= ~(ISIG);
tio.c_iflag &= ~(IXON | IXOFF | IXANY);
tio.c_cflag &= ~CRTSCTS;
tio.c_cc[VMIN] = 1;
tio.c_cc[VTIME] = 0;
cfsetispeed(&tio, speed);
cfsetospeed(&tio, speed);
tcsetattr(tty, TCSANOW, &tio);
s->stream.string_data = false;
s->stream.notify_read = poe_stream_msg_cb;
s->stream.notify_state = poe_stream_notify_cb;
ustream_fd_init(s, tty);
tcflush(tty, TCIFLUSH);
return 0;
}
static int
poe_port_setup(void)
{
int i;
for (i = 0; i < config.port_count; i++) {
if (!config.ports[i].enable) {
poe_cmd_port_enable(i, 0);
continue;
}
poe_set_port_priority(i, config.ports[i].priority);
poe_set_port_power_up_mode(i, config.ports[i].power_up_mode);
if (config.ports[i].power_budget) {
poe_cmd_port_power_budget(i, config.ports[i].power_budget);
poe_cmd_port_power_limit_type(i, 2);
} else {
poe_cmd_port_power_limit_type(i, 1);
}
poe_cmd_port_disconnect_type(i, 2);
poe_cmd_port_classification(i, 1);
poe_cmd_port_detection_type(i, 3);
poe_cmd_port_enable(i, 1);
}
return 0;
}
static int
poe_initial_setup(void)
{
poe_cmd_status();
poe_cmd_power_mgmt_mode(2);
poe_cmd_global_power_budget(0, 0);
poe_cmd_global_port_enable(0);
poe_cmd_global_power_budget(config.budget, config.budget_guard);
poe_port_setup();
return 0;
}
static void
state_timeout_cb(struct uloop_timeout *t)
{
int i;
poe_cmd_power_stats();
poe_cmd_port_overview();
for (i = 0; i < config.port_count; i++) {
poe_cmd_port_ext_config(i);
poe_cmd_port_power_stats(i);
}
uloop_timeout_set(&state_timeout, 2 * 1000);
}
static int
ubus_poe_info_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
char tmp[16];
void *c;
int i;
blob_buf_init(&b, 0);
snprintf(tmp, sizeof(tmp), "v%u.%u.%u.%u",
state.sys_version >> 4, state.sys_version & 0xf,
state.sys_ext_version >> 4, state.sys_ext_version & 0xf);
blobmsg_add_string(&b, "firmware", tmp);
if (state.sys_mcu)
blobmsg_add_string(&b, "mcu", state.sys_mcu);
blobmsg_add_double(&b, "budget", config.budget);
blobmsg_add_double(&b, "consumption", state.power_consumption);
c = blobmsg_open_table(&b, "ports");
for (i = 0; i < config.port_count; i++) {
void *p;
if (!config.ports[i].enable)
continue;
p = blobmsg_open_table(&b, config.ports[i].name);
blobmsg_add_u32(&b, "priority", config.ports[i].priority);
if (state.ports[i].poe_mode)
blobmsg_add_string(&b, "mode", state.ports[i].poe_mode);
if (state.ports[i].status)
blobmsg_add_string(&b, "status", state.ports[i].status);
else
blobmsg_add_string(&b, "status", "unknown");
if (state.ports[i].watt)
blobmsg_add_double(&b, "consumption", state.ports[i].watt);
blobmsg_close_table(&b, p);
}
blobmsg_close_table(&b, c);
ubus_send_reply(ctx, req, b.head);
return UBUS_STATUS_OK;
}
static int
ubus_poe_reload_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
config_load(0);
poe_port_setup();
return UBUS_STATUS_OK;
}
static const struct ubus_method ubus_poe_methods[] = {
UBUS_METHOD_NOARG("info", ubus_poe_info_cb),
UBUS_METHOD_NOARG("reload", ubus_poe_reload_cb),
};
static struct ubus_object_type ubus_poe_object_type =
UBUS_OBJECT_TYPE("poe", ubus_poe_methods);
static struct ubus_object ubus_poe_object = {
.name = "poe",
.type = &ubus_poe_object_type,
.methods = ubus_poe_methods,
.n_methods = ARRAY_SIZE(ubus_poe_methods),
};
static void
ubus_connect_handler(struct ubus_context *ctx)
{
int ret;
ret = ubus_add_object(ctx, &ubus_poe_object);
if (ret)
fprintf(stderr, "Failed to add object: %s\n", ubus_strerror(ret));
}
int
main(int argc, char ** argv)
{
int ch;
ulog_open(ULOG_STDIO | ULOG_SYSLOG, LOG_DAEMON, "realtek-poe");
ulog_threshold(LOG_INFO);
while ((ch = getopt(argc, argv, "d")) != -1) {
switch (ch) {
case 'd':
config.debug = 1;
break;
}
}
config_load(1);
uloop_init();
conn.cb = ubus_connect_handler;
ubus_auto_connect(&conn);
if (poe_stream_open("/dev/ttyS1", &stream, B19200) < 0)
return -1;
poe_initial_setup();
state_timeout.cb = state_timeout_cb;
uloop_timeout_set(&state_timeout, 1000);
uloop_run();
uloop_done();
return 0;
}

View File

@@ -3,8 +3,5 @@
START=80
boot() {
DESC=$(cat /etc/openwrt_release | grep DISTRIB_DESCRIPTION= | cut -d\' -f2)
HASH=$(cat /etc/openwrt_release | grep DISTRIB_TIP= | cut -d\' -f2)
VERSION=$(cat /etc/openwrt_release | grep DISTRIB_TIP_VERSION= | cut -d\' -f2)
echo "$DESC / TIP-$VERSION-$HASH" > /tmp/ucentral.version
echo $(cat /etc/openwrt_release | grep DISTRIB_TIP= | cut -d\' -f2) > /tmp/ucentral.version
}

View File

@@ -206,7 +206,7 @@ index 0000000000..124dfd596a
+ setup_feeds(profile)
+ generate_config(profile)
+ if profile["image"]:
+ Path("image-file").write_text(profile["image"])
+ Path("tmp/image-file").write_text(profile["image"])
+ print("Running make defconfig")
+ if run(["make", "defconfig"]).returncode:
+ die(f"Error running make defconfig")

View File

@@ -1,7 +1,7 @@
From af8a5fcd98e0d1d0f0cca85c62a3551d3d589d88 Mon Sep 17 00:00:00 2001
From 5ed64f1cde06fa3f0fb27c618c86aeeb9309d845 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Sat, 29 Aug 2020 08:25:41 +0200
Subject: [PATCH 01/25] base-files: add the wlan-ap repo hash
Subject: [PATCH 12/38] base-files: add the wlan-ap repo hash
currently the banner will show the revision of the build tree.
This patch adds the hash of the wlan-ap tree.
@@ -9,13 +9,14 @@ This patch adds the hash of the wlan-ap tree.
Signed-off-by: John Crispin <john@phrozen.org>
---
include/version.mk | 7 +++++
package/base-files/Makefile | 1 +
package/base-files/files/etc/banner | 1 +
package/base-files/files/etc/openwrt_release | 2 ++
package/base-files/files/etc/openwrt_version | 1 +
...p-revision-info-to-system.board-call.patch | 28 +++++++++++++++++++
scripts/gen_config.py | 2 +-
scripts/getver.sh | 12 ++++++++
7 files changed, 52 insertions(+), 1 deletion(-)
8 files changed, 53 insertions(+), 1 deletion(-)
create mode 100644 package/system/procd/patches/0001-procd-add-tip-revision-info-to-system.board-call.patch
diff --git a/include/version.mk b/include/version.mk
@@ -42,6 +43,18 @@ index a4b47c8a57..214f32974b 100644
+ -e 's,%x,$(call sed_escape,$(VERSION_TIP_VERSION)),g' \
-e 's,%h,$(call sed_escape,$(VERSION_HWREV)),g'
diff --git a/package/base-files/Makefile b/package/base-files/Makefile
index 8a1ddf96f5..0ff6fa84c1 100644
--- a/package/base-files/Makefile
+++ b/package/base-files/Makefile
@@ -205,6 +205,7 @@ define Package/base-files/install
$(if $(CONFIG_TARGET_PREINIT_DISABLE_FAILSAFE), \
rm -f $(1)/etc/banner.failsafe,)
+ $(CP) $(1)/etc/openwrt_release $(TOPDIR)/tmp/
endef
ifneq ($(DUMP),1)
diff --git a/package/base-files/files/etc/banner b/package/base-files/files/etc/banner
index f73423bad4..65c175e1ef 100644
--- a/package/base-files/files/etc/banner
@@ -54,14 +67,14 @@ index f73423bad4..65c175e1ef 100644
%D %V, %C
---------------------------------------------------
diff --git a/package/base-files/files/etc/openwrt_release b/package/base-files/files/etc/openwrt_release
index d03400ca05..0327c21f68 100644
index d03400ca05..3652b1a49a 100644
--- a/package/base-files/files/etc/openwrt_release
+++ b/package/base-files/files/etc/openwrt_release
@@ -5,3 +5,5 @@ DISTRIB_TARGET='%S'
DISTRIB_ARCH='%A'
DISTRIB_DESCRIPTION='%D %V %C'
DISTRIB_TAINTS='%t'
+DISTRIB_TIP='%a'
+DISTRIB_TIP='%D %V %C / TIP-%x-%a'
+DISTRIB_TIP_VERSION='%x'
diff --git a/package/base-files/files/etc/openwrt_version b/package/base-files/files/etc/openwrt_version
index 48157ed97f..bb0ef233ac 100644
@@ -105,7 +118,7 @@ index 0000000000..4e8f05a700
+2.25.1
+
diff --git a/scripts/gen_config.py b/scripts/gen_config.py
index 5bc7068ae7..b380a2e605 100755
index 124dfd596a..e9418d776c 100755
--- a/scripts/gen_config.py
+++ b/scripts/gen_config.py
@@ -62,7 +62,7 @@ def load_yaml(fname: str, profile: dict, include = True):

View File

@@ -5,4 +5,4 @@ feeds:
path: ../../feeds/realtek
packages:
- rtl83xx-poe=y
- realtek-poe=y

View File

@@ -4,17 +4,25 @@ feeds:
- name: ucentral
path: ../../feeds/ucentral
include:
- webui
packages:
- libmosquitto-ssl
- lldpd
- curl
- ip-bridge
- ucentral-client
- ucentral-jsonschema
- ucentral-mqtt
- ucentral-schema
- ucentral-defaults
- ucode
- rtty-openssl
- tcpdump
- tip-defaults
- tmate
- udevmand
- umdns
- vxlan
diffconfig: |
CONFIG_IMAGEOPT=y