diff --git a/command/cmd.uc b/command/cmd.uc index 7f45463..45fb1b9 100755 --- a/command/cmd.uc +++ b/command/cmd.uc @@ -60,6 +60,7 @@ let scope = { ctx, fs, restrict, + capab, /* log helper */ log, diff --git a/command/cmd_fixedconfig.uc b/command/cmd_fixedconfig.uc new file mode 100644 index 0000000..4582c31 --- /dev/null +++ b/command/cmd_fixedconfig.uc @@ -0,0 +1,26 @@ + +if (!args.country) { + result(2, 'Country code is missing.'); + return; +} + +if (capab.country_code && !(args.country in capab.country_code)) { + result(2, 'Country code "%s" is not allowed.', args.country); + return; +} + +if (fs.stat('/tmp/squashfs')) { + system('fw_setenv country ' + args.country); +} else { + system('mount_certs'); + fs.writefile('/certificates/ucentral.defaults', args); +} +fs.writefile('/etc/modules.conf', 'options cfg80211 ieee80211_regdom=' + args.country); + +include('reboot_cause.uc', { reason: 'fixedconfig' }); +result(0, "Applied fixed config, rebooting"); +sleep(5); +system('umount /certificates'); +system('ubidetach -d 3'); +system("(sleep 10; jffs2reset -r -y)&"); +system("/etc/init.d/ucentral stop"); diff --git a/renderer/renderer.uc b/renderer/renderer.uc index d8bf564..958bdf6 100644 --- a/renderer/renderer.uc +++ b/renderer/renderer.uc @@ -21,6 +21,12 @@ if (developer != 'developer=1') { restrict = restrictfile ? json(restrictfile.read("all")) : {}; } +let default_config = fs.readfile('/etc/ucentral/ucentral.defaults'); +default_config = default_config ? json(default_config) : {}; +default_config.country ??= 'US'; + +system('iw reg set ' + default_config.country); + let serial = cursor.get("ucentral", "config", "serial"); assert(cursor, "Unable to instantiate uci"); @@ -1126,6 +1132,7 @@ return /** @lends uCentral.prototype */ { cursor, capab, restrict, + default_config, /** @member {uCentral.files} */ files, diff --git a/renderer/templates/radio.uc b/renderer/templates/radio.uc index 43e4c28..3822a48 100644 --- a/renderer/templates/radio.uc +++ b/renderer/templates/radio.uc @@ -53,10 +53,7 @@ 145, 149, 153, 157, 161, 165, 169, 173, 177, 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 233 ]; - if (capab.country_code && !(radio.country in capab.country_code)) { - warn("Overriding country code to %s", capab.country_code[0]); - radio.country = capab.country_code[0]; - } + radio.country = default_config.country; if (length(restrict.country) && !(radio.country in restrict.country)) { warn("Country code is restricted"); diff --git a/schema/radio.yml b/schema/radio.yml index cafc9b1..3c13f9b 100644 --- a/schema/radio.yml +++ b/schema/radio.yml @@ -42,15 +42,6 @@ properties: type: integer maximum: 196 minimum: 1 - country: - description: - Specifies the country code, affects the available channels and - transmission powers. - type: string - maxLength: 2 - minLength: 2 - examples: - - US allow-dfs: description: This property defines whether a radio may use DFS channels. diff --git a/schemareader.uc b/schemareader.uc index 8520d34..1a27379 100644 --- a/schemareader.uc +++ b/schemareader.uc @@ -981,26 +981,6 @@ function instantiateRadio(location, value, errors) { obj.valid_channels = parseValidChannels(location + "/valid-channels", value["valid-channels"], errors); } - function parseCountry(location, value, errors) { - if (type(value) == "string") { - if (length(value) > 2) - push(errors, [ location, "must be at most 2 characters long" ]); - - if (length(value) < 2) - push(errors, [ location, "must be at least 2 characters long" ]); - - } - - if (type(value) != "string") - push(errors, [ location, "must be of type string" ]); - - return value; - } - - if (exists(value, "country")) { - obj.country = parseCountry(location + "/country", value["country"], errors); - } - function parseAllowDfs(location, value, errors) { if (type(value) != "bool") push(errors, [ location, "must be of type boolean" ]); diff --git a/system/capabilities.uc b/system/capabilities.uc index 2bb2bbf..636ded1 100755 --- a/system/capabilities.uc +++ b/system/capabilities.uc @@ -5,14 +5,17 @@ push(REQUIRE_SEARCH_PATH, let ubus = require("ubus"); let fs = require("fs"); - +let default_config = { + country: 'US' +}; let boardfile = fs.open("/etc/board.json", "r"); let board = json(boardfile.read("all")); boardfile.close(); let restrictfile = fs.open("/etc/ucentral/restrictions.json", "r"); capa = { - 'secure-rtty': true + 'secure-rtty': true, + 'default-config': true, }; if (restrictfile) { capa.restrictions = json(restrictfile.read("all")) || {}; @@ -25,7 +28,36 @@ if (restrictfile) { capa.developer = false; } ctx = ubus.connect(); + +if (board.wifi?.country) { + default_config.country = split(board.wifi.country, ' '); + capa.country_codes = board.wifi.country; +} + +if (fs.stat('/tmp/squashfs')) { + let pipe = fs.popen('fw_printenv country'); + let country = replace(pipe.read("all"), '\n', ''); + pipe.close(); + if (country) + default_config.country = country; + else + system('fw_setenv country ' + default_config.country); + fs.writefile('/etc/ucentral/ucentral.defaults', default_config); +} else { + if (!fs.stat('/certificates/ucentral.defaults')) { + fs.writefile('/certificates/ucentral.defaults', default_config); + } + if (fs.stat('/certificates/ucentral.defaults')) { + let defaults = fs.readfile('/certificates/ucentral.defaults'); + if (json(defaults)) + default_config = json(defaults); + } + fs.writefile('/etc/ucentral/ucentral.defaults', default_config); +} +capa.country = default_config.country || 'US'; + let wifi = require("wifi.phy"); + capa.compatible = replace(board.model.id, ',', '_'); capa.model = board.model.name; @@ -87,15 +119,11 @@ for (let k, v in board.network) { if (length(macs)) capa.macaddr = macs; -if (board.wifi?.country) - capa.country_code = split(board.wifi.country, ' '); - if (board.system?.label_macaddr) capa.label_macaddr = board.system?.label_macaddr; if (length(wifi)) capa.wifi = wifi; -capafile = fs.open("/etc/ucentral/capabilities.json", "w"); -capafile.write(capa); -capafile.close(); +fs.writefile('/etc/ucentral/capabilities.json', capa); + diff --git a/ucentral.schema.full.json b/ucentral.schema.full.json index aaf78d0..e02b3c8 100644 --- a/ucentral.schema.full.json +++ b/ucentral.schema.full.json @@ -594,15 +594,6 @@ "minimum": 1 } }, - "country": { - "description": "Specifies the country code, affects the available channels and transmission powers.", - "type": "string", - "maxLength": 2, - "minLength": 2, - "examples": [ - "US" - ] - }, "allow-dfs": { "description": "This property defines whether a radio may use DFS channels.", "type": "boolean", diff --git a/ucentral.schema.json b/ucentral.schema.json index a9a4d2c..955e3ea 100644 --- a/ucentral.schema.json +++ b/ucentral.schema.json @@ -459,14 +459,6 @@ "minimum": 1 } }, - "country": { - "type": "string", - "maxLength": 2, - "minLength": 2, - "examples": [ - "US" - ] - }, "allow-dfs": { "type": "boolean", "default": true diff --git a/ucentral.schema.pretty.json b/ucentral.schema.pretty.json index 3d51f22..8348e61 100644 --- a/ucentral.schema.pretty.json +++ b/ucentral.schema.pretty.json @@ -510,15 +510,6 @@ "minimum": 1 } }, - "country": { - "description": "Specifies the country code, affects the available channels and transmission powers.", - "type": "string", - "maxLength": 2, - "minLength": 2, - "examples": [ - "US" - ] - }, "allow-dfs": { "description": "This property defines whether a radio may use DFS channels.", "type": "boolean",