Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision Next revisionBoth sides next revision | ||
| inbox:toh:d-link:covr-p2500_a1 [2023/11/09 17:57] – [Failsafe mode] jokujossai | inbox:toh:d-link:covr-p2500_a1 [2023/11/23 17:12] – [D-Link COVR-P2500 A1] jokujossai | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== D-Link COVR-P2500 A1====== | ====== D-Link COVR-P2500 A1====== | ||
| ~~NOTOC~~ | ~~NOTOC~~ | ||
| - | |||
| - | /* This template is intended to be used via https:// | ||
| - | |||
| - | {{page> | ||
| The D-Link COVR-P2500 A1 is a AC1200 dual band wireless access point with wired Ethernet, Wi-Fi and PowerLine interfaces. It is basically a standard router with a Homeplug AV2 Powerline Communication (PLC) interface connected internally to one of the Ethernet switch ports. | The D-Link COVR-P2500 A1 is a AC1200 dual band wireless access point with wired Ethernet, Wi-Fi and PowerLine interfaces. It is basically a standard router with a Homeplug AV2 Powerline Communication (PLC) interface connected internally to one of the Ethernet switch ports. | ||
| Line 81: | Line 77: | ||
| - Flash with [[docs: | - Flash with [[docs: | ||
| - The IP address of the Recovery UI is 192.168.0.50. | - The IP address of the Recovery UI is 192.168.0.50. | ||
| - | - Uploading does not work with modern operating systems, use dlink_recovery_upload.py script (Linux and Windows 10 version 1703 or newer) | + | - Uploading does not work with modern operating systems, use [[# |
| - | ==== Failsafe mode insallation | + | === dlink_recovery_upload.py === |
| + | <WRAP bootlog> | ||
| + | < | ||
| + | # SPDX-License-Identifier: | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | # this software and associated documentation files (the “Software”), | ||
| + | # | ||
| + | # | ||
| + | # and to permit persons to whom the Software is furnished to do so, subject to the | ||
| + | # | ||
| + | # | ||
| + | # The above copyright notice and this permission notice shall be included in all | ||
| + | # | ||
| + | # | ||
| + | # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
| + | # | ||
| + | |||
| + | |||
| + | import argparse | ||
| + | import ctypes | ||
| + | import ctypes.wintypes | ||
| + | import os | ||
| + | import random | ||
| + | import socket | ||
| + | import sys | ||
| + | import time | ||
| + | |||
| + | BUFFER_SIZE = 512 | ||
| + | ACK_TIMEOUT = 10 | ||
| + | |||
| + | |||
| + | if sys.platform in (" | ||
| + | class TCP_INFO(ctypes.Structure): | ||
| + | """ | ||
| + | tcp_info structure (https:// | ||
| + | |||
| + | struct tcp_info | ||
| + | { | ||
| + | uint8_t | ||
| + | uint8_t | ||
| + | uint8_t | ||
| + | uint8_t | ||
| + | uint8_t | ||
| + | uint8_t | ||
| + | uint8_t | ||
| + | |||
| + | uint32_t | ||
| + | uint32_t | ||
| + | uint32_t | ||
| + | uint32_t | ||
| + | |||
| + | uint32_t | ||
| + | uint32_t | ||
| + | uint32_t | ||
| + | uint32_t | ||
| + | uint32_t | ||
| + | |||
| + | /* Times. */ | ||
| + | uint32_t | ||
| + | uint32_t | ||
| + | uint32_t | ||
| + | uint32_t | ||
| + | |||
| + | /* Metrics. */ | ||
| + | uint32_t | ||
| + | uint32_t | ||
| + | uint32_t | ||
| + | uint32_t | ||
| + | uint32_t | ||
| + | uint32_t | ||
| + | uint32_t | ||
| + | uint32_t | ||
| + | |||
| + | uint32_t | ||
| + | uint32_t | ||
| + | |||
| + | uint32_t | ||
| + | }; | ||
| + | """ | ||
| + | _fields_ = [ | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | |||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | |||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | |||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | |||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | |||
| + | (" | ||
| + | (" | ||
| + | |||
| + | (" | ||
| + | ] | ||
| + | |||
| + | def wait_ack(s: socket.socket): | ||
| + | """ | ||
| + | Linux compatible wait_ack implementation. | ||
| + | |||
| + | Waits until tcp_info.tcpi_unacked is zero. | ||
| + | |||
| + | :param socket.socket s: The socket to check for unacked TCP packets | ||
| + | :raises RuntimeError: | ||
| + | """ | ||
| + | timeout = time.time() + ACK_TIMEOUT | ||
| + | unacked = 1 | ||
| + | while unacked > 0: | ||
| + | # Check timeout | ||
| + | if time.time() > timeout: | ||
| + | raise RuntimeError(" | ||
| + | |||
| + | # Fetch tcp_info | ||
| + | tcp_info = TCP_INFO.from_buffer_copy( | ||
| + | s.getsockopt( | ||
| + | socket.IPPROTO_TCP, | ||
| + | socket.TCP_INFO, | ||
| + | ctypes.sizeof(TCP_INFO) | ||
| + | ) | ||
| + | ) | ||
| + | |||
| + | unacked = tcp_info.tcpi_unacked | ||
| + | elif sys.platform == " | ||
| + | class TCP_INFO_v0(ctypes.Structure): | ||
| + | """ | ||
| + | TCP_INFO_v0 structure (https:// | ||
| + | |||
| + | Minimum supported client Windows 10, version 1703 [desktop apps only] | ||
| + | Minimum supported server Windows Server 2016 [desktop apps only] | ||
| + | |||
| + | typedef struct _TCP_INFO_v0 { | ||
| + | TCPSTATE State; | ||
| + | ULONG Mss; | ||
| + | ULONG64 | ||
| + | BOOLEAN | ||
| + | ULONG RttUs; | ||
| + | ULONG MinRttUs; | ||
| + | ULONG BytesInFlight; | ||
| + | ULONG Cwnd; | ||
| + | ULONG SndWnd; | ||
| + | ULONG RcvWnd; | ||
| + | ULONG RcvBuf; | ||
| + | ULONG64 | ||
| + | ULONG64 | ||
| + | ULONG BytesReordered; | ||
| + | ULONG BytesRetrans; | ||
| + | ULONG FastRetrans; | ||
| + | ULONG DupAcksIn; | ||
| + | ULONG TimeoutEpisodes; | ||
| + | UCHAR SynRetrans; | ||
| + | } TCP_INFO_v0, | ||
| + | """ | ||
| + | _fields_ = [ | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | (" | ||
| + | ] | ||
| + | |||
| + | # WSAIoctl function (https:// | ||
| + | WSAIoctl_Fn = ctypes.windll.ws2_32.WSAIoctl | ||
| + | WSAIoctl_Fn.argtypes = [ | ||
| + | ctypes.c_void_p, | ||
| + | ctypes.wintypes.DWORD, | ||
| + | ctypes.c_void_p, | ||
| + | ctypes.wintypes.DWORD, | ||
| + | ctypes.c_void_p, | ||
| + | ctypes.wintypes.DWORD, | ||
| + | ctypes.POINTER(ctypes.wintypes.DWORD), | ||
| + | ctypes.c_void_p, | ||
| + | ctypes.c_void_p, | ||
| + | ] | ||
| + | WSAIoctl_Fn.restype = ctypes.c_int | ||
| + | |||
| + | def wait_ack(s: socket.socket): | ||
| + | """ | ||
| + | Windows compatible wait_ack implementation. | ||
| + | |||
| + | Waits until TCP_INFO_v0.BytesInFlight is zero. | ||
| + | Raises RuntimeError if ACK_TIMEOUT exceeded | ||
| + | """ | ||
| + | timeout = time.time() + ACK_TIMEOUT | ||
| + | |||
| + | sockfd = ctypes.c_void_p(s.fileno()) | ||
| + | # SIO_TCP_INFO | ||
| + | dwIoControlCode = ctypes.wintypes.DWORD( | ||
| + | 1 << 31 # IOC_IN | ||
| + | | | ||
| + | 1 << 30 # IOC_OUT | ||
| + | | | ||
| + | 3 << 27 # IOC_VENDOR? | ||
| + | | | ||
| + | 39 | ||
| + | ) | ||
| + | infoVersion = ctypes.wintypes.DWORD(0) | ||
| + | tcpinfo = TCP_INFO_v0() | ||
| + | bytesReturned = ctypes.wintypes.DWORD(0) | ||
| + | |||
| + | unacked = 1 | ||
| + | while unacked > 0: | ||
| + | # Check timeout | ||
| + | if time.time() > timeout: | ||
| + | raise RuntimeError(" | ||
| + | |||
| + | # Fetch TCP_INFO_v0 | ||
| + | res = WSAIoctl_Fn( | ||
| + | sockfd, | ||
| + | dwIoControlCode, | ||
| + | ctypes.pointer(infoVersion), | ||
| + | ctypes.wintypes.DWORD(ctypes.sizeof(infoVersion)), | ||
| + | ctypes.pointer(tcpinfo), | ||
| + | ctypes.wintypes.DWORD(ctypes.sizeof(tcpinfo)), | ||
| + | ctypes.pointer(bytesReturned), | ||
| + | None, | ||
| + | None | ||
| + | ) | ||
| + | assert res == 0 | ||
| + | |||
| + | unacked = tcpinfo.BytesInFlight | ||
| + | elif sys.platform == " | ||
| + | """ | ||
| + | SO_NWRITE returns the amount of data in the output buffer not yet sent by the protocol. | ||
| + | |||
| + | / | ||
| + | #define SO_NWRITE | ||
| + | """ | ||
| + | SO_NWRITE = 0x1024 | ||
| + | |||
| + | def wait_ack(s: socket.socket): | ||
| + | """ | ||
| + | MacOS compatible wait_ack implementation. | ||
| + | |||
| + | Waits until SO_NWRITE is zero | ||
| + | |||
| + | :param socket.socket s: The socket to check for unacked TCP packets | ||
| + | :raises RuntimeError: | ||
| + | """ | ||
| + | timeout = time.time() + ACK_TIMEOUT | ||
| + | unacked = 1 | ||
| + | while unacked > 0: | ||
| + | # Check timeout | ||
| + | if time.time() > timeout: | ||
| + | raise RuntimeError(" | ||
| + | |||
| + | # Fecth SO_NWRITE | ||
| + | unacked = s.getsockopt( | ||
| + | socket.SOL_SOCKET, | ||
| + | SO_NWRITE | ||
| + | ) | ||
| + | else: | ||
| + | raise RuntimeError(" | ||
| + | |||
| + | |||
| + | def upload(firmware, | ||
| + | """ | ||
| + | Upload firmware to router | ||
| + | |||
| + | :param str firmware: Firmware file path | ||
| + | """ | ||
| + | |||
| + | assert os.path.isfile(firmware), | ||
| + | # File size for Content-Length calculation | ||
| + | fsize = os.stat(firmware).st_size | ||
| + | |||
| + | # Connect to router with TCP_NODELAY | ||
| + | s = socket.socket(socket.AF_INET, | ||
| + | s.setsockopt(socket.IPPROTO_TCP, | ||
| + | s.connect((host, | ||
| + | |||
| + | print(f" | ||
| + | |||
| + | # Values for headers | ||
| + | boundary = " | ||
| + | content_disposition = ' | ||
| + | content_type = ' | ||
| + | newline = " | ||
| + | |||
| + | # Calculate HTTP Content-Length | ||
| + | content_length = ( | ||
| + | 2+len(boundary)+len(newline) | ||
| + | +len(content_disposition)+len(newline) | ||
| + | +len(content_type)+len(newline) | ||
| + | +len(newline) | ||
| + | +fsize+len(newline) | ||
| + | +2+len(boundary)+2+len(newline) | ||
| + | ) | ||
| + | |||
| + | # Send HTTP headers | ||
| + | buffer = """ | ||
| + | Host: {} | ||
| + | Content-Length: | ||
| + | Content-Type: | ||
| + | Connection: Keep-Alive | ||
| + | |||
| + | """ | ||
| + | s.send(buffer) | ||
| + | wait_ack(s) | ||
| + | |||
| + | # Send multipart encapsulation boundary and headers | ||
| + | buffer = """ | ||
| + | {} | ||
| + | {} | ||
| + | |||
| + | """ | ||
| + | s.send(buffer) | ||
| + | wait_ack(s) | ||
| + | |||
| + | # Send firmware | ||
| + | print(" | ||
| + | sent_bytes = 0 | ||
| + | with open(firmware, | ||
| + | while True: | ||
| + | buffer = fh.read(BUFFER_SIZE) | ||
| + | if buffer == b"": | ||
| + | break | ||
| + | s.send(buffer) | ||
| + | wait_ack(s) | ||
| + | sent_bytes += len(buffer) | ||
| + | print(" | ||
| + | # | ||
| + | |||
| + | # Send ending boundary | ||
| + | buffer = """ | ||
| + | --{}-- | ||
| + | """ | ||
| + | s.send(buffer) | ||
| + | wait_ack(s) | ||
| + | |||
| + | print() | ||
| + | print(" | ||
| + | |||
| + | # Print response | ||
| + | response = s.recv(4096).decode() | ||
| + | print(response) | ||
| + | # Check response contains " | ||
| + | assert " | ||
| + | |||
| + | # Wait some time before closing socket | ||
| + | time.sleep(1) | ||
| + | s.close() | ||
| + | |||
| + | # COVR-P2500 firmwares logic | ||
| + | # Increase percentage value every 2200ms and after 100% show ready message | ||
| + | percent = 1 | ||
| + | while percent <= 100: | ||
| + | print(f" | ||
| + | percent += 1 | ||
| + | time.sleep(2.2) | ||
| + | print(" | ||
| + | |||
| + | |||
| + | if __name__ == " | ||
| + | parser = argparse.ArgumentParser( | ||
| + | description=" | ||
| + | epilog=" | ||
| + | ) | ||
| + | parser.add_argument(" | ||
| + | parser.add_argument(" | ||
| + | parser.add_argument(" | ||
| + | parser.add_argument(" | ||
| + | |||
| + | args = parser.parse_args() | ||
| + | |||
| + | upload(args.firmware, | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | ==== Reverting to stock ==== | ||
| + | |||
| + | - Obtain unencrypted version of original firmware or decrypt with [[https:// | ||
| + | - Flash with [[docs: | ||
| + | - The IP address of the Recovery UI is 192.168.0.50. | ||
| + | - Uploading does not work with modern operating systems, use [[# | ||
| + | ==== Failsafe mode installation | ||
| **NOTE! Only use this method with stock firmware. OpenWRT has different flash layout** | **NOTE! Only use this method with stock firmware. OpenWRT has different flash layout** | ||
| Line 157: | Line 576: | ||
| ***/ | ***/ | ||
| + | |||
| + | ===== Specific Configuration ===== | ||
| + | |||
| + | ==== Network interfaces ==== | ||
| + | The default network configuration is: | ||
| + | ^ Interface Name ^ Description | ||
| + | | br-lan | ||
| + | | vlan1 (eth0.1) | ||
| + | | vlan2 (eth0.2) | ||
| + | | vlan3 (eth0.3 | ||
| + | | wlan0 | WiFi 5 GHz | Disabled | ||
| + | | wlan1 | WiFi 2.4 GHz | Disabled | ||
| + | |||
| + | ==== Switch Ports (for VLANs) ==== | ||
| + | |||
| + | ^ Port ^ Switch port ^ | ||
| + | | CPU | 0 | | ||
| + | | LAN 1 | 1 | | ||
| + | | LAN 2 | 2 | | ||
| + | | WAN | 3 | | ||
| + | | PLC | 4 | | ||
| + | |||
| + | ==== Powerline configuration ==== | ||
| + | |||
| + | Powerline interface needs '' | ||
| + | |||
| + | '' | ||
| + | |||
| + | === Powerline Quick Setup === | ||
| + | |||
| + | 1. Add file [[# | ||
| + | |||
| + | 2. Make plc configuration kept on sysupgrade by creating file ''/ | ||
| + | |||
| + | /etc/plc | ||
| + | / | ||
| + | / | ||
| + | |||
| + | 3. Install '' | ||
| + | |||
| + | 4. Install open-plc packages '' | ||
| + | |||
| + | 5. (Optional) Download '' | ||
| + | |||
| + | 6. Run setup tool ''/ | ||
| + | |||
| + | <hidden Setup example> | ||
| + | < | ||
| + | root@covrp2500_1:/# | ||
| + | Download original firmware and extract files from /lib/plc to /etc/plc [y|n] y | ||
| + | Downloading ' | ||
| + | Connecting to 60.248.210.49: | ||
| + | Writing to ' | ||
| + | COVRP2500A1_FW101b08 15460k --:--:-- ETA | ||
| + | Download completed (15990457 bytes) | ||
| + | Parallel unsquashfs: Using 1 processor | ||
| + | 4 inodes (6 blocks) to write | ||
| + | |||
| + | [===================================================================|] 6/6 100% | ||
| + | |||
| + | created 4 files | ||
| + | created 3 directories | ||
| + | created 0 symlinks | ||
| + | created 0 devices | ||
| + | created 0 fifos | ||
| + | created 0 sockets | ||
| + | 1) / | ||
| + | 2) / | ||
| + | 3) / | ||
| + | Select PibPath [1-3]: 1 | ||
| + | 1) / | ||
| + | 2) / | ||
| + | Select NvmPath [1-2]: 2 | ||
| + | NetworkPasswd (leave empty to use default plc_networkpwd): | ||
| + | Enable plc [0-1]: 1 | ||
| + | Automatically add to br-lan bridge [0-1]: 1 | ||
| + | root@covrp2500_1:/# | ||
| + | root@covrp2500_1:/# | ||
| + | bridge name | ||
| + | br-lan | ||
| + | eth0.1 | ||
| + | root@covrp2500_1:/# | ||
| + | br-lan 00: | ||
| + | br-lan XX: | ||
| + | |||
| + | source address = XX: | ||
| + | |||
| + | network-> | ||
| + | network-> | ||
| + | network-> | ||
| + | network-> | ||
| + | network-> | ||
| + | network-> | ||
| + | network-> | ||
| + | |||
| + | station-> | ||
| + | station-> | ||
| + | station-> | ||
| + | station-> | ||
| + | station-> | ||
| + | |||
| + | |||
| + | </ | ||
| + | </ | ||
| + | |||
| + | 6. Start plc service with ''/ | ||
| + | |||
| + | === / | ||
| + | <hidden / | ||
| + | <code - / | ||
| + | #!/bin/sh / | ||
| + | |||
| + | USE_PROCD=1 | ||
| + | |||
| + | START=60 | ||
| + | STOP=80 | ||
| + | |||
| + | EXTRA_COMMANDS=" | ||
| + | EXTRA_HELP=" | ||
| + | |||
| + | mtd_get_key() { | ||
| + | local mtdname=" | ||
| + | local key=" | ||
| + | local part | ||
| + | local value_dirty | ||
| + | |||
| + | part=$(find_mtd_part " | ||
| + | if [ -z " | ||
| + | echo " | ||
| + | return | ||
| + | fi | ||
| + | |||
| + | value_dirty=$(strings " | ||
| + | |||
| + | echo " | ||
| + | } | ||
| + | |||
| + | board=$(board_name) | ||
| + | |||
| + | start_service() { | ||
| + | if [ ! -f / | ||
| + | touch / | ||
| + | uci set plc.config=config | ||
| + | uci commit plc | ||
| + | fi | ||
| + | |||
| + | local NvmPath | ||
| + | local PibPath | ||
| + | local Mac | ||
| + | local device | ||
| + | local NmkSelected | ||
| + | local NetworkPasswd | ||
| + | local Nmk | ||
| + | local Dek | ||
| + | local Dak | ||
| + | local AdapterName | ||
| + | local Enabled | ||
| + | local Network | ||
| + | local pibpath_tmp | ||
| + | |||
| + | config_load plc | ||
| + | config_get NvmPath config NvmPath | ||
| + | config_get PibPath config PibPath | ||
| + | config_get Mac config Mac | ||
| + | config_get NmkSelected config NmkSelected | ||
| + | config_get NetworkPasswd config NetworkPasswd | ||
| + | config_get Nmk config Nmk | ||
| + | config_get Dek config Dek | ||
| + | config_get Dak config Dak | ||
| + | config_get AdapterName config AdapterName | ||
| + | config_get Enabled config Enabled | ||
| + | config_get Network config Network | ||
| + | config_load network | ||
| + | config_get device plc device | ||
| + | |||
| + | if [ -z " | ||
| + | echo " | ||
| + | exit 1 | ||
| + | fi | ||
| + | if [ ! -f " | ||
| + | echo " | ||
| + | exit 1 | ||
| + | fi | ||
| + | |||
| + | if [ -z " | ||
| + | echo " | ||
| + | exit 1 | ||
| + | fi | ||
| + | if [ ! -f " | ||
| + | echo " | ||
| + | exit 1 | ||
| + | fi | ||
| + | if [ -z " | ||
| + | Mac=" | ||
| + | fi | ||
| + | if [ -z " | ||
| + | echo " | ||
| + | exit 1 | ||
| + | fi | ||
| + | |||
| + | # Create modded pib | ||
| + | pibpath_tmp=" | ||
| + | rm -f " | ||
| + | cp " | ||
| + | |||
| + | # Patch MAC into pib | ||
| + | if [ ! -z " | ||
| + | modpib -M " | ||
| + | fi | ||
| + | |||
| + | # Patch NMK | ||
| + | if [ ' | ||
| + | if [ -z " | ||
| + | NetworkPwd=" | ||
| + | fi | ||
| + | Nmk=" | ||
| + | fi | ||
| + | if [ ! -z " | ||
| + | modpib -N " | ||
| + | fi | ||
| + | |||
| + | # Patch DAK | ||
| + | if [ -z " | ||
| + | if [ -z " | ||
| + | Dek=" | ||
| + | |||
| + | if [ ! -z " | ||
| + | Dak=" | ||
| + | fi | ||
| + | fi | ||
| + | else | ||
| + | Dak=" | ||
| + | fi | ||
| + | if [ ! -z " | ||
| + | modpib -D " | ||
| + | fi | ||
| + | |||
| + | # Patch USR | ||
| + | if [ -z " | ||
| + | AdapterName=" | ||
| + | fi | ||
| + | modpib -U " | ||
| + | |||
| + | if [ -z " | ||
| + | echo " | ||
| + | exit 1 | ||
| + | fi | ||
| + | if [ " | ||
| + | echo " | ||
| + | exit 1 | ||
| + | fi | ||
| + | |||
| + | cd /tmp | ||
| + | |||
| + | for i in $(seq 1 30); do | ||
| + | if [ -d / | ||
| + | break | ||
| + | fi | ||
| + | sleep 1s | ||
| + | done | ||
| + | |||
| + | procd_open_instance | ||
| + | if [ -z " | ||
| + | procd_set_param command / | ||
| + | else | ||
| + | [ ! -e /dev/fd ] && ln -s / | ||
| + | procd_set_param command sh -c '/ | ||
| + | while read line; do \ | ||
| + | echo " | ||
| + | if [ $(expr match " | ||
| + | echo " | ||
| + | brctl addif " | ||
| + | fi; \ | ||
| + | done)' | ||
| + | fi | ||
| + | procd_set_param file / | ||
| + | procd_set_param stdout 1 | ||
| + | procd_set_param stderr 1 | ||
| + | procd_set_param netdev " | ||
| + | procd_close_instance | ||
| + | } | ||
| + | |||
| + | service_triggers() { | ||
| + | procd_add_reload_trigger " | ||
| + | } | ||
| + | |||
| + | reload_service() { | ||
| + | stop | ||
| + | start | ||
| + | } | ||
| + | |||
| + | stop_service() { | ||
| + | local device | ||
| + | local Network | ||
| + | |||
| + | config_load plc | ||
| + | config_get Network config Network | ||
| + | config_load network | ||
| + | config_get device plc device | ||
| + | |||
| + | if [ ! -z " | ||
| + | brctl delif " | ||
| + | fi | ||
| + | } | ||
| + | |||
| + | service_stopped() { | ||
| + | local PibPath | ||
| + | local Mac | ||
| + | local device | ||
| + | |||
| + | config_load plc | ||
| + | config_get PibPath config PibPath | ||
| + | config_get Mac config Mac | ||
| + | config_load network | ||
| + | config_get device plc device | ||
| + | |||
| + | if [ ! -z " | ||
| + | rm " | ||
| + | fi | ||
| + | |||
| + | if [ -z " | ||
| + | Mac=" | ||
| + | fi | ||
| + | |||
| + | plctool -i " | ||
| + | } | ||
| + | |||
| + | setup() { | ||
| + | if [ ! -f / | ||
| + | touch / | ||
| + | uci set plc.config=config | ||
| + | uci commit plc | ||
| + | fi | ||
| + | |||
| + | echo -n " | ||
| + | read i | ||
| + | if [ " | ||
| + | if [ -z " | ||
| + | echo " | ||
| + | exit 1 | ||
| + | fi | ||
| + | |||
| + | cd /tmp | ||
| + | FW=" | ||
| + | rm -f " | ||
| + | wget -O " | ||
| + | if [ ! -f " | ||
| + | echo " | ||
| + | exit 1 | ||
| + | fi | ||
| + | unsquashfs -lls " | ||
| + | if [ $? -ne 0 ]; then | ||
| + | echo "$FW does not contain any / | ||
| + | exit 1 | ||
| + | fi | ||
| + | |||
| + | unsquashfs " | ||
| + | mkdir -p /etc/plc/ | ||
| + | cp squashfs-root/ | ||
| + | rm -rf squashfs-root | ||
| + | rm " | ||
| + | fi | ||
| + | |||
| + | options=$(echo / | ||
| + | if [ " | ||
| + | echo "No files matching / | ||
| + | exit 1 | ||
| + | fi | ||
| + | count=$(echo $options | wc -w) | ||
| + | i="" | ||
| + | while [ -z " | ||
| + | i=1 | ||
| + | for f in $options; do | ||
| + | echo "${i}) $f" | ||
| + | i=$((i+1)) | ||
| + | done | ||
| + | echo -n " | ||
| + | read i | ||
| + | done | ||
| + | pibpath=$(echo $options | awk ' | ||
| + | uci set plc.config.PibPath=$pibpath | ||
| + | |||
| + | options=$(echo / | ||
| + | if [ " | ||
| + | echo "No files matching / | ||
| + | exit 1 | ||
| + | fi | ||
| + | count=$(echo $options | wc -w) | ||
| + | if [ $count -gt 1 ]; then | ||
| + | i="" | ||
| + | while [ -z " | ||
| + | i=1 | ||
| + | for f in $options; do | ||
| + | echo "${i}) $f" | ||
| + | i=$((i+1)) | ||
| + | done | ||
| + | echo -n " | ||
| + | read i | ||
| + | done | ||
| + | nvmpath=$(echo $options | awk ' | ||
| + | else | ||
| + | nvmpath=$options | ||
| + | fi | ||
| + | uci set plc.config.NvmPath=$nvmpath | ||
| + | |||
| + | echo -n " | ||
| + | read networkpwd | ||
| + | if [ -z " | ||
| + | networkpwd=" | ||
| + | fi | ||
| + | uci set plc.config.NetworkPasswd=" | ||
| + | uci set plc.config.Nmk=" | ||
| + | uci set plc.config.NmkSelected=' | ||
| + | |||
| + | uci set plc.config.Mac=" | ||
| + | |||
| + | dek=" | ||
| + | uci set plc.config.Dek=" | ||
| + | uci set plc.config.Dak=" | ||
| + | |||
| + | uci set plc.config.AdapterName=" | ||
| + | |||
| + | echo -n " | ||
| + | read i | ||
| + | if [ ! -z " | ||
| + | uci set plc.config.Enabled=1 | ||
| + | enable | ||
| + | else | ||
| + | uci set plc.config.Enabled=0 | ||
| + | disable | ||
| + | fi | ||
| + | |||
| + | echo -n " | ||
| + | read i | ||
| + | if [ ! -z " | ||
| + | uci set plc.config.Network=" | ||
| + | else | ||
| + | uci set plc.config.Network="" | ||
| + | fi | ||
| + | |||
| + | # Commit changes | ||
| + | if [ ! -z "$(uci changes plc)" ]; then | ||
| + | uci commit plc | ||
| + | fi | ||
| + | } | ||
| + | </ | ||
| + | </ | ||
| ===== Hardware ===== | ===== Hardware ===== | ||