Compare commits

...

51 Commits

Author SHA1 Message Date
jaspreetsachdev
7dd139cf3b Merge pull request #925 from Telecominfraproject/release-4.1
Release 4.1
2025-08-30 12:44:52 -04:00
Jaspreet Sachdev
544b687f46 Merge remote-tracking branch 'origin/main' into release-4.1 2025-08-30 12:42:04 -04:00
Arif Alam
c27b015a63 est_client: fix certificate issuer matching
Signed-off-by: Arif Alam <arif.alam@netexperience.com>
2025-08-29 22:52:28 -04:00
Arif Alam
02c2e6945b est_client: cloud_discovery: fixup demo environment
Signed-off-by: Arif Alam <arif.alam@netexperience.com>
2025-08-28 21:39:54 -04:00
Sebastian Huang
e7cd5038ac mediatek-sdk: Disable surge protection mode for AN8801SB PHY driver
Signed-off-by: Sebastian Huang <sebastian_huang@accton.com>
2025-08-20 08:16:30 +02:00
Paul White
34e4a01e25 ucentral-state: Respect LED config before enabling
Ensure that LEDs are configured to be ON before attempting to change their state.

Previously, if the LED was configured to be OFF, it would still enter a double-blink
state when the cloud connection was lost, and then switch to solid ON upon
reconnection—ignoring the configured OFF state.

This update changes that behavior:
    - If LEDs are configured OFF, they will remain OFF even during cloud
      disconnection (no double-blink).
    - After temporary state changes (e.g., during factory reset), the LED will
      return to its configured state (either OFF or ON).

Signed-off-by: Paul White <paul@shasta.cloud>
2025-08-20 08:16:08 +02:00
Tanya Singh
60e9fb2645 cloud_discover: typo fix in DHCP script option 138
Signed-off-by: Tanya Singh <tanya_singh@accton.com>
2025-08-19 07:33:01 +02:00
jaspreetsachdev
462ff4f813 Merge pull request #915 from Telecominfraproject/release-4.1
Release 4.1
2025-08-18 12:28:42 -04:00
Jaspreet Sachdev
71b738f8ee Merge remote-tracking branch 'origin/main' into release-4.1 2025-08-18 12:26:55 -04:00
John Crispin
b995833a03 cloud_discovery: fix typo
Signed-off-by: John Crispin <john@phrozen.org>
2025-08-14 16:58:33 +02:00
John Crispin
9866d4a86e cloud_discovery: update CDS QA endpoint
Signed-off-by: John Crispin <john@phrozen.org>
2025-08-14 16:14:42 +02:00
jaspreetsachdev
4ad04c7948 Merge pull request #914 from Telecominfraproject/release-4.1
Release 4.1 merge
2025-08-14 09:54:57 -04:00
John Crispin
143d4e3b58 cloud_discovery: make the reenrollment process more robust
Signed-off-by: John Crispin <john@phrozen.org>
2025-08-14 11:44:04 +02:00
John Crispin
0735fd8c9a elfutils: fix build with GCC11
Signed-off-by: John Crispin <john@phrozen.org>
2025-08-14 10:31:04 +02:00
Tanya Singh
c7f9061eee cloud_discovery: Fix typo in cloud_discovery script
Signed-off-by: Tanya Singh <tanya_singh@accton.com>
2025-08-14 07:57:59 +02:00
Paul White
f4a58c0989 qca-ssdk: Move MIB loop cnt variable to handle
The MIB loop cnt variable was defined as a static variable in the function that
implements the loop, however this function can be called for more than one switch
on some platforms.   This results in a race condition that leads to memory
corruption and kernel crashes.

The fix moves the loop cnt variable to the passed in switch handle, this way
there is one per switch chip.   Thix fix was identified by looking at newer
versions of the qca-ssdk software package from QCA.

Signed-off-by: Paul White <paul@shasta.cloud>
2025-08-13 14:39:38 +02:00
John Crispin
cd78a832e3 cloud_discovery: use production CDS for migration path
Signed-off-by: John Crispin <john@phrozen.org>
2025-08-13 14:35:42 +02:00
Paul White
7b6fc736f6 base-files: boot: add sync after uci-defaults
A scenario was seen where UCI config was not flushed to disk before
an AP power-cycle after uci-defaults was completed.  Since these
scripts are deleted after being ran once, there is no way to recover
without a factory reset.

Adding this sync operation proved to help avoid this situation from
happening

Signed-off-by: Paul White <paul@shasta.cloud>
2025-08-12 19:19:10 +02:00
John Crispin
f997f8dff0 tip-defaults: add operational OpenLan root CA
Signed-off-by: John Crispin <john@phrozen.org>
2025-08-12 19:11:54 +02:00
John Crispin
c4b3eeed81 est_client: switch to production environment
Signed-off-by: John Crispin <john@phrozen.org>
2025-08-11 06:36:22 +02:00
John Crispin
b2ba9d7c1b ucentral-client: update to latest HEAD
549e84e ucentral-client: Add discovery metadata to connect payload

Signed-off-by: John Crispin <john@phrozen.org>
2025-08-11 06:13:02 +02:00
Marek Kwaczynski
b982f3f4c2 cloud_discovery: Track and persist discovery method
Adds support for recording the method used to discover the cloud
controller (e.g. DHCP, FLASH, OpenLAN).
The selected method  records the current date and time along
with the discovery method into "/etc/ucentral/discovery.state.json".
The date is stored in epoch format.

Fixed: WIFI-14966

Signed-off-by: Marek Kwaczynski <marek@shasta.cloud>
2025-08-11 05:41:36 +02:00
John Crispin
68dfd58303 wireless-regdb: disable channel 14 in JP
Fixes: WIFI-14962
Signed-off-by: John Crispin <john@phrozen.org>
2025-08-07 14:51:33 +02:00
John Crispin
6ba26cba2b est_client: add a function to validate that the CN is correct
cloud_discovery will not start if the CN does not match the devices serial.
an error will be written to syslog

---
Wed Aug  6 14:23:23 2025 user.notice root: ERROR
Wed Aug  6 14:23:23 2025 user.notice root: ERROR
Wed Aug  6 14:23:23 2025 user.notice root: ERROR
Wed Aug  6 14:23:23 2025 user.notice root: The certificate used has a CN that does not match the serial of the device
Wed Aug  6 14:23:23 2025 user.notice root: ERROR
Wed Aug  6 14:23:23 2025 user.notice root: ERROR
Wed Aug  6 14:23:23 2025 user.notice root: ERROR
---

Signed-off-by: John Crispin <john@phrozen.org>
2025-08-06 16:23:57 +02:00
John Crispin
b5b276bfcc est_client: check if a cert is present inside the fwtool helper
This was causing devices without a birt cert being present from doing a
sysupgrade.

Signed-off-by: John Crispin <john@phrozen.org>
2025-08-06 11:03:59 +02:00
Tanya Singh
de7dc7e01a ipq50xx: Fix bootbank switching when firmware upgrade is triggered for Edgecore EAP104 and OAP101 series
Fixes: WIFI-14957
Signed-off-by: Tanya Singh <tanya_singh@accton.com>
2025-08-06 10:54:55 +02:00
jackcybertan
a967d67af3 qca-wifi-7: Added ramoops support for SonicFi IPQ5332 devices
Fixes: WIFI-14869
Signed-off-by: jackcybertan <jack.tsai@cybertan.com.tw>
2025-08-06 10:53:52 +02:00
John Crispin
8a68073f4f ucentral-schema: update to latest HEAD
remove a patch that was accidentally merged

Signed-off-by: John Crispin <john@phrozen.org>
2025-08-04 16:33:15 +02:00
John Crispin
efd804987e rtty: there was an error in the operationalpem passed to the client
Signed-off-by: John Crispin <john@phrozen.org>
2025-08-04 15:44:21 +02:00
jackcybertan
b036ba37e3 certificates: Store-PKI2.0-key-for-RAP6x-production
Fixes: WIFI-14951
Signed-off-by: jackcybertan <jack.tsai@cybertan.com.tw>
2025-08-04 08:39:53 +02:00
John Crispin
7352de2421 update to latest HEAD
e27ecb4 ssid: decouple batman tunnel from meshpoint interfaces

Signed-off-by: John Crispin <john@phrozen.org>
2025-08-04 08:36:13 +02:00
John Crispin
8c11eb23a3 mt7621: add insta1/2 partitions for yuncore ax820
Signed-off-by: John Crispin <john@phrozen.org>
2025-08-04 08:35:42 +02:00
Tanya Singh
83874b75f3 mediatek-sdk: Remove extra lines (for logging) from 99-mtk-sr-scene-cond
Signed-off-by: Tanya Singh <tanya_singh@accton.com>
2025-08-04 08:08:24 +02:00
John Crispin
694cf6ded8 rtty: use the operational certificate
Fixes: WIFI-14943
Signed-off-by: John Crispin <john@phrozen.org>
2025-07-31 17:50:14 +02:00
John Crispin
0a3a207584 uboot-envtools: add udaya-id5 support
Signed-off-by: John Crispin <john@phrozen.org>
2025-07-31 14:54:56 +02:00
Tanya Singh
b0e95e68a2 afc: Use either ca-cert or access-token to get authorization in curl command for the AFC server
Fixes:WIFI-14427
Signed-off-by: Tanya Singh <tanya_singh@accton.com>
2025-07-31 10:03:02 +02:00
Tanya Singh
26ed5acb60 rrmd: update timeout for RRM during self-healing and fix center channel mapping in RRM with Channel Utilization
Fixes: WIFI-14901
Signed-off-by: Tanya Singh <tanya_singh@accton.com>
2025-07-31 10:02:27 +02:00
John Crispin
d1e4c48617 cloud_discovery: add automatic reenrolment of operational certificates
The daemon will check the vailidity of the operational certificate once and hour.
If the certificate is valid for less than three days, a reenrollment is attempted.
Once the reenroll happened the connection to the cloud controller will be restarted.

Fixes: WIFI-14900
Fixes: WIFI-14694
Signed-off-by: John Crispin <john@phrozen.org>
2025-07-31 09:48:10 +02:00
Tanya Singh
3a8fc316f2 qca-wifi-7/afc: Use curl instead of uclient to send/receive AFC request/response using hostapd
Fixes: WIFI-14427
Signed-off-by: Tanya Singh <tanya_singh@accton.com>
2025-07-30 09:34:26 +02:00
jackcybertan
d85dc2a819 certificates: Enhance PKI enrollment on squashfs (SonicFi RAP6* series)
The updated flow:
- Mount /dev/mtdblock* (the certificates partition) to /mnt
- Copy its contents to /certificates
- Unmount /mnt
- Extract the PKI 2.0 certificates into /certificates

Fixes: WIFI-14904
Signed-off-by: jackcybertan <jack.tsai@cybertan.com.tw>
2025-07-30 09:04:52 +02:00
John Crispin
acca9737e4 ucentral-schema: update to latest HEAD
30c7374 Add 'access-token' to AFC server config

Fixes: WIFI-14427
Signed-off-by: John Crispin <john@phrozen.org>
2025-07-30 09:02:17 +02:00
Tanya Singh
6d2fd1de0d afc: Use curl instead of uclient to send/receive AFC request/response using hostapd
Fixes: WIFI-14427
Signed-off-by: Tanya Singh <tanya_singh@accton.com>
2025-07-30 09:02:05 +02:00
John Crispin
1d822a10d2 toolchain: use gcc11 for legacy targets
Signed-off-by: John Crispin <john@phrozen.org>
2025-07-28 09:51:18 +02:00
John Crispin
ebdc88ee1f certificates: improvements
* make the code more generic
* add udaya a2 support

