diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml index a1988b3..097d072 100755 --- a/.gitea/workflows/ci.yaml +++ b/.gitea/workflows/ci.yaml @@ -37,4 +37,39 @@ jobs: run: | echo "Initiating unit tests..." # Busted will automatically find and run files in the 'spec/' directory - busted --lua=lua5.1 --verbose spec/ \ No newline at end of file + busted --lua=lua5.1 --verbose spec/ + + deploy-to-device: + name: Deploy to Roof Unit + needs: test-and-lint + runs-on: ubuntu-latest + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + + steps: + - name: 1. Checkout Repository Code + uses: actions/checkout@v4 + + - name: 2. Prepare SSH Environment + run: | + echo "Preparing the sacred keys and crypto-litany for SSH communion..." + mkdir -p ~/.ssh/ + echo "${{ secrets.ROOF_UNIT_SSH_KEY }}" > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + + ssh-keyscan -H "${{ secrets.ROOF_UNIT_HOSTNAME }}" >> ~/.ssh/known_hosts + + # Recreate the SSH alias, now including the required legacy crypto options + echo "Host roof-unit" > ~/.ssh/config + echo " HostName ${{ secrets.ROOF_UNIT_HOSTNAME }}" >> ~/.ssh/config + echo " User ${{ secrets.ROOF_UNIT_USER }}" >> ~/.ssh/config + echo " IdentityFile ~/.ssh/id_rsa" >> ~/.ssh/config + echo " KexAlgorithms +diffie-hellman-group1-sha1" >> ~/.ssh/config + echo " HostKeyAlgorithms +ssh-rsa" >> ~/.ssh/config + echo " MACs +hmac-sha1" >> ~/.ssh/config + echo " PubkeyAcceptedAlgorithms +ssh-rsa" >> ~/.ssh/config + + - name: 3. Execute Deployment Ritual + run: | + echo "Initiating deployment sequence..." + chmod +x ./skyweave_deploy.sh + ./skyweave_deploy.sh \ No newline at end of file diff --git a/skyweave/handlers/network.lua b/skyweave/handlers/network.lua index aa4af55..c0cd4d8 100755 --- a/skyweave/handlers/network.lua +++ b/skyweave/handlers/network.lua @@ -48,6 +48,10 @@ function network_handler.get_network_config(request_context) domain = utils.uci_get("dhcp.@dnsmasq[0].domain") or "", ignore = utils.uci_get("dhcp.lan.ignore") or "" -- bool, uci_get returns "0" or "1" } + response_data.lte = { + imei = utils.get_modem_imei() or "", + iccid = utils.get_sim_iccid() or "" + } return response_data end diff --git a/skyweave/utils.lua b/skyweave/utils.lua index 62df5fc..8f7dd6b 100755 --- a/skyweave/utils.lua +++ b/skyweave/utils.lua @@ -308,4 +308,70 @@ function utils.get_station_dump_info(interface_name) return station_data end +--- +-- The Litany of IMEI Retrieval +-- This incantation queries the modem for its unique identity slate. +-- @return (string) The IMEI of the modem, or (nil, string) on failure. +--- +function utils.get_modem_imei() + -- The command to invoke the spirit of the QMI daemon for the IMEI. + local command = "uqmi -d /dev/cdc-wdm0 --get-imei" + local output = utils.execute_command(command) + + -- A silent spirit offers no truths. + if not output or output == "" then + return nil, "No output from uqmi --get-imei command" + end + + -- The IMEI is presented within a sacred container of quotes. We must extract it. + local imei = output:match('"(.-)"') + if not imei then + return nil, "Failed to parse IMEI from uqmi output" + end + + -- Return the sanctified identity code. + return imei +end + +--- +-- The Rite of ICCID Transmutation +-- This complex rite reads the raw data-wafer identity and transmutes it into its true form. +-- @return (string) The decoded ICCID of the SIM, or (nil, string) on failure. +--- +function utils.get_sim_iccid() + -- This command reads the raw data from the SIM's sacred memory location (EF-ICCID). + local command = "qmicli -d /dev/cdc-wdm0 --uim-read-transparent=0x3F00,0x2FE2" + local output = utils.execute_command(command) + + if not output or output == "" then + return nil, "No output from qmicli command" + end + + -- The data-psalm contains many verses, but we seek only one. + local raw_data = output:match("Read result:%s*([%x%s:]+)") + if not raw_data then + return nil, "Failed to parse raw ICCID data from qmicli output" + end + + -- Cleanse the raw data of its structural impurities (spaces and colons). + raw_data = raw_data:gsub("[:%s]","") + + -- Prepare for the transmutation rite. + local decoded_iccid = "" + -- The raw data is in a semi-nibble-swapped format and must be corrected. + -- This loop performs the ritual of character-pair swapping. + for i = 1, #raw_data, 2 do + local char1 = raw_data:sub(i, i) + local char2 = raw_data:sub(i + 1, i + 1) + if char2 then + decoded_iccid = decoded_iccid .. char2 .. char1 + else + decoded_iccid = decoded_iccid .. char1 -- Append last char if odd length + end + end + + -- The transmutation is complete. Present the true ICCID. + return decoded_iccid +end + return utils