mirror of
				https://github.com/Telecominfraproject/wlan-ap.git
				synced 2025-10-30 18:07:52 +00:00 
			
		
		
		
	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:
		
							
								
								
									
										7
									
								
								.github/workflows/build-dev.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.github/workflows/build-dev.yml
									
									
									
									
										vendored
									
									
								
							| @@ -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
											
										
									
								
							
							
								
								
									
										25
									
								
								feeds/realtek/realtek-poe/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								feeds/realtek/realtek-poe/Makefile
									
									
									
									
									
										Normal 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)) | ||||
							
								
								
									
										9
									
								
								feeds/realtek/realtek-poe/files/etc/config/poe
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								feeds/realtek/realtek-poe/files/etc/config/poe
									
									
									
									
									
										Normal 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' | ||||
							
								
								
									
										20
									
								
								feeds/realtek/realtek-poe/files/etc/init.d/poe
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										20
									
								
								feeds/realtek/realtek-poe/files/etc/init.d/poe
									
									
									
									
									
										Executable 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 | ||||
| } | ||||
							
								
								
									
										28
									
								
								feeds/realtek/realtek-poe/src/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								feeds/realtek/realtek-poe/src/CMakeLists.txt
									
									
									
									
									
										Normal 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 | ||||
| ) | ||||
							
								
								
									
										845
									
								
								feeds/realtek/realtek-poe/src/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										845
									
								
								feeds/realtek/realtek-poe/src/main.c
									
									
									
									
									
										Normal 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; | ||||
| } | ||||
| @@ -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 | ||||
| } | ||||
|   | ||||
| @@ -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") | ||||
|   | ||||
| @@ -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): | ||||
|   | ||||
| @@ -5,4 +5,4 @@ feeds: | ||||
|     path: ../../feeds/realtek | ||||
|  | ||||
| packages: | ||||
|   - rtl83xx-poe=y | ||||
|   - realtek-poe=y | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 John Crispin
					John Crispin