Signed-off-by: John Crispin <john@phrozen.org>
2025-07-28 09:50:22 +02:00
John Crispin
778cc679a0 profiles: add more wifi-5 profiles
* edgecore_spw2ac1200
* hfcl_ion4

Signed-off-by: John Crispin <john@phrozen.org>
2025-07-27 19:35:04 +02:00
YenLin Pan
088d78faa7 qca-ssdk: adjust the amplitude level of SGMII for Zyxel NWA130BE
To fix EMI and avoid Ethernet RX stuck after reboot for Zyxel NWA130BE.
Ethernet Rx stuck was sometimes happened when we do stress reboot,
need to adjust the amplitude level of SGMII for CPU and QCA8385 side.
And those settings come from the result that Zyxel HW team and Manufacturer
co-work to fine tune for NWA130BE.

Signed-off-by: YenLin Pan <YenLin.Pan@zyxel.com.tw>
2025-07-27 19:24:15 +02:00
Tanya Singh
5306f7db27 cloud_discovery: Add 'sync' after file generation in Cloud discovery process
Fixes: WIFI-14906
Signed-off-by: Tanya Singh <tanya_singh@accton.com>
2025-07-27 17:40:03 +02:00
Tanya Singh
c8bffdc250 rrmd: Add self-healing in ucentral-state and channel switching improvements to RRM with channel utilization
Fixes: WIFI-14901
Signed-off-by: Tanya Singh <tanya_singh@accton.com>
2025-07-27 17:39:21 +02:00
John Crispin
3a3de9e146 ucentral-schema: update to latest HEAD
92fb3c1 WIFI-14901: Add rrm_chanutil status to health.uc (when it fails) and save health metric in /tmp/ucentral.health
6313892 WIFI-14906: Add 'sync' after file generation in Cloud discovery process

Signed-off-by: John Crispin <john@phrozen.org>
2025-07-27 17:03:48 +02:00
John Crispin
4d5c9a2d4c ucentral-client: update to latest HEAD
c536f69 cloud package manager

Fixes: WIFI-14588
Signed-off-by: John Crispin <john@phrozen.org>
2025-07-27 16:54:44 +02:00
John Crispin
41aa4c2978 cloud_discovery: set correct timeouts inside UCI
Fixes: WIFI-14897
Signed-off-by: John Crispin <john@phrozen.org>
2025-07-27 16:35:15 +02:00
37 changed files with 1202 additions and 104 deletions

View File

@@ -4,19 +4,19 @@ let fs = require("fs");
let ubus = require('ubus').connect();
let gps_info = ubus.call('gps', 'info');
let latitude = gps_info.latitude ?? 0;
let longitude = gps_info.longitude ?? 0;
let latitude = gps_info.latitude || 0;
let longitude = gps_info.longitude || 0;
// afc-location.json file content
let afc_location = {};
afc_location.location_type = "ellipse";
afc_location.location = longitude + ":" + latitude ;
afc_location.height = gps_info.elevation ?? 0;
afc_location.height = gps_info.elevation || 0;
afc_location.height_type = "AMSL";
afc_location.major_axis = gps_info.major_axis ?? 0;
afc_location.minor_axis = gps_info.minor_axis ?? 0;
afc_location.orientation = gps_info.major_orientation ?? 0;
afc_location.vertical_tolerance = gps_info.vdop ?? 0;
afc_location.major_axis = int(gps_info.major_axis) || 1;
afc_location.minor_axis = int(gps_info.minor_axis) || 1;
afc_location.orientation = gps_info.major_orientation || 0;
afc_location.vertical_tolerance = int(gps_info.vdop) || 1;
let afc_location_json = fs.open("/etc/ucentral/afc-location.json", "w");
afc_location_json.write(afc_location);

View File

@@ -1,7 +1,8 @@
let libubus = require("ubus");
import { open, readfile } from "fs";
import { open, readfile, writefile } from "fs";
import { wdev_create, wdev_remove, is_equal, vlist_new, phy_is_fullmac, phy_open } from "common";
let uci = require('uci').cursor();
let ubus = libubus.connect(null, 60);
hostapd.data.config = {};
@@ -893,10 +894,24 @@ return {
hostapd.ubus.disconnect();
},
afc_request: function(iface, data) {
let ret = ubus.call("afc", "request", { data });
if (type(ret) != "object")
return;
return ret.data;
let wireless_config = uci.get_all('wireless');
for (let l, afc_server in wireless_config) {
if (afc_server['.type'] == 'afc-server' && afc_server.url && data) {
hostapd.printf(`Sending AFC request: ${data}`);
writefile("/tmp/afc-request.json", data);
if (afc_server.access_token)
system(`curl -s -X POST ${afc_server.url} -H \'accept: \*\/\*\' -H \'Authorization: Bearer ${afc_server.access_token}\' -H \'Content-Type: application/json\' -d \'${data}\' --output /tmp/afc-response.json`);
else if (afc_server.cert)
system(`curl -s -X POST ${afc_server.url} -H \'accept: \*\/\*\' --cert \'${afc_server.cert}\' -H \'Content-Type: application/json\' -d \'${data}\' --output /tmp/afc-response.json`);
let afc_response = (readfile("/tmp/afc-response.json"));
if (afc_response)
return afc_response;
else
return;
}
}
},
bss_add: function(name, obj) {
bss_event("add", name);

View File

@@ -107,29 +107,42 @@ platform_do_upgrade() {
board=$(board_name)
case $board in
glinet,b3000|\
edgecore,oap101|\
edgecore,oap101-6e|\
edgecore,oap101e|\
edgecore,oap101e-6e|\
edgecore,eap104)
if [ "$(find_mtd_chardev rootfs)" ]; then
CI_UBIPART="rootfs"
else
if grep -q rootfs1 /proc/cmdline; then
CI_UBIPART="rootfs2"
CI_FWSETENV="active 2"
else
CI_UBIPART="rootfs1"
CI_FWSETENV="active 1"
fi
fi
nand_upgrade_tar "$1"
;;
glinet,b3000)
CI_UBIPART="rootfs1"
[ "$(find_mtd_chardev rootfs)" ] && CI_UBIPART="rootfs"
nand_upgrade_tar "$1"
;;
hfcl,ion4x_w|\
hfcl,ion4x_w|\
hfcl,ion4xi_w)
wp_part=$(fw_printenv primary | cut -d = -f2)
echo "Current Primary is $wp_part"
if [[ $wp_part == 1 ]]; then
CI_UBIPART="rootfs"
CI_FWSETENV="primary 0"
else
CI_UBIPART="rootfs_1"
CI_FWSETENV="primary 1"
fi
nand_upgrade_tar "$1"
;;
wp_part=$(fw_printenv primary | cut -d = -f2)
echo "Current Primary is $wp_part"
if [[ $wp_part == 1 ]]; then
CI_UBIPART="rootfs"
CI_FWSETENV="primary 0"
else
CI_UBIPART="rootfs_1"
CI_FWSETENV="primary 1"
fi
nand_upgrade_tar "$1"
;;
cig,wf186w|\
cig,wf186h|\
emplus,wap385c|\

View File

@@ -0,0 +1,61 @@
--- a/include/init/ssdk_plat.h
+++ b/include/init/ssdk_plat.h
@@ -330,6 +330,7 @@ struct qca_phy_priv {
struct mii_bus *miibus;
/*qca808x_end*/
u64 *mib_counters;
+ a_uint32_t mib_loop_cnt;
/* dump buf */
a_uint8_t buf[2048];
a_uint32_t link_polling_required;
--- a/src/ref/ref_mib.c
+++ b/src/ref/ref_mib.c
@@ -479,39 +479,37 @@ qca_ar8327_sw_get_port_mib(struct switch
#endif
int
-_qca_ar8327_sw_capture_port_tx_counter(struct qca_phy_priv *priv, int port)
+_qca_ar8327_sw_capture_port_tx_counter(a_uint32_t dev_id, int port)
{
fal_mib_info_t mib_Info;
memset(&mib_Info, 0, sizeof(fal_mib_info_t));
- fal_get_tx_mib_info(priv->device_id, port, &mib_Info);
+ fal_get_tx_mib_info(dev_id, port, &mib_Info);
return 0;
}
int
-_qca_ar8327_sw_capture_port_rx_counter(struct qca_phy_priv *priv, int port)
+_qca_ar8327_sw_capture_port_rx_counter(a_uint32_t dev_id, int port)
{
fal_mib_info_t mib_Info;
memset(&mib_Info, 0, sizeof(fal_mib_info_t));
- fal_get_rx_mib_info(priv->device_id, port, &mib_Info);
+ fal_get_rx_mib_info(dev_id, port, &mib_Info);
return 0;
}
void
qca_ar8327_sw_mib_task(struct qca_phy_priv *priv)
{
- static int loop = 0;
-
mutex_lock(&priv->reg_mutex);
- if ((loop % 2) == 0)
- _qca_ar8327_sw_capture_port_rx_counter(priv, loop/2);
+ if ((priv->mib_loop_cnt % 2) == 0)
+ _qca_ar8327_sw_capture_port_rx_counter(priv->device_id, priv->mib_loop_cnt/2);
else
- _qca_ar8327_sw_capture_port_tx_counter(priv, loop/2);
+ _qca_ar8327_sw_capture_port_tx_counter(priv->device_id, priv->mib_loop_cnt/2);
- if(++loop == (2 * (priv->ports))) {
- loop = 0;
+ if(++priv->mib_loop_cnt == (2 * (priv->ports))) {
+ priv->mib_loop_cnt = 0;
}
mutex_unlock(&priv->reg_mutex);

View File

@@ -200,7 +200,7 @@
phy-mode = "sgmii";
full-duplex;
pause;
airoha,surge = <1>;
airoha,surge = <0>;
airoha,polarity = <2>;
};

View File

@@ -34,13 +34,11 @@ case "$board" in
if [ -f "$phy0_file" ]; then
check_phy0=$(cat $phy0_file)
echo "check_phy0 = $check_phy0"
[ "$check_phy0" == 0 ] && echo 1 > $phy0_file
fi
if [ -f "$phy1_file" ]; then
check_phy1=$(cat $phy1_file)
echo "check_phy1 = $check_phy1"
[ "$check_phy1" == 0 ] && echo 1 > $phy1_file
fi

View File

@@ -4,19 +4,19 @@ let fs = require("fs");
let ubus = require('ubus').connect();
let gps_info = ubus.call('gps', 'info');
let latitude = gps_info.latitude ?? 0;
let longitude = gps_info.longitude ?? 0;
let latitude = gps_info.latitude || 0;
let longitude = gps_info.longitude || 0;
// afc-location.json file content
let afc_location = {};
afc_location.location_type = "ellipse";
afc_location.location = longitude + ":" + latitude ;
afc_location.height = gps_info.elevation ?? 0;
afc_location.height = gps_info.elevation || 0;
afc_location.height_type = "AMSL";
afc_location.major_axis = gps_info.major_axis ?? 0;
afc_location.minor_axis = gps_info.minor_axis ?? 0;
afc_location.orientation = gps_info.major_orientation ?? 0;
afc_location.vertical_tolerance = gps_info.vdop ?? 0;
afc_location.major_axis = int(gps_info.major_axis) || 1;
afc_location.minor_axis = int(gps_info.minor_axis) || 1;
afc_location.orientation = gps_info.major_orientation || 0;
afc_location.vertical_tolerance = int(gps_info.vdop) || 1;
let afc_location_json = fs.open("/etc/ucentral/afc-location.json", "w");
afc_location_json.write(afc_location);

View File

@@ -1,7 +1,8 @@
let libubus = require("ubus");
import { open, readfile } from "fs";
import { open, readfile, writefile } from "fs";
import { wdev_remove, is_equal, vlist_new, phy_is_fullmac, phy_open, wdev_set_radio_mask } from "common";
let uci = require('uci').cursor();
let ubus = libubus.connect(null, 60);
hostapd.data.config = {};
@@ -1006,7 +1007,6 @@ let main_obj = {
hostapd.data.ubus = ubus;
hostapd.data.obj = ubus.publish("hostapd", main_obj);
let auth_obj = {};
hostapd.data.auth_obj = ubus.publish("hostapd-auth", auth_obj);
@@ -1026,10 +1026,24 @@ return {
hostapd.ubus.disconnect();
},
afc_request: function(iface, data) {
let ret = ubus.call("afc", "request", { data });
if (type(ret) != "object")
return;
return ret.data;
let wireless_config = uci.get_all('wireless');
for (let l, afc_server in wireless_config) {
if (afc_server['.type'] == 'afc-server' && afc_server.url && data) {
hostapd.printf(`Sending AFC request: ${data}`);
writefile("/tmp/afc-request.json", data);
if (afc_server.access_token)
system(`curl -s -X POST ${afc_server.url} -H \'accept: \*\/\*\' -H \'Authorization: Bearer ${afc_server.access_token}\' -H \'Content-Type: application/json\' -d \'${data}\' --output /tmp/afc-response.json`);
else if (afc_server.cert)
system(`curl -s -X POST ${afc_server.url} -H \'accept: \*\/\*\' --cert \'${afc_server.cert}\' -H \'Content-Type: application/json\' -d \'${data}\' --output /tmp/afc-response.json`);
let afc_response = (readfile("/tmp/afc-response.json"));
if (afc_response)
return afc_response;
else
return;
}
}
},
bss_create: function(phy, name, obj) {
phy = hostapd.data.config[phy];

View File

@@ -31,6 +31,20 @@
stdout-path = "serial0";
};
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
ramoops@49c00000 {
compatible = "ramoops";
reg = <0x0 0x49c00000 0x0 0x100000>;
record-size = <0x20000>;
console-size = <0x20000>;
pmsg-size = <0x20000>;
};
};
soc@0 {
mdio:mdio@90000 {
pinctrl-0 = <&mdio1_pins>;

View File

@@ -190,6 +190,14 @@
/delete-node/ wcnss@4a900000;
/delete-node/ q6_caldb_region@4ce00000;
ramoops@49c00000 {
compatible = "ramoops";
reg = <0x0 0x49c00000 0x0 0x100000>;
record-size = <0x20000>;
console-size = <0x20000>;
pmsg-size = <0x20000>;
};
q6_mem_regions: q6_mem_regions@4A900000 {
no-map;
reg = <0x0 0x4A900000 0x0 0x5100000>;

View File

@@ -190,6 +190,14 @@
/delete-node/ wcnss@4a900000;
/delete-node/ q6_caldb_region@4ce00000;
ramoops@49c00000 {
compatible = "ramoops";
reg = <0x0 0x49c00000 0x0 0x100000>;
record-size = <0x20000>;
console-size = <0x20000>;
pmsg-size = <0x20000>;
};
q6_mem_regions: q6_mem_regions@4A900000 {
no-map;
reg = <0x0 0x4A900000 0x0 0x5100000>;

View File

@@ -190,6 +190,14 @@
/delete-node/ wcnss@4a900000;
/delete-node/ q6_caldb_region@4ce00000;
ramoops@49c00000 {
compatible = "ramoops";
reg = <0x0 0x49c00000 0x0 0x100000>;
record-size = <0x20000>;
console-size = <0x20000>;
pmsg-size = <0x20000>;
};
q6_mem_regions: q6_mem_regions@4A900000 {
no-map;
reg = <0x0 0x4A900000 0x0 0x5100000>;

View File

@@ -100,6 +100,7 @@ endif
ifdef CONFIG_TARGET_PROFILE
TARGET_PROFILE=$(subst ",,$(CONFIG_TARGET_PROFILE))
PATCH_PROFILE_NAME=patches-$(subst DEVICE_,,$(TARGET_PROFILE))
FILES_PROFILE_NAME=files-$(subst DEVICE_,,$(TARGET_PROFILE))
endif
QCASSDK_CONFIG_OPTS+= TOOL_PATH=$(TOOLCHAIN_BIN_PATH) \
@@ -202,6 +203,15 @@ define patch_profile
$(call PatchDir/Default,$(PKG_BUILD_DIR),./$(PATCH_PROFILE_NAME))
endef
define files_profile
if [ -d "./$(FILES_PROFILE_NAME)" ]; then \
$(CP) ./$(FILES_PROFILE_NAME)/* ./files/ ; \
fi
endef
Hooks/Prepare/Post += patch_profile
Hooks/Prepare/Post += files_profile
$(eval $(call KernelPackage,qca-ssdk-qca-nohnat))
$(eval $(call KernelPackage,qca-ssdk-qca-hnat))

View File

@@ -0,0 +1,317 @@
#!/bin/sh /etc/rc.common
# Copyright (c) 2018, 2021, The Linux Foundation. All rights reserved.
# Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
#
# Permission to use, copy, modify, and/or 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
#
START=16
#!/bin/sh
ruletype="ip4 ip6"
side="wan lan"
qwan="1 3 2 0 5 7 6 4"
qlan="0 1 2 3 4 5 6 7"
function create_war_acl_rules(){
for lw in $side
do
#echo $lw
if [ "$lw" == "wan" ];then
listid=254
queue=$qwan
portmap=0x20
else
listid=255
queue=$qlan
portmap=0x1e
fi
#echo $queue
#echo "creating list $listid"
ssdk_sh acl list create $listid 255
ruleid=0
for rt in $ruletype
do
for qid in $queue
do
cmd="ssdk_sh acl rule add $listid $ruleid 1 n 0 0"
#echo $cmd
if [ "$rt" == "ip4" ];then
cmd="$cmd ip4 n n n n n n n n n n n n n n n n n n n n n n n n n n n n n"
#echo $cmd
else
cmd="$cmd ip6 n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n"
#echo $cmd
fi
if [ $ruleid -le 3 ];then
#non-zero dscp
cmd="$cmd y 0x0 0xff"
elif [ $ruleid -le 7 ];then
#zero dscp
cmd="$cmd n"
elif [ $ruleid -le 11 ];then
#non-zero dscp
cmd="$cmd y 0x0 0xff"
else
#zero dscp
cmd="$cmd n"
fi
p=$((ruleid/2))
cmd="$cmd y mask $((ruleid%2)) 0x1 y mask $((p%2)) 0x1 n n n n n n n n n n n n n n n y n n n n n n n y $qid n n 0 0 n n n n n n n n n n n n n n n n n n n n 0"
#echo $cmd
$cmd
ruleid=`expr $ruleid + 1`
done
done
ssdk_sh acl list bind $listid 0 1 $portmap
done
}
function create_war_cosmap(){
ssdk_sh cosmap pri2q set 0 0
ssdk_sh cosmap pri2q set 1 0
ssdk_sh cosmap pri2q set 2 0
ssdk_sh cosmap pri2q set 3 0
ssdk_sh cosmap pri2q set 4 1
ssdk_sh cosmap pri2q set 5 1
ssdk_sh cosmap pri2q set 6 1
ssdk_sh cosmap pri2q set 7 1
ssdk_sh cosmap pri2ehq set 0 0
ssdk_sh cosmap pri2ehq set 1 0
ssdk_sh cosmap pri2ehq set 2 0
ssdk_sh cosmap pri2ehq set 3 0
ssdk_sh cosmap pri2ehq set 4 1
ssdk_sh cosmap pri2ehq set 5 1
ssdk_sh cosmap pri2ehq set 6 1
ssdk_sh cosmap pri2ehq set 7 1
}
function create_acl_byp_egstp_rules(){
chip_ver=$1
cmd="ssdk_sh servcode config set 1 n 0 0xfffefc7f 0xffbdff 0 0 0 0 0 0"
if [ "$chip_ver" == "0x2000" ] || [ "$chip_ver" = "0x2001" ] || [ "$chip_ver" = "0x2100" ]; then
cmd="$cmd 0"
fi
#echo $cmd
$cmd
ssdk_sh acl list create 56 48
#action bypass eg stp check
action="y n n n n n n n n n n 0 0 n n n n n n n n n n n n n y n n n n n n n n n n n n y n n n n n n n n n n n n n n n n n n"
if [ "$chip_ver" == "0x2000" ]; then
action="$action n n 0"
elif [ "$chip_ver" = "0x2001" ] || [ "$chip_ver" = "0x2100" ]; then
action="$action n n n 0"
else
action="$action 0"
fi
for ruleid in $( seq 0 2 )
do
if [ "$ruleid" == "0" ];then
cmd="ssdk_sh acl rule add 56 0 1 n 0 0 mac n n n n n y 01-80-c2-00-00-00 ff-ff-ff-ff-ff-ff n n n n n n n n n n n n n n n n n n n n n n n"
elif [ "$ruleid" == "1" ];then
cmd="ssdk_sh acl rule add 56 1 1 n 0 0 mac n n n n n n n yes 0x8809 0xffff n n n n n n n n n n n n n n n n n n n n n"
else
cmd="ssdk_sh acl rule add 56 2 1 n 0 0 mac n n n n n n n yes 0x888e 0xffff n n n n n n n n n n n n n n n n n n n n n"
fi
if [ "$chip_ver" == "0x2000" ] || [ "$chip_ver" = "0x2001" ] || [ "$chip_ver" = "0x2100" ]; then
cmd="$cmd n $action"
else
cmd="$cmd $action"
fi
#echo $cmd
$cmd
done
ssdk_sh acl list bind 56 0 2 1
}
function delete_war_acl_rules(){
for lw in $side
do
#echo $lw
if [ "$lw" == "wan" ];then
listid=254
queue=$qwan
portmap=0x20
else
listid=255
queue=$qlan
portmap=0x1e
fi
ssdk_sh acl list unbind $listid 0 1 $portmap
for rt in $ruletype
do
for qid in $queue
do
cmd="ssdk_sh acl rule del $listid 0 1"
echo $cmd
$cmd
done
done
#echo "deleting list $listid"
ssdk_sh acl list destroy $listid
done
}
function delete_war_cosmap(){
ssdk_sh cosmap pri2q set 0 0
ssdk_sh cosmap pri2q set 1 0
ssdk_sh cosmap pri2q set 2 1
ssdk_sh cosmap pri2q set 3 1
ssdk_sh cosmap pri2q set 4 2
ssdk_sh cosmap pri2q set 5 2
ssdk_sh cosmap pri2q set 6 3
ssdk_sh cosmap pri2q set 7 3
ssdk_sh cosmap pri2ehq set 0 1
ssdk_sh cosmap pri2ehq set 1 0
ssdk_sh cosmap pri2ehq set 2 2
ssdk_sh cosmap pri2ehq set 3 2
ssdk_sh cosmap pri2ehq set 4 3
ssdk_sh cosmap pri2ehq set 5 3
ssdk_sh cosmap pri2ehq set 6 4
ssdk_sh cosmap pri2ehq set 7 5
}
function delete_acl_byp_egstp_rules(){
chip_ver=$1
cmd="ssdk_sh servcode config set 1 n 0 0xfffefcff 0xffbfff 0 0 0 0 0 0"
if [ "$chip_ver" == "0x2000" ] || [ "$chip_ver" = "0x2001" ] || [ "$chip_ver" = "0x2100" ]; then
cmd="$cmd 0"
fi
#echo $cmd
$cmd
ssdk_sh acl list unbind 56 0 2 1
ssdk_sh acl rule del 56 0 1
ssdk_sh acl rule del 56 1 1
ssdk_sh acl rule del 56 2 1
ssdk_sh acl list destroy 56
}
function edma_war_config_add(){
create_war_cosmap
ssdk_sh acl status set enable
create_war_acl_rules
}
function edma_war_config_del(){
delete_war_acl_rules
delete_war_cosmap
}
function ipq50xx_serdes_monitor () {
#if qca808x phy exist, need to monitor the serdes to avoid the effect for WIFI
port_id=2
old_linkstatus="DISABLE"
phy_id_info=`ssdk_sh port phyid get $port_id | grep Org | awk -F '!' '{print $2}'`
if [ "$phy_id_info" = "[Org ID]:0x004d[Rev ID]:0xd101" ]; then
ssdk_sh debug phy set 29 0xb 0x300d
ssdk_sh debug uniphy set 0 0x7ac 0x300d 4
while true
do
cur_linkstatus=`ssdk_sh port linkstatus get $port_id | grep Status | awk -F ':' '{print $2}'`
#when qca808x phy link status is from down to up, serdes tx would be enabled
if [ "$cur_linkstatus" = "ENABLE" ] && [ "$old_linkstatus" = "DISABLE" ]; then
ssdk_sh debug phy set 29 0xb 0xb00d
ssdk_sh debug uniphy set 0 0x7ac 0xb00d 4
fi
#when qca808x phy link status is from up to down, serdes tx would be disabled
if [ "$cur_linkstatus" = "DISABLE" ] && [ "$old_linkstatus" = "ENABLE" ]; then
ssdk_sh debug phy set 29 0xb 0x300d
ssdk_sh debug uniphy set 0 0x7ac 0x300d 4
fi
old_linkstatus=$cur_linkstatus
done
fi
}
function ipq53xx_phy_amplitude_set () {
#for qca808x phy sgmii, set half amplitude with src_half_swing register
port_id=2
phy_id_info=`ssdk_sh port phyid get $port_id | grep Org | awk -F '!' '{print $2}'`
if [ "$phy_id_info" = "[Org ID]:0x004d[Rev ID]:0xd180" ]; then
ssdk_sh debug phy set 5 0x40010087 0x208a
ssdk_sh debug phy set 6 0x40010087 0x208a
#Set the Reg0x67 bits[7:5]=3b000 and bit4=1b1
ampl_val=$(eval "ssdk_sh debug phy get 5 0x40010067 | grep SSDK | grep -oE '0x[0-9a-fA-F]+' | sed 's/\(0x..\)./\11/'")
ssdk_sh debug phy set 5 0x40010067 $ampl_val
ampl_val=$(eval "ssdk_sh debug phy get 6 0x40010067 | grep SSDK | grep -oE '0x[0-9a-fA-F]+' | sed 's/\(0x..\)./\11/'")
ssdk_sh debug phy set 6 0x40010067 $ampl_val
fi
}
function ipq53xx_uniphy_amplitude_set () {
#for ipq50xx sgmii, set half amplitude with tx_emp_lvl/margin_index and tx_margin
ssdk_sh debug uniphy set 0 0x7ac 0xb10d 4
ssdk_sh debug uniphy set 0 0x24 0 4
ssdk_sh debug uniphy set 1 0x7ac 0xb10d 4
ssdk_sh debug uniphy set 1 0x24 0 4
}
ssdk_dependency() {
counter=0
[ -e /lib/modules/$(uname -r)/qca-ssdk.ko ] && [ ! -d /sys/module/qca_ssdk ] && {
insmod qca-ssdk.ko
}
while [ ! -d /sys/ssdk ] && [ "$counter" -le 5 ]
do
sleep 1
counter=$((counter+1))
done
}
start() {
ssdk_dependency
chip_ver=`ssdk_sh debug reg get 0 4 | grep Data | tr -d 'SSDK Init OK![Data]:'`
#The following commands should be uncommented to enable EDMA WAR
if [ "$chip_ver" = "0x1401" ]; then
#edma_war_config_add
echo ''
fi
#The following commands should be uncommented to add acl egress stp bypass rules
if [ "$chip_ver" = "0x1500" ] || [ "$chip_ver" = "0x1501" ] || [ "$chip_ver" = "0x2000" ] || [ "$chip_ver" = "0x2001" ] || [ "$chip_ver" = "0x2100" ]; then
#create_acl_byp_egstp_rules $chip_ver
echo ''
fi
#The following commands should be uncommented to enable WAR for ipq50xx
chip_type_info=`cat tmp/sysinfo/model`
result=$(echo $chip_type_info | grep "IPQ5018")
if [ "$result" != "" ]; then
#ipq50xx_serdes_monitor &
#ipq50xx_uniphy_amplitude_set
#ipq50xx_phy_amplitude_set
echo ''
fi
if [ "$chip_ver" = "0x2001" ]; then
ipq53xx_uniphy_amplitude_set
ipq53xx_phy_amplitude_set
echo ''
fi
echo starting
}
stop() {
chip_ver=`ssdk_sh debug reg get 0 4 | grep Data | tr -d 'SSDK Init OK![Data]:'`
#The following commands should be uncommented to disable EDMA WAR
if [ "$chip_ver" = "0x1401" ]; then
#edma_war_config_del
echo ''
fi
#The following commands should be uncommented to delete acl egress stp bypass rules
if [ "$chip_ver" = "0x1500" ] || [ "$chip_ver" = "0x1501" ] || [ "$chip_ver" = "0x2000" ] || [ "$chip_ver" = "0x2001" ] || [ "$chip_ver" = "0x2100" ]; then
#delete_acl_byp_egstp_rules $chip_ver
echo ''
fi
echo stoping
}

View File

@@ -20,6 +20,7 @@ copy_certificates() {
[ -z "$country" ] && country=US
echo "options cfg80211 ieee80211_regdom="$country > /etc/modules.conf
echo -n $country > /etc/ucentral/country
sync
exit 0
}

View File

@@ -6,13 +6,16 @@ check_certificates() {
check_certificates
bootconfig_lookup() {
case "$(fw_printenv -n cert_part)" in
0) echo "0:BOOTCONFIG"
;;
1) echo "0:BOOTCONFIG1"
;;
esac
tar_part_lookup() {
part="$(fw_printenv -n cert_part)"
if [ "$part" -eq 0 ]; then
echo "$2"
part=1
else
echo "$1"
part=0
fi
fw_setenv cert_part $part
}
. /lib/functions.sh
@@ -35,13 +38,40 @@ sonicfi,rap7*)
[ -n "$mtd" ] && mount -t ext4 /dev/mtdblock$mtd /certificates
fi
if [ ! -f /certificates/cert.pem ] || [ ! -f /certificates/key.pem ]; then
bootconfig=$(bootconfig_lookup)
if [ -n "$bootconfig" ]; then
mmc_dev=$(echo $(find_mmc_part "$bootconfig") | sed 's/^.\{5\}//')
part=$(tar_part_lookup "0:BOOTCONFIG" "0:BOOTCONFIG1")
if [ -n "part" ]; then
mmc_dev=$(echo $(find_mmc_part "$part") | sed 's/^.\{5\}//')
[ -n "$mmc_dev" ] && tar xf /dev/$mmc_dev -C /certificates
fi
fi
;;
udaya,a5-id2|\
yuncore,ax820)
mtd=$(find_mtd_index certificates)
if [ "$(head -c 4 /dev/mtd$mtd)" == "hsqs" ]; then
mount -t squashfs /dev/mtdblock$mtd /mnt
cp /mnt/* /certificates
umount /mnt
fi
part=$(tar_part_lookup "insta1" "insta2")
if [ -n "insta" ]; then
mtd=$(find_mtd_index $part)
[ -n "$mtd" ] && tar xf /dev/mtdblock$mtd -C /certificates
fi
;;
sonicfi,rap6*)
mtd=$(find_mtd_index certificates)
if [ "$(head -c 4 /dev/mtd$mtd)" == "hsqs" ]; then
mount -t squashfs /dev/mtdblock$mtd /mnt
cp /mnt/* /certificates
umount /mnt
fi
part=$(tar_part_lookup "devinfo" "certificates")
if [ -n "$part" ]; then
mtd=$(find_mtd_index $part)
[ -n "$mtd" ] && tar xf /dev/mtdblock$mtd -C /certificates
fi
;;
*)
mtd=$(find_mtd_index certificates)

View File

@@ -1,25 +1,44 @@
#!/bin/sh
bootconfig_lookup() {
bootconfig="$(fw_printenv -n cert_part)"
case "$(fw_printenv -n cert_part)" in
0) echo "0:BOOTCONFIG1"
bootconfig=1
;;
*) echo "0:BOOTCONFIG"
bootconfig=0
;;
esac
fw_setenv cert_part $bootconfig
tar_part_lookup() {
part="$(fw_printenv -n cert_part)"
if [ "$part" -eq 0 ]; then
echo "$2"
part=1
else
echo "$1"
part=0
fi
fw_setenv cert_part $part
}
. /lib/functions.sh
case "$(board_name)" in
sonicfi,rap7110c-341x)
cd /certificates
tar cf /tmp/certs.tar
bootconfig=$(bootconfig_lookup)
mmc_dev=$(echo $(find_mmc_part $bootconfig) | sed 's/^.\{5\}//')
dd if=/tmp/certs.tar of=/dev/$bootconfig
tar cf /tmp/certs.tar .
part=$(tar_part_lookup "0:BOOTCONFIG" "0:BOOTCONFIG1")
mmc_dev=$(echo $(find_mmc_part $part) | sed 's/^.\{5\}//')
dd if=/tmp/certs.tar of=/dev/$mmc_dev
;;
udaya,a5-id2|\
yuncore,ax820)
cd /certificates
tar cf /tmp/certs.tar .
part=$(tar_part_lookup "insta1" "insta2")
mtd=$(find_mtd_index $part)
dd if=/tmp/certs.tar of=/dev/mtdblock$mtd
;;
sonicfi,rap6*)
if [ "$(fw_printenv -n store_certs_disabled)" != "1" ]; then
cd /certificates
tar cf /tmp/certs.tar .
part=$(tar_part_lookup "devinfo" "certificates")
mtd=$(find_mtd_index $part)
block_size=$(cat /sys/class/mtd/mtd$mtd/size)
dd if=/tmp/certs.tar of=/tmp/certs_pad.tar bs=$block_size conv=sync
mtd write /tmp/certs_pad.tar /dev/mtd$mtd
rm -f /tmp/certs.tar /tmp/certs_pad.tar
fi
;;
esac

View File

@@ -22,6 +22,19 @@ start_service() {
[ "$valid" == "true" ] ||
/usr/share/ucentral/ucentral.uc /etc/ucentral/ucentral.cfg.0000000001 > /dev/null
est_client check
[ $? -eq 1 ] && {
logger ERROR
logger ERROR
logger ERROR
logger The certificate used has a CN that does not match the serial of the device
echo The certificate used has a CN that does not match the serial of the device
logger ERROR
logger ERROR
logger ERROR
return
}
procd_open_instance
procd_set_param command "$PROG"
procd_set_param respawn

View File

@@ -15,9 +15,14 @@ const ONLINE = 2;
const OFFLINE = 3;
const ORPHAN = 4;
const DISCOVER_DHCP = "DHCP";
const DISCOVER_FLASH = "FLASH";
const DISCOVER_LOOKUP = "OpenLAN";
let ubus = libubus.connect();
let uci = libuci.cursor();
let state = DISCOVER;
let discovery_method = "";
let validate_time;
let offline_time;
let orphan_time;
@@ -27,6 +32,8 @@ let timeouts = {
'validate': 120,
'orphan': 2 * 60 * 60,
interval: 10000,
expiry_interval: 60 * 60 * 1000,
expiry_threshold: 1 * 365 * 24 * 60 * 60,
};
ulog_open(ULOG_SYSLOG | ULOG_STDIO, LOG_DAEMON, "cloud_discover");
@@ -35,6 +42,24 @@ ulog(LOG_INFO, 'Start\n');
uloop.init();
let cds_server = 'discovery.open-lan.org';
function detect_certificate_type() {
let pipe = fs.popen(`openssl x509 -in /etc/ucentral/cert.pem -noout -issuer`);
let issuer = pipe.read("all");
pipe.close();
if (match(issuer, /OpenLAN Demo Birth CA/)) {
ulog(LOG_INFO, 'Certificate type is "Demo" \n');
cds_server = 'discovery-qa.open-lan.org';
timeouts.expiry_threshold = 3 * 24 * 60 * 60;
} else if (match(issuer, /OpenLAN Birth Issuing CA/)) {
ulog(LOG_INFO, 'Certificate type is "Production"\n');
} else {
ulog(LOG_INFO, 'Certificate type is "TIP"\n');
}
}
function readjsonfile(path) {
let file = fs.readfile(path);
if (file)
@@ -76,6 +101,14 @@ function gateway_load() {
return readjsonfile('/etc/ucentral/gateway.json');
}
function discovery_state_write() {
let discovery_state = {
"type": discovery_method,
"updated": time()
};
fs.writefile('/etc/ucentral/discovery.state.json', discovery_state);
}
function gateway_write(data) {
let gateway = gateway_load();
gateway ??= {};
@@ -89,8 +122,10 @@ function gateway_write(data) {
if (new[key] != gateway[key])
changed = true;
}
if (changed)
if (changed) {
fs.writefile('/etc/ucentral/gateway.json', new);
system('sync');
}
return changed;
}
@@ -127,6 +162,7 @@ function set_state(set) {
if (prev == VALIDATING) {
ulog(LOG_INFO, 'Setting cloud controller to validated\n');
gateway_write({ valid: true });
discovery_state_write();
}
break;
@@ -161,7 +197,7 @@ function redirector_lookup() {
let serial = uci.get('system', '@system[-1]', 'mac');
fs.unlink(path);
system(`curl -k --cert /etc/ucentral/operational.pem --key /etc/ucentral/key.pem --cacert /etc/ucentral/operational.ca https://openlan.keys.tip.build/v1/devices/${serial} --output /tmp/ucentral.redirector`);
system(`curl -k --cert /etc/ucentral/operational.pem --key /etc/ucentral/key.pem --cacert /etc/ucentral/operational.ca https://${cds_server}/v1/devices/${serial} --output /tmp/ucentral.redirector`);
if (!fs.stat(path))
return;
let redir = readjsonfile(path);
@@ -224,15 +260,18 @@ function interval_handler() {
if (!time_is_valid())
return;
discovery_method = DISCOVER_DHCP;
if (discover_dhcp())
return;
if (system('/usr/bin/est_client enroll'))
return;
discovery_method = DISCOVER_FLASH;
if (!discover_flash())
return;
discovery_method = DISCOVER_LOOKUP;
redirector_lookup();
break;
@@ -252,6 +291,36 @@ function interval_handler() {
}
}
function trigger_reenroll() {
ulog(LOG_INFO, 'triggering reenroll\n');
if (system('/usr/bin/est_client reenroll')) {
ulog(LOG_INFO, 'reenroll failed\n');
return;
}
ulog(LOG_INFO, 'reenroll succeeded\n');
ulog(LOG_INFO, 'stopping client\n');
system('/etc/init.d/ucentral stop');
set_state(DISCOVER);
}
function expiry_handler() {
let stat = fs.stat('/etc/ucentral/operational.ca');
if (!stat)
return;
let ret = system(`openssl x509 -checkend ${timeouts.expiry_threshold} -noout -in /certificates/operational.pem`);
if (!ret) {
ulog(LOG_INFO, 'checked certificate expiry - all ok\n');
return;
}
ulog(LOG_INFO, 'certificate will expire soon\n');
trigger_reenroll();
}
let ubus_methods = {
discover: {
call: function(req) {
@@ -326,8 +395,17 @@ let ubus_methods = {
},
args: {},
},
reenroll: {
call: function(req) {
trigger_reenroll();
return 0;
},
args: {},
},
};
detect_certificate_type();
if (gateway_available()) {
let status = ubus.call('ucentral', 'status');
ulog(LOG_INFO, 'cloud is known\n');
@@ -344,6 +422,7 @@ if (gateway_available()) {
timeouts_load();
interval = uloop.interval(timeouts.interval, interval_handler);
uloop.interval(timeouts.expiry_interval, expiry_handler);
ubus.publish('cloud', ubus_methods);

View File

@@ -4,12 +4,28 @@
import { ulog_open, ulog, ULOG_SYSLOG, ULOG_STDIO, LOG_DAEMON, LOG_INFO } from 'log';
import * as fs from 'fs';
import * as libuci from 'uci';
let store_operational_pem = false;
let store_operational_ca = false;
let est_server = 'qaest.certificates.open-lan.org:8001';
let est_server = 'est.certificates.open-lan.org';
let cert_prefix = 'operational';
function set_est_server() {
let pipe = fs.popen(`openssl x509 -in /etc/ucentral/cert.pem -noout -issuer`);
let issuer = pipe.read("all");
pipe.close();
if (match(issuer, /OpenLAN Demo Birth CA/)) {
ulog(LOG_INFO, 'Certificate type is "Demo" \n');
est_server = 'qaest.certificates.open-lan.org:8001';
} else if (match(issuer, /OpenLAN Birth Issuing CA/)) {
ulog(LOG_INFO, 'Certificate type is "Production"\n');
} else {
ulog(LOG_INFO, 'Certificate type is "TIP"\n');
}
}
if (getenv('EST_SERVER'))
est_server = getenv('EST_SERVER');
@@ -78,6 +94,8 @@ function call_est_server(path, cert, target) {
if (generate_csr(cert))
return 1;
set_est_server();
let ret = system('curl -m 10 -X POST https://' + est_server + '/.well-known/est/' + path + ' -d @/tmp/csr.nohdr.p10 -H "Content-Type: application/pkcs10" --cert ' + cert + ' --key /etc/ucentral/key.pem --cacert /etc/ucentral/insta.pem -o /tmp/operational.nohdr.p7');
if (ret) {
ulog(LOG_INFO, 'Failed to request operational certificate\n');
@@ -125,6 +143,9 @@ function load_operational_ca() {
ulog(LOG_INFO, 'Operational CA is present\n');
return 0;
}
set_est_server();
let ret = system('curl -m 10 -X GET https://' + est_server + '/.well-known/est/cacerts --cert /etc/ucentral/' + cert_prefix + '.pem --key /etc/ucentral/key.pem --cacert /etc/ucentral/insta.pem -o /tmp/' + cert_prefix + '.ca.nohdr.p7');
if (!ret)
ret = p7_too_pem('/tmp/' + cert_prefix + '.ca.nohdr.p7', '/etc/ucentral/' + cert_prefix + '.ca');
@@ -139,11 +160,14 @@ function load_operational_ca() {
}
function fwtool() {
if (!fs.stat('/etc/ucentral/cert.pem'))
return 0;
let pipe = fs.popen(`openssl x509 -in /etc/ucentral/cert.pem -noout -issuer`);
let issuer = pipe.read("all");
pipe.close();
if (!(match(issuer, /OpenLAN/) && match(issuer, /Birth CA/)))
if (!(match(issuer, /OpenLAN/) && match(issuer, /Birth/)))
return 0;
ulog(LOG_INFO, 'The issuer is insta\n');
@@ -163,6 +187,20 @@ function fwtool() {
return 0;
}
function check_cert() {
if (!fs.stat('/etc/ucentral/cert.pem'))
return 0;
let pipe = fs.popen("openssl x509 -in /etc/ucentral/cert.pem -noout -subject -nameopt multiline | grep commonName | awk '{ print $3 }'");
let cn = pipe.read("all");
pipe.close();
if (!cn)
return 0;
cn = lc(trim(cn));
let uci = libuci.cursor();
let serial = uci.get('ucentral', 'config', 'serial');
return cn != serial;
}
switch(ARGV[0]) {
case 'enroll':
let ret = simpleenroll();
@@ -184,4 +222,7 @@ case 'reenroll':
case 'fwtool':
exit(fwtool());
case 'check':
exit(check_cert());
}

View File

@@ -5,7 +5,7 @@ import * as fs from 'fs';
let cmd = ARGV[0];
let ifname = getenv("interface");
let opt224 = getenv("opt138");
let opt138 = getenv("opt138");
let opt224 = getenv("opt224");
if (cmd != 'bound' && cmd != 'renew')

View File

@@ -4,3 +4,6 @@ MIIFajCCA1KgAwIBAgICDnowDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUT3BlbkxBTiBEZW1vIFJv
-----BEGIN CERTIFICATE-----
MIIFIDCCAwigAwIBAgICDnkwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUT3BlbkxBTiBEZW1vIFJvb3QgQ0EwHhcNMjUwMjIxMTUwMDAwWhcNMjYwMjIxMTUwMDAwWjAfMR0wGwYDVQQDDBRPcGVuTEFOIERlbW8gUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMjExylKdJWoJu9mOHPJ6yZFXKe1lE467G65acpS2FKIWnPVFjNCmATMpkMOIFzEFwyFdbQjzOidtiL+73zlE52lOJpXCfOcxDFqDYDJJ8//J1/gQWsBaKpSvgLiHU/0awkQg+yJYZpj8YZa4NkFe+zTjQScSfOsqPPb3rZ7DOQ2BKAhjVShKmVbtNil0iO0zm8vE8DNkktTNMREp2pzb8MbCAgfOkwlrby6T+rV3TvmjThGdFUb5lWDFxWtlF8W0SUII9qj7p5TdGpryeLsO0nZTBtS4HxZNdvmKOHfgcRHmSZIJigB2NzKLNrXF9JBW0WnUSwZJZAG2C1RTx6lADILPueuusyfR/hZ3koKi4PHnSiTwQghzia9K9QjNHq5z9R9ZoCnhBg1VyU4LKmp862L0sIp2vgnOYunEIi9aCYBaDwo+0FuVjZuXyDIatwVuA7TN5IWPHA6XLdOt1mmkeYy1Ldr4XHjdondhtOyeei1UFXmyyLm2+kmRYfTm91TqYmNzRgbRV2NHO50AmsnBknX4Rv3gishGe0+dV5yFcUwZud0z2rSCkuoai5tKrPT+6Y6NqkT9u9HFifIBXnLwEzVUqHRtW6SuWj2DClVQIXIUZtFnhY4GuTuf6DlzgnXO58oDVCZmCW4ULIpbqGeRsvBHR8Sw5JXP/1+TMUYhE8TAgMBAAGjZjBkMB8GA1UdIwQYMBaAFDzIg8eyTI3xc4A2R60f8HanhBZDMB0GA1UdDgQWBBQ8yIPHskyN8XOANketH/B2p4QWQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBATANBgkqhkiG9w0BAQsFAAOCAgEAkHZ5KR8IOrdfMFy+iOvauvZxfQ84LL6TpB2FQKDjneJUdd7c29UJJFNW/0mp4Gc6jKZab6J8Dx/pNnbH0RqFjGjeRGtJ4Sk0G7gf9zw1S7qut5WJDcisM9l/wXC+zy/KSKKPQmbt0grWOtU7+NNPh1YU76hIrInq/u2sVZyKH8SXQ957fbJk6BX6JTKyNEn05AB6rNSrbOWo8sy2MlcJ7bBsrWYI1t6GcWFh4b36bLu7/dKJWpyFNXXIkKJsgMEDpEQae56+fSSDo0KRNtYB82fNZDIQlGK81rGJWNzAahM+3GD1tgk/3ZVugfaJhcBpoHHKNOGqZAvtirLAIDocno7AzqoeIz974Rh2Olsl2/arApYPyyfi8PMYuFe/d4h+Wie8n+jh5n48lZ2Ve4PK+j+QHD6tTZS4f0bGnPL1puMxzQloltuQWgLDeVfEgrc3snLvjOg8aDzWm/es85lP8XcyW54U4t3JmrNUC2C7v+Uafx7cL7eDeunhs+BRhtGV+IUmjub2IrpqZp3zZqn+LVRdYJIy/qHhjS5+ImckXkFojOmeWhfmEmYSuNP8Oa6cGuXp829qnbxLh9Qzi3TfXV883KLse4kL5Zl7gBA/4hz2hVMyGJ8fY+VvzbaTuOXyvKJ+rGZCTcRSeotBLnIevVMiL7SqOEwN0j4Mfbznfq8=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFFTCCAv2gAwIBAgICAxIwDQYJKoZIhvcNAQELBQAwGjEYMBYGA1UEAwwPT3BlbkxBTiBSb290IENBMCAXDTI1MDUxNDA4NDcxMFoYDzIwNTUwNTE0MDg0NzEwWjAaMRgwFgYDVQQDDA9PcGVuTEFOIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGibJ04A55kSURTBSKgcBmLnND2I5wws1taKqqU9aaRhB7NtvMHwh2voH9b1brUiulZaZwTN/9kzd4AnXeKQ+0u5tV7Ofk0fzF2MK47n17TS30Yenqc4NuQEKdpKK/pM3VvOEppR/bqtgyLtDmbDnmFOx+zTj/+smTgouwA+Iier0P4s5OohYxn/bjOqwQbHbU79VpGBIWv6/kt55AhH7zvsqqKHkrzTxnsRBv3SBIufrjJr9PIhZBLDrqr56P6KgAi0eoutNt2ToiJbE0WfjU7GI1RSiSN5bGj1zXhjNVzQWs1H9QzRf3c9pl3+haHQZ7FZ1UqiTRewmbNrQ6I9k81au3SttUlb87MyAuDSzatkiq7CjQ8VE1J6te6ZBt2zWpUhHsR/Lg7g3eOw5dL4oZJdK5GgGu/MUajLUXifIqM13Mvg0VTzDhN69VLXLSL0gPcicsQCwJuAza1IC/VqmBGx19fAkyJhOurCXWOgisi0g1+xzPKRphUNwMPUf8vBVOM/Vc6xDIvwVGE3+eWXyhixneFlSpAI03nWWjpwWXihTBoxbfRXO3Y/ilJqrgFN+U4PJcCPA+Wo7ThH0mgX6bOTPcgXMUzT3v3FF6Bx5/PNV3kYrw2yLzribUiS6AGvVGnW4hX2Z6OQvA/aHME8KF+6y6m4pC7FkUjVaRlzWu/wIDAQABo2MwYTAfBgNVHSMEGDAWgBSUaFuoOPk4QLByZP47kj4p1IbCJjAdBgNVHQ4EFgQUlGhbqDj5OECwcmT+O5I+KdSGwiYwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAB+/RUC2X6eVoPsFNMkaXO5Iib/ub0JoWhODQm8j2Mr5dpGXESSpXjfDcqDOLuJbWWoflXBLdr8BsVCBqOA9YgCX0H8Br7dUWmCScixxLW0he592/424EvdwifxcKHZLjv9CKV5Txhqnm2djc5RY/nTH5MYVrIh/If2TNO5ydDP6+vgy9GQ4en04VK7rz+PW17O8l7k9/lOmYptZmHgSDAPj/cT3PlG+McqaI5rMSHeEHlzH+PvgWjtSeEhF4FwFBXroDl4/yb4l2JB8bqAZ3vsOXSkigFcZh5MXPe+zuSSW+G8iLr4xoi0CFsP2DaHEyxgqP4B1FtE9nFPo6cvWbwqTVT7QSzqfH+jPJuQvpFXeRF5UFegNZTFT5/uFFPamihakFslEYxeJey1y+OJdLcP6ef87ruSt8amsq56OAETYpnW4JFowlEh0C+QwLGHGGY6WrOgHY/90hJmPgXBdBVg/IoOhzbvk5A+LqZDvxV2/rLNfClw8Kr3g5e8obcB6dWgMCy2z+us0H79ucnmhzQKsjpxM9T1ncHovAQfiD3jVqfHULY53avh0wIAjosoTGbe8dyx80quHe+16qWan7C9idXeAYYJXbZt5hs6hLw4I8M1LsjTg6vwsqiaHZpsmDyyQLdFjNJldG7aosfS9F+BIpuwijF+1dashL0CPsbIJ
-----END CERTIFICATE-----

View File

@@ -6,6 +6,8 @@ STOP=01
USE_PROCD=1
start_service() {
[ -e "/tmp/rrm_timestamp" ] && rm -rf /tmp/rrm_timestamp
[ -e "/tmp/rrm_chan_switch" ] && rm -rf /tmp/rrm_chan_switch
rm -rf /tmp/threshold_breach_count*
rm -rf /tmp/fixed_channel*
rm -rf /tmp/chanutil_phy*

View File

@@ -24,6 +24,10 @@ function stats_info_write(path, value) {
file.close();
}
function record_rrm_timestamp() {
stats_info_write("/tmp/rrm_timestamp", time());
}
// total number of radios: default=2
let num_radios = 2;
let phy_count;
@@ -136,20 +140,122 @@ function channel_to_freq(band, channel) {
return freq;
}
function center_freq_calc(band, freq, bandwidth) {
if (bandwidth == 40)
return +freq + 10;
if (bandwidth == 80)
return +freq + 30;
if (bandwidth == 160)
return +freq + 70;
if (bandwidth == 320)
if (freq == 6115)
return +freq - 10;
else
return +freq + 150;
// using mapping to get correct center channel, especially for 6G radio
function get_center_channel(channel, band, bw) {
let center_channel = channel;
let center_channel_map = {};
return +freq;
switch (band) {
case '5g':
if (bw == 40) {
center_channel_map = {
"36": 38, "40": 38,
"44": 46, "48": 46,
"52": 54, "56": 54,
"60": 62, "64": 62,
"100": 102, "104": 102,
"108": 110, "112": 110,
"116": 118, "120": 118,
"124": 126, "128": 126,
"132": 134, "136": 134,
"140": 142, "144": 142,
"149": 151, "153": 151,
"157": 159, "161": 159,
"165": 167
};
} else if (bw == 80) {
center_channel_map = {
"36": 42, "40": 42, "44": 42, "48": 42,
"52": 58, "56": 58, "60": 58, "64": 58,
"100": 106, "104": 106, "108": 106, "112": 106,
"116": 122, "120": 122, "124": 122, "128": 122,
"132": 138, "136": 138, "140": 138, "144": 138,
"149": 155, "153": 155, "157": 155, "161": 155,
"165": 171
};
} else if (bw == 160) {
center_channel_map = {
"36": 50, "40": 50, "44": 50, "48": 50,
"52": 50, "56": 50, "60": 50, "64": 50,
"100": 114, "104": 114, "108": 114, "112": 114,
"116": 114, "120": 114, "124": 114, "128": 114
};
}
break;
case '6g':
if (bw == 40) {
center_channel_map = {
"1": 3, "5": 3, "9": 11, "13": 11,
"17": 19, "21": 19, "25": 27, "29": 27,
"33": 35, "37": 35, "41": 43, "45": 43,
"49": 51, "53": 51, "57": 59, "61": 59,
"65": 67, "69": 67, "73": 75, "77": 75,
"81": 83, "85": 83, "89": 91, "93": 91,
"97": 99, "101": 99, "105": 107, "109": 107,
"113": 115, "117": 115, "121": 123, "125": 123,
"129": 131, "133": 131, "137": 139, "141": 139,
"145": 147, "149": 147, "153": 155, "157": 155,
"161": 163, "165": 163, "169": 171, "173": 171,
"177": 179, "181": 179, "185": 187, "189": 187,
"193": 195, "197": 195, "201": 203, "205": 203,
"209": 211, "213": 211, "217": 219, "221": 219,
"225": 227
};
} else if (bw == 80) {
center_channel_map = {
"1": 7, "5": 7, "9": 7, "13": 7,
"17": 23, "21": 23, "25": 23, "29": 23,
"33": 39, "37": 39, "41": 39, "45": 39,
"49": 55, "53": 55, "57": 55, "61": 55,
"65": 71, "69": 71, "73": 71, "77": 71,
"81": 87, "85": 87, "89": 87, "93": 87,
"97": 103, "101": 103, "105": 103, "109": 103,
"113": 119, "117": 119, "121": 119, "125": 119,
"129": 135, "133": 135, "137": 135, "141": 135,
"145": 151, "149": 151, "153": 151, "157": 151,
"161": 167, "165": 167, "169": 167, "173": 167,
"177": 183, "181": 183, "185": 183, "189": 183,
"193": 199, "197": 199, "201": 199, "205": 199,
"209": 215
};
} else if (bw == 160) {
center_channel_map = {
"1": 15, "5": 15, "9": 15, "13": 15,
"17": 15, "21": 15, "25": 15, "29": 15,
"33": 47, "37": 47, "41": 47, "45": 47,
"49": 47, "53": 47, "57": 47, "61": 47,
"65": 79, "69": 79, "73": 79, "77": 79,
"81": 79, "85": 79, "89": 79, "93": 79,
"97": 111, "101": 111, "105": 111, "109": 111,
"113": 111, "117": 111, "121": 111, "125": 111,
"129": 143, "133": 143, "137": 143, "141": 143,
"145": 143, "149": 143, "153": 143, "157": 143,
"161": 175, "165": 175, "169": 175, "173": 175,
"177": 175, "181": 175, "185": 175, "189": 175,
"193": 207
};
} else if (bw == 320) {
center_channel_map = {
"1": 31, "5": 31, "9": 31, "13": 31,
"17": 31, "21": 31, "25": 31, "29": 31,
"33": 63, "37": 63, "41": 63, "45": 63,
"49": 63, "53": 63, "57": 63, "61": 63,
"65": 63, "69": 63, "73": 63, "77": 63,
"81": 63, "85": 63, "89": 63, "93": 63,
"97": 127, "101": 127, "105": 127, "109": 127,
"113": 127, "117": 127, "121": 127, "125": 127,
"129": 127, "133": 127, "137": 127, "141": 127,
"145": 127, "149": 127, "153": 127, "157": 127,
"161": 191
};
}
break;
}
if (center_channel_map[channel])
center_channel = center_channel_map[channel];
return center_channel;
}
function interface_status_check(iface) {
@@ -201,6 +307,9 @@ function check_current_channel(iface) {
function hostapd_switch_channel(msg) {
ulog_info(`[%s] Start switch channel to %d \n`, msg.iface, msg.channel);
// Channel switch in progress, set flag = 1
stats_info_write("/tmp/rrm_chan_switch", 1);
let chan_switch_status = 0;
let sec_channel_offset = null;
@@ -208,7 +317,8 @@ function hostapd_switch_channel(msg) {
let bandwidth = replace(msg.htmode, /[^0-9]/g, '');
let target_freq = channel_to_freq(msg.band, msg.channel);
let center_freq = center_freq_calc(msg.band, target_freq, bandwidth);
let center_channel = get_center_channel(msg.channel, msg.band, bandwidth);
let center_freq = channel_to_freq(msg.band, center_channel);
if (bandwidth > 20)
sec_channel_offset = 1;
@@ -245,9 +355,20 @@ function switch_status_check(iface, dfs_enabled_5g_flag) {
ulog_info(`[%s] 5G radio might need some time to be UP (DFS enabled) \n`, iface);
let p = 0;
// Max 65 seconds wait for the DFS enabled interface to be UP
// Default max 70 seconds wait for the DFS enabled interface to be UP
let timer = 70;
// get real timer from hostapd_cli command
let check_cac_time = sprintf('hostapd_cli -i %s status | grep \"cac_time_left_seconds\" | awk -F "=" \'{print $2}\'', iface);
let _cac_time = fs.popen(check_cac_time);
let cac_time = trim(_cac_time.read('all'));
_cac_time.close();
// if cac_time is a valid number, set timer to cac_time + 5 seconds
if (cac_time > 0 && match(cac_time, /^[0-9]+$/)) {
timer = int(cac_time) + 5;
}
while (p < timer) {
ulog_info(`[%s] Check#%d \n `, iface, p);
@@ -267,6 +388,9 @@ function switch_status_check(iface, dfs_enabled_5g_flag) {
}
}
// Channel switch done, set flag = 0
stats_info_write("/tmp/rrm_chan_switch", 0);
let current_chan = check_current_channel(iface);
return current_chan;
}
@@ -436,7 +560,7 @@ function random_channel_selection(iface, band, htmode, chan_list_valid) {
ulog_info(`[%s] Selected channel list from config (default channel list shall be used in case channels haven't been selected) = %s \n`, iface, (chan_list_valid || '[]'));
if (band == '2g' && bw >= 40) {
ulog_info(`[%s] It is highly recommended to NOT use %dMHz bandwidth for 2.4G radio \n`, iface, bw);
ulog_info(`[%s] It is highly recommended to NOT use %dMHz bandwidth for 2.4G radio (RRM will not work properly) \n`, iface, bw);
} else if (band == '5g' && bw > 160) {
ulog_info(`[%s] %dMHz bandwidth not supported for 5G radio. Please use a bandwidth of 160MHz or lower\n`, iface, bw);
}
@@ -568,9 +692,28 @@ function random_channel_selection(iface, band, htmode, chan_list_valid) {
return random_channel;
}
function check_center_channel(chosen_random_channel, current_channel, band, htmode) {
let ret = false;
let bw = replace(htmode, /[^0-9]/g, '');
if (band != '2g' || bw != 20) {
// for 2G band or 20MHz bandwidth, center channel is the same as the channel
let chosen_random_channel_center = get_center_channel(chosen_random_channel, band, bw);
let current_channel_center = get_center_channel(current_channel, band, bw);
ulog_info(`Center channel of the chosen random channel (%d) = %d; Center channel of the current channel (%d) = %d \n`, chosen_random_channel, chosen_random_channel_center, current_channel, current_channel_center);
if (chosen_random_channel_center == current_channel_center)
ret = true;
}
return ret;
}
function algo_rcs(iface, current_channel, band, htmode, selected_channels) {
let chosen_random_channel = 0;
let res = 0;
let same_center_channel = false;
// random_channel_selection script will help to select random channel
chosen_random_channel = random_channel_selection(iface, band, htmode, selected_channels);
@@ -580,8 +723,15 @@ function algo_rcs(iface, current_channel, band, htmode, selected_channels) {
ulog_info(`[%s] RCS assigned the same channel = %d; Skip channel switch \n`, iface, chosen_random_channel);
res = 0;
} else if (chosen_random_channel > 0) {
ulog_info(`[%s] RCS done ... random channel found = %d\n`, iface, chosen_random_channel);
res = 1;
// check if the random channel has the same center channel as the current channel
same_center_channel = check_center_channel(chosen_random_channel, current_channel, band, htmode);
if (same_center_channel) {
ulog_info(`[%s] RCS found channel %d with the same center channel as current channel %d; Skip channel switch \n`, iface, chosen_random_channel, current_channel);
res = 0;
} else {
ulog_info(`[%s] RCS done ... random channel found = %d\n`, iface, chosen_random_channel);
res = 1;
}
} else {
ulog_info(`[%s] RCS scan FAIL. Retry Channel optimization at next cycle \n`, iface);
res = 0;
@@ -611,6 +761,8 @@ function channel_optimize() {
return config.interval;
}
record_rrm_timestamp();
let current_rf_down = {};
let cool_down_f = {};
let check_all_cool_down = 0;
@@ -924,7 +1076,7 @@ function channel_optimize() {
}
} else {
// revert back to the original channel
ulog_info(`[%s] Channel %d has a cac_time longer than 60 seconds, RRM failed for this interval (you might want to avoid selecting this channel) \n`, radio_iface[l], init_payload.channel);
ulog_info(`[%s] Channel %d may have a cac_time longer than 60 seconds, RRM failed for this interval (you might want to avoid selecting this channel) \n`, radio_iface[l], init_payload.channel);
}
} else if (selected_algo == "ACS") {
let random_wait_time = random_time_calc();
@@ -940,6 +1092,9 @@ function channel_optimize() {
check_all_threshold_breach >= 1: threshold breach count exceeded for one or more interfaces
*/
// Channel switch in progress, set flag = 1
stats_info_write("/tmp/rrm_chan_switch", 1);
// flag to check if 5G radio was restarted
let radio_5g_restarted = 0;
@@ -1003,6 +1158,10 @@ function channel_optimize() {
sleep(30000);
}
}
sleep(5000);
// Channel switch done, set flag = 0
stats_info_write("/tmp/rrm_chan_switch", 0);
} else {
if (threshold_breach_f[l] != 1) {
ulog_info(`[%s] Threshold breach count (=%d) < Allowed consecutive Channel Utilization threshold breach count (=%d), will be checked again in the next interval \n`, radio_iface[l], threshold_breach_count[l], config.consecutive_threshold_breach);
@@ -1016,6 +1175,7 @@ function channel_optimize() {
}
}
ulog_info(`RRM with channel optimization finished; next RRM round starts in %d seconds \n`, config.interval/1000);
record_rrm_timestamp();
return config.interval;
}

View File

@@ -51,7 +51,7 @@ start_rtty() {
procd_set_param command $BIN -h $host -I "$id" -a
[ -n "$port" ] && procd_append_param command -p "$port"
[ -n "$description" ] && procd_append_param command -d "$description"
[ "$ssl" = "1" ] && procd_append_param command -s -c /etc/ucentral/cert.pem -k /etc/ucentral/key.pem
[ "$ssl" = "1" ] && procd_append_param command -s -c /etc/ucentral/operational.pem -k /etc/ucentral/key.pem
[ -n "$token" ] && procd_append_param command -t "$token"
[ "$verbose" = "1" ] && procd_append_param command -v
[ "$timeout" -eq "0" ] || procd_append_param command -e $timeout

View File

@@ -4,10 +4,9 @@ PKG_NAME:=ucentral-client
PKG_RELEASE:=1
PKG_SOURCE_URL=https://github.com/Telecominfraproject/wlan-ucentral-client.git
PKG_MIRROR_HASH:=2e28e0aa61b74851c7daf3634ec34d303a603e881e6c5d1fd76c837dea527582
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2025-07-08
PKG_SOURCE_VERSION:=69829f63ea172ce9bd19b7b02073746fe9cf6a52
PKG_SOURCE_DATE:=2025-08-11
PKG_SOURCE_VERSION:=549e84e5fea7230c5471d6a3dbddcc7d3152f665
PKG_LICENSE:=BSD-3-Clause
PKG_MAINTAINER:=John Crispin <john@phrozen.org>

View File

@@ -6,9 +6,9 @@ config ucentral config
option reporting 10
config timeouts timeouts
option offline 120
option offline 14400
option validate 120
option orphan 120
option orphan 7200
#config event
# option type dhcp

View File

@@ -4,10 +4,9 @@ PKG_NAME:=ucentral-schema
PKG_RELEASE:=1
PKG_SOURCE_URL=https://github.com/Telecominfraproject/wlan-ucentral-schema.git
PKG_MIRROR_HASH:=9b12cf94b94688aaf2245742ac1cd3d7a2bccade7e248c47c5f13a3dd7c07401
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2025-07-11
PKG_SOURCE_VERSION:=b971b73d4cedae6175926373adcdc37a04ced11c
PKG_SOURCE_DATE:=2025-08-04
PKG_SOURCE_VERSION:=1c6b3095cb9e398fcbfcb2bf995365066eb76b21
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
PKG_LICENSE:=BSD-3-Clause

View File

@@ -20,9 +20,68 @@ let config;
let offline_timer;
let current_state;
let online = false;
let leds_off = false;
function self_healing() {
let heal_wifi = false;
let health_stat = json(fs.readfile('/tmp/ucentral.health'));
let last_nw_restart_ts = int(fs.readfile('/tmp/ucentral.nw_restart_ts')) || 0;
let time_passed_since_nw_restart = time() - last_nw_restart_ts;
if (health_stat) {
if (health_stat.data.rrm_chanutil == false) {
// RRM with Channel utilization abnormal, restart rrmd
ulog(LOG_INFO, 'RRM with Channel utilization abnormal, restarting rrmd\n');
system('/etc/init.d/rrmd restart');
}
if (health_stat.sanity != 100) {
for (let iface in health_stat.data.interfaces) {
let iface_data = health_stat.data.interfaces[iface];
if (iface_data.ssids) {
// one of the VAPs have an issue: flag up!
heal_wifi = true;
ulog(LOG_INFO, 'Time passed since last network restart = %d seconds\n', time_passed_since_nw_restart);
break;
}
}
} else {
// all VAPs are healthy, no need to heal anything
return;
}
}
if (fs.stat('/tmp/rrm_timestamp')) {
let rrm_chan_switch_flag = int(fs.readfile('/tmp/rrm_chan_switch')) || 0;
let last_rrm_timestamp = int(fs.readfile('/tmp/rrm_timestamp'));
let time_passed_since_rrm = time() - last_rrm_timestamp;
if (rrm_chan_switch_flag == 1) {
// RRM chan switch in progress, do not restart network!
ulog(LOG_INFO, 'RRM channel switch in progress, cannot restart network \n');
heal_wifi = false;
}
if (time_passed_since_rrm < 180) {
// RRM in progress, do not restart network!
ulog(LOG_INFO, 'RRM with Channel utilization may still be in progress, cannot restart network \n');
heal_wifi = false;
}
}
// keep a gap of at least 5 minutes between network restarts
if (heal_wifi && time_passed_since_nw_restart > 300) {
ulog(LOG_INFO, 'Restarting network \n');
// update network restart timestamp
let f = fs.open("/tmp/ucentral.nw_restart_ts", "w");
if (f) {
f.write(time());
f.close();
}
// restart network
system('/etc/init.d/network restart');
}
}
let healthcheck;
@@ -42,7 +101,7 @@ healthcheck = {
},
spawn: function() {
ulog(LOG_INFO, 'healtcheck execute\n');
ulog(LOG_INFO, 'healthcheck execute\n');
healthcheck.pid = uloop.process('/usr/share/ucentral/health.uc', [], {}, healthcheck.complete);
},
};
@@ -90,6 +149,13 @@ function online_handler() {
function config_load() {
ulog(LOG_INFO, 'loading config\n');
uci.load('system');
let led_off_cfg = uci.get("system", "@system[0]", "leds_off");
if (led_off_cfg == 1) {
leds_off = true;
}
uci.load('state');
config = uci.get_all('state');
@@ -133,7 +199,7 @@ function led_find(alias) {
function factory_reset_timeout() {
let led = led_find('led-running');
if (led)
led_write(led, 'trigger', 'default-on');
led_write(led, 'trigger', leds-off ? 'none' : 'default-on');
}
let blink_timer;
@@ -152,7 +218,7 @@ let state_handler = {
offline: function() {
online = false;
let led = led_find('led-running');
if (led)
if (!leds_off && led)
led_write(led, 'trigger', 'heartbeat');
if (config.ui.offline_trigger) {
if (offline_timer)
@@ -165,7 +231,7 @@ let state_handler = {
online: function() {
online = true;
let led = led_find('led-running');
if (led)
if (!leds_off && led)
led_write(led, 'trigger', 'default-on');
online_handler();
return 0;
@@ -207,7 +273,7 @@ let ubus_methods = {
current_state = req.args.state;
blink_timeout();
ulog(LOG_INFO, 'set state -> ' + req.args.state + '\n');
return state_handler[req.args.state](req.args);
},
args: {

View File

@@ -0,0 +1,37 @@
From 0b83834085bf536183b0683f4f86800dbe1e2d39 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Mon, 28 Jul 2025 07:49:07 +0200
Subject: [PATCH] toolchain: use older gcc11 for legacy targets
Signed-off-by: John Crispin <john@phrozen.org>
---
toolchain/binutils/Config.version | 1 +
toolchain/gcc/Config.version | 1 +
2 files changed, 2 insertions(+)
diff --git a/toolchain/binutils/Config.version b/toolchain/binutils/Config.version
index c9f8584480..5393d389a5 100644
--- a/toolchain/binutils/Config.version
+++ b/toolchain/binutils/Config.version
@@ -1,6 +1,7 @@
config BINUTILS_VERSION_2_37
bool
+ default y if TARGET_ipq40xx
config BINUTILS_VERSION_2_38
bool
diff --git a/toolchain/gcc/Config.version b/toolchain/gcc/Config.version
index 7126a0c883..b7de3d00e3 100644
--- a/toolchain/gcc/Config.version
+++ b/toolchain/gcc/Config.version
@@ -1,5 +1,6 @@
config GCC_VERSION_11
default y if GCC_USE_VERSION_11
+ default y if TARGET_ipq40xx
bool
config GCC_VERSION_13
--
2.34.1

View File

@@ -0,0 +1,33 @@
From 309a419087da906a2f3b0f39763f021e9729dd85 Mon Sep 17 00:00:00 2001
From: Paul White <paul@shasta.cloud>
Date: Mon, 4 Aug 2025 04:14:23 +0000
Subject: [PATCH] base-files: boot: add sync after uci-defaults
A scenario was seen where UCI config was not flushed to disk before
an AP power-cycle after uci-defaults was completed. Since these
scripts are deleted after being ran once, there is no way to recover
without a factory reset.
Adding this sync operation proved to help avoid this situation from
happening
Signed-off-by: Paul White <paul@shasta.cloud>
---
package/base-files/files/etc/init.d/boot | 1 +
1 file changed, 1 insertion(+)
diff --git a/package/base-files/files/etc/init.d/boot b/package/base-files/files/etc/init.d/boot
index 15756669a9..c8a803e32c 100755
--- a/package/base-files/files/etc/init.d/boot
+++ b/package/base-files/files/etc/init.d/boot
@@ -15,6 +15,7 @@ uci_apply_defaults() {
( . "./$(basename $file)" ) && rm -f "$file"
done
uci commit
+ sync
}
boot() {
--
2.43.0

View File

@@ -0,0 +1,25 @@
From d366477af72e725524b47f2fffe8a8c1d500060d Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Thu, 31 Jul 2025 14:45:12 +0200
Subject: [PATCH] uboot-envtools: add udaya-id5
Signed-off-by: John Crispin <john@phrozen.org>
---
package/boot/uboot-envtools/files/ipq40xx | 1 +
1 file changed, 1 insertion(+)
diff --git a/package/boot/uboot-envtools/files/ipq40xx b/package/boot/uboot-envtools/files/ipq40xx
index 8d993fae36..78299195bd 100644
--- a/package/boot/uboot-envtools/files/ipq40xx
+++ b/package/boot/uboot-envtools/files/ipq40xx
@@ -42,6 +42,7 @@ luma,wrtq-329acn|\
netgear,wac510|\
openmesh,a42|\
openmesh,a62|\
+udaya,a5-id2|\
pakedge,wr-1|\
plasmacloud,pa1200|\
plasmacloud,pa2200)
--
2.34.1

View File

@@ -0,0 +1,36 @@
From 3ceb72aaffa13375c049d161702e9d9f55da38c8 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Mon, 4 Aug 2025 08:34:50 +0200
Subject: [PATCH] yuncore_ax820: add insta1/2 partitions
Signed-off-by: John Crispin <john@phrozen.org>
---
target/linux/ramips/dts/mt7621_yuncore_ax820.dts | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/target/linux/ramips/dts/mt7621_yuncore_ax820.dts b/target/linux/ramips/dts/mt7621_yuncore_ax820.dts
index b2f55b9be0..cc1b59340b 100644
--- a/target/linux/ramips/dts/mt7621_yuncore_ax820.dts
+++ b/target/linux/ramips/dts/mt7621_yuncore_ax820.dts
@@ -120,7 +120,17 @@
partition@90000 {
compatible = "denx,uimage";
label = "firmware";
- reg = <0x90000 0xf60000>;
+ reg = <0x90000 0xf40000>;
+ };
+
+ partition@fd0000 {
+ label = "insta1";
+ reg = <0xfd0000 0x10000>;
+ };
+
+ partition@fe0000 {
+ label = "insta2";
+ reg = <0xfe0000 0x10000>;
};
partition@ff0000 {
--
2.34.1

View File

@@ -0,0 +1,26 @@
From b82a8514a3f52b91ec84f703ef92740dda19d5d9 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Thu, 14 Aug 2025 10:29:29 +0200
Subject: [PATCH] elfutils: fix build with GCC11
Signed-off-by: John Crispin <john@phrozen.org>
---
package/libs/elfutils/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package/libs/elfutils/Makefile b/package/libs/elfutils/Makefile
index f7364c36be..76112c89ff 100644
--- a/package/libs/elfutils/Makefile
+++ b/package/libs/elfutils/Makefile
@@ -87,7 +87,7 @@ TARGET_CFLAGS += \
-Wno-unused-result \
-Wno-format-nonliteral
-ifneq ($(CONFIG_GCC_USE_VERSION_11),y)
+ifneq ($(CONFIG_GCC_VERSION_11),y)
TARGET_CFLAGS += \
-Wno-error=use-after-free
endif
--
2.34.1

View File

@@ -0,0 +1,39 @@
From d0a0f0304f292a40f2fcdd20b320089627b0f05f Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Thu, 7 Aug 2025 14:50:51 +0200
Subject: [PATCH] wireless-regdb: fix channel 14 in JP
Signed-off-by: John Crispin <john@phrozen.org>
---
.../patches/200-jp-no-channel-14.patch | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
create mode 100644 package/firmware/wireless-regdb/patches/200-jp-no-channel-14.patch
diff --git a/package/firmware/wireless-regdb/patches/200-jp-no-channel-14.patch b/package/firmware/wireless-regdb/patches/200-jp-no-channel-14.patch
new file mode 100644
index 0000000000..ea1411cfdd
--- /dev/null
+++ b/package/firmware/wireless-regdb/patches/200-jp-no-channel-14.patch
@@ -0,0 +1,19 @@
+--- a/db.txt
++++ b/db.txt
+@@ -16,8 +16,6 @@ country 00:
+ (2402 - 2472 @ 40), (20)
+ # Channel 12 - 13.
+ (2457 - 2482 @ 20), (20), NO-IR, AUTO-BW
+- # Channel 14. Only JP enables this and for 802.11b only
+- (2474 - 2494 @ 20), (20), NO-IR, NO-OFDM
+ # Channel 36 - 48
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ # Channel 52 - 64
+@@ -945,7 +943,6 @@ country JO: DFS-JP
+ # https://www.soumu.go.jp/main_content/000833682.pdf
+ country JP: DFS-JP
+ (2402 - 2482 @ 40), (20)
+- (2474 - 2494 @ 20), (20), NO-OFDM
+ (4910 - 4990 @ 40), (23)
+ (5170 - 5250 @ 80), (20), AUTO-BW
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
--
2.34.1

View File

@@ -0,0 +1,12 @@
---
profile: edgecore_spw2ac1200
target: ipq40xx
subtarget: generic
description: Build image for the Edgecore spw2ac1200
image: bin/targets/ipq40xx/generic/openwrt-ipq40xx-generic-edgecore_spw2ac1200-squashfs-nand-sysupgrade.bin
packages:
- ipq40xx
include:
- ucentral-ap
- hostapd
- target-ipq40xx

12
profiles/hfcl_ion4.yml Normal file
View File

@@ -0,0 +1,12 @@
---
profile: hfcl_ion4
target: ipq40xx
subtarget: generic
description: Build image for the HFCL ION4
image: bin/targets/ipq40xx/generic/openwrt-ipq40xx-generic-hfcl_ion4-squashfs-nand-sysupgrade.bin
packages:
- ipq40xx
include:
- ucentral-ap
- hostapd
- target-ipq40xx