├── .github └── workflows │ └── build.yaml ├── .gitignore ├── Dockerfile ├── README.md ├── docker ├── entrypoint-msh.sh └── telegraf.conf ├── go.mod ├── go.sum ├── grafana └── dashboard.json ├── main.go ├── modems ├── comhemc2 │ └── comhemc2.go ├── superhub3 │ ├── README.md │ ├── superhub3.go │ ├── superhub3_test.go │ └── test_state │ │ ├── README.md │ │ ├── chm.json │ │ ├── chmb.json │ │ ├── chmi.json │ │ ├── eni.json │ │ ├── frd.json │ │ ├── msh.json │ │ └── mshm.json ├── superhub4 │ ├── README.md │ ├── sh4-testcase.sh │ ├── superhub4.go │ └── test_state │ │ ├── cg0.json │ │ └── sno.json ├── superhub5 │ ├── README.md │ └── superhub5.go ├── tc4400 │ ├── README.md │ └── tc4400.go └── ubee │ ├── README.md │ └── ubee.go ├── outputs ├── influx.go └── prometheus.go └── utils ├── tools.go └── types.go /.github/workflows/build.yaml: -------------------------------------------------------------------------------- 1 | name: Build binaries 2 | 3 | on: 4 | push: 5 | branches: 6 | - '*' 7 | workflow_dispatch: 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout source 15 | uses: actions/checkout@v3 16 | 17 | - name: Setup Go 18 | uses: actions/setup-go@v2 19 | with: 20 | go-version: '1.21.1' 21 | 22 | - name: Extract branch name 23 | shell: bash 24 | run: | 25 | OBJECT_SUFFIX='' 26 | DOCKER_TAG="latest" 27 | if [[ "${GITHUB_REF_NAME}" != "main" ]]; then 28 | OBJECT_SUFFIX=".${GITHUB_REF_NAME}" 29 | DOCKER_TAG="${GITHUB_REF_NAME}" 30 | fi 31 | echo "object_suffix=${OBJECT_SUFFIX}" >> $GITHUB_ENV 32 | echo "docker_tag=${DOCKER_TAG}" >> $GITHUB_ENV 33 | id: extract_branch 34 | 35 | - name: Run Go builds 36 | run: | 37 | OBJECT_SUFFIX="${{ env.object_suffix }}" 38 | mkdir output/ 39 | CGO_ENABLED=0 go build -o "output/modem-stats${OBJECT_SUFFIX}.x86" -ldflags '-extldflags "-static"' main.go 40 | CGO_ENABLED=0 GOARCH=arm GOARM=5 go build -o "output/modem-stats${OBJECT_SUFFIX}.arm5" -ldflags '-extldflags "-static"' main.go 41 | CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -o "output/modem-stats${OBJECT_SUFFIX}.macos-arm64" -ldflags '-extldflags "-static"' main.go 42 | 43 | - name: Push binaries to B2 44 | uses: jakejarvis/s3-sync-action@master 45 | env: 46 | AWS_S3_BUCKET: modem-stats 47 | AWS_ACCESS_KEY_ID: ${{ secrets.B2_APPKEY_ID }} 48 | AWS_SECRET_ACCESS_KEY: ${{ secrets.B2_APPKEY }} 49 | SOURCE_DIR: 'output' 50 | AWS_S3_ENDPOINT: 'https://s3.us-west-000.backblazeb2.com/' 51 | 52 | - name: Log in to Docker Hub 53 | uses: docker/login-action@v2 54 | with: 55 | username: ${{ secrets.DOCKER_USERNAME }} 56 | password: ${{ secrets.DOCKER_PASSWORD }} 57 | 58 | - name: Set up Docker Buildx 59 | uses: docker/setup-buildx-action@v2 60 | 61 | - name: Build and push Docker image 62 | uses: docker/build-push-action@v5 63 | with: 64 | tags: msh100/modem-stats:${{ env.docker_tag }} 65 | build-args: | 66 | OBJECT_SUFFIX=${{ env.object_suffix }} 67 | context: . 68 | push: true 69 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/venv/ 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM telegraf:1.16.2 as builder 2 | 3 | ARG OBJECT_SUFFIX='' 4 | 5 | ADD . /test 6 | RUN ls -lah test/ 7 | 8 | ADD "output/modem-stats${OBJECT_SUFFIX}.x86" /modem-stats 9 | RUN chmod +x /modem-stats 10 | 11 | ADD ./docker/entrypoint-msh.sh /entrypoint-msh.sh 12 | RUN chmod +x /entrypoint-msh.sh 13 | 14 | RUN mkdir -p /etc/telegraf.d/ /etc/template/ 15 | ADD ./docker/telegraf.conf /etc/template/ 16 | 17 | # We build from scratch as to remove all the volume and exposures from the 18 | # source Telegraf Docker image. Since we don't have any state or listeners, 19 | # this is "okay" to do. 20 | FROM scratch 21 | 22 | COPY --from=builder / / 23 | 24 | ENTRYPOINT /entrypoint-msh.sh 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Modem Statistics Parser 2 | 3 | A utility to read and parse channel diagnostics information from DOCSIS modems. 4 | This package is intended to be used within a Telegraf instance to be fed into 5 | InfluxDB. 6 | A Prometheus endpoint can also be exposed for collection. 7 | 8 | This package has been written in Go in an attempt to allow it to run on low end 9 | hardware (such as a Raspberry Pi Zero) with no issues. 10 | 11 | ![Grafana dashboard screenshot](https://user-images.githubusercontent.com/4477262/114266746-cd910980-99ef-11eb-8a5e-f4f719897719.JPG) 12 | 13 | 14 | * [Usage](#Usage) 15 | * [Docker Image](#Docker-Image) 16 | * [Telegraf](#Telegraf) 17 | * [Prometheus](#Prometheus) 18 | * [Binaries](#Binaries) 19 | * [Download](#Downloading) 20 | * [Build](#Building) 21 | * [Configuration](#Configuration) 22 | * [Example Usage](#Example-Usage) 23 | * [Grafana](#Grafana) 24 | 25 | 26 | ## Usage 27 | 28 | In its simplest form, you can run this repository directly. 29 | The only dependency being Go. 30 | 31 | A compiled binary of this repository will require no dependencies. 32 | 33 | 34 | ### Docker Image 35 | 36 | A Docker image exists for this repository with Telegraf configured to write to 37 | InfluxDB at `msh100/modem-stats`. 38 | This image currently only supports X86. 39 | 40 | The following environment variables must be set: 41 | 42 | Name | Description | Example 43 | -----------------|---------------------------------------------|--------------------- 44 | `INFLUX_URL` | The HTTP API URI for your InfluxDB server. | `http://influxdb:8086` 45 | `INFLUX_DB` | The InfluxDB database to use | `modem-stats` 46 | `PING_TARGETS` | A comma seperated string of targets to ping | `1.1.1.1,8.8.8.8,bbc.co.uk` 47 | `FETCH_INTERVAL` | The frequency (in seconds) to fetch stats. | `10` (default `10`) 48 | 49 | Environment variables must also be passed in for `modem-stats` to run. 50 | Check the [configuration section below](#Configuration). 51 | 52 | `docker-compose.yaml` example: 53 | ```yaml 54 | --- 55 | version: "2.1" 56 | services: 57 | modem-stats: 58 | image: msh100/modem-stats 59 | container_name: modem-stats 60 | environment: 61 | - INFLUX_URL=http://influxdb:8086 62 | - INFLUX_DB=modem-stats 63 | - PING_TARGETS=1.1.1.1,8.8.8.8,bbc.co.uk 64 | - ROUTER_TYPE=superhub3 65 | - ROUTER_IP=192.168.100.1 66 | restart: unless-stopped 67 | ``` 68 | 69 | 70 | ### Telegraf 71 | 72 | If you are already running Telegraf, it makes more sense to add an extra input 73 | to collect data from your modem. 74 | 75 | To do this, we utilise the `input.execd` plugin (which exists in upstream 76 | Telegraf). 77 | Telegraf will be able to trigger a statistics fetch and interpret the output to 78 | pass it over to your Telegraf outputs. 79 | 80 | To run within Telegraf, you should [obtain a binary](#Downloading) for your 81 | architecture and make that binary accessible to Telegraf (this may involve 82 | mounting the binary if you are running Docker). 83 | 84 | The Telegraf configuration should then use the `execd` input to collect data 85 | from modem stats. 86 | 87 | We need to set the `--daemon` flag to instruct Modem Stats to listen for new 88 | STDIN lines to trigger data gathering. 89 | 90 | ``` 91 | [[inputs.execd]] 92 | command = ["/modem-stats", "--daemon"] 93 | data_format = "influx" 94 | signal = "STDIN" 95 | ``` 96 | 97 | To pass [configuration](#Configuration), you need to start Telegraf with those 98 | environment variables defined. 99 | If this is not possible, you can create a wrapper script to set those variables 100 | and call `modem-stats`, like the following: 101 | 102 | ```bash 103 | #!/bin/bash 104 | /modem-stats --modem=superhub3 --daemon 105 | ``` 106 | 107 | 108 | ### Prometheus 109 | 110 | Is it possible to expose a Prometheus exporter. 111 | If `--port` is defined, a webserver will start and Prometheus metrics will be 112 | accessible at `/metrics`. 113 | 114 | ``` 115 | $ /modem-stats --modem=superhub3 --port=9000 116 | ``` 117 | 118 | 119 | ## Binaries 120 | 121 | The output of this repository is ultimately a single static binary with zero 122 | dependencies. 123 | 124 | 125 | ### Downloading 126 | 127 | Upon push to main, this repository builds and pushed binaries. 128 | These can be downloaded from: 129 | 130 | * [Linux amd64](https://b2.msh100.uk/file/modem-stats/modem-stats.x86) 131 | * [Linux ARM5](https://b2.msh100.uk/file/modem-stats/modem-stats.arm5) 132 | * [MacOS ARM64](https://b2.msh100.uk/file/modem-stats/modem-stats.macos-arm64) 133 | 134 | More architectures can be added on request. 135 | 136 | In most cases, these binaries will be sufficient. 137 | 138 | 139 | ### Building 140 | 141 | If you would like to build the binaries yourself, you will require Go 1.21 (may 142 | work with earlier versions, but this is untested). 143 | 144 | ``` 145 | go build -o modem-stats main.go 146 | ``` 147 | 148 | For other architectures, extra options will need to be provided. 149 | [Refer to this blog port for more information](https://www.digitalocean.com/community/tutorials/how-to-build-go-executables-for-multiple-platforms-on-ubuntu-16-04). 150 | 151 | 152 | ## Configuration 153 | 154 | The scripts need to know the modem type (`ROUTER_TYPE` or `--modem=`). 155 | Additional information depends on the model. 156 | 157 | **Virgin Media Superhub 3
158 | Ziggo Connectbox:** 159 | * `ROUTER_TYPE=superhub3` or `--modem=superhub3` 160 | * `ROUTER_IP` or `--ip=x.x.x.x` (defaults to `192.168.100.1`) 161 | 162 | **Virgin Media Superhub 4:** 163 | > **:warning: Warning:** Despite this statistics parser being fully functional, after some time the Superhub 4 fails to provide valid statistics until the device is rebooted. This is not an issue with the parser, but is an issue with the Superhub itself. [Issue](https://github.com/msh100/modem-stats/issues/2). 164 | * `ROUTER_TYPE=superhub4` or `--modem=superhub4` 165 | * `ROUTER_IP` or `--ip=x.x.x.x` (defaults to `192.168.100.1`) 166 | 167 | **Virgin Media Superhub 5:** 168 | * `ROUTER_TYPE=superhub5` or `--modem=superhub5` 169 | * `ROUTER_IP` or `--ip=x.x.x.x` (defaults to `192.168.100.1`) 170 | 171 | **Com Hem WiFi Hub C2:** 172 | (This is likely to work on any Sagemcom DOCSIS modem) 173 | * `ROUTER_TYPE=comhemc2` or `--modem=comhemc2` 174 | * `ROUTER_IP` or `--ip=x.x.x.x` (defaults to `192.168.10.1`) 175 | * `ROUTER_USER` or `--username=admin` (defaults to `admin`) 176 | * `ROUTER_PASS` or `--password=password` (defaults to `admin`) 177 | 178 | **Ubee UBC1318:** 179 | * `ROUTER_TYPE=ubee` 180 | * `ROUTER_IP` or `--ip=x.x.x.x` (defaults to `192.168.100.1`) 181 | 182 | **Technicolor TC4400:** 183 | * `ROUTER_TYPE=tc4400` 184 | * `ROUTER_IP` or `--ip=x.x.x.x` (defaults to `192.168.100.1`) 185 | * `ROUTER_USER` or `--username=user` (defaults to `user`) 186 | * `ROUTER_PASS` or `--password=password` (defaults to `password`) 187 | 188 | 189 | ### Example Usage 190 | 191 | ``` 192 | $ ROUTER_TYPE=superhub3 ROUTER_IP=192.168.100.1 go run main.go 193 | downstream,channel=3,id=10,modulation=QAM256,scheme=SC-QAM frequency=211000000,snr=403,power=71,prerserr=300,postrserr=0 194 | downstream,channel=9,id=16,modulation=QAM256,scheme=SC-QAM frequency=259000000,snr=409,power=68,prerserr=72,postrserr=0 195 | ... 196 | $ go run main.go --modem=superhub3 --ip=192.168.100.1 197 | downstream,channel=3,id=10,modulation=QAM256,scheme=SC-QAM frequency=211000000,snr=403,power=71,prerserr=300,postrserr=0 198 | downstream,channel=9,id=16,modulation=QAM256,scheme=SC-QAM frequency=259000000,snr=409,power=68,prerserr=72,postrserr=0 199 | ... 200 | ``` 201 | 202 | 203 | ## Grafana 204 | 205 | You can add [the Router Stats dashboard](https://grafana.com/grafana/dashboards/14209) 206 | to your Grafana instance by adding dashboard ID `14209`. 207 | -------------------------------------------------------------------------------- /docker/entrypoint-msh.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit 3 | set -o pipefail 4 | set -o nounset 5 | 6 | : ${INFLUX_URL:?INFLUX_URL not defined (example "http://influxdb:8086")} 7 | : ${INFLUX_DB:?INFLUX_DB not defined (example "modem-stats")} 8 | FETCH_INTERVAL="${FETCH_INTERVAL:-10}" 9 | 10 | # Fetch interval needs to be a numerical value 11 | if ! [[ "${FETCH_INTERVAL}" =~ ^[0-9]+$ ]] ; then 12 | echo "FETCH_INTERVAL must be numerical" >&2 13 | exit 1 14 | fi 15 | 16 | # Create a ping targets array from comma seperated string of targets 17 | PING_TARGETS="${PING_TARGETS:-""}" 18 | if [ "${PING_TARGETS}" != "" ]; then 19 | PING_TARGETS_ARR=(${PING_TARGETS//,/ }) 20 | PING_TARGETS_STRING="" 21 | for TARGET_VALUE in "${PING_TARGETS_ARR[@]}"; do 22 | PING_TARGETS_STRING="${PING_TARGETS_STRING}\"${TARGET_VALUE}\", " 23 | done 24 | PING_TARGETS="[ ${PING_TARGETS_STRING::-2} ]" 25 | else 26 | PING_TARGETS="[]" 27 | fi 28 | 29 | # We can't template an array, so need to write this before exec 30 | cat /etc/template/telegraf.conf |\ 31 | sed "s/_PING_TARGETS/${PING_TARGETS}/" >\ 32 | /etc/telegraf.d/telegraf.conf 33 | 34 | export FETCH_INTERVAL 35 | export INFLUX_URL 36 | export INFLUX_DB 37 | 38 | exec telegraf \ 39 | --config "/etc/telegraf.d/telegraf.conf" \ 40 | --config-directory "/etc/telegraf.d/" 41 | -------------------------------------------------------------------------------- /docker/telegraf.conf: -------------------------------------------------------------------------------- 1 | [agent] 2 | interval = "${FETCH_INTERVAL}s" 3 | round_interval = true 4 | metric_batch_size = 1000 5 | metric_buffer_limit = 10000 6 | collection_jitter = "0s" 7 | flush_interval = "5s" 8 | flush_jitter = "0s" 9 | precision = "" 10 | debug = false 11 | quiet = false 12 | logfile = "" 13 | hostname = "" 14 | omit_hostname = false 15 | 16 | [[outputs.influxdb]] 17 | urls = ["${INFLUX_URL}"] 18 | database = "${INFLUX_DB}" 19 | retention_policy = "" 20 | write_consistency = "any" 21 | timeout = "5s" 22 | 23 | [[inputs.ping]] 24 | urls = _PING_TARGETS 25 | 26 | [[inputs.execd]] 27 | command = ["/modem-stats", "--daemon"] 28 | data_format = "influx" 29 | signal = "STDIN" 30 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/msh100/modem-stats 2 | 3 | go 1.15 4 | 5 | require ( 6 | github.com/Jeffail/gabs/v2 v2.6.0 7 | github.com/PuerkitoBio/goquery v1.7.1 // indirect 8 | github.com/evanphx/json-patch v0.5.2 // indirect 9 | github.com/evanphx/json-patch/v5 v5.6.0 // indirect 10 | github.com/jessevdk/go-flags v1.5.0 11 | github.com/prometheus/client_golang v1.11.0 12 | github.com/stretchr/testify v1.4.0 13 | ) 14 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | github.com/Jeffail/gabs/v2 v2.6.0 h1:WdCnGaDhNa4LSRTMwhLZzJ7SRDXjABNP13SOKvCpL5w= 3 | github.com/Jeffail/gabs/v2 v2.6.0/go.mod h1:xCn81vdHKxFUuWWAaD5jCTQDNPBMh5pPs9IJ+NcziBI= 4 | github.com/PuerkitoBio/goquery v1.7.1 h1:oE+T06D+1T7LNrn91B4aERsRIeCLJ/oPSa6xB9FPnz4= 5 | github.com/PuerkitoBio/goquery v1.7.1/go.mod h1:XY0pP4kfraEmmV1O7Uf6XyjoslwsneBbgeDjLYuN8xY= 6 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 7 | github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 8 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 9 | github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 10 | github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= 11 | github.com/andybalholm/cascadia v1.2.0 h1:vuRCkM5Ozh/BfmsaTm26kbjm0mIOM3yS5Ek/F5h18aE= 12 | github.com/andybalholm/cascadia v1.2.0/go.mod h1:YCyR8vOZT9aZ1CHEd8ap0gMVm2aFgxBp0T0eFw1RUQY= 13 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= 14 | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= 15 | github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= 16 | github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= 17 | github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= 18 | github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 19 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 20 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 21 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 22 | github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k= 23 | github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= 24 | github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= 25 | github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= 26 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 27 | github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 28 | github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= 29 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= 30 | github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= 31 | github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= 32 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 33 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 34 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 35 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 36 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 37 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 38 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 39 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 40 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 41 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 42 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 43 | github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= 44 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 45 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 46 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 47 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 48 | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 49 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 50 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 51 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 52 | github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 53 | github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= 54 | github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= 55 | github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= 56 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 57 | github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 58 | github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 59 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 60 | github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= 61 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 62 | github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 63 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= 64 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 65 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 66 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 67 | github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= 68 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= 69 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 70 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 71 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 72 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 73 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 74 | github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 75 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 76 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 77 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 78 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 79 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 80 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 81 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= 82 | github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= 83 | github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= 84 | github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= 85 | github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= 86 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 87 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 88 | github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= 89 | github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 90 | github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 91 | github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= 92 | github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= 93 | github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= 94 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 95 | github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= 96 | github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= 97 | github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= 98 | github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= 99 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 100 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= 101 | github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= 102 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 103 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 104 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 105 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 106 | github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= 107 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 108 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 109 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 110 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 111 | golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 112 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 113 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 114 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 115 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 116 | golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 117 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 118 | golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= 119 | golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 120 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 121 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 122 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 123 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 124 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 125 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 126 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 127 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 128 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 129 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 130 | golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 131 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 132 | golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 133 | golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 134 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 135 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 136 | golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 137 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 138 | golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q= 139 | golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 140 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 141 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 142 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 143 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 144 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 145 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 146 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 147 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 148 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 149 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 150 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 151 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 152 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 153 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 154 | google.golang.org/protobuf v1.26.0-rc.1 h1:7QnIQpGRHE5RnLKnESfDoxm2dTapTZua5a0kS0A+VXQ= 155 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 156 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 157 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 158 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 159 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 160 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 161 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 162 | gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 163 | gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= 164 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 165 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io/ioutil" 7 | "log" 8 | "os" 9 | "time" 10 | 11 | flags "github.com/jessevdk/go-flags" 12 | "github.com/msh100/modem-stats/modems/comhemc2" 13 | "github.com/msh100/modem-stats/modems/superhub3" 14 | "github.com/msh100/modem-stats/modems/superhub4" 15 | "github.com/msh100/modem-stats/modems/superhub5" 16 | "github.com/msh100/modem-stats/modems/tc4400" 17 | "github.com/msh100/modem-stats/modems/ubee" 18 | "github.com/msh100/modem-stats/outputs" 19 | "github.com/msh100/modem-stats/utils" 20 | ) 21 | 22 | var commandLineOpts struct { 23 | Daemon bool `short:"d" long:"daemon" description:"Gather statistics on new line to STDIN"` 24 | PrometheusPort int `short:"p" long:"port" description:"Prometheus exporter port (disabled if not defined)"` 25 | Modem string `short:"m" long:"modem" description:"Which modem to use" default:"superhub3"` 26 | ModemIP string `long:"ip" description:"The modem's IP address"` 27 | Username string `long:"username" description:"The modem's username (if applicable)"` 28 | Password string `long:"password" description:"The modem's password (if applicable)"` 29 | } 30 | 31 | func main() { 32 | _, err := flags.ParseArgs(&commandLineOpts, os.Args) 33 | if err != nil { 34 | log.Fatal("error parsing command line arguments") 35 | os.Exit(1) 36 | } 37 | 38 | var body []byte 39 | var fetchTime int64 40 | if localFile := utils.Getenv("LOCAL_FILE", ""); localFile != "" { 41 | timeStart := time.Now().UnixNano() / int64(time.Millisecond) 42 | file, _ := os.Open(localFile) 43 | body, _ = ioutil.ReadAll(file) 44 | fetchTime = (time.Now().UnixNano() / int64(time.Millisecond)) - timeStart 45 | } 46 | 47 | var routerType string 48 | superhubType := utils.Getenv("SH_VERSION", "") 49 | if superhubType != "" { 50 | routerType = fmt.Sprintf("superhub%s", superhubType) 51 | } else { 52 | routerType = utils.Getenv("ROUTER_TYPE", commandLineOpts.Modem) 53 | } 54 | 55 | var modem utils.DocsisModem 56 | 57 | switch routerType { 58 | case "superhub4": 59 | modem = &superhub4.Modem{ 60 | IPAddress: utils.Getenv("ROUTER_IP", commandLineOpts.ModemIP), 61 | Stats: body, 62 | FetchTime: fetchTime, 63 | } 64 | case "comhemc2": 65 | modem = &comhemc2.Modem{ 66 | IPAddress: utils.Getenv("ROUTER_IP", commandLineOpts.ModemIP), 67 | Stats: body, 68 | FetchTime: fetchTime, 69 | Username: utils.Getenv("ROUTER_USER", commandLineOpts.Username), 70 | Password: utils.Getenv("ROUTER_PASS", commandLineOpts.Password), 71 | } 72 | case "superhub3": 73 | modem = &superhub3.Modem{ 74 | IPAddress: utils.Getenv("ROUTER_IP", commandLineOpts.ModemIP), 75 | Stats: body, 76 | FetchTime: fetchTime, 77 | } 78 | case "ubee": 79 | modem = &ubee.Modem{ 80 | IPAddress: utils.Getenv("ROUTER_IP", commandLineOpts.ModemIP), 81 | Stats: body, 82 | FetchTime: fetchTime, 83 | } 84 | case "superhub5": 85 | modem = &superhub5.Modem{ 86 | IPAddress: utils.Getenv("ROUTER_IP", commandLineOpts.ModemIP), 87 | Stats: body, 88 | FetchTime: fetchTime, 89 | } 90 | case "tc4400": 91 | modem = &tc4400.Modem{ 92 | IPAddress: utils.Getenv("ROUTER_IP", commandLineOpts.ModemIP), 93 | Stats: body, 94 | FetchTime: fetchTime, 95 | Username: utils.Getenv("ROUTER_USER", commandLineOpts.Username), 96 | Password: utils.Getenv("ROUTER_PASS", commandLineOpts.Password), 97 | } 98 | default: 99 | log.Fatalf("unknown modem: %s", routerType) 100 | } 101 | 102 | if commandLineOpts.PrometheusPort > 0 { 103 | outputs.Prometheus(modem, commandLineOpts.PrometheusPort) 104 | } else { 105 | for { 106 | modemStats, err := utils.FetchStats(modem) 107 | 108 | if err != nil { 109 | log.Printf("Error returned by parser: %v", err) 110 | } else { 111 | outputs.PrintForInflux(modemStats) 112 | } 113 | 114 | if commandLineOpts.Daemon { 115 | bufio.NewScanner(os.Stdin).Scan() 116 | utils.ResetStats(modem) 117 | } else { 118 | break 119 | } 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /modems/comhemc2/comhemc2.go: -------------------------------------------------------------------------------- 1 | package comhemc2 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io/ioutil" 7 | "net/http" 8 | "strconv" 9 | "strings" 10 | "time" 11 | 12 | gabs "github.com/Jeffail/gabs/v2" 13 | 14 | "github.com/msh100/modem-stats/utils" 15 | ) 16 | 17 | type Modem struct { 18 | IPAddress string 19 | Stats []byte 20 | FetchTime int64 21 | Username string 22 | Password string 23 | sagemClient *sagemClient 24 | } 25 | 26 | type sagemClient struct { 27 | host string 28 | username string 29 | password string 30 | 31 | currentNonce int 32 | serverNonce string 33 | sessionID int 34 | requestID int 35 | } 36 | 37 | func (sagemClient *sagemClient) loginRequest() string { 38 | request := `[ 39 | { 40 | "method": "logIn", 41 | "parameters": { 42 | "user": "%s", 43 | "persistent": "true", 44 | "session-options": { 45 | "nss": [ 46 | { 47 | "name": "gtw", 48 | "uri": "http://sagemcom.com/gateway-data" 49 | } 50 | ], 51 | "language": "ident", 52 | "context-flags": { 53 | "get-content-name": true, 54 | "local-time": true 55 | }, 56 | "capability-depth": 2, 57 | "capability-flags": { 58 | "name": true, 59 | "default-value": false, 60 | "restriction": true, 61 | "description": false 62 | }, 63 | "time-format": "ISO_8601", 64 | "write-only-string": "_XMO_WRITE_ONLY_", 65 | "undefined-write-only-string": "_XMO_UNDEFINED_WRITE_ONLY_" 66 | } 67 | } 68 | } 69 | ]` 70 | 71 | return fmt.Sprintf(request, sagemClient.username) 72 | } 73 | 74 | func (sagemClient *sagemClient) apiRequest(actions string) ([]byte, error) { 75 | actionsObj, _ := gabs.ParseJSON([]byte(actions)) 76 | requestMethod := utils.GabsString(actionsObj, "0.method") 77 | if sagemClient.sessionID == 0 && requestMethod != "logIn" { 78 | _, err := sagemClient.apiRequest(sagemClient.loginRequest()) 79 | if err != nil { 80 | return nil, err 81 | } 82 | } 83 | 84 | sagemClient.requestID = sagemClient.requestID + 1 85 | sagemClient.currentNonce = utils.RandomInt(10000, 50000) 86 | 87 | credentialHash := fmt.Sprintf("%s:%s:%s", 88 | sagemClient.username, 89 | sagemClient.serverNonce, 90 | utils.StringToMD5(sagemClient.password), 91 | ) 92 | 93 | authKey := utils.StringToMD5( 94 | fmt.Sprintf("%s:%d:%d:JSON:/cgi/json-req", 95 | utils.StringToMD5(credentialHash), 96 | sagemClient.requestID, 97 | sagemClient.currentNonce, 98 | ), 99 | ) 100 | 101 | APIAddress := fmt.Sprintf("http://%s/cgi/json-req", sagemClient.host) 102 | 103 | payloadObj := gabs.New() 104 | payloadObj.Set(sagemClient.requestID, "request", "id") 105 | payloadObj.Set(sagemClient.sessionID, "request", "session-id") 106 | payloadObj.Set("False", "request", "priority") 107 | payloadObj.Set(actionsObj, "request", "actions") 108 | if sagemClient.currentNonce > 0 { 109 | payloadObj.Set(fmt.Sprintf("%d", sagemClient.currentNonce), "request", "cnonce") 110 | } 111 | payloadObj.Set(authKey, "request", "auth-key") 112 | jsonPayload := []byte(fmt.Sprintf("req=%s", payloadObj.String())) 113 | 114 | req, _ := http.NewRequest("POST", APIAddress, bytes.NewBuffer(jsonPayload)) 115 | client := &http.Client{} 116 | resp, err := client.Do(req) 117 | if err != nil { 118 | return nil, err 119 | } 120 | defer resp.Body.Close() 121 | body, _ := ioutil.ReadAll(resp.Body) 122 | 123 | returnValue, _ := gabs.ParseJSON(body) 124 | returnID := utils.GabsString(returnValue, "reply.actions.0.callbacks.0.parameters.id") 125 | returnNonce := utils.GabsString(returnValue, "reply.actions.0.callbacks.0.parameters.nonce") 126 | errorCode := utils.GabsString(returnValue, "reply.error.code") 127 | 128 | if returnID != "null" && returnNonce != "null" { 129 | sagemClient.sessionID, _ = strconv.Atoi(returnID) 130 | sagemClient.serverNonce = returnNonce 131 | } 132 | if errorCode == "16777219" { // Session has expired 133 | sagemClient.sessionID = 0 134 | sagemClient.currentNonce = 0 135 | sagemClient.requestID = -1 136 | sagemClient.serverNonce = "" 137 | 138 | _, err := sagemClient.apiRequest(sagemClient.loginRequest()) 139 | if err != nil { 140 | return nil, err 141 | } 142 | 143 | return sagemClient.apiRequest(actions) 144 | } 145 | 146 | return body, nil 147 | } 148 | 149 | func (sagemClient *sagemClient) getXpaths(xpaths []string) ([]byte, error) { 150 | xpathTpl := `{"id":%d,"method":"getValue","xpath":"%s","options":{}}` 151 | outputXpaths := []string{} 152 | 153 | for id, xpath := range xpaths { 154 | outputXpaths = append(outputXpaths, fmt.Sprintf(xpathTpl, id, xpath)) 155 | } 156 | xpathReq := fmt.Sprintf("[%s]", strings.Join(outputXpaths, ",")) 157 | 158 | return sagemClient.apiRequest(xpathReq) 159 | } 160 | 161 | func (comhemc2 *Modem) ClearStats() { 162 | comhemc2.Stats = nil 163 | } 164 | 165 | func (comhemc2 *Modem) Type() string { 166 | return utils.TypeDocsis 167 | } 168 | 169 | func (comhemc2 *Modem) ParseStats() (utils.ModemStats, error) { 170 | if comhemc2.Stats == nil { 171 | timeStart := time.Now().UnixNano() / int64(time.Millisecond) 172 | 173 | if comhemc2.sagemClient == nil { 174 | if comhemc2.Username == "" { 175 | comhemc2.Username = "admin" 176 | } 177 | if comhemc2.Password == "" { 178 | comhemc2.Password = "admin" 179 | } 180 | if comhemc2.IPAddress == "" { 181 | comhemc2.IPAddress = "192.168.10.1" 182 | } 183 | comhemc2.sagemClient = &sagemClient{ 184 | host: comhemc2.IPAddress, 185 | username: comhemc2.Username, 186 | password: comhemc2.Password, 187 | currentNonce: 0, 188 | sessionID: 0, 189 | requestID: -1, 190 | } 191 | } 192 | 193 | channelDataReq, err := comhemc2.sagemClient.getXpaths([]string{ 194 | "Device/Docsis/CableModem/Upstreams", 195 | "Device/Docsis/CableModem/Downstreams", 196 | }) 197 | if err != nil { 198 | return utils.ModemStats{}, err 199 | } 200 | 201 | fetchTime := (time.Now().UnixNano() / int64(time.Millisecond)) - timeStart 202 | 203 | comhemc2.FetchTime = fetchTime 204 | comhemc2.Stats = channelDataReq 205 | } 206 | 207 | var downChannels []utils.ModemChannel 208 | var upChannels []utils.ModemChannel 209 | 210 | jsonParsed, err := gabs.ParseJSON(comhemc2.Stats) 211 | if err != nil { 212 | return utils.ModemStats{}, err 213 | } 214 | 215 | reply := jsonParsed.Path("reply") 216 | for _, action := range reply.S("actions").Children() { 217 | query := utils.GabsString(action, "callbacks.0.xpath") 218 | channels := action.Path("callbacks.0.parameters") 219 | 220 | if query == "Device/Docsis/CableModem/Upstreams" { 221 | for _, channelData := range channels.S("value").Children() { 222 | upChannels = append(upChannels, utils.ModemChannel{ 223 | ChannelID: utils.GabsInt(channelData, "ChannelID"), 224 | Channel: utils.GabsInt(channelData, "uid"), 225 | Frequency: utils.GabsInt(channelData, "Frequency"), 226 | Power: int(utils.GabsFloat(channelData, "PowerLevel") * 10), 227 | }) 228 | } 229 | 230 | } else if query == "Device/Docsis/CableModem/Downstreams" { 231 | for _, channelData := range channels.S("value").Children() { 232 | modulation := utils.GabsString(channelData, "Modulation") 233 | var scheme string 234 | scheme = "SC-QAM" 235 | if modulation == "256-QAM/4K-QAM" { 236 | scheme = "OFDM" 237 | } 238 | 239 | downChannels = append(downChannels, utils.ModemChannel{ 240 | ChannelID: utils.GabsInt(channelData, "ChannelID"), 241 | Channel: utils.GabsInt(channelData, "uid"), 242 | Frequency: utils.GabsInt(channelData, "Frequency"), 243 | Snr: int(utils.GabsFloat(channelData, "SNR") * 10), 244 | Power: int(utils.GabsFloat(channelData, "PowerLevel") * 10), 245 | Prerserr: utils.GabsInt(channelData, "CorrectableCodewords"), 246 | Postrserr: utils.GabsInt(channelData, "UncorrectableCodewords"), 247 | Modulation: modulation, 248 | Scheme: scheme, 249 | }) 250 | } 251 | } 252 | 253 | } 254 | 255 | return utils.ModemStats{ 256 | UpChannels: upChannels, 257 | DownChannels: downChannels, 258 | FetchTime: comhemc2.FetchTime, 259 | }, nil 260 | } 261 | -------------------------------------------------------------------------------- /modems/superhub3/README.md: -------------------------------------------------------------------------------- 1 | # Superhub 3 Channel Processor 2 | 3 | ## Supported Modems 4 | 5 | The Superhub 3 is distributed to multiple countries with different branding by 6 | Liberty Global. 7 | 8 | This processor is known to work on: 9 | 10 | - Virgin Media Superhub 3 11 | - Ziggo Connectbox 12 | 13 | Expected to work, but untested: 14 | 15 | - Virgin Media Ireland Superhub 3 16 | - UPC Switzerland Connect Box 17 | - UPC Poland Connect Box 18 | - UPC Slovakia prémiový modem 19 | - Unity Media Germany Connect Box 20 | 21 | 22 | ## Fetching the Data 23 | 24 | The Superhub 3 (and equivilent international variants) exposes an endpoint over 25 | HTTP which is used to display statistics on the web interface of the router. 26 | This page is visible without authentication and is constructed by making an 27 | extra HTTP call to an endpoint which returns a JSON document with SNMP MIBs and 28 | their associated values. 29 | 30 | A simple HTTP GET to `http://$ROUTER_IP/getRouterStatus` will return this 31 | document. 32 | 33 | The document has the following structure as a single dimentional object: 34 | ```json 35 | { 36 | "MIB1": "VALUE", 37 | "MIB2": "VALUE" 38 | } 39 | ``` 40 | 41 | ## Interpreting the Data 42 | 43 | 44 | ### Profile Speeds 45 | 46 | First of all, we create a list of upstream and downsteam profiles 47 | 48 | ``` 49 | 1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.$ID1.$ID2 = $DIRECTION 50 | ``` 51 | 52 | `$ID2` represents the SFID which is displayed in the Superhub web interface. 53 | Profile's with the `$DIRECTION` of `1` are downstream, and `2` are upstream. 54 | 55 | From here we loop over all the configs to see which is active, as represented 56 | by a `1` value at the following MIB: 57 | 58 | ``` 59 | 1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.$ID1.$ID2 60 | ``` 61 | 62 | There should only be a single MIB for each upstream and downstream. 63 | From here ID2 is the value we need to determine the MaxRate and MaxBurst. 64 | 65 | ``` 66 | 1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.$ID2 = MaxRate 67 | 1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.$ID2 = MaxBurst 68 | ``` 69 | 70 | 71 | ### Channel Information 72 | 73 | Each channel has a number of values. 74 | Note that the channel ID and what the Superhub considers to be the ID are 75 | not the same values. 76 | 77 | The MIBs that are used for **downstream** channels are: 78 | 79 | ``` 80 | 1.3.6.1.2.1.10.127.1.1.1.1.$ID = Channel ID 81 | 1.3.6.1.2.1.10.127.1.1.1.1.2.$ID = Frequency 82 | 1.3.6.1.2.1.10.127.1.1.1.1.6.$ID = Power Level 83 | 1.3.6.1.2.1.10.127.1.1.4.1.5.$ID = SNR 84 | 1.3.6.1.2.1.10.127.1.1.4.1.3.$ID = Pre RS Errors 85 | 1.3.6.1.2.1.10.127.1.1.4.1.4.$ID = Post RS Errors 86 | ``` 87 | 88 | The MIBs that are used for **upstream** channels are: 89 | 90 | ``` 91 | 1.3.6.1.2.1.10.127.1.1.2.1.1.$ID = Channel ID 92 | 1.3.6.1.2.1.10.127.1.1.2.1.1.$ID = Frequency 93 | 1.3.6.1.4.1.4491.2.1.20.1.2.1.1.$ID = Power Level 94 | ``` 95 | 96 | 97 | #### Detemine Channels 98 | 99 | The method we use to determine channels is by iterating over MIB strings to 100 | find matches. 101 | 102 | ``` 103 | 1.3.6.1.2.1.10.127.1.1.1.1.1.([0-9]+) = Upstream Channels 104 | 1.3.6.1.2.1.10.127.1.1.2.1.1.([0-9]+) = Downstream Channels 105 | ``` 106 | 107 | There's also a MIB that lists all channels: 108 | 109 | ``` 110 | 1.3.6.1.4.1.4115.1.3.4.1.1.12.0 111 | ``` 112 | 113 | The issue we encountered here is the unpredictability in switching from 114 | downstream to upstream channels. 115 | -------------------------------------------------------------------------------- /modems/superhub3/superhub3.go: -------------------------------------------------------------------------------- 1 | package superhub3 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "regexp" 7 | "strconv" 8 | "strings" 9 | 10 | "github.com/msh100/modem-stats/utils" 11 | ) 12 | 13 | type Modem struct { 14 | IPAddress string 15 | Stats []byte 16 | FetchTime int64 17 | } 18 | 19 | func (sh3 *Modem) ClearStats() { 20 | sh3.Stats = nil 21 | } 22 | 23 | func (sh3 *Modem) Type() string { 24 | return utils.TypeDocsis 25 | } 26 | 27 | func (sh3 *Modem) fetchURL() string { 28 | if sh3.IPAddress == "" { 29 | sh3.IPAddress = "192.168.100.1" 30 | } 31 | return fmt.Sprintf("http://%s/getRouterStatus", sh3.IPAddress) 32 | } 33 | 34 | func (sh3 *Modem) activeChannels() ([]int, []int) { 35 | downChannelRegex := regexp.MustCompile("\"1.3.6.1.2.1.10.127.1.1.1.1.1.([0-9]+)\"") 36 | upChannelRegex := regexp.MustCompile("\"1.3.6.1.2.1.10.127.1.1.2.1.1.([0-9]+)\"") 37 | 38 | downChannels := []int{} 39 | upChannels := []int{} 40 | 41 | for _, value := range downChannelRegex.FindAllStringSubmatch(string(sh3.Stats), -1) { 42 | channelID, _ := strconv.Atoi(value[1]) 43 | downChannels = append(downChannels, channelID) 44 | } 45 | for _, value := range upChannelRegex.FindAllStringSubmatch(string(sh3.Stats), -1) { 46 | channelID, _ := strconv.Atoi(value[1]) 47 | upChannels = append(upChannels, channelID) 48 | } 49 | 50 | return downChannels, upChannels 51 | } 52 | 53 | func (sh3 *Modem) activeConfigs() (int, int) { 54 | activeConfigRegex := regexp.MustCompile("\"1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.[0-9]+.([0-9]+)\":\"1\"") 55 | configRegex := regexp.MustCompile("\"1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.[0-9]+.([0-9]+)\":\"([1-2])\"") 56 | 57 | downConfig := 0 58 | upConfig := 0 59 | 60 | // If the JSON for the stats input has been beautified, this regex wont work 61 | statsData := strings.ReplaceAll(string(sh3.Stats), "\": \"", "\":\"") 62 | 63 | var upConfigs []int 64 | var downConfigs []int 65 | for _, value := range configRegex.FindAllStringSubmatch(statsData, -1) { 66 | thisConfig, _ := strconv.Atoi(value[1]) 67 | thisDirection, _ := strconv.Atoi(value[2]) 68 | 69 | if thisDirection == 1 { 70 | downConfigs = append(downConfigs, thisConfig) 71 | } else { 72 | upConfigs = append(upConfigs, thisConfig) 73 | } 74 | } 75 | 76 | for _, value := range activeConfigRegex.FindAllStringSubmatch(statsData, -1) { 77 | thisConfig, _ := strconv.Atoi(value[1]) 78 | 79 | for _, testConfig := range upConfigs { 80 | if testConfig == thisConfig { 81 | upConfig = testConfig 82 | break 83 | } 84 | } 85 | for _, testConfig := range downConfigs { 86 | if testConfig == thisConfig { 87 | downConfig = testConfig 88 | break 89 | } 90 | } 91 | } 92 | 93 | return downConfig, upConfig 94 | } 95 | 96 | func (sh3 *Modem) readMIBInt(json map[string]interface{}, mib string, channel int) int { 97 | MIB := fmt.Sprintf("%s.%d", mib, channel) 98 | outputInt := -1 99 | if json[MIB] != nil { 100 | outputInt, _ = strconv.Atoi(json[MIB].(string)) 101 | } 102 | return outputInt 103 | } 104 | 105 | func (sh3 *Modem) dataAsJSON() map[string]interface{} { 106 | var snmpData map[string]interface{} 107 | json.Unmarshal(sh3.Stats, &snmpData) 108 | return snmpData 109 | } 110 | 111 | func (sh3 *Modem) ParseStats() (utils.ModemStats, error) { 112 | if sh3.Stats == nil { 113 | var err error 114 | sh3.Stats, sh3.FetchTime, err = utils.SimpleHTTPFetch(sh3.fetchURL()) 115 | if err != nil { 116 | return utils.ModemStats{}, err 117 | } 118 | } 119 | 120 | downChannelIDs, upChannelIDs := sh3.activeChannels() 121 | downConfigID, upConfigID := sh3.activeConfigs() 122 | 123 | snmpData := sh3.dataAsJSON() 124 | 125 | var downChannels []utils.ModemChannel 126 | var upChannels []utils.ModemChannel 127 | 128 | for _, channel := range downChannelIDs { 129 | channelID := sh3.readMIBInt(snmpData, "1.3.6.1.2.1.10.127.1.1.1.1.1", channel) 130 | frequency := sh3.readMIBInt(snmpData, "1.3.6.1.2.1.10.127.1.1.1.1.2", channel) 131 | snr := sh3.readMIBInt(snmpData, "1.3.6.1.2.1.10.127.1.1.4.1.5", channel) 132 | power := sh3.readMIBInt(snmpData, "1.3.6.1.2.1.10.127.1.1.1.1.6", channel) 133 | preRSErr := sh3.readMIBInt(snmpData, "1.3.6.1.2.1.10.127.1.1.4.1.3", channel) 134 | postRSErr := sh3.readMIBInt(snmpData, "1.3.6.1.2.1.10.127.1.1.4.1.4", channel) 135 | 136 | downChannels = append(downChannels, utils.ModemChannel{ 137 | ChannelID: channelID, 138 | Channel: channel, 139 | Frequency: frequency, 140 | Snr: snr, 141 | Power: power, 142 | Prerserr: preRSErr, 143 | Postrserr: postRSErr, 144 | Modulation: "QAM256", 145 | Scheme: "SC-QAM", 146 | }) 147 | } 148 | 149 | for _, channel := range upChannelIDs { 150 | channelID := sh3.readMIBInt(snmpData, "1.3.6.1.2.1.10.127.1.1.2.1.1", channel) 151 | frequency := sh3.readMIBInt(snmpData, "1.3.6.1.2.1.10.127.1.1.2.1.2", channel) 152 | power := sh3.readMIBInt(snmpData, "1.3.6.1.4.1.4491.2.1.20.1.2.1.1", channel) 153 | 154 | upChannels = append(upChannels, utils.ModemChannel{ 155 | ChannelID: channelID, 156 | Channel: channel, 157 | Frequency: frequency, 158 | Power: power, 159 | }) 160 | } 161 | 162 | downConfigRate := sh3.readMIBInt(snmpData, "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1", downConfigID) 163 | downConfigBurst := sh3.readMIBInt(snmpData, "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1", downConfigID) 164 | upConfigRate := sh3.readMIBInt(snmpData, "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1", upConfigID) 165 | upConfigBurst := sh3.readMIBInt(snmpData, "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1", upConfigID) 166 | 167 | return utils.ModemStats{ 168 | Configs: []utils.ModemConfig{ 169 | { 170 | Config: "upstream", 171 | Maxrate: upConfigRate, 172 | Maxburst: upConfigBurst, 173 | }, 174 | { 175 | Config: "downstream", 176 | Maxrate: downConfigRate, 177 | Maxburst: downConfigBurst, 178 | }, 179 | }, 180 | UpChannels: upChannels, 181 | DownChannels: downChannels, 182 | FetchTime: sh3.FetchTime, 183 | ModemType: utils.TypeDocsis, 184 | }, nil 185 | } 186 | -------------------------------------------------------------------------------- /modems/superhub3/superhub3_test.go: -------------------------------------------------------------------------------- 1 | package superhub3 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "regexp" 7 | "testing" 8 | 9 | "github.com/msh100/modem-stats/utils" 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func check(e error) { 14 | if e != nil { 15 | panic(e) 16 | } 17 | } 18 | func Test_ClearStats(t *testing.T) { 19 | modemWithStats := Modem{ 20 | Stats: []byte("random"), 21 | } 22 | 23 | assert.Equal(t, []byte("random"), modemWithStats.Stats) 24 | modemWithStats.ClearStats() 25 | assert.Equal(t, []byte(nil), modemWithStats.Stats) 26 | } 27 | 28 | func Test_Type(t *testing.T) { 29 | modem := Modem{} 30 | assert.Equal(t, "DOCSIS", modem.Type()) 31 | } 32 | func Test_fetchURL(t *testing.T) { 33 | definedIP := Modem{ 34 | IPAddress: "192.168.0.1", 35 | } 36 | defaultIP := Modem{} 37 | 38 | assert.Equal(t, "http://192.168.0.1/getRouterStatus", definedIP.fetchURL()) 39 | assert.Equal(t, "http://192.168.100.1/getRouterStatus", defaultIP.fetchURL()) 40 | } 41 | 42 | func Test_activeChannels(t *testing.T) { 43 | type test struct { 44 | input string 45 | up []int 46 | } 47 | 48 | expectedDown := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24} 49 | expectedUp := []int{1, 2, 3, 4} 50 | testTable := []test{ 51 | { 52 | input: "chm.json", 53 | }, 54 | { 55 | input: "chmb.json", 56 | }, 57 | { 58 | input: "chmi.json", 59 | }, 60 | { 61 | input: "eni.json", 62 | }, 63 | { 64 | input: "frd.json", 65 | }, 66 | { 67 | input: "msh.json", 68 | }, 69 | { 70 | input: "mshm.json", 71 | up: []int{2, 3, 4, 5}, // This user has channel 1 used for their telephone over DOCSIS 72 | }, 73 | } 74 | 75 | for _, testData := range testTable { 76 | dat, err := ioutil.ReadFile(fmt.Sprintf("test_state/%s", testData.input)) 77 | check(err) 78 | fmt.Println(testData.input) 79 | modem := Modem{ 80 | Stats: dat, 81 | } 82 | 83 | testUp := expectedUp 84 | if testData.up != nil { 85 | testUp = testData.up 86 | } 87 | 88 | downChannels, upChannels := modem.activeChannels() 89 | assert.EqualValues(t, expectedDown, downChannels) 90 | assert.EqualValues(t, testUp, upChannels) 91 | } 92 | } 93 | 94 | func Test_activeProfile(t *testing.T) { 95 | type test struct { 96 | input string 97 | upProfile int 98 | downProfile int 99 | } 100 | 101 | testTable := []test{ 102 | { 103 | input: "chm.json", 104 | upProfile: 137484, 105 | downProfile: 137483, 106 | }, 107 | { 108 | input: "chmb.json", 109 | upProfile: 8805, 110 | downProfile: 8804, 111 | }, 112 | { 113 | input: "chmi.json", 114 | upProfile: 8805, 115 | downProfile: 8804, 116 | }, 117 | { 118 | input: "eni.json", 119 | upProfile: 981273, 120 | downProfile: 981272, 121 | }, 122 | { 123 | input: "frd.json", 124 | upProfile: 172472, 125 | downProfile: 172471, 126 | }, 127 | { 128 | input: "msh.json", 129 | upProfile: 12500, 130 | downProfile: 12499, 131 | }, 132 | { 133 | input: "mshm.json", 134 | upProfile: 12428, 135 | downProfile: 12427, 136 | }, 137 | } 138 | 139 | for _, testData := range testTable { 140 | dat, err := ioutil.ReadFile(fmt.Sprintf("test_state/%s", testData.input)) 141 | check(err) 142 | modem := Modem{ 143 | Stats: dat, 144 | } 145 | 146 | downProfile, upProfile := modem.activeConfigs() 147 | assert.EqualValues(t, testData.upProfile, downProfile, fmt.Sprintf("%s up profile mismatch", testData.input)) 148 | assert.EqualValues(t, testData.downProfile, upProfile, fmt.Sprintf("%s down profile mismatch", testData.input)) 149 | } 150 | } 151 | 152 | func Test_readMIBInt(t *testing.T) { 153 | type testValues struct { 154 | mib string 155 | finalInt int 156 | expected int 157 | } 158 | type test struct { 159 | input string 160 | tests []testValues 161 | } 162 | 163 | testTable := []test{ 164 | { 165 | input: "chm.json", 166 | tests: []testValues{ 167 | { 168 | mib: "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3", 169 | finalInt: 137534, 170 | expected: 3044, 171 | }, 172 | { 173 | mib: "1.3.6.1.4.1.4491.2.1.20.1.2.1.2", 174 | finalInt: 4, 175 | expected: 36, 176 | }, 177 | { 178 | mib: "1337", 179 | finalInt: 1234, 180 | expected: -1, // Intentionally invalid 181 | }, 182 | }, 183 | }, 184 | { 185 | input: "msh.json", 186 | tests: []testValues{ 187 | { 188 | mib: "1.3.6.1.4.1.4491.2.1.20.1.2.1.2", 189 | finalInt: 4, 190 | expected: 5, 191 | }, 192 | }, 193 | }, 194 | } 195 | 196 | for _, testData := range testTable { 197 | dat, err := ioutil.ReadFile(fmt.Sprintf("test_state/%s", testData.input)) 198 | check(err) 199 | modem := Modem{ 200 | Stats: dat, 201 | } 202 | dataJSON := modem.dataAsJSON() 203 | 204 | for _, testCase := range testData.tests { 205 | MibValue := modem.readMIBInt(dataJSON, testCase.mib, testCase.finalInt) 206 | assert.EqualValues(t, testCase.expected, MibValue) 207 | } 208 | 209 | } 210 | } 211 | 212 | func Test_dataAsJSON(t *testing.T) { 213 | testTable := []string{ 214 | "chm.json", 215 | "chmb.json", 216 | "chmi.json", 217 | "eni.json", 218 | "frd.json", 219 | "msh.json", 220 | "mshm.json", 221 | } 222 | mibRegex := "^([0-2])((.0)|(.[1-9][0-9]*))*$" 223 | re := regexp.MustCompile(mibRegex) 224 | 225 | for _, testData := range testTable { 226 | dat, err := ioutil.ReadFile(fmt.Sprintf("test_state/%s", testData)) 227 | check(err) 228 | modem := Modem{ 229 | Stats: dat, 230 | } 231 | dataJSON := modem.dataAsJSON() 232 | 233 | for key := range dataJSON { 234 | assert.True(t, re.Match([]byte(key))) 235 | } 236 | } 237 | } 238 | 239 | func Test_ParseStats(t *testing.T) { 240 | testTable := []string{ 241 | "chm.json", 242 | "chmb.json", 243 | "chmi.json", 244 | "eni.json", 245 | "frd.json", 246 | "msh.json", 247 | "mshm.json", 248 | } 249 | 250 | for _, testData := range testTable { 251 | dat, err := ioutil.ReadFile(fmt.Sprintf("test_state/%s", testData)) 252 | check(err) 253 | modem := Modem{ 254 | Stats: dat, 255 | } 256 | 257 | parsed, err := modem.ParseStats() 258 | assert.Nil(t, err) 259 | assert.Equal(t, "DOCSIS", parsed.ModemType) 260 | assert.Zero(t, parsed.FetchTime) 261 | 262 | assert.Greater(t, len(parsed.DownChannels), 0) 263 | for _, downChannel := range parsed.DownChannels { 264 | validateDownChannel(t, downChannel) 265 | } 266 | 267 | assert.Greater(t, len(parsed.UpChannels), 0) 268 | for _, upChannel := range parsed.UpChannels { 269 | validateUpChannel(t, upChannel) 270 | } 271 | 272 | assert.Equal(t, len(parsed.Configs), 2) 273 | if parsed.Configs[0].Config == "upstream" { 274 | assert.Equal(t, "upstream", parsed.Configs[0].Config) 275 | assert.Equal(t, "downstream", parsed.Configs[1].Config) 276 | } else { 277 | assert.Equal(t, "downstream", parsed.Configs[0].Config) 278 | assert.Equal(t, "upstream", parsed.Configs[1].Config) 279 | } 280 | assert.Greater(t, parsed.Configs[0].Maxrate, 0) 281 | assert.Greater(t, parsed.Configs[1].Maxrate, 0) 282 | assert.Greater(t, parsed.Configs[0].Maxburst, 0) 283 | assert.Greater(t, parsed.Configs[1].Maxburst, 0) 284 | } 285 | 286 | } 287 | 288 | func validateDownChannel(t *testing.T, channel utils.ModemChannel) { 289 | assert.Greater(t, channel.ChannelID, 0) 290 | assert.Greater(t, channel.Channel, 0) 291 | 292 | assert.Greater(t, channel.Frequency, 108000000) // DOCSIS 3.0 108Mhz to 1Ghz 293 | assert.Less(t, channel.Frequency, 1000000000) 294 | 295 | assert.Greater(t, channel.Snr, 30) // DOCSIS 3.0 spec has 30dB minimum 296 | 297 | assert.Greater(t, channel.Power, -150) // DOCSIS 3.0 spec allows +/- 15dBmV 298 | assert.Less(t, channel.Power, 150) 299 | 300 | assert.GreaterOrEqual(t, channel.Prerserr, 0) 301 | assert.GreaterOrEqual(t, channel.Postrserr, 0) 302 | 303 | assert.Equal(t, "QAM256", channel.Modulation) 304 | assert.Equal(t, "SC-QAM", channel.Scheme) 305 | 306 | assert.Zero(t, channel.Noise) 307 | assert.Zero(t, channel.Attenuation) 308 | } 309 | 310 | func validateUpChannel(t *testing.T, channel utils.ModemChannel) { 311 | assert.Greater(t, channel.ChannelID, 0) 312 | assert.Greater(t, channel.Channel, 0) 313 | 314 | assert.Greater(t, channel.Frequency, 5000000) // DOCSIS 3.0 5Mhz to 85Mhz 315 | assert.Less(t, channel.Frequency, 85000000) 316 | 317 | assert.NotZero(t, channel.Power) 318 | 319 | assert.Equal(t, channel.Prerserr, 0) 320 | assert.Equal(t, channel.Postrserr, 0) 321 | 322 | assert.Equal(t, "", channel.Modulation) 323 | assert.Equal(t, "", channel.Scheme) 324 | 325 | assert.Zero(t, channel.Noise) 326 | assert.Zero(t, channel.Attenuation) 327 | } 328 | 329 | func Test_FailedHTTPCall(t *testing.T) { 330 | modem := Modem{ 331 | IPAddress: "127.0.0.1", 332 | } 333 | 334 | stats, err := modem.ParseStats() 335 | assert.NotNil(t, err) 336 | assert.Equal(t, stats, utils.ModemStats{}) 337 | 338 | modem = Modem{ 339 | IPAddress: "127.0.0.257", 340 | } 341 | 342 | stats, err = modem.ParseStats() 343 | assert.NotNil(t, err) 344 | assert.Equal(t, stats, utils.ModemStats{}) 345 | } 346 | -------------------------------------------------------------------------------- /modems/superhub3/test_state/README.md: -------------------------------------------------------------------------------- 1 | # Superhub 3 Test State 2 | 3 | These files come from real `/getRouterStatus` calls to the Superhub 3. 4 | 5 | To anonymise the data the following fields have been removed from the files: 6 | 7 | * `1.3.6.1.2.1.69.1.5.8.1.*` - Log entries 8 | * `1.3.6.1.4.1.4115.1.20.*` - IP addressing 9 | * `1.3.6.1.4.1.4115.1.3.4.1.4.3.2.0` - Gateway 10 | 11 | `eni.json` comes from a Ziggo Connectbox. 12 | All other `json` statistics come from UK Virgin Media Superhub 3s. 13 | -------------------------------------------------------------------------------- /modems/superhub3/test_state/chm.json: -------------------------------------------------------------------------------- 1 | { 2 | "1.3.6.1.4.1.4115.1.3.4.1.5.9.0": "10", 3 | "1.3.6.1.4.1.4115.1.3.3.1.1.1.3.1.0": "1", 4 | "1.3.6.1.4.1.4491.2.1.14.1.5.4.0": "5", 5 | "1.3.6.1.2.1.10.127.1.1.5.0": "4", 6 | "1.3.6.1.2.1.126.1.1.1.1.1.2": "1", 7 | "1.3.6.1.2.1.69.1.4.5.0": "cmreg-vmdg505-bbt060+voc-b.cm", 8 | "1.3.6.1.2.1.10.127.1.1.4.1.3.1": "251", 9 | "1.3.6.1.2.1.10.127.1.1.4.1.4.1": "0", 10 | "1.3.6.1.2.1.10.127.1.1.4.1.5.1": "403", 11 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.1": "403", 12 | "1.3.6.1.2.1.10.127.1.1.4.1.3.2": "310", 13 | "1.3.6.1.2.1.10.127.1.1.4.1.4.2": "0", 14 | "1.3.6.1.2.1.10.127.1.1.4.1.5.2": "409", 15 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.2": "409", 16 | "1.3.6.1.2.1.10.127.1.1.4.1.3.3": "620", 17 | "1.3.6.1.2.1.10.127.1.1.4.1.4.3": "0", 18 | "1.3.6.1.2.1.10.127.1.1.4.1.5.3": "403", 19 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.3": "403", 20 | "1.3.6.1.2.1.10.127.1.1.4.1.3.4": "1056", 21 | "1.3.6.1.2.1.10.127.1.1.4.1.4.4": "0", 22 | "1.3.6.1.2.1.10.127.1.1.4.1.5.4": "403", 23 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.4": "403", 24 | "1.3.6.1.2.1.10.127.1.1.4.1.3.5": "1136", 25 | "1.3.6.1.2.1.10.127.1.1.4.1.4.5": "0", 26 | "1.3.6.1.2.1.10.127.1.1.4.1.5.5": "409", 27 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.5": "409", 28 | "1.3.6.1.2.1.10.127.1.1.4.1.3.6": "331", 29 | "1.3.6.1.2.1.10.127.1.1.4.1.4.6": "0", 30 | "1.3.6.1.2.1.10.127.1.1.4.1.5.6": "403", 31 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.6": "403", 32 | "1.3.6.1.2.1.10.127.1.1.4.1.3.7": "359", 33 | "1.3.6.1.2.1.10.127.1.1.4.1.4.7": "0", 34 | "1.3.6.1.2.1.10.127.1.1.4.1.5.7": "409", 35 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.7": "409", 36 | "1.3.6.1.2.1.10.127.1.1.4.1.3.8": "711", 37 | "1.3.6.1.2.1.10.127.1.1.4.1.4.8": "0", 38 | "1.3.6.1.2.1.10.127.1.1.4.1.5.8": "403", 39 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.8": "403", 40 | "1.3.6.1.2.1.10.127.1.1.4.1.3.9": "601", 41 | "1.3.6.1.2.1.10.127.1.1.4.1.4.9": "0", 42 | "1.3.6.1.2.1.10.127.1.1.4.1.5.9": "409", 43 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.9": "409", 44 | "1.3.6.1.2.1.10.127.1.1.4.1.3.10": "610", 45 | "1.3.6.1.2.1.10.127.1.1.4.1.4.10": "0", 46 | "1.3.6.1.2.1.10.127.1.1.4.1.5.10": "403", 47 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.10": "403", 48 | "1.3.6.1.2.1.10.127.1.1.4.1.3.11": "578", 49 | "1.3.6.1.2.1.10.127.1.1.4.1.4.11": "0", 50 | "1.3.6.1.2.1.10.127.1.1.4.1.5.11": "409", 51 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.11": "409", 52 | "1.3.6.1.2.1.10.127.1.1.4.1.3.12": "505", 53 | "1.3.6.1.2.1.10.127.1.1.4.1.4.12": "0", 54 | "1.3.6.1.2.1.10.127.1.1.4.1.5.12": "409", 55 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.12": "409", 56 | "1.3.6.1.2.1.10.127.1.1.4.1.3.13": "574", 57 | "1.3.6.1.2.1.10.127.1.1.4.1.4.13": "0", 58 | "1.3.6.1.2.1.10.127.1.1.4.1.5.13": "403", 59 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.13": "403", 60 | "1.3.6.1.2.1.10.127.1.1.4.1.3.14": "784", 61 | "1.3.6.1.2.1.10.127.1.1.4.1.4.14": "0", 62 | "1.3.6.1.2.1.10.127.1.1.4.1.5.14": "403", 63 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.14": "403", 64 | "1.3.6.1.2.1.10.127.1.1.4.1.3.15": "1144", 65 | "1.3.6.1.2.1.10.127.1.1.4.1.4.15": "0", 66 | "1.3.6.1.2.1.10.127.1.1.4.1.5.15": "403", 67 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.15": "403", 68 | "1.3.6.1.2.1.10.127.1.1.4.1.3.16": "2655", 69 | "1.3.6.1.2.1.10.127.1.1.4.1.4.16": "0", 70 | "1.3.6.1.2.1.10.127.1.1.4.1.5.16": "409", 71 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.16": "409", 72 | "1.3.6.1.2.1.10.127.1.1.4.1.3.17": "1245", 73 | "1.3.6.1.2.1.10.127.1.1.4.1.4.17": "0", 74 | "1.3.6.1.2.1.10.127.1.1.4.1.5.17": "403", 75 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.17": "403", 76 | "1.3.6.1.2.1.10.127.1.1.4.1.3.18": "1351", 77 | "1.3.6.1.2.1.10.127.1.1.4.1.4.18": "0", 78 | "1.3.6.1.2.1.10.127.1.1.4.1.5.18": "409", 79 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.18": "409", 80 | "1.3.6.1.2.1.10.127.1.1.4.1.3.19": "1985", 81 | "1.3.6.1.2.1.10.127.1.1.4.1.4.19": "0", 82 | "1.3.6.1.2.1.10.127.1.1.4.1.5.19": "409", 83 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.19": "409", 84 | "1.3.6.1.2.1.10.127.1.1.4.1.3.20": "2154", 85 | "1.3.6.1.2.1.10.127.1.1.4.1.4.20": "0", 86 | "1.3.6.1.2.1.10.127.1.1.4.1.5.20": "403", 87 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.20": "403", 88 | "1.3.6.1.2.1.10.127.1.1.4.1.3.21": "1885", 89 | "1.3.6.1.2.1.10.127.1.1.4.1.4.21": "0", 90 | "1.3.6.1.2.1.10.127.1.1.4.1.5.21": "403", 91 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.21": "403", 92 | "1.3.6.1.2.1.10.127.1.1.4.1.3.22": "1714", 93 | "1.3.6.1.2.1.10.127.1.1.4.1.4.22": "0", 94 | "1.3.6.1.2.1.10.127.1.1.4.1.5.22": "409", 95 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.22": "409", 96 | "1.3.6.1.2.1.10.127.1.1.4.1.3.23": "1431", 97 | "1.3.6.1.2.1.10.127.1.1.4.1.4.23": "0", 98 | "1.3.6.1.2.1.10.127.1.1.4.1.5.23": "409", 99 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.23": "409", 100 | "1.3.6.1.2.1.10.127.1.1.4.1.3.24": "1399", 101 | "1.3.6.1.2.1.10.127.1.1.4.1.4.24": "0", 102 | "1.3.6.1.2.1.10.127.1.1.4.1.5.24": "409", 103 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.24": "409", 104 | "1.3.6.1.2.1.10.127.1.1.1.1.1.1": "1", 105 | "1.3.6.1.2.1.10.127.1.1.1.1.2.1": "139000000", 106 | "1.3.6.1.2.1.10.127.1.1.1.1.4.1": "4", 107 | "1.3.6.1.2.1.10.127.1.1.1.1.6.1": "53", 108 | "1.3.6.1.2.1.10.127.1.1.1.1.1.2": "2", 109 | "1.3.6.1.2.1.10.127.1.1.1.1.2.2": "147000000", 110 | "1.3.6.1.2.1.10.127.1.1.1.1.4.2": "4", 111 | "1.3.6.1.2.1.10.127.1.1.1.1.6.2": "50", 112 | "1.3.6.1.2.1.10.127.1.1.1.1.1.3": "3", 113 | "1.3.6.1.2.1.10.127.1.1.1.1.2.3": "155000000", 114 | "1.3.6.1.2.1.10.127.1.1.1.1.4.3": "4", 115 | "1.3.6.1.2.1.10.127.1.1.1.1.6.3": "49", 116 | "1.3.6.1.2.1.10.127.1.1.1.1.1.4": "4", 117 | "1.3.6.1.2.1.10.127.1.1.1.1.2.4": "163000000", 118 | "1.3.6.1.2.1.10.127.1.1.1.1.4.4": "4", 119 | "1.3.6.1.2.1.10.127.1.1.1.1.6.4": "45", 120 | "1.3.6.1.2.1.10.127.1.1.1.1.1.5": "5", 121 | "1.3.6.1.2.1.10.127.1.1.1.1.2.5": "171000000", 122 | "1.3.6.1.2.1.10.127.1.1.1.1.4.5": "4", 123 | "1.3.6.1.2.1.10.127.1.1.1.1.6.5": "45", 124 | "1.3.6.1.2.1.10.127.1.1.1.1.1.6": "6", 125 | "1.3.6.1.2.1.10.127.1.1.1.1.2.6": "179000000", 126 | "1.3.6.1.2.1.10.127.1.1.1.1.4.6": "4", 127 | "1.3.6.1.2.1.10.127.1.1.1.1.6.6": "43", 128 | "1.3.6.1.2.1.10.127.1.1.1.1.1.7": "7", 129 | "1.3.6.1.2.1.10.127.1.1.1.1.2.7": "187000000", 130 | "1.3.6.1.2.1.10.127.1.1.1.1.4.7": "4", 131 | "1.3.6.1.2.1.10.127.1.1.1.1.6.7": "43", 132 | "1.3.6.1.2.1.10.127.1.1.1.1.1.8": "8", 133 | "1.3.6.1.2.1.10.127.1.1.1.1.2.8": "195000000", 134 | "1.3.6.1.2.1.10.127.1.1.1.1.4.8": "4", 135 | "1.3.6.1.2.1.10.127.1.1.1.1.6.8": "41", 136 | "1.3.6.1.2.1.10.127.1.1.1.1.1.9": "9", 137 | "1.3.6.1.2.1.10.127.1.1.1.1.2.9": "203000000", 138 | "1.3.6.1.2.1.10.127.1.1.1.1.4.9": "4", 139 | "1.3.6.1.2.1.10.127.1.1.1.1.6.9": "40", 140 | "1.3.6.1.2.1.10.127.1.1.1.1.1.10": "10", 141 | "1.3.6.1.2.1.10.127.1.1.1.1.2.10": "211000000", 142 | "1.3.6.1.2.1.10.127.1.1.1.1.4.10": "4", 143 | "1.3.6.1.2.1.10.127.1.1.1.1.6.10": "41", 144 | "1.3.6.1.2.1.10.127.1.1.1.1.1.11": "11", 145 | "1.3.6.1.2.1.10.127.1.1.1.1.2.11": "219000000", 146 | "1.3.6.1.2.1.10.127.1.1.1.1.4.11": "4", 147 | "1.3.6.1.2.1.10.127.1.1.1.1.6.11": "45", 148 | "1.3.6.1.2.1.10.127.1.1.1.1.1.12": "12", 149 | "1.3.6.1.2.1.10.127.1.1.1.1.2.12": "227000000", 150 | "1.3.6.1.2.1.10.127.1.1.1.1.4.12": "4", 151 | "1.3.6.1.2.1.10.127.1.1.1.1.6.12": "48", 152 | "1.3.6.1.2.1.10.127.1.1.1.1.1.13": "13", 153 | "1.3.6.1.2.1.10.127.1.1.1.1.2.13": "235000000", 154 | "1.3.6.1.2.1.10.127.1.1.1.1.4.13": "4", 155 | "1.3.6.1.2.1.10.127.1.1.1.1.6.13": "46", 156 | "1.3.6.1.2.1.10.127.1.1.1.1.1.14": "14", 157 | "1.3.6.1.2.1.10.127.1.1.1.1.2.14": "243000000", 158 | "1.3.6.1.2.1.10.127.1.1.1.1.4.14": "4", 159 | "1.3.6.1.2.1.10.127.1.1.1.1.6.14": "43", 160 | "1.3.6.1.2.1.10.127.1.1.1.1.1.15": "15", 161 | "1.3.6.1.2.1.10.127.1.1.1.1.2.15": "251000000", 162 | "1.3.6.1.2.1.10.127.1.1.1.1.4.15": "4", 163 | "1.3.6.1.2.1.10.127.1.1.1.1.6.15": "40", 164 | "1.3.6.1.2.1.10.127.1.1.1.1.1.16": "16", 165 | "1.3.6.1.2.1.10.127.1.1.1.1.2.16": "259000000", 166 | "1.3.6.1.2.1.10.127.1.1.1.1.4.16": "4", 167 | "1.3.6.1.2.1.10.127.1.1.1.1.6.16": "37", 168 | "1.3.6.1.2.1.10.127.1.1.1.1.1.17": "17", 169 | "1.3.6.1.2.1.10.127.1.1.1.1.2.17": "267000000", 170 | "1.3.6.1.2.1.10.127.1.1.1.1.4.17": "4", 171 | "1.3.6.1.2.1.10.127.1.1.1.1.6.17": "37", 172 | "1.3.6.1.2.1.10.127.1.1.1.1.1.18": "18", 173 | "1.3.6.1.2.1.10.127.1.1.1.1.2.18": "275000000", 174 | "1.3.6.1.2.1.10.127.1.1.1.1.4.18": "4", 175 | "1.3.6.1.2.1.10.127.1.1.1.1.6.18": "35", 176 | "1.3.6.1.2.1.10.127.1.1.1.1.1.19": "19", 177 | "1.3.6.1.2.1.10.127.1.1.1.1.2.19": "283000000", 178 | "1.3.6.1.2.1.10.127.1.1.1.1.4.19": "4", 179 | "1.3.6.1.2.1.10.127.1.1.1.1.6.19": "32", 180 | "1.3.6.1.2.1.10.127.1.1.1.1.1.20": "20", 181 | "1.3.6.1.2.1.10.127.1.1.1.1.2.20": "291000000", 182 | "1.3.6.1.2.1.10.127.1.1.1.1.4.20": "4", 183 | "1.3.6.1.2.1.10.127.1.1.1.1.6.20": "30", 184 | "1.3.6.1.2.1.10.127.1.1.1.1.1.21": "21", 185 | "1.3.6.1.2.1.10.127.1.1.1.1.2.21": "299000000", 186 | "1.3.6.1.2.1.10.127.1.1.1.1.4.21": "4", 187 | "1.3.6.1.2.1.10.127.1.1.1.1.6.21": "32", 188 | "1.3.6.1.2.1.10.127.1.1.1.1.1.22": "22", 189 | "1.3.6.1.2.1.10.127.1.1.1.1.2.22": "307000000", 190 | "1.3.6.1.2.1.10.127.1.1.1.1.4.22": "4", 191 | "1.3.6.1.2.1.10.127.1.1.1.1.6.22": "34", 192 | "1.3.6.1.2.1.10.127.1.1.1.1.1.23": "23", 193 | "1.3.6.1.2.1.10.127.1.1.1.1.2.23": "315000000", 194 | "1.3.6.1.2.1.10.127.1.1.1.1.4.23": "4", 195 | "1.3.6.1.2.1.10.127.1.1.1.1.6.23": "37", 196 | "1.3.6.1.2.1.10.127.1.1.1.1.1.24": "24", 197 | "1.3.6.1.2.1.10.127.1.1.1.1.2.24": "323000000", 198 | "1.3.6.1.2.1.10.127.1.1.1.1.4.24": "4", 199 | "1.3.6.1.2.1.10.127.1.1.1.1.6.24": "39", 200 | "1.3.6.1.2.1.10.127.1.1.2.1.1.1": "2", 201 | "1.3.6.1.2.1.10.127.1.1.2.1.2.1": "53700085", 202 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.1": "358", 203 | "1.3.6.1.2.1.10.127.1.1.2.1.15.1": "2", 204 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.1": "5120", 205 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.1": "5", 206 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.1": "47", 207 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.1": "0", 208 | "1.3.6.1.2.1.10.127.1.1.2.1.1.2": "4", 209 | "1.3.6.1.2.1.10.127.1.1.2.1.2.2": "39400043", 210 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.2": "355", 211 | "1.3.6.1.2.1.10.127.1.1.2.1.15.2": "2", 212 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.2": "5120", 213 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.2": "5", 214 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.2": "46", 215 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.2": "0", 216 | "1.3.6.1.2.1.10.127.1.1.2.1.1.3": "1", 217 | "1.3.6.1.2.1.10.127.1.1.2.1.2.3": "60300033", 218 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.3": "360", 219 | "1.3.6.1.2.1.10.127.1.1.2.1.15.3": "2", 220 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.3": "5120", 221 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.3": "5", 222 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.3": "41", 223 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.3": "0", 224 | "1.3.6.1.2.1.10.127.1.1.2.1.1.4": "3", 225 | "1.3.6.1.2.1.10.127.1.1.2.1.2.4": "46200096", 226 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.4": "355", 227 | "1.3.6.1.2.1.10.127.1.1.2.1.15.4": "2", 228 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.4": "5120", 229 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.4": "5", 230 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.4": "36", 231 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.4": "0", 232 | "1.3.6.1.4.1.4115.1.3.4.1.1.12.0": "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,2,4,1,3", 233 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.137483": "22000061", 234 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.137483": "42600", 235 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.137483": "0", 236 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.137483": "42600", 237 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.137483": "2", 238 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.137484": "230000061", 239 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.137484": "42600", 240 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.137484": "0", 241 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.137484": "0", 242 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.137484": "1", 243 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.137531": "5250065", 244 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.137531": "16320", 245 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.137531": "0", 246 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.137531": "16320", 247 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.137531": "2", 248 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.137532": "128000", 249 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.137532": "3044", 250 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.137532": "0", 251 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.137532": "1522", 252 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.137532": "2", 253 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.137533": "55000065", 254 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.137533": "10000", 255 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.137533": "0", 256 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.137533": "0", 257 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.137533": "1", 258 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.137534": "128000", 259 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.137534": "3044", 260 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.137534": "0", 261 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.137534": "0", 262 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.137534": "1", 263 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.137483": "22000061", 264 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.137483": "42600", 265 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.137483": "0", 266 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.137483": "42600", 267 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.137483": "2", 268 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.137484": "230000061", 269 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.137484": "42600", 270 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.137484": "0", 271 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.137484": "0", 272 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.137484": "1", 273 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.137531": "5250065", 274 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.137531": "16320", 275 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.137531": "0", 276 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.137531": "16320", 277 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.137531": "2", 278 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.137532": "128000", 279 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.137532": "3044", 280 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.137532": "0", 281 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.137532": "1522", 282 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.137532": "2", 283 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.137533": "55000065", 284 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.137533": "10000", 285 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.137533": "0", 286 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.137533": "0", 287 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.137533": "1", 288 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.137534": "128000", 289 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.137534": "3044", 290 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.137534": "0", 291 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.137534": "0", 292 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.137534": "1", 293 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.137483": "22000061", 294 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.137483": "42600", 295 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.137483": "0", 296 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.137483": "42600", 297 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.137483": "2", 298 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.137484": "230000061", 299 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.137484": "42600", 300 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.137484": "0", 301 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.137484": "0", 302 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.137484": "1", 303 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.137531": "5250065", 304 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.137531": "16320", 305 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.137531": "0", 306 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.137531": "16320", 307 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.137531": "2", 308 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.137532": "128000", 309 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.137532": "3044", 310 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.137532": "0", 311 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.137532": "1522", 312 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.137532": "2", 313 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.137533": "55000065", 314 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.137533": "10000", 315 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.137533": "0", 316 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.137533": "0", 317 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.137533": "1", 318 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.137534": "128000", 319 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.137534": "3044", 320 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.137534": "0", 321 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.137534": "0", 322 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.137534": "1", 323 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.1.137483": "2", 324 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.1.137483": "1", 325 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.2.137484": "1", 326 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.2.137484": "1", 327 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.3.137531": "2", 328 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.3.137531": "0", 329 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.4.137532": "2", 330 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.4.137532": "0", 331 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.5.137533": "1", 332 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.5.137533": "0", 333 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.6.137534": "1", 334 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.6.137534": "0", 335 | "1.3.6.1.4.1.4115.1.3.3.1.1.1.3.2.0": "1", 336 | "1": "Finish" 337 | } -------------------------------------------------------------------------------- /modems/superhub3/test_state/chmb.json: -------------------------------------------------------------------------------- 1 | { 2 | "1.3.6.1.4.1.4115.1.3.4.1.5.9.0": "6", 3 | "1.3.6.1.4.1.4115.1.3.3.1.1.1.3.1.0": "1", 4 | "1.3.6.1.4.1.4491.2.1.14.1.5.4.0": "1", 5 | "1.3.6.1.2.1.10.127.1.1.5.0": "4", 6 | "1.3.6.1.2.1.126.1.1.1.1.1.2": "1", 7 | "1.3.6.1.2.1.69.1.4.5.0": ";fg87dsfd;kfoA,.iyewrkldJ", 8 | "1.3.6.1.2.1.10.127.1.1.4.1.3.1": "409", 9 | "1.3.6.1.2.1.10.127.1.1.4.1.4.1": "0", 10 | "1.3.6.1.2.1.10.127.1.1.4.1.5.1": "376", 11 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.1": "376", 12 | "1.3.6.1.2.1.10.127.1.1.4.1.3.2": "369", 13 | "1.3.6.1.2.1.10.127.1.1.4.1.4.2": "0", 14 | "1.3.6.1.2.1.10.127.1.1.4.1.5.2": "386", 15 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.2": "386", 16 | "1.3.6.1.2.1.10.127.1.1.4.1.3.3": "522", 17 | "1.3.6.1.2.1.10.127.1.1.4.1.4.3": "0", 18 | "1.3.6.1.2.1.10.127.1.1.4.1.5.3": "366", 19 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.3": "366", 20 | "1.3.6.1.2.1.10.127.1.1.4.1.3.4": "695", 21 | "1.3.6.1.2.1.10.127.1.1.4.1.4.4": "0", 22 | "1.3.6.1.2.1.10.127.1.1.4.1.5.4": "376", 23 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.4": "376", 24 | "1.3.6.1.2.1.10.127.1.1.4.1.3.5": "1378", 25 | "1.3.6.1.2.1.10.127.1.1.4.1.4.5": "0", 26 | "1.3.6.1.2.1.10.127.1.1.4.1.5.5": "376", 27 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.5": "376", 28 | "1.3.6.1.2.1.10.127.1.1.4.1.3.6": "677", 29 | "1.3.6.1.2.1.10.127.1.1.4.1.4.6": "0", 30 | "1.3.6.1.2.1.10.127.1.1.4.1.5.6": "376", 31 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.6": "376", 32 | "1.3.6.1.2.1.10.127.1.1.4.1.3.7": "517", 33 | "1.3.6.1.2.1.10.127.1.1.4.1.4.7": "0", 34 | "1.3.6.1.2.1.10.127.1.1.4.1.5.7": "376", 35 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.7": "376", 36 | "1.3.6.1.2.1.10.127.1.1.4.1.3.8": "435", 37 | "1.3.6.1.2.1.10.127.1.1.4.1.4.8": "0", 38 | "1.3.6.1.2.1.10.127.1.1.4.1.5.8": "376", 39 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.8": "376", 40 | "1.3.6.1.2.1.10.127.1.1.4.1.3.9": "379", 41 | "1.3.6.1.2.1.10.127.1.1.4.1.4.9": "0", 42 | "1.3.6.1.2.1.10.127.1.1.4.1.5.9": "376", 43 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.9": "376", 44 | "1.3.6.1.2.1.10.127.1.1.4.1.3.10": "476", 45 | "1.3.6.1.2.1.10.127.1.1.4.1.4.10": "0", 46 | "1.3.6.1.2.1.10.127.1.1.4.1.5.10": "376", 47 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.10": "376", 48 | "1.3.6.1.2.1.10.127.1.1.4.1.3.11": "456", 49 | "1.3.6.1.2.1.10.127.1.1.4.1.4.11": "0", 50 | "1.3.6.1.2.1.10.127.1.1.4.1.5.11": "373", 51 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.11": "373", 52 | "1.3.6.1.2.1.10.127.1.1.4.1.3.12": "362", 53 | "1.3.6.1.2.1.10.127.1.1.4.1.4.12": "0", 54 | "1.3.6.1.2.1.10.127.1.1.4.1.5.12": "376", 55 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.12": "376", 56 | "1.3.6.1.2.1.10.127.1.1.4.1.3.13": "377", 57 | "1.3.6.1.2.1.10.127.1.1.4.1.4.13": "0", 58 | "1.3.6.1.2.1.10.127.1.1.4.1.5.13": "373", 59 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.13": "373", 60 | "1.3.6.1.2.1.10.127.1.1.4.1.3.14": "389", 61 | "1.3.6.1.2.1.10.127.1.1.4.1.4.14": "0", 62 | "1.3.6.1.2.1.10.127.1.1.4.1.5.14": "376", 63 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.14": "376", 64 | "1.3.6.1.2.1.10.127.1.1.4.1.3.15": "482", 65 | "1.3.6.1.2.1.10.127.1.1.4.1.4.15": "0", 66 | "1.3.6.1.2.1.10.127.1.1.4.1.5.15": "376", 67 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.15": "376", 68 | "1.3.6.1.2.1.10.127.1.1.4.1.3.16": "535", 69 | "1.3.6.1.2.1.10.127.1.1.4.1.4.16": "0", 70 | "1.3.6.1.2.1.10.127.1.1.4.1.5.16": "386", 71 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.16": "386", 72 | "1.3.6.1.2.1.10.127.1.1.4.1.3.17": "564", 73 | "1.3.6.1.2.1.10.127.1.1.4.1.4.17": "0", 74 | "1.3.6.1.2.1.10.127.1.1.4.1.5.17": "386", 75 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.17": "386", 76 | "1.3.6.1.2.1.10.127.1.1.4.1.3.18": "585", 77 | "1.3.6.1.2.1.10.127.1.1.4.1.4.18": "0", 78 | "1.3.6.1.2.1.10.127.1.1.4.1.5.18": "386", 79 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.18": "386", 80 | "1.3.6.1.2.1.10.127.1.1.4.1.3.19": "731", 81 | "1.3.6.1.2.1.10.127.1.1.4.1.4.19": "0", 82 | "1.3.6.1.2.1.10.127.1.1.4.1.5.19": "386", 83 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.19": "386", 84 | "1.3.6.1.2.1.10.127.1.1.4.1.3.20": "782", 85 | "1.3.6.1.2.1.10.127.1.1.4.1.4.20": "0", 86 | "1.3.6.1.2.1.10.127.1.1.4.1.5.20": "386", 87 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.20": "386", 88 | "1.3.6.1.2.1.10.127.1.1.4.1.3.21": "848", 89 | "1.3.6.1.2.1.10.127.1.1.4.1.4.21": "0", 90 | "1.3.6.1.2.1.10.127.1.1.4.1.5.21": "376", 91 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.21": "376", 92 | "1.3.6.1.2.1.10.127.1.1.4.1.3.22": "762", 93 | "1.3.6.1.2.1.10.127.1.1.4.1.4.22": "0", 94 | "1.3.6.1.2.1.10.127.1.1.4.1.5.22": "386", 95 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.22": "386", 96 | "1.3.6.1.2.1.10.127.1.1.4.1.3.23": "904", 97 | "1.3.6.1.2.1.10.127.1.1.4.1.4.23": "0", 98 | "1.3.6.1.2.1.10.127.1.1.4.1.5.23": "376", 99 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.23": "376", 100 | "1.3.6.1.2.1.10.127.1.1.4.1.3.24": "1038", 101 | "1.3.6.1.2.1.10.127.1.1.4.1.4.24": "0", 102 | "1.3.6.1.2.1.10.127.1.1.4.1.5.24": "376", 103 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.24": "376", 104 | "1.3.6.1.2.1.10.127.1.1.1.1.1.1": "12", 105 | "1.3.6.1.2.1.10.127.1.1.1.1.2.1": "227000000", 106 | "1.3.6.1.2.1.10.127.1.1.1.1.4.1": "4", 107 | "1.3.6.1.2.1.10.127.1.1.1.1.6.1": "-2", 108 | "1.3.6.1.2.1.10.127.1.1.1.1.1.2": "1", 109 | "1.3.6.1.2.1.10.127.1.1.1.1.2.2": "139000000", 110 | "1.3.6.1.2.1.10.127.1.1.1.1.4.2": "4", 111 | "1.3.6.1.2.1.10.127.1.1.1.1.6.2": "5", 112 | "1.3.6.1.2.1.10.127.1.1.1.1.1.3": "2", 113 | "1.3.6.1.2.1.10.127.1.1.1.1.2.3": "147000000", 114 | "1.3.6.1.2.1.10.127.1.1.1.1.4.3": "4", 115 | "1.3.6.1.2.1.10.127.1.1.1.1.6.3": "-12", 116 | "1.3.6.1.2.1.10.127.1.1.1.1.1.4": "3", 117 | "1.3.6.1.2.1.10.127.1.1.1.1.2.4": "155000000", 118 | "1.3.6.1.2.1.10.127.1.1.1.1.4.4": "4", 119 | "1.3.6.1.2.1.10.127.1.1.1.1.6.4": "-2", 120 | "1.3.6.1.2.1.10.127.1.1.1.1.1.5": "4", 121 | "1.3.6.1.2.1.10.127.1.1.1.1.2.5": "163000000", 122 | "1.3.6.1.2.1.10.127.1.1.1.1.4.5": "4", 123 | "1.3.6.1.2.1.10.127.1.1.1.1.6.5": "0", 124 | "1.3.6.1.2.1.10.127.1.1.1.1.1.6": "5", 125 | "1.3.6.1.2.1.10.127.1.1.1.1.2.6": "171000000", 126 | "1.3.6.1.2.1.10.127.1.1.1.1.4.6": "4", 127 | "1.3.6.1.2.1.10.127.1.1.1.1.6.6": "0", 128 | "1.3.6.1.2.1.10.127.1.1.1.1.1.7": "6", 129 | "1.3.6.1.2.1.10.127.1.1.1.1.2.7": "179000000", 130 | "1.3.6.1.2.1.10.127.1.1.1.1.4.7": "4", 131 | "1.3.6.1.2.1.10.127.1.1.1.1.6.7": "0", 132 | "1.3.6.1.2.1.10.127.1.1.1.1.1.8": "7", 133 | "1.3.6.1.2.1.10.127.1.1.1.1.2.8": "187000000", 134 | "1.3.6.1.2.1.10.127.1.1.1.1.4.8": "4", 135 | "1.3.6.1.2.1.10.127.1.1.1.1.6.8": "0", 136 | "1.3.6.1.2.1.10.127.1.1.1.1.1.9": "8", 137 | "1.3.6.1.2.1.10.127.1.1.1.1.2.9": "195000000", 138 | "1.3.6.1.2.1.10.127.1.1.1.1.4.9": "4", 139 | "1.3.6.1.2.1.10.127.1.1.1.1.6.9": "0", 140 | "1.3.6.1.2.1.10.127.1.1.1.1.1.10": "9", 141 | "1.3.6.1.2.1.10.127.1.1.1.1.2.10": "203000000", 142 | "1.3.6.1.2.1.10.127.1.1.1.1.4.10": "4", 143 | "1.3.6.1.2.1.10.127.1.1.1.1.6.10": "-2", 144 | "1.3.6.1.2.1.10.127.1.1.1.1.1.11": "10", 145 | "1.3.6.1.2.1.10.127.1.1.1.1.2.11": "211000000", 146 | "1.3.6.1.2.1.10.127.1.1.1.1.4.11": "4", 147 | "1.3.6.1.2.1.10.127.1.1.1.1.6.11": "-2", 148 | "1.3.6.1.2.1.10.127.1.1.1.1.1.12": "11", 149 | "1.3.6.1.2.1.10.127.1.1.1.1.2.12": "219000000", 150 | "1.3.6.1.2.1.10.127.1.1.1.1.4.12": "4", 151 | "1.3.6.1.2.1.10.127.1.1.1.1.6.12": "-2", 152 | "1.3.6.1.2.1.10.127.1.1.1.1.1.13": "13", 153 | "1.3.6.1.2.1.10.127.1.1.1.1.2.13": "235000000", 154 | "1.3.6.1.2.1.10.127.1.1.1.1.4.13": "4", 155 | "1.3.6.1.2.1.10.127.1.1.1.1.6.13": "-2", 156 | "1.3.6.1.2.1.10.127.1.1.1.1.1.14": "14", 157 | "1.3.6.1.2.1.10.127.1.1.1.1.2.14": "243000000", 158 | "1.3.6.1.2.1.10.127.1.1.1.1.4.14": "4", 159 | "1.3.6.1.2.1.10.127.1.1.1.1.6.14": "-4", 160 | "1.3.6.1.2.1.10.127.1.1.1.1.1.15": "15", 161 | "1.3.6.1.2.1.10.127.1.1.1.1.2.15": "251000000", 162 | "1.3.6.1.2.1.10.127.1.1.1.1.4.15": "4", 163 | "1.3.6.1.2.1.10.127.1.1.1.1.6.15": "-4", 164 | "1.3.6.1.2.1.10.127.1.1.1.1.1.16": "16", 165 | "1.3.6.1.2.1.10.127.1.1.1.1.2.16": "259000000", 166 | "1.3.6.1.2.1.10.127.1.1.1.1.4.16": "4", 167 | "1.3.6.1.2.1.10.127.1.1.1.1.6.16": "-5", 168 | "1.3.6.1.2.1.10.127.1.1.1.1.1.17": "17", 169 | "1.3.6.1.2.1.10.127.1.1.1.1.2.17": "267000000", 170 | "1.3.6.1.2.1.10.127.1.1.1.1.4.17": "4", 171 | "1.3.6.1.2.1.10.127.1.1.1.1.6.17": "-5", 172 | "1.3.6.1.2.1.10.127.1.1.1.1.1.18": "18", 173 | "1.3.6.1.2.1.10.127.1.1.1.1.2.18": "275000000", 174 | "1.3.6.1.2.1.10.127.1.1.1.1.4.18": "4", 175 | "1.3.6.1.2.1.10.127.1.1.1.1.6.18": "-7", 176 | "1.3.6.1.2.1.10.127.1.1.1.1.1.19": "19", 177 | "1.3.6.1.2.1.10.127.1.1.1.1.2.19": "283000000", 178 | "1.3.6.1.2.1.10.127.1.1.1.1.4.19": "4", 179 | "1.3.6.1.2.1.10.127.1.1.1.1.6.19": "-7", 180 | "1.3.6.1.2.1.10.127.1.1.1.1.1.20": "20", 181 | "1.3.6.1.2.1.10.127.1.1.1.1.2.20": "291000000", 182 | "1.3.6.1.2.1.10.127.1.1.1.1.4.20": "4", 183 | "1.3.6.1.2.1.10.127.1.1.1.1.6.20": "-7", 184 | "1.3.6.1.2.1.10.127.1.1.1.1.1.21": "21", 185 | "1.3.6.1.2.1.10.127.1.1.1.1.2.21": "299000000", 186 | "1.3.6.1.2.1.10.127.1.1.1.1.4.21": "4", 187 | "1.3.6.1.2.1.10.127.1.1.1.1.6.21": "0", 188 | "1.3.6.1.2.1.10.127.1.1.1.1.1.22": "22", 189 | "1.3.6.1.2.1.10.127.1.1.1.1.2.22": "307000000", 190 | "1.3.6.1.2.1.10.127.1.1.1.1.4.22": "4", 191 | "1.3.6.1.2.1.10.127.1.1.1.1.6.22": "0", 192 | "1.3.6.1.2.1.10.127.1.1.1.1.1.23": "23", 193 | "1.3.6.1.2.1.10.127.1.1.1.1.2.23": "315000000", 194 | "1.3.6.1.2.1.10.127.1.1.1.1.4.23": "4", 195 | "1.3.6.1.2.1.10.127.1.1.1.1.6.23": "0", 196 | "1.3.6.1.2.1.10.127.1.1.1.1.1.24": "24", 197 | "1.3.6.1.2.1.10.127.1.1.1.1.2.24": "323000000", 198 | "1.3.6.1.2.1.10.127.1.1.1.1.4.24": "4", 199 | "1.3.6.1.2.1.10.127.1.1.1.1.6.24": "0", 200 | "1.3.6.1.2.1.10.127.1.1.2.1.1.1": "10", 201 | "1.3.6.1.2.1.10.127.1.1.2.1.2.1": "39399993", 202 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.1": "448", 203 | "1.3.6.1.2.1.10.127.1.1.2.1.15.1": "2", 204 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.1": "5120", 205 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.1": "5", 206 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.1": "0", 207 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.1": "0", 208 | "1.3.6.1.2.1.10.127.1.1.2.1.1.2": "12", 209 | "1.3.6.1.2.1.10.127.1.1.2.1.2.2": "25800000", 210 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.2": "458", 211 | "1.3.6.1.2.1.10.127.1.1.2.1.15.2": "2", 212 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.2": "5120", 213 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.2": "5", 214 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.2": "23", 215 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.2": "0", 216 | "1.3.6.1.2.1.10.127.1.1.2.1.1.3": "11", 217 | "1.3.6.1.2.1.10.127.1.1.2.1.2.3": "32600000", 218 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.3": "448", 219 | "1.3.6.1.2.1.10.127.1.1.2.1.15.3": "2", 220 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.3": "5120", 221 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.3": "5", 222 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.3": "0", 223 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.3": "0", 224 | "1.3.6.1.2.1.10.127.1.1.2.1.1.4": "9", 225 | "1.3.6.1.2.1.10.127.1.1.2.1.2.4": "46200000", 226 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.4": "448", 227 | "1.3.6.1.2.1.10.127.1.1.2.1.15.4": "2", 228 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.4": "5120", 229 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.4": "5", 230 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.4": "3", 231 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.4": "0", 232 | "1.3.6.1.4.1.4115.1.3.4.1.1.12.0": "12,1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19,20,21,22,23,24,10,12,11,9", 233 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.8804": "38500089", 234 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.8804": "42600", 235 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.8804": "0", 236 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.8804": "42600", 237 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.8804": "2", 238 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.8805": "402500089", 239 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.8805": "42600", 240 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.8805": "0", 241 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.8805": "0", 242 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.8805": "1", 243 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.20844": "5250065", 244 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.20844": "16320", 245 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.20844": "0", 246 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.20844": "16320", 247 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.20844": "2", 248 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.20845": "55000065", 249 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.20845": "10000", 250 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.20845": "0", 251 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.20845": "0", 252 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.20845": "1", 253 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.8804": "38500089", 254 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.8804": "42600", 255 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.8804": "0", 256 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.8804": "42600", 257 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.8804": "2", 258 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.8805": "402500089", 259 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.8805": "42600", 260 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.8805": "0", 261 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.8805": "0", 262 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.8805": "1", 263 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.20844": "5250065", 264 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.20844": "16320", 265 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.20844": "0", 266 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.20844": "16320", 267 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.20844": "2", 268 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.20845": "55000065", 269 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.20845": "10000", 270 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.20845": "0", 271 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.20845": "0", 272 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.20845": "1", 273 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.8804": "38500089", 274 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.8804": "42600", 275 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.8804": "0", 276 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.8804": "42600", 277 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.8804": "2", 278 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.8805": "402500089", 279 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.8805": "42600", 280 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.8805": "0", 281 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.8805": "0", 282 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.8805": "1", 283 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.20844": "5250065", 284 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.20844": "16320", 285 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.20844": "0", 286 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.20844": "16320", 287 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.20844": "2", 288 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.20845": "55000065", 289 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.20845": "10000", 290 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.20845": "0", 291 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.20845": "0", 292 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.20845": "1", 293 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.1.8804": "2", 294 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.1.8804": "1", 295 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.2.8805": "1", 296 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.2.8805": "1", 297 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.3.20844": "2", 298 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.3.20844": "0", 299 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.4.20845": "1", 300 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.4.20845": "0", 301 | "1.3.6.1.4.1.4115.1.3.3.1.1.1.3.2.0": "1", 302 | "1": "Finish" 303 | } -------------------------------------------------------------------------------- /modems/superhub3/test_state/chmi.json: -------------------------------------------------------------------------------- 1 | { 2 | "1.3.6.1.4.1.4115.1.3.4.1.5.9.0": "6", 3 | "1.3.6.1.4.1.4115.1.3.3.1.1.1.3.1.0": "1", 4 | "1.3.6.1.4.1.4491.2.1.14.1.5.4.0": "1", 5 | "1.3.6.1.2.1.10.127.1.1.5.0": "4", 6 | "1.3.6.1.2.1.126.1.1.1.1.1.2": "1", 7 | "1.3.6.1.2.1.69.1.4.5.0": "kldJKDHSUBsgvca69834ncxv9", 8 | "1.3.6.1.2.1.10.127.1.1.4.1.3.1": "15115", 9 | "1.3.6.1.2.1.10.127.1.1.4.1.4.1": "0", 10 | "1.3.6.1.2.1.10.127.1.1.4.1.5.1": "386", 11 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.1": "386", 12 | "1.3.6.1.2.1.10.127.1.1.4.1.3.2": "2006", 13 | "1.3.6.1.2.1.10.127.1.1.4.1.4.2": "0", 14 | "1.3.6.1.2.1.10.127.1.1.4.1.5.2": "373", 15 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.2": "373", 16 | "1.3.6.1.2.1.10.127.1.1.4.1.3.3": "1950", 17 | "1.3.6.1.2.1.10.127.1.1.4.1.4.3": "29", 18 | "1.3.6.1.2.1.10.127.1.1.4.1.5.3": "376", 19 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.3": "376", 20 | "1.3.6.1.2.1.10.127.1.1.4.1.3.4": "2029", 21 | "1.3.6.1.2.1.10.127.1.1.4.1.4.4": "0", 22 | "1.3.6.1.2.1.10.127.1.1.4.1.5.4": "376", 23 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.4": "376", 24 | "1.3.6.1.2.1.10.127.1.1.4.1.3.5": "2280", 25 | "1.3.6.1.2.1.10.127.1.1.4.1.4.5": "0", 26 | "1.3.6.1.2.1.10.127.1.1.4.1.5.5": "373", 27 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.5": "373", 28 | "1.3.6.1.2.1.10.127.1.1.4.1.3.6": "2464", 29 | "1.3.6.1.2.1.10.127.1.1.4.1.4.6": "0", 30 | "1.3.6.1.2.1.10.127.1.1.4.1.5.6": "376", 31 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.6": "376", 32 | "1.3.6.1.2.1.10.127.1.1.4.1.3.7": "2430", 33 | "1.3.6.1.2.1.10.127.1.1.4.1.4.7": "0", 34 | "1.3.6.1.2.1.10.127.1.1.4.1.5.7": "386", 35 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.7": "386", 36 | "1.3.6.1.2.1.10.127.1.1.4.1.3.8": "2700", 37 | "1.3.6.1.2.1.10.127.1.1.4.1.4.8": "0", 38 | "1.3.6.1.2.1.10.127.1.1.4.1.5.8": "376", 39 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.8": "376", 40 | "1.3.6.1.2.1.10.127.1.1.4.1.3.9": "2460", 41 | "1.3.6.1.2.1.10.127.1.1.4.1.4.9": "0", 42 | "1.3.6.1.2.1.10.127.1.1.4.1.5.9": "376", 43 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.9": "376", 44 | "1.3.6.1.2.1.10.127.1.1.4.1.3.10": "2969", 45 | "1.3.6.1.2.1.10.127.1.1.4.1.4.10": "0", 46 | "1.3.6.1.2.1.10.127.1.1.4.1.5.10": "376", 47 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.10": "376", 48 | "1.3.6.1.2.1.10.127.1.1.4.1.3.11": "3295", 49 | "1.3.6.1.2.1.10.127.1.1.4.1.4.11": "0", 50 | "1.3.6.1.2.1.10.127.1.1.4.1.5.11": "376", 51 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.11": "376", 52 | "1.3.6.1.2.1.10.127.1.1.4.1.3.12": "5481", 53 | "1.3.6.1.2.1.10.127.1.1.4.1.4.12": "1", 54 | "1.3.6.1.2.1.10.127.1.1.4.1.5.12": "373", 55 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.12": "373", 56 | "1.3.6.1.2.1.10.127.1.1.4.1.3.13": "6587", 57 | "1.3.6.1.2.1.10.127.1.1.4.1.4.13": "12", 58 | "1.3.6.1.2.1.10.127.1.1.4.1.5.13": "376", 59 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.13": "376", 60 | "1.3.6.1.2.1.10.127.1.1.4.1.3.14": "6943", 61 | "1.3.6.1.2.1.10.127.1.1.4.1.4.14": "13", 62 | "1.3.6.1.2.1.10.127.1.1.4.1.5.14": "373", 63 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.14": "373", 64 | "1.3.6.1.2.1.10.127.1.1.4.1.3.15": "8301", 65 | "1.3.6.1.2.1.10.127.1.1.4.1.4.15": "0", 66 | "1.3.6.1.2.1.10.127.1.1.4.1.5.15": "376", 67 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.15": "376", 68 | "1.3.6.1.2.1.10.127.1.1.4.1.3.16": "9517", 69 | "1.3.6.1.2.1.10.127.1.1.4.1.4.16": "0", 70 | "1.3.6.1.2.1.10.127.1.1.4.1.5.16": "373", 71 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.16": "373", 72 | "1.3.6.1.2.1.10.127.1.1.4.1.3.17": "9402", 73 | "1.3.6.1.2.1.10.127.1.1.4.1.4.17": "0", 74 | "1.3.6.1.2.1.10.127.1.1.4.1.5.17": "376", 75 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.17": "376", 76 | "1.3.6.1.2.1.10.127.1.1.4.1.3.18": "9664", 77 | "1.3.6.1.2.1.10.127.1.1.4.1.4.18": "0", 78 | "1.3.6.1.2.1.10.127.1.1.4.1.5.18": "376", 79 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.18": "376", 80 | "1.3.6.1.2.1.10.127.1.1.4.1.3.19": "13165", 81 | "1.3.6.1.2.1.10.127.1.1.4.1.4.19": "0", 82 | "1.3.6.1.2.1.10.127.1.1.4.1.5.19": "376", 83 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.19": "376", 84 | "1.3.6.1.2.1.10.127.1.1.4.1.3.20": "13670", 85 | "1.3.6.1.2.1.10.127.1.1.4.1.4.20": "0", 86 | "1.3.6.1.2.1.10.127.1.1.4.1.5.20": "376", 87 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.20": "376", 88 | "1.3.6.1.2.1.10.127.1.1.4.1.3.21": "14443", 89 | "1.3.6.1.2.1.10.127.1.1.4.1.4.21": "0", 90 | "1.3.6.1.2.1.10.127.1.1.4.1.5.21": "376", 91 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.21": "376", 92 | "1.3.6.1.2.1.10.127.1.1.4.1.3.22": "13466", 93 | "1.3.6.1.2.1.10.127.1.1.4.1.4.22": "13", 94 | "1.3.6.1.2.1.10.127.1.1.4.1.5.22": "389", 95 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.22": "389", 96 | "1.3.6.1.2.1.10.127.1.1.4.1.3.23": "14857", 97 | "1.3.6.1.2.1.10.127.1.1.4.1.4.23": "0", 98 | "1.3.6.1.2.1.10.127.1.1.4.1.5.23": "386", 99 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.23": "386", 100 | "1.3.6.1.2.1.10.127.1.1.4.1.3.24": "16065", 101 | "1.3.6.1.2.1.10.127.1.1.4.1.4.24": "0", 102 | "1.3.6.1.2.1.10.127.1.1.4.1.5.24": "386", 103 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.24": "386", 104 | "1.3.6.1.2.1.10.127.1.1.1.1.1.1": "37", 105 | "1.3.6.1.2.1.10.127.1.1.1.1.2.1": "475000000", 106 | "1.3.6.1.2.1.10.127.1.1.1.1.4.1": "4", 107 | "1.3.6.1.2.1.10.127.1.1.1.1.6.1": "0", 108 | "1.3.6.1.2.1.10.127.1.1.1.1.1.2": "15", 109 | "1.3.6.1.2.1.10.127.1.1.1.1.2.2": "251000000", 110 | "1.3.6.1.2.1.10.127.1.1.1.1.4.2": "4", 111 | "1.3.6.1.2.1.10.127.1.1.1.1.6.2": "-10", 112 | "1.3.6.1.2.1.10.127.1.1.1.1.1.3": "16", 113 | "1.3.6.1.2.1.10.127.1.1.1.1.2.3": "259000000", 114 | "1.3.6.1.2.1.10.127.1.1.1.1.4.3": "4", 115 | "1.3.6.1.2.1.10.127.1.1.1.1.6.3": "-12", 116 | "1.3.6.1.2.1.10.127.1.1.1.1.1.4": "17", 117 | "1.3.6.1.2.1.10.127.1.1.1.1.2.4": "267000000", 118 | "1.3.6.1.2.1.10.127.1.1.1.1.4.4": "4", 119 | "1.3.6.1.2.1.10.127.1.1.1.1.6.4": "-12", 120 | "1.3.6.1.2.1.10.127.1.1.1.1.1.5": "18", 121 | "1.3.6.1.2.1.10.127.1.1.1.1.2.5": "275000000", 122 | "1.3.6.1.2.1.10.127.1.1.1.1.4.5": "4", 123 | "1.3.6.1.2.1.10.127.1.1.1.1.6.5": "-15", 124 | "1.3.6.1.2.1.10.127.1.1.1.1.1.6": "19", 125 | "1.3.6.1.2.1.10.127.1.1.1.1.2.6": "283000000", 126 | "1.3.6.1.2.1.10.127.1.1.1.1.4.6": "4", 127 | "1.3.6.1.2.1.10.127.1.1.1.1.6.6": "-15", 128 | "1.3.6.1.2.1.10.127.1.1.1.1.1.7": "20", 129 | "1.3.6.1.2.1.10.127.1.1.1.1.2.7": "291000000", 130 | "1.3.6.1.2.1.10.127.1.1.1.1.4.7": "4", 131 | "1.3.6.1.2.1.10.127.1.1.1.1.6.7": "-14", 132 | "1.3.6.1.2.1.10.127.1.1.1.1.1.8": "21", 133 | "1.3.6.1.2.1.10.127.1.1.1.1.2.8": "299000000", 134 | "1.3.6.1.2.1.10.127.1.1.1.1.4.8": "4", 135 | "1.3.6.1.2.1.10.127.1.1.1.1.6.8": "-7", 136 | "1.3.6.1.2.1.10.127.1.1.1.1.1.9": "22", 137 | "1.3.6.1.2.1.10.127.1.1.1.1.2.9": "307000000", 138 | "1.3.6.1.2.1.10.127.1.1.1.1.4.9": "4", 139 | "1.3.6.1.2.1.10.127.1.1.1.1.6.9": "-5", 140 | "1.3.6.1.2.1.10.127.1.1.1.1.1.10": "23", 141 | "1.3.6.1.2.1.10.127.1.1.1.1.2.10": "315000000", 142 | "1.3.6.1.2.1.10.127.1.1.1.1.4.10": "4", 143 | "1.3.6.1.2.1.10.127.1.1.1.1.6.10": "-4", 144 | "1.3.6.1.2.1.10.127.1.1.1.1.1.11": "24", 145 | "1.3.6.1.2.1.10.127.1.1.1.1.2.11": "323000000", 146 | "1.3.6.1.2.1.10.127.1.1.1.1.4.11": "4", 147 | "1.3.6.1.2.1.10.127.1.1.1.1.6.11": "-4", 148 | "1.3.6.1.2.1.10.127.1.1.1.1.1.12": "25", 149 | "1.3.6.1.2.1.10.127.1.1.1.1.2.12": "371000000", 150 | "1.3.6.1.2.1.10.127.1.1.1.1.4.12": "4", 151 | "1.3.6.1.2.1.10.127.1.1.1.1.6.12": "-12", 152 | "1.3.6.1.2.1.10.127.1.1.1.1.1.13": "26", 153 | "1.3.6.1.2.1.10.127.1.1.1.1.2.13": "379000000", 154 | "1.3.6.1.2.1.10.127.1.1.1.1.4.13": "4", 155 | "1.3.6.1.2.1.10.127.1.1.1.1.6.13": "-15", 156 | "1.3.6.1.2.1.10.127.1.1.1.1.1.14": "27", 157 | "1.3.6.1.2.1.10.127.1.1.1.1.2.14": "387000000", 158 | "1.3.6.1.2.1.10.127.1.1.1.1.4.14": "4", 159 | "1.3.6.1.2.1.10.127.1.1.1.1.6.14": "-17", 160 | "1.3.6.1.2.1.10.127.1.1.1.1.1.15": "28", 161 | "1.3.6.1.2.1.10.127.1.1.1.1.2.15": "395000000", 162 | "1.3.6.1.2.1.10.127.1.1.1.1.4.15": "4", 163 | "1.3.6.1.2.1.10.127.1.1.1.1.6.15": "-19", 164 | "1.3.6.1.2.1.10.127.1.1.1.1.1.16": "29", 165 | "1.3.6.1.2.1.10.127.1.1.1.1.2.16": "411000000", 166 | "1.3.6.1.2.1.10.127.1.1.1.1.4.16": "4", 167 | "1.3.6.1.2.1.10.127.1.1.1.1.6.16": "-14", 168 | "1.3.6.1.2.1.10.127.1.1.1.1.1.17": "30", 169 | "1.3.6.1.2.1.10.127.1.1.1.1.2.17": "419000000", 170 | "1.3.6.1.2.1.10.127.1.1.1.1.4.17": "4", 171 | "1.3.6.1.2.1.10.127.1.1.1.1.6.17": "-14", 172 | "1.3.6.1.2.1.10.127.1.1.1.1.1.18": "31", 173 | "1.3.6.1.2.1.10.127.1.1.1.1.2.18": "427000000", 174 | "1.3.6.1.2.1.10.127.1.1.1.1.4.18": "4", 175 | "1.3.6.1.2.1.10.127.1.1.1.1.6.18": "-14", 176 | "1.3.6.1.2.1.10.127.1.1.1.1.1.19": "32", 177 | "1.3.6.1.2.1.10.127.1.1.1.1.2.19": "435000000", 178 | "1.3.6.1.2.1.10.127.1.1.1.1.4.19": "4", 179 | "1.3.6.1.2.1.10.127.1.1.1.1.6.19": "-17", 180 | "1.3.6.1.2.1.10.127.1.1.1.1.1.20": "33", 181 | "1.3.6.1.2.1.10.127.1.1.1.1.2.20": "443000000", 182 | "1.3.6.1.2.1.10.127.1.1.1.1.4.20": "4", 183 | "1.3.6.1.2.1.10.127.1.1.1.1.6.20": "-17", 184 | "1.3.6.1.2.1.10.127.1.1.1.1.1.21": "34", 185 | "1.3.6.1.2.1.10.127.1.1.1.1.2.21": "451000000", 186 | "1.3.6.1.2.1.10.127.1.1.1.1.4.21": "4", 187 | "1.3.6.1.2.1.10.127.1.1.1.1.6.21": "-14", 188 | "1.3.6.1.2.1.10.127.1.1.1.1.1.22": "35", 189 | "1.3.6.1.2.1.10.127.1.1.1.1.2.22": "459000000", 190 | "1.3.6.1.2.1.10.127.1.1.1.1.4.22": "4", 191 | "1.3.6.1.2.1.10.127.1.1.1.1.6.22": "-9", 192 | "1.3.6.1.2.1.10.127.1.1.1.1.1.23": "36", 193 | "1.3.6.1.2.1.10.127.1.1.1.1.2.23": "467000000", 194 | "1.3.6.1.2.1.10.127.1.1.1.1.4.23": "4", 195 | "1.3.6.1.2.1.10.127.1.1.1.1.6.23": "-5", 196 | "1.3.6.1.2.1.10.127.1.1.1.1.1.24": "38", 197 | "1.3.6.1.2.1.10.127.1.1.1.1.2.24": "483000000", 198 | "1.3.6.1.2.1.10.127.1.1.1.1.4.24": "4", 199 | "1.3.6.1.2.1.10.127.1.1.1.1.6.24": "5", 200 | "1.3.6.1.2.1.10.127.1.1.2.1.1.1": "11", 201 | "1.3.6.1.2.1.10.127.1.1.2.1.2.1": "32600000", 202 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.1": "490", 203 | "1.3.6.1.2.1.10.127.1.1.2.1.15.1": "2", 204 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.1": "5120", 205 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.1": "5", 206 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.1": "3", 207 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.1": "0", 208 | "1.3.6.1.2.1.10.127.1.1.2.1.1.2": "12", 209 | "1.3.6.1.2.1.10.127.1.1.2.1.2.2": "25800000", 210 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.2": "498", 211 | "1.3.6.1.2.1.10.127.1.1.2.1.15.2": "2", 212 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.2": "5120", 213 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.2": "5", 214 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.2": "11", 215 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.2": "0", 216 | "1.3.6.1.2.1.10.127.1.1.2.1.1.3": "10", 217 | "1.3.6.1.2.1.10.127.1.1.2.1.2.3": "39400000", 218 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.3": "495", 219 | "1.3.6.1.2.1.10.127.1.1.2.1.15.3": "2", 220 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.3": "5120", 221 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.3": "5", 222 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.3": "4", 223 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.3": "0", 224 | "1.3.6.1.2.1.10.127.1.1.2.1.1.4": "9", 225 | "1.3.6.1.2.1.10.127.1.1.2.1.2.4": "46200000", 226 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.4": "495", 227 | "1.3.6.1.2.1.10.127.1.1.2.1.15.4": "2", 228 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.4": "5120", 229 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.4": "5", 230 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.4": "3", 231 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.4": "0", 232 | "1.3.6.1.4.1.4115.1.3.4.1.1.12.0": "37,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,38,11,12,10,9", 233 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.4819": "5250065", 234 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.4819": "16320", 235 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.4819": "0", 236 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.4819": "16320", 237 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.4819": "2", 238 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.4820": "55000065", 239 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.4820": "10000", 240 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.4820": "0", 241 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.4820": "0", 242 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.4820": "1", 243 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.8804": "38500089", 244 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.8804": "42600", 245 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.8804": "0", 246 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.8804": "42600", 247 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.8804": "2", 248 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.8805": "402500089", 249 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.8805": "42600", 250 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.8805": "0", 251 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.8805": "0", 252 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.8805": "1", 253 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.4819": "5250065", 254 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.4819": "16320", 255 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.4819": "0", 256 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.4819": "16320", 257 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.4819": "2", 258 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.4820": "55000065", 259 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.4820": "10000", 260 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.4820": "0", 261 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.4820": "0", 262 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.4820": "1", 263 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.8804": "38500089", 264 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.8804": "42600", 265 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.8804": "0", 266 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.8804": "42600", 267 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.8804": "2", 268 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.8805": "402500089", 269 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.8805": "42600", 270 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.8805": "0", 271 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.8805": "0", 272 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.8805": "1", 273 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.4819": "5250065", 274 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.4819": "16320", 275 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.4819": "0", 276 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.4819": "16320", 277 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.4819": "2", 278 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.4820": "55000065", 279 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.4820": "10000", 280 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.4820": "0", 281 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.4820": "0", 282 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.4820": "1", 283 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.8804": "38500089", 284 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.8804": "42600", 285 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.8804": "0", 286 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.8804": "42600", 287 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.8804": "2", 288 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.8805": "402500089", 289 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.8805": "42600", 290 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.8805": "0", 291 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.8805": "0", 292 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.8805": "1", 293 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.1.4819": "2", 294 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.1.4819": "0", 295 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.2.4820": "1", 296 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.2.4820": "0", 297 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.3.8804": "2", 298 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.3.8804": "1", 299 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.4.8805": "1", 300 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.4.8805": "1", 301 | "1.3.6.1.4.1.4115.1.3.3.1.1.1.3.2.0": "1", 302 | "1": "Finish" 303 | } -------------------------------------------------------------------------------- /modems/superhub3/test_state/frd.json: -------------------------------------------------------------------------------- 1 | { 2 | "1.3.6.1.4.1.4115.1.3.4.1.5.9.0": "6", 3 | "1.3.6.1.4.1.4115.1.3.3.1.1.1.3.1.0": "1", 4 | "1.3.6.1.4.1.4491.2.1.14.1.5.4.0": "1", 5 | "1.3.6.1.2.1.10.127.1.1.5.0": "4", 6 | "1.3.6.1.2.1.126.1.1.1.1.1.2": "1", 7 | "1.3.6.1.2.1.69.1.4.5.0": "cmreg-vmdg505-bbt062-b.cm", 8 | "1.3.6.1.2.1.10.127.1.1.4.1.3.1": "39", 9 | "1.3.6.1.2.1.10.127.1.1.4.1.4.1": "0", 10 | "1.3.6.1.2.1.10.127.1.1.4.1.5.1": "389", 11 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.1": "389", 12 | "1.3.6.1.2.1.10.127.1.1.4.1.3.2": "31", 13 | "1.3.6.1.2.1.10.127.1.1.4.1.4.2": "0", 14 | "1.3.6.1.2.1.10.127.1.1.4.1.5.2": "389", 15 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.2": "389", 16 | "1.3.6.1.2.1.10.127.1.1.4.1.3.3": "14", 17 | "1.3.6.1.2.1.10.127.1.1.4.1.4.3": "0", 18 | "1.3.6.1.2.1.10.127.1.1.4.1.5.3": "386", 19 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.3": "386", 20 | "1.3.6.1.2.1.10.127.1.1.4.1.3.4": "12", 21 | "1.3.6.1.2.1.10.127.1.1.4.1.4.4": "0", 22 | "1.3.6.1.2.1.10.127.1.1.4.1.5.4": "386", 23 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.4": "386", 24 | "1.3.6.1.2.1.10.127.1.1.4.1.3.5": "30", 25 | "1.3.6.1.2.1.10.127.1.1.4.1.4.5": "0", 26 | "1.3.6.1.2.1.10.127.1.1.4.1.5.5": "389", 27 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.5": "389", 28 | "1.3.6.1.2.1.10.127.1.1.4.1.3.6": "26", 29 | "1.3.6.1.2.1.10.127.1.1.4.1.4.6": "0", 30 | "1.3.6.1.2.1.10.127.1.1.4.1.5.6": "386", 31 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.6": "386", 32 | "1.3.6.1.2.1.10.127.1.1.4.1.3.7": "21", 33 | "1.3.6.1.2.1.10.127.1.1.4.1.4.7": "0", 34 | "1.3.6.1.2.1.10.127.1.1.4.1.5.7": "386", 35 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.7": "386", 36 | "1.3.6.1.2.1.10.127.1.1.4.1.3.8": "28", 37 | "1.3.6.1.2.1.10.127.1.1.4.1.4.8": "0", 38 | "1.3.6.1.2.1.10.127.1.1.4.1.5.8": "389", 39 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.8": "389", 40 | "1.3.6.1.2.1.10.127.1.1.4.1.3.9": "25", 41 | "1.3.6.1.2.1.10.127.1.1.4.1.4.9": "0", 42 | "1.3.6.1.2.1.10.127.1.1.4.1.5.9": "386", 43 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.9": "386", 44 | "1.3.6.1.2.1.10.127.1.1.4.1.3.10": "28", 45 | "1.3.6.1.2.1.10.127.1.1.4.1.4.10": "0", 46 | "1.3.6.1.2.1.10.127.1.1.4.1.5.10": "386", 47 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.10": "386", 48 | "1.3.6.1.2.1.10.127.1.1.4.1.3.11": "37", 49 | "1.3.6.1.2.1.10.127.1.1.4.1.4.11": "0", 50 | "1.3.6.1.2.1.10.127.1.1.4.1.5.11": "386", 51 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.11": "386", 52 | "1.3.6.1.2.1.10.127.1.1.4.1.3.12": "44", 53 | "1.3.6.1.2.1.10.127.1.1.4.1.4.12": "0", 54 | "1.3.6.1.2.1.10.127.1.1.4.1.5.12": "389", 55 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.12": "389", 56 | "1.3.6.1.2.1.10.127.1.1.4.1.3.13": "67", 57 | "1.3.6.1.2.1.10.127.1.1.4.1.4.13": "0", 58 | "1.3.6.1.2.1.10.127.1.1.4.1.5.13": "386", 59 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.13": "386", 60 | "1.3.6.1.2.1.10.127.1.1.4.1.3.14": "56", 61 | "1.3.6.1.2.1.10.127.1.1.4.1.4.14": "0", 62 | "1.3.6.1.2.1.10.127.1.1.4.1.5.14": "386", 63 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.14": "386", 64 | "1.3.6.1.2.1.10.127.1.1.4.1.3.15": "70", 65 | "1.3.6.1.2.1.10.127.1.1.4.1.4.15": "0", 66 | "1.3.6.1.2.1.10.127.1.1.4.1.5.15": "386", 67 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.15": "386", 68 | "1.3.6.1.2.1.10.127.1.1.4.1.3.16": "116", 69 | "1.3.6.1.2.1.10.127.1.1.4.1.4.16": "0", 70 | "1.3.6.1.2.1.10.127.1.1.4.1.5.16": "389", 71 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.16": "389", 72 | "1.3.6.1.2.1.10.127.1.1.4.1.3.17": "84", 73 | "1.3.6.1.2.1.10.127.1.1.4.1.4.17": "0", 74 | "1.3.6.1.2.1.10.127.1.1.4.1.5.17": "389", 75 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.17": "389", 76 | "1.3.6.1.2.1.10.127.1.1.4.1.3.18": "57", 77 | "1.3.6.1.2.1.10.127.1.1.4.1.4.18": "0", 78 | "1.3.6.1.2.1.10.127.1.1.4.1.5.18": "389", 79 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.18": "389", 80 | "1.3.6.1.2.1.10.127.1.1.4.1.3.19": "21", 81 | "1.3.6.1.2.1.10.127.1.1.4.1.4.19": "0", 82 | "1.3.6.1.2.1.10.127.1.1.4.1.5.19": "389", 83 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.19": "389", 84 | "1.3.6.1.2.1.10.127.1.1.4.1.3.20": "21", 85 | "1.3.6.1.2.1.10.127.1.1.4.1.4.20": "0", 86 | "1.3.6.1.2.1.10.127.1.1.4.1.5.20": "386", 87 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.20": "386", 88 | "1.3.6.1.2.1.10.127.1.1.4.1.3.21": "63", 89 | "1.3.6.1.2.1.10.127.1.1.4.1.4.21": "0", 90 | "1.3.6.1.2.1.10.127.1.1.4.1.5.21": "389", 91 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.21": "389", 92 | "1.3.6.1.2.1.10.127.1.1.4.1.3.22": "37", 93 | "1.3.6.1.2.1.10.127.1.1.4.1.4.22": "0", 94 | "1.3.6.1.2.1.10.127.1.1.4.1.5.22": "389", 95 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.22": "389", 96 | "1.3.6.1.2.1.10.127.1.1.4.1.3.23": "43", 97 | "1.3.6.1.2.1.10.127.1.1.4.1.4.23": "0", 98 | "1.3.6.1.2.1.10.127.1.1.4.1.5.23": "389", 99 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.23": "389", 100 | "1.3.6.1.2.1.10.127.1.1.4.1.3.24": "41", 101 | "1.3.6.1.2.1.10.127.1.1.4.1.4.24": "0", 102 | "1.3.6.1.2.1.10.127.1.1.4.1.5.24": "389", 103 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.24": "389", 104 | "1.3.6.1.2.1.10.127.1.1.1.1.1.1": "30", 105 | "1.3.6.1.2.1.10.127.1.1.1.1.2.1": "402750000", 106 | "1.3.6.1.2.1.10.127.1.1.1.1.4.1": "4", 107 | "1.3.6.1.2.1.10.127.1.1.1.1.6.1": "-12", 108 | "1.3.6.1.2.1.10.127.1.1.1.1.1.2": "9", 109 | "1.3.6.1.2.1.10.127.1.1.1.1.2.2": "202750000", 110 | "1.3.6.1.2.1.10.127.1.1.1.1.4.2": "4", 111 | "1.3.6.1.2.1.10.127.1.1.1.1.6.2": "7", 112 | "1.3.6.1.2.1.10.127.1.1.1.1.1.3": "10", 113 | "1.3.6.1.2.1.10.127.1.1.1.1.2.3": "210750000", 114 | "1.3.6.1.2.1.10.127.1.1.1.1.4.3": "4", 115 | "1.3.6.1.2.1.10.127.1.1.1.1.6.3": "5", 116 | "1.3.6.1.2.1.10.127.1.1.1.1.1.4": "11", 117 | "1.3.6.1.2.1.10.127.1.1.1.1.2.4": "218750000", 118 | "1.3.6.1.2.1.10.127.1.1.1.1.4.4": "4", 119 | "1.3.6.1.2.1.10.127.1.1.1.1.6.4": "5", 120 | "1.3.6.1.2.1.10.127.1.1.1.1.1.5": "12", 121 | "1.3.6.1.2.1.10.127.1.1.1.1.2.5": "226750000", 122 | "1.3.6.1.2.1.10.127.1.1.1.1.4.5": "4", 123 | "1.3.6.1.2.1.10.127.1.1.1.1.6.5": "4", 124 | "1.3.6.1.2.1.10.127.1.1.1.1.1.6": "13", 125 | "1.3.6.1.2.1.10.127.1.1.1.1.2.6": "234750000", 126 | "1.3.6.1.2.1.10.127.1.1.1.1.4.6": "4", 127 | "1.3.6.1.2.1.10.127.1.1.1.1.6.6": "2", 128 | "1.3.6.1.2.1.10.127.1.1.1.1.1.7": "14", 129 | "1.3.6.1.2.1.10.127.1.1.1.1.2.7": "242750000", 130 | "1.3.6.1.2.1.10.127.1.1.1.1.4.7": "4", 131 | "1.3.6.1.2.1.10.127.1.1.1.1.6.7": "0", 132 | "1.3.6.1.2.1.10.127.1.1.1.1.1.8": "15", 133 | "1.3.6.1.2.1.10.127.1.1.1.1.2.8": "250750000", 134 | "1.3.6.1.2.1.10.127.1.1.1.1.4.8": "4", 135 | "1.3.6.1.2.1.10.127.1.1.1.1.6.8": "-2", 136 | "1.3.6.1.2.1.10.127.1.1.1.1.1.9": "16", 137 | "1.3.6.1.2.1.10.127.1.1.1.1.2.9": "258750000", 138 | "1.3.6.1.2.1.10.127.1.1.1.1.4.9": "4", 139 | "1.3.6.1.2.1.10.127.1.1.1.1.6.9": "-2", 140 | "1.3.6.1.2.1.10.127.1.1.1.1.1.10": "17", 141 | "1.3.6.1.2.1.10.127.1.1.1.1.2.10": "266750000", 142 | "1.3.6.1.2.1.10.127.1.1.1.1.4.10": "4", 143 | "1.3.6.1.2.1.10.127.1.1.1.1.6.10": "-4", 144 | "1.3.6.1.2.1.10.127.1.1.1.1.1.11": "18", 145 | "1.3.6.1.2.1.10.127.1.1.1.1.2.11": "274750000", 146 | "1.3.6.1.2.1.10.127.1.1.1.1.4.11": "4", 147 | "1.3.6.1.2.1.10.127.1.1.1.1.6.11": "-5", 148 | "1.3.6.1.2.1.10.127.1.1.1.1.1.12": "19", 149 | "1.3.6.1.2.1.10.127.1.1.1.1.2.12": "282750000", 150 | "1.3.6.1.2.1.10.127.1.1.1.1.4.12": "4", 151 | "1.3.6.1.2.1.10.127.1.1.1.1.6.12": "-5", 152 | "1.3.6.1.2.1.10.127.1.1.1.1.1.13": "20", 153 | "1.3.6.1.2.1.10.127.1.1.1.1.2.13": "290750000", 154 | "1.3.6.1.2.1.10.127.1.1.1.1.4.13": "4", 155 | "1.3.6.1.2.1.10.127.1.1.1.1.6.13": "-7", 156 | "1.3.6.1.2.1.10.127.1.1.1.1.1.14": "21", 157 | "1.3.6.1.2.1.10.127.1.1.1.1.2.14": "298750000", 158 | "1.3.6.1.2.1.10.127.1.1.1.1.4.14": "4", 159 | "1.3.6.1.2.1.10.127.1.1.1.1.6.14": "-9", 160 | "1.3.6.1.2.1.10.127.1.1.1.1.1.15": "22", 161 | "1.3.6.1.2.1.10.127.1.1.1.1.2.15": "306750000", 162 | "1.3.6.1.2.1.10.127.1.1.1.1.4.15": "4", 163 | "1.3.6.1.2.1.10.127.1.1.1.1.6.15": "-10", 164 | "1.3.6.1.2.1.10.127.1.1.1.1.1.16": "23", 165 | "1.3.6.1.2.1.10.127.1.1.1.1.2.16": "314750000", 166 | "1.3.6.1.2.1.10.127.1.1.1.1.4.16": "4", 167 | "1.3.6.1.2.1.10.127.1.1.1.1.6.16": "-12", 168 | "1.3.6.1.2.1.10.127.1.1.1.1.1.17": "24", 169 | "1.3.6.1.2.1.10.127.1.1.1.1.2.17": "322750000", 170 | "1.3.6.1.2.1.10.127.1.1.1.1.4.17": "4", 171 | "1.3.6.1.2.1.10.127.1.1.1.1.6.17": "-14", 172 | "1.3.6.1.2.1.10.127.1.1.1.1.1.18": "25", 173 | "1.3.6.1.2.1.10.127.1.1.1.1.2.18": "330750000", 174 | "1.3.6.1.2.1.10.127.1.1.1.1.4.18": "4", 175 | "1.3.6.1.2.1.10.127.1.1.1.1.6.18": "-10", 176 | "1.3.6.1.2.1.10.127.1.1.1.1.1.19": "26", 177 | "1.3.6.1.2.1.10.127.1.1.1.1.2.19": "370750000", 178 | "1.3.6.1.2.1.10.127.1.1.1.1.4.19": "4", 179 | "1.3.6.1.2.1.10.127.1.1.1.1.6.19": "-9", 180 | "1.3.6.1.2.1.10.127.1.1.1.1.1.20": "27", 181 | "1.3.6.1.2.1.10.127.1.1.1.1.2.20": "378750000", 182 | "1.3.6.1.2.1.10.127.1.1.1.1.4.20": "4", 183 | "1.3.6.1.2.1.10.127.1.1.1.1.6.20": "-7", 184 | "1.3.6.1.2.1.10.127.1.1.1.1.1.21": "28", 185 | "1.3.6.1.2.1.10.127.1.1.1.1.2.21": "386750000", 186 | "1.3.6.1.2.1.10.127.1.1.1.1.4.21": "4", 187 | "1.3.6.1.2.1.10.127.1.1.1.1.6.21": "-9", 188 | "1.3.6.1.2.1.10.127.1.1.1.1.1.22": "29", 189 | "1.3.6.1.2.1.10.127.1.1.1.1.2.22": "394750000", 190 | "1.3.6.1.2.1.10.127.1.1.1.1.4.22": "4", 191 | "1.3.6.1.2.1.10.127.1.1.1.1.6.22": "-10", 192 | "1.3.6.1.2.1.10.127.1.1.1.1.1.23": "31", 193 | "1.3.6.1.2.1.10.127.1.1.1.1.2.23": "410750000", 194 | "1.3.6.1.2.1.10.127.1.1.1.1.4.23": "4", 195 | "1.3.6.1.2.1.10.127.1.1.1.1.6.23": "-12", 196 | "1.3.6.1.2.1.10.127.1.1.1.1.1.24": "32", 197 | "1.3.6.1.2.1.10.127.1.1.1.1.2.24": "418750000", 198 | "1.3.6.1.2.1.10.127.1.1.1.1.4.24": "4", 199 | "1.3.6.1.2.1.10.127.1.1.1.1.6.24": "-15", 200 | "1.3.6.1.2.1.10.127.1.1.2.1.1.1": "2", 201 | "1.3.6.1.2.1.10.127.1.1.2.1.2.1": "39399985", 202 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.1": "510", 203 | "1.3.6.1.2.1.10.127.1.1.2.1.15.1": "2", 204 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.1": "5120", 205 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.1": "5", 206 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.1": "0", 207 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.1": "0", 208 | "1.3.6.1.2.1.10.127.1.1.2.1.1.2": "4", 209 | "1.3.6.1.2.1.10.127.1.1.2.1.2.2": "25800000", 210 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.2": "505", 211 | "1.3.6.1.2.1.10.127.1.1.2.1.15.2": "2", 212 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.2": "5120", 213 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.2": "5", 214 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.2": "2", 215 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.2": "0", 216 | "1.3.6.1.2.1.10.127.1.1.2.1.1.3": "1", 217 | "1.3.6.1.2.1.10.127.1.1.2.1.2.3": "46200000", 218 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.3": "510", 219 | "1.3.6.1.2.1.10.127.1.1.2.1.15.3": "2", 220 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.3": "5120", 221 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.3": "5", 222 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.3": "1", 223 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.3": "0", 224 | "1.3.6.1.2.1.10.127.1.1.2.1.1.4": "3", 225 | "1.3.6.1.2.1.10.127.1.1.2.1.2.4": "32600000", 226 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.4": "510", 227 | "1.3.6.1.2.1.10.127.1.1.2.1.15.4": "2", 228 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.4": "5120", 229 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.4": "5", 230 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.4": "0", 231 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.4": "0", 232 | "1.3.6.1.4.1.4115.1.3.4.1.1.12.0": "30,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,31,32,2,4,1,3", 233 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.172471": "38500089", 234 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.172471": "42600", 235 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.172471": "0", 236 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.172471": "42600", 237 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.172471": "2", 238 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.172472": "402500089", 239 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.172472": "42600", 240 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.172472": "0", 241 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.172472": "0", 242 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.172472": "1", 243 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.172473": "5250065", 244 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.172473": "16320", 245 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.172473": "0", 246 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.172473": "16320", 247 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.172473": "2", 248 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.172474": "55000065", 249 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.172474": "10000", 250 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.172474": "0", 251 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.172474": "0", 252 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.172474": "1", 253 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.172471": "38500089", 254 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.172471": "42600", 255 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.172471": "0", 256 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.172471": "42600", 257 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.172471": "2", 258 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.172472": "402500089", 259 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.172472": "42600", 260 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.172472": "0", 261 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.172472": "0", 262 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.172472": "1", 263 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.172473": "5250065", 264 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.172473": "16320", 265 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.172473": "0", 266 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.172473": "16320", 267 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.172473": "2", 268 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.172474": "55000065", 269 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.172474": "10000", 270 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.172474": "0", 271 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.172474": "0", 272 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.172474": "1", 273 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.172471": "38500089", 274 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.172471": "42600", 275 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.172471": "0", 276 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.172471": "42600", 277 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.172471": "2", 278 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.172472": "402500089", 279 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.172472": "42600", 280 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.172472": "0", 281 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.172472": "0", 282 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.172472": "1", 283 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.172473": "5250065", 284 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.172473": "16320", 285 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.172473": "0", 286 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.172473": "16320", 287 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.172473": "2", 288 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.172474": "55000065", 289 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.172474": "10000", 290 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.172474": "0", 291 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.172474": "0", 292 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.172474": "1", 293 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.1.172471": "2", 294 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.1.172471": "1", 295 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.2.172472": "1", 296 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.2.172472": "1", 297 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.3.172473": "2", 298 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.3.172473": "0", 299 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.4.172474": "1", 300 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.4.172474": "0", 301 | "1.3.6.1.4.1.4115.1.3.3.1.1.1.3.2.0": "1", 302 | "1": "Finish" 303 | } -------------------------------------------------------------------------------- /modems/superhub3/test_state/msh.json: -------------------------------------------------------------------------------- 1 | { 2 | "1.3.6.1.4.1.4115.1.3.4.1.5.9.0": "6", 3 | "1.3.6.1.4.1.4115.1.3.3.1.1.1.3.1.0": "1", 4 | "1.3.6.1.4.1.4491.2.1.14.1.5.4.0": "1", 5 | "1.3.6.1.2.1.10.127.1.1.5.0": "4", 6 | "1.3.6.1.2.1.126.1.1.1.1.1.2": "1", 7 | "1.3.6.1.2.1.69.1.4.5.0": "cmreg-vmdg505-bbt053-b.cm", 8 | "1.3.6.1.2.1.10.127.1.1.4.1.3.1": "88", 9 | "1.3.6.1.2.1.10.127.1.1.4.1.4.1": "0", 10 | "1.3.6.1.2.1.10.127.1.1.4.1.5.1": "403", 11 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.1": "403", 12 | "1.3.6.1.2.1.10.127.1.1.4.1.3.2": "61", 13 | "1.3.6.1.2.1.10.127.1.1.4.1.4.2": "0", 14 | "1.3.6.1.2.1.10.127.1.1.4.1.5.2": "403", 15 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.2": "403", 16 | "1.3.6.1.2.1.10.127.1.1.4.1.3.3": "183", 17 | "1.3.6.1.2.1.10.127.1.1.4.1.4.3": "0", 18 | "1.3.6.1.2.1.10.127.1.1.4.1.5.3": "403", 19 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.3": "403", 20 | "1.3.6.1.2.1.10.127.1.1.4.1.3.4": "52", 21 | "1.3.6.1.2.1.10.127.1.1.4.1.4.4": "0", 22 | "1.3.6.1.2.1.10.127.1.1.4.1.5.4": "403", 23 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.4": "403", 24 | "1.3.6.1.2.1.10.127.1.1.4.1.3.5": "55", 25 | "1.3.6.1.2.1.10.127.1.1.4.1.4.5": "0", 26 | "1.3.6.1.2.1.10.127.1.1.4.1.5.5": "403", 27 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.5": "403", 28 | "1.3.6.1.2.1.10.127.1.1.4.1.3.6": "71", 29 | "1.3.6.1.2.1.10.127.1.1.4.1.4.6": "0", 30 | "1.3.6.1.2.1.10.127.1.1.4.1.5.6": "409", 31 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.6": "409", 32 | "1.3.6.1.2.1.10.127.1.1.4.1.3.7": "67", 33 | "1.3.6.1.2.1.10.127.1.1.4.1.4.7": "0", 34 | "1.3.6.1.2.1.10.127.1.1.4.1.5.7": "409", 35 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.7": "409", 36 | "1.3.6.1.2.1.10.127.1.1.4.1.3.8": "52", 37 | "1.3.6.1.2.1.10.127.1.1.4.1.4.8": "0", 38 | "1.3.6.1.2.1.10.127.1.1.4.1.5.8": "403", 39 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.8": "403", 40 | "1.3.6.1.2.1.10.127.1.1.4.1.3.9": "76", 41 | "1.3.6.1.2.1.10.127.1.1.4.1.4.9": "0", 42 | "1.3.6.1.2.1.10.127.1.1.4.1.5.9": "403", 43 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.9": "403", 44 | "1.3.6.1.2.1.10.127.1.1.4.1.3.10": "66", 45 | "1.3.6.1.2.1.10.127.1.1.4.1.4.10": "0", 46 | "1.3.6.1.2.1.10.127.1.1.4.1.5.10": "403", 47 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.10": "403", 48 | "1.3.6.1.2.1.10.127.1.1.4.1.3.11": "77", 49 | "1.3.6.1.2.1.10.127.1.1.4.1.4.11": "0", 50 | "1.3.6.1.2.1.10.127.1.1.4.1.5.11": "409", 51 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.11": "409", 52 | "1.3.6.1.2.1.10.127.1.1.4.1.3.12": "68", 53 | "1.3.6.1.2.1.10.127.1.1.4.1.4.12": "0", 54 | "1.3.6.1.2.1.10.127.1.1.4.1.5.12": "403", 55 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.12": "403", 56 | "1.3.6.1.2.1.10.127.1.1.4.1.3.13": "121", 57 | "1.3.6.1.2.1.10.127.1.1.4.1.4.13": "0", 58 | "1.3.6.1.2.1.10.127.1.1.4.1.5.13": "409", 59 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.13": "409", 60 | "1.3.6.1.2.1.10.127.1.1.4.1.3.14": "119", 61 | "1.3.6.1.2.1.10.127.1.1.4.1.4.14": "0", 62 | "1.3.6.1.2.1.10.127.1.1.4.1.5.14": "403", 63 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.14": "403", 64 | "1.3.6.1.2.1.10.127.1.1.4.1.3.15": "84", 65 | "1.3.6.1.2.1.10.127.1.1.4.1.4.15": "0", 66 | "1.3.6.1.2.1.10.127.1.1.4.1.5.15": "409", 67 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.15": "409", 68 | "1.3.6.1.2.1.10.127.1.1.4.1.3.16": "78", 69 | "1.3.6.1.2.1.10.127.1.1.4.1.4.16": "0", 70 | "1.3.6.1.2.1.10.127.1.1.4.1.5.16": "403", 71 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.16": "403", 72 | "1.3.6.1.2.1.10.127.1.1.4.1.3.17": "72", 73 | "1.3.6.1.2.1.10.127.1.1.4.1.4.17": "0", 74 | "1.3.6.1.2.1.10.127.1.1.4.1.5.17": "403", 75 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.17": "403", 76 | "1.3.6.1.2.1.10.127.1.1.4.1.3.18": "61", 77 | "1.3.6.1.2.1.10.127.1.1.4.1.4.18": "0", 78 | "1.3.6.1.2.1.10.127.1.1.4.1.5.18": "403", 79 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.18": "403", 80 | "1.3.6.1.2.1.10.127.1.1.4.1.3.19": "72", 81 | "1.3.6.1.2.1.10.127.1.1.4.1.4.19": "0", 82 | "1.3.6.1.2.1.10.127.1.1.4.1.5.19": "403", 83 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.19": "403", 84 | "1.3.6.1.2.1.10.127.1.1.4.1.3.20": "105", 85 | "1.3.6.1.2.1.10.127.1.1.4.1.4.20": "0", 86 | "1.3.6.1.2.1.10.127.1.1.4.1.5.20": "403", 87 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.20": "403", 88 | "1.3.6.1.2.1.10.127.1.1.4.1.3.21": "78", 89 | "1.3.6.1.2.1.10.127.1.1.4.1.4.21": "0", 90 | "1.3.6.1.2.1.10.127.1.1.4.1.5.21": "403", 91 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.21": "403", 92 | "1.3.6.1.2.1.10.127.1.1.4.1.3.22": "84", 93 | "1.3.6.1.2.1.10.127.1.1.4.1.4.22": "0", 94 | "1.3.6.1.2.1.10.127.1.1.4.1.5.22": "409", 95 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.22": "409", 96 | "1.3.6.1.2.1.10.127.1.1.4.1.3.23": "88", 97 | "1.3.6.1.2.1.10.127.1.1.4.1.4.23": "0", 98 | "1.3.6.1.2.1.10.127.1.1.4.1.5.23": "403", 99 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.23": "403", 100 | "1.3.6.1.2.1.10.127.1.1.4.1.3.24": "89", 101 | "1.3.6.1.2.1.10.127.1.1.4.1.4.24": "0", 102 | "1.3.6.1.2.1.10.127.1.1.4.1.5.24": "403", 103 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.24": "403", 104 | "1.3.6.1.2.1.10.127.1.1.1.1.1.1": "25", 105 | "1.3.6.1.2.1.10.127.1.1.1.1.2.1": "331000000", 106 | "1.3.6.1.2.1.10.127.1.1.1.1.4.1": "4", 107 | "1.3.6.1.2.1.10.127.1.1.1.1.6.1": "65", 108 | "1.3.6.1.2.1.10.127.1.1.1.1.1.2": "9", 109 | "1.3.6.1.2.1.10.127.1.1.1.1.2.2": "203000000", 110 | "1.3.6.1.2.1.10.127.1.1.1.1.4.2": "4", 111 | "1.3.6.1.2.1.10.127.1.1.1.1.6.2": "71", 112 | "1.3.6.1.2.1.10.127.1.1.1.1.1.3": "10", 113 | "1.3.6.1.2.1.10.127.1.1.1.1.2.3": "211000000", 114 | "1.3.6.1.2.1.10.127.1.1.1.1.4.3": "4", 115 | "1.3.6.1.2.1.10.127.1.1.1.1.6.3": "71", 116 | "1.3.6.1.2.1.10.127.1.1.1.1.1.4": "11", 117 | "1.3.6.1.2.1.10.127.1.1.1.1.2.4": "219000000", 118 | "1.3.6.1.2.1.10.127.1.1.1.1.4.4": "4", 119 | "1.3.6.1.2.1.10.127.1.1.1.1.6.4": "73", 120 | "1.3.6.1.2.1.10.127.1.1.1.1.1.5": "12", 121 | "1.3.6.1.2.1.10.127.1.1.1.1.2.5": "227000000", 122 | "1.3.6.1.2.1.10.127.1.1.1.1.4.5": "4", 123 | "1.3.6.1.2.1.10.127.1.1.1.1.6.5": "71", 124 | "1.3.6.1.2.1.10.127.1.1.1.1.1.6": "13", 125 | "1.3.6.1.2.1.10.127.1.1.1.1.2.6": "235000000", 126 | "1.3.6.1.2.1.10.127.1.1.1.1.4.6": "4", 127 | "1.3.6.1.2.1.10.127.1.1.1.1.6.6": "70", 128 | "1.3.6.1.2.1.10.127.1.1.1.1.1.7": "14", 129 | "1.3.6.1.2.1.10.127.1.1.1.1.2.7": "243000000", 130 | "1.3.6.1.2.1.10.127.1.1.1.1.4.7": "4", 131 | "1.3.6.1.2.1.10.127.1.1.1.1.6.7": "69", 132 | "1.3.6.1.2.1.10.127.1.1.1.1.1.8": "15", 133 | "1.3.6.1.2.1.10.127.1.1.1.1.2.8": "251000000", 134 | "1.3.6.1.2.1.10.127.1.1.1.1.4.8": "4", 135 | "1.3.6.1.2.1.10.127.1.1.1.1.6.8": "70", 136 | "1.3.6.1.2.1.10.127.1.1.1.1.1.9": "16", 137 | "1.3.6.1.2.1.10.127.1.1.1.1.2.9": "259000000", 138 | "1.3.6.1.2.1.10.127.1.1.1.1.4.9": "4", 139 | "1.3.6.1.2.1.10.127.1.1.1.1.6.9": "68", 140 | "1.3.6.1.2.1.10.127.1.1.1.1.1.10": "17", 141 | "1.3.6.1.2.1.10.127.1.1.1.1.2.10": "267000000", 142 | "1.3.6.1.2.1.10.127.1.1.1.1.4.10": "4", 143 | "1.3.6.1.2.1.10.127.1.1.1.1.6.10": "68", 144 | "1.3.6.1.2.1.10.127.1.1.1.1.1.11": "18", 145 | "1.3.6.1.2.1.10.127.1.1.1.1.2.11": "275000000", 146 | "1.3.6.1.2.1.10.127.1.1.1.1.4.11": "4", 147 | "1.3.6.1.2.1.10.127.1.1.1.1.6.11": "65", 148 | "1.3.6.1.2.1.10.127.1.1.1.1.1.12": "19", 149 | "1.3.6.1.2.1.10.127.1.1.1.1.2.12": "283000000", 150 | "1.3.6.1.2.1.10.127.1.1.1.1.4.12": "4", 151 | "1.3.6.1.2.1.10.127.1.1.1.1.6.12": "64", 152 | "1.3.6.1.2.1.10.127.1.1.1.1.1.13": "20", 153 | "1.3.6.1.2.1.10.127.1.1.1.1.2.13": "291000000", 154 | "1.3.6.1.2.1.10.127.1.1.1.1.4.13": "4", 155 | "1.3.6.1.2.1.10.127.1.1.1.1.6.13": "64", 156 | "1.3.6.1.2.1.10.127.1.1.1.1.1.14": "21", 157 | "1.3.6.1.2.1.10.127.1.1.1.1.2.14": "299000000", 158 | "1.3.6.1.2.1.10.127.1.1.1.1.4.14": "4", 159 | "1.3.6.1.2.1.10.127.1.1.1.1.6.14": "65", 160 | "1.3.6.1.2.1.10.127.1.1.1.1.1.15": "22", 161 | "1.3.6.1.2.1.10.127.1.1.1.1.2.15": "307000000", 162 | "1.3.6.1.2.1.10.127.1.1.1.1.4.15": "4", 163 | "1.3.6.1.2.1.10.127.1.1.1.1.6.15": "64", 164 | "1.3.6.1.2.1.10.127.1.1.1.1.1.16": "23", 165 | "1.3.6.1.2.1.10.127.1.1.1.1.2.16": "315000000", 166 | "1.3.6.1.2.1.10.127.1.1.1.1.4.16": "4", 167 | "1.3.6.1.2.1.10.127.1.1.1.1.6.16": "65", 168 | "1.3.6.1.2.1.10.127.1.1.1.1.1.17": "24", 169 | "1.3.6.1.2.1.10.127.1.1.1.1.2.17": "323000000", 170 | "1.3.6.1.2.1.10.127.1.1.1.1.4.17": "4", 171 | "1.3.6.1.2.1.10.127.1.1.1.1.6.17": "65", 172 | "1.3.6.1.2.1.10.127.1.1.1.1.1.18": "26", 173 | "1.3.6.1.2.1.10.127.1.1.1.1.2.18": "339000000", 174 | "1.3.6.1.2.1.10.127.1.1.1.1.4.18": "4", 175 | "1.3.6.1.2.1.10.127.1.1.1.1.6.18": "68", 176 | "1.3.6.1.2.1.10.127.1.1.1.1.1.19": "27", 177 | "1.3.6.1.2.1.10.127.1.1.1.1.2.19": "347000000", 178 | "1.3.6.1.2.1.10.127.1.1.1.1.4.19": "4", 179 | "1.3.6.1.2.1.10.127.1.1.1.1.6.19": "68", 180 | "1.3.6.1.2.1.10.127.1.1.1.1.1.20": "28", 181 | "1.3.6.1.2.1.10.127.1.1.1.1.2.20": "355000000", 182 | "1.3.6.1.2.1.10.127.1.1.1.1.4.20": "4", 183 | "1.3.6.1.2.1.10.127.1.1.1.1.6.20": "66", 184 | "1.3.6.1.2.1.10.127.1.1.1.1.1.21": "29", 185 | "1.3.6.1.2.1.10.127.1.1.1.1.2.21": "363000000", 186 | "1.3.6.1.2.1.10.127.1.1.1.1.4.21": "4", 187 | "1.3.6.1.2.1.10.127.1.1.1.1.6.21": "68", 188 | "1.3.6.1.2.1.10.127.1.1.1.1.1.22": "30", 189 | "1.3.6.1.2.1.10.127.1.1.1.1.2.22": "371000000", 190 | "1.3.6.1.2.1.10.127.1.1.1.1.4.22": "4", 191 | "1.3.6.1.2.1.10.127.1.1.1.1.6.22": "68", 192 | "1.3.6.1.2.1.10.127.1.1.1.1.1.23": "31", 193 | "1.3.6.1.2.1.10.127.1.1.1.1.2.23": "379000000", 194 | "1.3.6.1.2.1.10.127.1.1.1.1.4.23": "4", 195 | "1.3.6.1.2.1.10.127.1.1.1.1.6.23": "65", 196 | "1.3.6.1.2.1.10.127.1.1.1.1.1.24": "32", 197 | "1.3.6.1.2.1.10.127.1.1.1.1.2.24": "387000000", 198 | "1.3.6.1.2.1.10.127.1.1.1.1.4.24": "4", 199 | "1.3.6.1.2.1.10.127.1.1.1.1.6.24": "70", 200 | "1.3.6.1.2.1.10.127.1.1.2.1.1.1": "5", 201 | "1.3.6.1.2.1.10.127.1.1.2.1.2.1": "32599975", 202 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.1": "308", 203 | "1.3.6.1.2.1.10.127.1.1.2.1.15.1": "2", 204 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.1": "5120", 205 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.1": "5", 206 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.1": "8", 207 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.1": "0", 208 | "1.3.6.1.2.1.10.127.1.1.2.1.1.2": "4", 209 | "1.3.6.1.2.1.10.127.1.1.2.1.2.2": "39399948", 210 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.2": "305", 211 | "1.3.6.1.2.1.10.127.1.1.2.1.15.2": "2", 212 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.2": "5120", 213 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.2": "5", 214 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.2": "8", 215 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.2": "0", 216 | "1.3.6.1.2.1.10.127.1.1.2.1.1.3": "3", 217 | "1.3.6.1.2.1.10.127.1.1.2.1.2.3": "46199951", 218 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.3": "303", 219 | "1.3.6.1.2.1.10.127.1.1.2.1.15.3": "2", 220 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.3": "5120", 221 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.3": "5", 222 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.3": "5", 223 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.3": "0", 224 | "1.3.6.1.2.1.10.127.1.1.2.1.1.4": "2", 225 | "1.3.6.1.2.1.10.127.1.1.2.1.2.4": "53699869", 226 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.4": "300", 227 | "1.3.6.1.2.1.10.127.1.1.2.1.15.4": "2", 228 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.4": "5120", 229 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.4": "5", 230 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.4": "5", 231 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.4": "0", 232 | "1.3.6.1.4.1.4115.1.3.4.1.1.12.0": "25,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,26,27,28,29,30,31,32,5,4,3,2", 233 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.12499": "38520000", 234 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.12499": "42600", 235 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.12499": "0", 236 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.12499": "16320", 237 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.12499": "2", 238 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.12500": "575000000", 239 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.12500": "42600", 240 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.12500": "0", 241 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.12500": "0", 242 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.12500": "1", 243 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.12501": "5250065", 244 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.12501": "16320", 245 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.12501": "0", 246 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.12501": "16320", 247 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.12501": "2", 248 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.12502": "55000065", 249 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.12502": "10000", 250 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.12502": "0", 251 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.12502": "0", 252 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.12502": "1", 253 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.12499": "38520000", 254 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.12499": "42600", 255 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.12499": "0", 256 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.12499": "16320", 257 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.12499": "2", 258 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.12500": "575000000", 259 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.12500": "42600", 260 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.12500": "0", 261 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.12500": "0", 262 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.12500": "1", 263 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.12501": "5250065", 264 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.12501": "16320", 265 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.12501": "0", 266 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.12501": "16320", 267 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.12501": "2", 268 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.12502": "55000065", 269 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.12502": "10000", 270 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.12502": "0", 271 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.12502": "0", 272 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.12502": "1", 273 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.12499": "38520000", 274 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.12499": "42600", 275 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.12499": "0", 276 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.12499": "16320", 277 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.12499": "2", 278 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.12500": "575000000", 279 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.12500": "42600", 280 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.12500": "0", 281 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.12500": "0", 282 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.12500": "1", 283 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.12501": "5250065", 284 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.12501": "16320", 285 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.12501": "0", 286 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.12501": "16320", 287 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.12501": "2", 288 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.12502": "55000065", 289 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.12502": "10000", 290 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.12502": "0", 291 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.12502": "0", 292 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.12502": "1", 293 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.1.12499": "2", 294 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.1.12499": "1", 295 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.2.12500": "1", 296 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.2.12500": "1", 297 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.3.12501": "2", 298 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.3.12501": "0", 299 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.4.12502": "1", 300 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.4.12502": "0", 301 | "1.3.6.1.4.1.4115.1.3.3.1.1.1.3.2.0": "1", 302 | "1": "Finish" 303 | } -------------------------------------------------------------------------------- /modems/superhub3/test_state/mshm.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": "Finish", 3 | "1.3.6.1.4.1.4115.1.3.4.1.5.9.0": "10", 4 | "1.3.6.1.4.1.4115.1.3.3.1.1.1.3.1.0": "1", 5 | "1.3.6.1.4.1.4491.2.1.14.1.5.4.0": "5", 6 | "1.3.6.1.2.1.10.127.1.1.5.0": "4", 7 | "1.3.6.1.2.1.126.1.1.1.1.1.2": "1", 8 | "1.3.6.1.2.1.69.1.4.5.0": "cmreg-vmdg505-bbt053+voc-b.cm", 9 | "1.3.6.1.2.1.10.127.1.1.4.1.3.1": "10", 10 | "1.3.6.1.2.1.10.127.1.1.4.1.4.1": "0", 11 | "1.3.6.1.2.1.10.127.1.1.4.1.5.1": "403", 12 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.1": "403", 13 | "1.3.6.1.2.1.10.127.1.1.4.1.3.2": "24", 14 | "1.3.6.1.2.1.10.127.1.1.4.1.4.2": "0", 15 | "1.3.6.1.2.1.10.127.1.1.4.1.5.2": "403", 16 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.2": "403", 17 | "1.3.6.1.2.1.10.127.1.1.4.1.3.3": "23", 18 | "1.3.6.1.2.1.10.127.1.1.4.1.4.3": "0", 19 | "1.3.6.1.2.1.10.127.1.1.4.1.5.3": "409", 20 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.3": "409", 21 | "1.3.6.1.2.1.10.127.1.1.4.1.3.4": "46", 22 | "1.3.6.1.2.1.10.127.1.1.4.1.4.4": "0", 23 | "1.3.6.1.2.1.10.127.1.1.4.1.5.4": "403", 24 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.4": "403", 25 | "1.3.6.1.2.1.10.127.1.1.4.1.3.5": "37", 26 | "1.3.6.1.2.1.10.127.1.1.4.1.4.5": "0", 27 | "1.3.6.1.2.1.10.127.1.1.4.1.5.5": "403", 28 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.5": "403", 29 | "1.3.6.1.2.1.10.127.1.1.4.1.3.6": "105", 30 | "1.3.6.1.2.1.10.127.1.1.4.1.4.6": "0", 31 | "1.3.6.1.2.1.10.127.1.1.4.1.5.6": "403", 32 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.6": "403", 33 | "1.3.6.1.2.1.10.127.1.1.4.1.3.7": "84", 34 | "1.3.6.1.2.1.10.127.1.1.4.1.4.7": "0", 35 | "1.3.6.1.2.1.10.127.1.1.4.1.5.7": "389", 36 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.7": "389", 37 | "1.3.6.1.2.1.10.127.1.1.4.1.3.8": "32", 38 | "1.3.6.1.2.1.10.127.1.1.4.1.4.8": "0", 39 | "1.3.6.1.2.1.10.127.1.1.4.1.5.8": "403", 40 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.8": "403", 41 | "1.3.6.1.2.1.10.127.1.1.4.1.3.9": "69", 42 | "1.3.6.1.2.1.10.127.1.1.4.1.4.9": "0", 43 | "1.3.6.1.2.1.10.127.1.1.4.1.5.9": "403", 44 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.9": "403", 45 | "1.3.6.1.2.1.10.127.1.1.4.1.3.10": "207", 46 | "1.3.6.1.2.1.10.127.1.1.4.1.4.10": "0", 47 | "1.3.6.1.2.1.10.127.1.1.4.1.5.10": "403", 48 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.10": "403", 49 | "1.3.6.1.2.1.10.127.1.1.4.1.3.11": "37", 50 | "1.3.6.1.2.1.10.127.1.1.4.1.4.11": "0", 51 | "1.3.6.1.2.1.10.127.1.1.4.1.5.11": "409", 52 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.11": "409", 53 | "1.3.6.1.2.1.10.127.1.1.4.1.3.12": "53", 54 | "1.3.6.1.2.1.10.127.1.1.4.1.4.12": "0", 55 | "1.3.6.1.2.1.10.127.1.1.4.1.5.12": "403", 56 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.12": "403", 57 | "1.3.6.1.2.1.10.127.1.1.4.1.3.13": "92", 58 | "1.3.6.1.2.1.10.127.1.1.4.1.4.13": "0", 59 | "1.3.6.1.2.1.10.127.1.1.4.1.5.13": "409", 60 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.13": "409", 61 | "1.3.6.1.2.1.10.127.1.1.4.1.3.14": "50", 62 | "1.3.6.1.2.1.10.127.1.1.4.1.4.14": "0", 63 | "1.3.6.1.2.1.10.127.1.1.4.1.5.14": "403", 64 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.14": "403", 65 | "1.3.6.1.2.1.10.127.1.1.4.1.3.15": "63", 66 | "1.3.6.1.2.1.10.127.1.1.4.1.4.15": "0", 67 | "1.3.6.1.2.1.10.127.1.1.4.1.5.15": "403", 68 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.15": "403", 69 | "1.3.6.1.2.1.10.127.1.1.4.1.3.16": "81", 70 | "1.3.6.1.2.1.10.127.1.1.4.1.4.16": "0", 71 | "1.3.6.1.2.1.10.127.1.1.4.1.5.16": "403", 72 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.16": "403", 73 | "1.3.6.1.2.1.10.127.1.1.4.1.3.17": "52", 74 | "1.3.6.1.2.1.10.127.1.1.4.1.4.17": "0", 75 | "1.3.6.1.2.1.10.127.1.1.4.1.5.17": "409", 76 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.17": "409", 77 | "1.3.6.1.2.1.10.127.1.1.4.1.3.18": "63", 78 | "1.3.6.1.2.1.10.127.1.1.4.1.4.18": "0", 79 | "1.3.6.1.2.1.10.127.1.1.4.1.5.18": "403", 80 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.18": "403", 81 | "1.3.6.1.2.1.10.127.1.1.4.1.3.19": "59", 82 | "1.3.6.1.2.1.10.127.1.1.4.1.4.19": "0", 83 | "1.3.6.1.2.1.10.127.1.1.4.1.5.19": "403", 84 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.19": "403", 85 | "1.3.6.1.2.1.10.127.1.1.4.1.3.20": "72", 86 | "1.3.6.1.2.1.10.127.1.1.4.1.4.20": "0", 87 | "1.3.6.1.2.1.10.127.1.1.4.1.5.20": "403", 88 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.20": "403", 89 | "1.3.6.1.2.1.10.127.1.1.4.1.3.21": "119", 90 | "1.3.6.1.2.1.10.127.1.1.4.1.4.21": "0", 91 | "1.3.6.1.2.1.10.127.1.1.4.1.5.21": "403", 92 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.21": "403", 93 | "1.3.6.1.2.1.10.127.1.1.4.1.3.22": "70", 94 | "1.3.6.1.2.1.10.127.1.1.4.1.4.22": "0", 95 | "1.3.6.1.2.1.10.127.1.1.4.1.5.22": "403", 96 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.22": "403", 97 | "1.3.6.1.2.1.10.127.1.1.4.1.3.23": "73", 98 | "1.3.6.1.2.1.10.127.1.1.4.1.4.23": "0", 99 | "1.3.6.1.2.1.10.127.1.1.4.1.5.23": "409", 100 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.23": "409", 101 | "1.3.6.1.2.1.10.127.1.1.4.1.3.24": "83", 102 | "1.3.6.1.2.1.10.127.1.1.4.1.4.24": "0", 103 | "1.3.6.1.2.1.10.127.1.1.4.1.5.24": "403", 104 | "1.3.6.1.4.1.4491.2.1.20.1.24.1.1.24": "403", 105 | "1.3.6.1.2.1.10.127.1.1.1.1.1.1": "1", 106 | "1.3.6.1.2.1.10.127.1.1.1.1.2.1": "139000000", 107 | "1.3.6.1.2.1.10.127.1.1.1.1.4.1": "4", 108 | "1.3.6.1.2.1.10.127.1.1.1.1.6.1": "70", 109 | "1.3.6.1.2.1.10.127.1.1.1.1.1.2": "2", 110 | "1.3.6.1.2.1.10.127.1.1.1.1.2.2": "147000000", 111 | "1.3.6.1.2.1.10.127.1.1.1.1.4.2": "4", 112 | "1.3.6.1.2.1.10.127.1.1.1.1.6.2": "65", 113 | "1.3.6.1.2.1.10.127.1.1.1.1.1.3": "3", 114 | "1.3.6.1.2.1.10.127.1.1.1.1.2.3": "155000000", 115 | "1.3.6.1.2.1.10.127.1.1.1.1.4.3": "4", 116 | "1.3.6.1.2.1.10.127.1.1.1.1.6.3": "63", 117 | "1.3.6.1.2.1.10.127.1.1.1.1.1.4": "4", 118 | "1.3.6.1.2.1.10.127.1.1.1.1.2.4": "163000000", 119 | "1.3.6.1.2.1.10.127.1.1.1.1.4.4": "4", 120 | "1.3.6.1.2.1.10.127.1.1.1.1.6.4": "61", 121 | "1.3.6.1.2.1.10.127.1.1.1.1.1.5": "5", 122 | "1.3.6.1.2.1.10.127.1.1.1.1.2.5": "171000000", 123 | "1.3.6.1.2.1.10.127.1.1.1.1.4.5": "4", 124 | "1.3.6.1.2.1.10.127.1.1.1.1.6.5": "66", 125 | "1.3.6.1.2.1.10.127.1.1.1.1.1.6": "6", 126 | "1.3.6.1.2.1.10.127.1.1.1.1.2.6": "179000000", 127 | "1.3.6.1.2.1.10.127.1.1.1.1.4.6": "4", 128 | "1.3.6.1.2.1.10.127.1.1.1.1.6.6": "65", 129 | "1.3.6.1.2.1.10.127.1.1.1.1.1.7": "7", 130 | "1.3.6.1.2.1.10.127.1.1.1.1.2.7": "187000000", 131 | "1.3.6.1.2.1.10.127.1.1.1.1.4.7": "4", 132 | "1.3.6.1.2.1.10.127.1.1.1.1.6.7": "65", 133 | "1.3.6.1.2.1.10.127.1.1.1.1.1.8": "8", 134 | "1.3.6.1.2.1.10.127.1.1.1.1.2.8": "195000000", 135 | "1.3.6.1.2.1.10.127.1.1.1.1.4.8": "4", 136 | "1.3.6.1.2.1.10.127.1.1.1.1.6.8": "65", 137 | "1.3.6.1.2.1.10.127.1.1.1.1.1.9": "9", 138 | "1.3.6.1.2.1.10.127.1.1.1.1.2.9": "203000000", 139 | "1.3.6.1.2.1.10.127.1.1.1.1.4.9": "4", 140 | "1.3.6.1.2.1.10.127.1.1.1.1.6.9": "64", 141 | "1.3.6.1.2.1.10.127.1.1.1.1.1.10": "10", 142 | "1.3.6.1.2.1.10.127.1.1.1.1.2.10": "211000000", 143 | "1.3.6.1.2.1.10.127.1.1.1.1.4.10": "4", 144 | "1.3.6.1.2.1.10.127.1.1.1.1.6.10": "63", 145 | "1.3.6.1.2.1.10.127.1.1.1.1.1.11": "11", 146 | "1.3.6.1.2.1.10.127.1.1.1.1.2.11": "219000000", 147 | "1.3.6.1.2.1.10.127.1.1.1.1.4.11": "4", 148 | "1.3.6.1.2.1.10.127.1.1.1.1.6.11": "64", 149 | "1.3.6.1.2.1.10.127.1.1.1.1.1.12": "12", 150 | "1.3.6.1.2.1.10.127.1.1.1.1.2.12": "227000000", 151 | "1.3.6.1.2.1.10.127.1.1.1.1.4.12": "4", 152 | "1.3.6.1.2.1.10.127.1.1.1.1.6.12": "64", 153 | "1.3.6.1.2.1.10.127.1.1.1.1.1.13": "13", 154 | "1.3.6.1.2.1.10.127.1.1.1.1.2.13": "235000000", 155 | "1.3.6.1.2.1.10.127.1.1.1.1.4.13": "4", 156 | "1.3.6.1.2.1.10.127.1.1.1.1.6.13": "63", 157 | "1.3.6.1.2.1.10.127.1.1.1.1.1.14": "14", 158 | "1.3.6.1.2.1.10.127.1.1.1.1.2.14": "243000000", 159 | "1.3.6.1.2.1.10.127.1.1.1.1.4.14": "4", 160 | "1.3.6.1.2.1.10.127.1.1.1.1.6.14": "61", 161 | "1.3.6.1.2.1.10.127.1.1.1.1.1.15": "15", 162 | "1.3.6.1.2.1.10.127.1.1.1.1.2.15": "251000000", 163 | "1.3.6.1.2.1.10.127.1.1.1.1.4.15": "4", 164 | "1.3.6.1.2.1.10.127.1.1.1.1.6.15": "61", 165 | "1.3.6.1.2.1.10.127.1.1.1.1.1.16": "16", 166 | "1.3.6.1.2.1.10.127.1.1.1.1.2.16": "259000000", 167 | "1.3.6.1.2.1.10.127.1.1.1.1.4.16": "4", 168 | "1.3.6.1.2.1.10.127.1.1.1.1.6.16": "63", 169 | "1.3.6.1.2.1.10.127.1.1.1.1.1.17": "17", 170 | "1.3.6.1.2.1.10.127.1.1.1.1.2.17": "267000000", 171 | "1.3.6.1.2.1.10.127.1.1.1.1.4.17": "4", 172 | "1.3.6.1.2.1.10.127.1.1.1.1.6.17": "64", 173 | "1.3.6.1.2.1.10.127.1.1.1.1.1.18": "18", 174 | "1.3.6.1.2.1.10.127.1.1.1.1.2.18": "275000000", 175 | "1.3.6.1.2.1.10.127.1.1.1.1.4.18": "4", 176 | "1.3.6.1.2.1.10.127.1.1.1.1.6.18": "60", 177 | "1.3.6.1.2.1.10.127.1.1.1.1.1.19": "19", 178 | "1.3.6.1.2.1.10.127.1.1.1.1.2.19": "283000000", 179 | "1.3.6.1.2.1.10.127.1.1.1.1.4.19": "4", 180 | "1.3.6.1.2.1.10.127.1.1.1.1.6.19": "61", 181 | "1.3.6.1.2.1.10.127.1.1.1.1.1.20": "20", 182 | "1.3.6.1.2.1.10.127.1.1.1.1.2.20": "291000000", 183 | "1.3.6.1.2.1.10.127.1.1.1.1.4.20": "4", 184 | "1.3.6.1.2.1.10.127.1.1.1.1.6.20": "60", 185 | "1.3.6.1.2.1.10.127.1.1.1.1.1.21": "21", 186 | "1.3.6.1.2.1.10.127.1.1.1.1.2.21": "299000000", 187 | "1.3.6.1.2.1.10.127.1.1.1.1.4.21": "4", 188 | "1.3.6.1.2.1.10.127.1.1.1.1.6.21": "60", 189 | "1.3.6.1.2.1.10.127.1.1.1.1.1.22": "22", 190 | "1.3.6.1.2.1.10.127.1.1.1.1.2.22": "307000000", 191 | "1.3.6.1.2.1.10.127.1.1.1.1.4.22": "4", 192 | "1.3.6.1.2.1.10.127.1.1.1.1.6.22": "56", 193 | "1.3.6.1.2.1.10.127.1.1.1.1.1.23": "23", 194 | "1.3.6.1.2.1.10.127.1.1.1.1.2.23": "315000000", 195 | "1.3.6.1.2.1.10.127.1.1.1.1.4.23": "4", 196 | "1.3.6.1.2.1.10.127.1.1.1.1.6.23": "56", 197 | "1.3.6.1.2.1.10.127.1.1.1.1.1.24": "24", 198 | "1.3.6.1.2.1.10.127.1.1.1.1.2.24": "323000000", 199 | "1.3.6.1.2.1.10.127.1.1.1.1.4.24": "4", 200 | "1.3.6.1.2.1.10.127.1.1.1.1.6.24": "56", 201 | "1.3.6.1.2.1.10.127.1.1.2.1.1.2": "4", 202 | "1.3.6.1.2.1.10.127.1.1.2.1.2.2": "39400064", 203 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.2": "333", 204 | "1.3.6.1.2.1.10.127.1.1.2.1.15.2": "2", 205 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.2": "5120", 206 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.2": "5", 207 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.2": "6", 208 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.2": "0", 209 | "1.3.6.1.2.1.10.127.1.1.2.1.1.3": "3", 210 | "1.3.6.1.2.1.10.127.1.1.2.1.2.3": "46200129", 211 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.3": "330", 212 | "1.3.6.1.2.1.10.127.1.1.2.1.15.3": "2", 213 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.3": "5120", 214 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.3": "5", 215 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.3": "7", 216 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.3": "0", 217 | "1.3.6.1.2.1.10.127.1.1.2.1.1.4": "2", 218 | "1.3.6.1.2.1.10.127.1.1.2.1.2.4": "53700014", 219 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.4": "330", 220 | "1.3.6.1.2.1.10.127.1.1.2.1.15.4": "2", 221 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.4": "5120", 222 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.4": "5", 223 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.4": "3", 224 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.4": "0", 225 | "1.3.6.1.2.1.10.127.1.1.2.1.1.5": "5", 226 | "1.3.6.1.2.1.10.127.1.1.2.1.2.5": "32600138", 227 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.1.5": "335", 228 | "1.3.6.1.2.1.10.127.1.1.2.1.15.5": "2", 229 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.2.5": "5120", 230 | "1.3.6.1.4.1.4115.1.3.4.1.9.2.1.3.5": "5", 231 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.2.5": "6", 232 | "1.3.6.1.4.1.4491.2.1.20.1.2.1.3.5": "0", 233 | "1.3.6.1.4.1.4115.1.3.4.1.1.12.0": "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,4,3,2,5", 234 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.12427": "38520000", 235 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.12427": "42600", 236 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.12427": "0", 237 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.12427": "16320", 238 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.12427": "2", 239 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.12428": "575000000", 240 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.12428": "42600", 241 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.12428": "0", 242 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.12428": "0", 243 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.12428": "1", 244 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.12429": "5250065", 245 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.12429": "16320", 246 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.12429": "0", 247 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.12429": "16320", 248 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.12429": "2", 249 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.12430": "128000", 250 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.12430": "3044", 251 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.12430": "0", 252 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.12430": "1522", 253 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.12430": "2", 254 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.12431": "55000065", 255 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.12431": "10000", 256 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.12431": "0", 257 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.12431": "0", 258 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.12431": "1", 259 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.1.12432": "128000", 260 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.1.12432": "3044", 261 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.1.12432": "0", 262 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.1.12432": "0", 263 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.1.12432": "1", 264 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.12427": "38520000", 265 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.12427": "42600", 266 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.12427": "0", 267 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.12427": "16320", 268 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.12427": "2", 269 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.12428": "575000000", 270 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.12428": "42600", 271 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.12428": "0", 272 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.12428": "0", 273 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.12428": "1", 274 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.12429": "5250065", 275 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.12429": "16320", 276 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.12429": "0", 277 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.12429": "16320", 278 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.12429": "2", 279 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.12430": "128000", 280 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.12430": "3044", 281 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.12430": "0", 282 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.12430": "1522", 283 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.12430": "2", 284 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.12431": "55000065", 285 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.12431": "10000", 286 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.12431": "0", 287 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.12431": "0", 288 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.12431": "1", 289 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.2.12432": "128000", 290 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.2.12432": "3044", 291 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.2.12432": "0", 292 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.2.12432": "0", 293 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.2.12432": "1", 294 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.12427": "38520000", 295 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.12427": "42600", 296 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.12427": "0", 297 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.12427": "16320", 298 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.12427": "2", 299 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.12428": "575000000", 300 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.12428": "42600", 301 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.12428": "0", 302 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.12428": "0", 303 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.12428": "1", 304 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.12429": "5250065", 305 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.12429": "16320", 306 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.12429": "0", 307 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.12429": "16320", 308 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.12429": "2", 309 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.12430": "128000", 310 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.12430": "3044", 311 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.12430": "0", 312 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.12430": "1522", 313 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.12430": "2", 314 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.12431": "55000065", 315 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.12431": "10000", 316 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.12431": "0", 317 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.12431": "0", 318 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.12431": "1", 319 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.6.2.3.12432": "128000", 320 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.7.2.3.12432": "3044", 321 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.8.2.3.12432": "0", 322 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.12.2.3.12432": "0", 323 | "1.3.6.1.4.1.4491.2.1.21.1.2.1.13.2.3.12432": "1", 324 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.1.12427": "2", 325 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.1.12427": "1", 326 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.2.12428": "1", 327 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.2.12428": "1", 328 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.3.12429": "2", 329 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.3.12429": "0", 330 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.4.12430": "2", 331 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.4.12430": "0", 332 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.5.12431": "1", 333 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.5.12431": "0", 334 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.7.2.6.12432": "1", 335 | "1.3.6.1.4.1.4491.2.1.21.1.3.1.8.2.6.12432": "0", 336 | "1.3.6.1.4.1.4115.1.3.3.1.1.1.3.2.0": "1" 337 | } -------------------------------------------------------------------------------- /modems/superhub4/README.md: -------------------------------------------------------------------------------- 1 | # Superhub 4 Channel Processor 2 | 3 | ## Supported Modems 4 | 5 | The Superhub 4 is distributed to multiple countries with different branding by 6 | Liberty Global. 7 | 8 | This processor is known to work on: 9 | 10 | - Virgin Media Superhub 4 11 | 12 | Expected to work, but untested: 13 | 14 | - Virgin Media Ireland Hub 2.0 15 | - Ziggo Connect box Giga 16 | - UPC Switzerland Giga Connect Box 17 | - UPC Poland Giga Connect Box 18 | - UPC Slovakia Giga Connect Box 19 | 20 | 21 | ## Fetching the Data 22 | 23 | The Superhub 4 (and equivilent international variants) exposes an endpoint over 24 | HTTP which is used to display statistics on the web interface of the router. 25 | This page is visible without authentication and is constructed by making an 26 | extra HTTP call to an endpoint which returns a JSON array with some statistics 27 | values. 28 | 29 | A simple HTTP GET to 30 | `http://$ROUTER_IP/php/ajaxGet_device_networkstatus_data.php` will return this 31 | document. 32 | 33 | The document returned is a single array. 34 | ```json 35 | [ 36 | "402750000", 37 | "46200000", 38 | ... 39 | ``` 40 | 41 | ## Interpreting the Data 42 | 43 | The array provided is in a predictable order. 44 | 45 | Values that are returned as arrays need to be JSON loaded as they are JSON 46 | arrays stored as strings. 47 | 48 | Strangely, when an array is empty, one element exists within it with empty 49 | values. 50 | For example on a connection with no 3.1 upstream channels, the 3.1 upstream 51 | channels value appears like this: 52 | ```json 53 | "[[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]]" 54 | ``` 55 | 56 | 57 | ### Array order 58 | 59 | 0. 60 | 1. 61 | 2. 62 | 3. 63 | 4. 64 | 5. 65 | 6. 66 | 7. 67 | 8. DOCSIS Version 68 | 9. Loaded firmware version 69 | 10. 70 | 11. Downstream maximum rate 71 | 12. Downstream maximum burst 72 | 13. 73 | 14. 74 | 15. Upstream maximum rate 75 | 16. Upstream maximum burst 76 | 17. 77 | 18. 78 | 19. Scheduling type 79 | 20. Array of 3.0 downstream channels 80 | 21. Array of 3.0 upstream channels 81 | 22. Array of log entries 82 | 23. Array of 3.1 downstream channels 83 | 24. Array of 3.1 upstream channels 84 | 25. Count of 3.0 upstream channels 85 | 26. Count of 3.0 downstream channels 86 | 27. Count of 3.1 downstream channels 87 | 28. Count of 3.1 upstream channels 88 | 29. 89 | 90 | Blanks are values that are currently unknown. 91 | They should be easy to determine but no effort has gone into this yet. 92 | 93 | 94 | ### Channel Arrays 95 | 96 | #### 3.0 Downstream Channels 97 | 98 | Example: 99 | ```json 100 | ["30","402750000","5.400002","40.366287","QAM256","Locked","40.366287","5","0"] 101 | ``` 102 | 103 | 0. Channel ID 104 | 1. Frequency 105 | 2. Power level 106 | 3. SNR 107 | 4. Modulation 108 | 5. Locked Status 109 | 6. SNR again *Unsure as to why* 110 | 7. Pre RS Errors 111 | 8. Post RS Errors 112 | 113 | 114 | #### 3.0 Upstream Channels 115 | 116 | Example: 117 | ```json 118 | ["3","46200000","46.770599","5120 KSym/sec","64QAM","US_TYPE_STDMA","0","0","0","0"] 119 | ``` 120 | 121 | 0. Channel ID 122 | 1. Frequency 123 | 2. Power Level 124 | 3. 125 | 4. Modulation 126 | 5. 127 | 6. 128 | 7. 129 | 8. 130 | 9. 131 | 132 | 133 | #### 3.1 Downstream Channels 134 | 135 | Example: 136 | ```json 137 | ["33","96","4K","1880","QAM4096","759","Locked","43","5.5","186002","0"] 138 | ``` 139 | 140 | 0. Channel ID 141 | 1. Frequency 142 | 2. 143 | 3. 144 | 4. Modulation 145 | 5. Locked status 146 | 6. 147 | 7. SNR 148 | 8. Power level 149 | 9. Pre RS Errors 150 | 10. Post RS Errors 151 | 152 | 153 | #### 3.1 Upstream Channels 154 | 155 | Example: 156 | ```json 157 | ["14","10.0","37.0","2K","QAM8","OFDMA","200","53.9","6","0"] 158 | ``` 159 | 160 | 0. Channel ID 161 | 1. Channel Width 162 | 2. Power Level 163 | 3. FFT Type 164 | 4. Modulation 165 | 5. Channel Type 166 | 6. Number of subcarriers 167 | 7. First active subcarrier (MHz) **Note:** UI says this is Hz, but this looks like an error 168 | 8. T3 Timeouts 169 | 9. T4 Timeouts 170 | -------------------------------------------------------------------------------- /modems/superhub4/sh4-testcase.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Superhub 4 statistics failure test case. 4 | # This simple script is designed to demonstrate that 5 | # https://github.com/msh100/modem-stats/issues/2 affects all Superhub 4 users. 6 | 7 | # This script will do the following: 8 | # 1) Ensure the Superhub 4 is in a bad state 9 | # 2) Wait until the Superhub 4 is healthy (rebooted since step 1). 10 | # 3) Query the Superhub 4 until it is in a bad state again (10 consecutive failures). 11 | # 4) Print time and number of queries taken to break the Superhub. 12 | 13 | is_broken() { 14 | local broken_stats data 15 | data="$1" 16 | broken_stats='["","","","",null,"","","","","","","","","","","","","","","","[[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]]","[[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]]","[]","[[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]]","[[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]]","","","","",""]' 17 | 18 | [ "${data}" == "${broken_stats}" ] 19 | } 20 | 21 | get_stats_from_superhub() { 22 | local router_ip data 23 | router_ip=$1 24 | query_address="http://${router_ip}/php/ajaxGet_device_networkstatus_data.php" 25 | curl -s "${query_address}" 26 | } 27 | 28 | to_log() { 29 | echo "[$(date)]" "${@}" 30 | } 31 | 32 | main() { 33 | local query 34 | local router_ip 35 | router_ip="$1" 36 | query="$(get_stats_from_superhub "${router_ip}")" 37 | 38 | if ! is_broken "${query}"; then 39 | to_log "The Superhub 4 needs to be in a bad state before starting this script" 40 | exit 1 41 | fi 42 | 43 | to_log "Superhub 4 is in a bad state. Stop all queries to the router and then restart the router to begin the test." 44 | 45 | until ! is_broken "${query}"; do 46 | query="$(get_stats_from_superhub "${router_ip}")" 47 | sleep 10 48 | done 49 | 50 | to_log "Superhub 4 is healthy, starting test." 51 | 52 | local count broken_count 53 | count=0 54 | broken_count=0 55 | until [ "${broken_count}" == "10" ]; do 56 | ((count=count+1)) 57 | query="$(get_stats_from_superhub "${router_ip}")" 58 | 59 | if is_broken "${query}"; then 60 | ((broken_count=broken_count+1)) 61 | else 62 | broken_count=0 63 | fi 64 | 65 | sleep 10 66 | done 67 | 68 | to_log "Superhub 4 statistics are now broken after ${count} queries" 69 | } 70 | 71 | main "$@" 72 | -------------------------------------------------------------------------------- /modems/superhub4/superhub4.go: -------------------------------------------------------------------------------- 1 | package superhub4 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "strconv" 8 | "strings" 9 | 10 | "github.com/msh100/modem-stats/utils" 11 | ) 12 | 13 | type Modem struct { 14 | IPAddress string 15 | Stats []byte 16 | FetchTime int64 17 | } 18 | 19 | func (sh4 *Modem) ClearStats() { 20 | sh4.Stats = nil 21 | } 22 | 23 | func (sh4 *Modem) Type() string { 24 | return utils.TypeDocsis 25 | } 26 | 27 | func (sh4 *Modem) fetchURL() string { 28 | if sh4.IPAddress == "" { 29 | sh4.IPAddress = "192.168.100.1" 30 | } 31 | return fmt.Sprintf("http://%s/php/ajaxGet_device_networkstatus_data.php", sh4.IPAddress) 32 | } 33 | 34 | func (sh4 *Modem) ParseStats() (utils.ModemStats, error) { 35 | if sh4.Stats == nil { 36 | var err error 37 | sh4.Stats, sh4.FetchTime, err = utils.SimpleHTTPFetch(sh4.fetchURL()) 38 | if err != nil { 39 | return utils.ModemStats{}, err 40 | } 41 | } 42 | 43 | var errstrings []string 44 | 45 | var arr []string 46 | json.Unmarshal([]byte(sh4.Stats), &arr) 47 | 48 | downRate, _ := strconv.Atoi(arr[11]) 49 | downBurst, _ := strconv.Atoi(arr[12]) 50 | upRate, _ := strconv.Atoi(arr[15]) 51 | upBurst, _ := strconv.Atoi(arr[16]) 52 | 53 | if downRate == 0 || downBurst == 0 || upRate == 0 || upBurst == 0 { 54 | error := fmt.Errorf("got nil values for speed config %d,%d,%d,%d", downRate, downBurst, upRate, upBurst) 55 | errstrings = append(errstrings, error.Error()) 56 | } 57 | 58 | var downChannelsData [][]string 59 | json.Unmarshal([]byte(arr[20]), &downChannelsData) 60 | var downChannels []utils.ModemChannel 61 | for index, downChannelData := range downChannelsData { 62 | if len(downChannelData) != 9 { 63 | error := fmt.Errorf("abnormal down channel length, expected 9, got %d", len(downChannelData)) 64 | errstrings = append(errstrings, error.Error()) 65 | break 66 | } 67 | 68 | channelID, _ := strconv.Atoi(downChannelData[0]) 69 | frequency, _ := strconv.Atoi(downChannelData[1]) 70 | snr, _ := strconv.ParseFloat(downChannelData[3], 64) 71 | snrint := int(snr * 10) 72 | power, _ := strconv.ParseFloat(downChannelData[2], 64) 73 | powerint := int(power * 10) 74 | prerserr, _ := strconv.Atoi(downChannelData[7]) 75 | postrserr, _ := strconv.Atoi(downChannelData[8]) 76 | 77 | if channelID < 1 || channelID > 1024 { 78 | error := fmt.Errorf("abnormal channel ID, got %d", channelID) 79 | errstrings = append(errstrings, error.Error()) 80 | break 81 | } 82 | if powerint > 2000 || powerint < -2000 { 83 | error := fmt.Errorf("power level for 3.0 channel %d is abnormal, got %d", channelID, powerint) 84 | errstrings = append(errstrings, error.Error()) 85 | break 86 | } 87 | 88 | downChannels = append(downChannels, utils.ModemChannel{ 89 | ChannelID: channelID, 90 | Channel: index + 1, 91 | Frequency: frequency, 92 | Snr: snrint, 93 | Power: powerint, 94 | Prerserr: prerserr, 95 | Postrserr: postrserr, 96 | Modulation: downChannelData[4], 97 | Scheme: "SC-QAM", 98 | }) 99 | } 100 | 101 | var down31ChannelsData [][]string 102 | json.Unmarshal([]byte(arr[23]), &down31ChannelsData) 103 | for index, down31ChannelData := range down31ChannelsData { 104 | if len(down31ChannelData) != 11 { 105 | error := fmt.Errorf("abnormal 3.1 down channel length, expected 11, got %d", len(down31ChannelData)) 106 | errstrings = append(errstrings, error.Error()) 107 | break 108 | } 109 | 110 | channelID, _ := strconv.Atoi(down31ChannelData[0]) 111 | frequency, _ := strconv.Atoi(down31ChannelData[1] + "000000") 112 | snr, _ := strconv.ParseFloat(down31ChannelData[7], 64) 113 | snrint := int(snr * 10) 114 | power, _ := strconv.ParseFloat(down31ChannelData[8], 64) 115 | powerint := int(power * 10) 116 | prerserr, _ := strconv.Atoi(down31ChannelData[9]) 117 | postrserr, _ := strconv.Atoi(down31ChannelData[10]) 118 | 119 | if channelID < 1 || channelID > 1024 { 120 | error := fmt.Errorf("abnormal channel ID, got %d", channelID) 121 | errstrings = append(errstrings, error.Error()) 122 | break 123 | } 124 | if powerint > 2000 || powerint < -2000 { 125 | error := fmt.Errorf("power level for 3.1 channel %d is abnormal, got %d", channelID, powerint) 126 | errstrings = append(errstrings, error.Error()) 127 | break 128 | } 129 | 130 | downChannels = append(downChannels, utils.ModemChannel{ 131 | ChannelID: channelID, 132 | Channel: index + 1, 133 | Frequency: frequency, 134 | Snr: snrint, 135 | Power: powerint, 136 | Prerserr: prerserr, 137 | Postrserr: postrserr, 138 | Modulation: down31ChannelData[4], 139 | Scheme: "OFDM", 140 | }) 141 | } 142 | 143 | var upChannelsData [][]string 144 | json.Unmarshal([]byte(arr[21]), &upChannelsData) 145 | var upChannels []utils.ModemChannel 146 | for index, upChannelData := range upChannelsData { 147 | if len(upChannelData) != 10 { 148 | error := fmt.Errorf("abnormal up channel length, expected 10, got %d", len(upChannelData)) 149 | errstrings = append(errstrings, error.Error()) 150 | break 151 | } 152 | 153 | channelID, _ := strconv.Atoi(upChannelData[0]) 154 | frequency, _ := strconv.Atoi(upChannelData[1]) 155 | power, _ := strconv.ParseFloat(upChannelData[2], 64) 156 | powerint := int(power * 10) 157 | 158 | if channelID < 1 || channelID > 1024 { 159 | error := fmt.Errorf("abnormal channel ID, got %d", channelID) 160 | errstrings = append(errstrings, error.Error()) 161 | break 162 | } 163 | if powerint > 2000 || powerint < -2000 { 164 | error := fmt.Errorf("power level for up channel %d is abnormal, got %d", channelID, powerint) 165 | errstrings = append(errstrings, error.Error()) 166 | break 167 | } 168 | 169 | upChannels = append(upChannels, utils.ModemChannel{ 170 | ChannelID: channelID, 171 | Channel: index + 1, 172 | Frequency: frequency, 173 | Power: powerint, 174 | }) 175 | } 176 | 177 | var channelOffset int = len(upChannels) 178 | var up31ChannelsData [][]string 179 | json.Unmarshal([]byte(arr[24]), &up31ChannelsData) 180 | for index, up31ChannelData := range up31ChannelsData { 181 | if len(up31ChannelData) != 10 { 182 | error := fmt.Errorf("abnormal 3.1 up channel length, expected 10, got %d", len(up31ChannelData)) 183 | errstrings = append(errstrings, error.Error()) 184 | break 185 | } 186 | 187 | channelID, _ := strconv.Atoi(up31ChannelData[0]) 188 | frequency, _ := strconv.ParseFloat(up31ChannelData[7], 64) 189 | frequencyInt := int(frequency * 1000000) 190 | power, _ := strconv.ParseFloat(up31ChannelData[2], 64) 191 | powerint := int(power * 10) 192 | 193 | if channelID < 1 || channelID > 1024 { 194 | error := fmt.Errorf("abnormal 3.1 channel ID, got %d", channelID) 195 | errstrings = append(errstrings, error.Error()) 196 | break 197 | } 198 | if powerint > 2000 || powerint < -2000 { 199 | error := fmt.Errorf("power level for up 3.1 channel %d is abnormal, got %d", channelID, powerint) 200 | errstrings = append(errstrings, error.Error()) 201 | break 202 | } 203 | 204 | upChannels = append(upChannels, utils.ModemChannel{ 205 | ChannelID: channelID, 206 | Channel: channelOffset + index + 1, 207 | Frequency: frequencyInt, 208 | Power: powerint, 209 | }) 210 | } 211 | 212 | var returnerr error 213 | returnerr = nil 214 | if len(errstrings) > 0 { 215 | returnerr = errors.New(strings.Join(errstrings, "\n")) 216 | } 217 | 218 | return utils.ModemStats{ 219 | Configs: []utils.ModemConfig{ 220 | { 221 | Config: "downstream", 222 | Maxrate: downRate, 223 | Maxburst: downBurst, 224 | }, 225 | { 226 | Config: "upstream", 227 | Maxrate: upRate, 228 | Maxburst: upBurst, 229 | }, 230 | }, 231 | UpChannels: upChannels, 232 | DownChannels: downChannels, 233 | FetchTime: sh4.FetchTime, 234 | }, returnerr 235 | } 236 | -------------------------------------------------------------------------------- /modems/superhub4/test_state/cg0.json: -------------------------------------------------------------------------------- 1 | [ 2 | "371000000", 3 | "49600000", 4 | "Locked", 5 | "ACTIVE", 6 | 6, 7 | "true", 8 | "1", 9 | "true", 10 | "3.1", 11 | "wrkldJKDHSUBsgvca69834ncx", 12 | "20269", 13 | "1200000450", 14 | "42600", 15 | "0", 16 | "20268", 17 | "55000270", 18 | "42600", 19 | "0", 20 | "16320", 21 | "bestEffort", 22 | "[[\"30\",\"371000000\",\"7.699997\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"1\",\"139000000\",\"9.400002\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"2\",\"147000000\",\"9.599998\",\"38.605377\",\"QAM256\",\"Locked\",\"38.605377\",\"0\",\"0\"],[\"3\",\"155000000\",\"9.300003\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"4\",\"163000000\",\"9.300003\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"5\",\"171000000\",\"9.000000\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"6\",\"179000000\",\"9.000000\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"7\",\"187000000\",\"8.900002\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"8\",\"195000000\",\"9.099998\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"9\",\"203000000\",\"8.900002\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"10\",\"211000000\",\"8.800003\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"11\",\"219000000\",\"8.599998\",\"38.605377\",\"QAM256\",\"Locked\",\"38.605377\",\"0\",\"0\"],[\"12\",\"227000000\",\"8.400002\",\"38.605377\",\"QAM256\",\"Locked\",\"38.605377\",\"0\",\"0\"],[\"13\",\"235000000\",\"8.099998\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"14\",\"243000000\",\"7.699997\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"15\",\"251000000\",\"7.699997\",\"38.605377\",\"QAM256\",\"Locked\",\"38.605377\",\"0\",\"0\"],[\"16\",\"259000000\",\"7.500000\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"17\",\"267000000\",\"7.699997\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"18\",\"275000000\",\"7.800003\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"19\",\"283000000\",\"7.900002\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"20\",\"291000000\",\"7.800003\",\"38.605377\",\"QAM256\",\"Locked\",\"38.605377\",\"0\",\"0\"],[\"21\",\"299000000\",\"7.699997\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"22\",\"307000000\",\"7.400002\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"23\",\"315000000\",\"7.199997\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"24\",\"323000000\",\"7.300003\",\"38.605377\",\"QAM256\",\"Locked\",\"38.605377\",\"0\",\"0\"],[\"25\",\"331000000\",\"7.500000\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"26\",\"339000000\",\"7.699997\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"27\",\"347000000\",\"8.000000\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"28\",\"355000000\",\"7.800003\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"],[\"29\",\"363000000\",\"7.800003\",\"38.605377\",\"QAM256\",\"Locked\",\"38.605377\",\"0\",\"0\"],[\"31\",\"379000000\",\"7.800003\",\"38.983261\",\"QAM256\",\"Locked\",\"38.983261\",\"0\",\"0\"]]", 23 | "[[\"9\",\"49600000\",\"42.520599\",\"5120 KSym\\\/sec\",\"64QAM\",\"US_TYPE_STDMA\",\"0\",\"0\",\"1\",\"0\"],[\"13\",\"23600000\",\"43.020599\",\"5120 KSym\\\/sec\",\"64QAM\",\"US_TYPE_STDMA\",\"0\",\"0\",\"4\",\"0\"],[\"12\",\"30100000\",\"43.020599\",\"5120 KSym\\\/sec\",\"64QAM\",\"US_TYPE_STDMA\",\"0\",\"0\",\"1\",\"0\"],[\"11\",\"36600000\",\"43.020599\",\"5120 KSym\\\/sec\",\"64QAM\",\"US_TYPE_STDMA\",\"0\",\"0\",\"6\",\"0\"],[\"10\",\"43100000\",\"43.020599\",\"5120 KSym\\\/sec\",\"64QAM\",\"US_TYPE_STDMA\",\"0\",\"0\",\"5\",\"0\"]]", 24 | "[]", 25 | "[[\"159\",\"96\",\"4K\",\"1880\",\"QAM4096\",\"759\",\"Locked\",\"41\",\"6.9\",\"1399128308\",\"0\"]]", 26 | "[[\"14\",\"10.0\",\"37.0\",\"2K\",\"QAM8\",\"OFDMA\",\"200\",\"53.9\",\"6\",\"0\"]]", 27 | "5", 28 | "31", 29 | "1", 30 | "1", 31 | "SC-QAM" 32 | ] 33 | -------------------------------------------------------------------------------- /modems/superhub4/test_state/sno.json: -------------------------------------------------------------------------------- 1 | [ 2 | "147000000", 3 | "23600000", 4 | "Locked", 5 | "ACTIVE", 6 | 6, 7 | "true", 8 | "1", 9 | "true", 10 | "3.1", 11 | "wrkldJKDHSUBsgvca69834ncx", 12 | "17303", 13 | "1200000450", 14 | "42600", 15 | "0", 16 | "17302", 17 | "55000270", 18 | "42600", 19 | "0", 20 | "16320", 21 | "bestEffort", 22 | "[[\"2\",\"147000000\",\"7.300003\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"1\",\"139000000\",\"7.099998\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"3\",\"155000000\",\"7.300003\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"4\",\"163000000\",\"7.099998\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"5\",\"171000000\",\"6.699997\",\"40.366287\",\"QAM256\",\"Locked\",\"40.366287\",\"0\",\"0\"],[\"6\",\"179000000\",\"6.599998\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"7\",\"187000000\",\"7.099998\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"8\",\"195000000\",\"7.000000\",\"43.376591\",\"QAM256\",\"Locked\",\"43.376591\",\"0\",\"0\"],[\"9\",\"203000000\",\"6.400002\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"10\",\"211000000\",\"6.099998\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"11\",\"219000000\",\"5.800003\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"12\",\"227000000\",\"5.800003\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"13\",\"235000000\",\"5.699997\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"14\",\"243000000\",\"5.500000\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"15\",\"251000000\",\"5.099998\",\"40.366287\",\"QAM256\",\"Locked\",\"40.366287\",\"0\",\"0\"],[\"16\",\"259000000\",\"4.800003\",\"40.366287\",\"QAM256\",\"Locked\",\"40.366287\",\"0\",\"0\"],[\"17\",\"267000000\",\"5.199997\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"18\",\"275000000\",\"5.900002\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"19\",\"283000000\",\"5.900002\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"20\",\"291000000\",\"5.400002\",\"40.366287\",\"QAM256\",\"Locked\",\"40.366287\",\"0\",\"0\"],[\"21\",\"299000000\",\"5.900002\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"22\",\"307000000\",\"5.699997\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"23\",\"315000000\",\"5.500000\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"24\",\"323000000\",\"4.699997\",\"40.366287\",\"QAM256\",\"Locked\",\"40.366287\",\"0\",\"0\"],[\"25\",\"331000000\",\"4.699997\",\"40.366287\",\"QAM256\",\"Locked\",\"40.366287\",\"0\",\"0\"],[\"26\",\"339000000\",\"5.000000\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"27\",\"347000000\",\"5.400002\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"],[\"28\",\"355000000\",\"5.300003\",\"40.366287\",\"QAM256\",\"Locked\",\"40.366287\",\"0\",\"0\"],[\"29\",\"363000000\",\"5.099998\",\"40.366287\",\"QAM256\",\"Locked\",\"40.366287\",\"0\",\"0\"],[\"30\",\"371000000\",\"4.599998\",\"40.366287\",\"QAM256\",\"Locked\",\"40.366287\",\"0\",\"0\"],[\"31\",\"379000000\",\"4.800003\",\"40.946209\",\"QAM256\",\"Locked\",\"40.946209\",\"0\",\"0\"]]", 23 | "[[\"5\",\"23600000\",\"44.770599\",\"5120 KSym\\\/sec\",\"64QAM\",\"US_TYPE_STDMA\",\"0\",\"0\",\"0\",\"0\"],[\"4\",\"30100000\",\"45.270599\",\"5120 KSym\\\/sec\",\"64QAM\",\"US_TYPE_STDMA\",\"0\",\"0\",\"0\",\"0\"],[\"3\",\"36600000\",\"45.770599\",\"5120 KSym\\\/sec\",\"64QAM\",\"US_TYPE_STDMA\",\"0\",\"0\",\"0\",\"0\"],[\"2\",\"43100000\",\"45.270599\",\"5120 KSym\\\/sec\",\"64QAM\",\"US_TYPE_STDMA\",\"0\",\"0\",\"0\",\"0\"],[\"1\",\"49600000\",\"45.770599\",\"5120 KSym\\\/sec\",\"64QAM\",\"US_TYPE_STDMA\",\"0\",\"0\",\"0\",\"0\"]]", 24 | "[[\"Fri Oct 7 10:06:54 2022\\n\",\"3\",\"Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:07:24 2022\\n\",\"3\",\"Received Response to Broadcast Maintenance Request, But no Unicast Maintenance opportunities received - T4 time out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:08:54 2022\\n\",\"3\",\"Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:09:19 2022\\n\",\"5\",\"DBC-REQ Mismatch Between Calculated Value for P1.6hi Compared to CCAP Provided Value;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:14:20 2022\\n\",\"3\",\"Received Response to Broadcast Maintenance Request, But no Unicast Maintenance opportunities received - T4 time out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:16:27 2022\\n\",\"3\",\"No Ranging Response received - T3 time-out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:17:41 2022\\n\",\"5\",\"MIMO Event MIMO: Stored MIMO=-1 post cfg file MIMO=-1;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:17:45 2022\\n\",\"3\",\"No Ranging Response received - T3 time-out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:18:41 2022\\n\",\"5\",\"Initializing Channel Timeout Expires - Time the CM can perform initial ranging on all upstream channels in the TCS has expired;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:18:41 2022\\n\",\"5\",\"TCS Partial Service;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:18:42 2022\\n\",\"3\",\"Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:18:44 2022\\n\",\"5\",\"TCS Partial Service;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:18:44 2022\\n\",\"6\",\"US profile assignment change. US Chan ID: 6; Previous Profile: ; New Profile: 11.;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:18:45 2022\\n\",\"3\",\"Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:18:58 2022\\n\",\"3\",\"Ranging Request Retries exhausted;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:18:58 2022\\n\",\"3\",\"Unicast Maintenance Ranging attempted - No response - Retries exhausted;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:18:59 2022\\n\",\"3\",\"Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:19:44 2022\\n\",\"3\",\"Received Response to Broadcast Maintenance Request, But no Unicast Maintenance opportunities received - T4 time out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:20:36 2022\\n\",\"3\",\"Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:21:06 2022\\n\",\"3\",\"Received Response to Broadcast Maintenance Request, But no Unicast Maintenance opportunities received - T4 time out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:22:36 2022\\n\",\"3\",\"Ranging Request Retries exhausted;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:22:36 2022\\n\",\"3\",\"Unicast Maintenance Ranging attempted - No response - Retries exhausted;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:23:06 2022\\n\",\"3\",\"Received Response to Broadcast Maintenance Request, But no Unicast Maintenance opportunities received - T4 time out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:24:36 2022\\n\",\"3\",\"Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:25:06 2022\\n\",\"3\",\"Received Response to Broadcast Maintenance Request, But no Unicast Maintenance opportunities received - T4 time out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:26:36 2022\\n\",\"3\",\"Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:27:05 2022\\n\",\"3\",\"Received Response to Broadcast Maintenance Request, But no Unicast Maintenance opportunities received - T4 time out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:28:35 2022\\n\",\"3\",\"Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:29:05 2022\\n\",\"3\",\"Received Response to Broadcast Maintenance Request, But no Unicast Maintenance opportunities received - T4 time out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:30:15 2022\\n\",\"3\",\"Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:30:45 2022\\n\",\"3\",\"Received Response to Broadcast Maintenance Request, But no Unicast Maintenance opportunities received - T4 time out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:32:15 2022\\n\",\"3\",\"Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:32:45 2022\\n\",\"3\",\"Received Response to Broadcast Maintenance Request, But no Unicast Maintenance opportunities received - T4 time out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:34:15 2022\\n\",\"3\",\"Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 10:34:18 2022\\n\",\"5\",\"DBC-REQ Mismatch Between Calculated Value for P1.6hi Compared to CCAP Provided Value;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Fri Oct 7 12:02:07 2022\\n\",\"3\",\"No Ranging Response received - T3 time-out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Sun Oct 9 09:08:38 2022\\n\",\"4\",\"DHCP RENEW WARNING - Field invalid in response v4 option;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Sun Oct 9 09:08:38 2022\\n\",\"6\",\"DHCP Renew - lease parameters tftp file-cmreg-vmdg640-bbt076-b.cm modified;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Sun Oct 9 12:49:11 2022\\n\",\"3\",\"No Ranging Response received - T3 time-out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Mon Oct 10 06:47:12 2022\\n\",\"6\",\"US profile assignment change. US Chan ID: 6; Previous Profile: 12; New Profile: 11.;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Mon Oct 10 15:10:20 2022\\n\",\"3\",\"No Ranging Response received - T3 time-out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Tue Oct 11 06:30:50 2022\\n\",\"6\",\"CM-STATUS message sent. Event Type Code: 23; Chan ID: 159; DSID: N\\\/A; MAC Addr: N\\\/A; OFDM\\\/OFDMA Profile ID: N\\\/A.;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Tue Oct 11 14:34:59 2022\\n\",\"3\",\"No Ranging Response received - T3 time-out;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"],[\"Wed Oct 12 20:42:35 2022\\n\",\"6\",\"US profile assignment change. US Chan ID: 6; Previous Profile: 12; New Profile: 11.;CM-MAC=e4:57:40:ef:77:4b;CMTS-MAC=00:ca:e5:c9:ea:af;CM-QOS=1.1;CM-VER=3.1;\"]]", 25 | "[[\"159\",\"96\",\"4K\",\"1880\",\"QAM4096\",\"424\",\"Locked\",\"44\",\"4.5\",\"1404549293\",\"0\"]]", 26 | "[[\"6\",\"10.0\",\"39.8\",\"2K\",\"QAM8\",\"OFDMA\",\"200\",\"53.9\",\"0\",\"0\"]]", 27 | "5", 28 | "31", 29 | "1", 30 | "1", 31 | "SC-QAM" 32 | ] 33 | -------------------------------------------------------------------------------- /modems/superhub5/README.md: -------------------------------------------------------------------------------- 1 | # Superhub 5 Channel Processor 2 | 3 | ## Supported Modems 4 | 5 | This processor is only known to work with the Virgin Media Superhub 5. 6 | 7 | 8 | ## Fetching the Data 9 | 10 | The Superhub 5 exposes a REST API on its webserver at `/rest/v1`. 11 | There are 3 endpoints which interest us here: 12 | 13 | * `/rest/v1/cablemodem/downstream` 14 | * `/rest/v1/cablemodem/upstream` 15 | * `/rest/v1/cablemodem/serviceflows` 16 | 17 | The Superhub 5 runs at `192.168.0.1` in router mode and `192.168.100.1` in 18 | modem mode. 19 | 20 | ## Interpreting the Data 21 | 22 | JSON data is returned from each GET request. 23 | 24 | 25 | ### Downstream 26 | 27 | `.downstream.channels` contains an array of downstream channels. 28 | Each channel is made up of: 29 | 30 | - `channelId` - Channel ID 31 | - `frequency` - Frequench in hertz 32 | - `power` - Power in dBmV 33 | - `modulation` - Channel modulation (map below) 34 | - `snr` - Signal to Noise ratio in dB 35 | - `rxMer` - Signal to Noise ratio in dB (used by DOCSIS 3.1 channels) 36 | - `correctedErrors` - Count of corrected codewords 37 | - `uncorrectedErrors` - Count of uncorrectable codewords 38 | - `lockStatus` - (Bool) Channel locked 39 | 40 | For example: 41 | 42 | ```json 43 | { 44 | "channelId": 25, 45 | "frequency": 331000000, 46 | "power": 4.4, 47 | "modulation": "qam_256", 48 | "snr": 41, 49 | "rxMer": 41, 50 | "correctedErrors": 18, 51 | "uncorrectedErrors": 22, 52 | "lockStatus": true 53 | } 54 | ``` 55 | 56 | The returned value for power is 10x greater on DOCSIS 3.1 channels than on 57 | DOCSIS 3.0 channels, therefore they need to be normalised. 58 | 59 | **Note:** It has been noted that the corrected count is displayed as "Pre RS 60 | errors" in the Superhub UI, and uncorrected is displayed as "post RS errors". 61 | The number for post was higher than pre which didn't make sense and I assume 62 | that the Superhub 5 displays this data incorrectly. 63 | 64 | 65 | ### Upstream 66 | 67 | `.upstream.channels` is similar to that of downstream and contains an array of 68 | upstream channels. 69 | Each channel is made up of: 70 | 71 | - `channelId` - Channel ID 72 | - `frequency` - Frequench in hertz 73 | - `lockStatus` - (Bool) Channel locked 74 | - `power` - Power in dBmV 75 | - `modulation` - Channel modulation (map below) 76 | - `t1Timeout` - T1 Timeout count 77 | - `t2Timeout` - T2 Timeout count 78 | - `t3Timeout` - T3 Timeout count 79 | - `t4Timeout` - T4 Timeout count 80 | - `channelType` - Type of upstream channel 81 | 82 | For example: 83 | 84 | ```json 85 | { 86 | "channelId": 1, 87 | "frequency": 60300000, 88 | "lockStatus": true, 89 | "power": 44.3, 90 | "symbolRate": 5120, 91 | "modulation": "qam_64", 92 | "t1Timeout": 0, 93 | "t2Timeout": 0, 94 | "t3Timeout": 0, 95 | "t4Timeout": 0, 96 | "channelType": "atdma" 97 | } 98 | ``` 99 | 100 | The returned value for power is 10x greater on DOCSIS 3.1 channels than on 101 | DOCSIS 3.0 channels, therefore they need to be normalised. 102 | 103 | 104 | ### Service Flows 105 | 106 | To get the upstream and downstream rate/burst, we need to read from an array 107 | at `.serviceFlows`. 108 | Each object will contain an object at `.serviceFlow`. 109 | 110 | We are interested in the value where `direction == "downstream"` or 111 | `direction == "upstream"`. 112 | 113 | Example: 114 | 115 | ```json 116 | { 117 | "serviceFlow": { 118 | "serviceFlowId": 17980, 119 | "direction": "downstream", 120 | "maxTrafficRate": 402500089, 121 | "maxTrafficBurst": 42600, 122 | "minReservedRate": 0, 123 | "maxConcatenatedBurst": 0, 124 | "scheduleType": "undefined" 125 | } 126 | } 127 | ``` 128 | 129 | ### Modulation Map 130 | 131 | Modulation is mapped by `/common/js/networkstatus.js` in the following ways: 132 | 133 | ```javascript 134 | var MODULATION_MAP = { 135 | qpsk : "QPSK", 136 | qam_8 : "QAM 8", 137 | qam_16 : "QAM 16", 138 | qam_32 : "QAM 32", 139 | qam_64 : "QAM 64", 140 | qam_128 : "QAM 128", 141 | qam_256 : "QAM 256", 142 | other : "rs46", 143 | unsupported : "c_st30", 144 | error : "c_st30", 145 | unknown : "c_cd04" // 'Unknown' 146 | }; 147 | ``` 148 | -------------------------------------------------------------------------------- /modems/superhub5/superhub5.go: -------------------------------------------------------------------------------- 1 | package superhub5 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io/ioutil" 7 | "regexp" 8 | "time" 9 | 10 | jsonpatch "github.com/evanphx/json-patch" 11 | "github.com/msh100/modem-stats/utils" 12 | ) 13 | 14 | type Modem struct { 15 | IPAddress string 16 | Stats []byte 17 | FetchTime int64 18 | } 19 | 20 | func (sh5 *Modem) ClearStats() { 21 | sh5.Stats = nil 22 | } 23 | 24 | func (sh5 *Modem) Type() string { 25 | return utils.TypeDocsis 26 | } 27 | 28 | func (sh5 *Modem) apiAddress() string { 29 | if sh5.IPAddress == "" { 30 | sh5.IPAddress = "192.168.100.1" // TODO: Is this a reasonable default? 31 | } 32 | return fmt.Sprintf("http://%s/rest/v1/cablemodem", sh5.IPAddress) 33 | } 34 | 35 | type dsChannel struct { 36 | ID int `json:"channelId"` 37 | Frequency int `json:"frequency"` 38 | Power float32 `json:"power"` 39 | Modulation string `json:"modulation"` 40 | SNR int `json:"snr"` 41 | PreRS int `json:"correctedErrors"` 42 | PostRS int `json:"uncorrectedErrors"` 43 | ChannelType string `json:"channelType"` 44 | RxMer int `json:"rxMer"` 45 | } 46 | 47 | type usChannel struct { 48 | ID int `json:"channelId"` 49 | Frequency int `json:"frequency"` 50 | Power float32 `json:"power"` 51 | Modulation string `json:"modulation"` 52 | ChannelType string `json:"channelType"` 53 | } 54 | 55 | type serviceFlow struct { 56 | ServiceFlow struct { 57 | ID int `json:"serviceFlowId"` 58 | Direction string `json:"direction"` 59 | MaxRate int `json:"maxTrafficRate"` 60 | MaxBurst int `json:"maxTrafficBurst"` 61 | } `json:"serviceFlow"` 62 | } 63 | 64 | type resultsStruct struct { 65 | Downstream struct { 66 | Channels []dsChannel `json:"channels"` 67 | } `json:"downstream"` 68 | Upstream struct { 69 | Channels []usChannel `json:"channels"` 70 | } `json:"upstream"` 71 | ServiceFlows []serviceFlow `json:"serviceFlows"` 72 | } 73 | 74 | func (sh5 *Modem) ParseStats() (utils.ModemStats, error) { 75 | if sh5.Stats == nil { 76 | sh5.Stats = []byte("{}") 77 | queries := []string{ 78 | sh5.apiAddress() + "/downstream", 79 | sh5.apiAddress() + "/upstream", 80 | sh5.apiAddress() + "/serviceflows", 81 | } 82 | 83 | timeStart := time.Now().UnixNano() / int64(time.Millisecond) 84 | statsData := utils.BoundedParallelGet(queries, 3) 85 | sh5.FetchTime = (time.Now().UnixNano() / int64(time.Millisecond)) - timeStart 86 | 87 | for _, query := range statsData { 88 | stats, err := ioutil.ReadAll(query.Res.Body) 89 | if err != nil { 90 | return utils.ModemStats{}, err 91 | } 92 | 93 | sh5.Stats, err = jsonpatch.MergeMergePatches(sh5.Stats, stats) 94 | if err != nil { 95 | return utils.ModemStats{}, err 96 | } 97 | } 98 | } 99 | 100 | var upChannels []utils.ModemChannel 101 | var downChannels []utils.ModemChannel 102 | var modemConfigs []utils.ModemConfig 103 | 104 | var results resultsStruct 105 | json.Unmarshal(sh5.Stats, &results) 106 | 107 | for index, downstream := range results.Downstream.Channels { 108 | re := regexp.MustCompile("[0-9]+") 109 | qamSize := re.FindString(downstream.Modulation) 110 | 111 | powerInt := int(downstream.Power * 10) 112 | snr := downstream.SNR * 10 113 | 114 | var scheme string 115 | if downstream.ChannelType == "sc_qam" { 116 | scheme = "SC-QAM" 117 | } else if downstream.ChannelType == "ofdm" { 118 | scheme = "OFDM" 119 | powerInt = int(downstream.Power) 120 | snr = downstream.RxMer 121 | } else { 122 | fmt.Println("Unknown channel scheme:", downstream.ChannelType) 123 | continue 124 | } 125 | 126 | downChannels = append(downChannels, utils.ModemChannel{ 127 | ChannelID: downstream.ID, 128 | Channel: index + 1, 129 | Frequency: downstream.Frequency, 130 | Snr: snr, 131 | Power: powerInt, 132 | Prerserr: downstream.PreRS + downstream.PostRS, 133 | Postrserr: downstream.PostRS, 134 | Modulation: "QAM" + qamSize, 135 | Scheme: scheme, 136 | }) 137 | } 138 | 139 | for index, upstream := range results.Upstream.Channels { 140 | powerInt := int(upstream.Power * 10) 141 | 142 | var scheme string 143 | if upstream.ChannelType == "atdma" { 144 | scheme = "ATDMA" 145 | } else if upstream.ChannelType == "ofdma" { 146 | scheme = "OFDMA" 147 | powerInt = int(upstream.Power) 148 | } else { 149 | fmt.Println("Unknown channel scheme:", upstream.ChannelType) 150 | continue 151 | } 152 | 153 | upChannels = append(upChannels, utils.ModemChannel{ 154 | ChannelID: upstream.ID, 155 | Channel: index + 1, 156 | Frequency: upstream.Frequency, 157 | Power: powerInt, 158 | Scheme: scheme, 159 | }) 160 | } 161 | 162 | for _, modemConfig := range results.ServiceFlows { 163 | modemConfigs = append(modemConfigs, utils.ModemConfig{ 164 | Config: modemConfig.ServiceFlow.Direction, 165 | Maxrate: modemConfig.ServiceFlow.MaxRate, 166 | Maxburst: modemConfig.ServiceFlow.MaxBurst, 167 | }) 168 | } 169 | 170 | return utils.ModemStats{ 171 | Configs: modemConfigs, 172 | UpChannels: upChannels, 173 | DownChannels: downChannels, 174 | FetchTime: sh5.FetchTime, 175 | }, nil 176 | } 177 | -------------------------------------------------------------------------------- /modems/tc4400/README.md: -------------------------------------------------------------------------------- 1 | # Technicolor TC4400 Channel Processor 2 | 3 | ## Supported Modems 4 | 5 | This processor is only known to work with the Technicolor TC4400. 6 | 7 | 8 | ## Fetching the Data 9 | 10 | The Technicolor TC4400 exposes a webserver which returns data in tables. 11 | All the channel statistics are returned on a single page which requires BASIC 12 | authentication. 13 | 14 | All the channel statistics information can be fetched from the 15 | `/cmconnectionstatus.html` endpoint. 16 | 17 | 18 | ## Interpreting the Data 19 | 20 | The page returned is formatted HTML. 21 | The page contains four tables, in a predictable order. 22 | 23 | 1. Overall status 24 | 2. Downstream channels 25 | 3. Upstream channels 26 | 4. DHCP leases 27 | 28 | 29 | ### Downstream 30 | 31 | The second table on the page returns all of the downstream channels. 32 | 33 | The first row of this table is a header in a single cell. 34 | The second row is made up of the column headers. 35 | Every subsequent row is data, with the columns made up of: 36 | 37 | 1. Channel index 38 | 2. Channel ID 39 | 3. Lock status 40 | 4. Channel type 41 | 5. Bonding status 42 | 6. Centre frequency (in Hz) 43 | 7. Channel width (in Hz) 44 | 8. SNR/MER threshold (value in dB) 45 | 9. Power level (in dBmV) 46 | 10. Modulation/Profile ID 47 | 11. Unerrored codewords 48 | 12. Corrected codewords 49 | 13. Uncorrectable codewords 50 | 51 | 52 | ### Upstream 53 | 54 | The third table on the page returns all of the upstream channels. 55 | 56 | As with the downstream channels, the first row of this table is a header in a 57 | single cell. 58 | The second row is made up of the column headers. 59 | Every subsequent row is data, with the columns made up of: 60 | 61 | 1. Channel index 62 | 2. Channel ID 63 | 3. Lock status 64 | 4. Channel type 65 | 5. Bonding status 66 | 6. Centre frequency (in Hz) 67 | 7. Channel width (in Hz) 68 | 8. Power level (in dBmV) 69 | 9. Modulation/Profile ID 70 | -------------------------------------------------------------------------------- /modems/tc4400/tc4400.go: -------------------------------------------------------------------------------- 1 | package tc4400 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io/ioutil" 7 | "net/http" 8 | "strings" 9 | "time" 10 | 11 | "github.com/PuerkitoBio/goquery" 12 | "github.com/msh100/modem-stats/utils" 13 | ) 14 | 15 | type Modem struct { 16 | IPAddress string 17 | Stats []byte 18 | FetchTime int64 19 | Username string 20 | Password string 21 | } 22 | 23 | func (tc4400 *Modem) ClearStats() { 24 | tc4400.Stats = nil 25 | } 26 | 27 | func (tc4400 *Modem) Type() string { 28 | return utils.TypeDocsis 29 | } 30 | 31 | func (tc4400 *Modem) apiAddress() string { 32 | if tc4400.IPAddress == "" { 33 | tc4400.IPAddress = "192.168.100.1" 34 | } 35 | return fmt.Sprintf("http://%s/cmconnectionstatus.html", tc4400.IPAddress) 36 | } 37 | 38 | func (tc4400 *Modem) getStats() ([]byte, error) { 39 | if tc4400.Stats == nil { 40 | req, err := http.NewRequest("GET", tc4400.apiAddress(), nil) 41 | if err != nil { 42 | return nil, err 43 | } 44 | req.SetBasicAuth(tc4400.Username, tc4400.Password) 45 | 46 | timeStart := time.Now().UnixNano() / int64(time.Millisecond) 47 | 48 | client := &http.Client{} 49 | resp, err := client.Do(req) 50 | if err != nil { 51 | return nil, err 52 | } 53 | defer resp.Body.Close() 54 | 55 | if resp.StatusCode == http.StatusOK { 56 | bodyBytes, err := ioutil.ReadAll(resp.Body) 57 | if err != nil { 58 | return nil, err 59 | } 60 | tc4400.Stats = bodyBytes 61 | tc4400.FetchTime = (time.Now().UnixNano() / int64(time.Millisecond)) - timeStart 62 | } else { 63 | return nil, fmt.Errorf("Request failed with status: %s", resp.Status) 64 | } 65 | } 66 | 67 | return tc4400.Stats, nil 68 | } 69 | 70 | func (tc4400 *Modem) ParseStats() (utils.ModemStats, error) { 71 | modemStats, err := tc4400.getStats() 72 | if err != nil { 73 | return utils.ModemStats{}, err 74 | } 75 | 76 | var downChannels []utils.ModemChannel 77 | var upChannels []utils.ModemChannel 78 | 79 | r := bytes.NewReader(modemStats) 80 | 81 | doc, err := goquery.NewDocumentFromReader(r) 82 | if err != nil { 83 | return utils.ModemStats{}, err 84 | } 85 | 86 | doc.Find("table").Eq(1).Find("tr").Each(func(i int, rowHtml *goquery.Selection) { 87 | if i <= 1 { 88 | return 89 | } 90 | 91 | var thisChannel utils.ModemChannel 92 | var lockStatus string 93 | 94 | rowHtml.Find("td").Each(func(j int, cellHtml *goquery.Selection) { 95 | cellText := strings.TrimSpace(cellHtml.Text()) 96 | 97 | switch j { 98 | case 0: 99 | thisChannel.Channel = utils.ExtractIntValue(cellText) 100 | case 1: 101 | thisChannel.ChannelID = utils.ExtractIntValue(cellText) 102 | case 2: 103 | lockStatus = cellText 104 | case 3: 105 | thisChannel.Scheme = cellText 106 | case 5: 107 | thisChannel.Frequency = utils.ExtractIntValue(cellText) 108 | case 7: 109 | thisChannel.Snr = int(utils.ExtractFloatValue(cellText) * 10) 110 | case 8: 111 | thisChannel.Power = int(utils.ExtractFloatValue(cellText) * 10) 112 | // case 9: // TODO: This is broken on OFDM channels 113 | // thisChannel.Modulation = cellText 114 | case 11: 115 | thisChannel.Prerserr = utils.ExtractIntValue(cellText) 116 | case 13: 117 | thisChannel.Postrserr = utils.ExtractIntValue(cellText) 118 | } 119 | }) 120 | 121 | if lockStatus == "Locked" { 122 | downChannels = append(downChannels, thisChannel) 123 | } 124 | }) 125 | 126 | doc.Find("table").Eq(2).Find("tr").Each(func(i int, rowHtml *goquery.Selection) { 127 | if i <= 1 { 128 | return 129 | } 130 | 131 | var thisChannel utils.ModemChannel 132 | var lockStatus string 133 | 134 | rowHtml.Find("td").Each(func(j int, cellHtml *goquery.Selection) { 135 | cellText := strings.TrimSpace(cellHtml.Text()) 136 | 137 | switch j { 138 | case 0: 139 | thisChannel.Channel = utils.ExtractIntValue(cellText) 140 | case 1: 141 | thisChannel.ChannelID = utils.ExtractIntValue(cellText) 142 | case 2: 143 | lockStatus = cellText 144 | case 3: 145 | thisChannel.Scheme = cellText 146 | case 5: 147 | thisChannel.Frequency = utils.ExtractIntValue(cellText) 148 | case 7: 149 | thisChannel.Power = int(utils.ExtractFloatValue(cellText) * 10) 150 | // case 8: // TODO: This is broken on OFDM channels 151 | // thisChannel.Modulation = cellText 152 | } 153 | }) 154 | 155 | if lockStatus == "Locked" { 156 | upChannels = append(upChannels, thisChannel) 157 | } 158 | }) 159 | 160 | return utils.ModemStats{ 161 | DownChannels: downChannels, 162 | UpChannels: upChannels, 163 | }, nil 164 | } 165 | -------------------------------------------------------------------------------- /modems/ubee/README.md: -------------------------------------------------------------------------------- 1 | # Ubee DOCSIS Modem 2 | 3 | 4 | ## Supported Modems 5 | 6 | The Ubee UBC1318, a DOCSIS modem used by Ziggo NL. 7 | 8 | It is unknown if this processor works on non Ziggo provided modems or other modems from Ubee. 9 | 10 | 11 | ## Fetching the Data 12 | 13 | The Ubee modem exposes statistics over its web interface on a page which requires no authentication. 14 | A string containing JSON is stored on this page and parsed to provide the statistics overview. 15 | 16 | This can be accessed at: 17 | 18 | ``` 19 | http://$ROUTER_IP/htdocs/cm_info_connection.php 20 | ``` 21 | 22 | ## Interpreting the Data 23 | 24 | Within the HTML contents there are a few variables in inline Javascript which we care about. 25 | 26 | * `ds_modulation` - A map of modulation IDs to strings (used in downstream channels). 27 | * `us_modulation` - A map of modulation IDs to strings (used in upstream channels). 28 | * `ifType` - A map of interface schemes to strings (used on all channels). 29 | * `cm_conn_json` - A string of a JSON array of active channels in the DOCSIS bond. 30 | 31 | Within this processor, it's assumed the modulation and type maps are unchanging and these values are not dynamically loaded. 32 | 33 | 34 | ### `cm_conn_json` JSON Object 35 | 36 | The JSON object contains many named fields, all with string values (except the channel objects arrays) regardless of the type. 37 | 38 | * `cm_conn_ds_gourpObj` - An array of downstream channels 39 | * `cm_conn_us_gourpObj` - An array of upstream channels 40 | 41 | 42 | #### Downstream 43 | 44 | Each object in the array contains the following fields: 45 | 46 | * `ds_type` - The interface scheme, mapped in `ifType`. 47 | * `ds_id` - Channel ID. 48 | * `ds_freq` - Channel frequency in Hz. 49 | * `ds_width` - Channel width. 50 | * `ds_power` - Channel power in dBmV. 51 | * `ds_snr` - Signal to noise ratio in dB. 52 | Note on 3.0 channels this is multipled by 10 and provided as an int. 53 | * `ds_modulation` - Channel modulation, mapped in `ds_modulation`. 54 | * `ds_correct` - Corrected codeword count. 55 | * `ds_uncorrect` - Uncorrectable codewords count. 56 | 57 | 58 | #### Upstream 59 | 60 | * `us_status` - Status of the channel (Locked or not 0/1). 61 | * `us_type` - The interface scheme, mapped in `ifType`. 62 | * `us_id` - Channel ID. 63 | * `us_freq` - Channel frequency in Hz. 64 | * `us_width` - Channel width. 65 | * `us_power` - Channel power in dBmV. 66 | * `us_modulation` - Channel modulation, mapped in `us_modulation`. 67 | -------------------------------------------------------------------------------- /modems/ubee/ubee.go: -------------------------------------------------------------------------------- 1 | package ubee 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "regexp" 7 | 8 | "github.com/msh100/modem-stats/utils" 9 | ) 10 | 11 | type Modem struct { 12 | IPAddress string 13 | Stats []byte 14 | FetchTime int64 15 | } 16 | 17 | func (ubee *Modem) ClearStats() { 18 | ubee.Stats = nil 19 | } 20 | 21 | func (ubee *Modem) Type() string { 22 | return utils.TypeDocsis 23 | } 24 | 25 | func (ubee *Modem) fetchURL() string { 26 | if ubee.IPAddress == "" { 27 | ubee.IPAddress = "192.168.100.1" 28 | } 29 | return fmt.Sprintf("http://%s/htdocs/cm_info_connection.php", ubee.IPAddress) 30 | } 31 | 32 | type dsChannel struct { 33 | Type int `json:"ds_type,string"` 34 | ID int `json:"ds_id,string"` 35 | Frequency int `json:"ds_freq,string"` 36 | Width int `json:"ds_width,string"` 37 | Power int `json:"ds_power,string"` 38 | SNR float32 `json:"ds_snr,string"` 39 | Modulation int `json:"ds_modulation,string"` 40 | PreRS int `json:"ds_correct,string"` 41 | PostRS int `json:"ds_uncorrect,string"` 42 | } 43 | 44 | type usChannel struct { 45 | Status int `json:"us_status,string"` 46 | Type int `json:"us_type,string"` 47 | ID int `json:"us_id,string"` 48 | Frequency int `json:"us_freq,string"` 49 | Width int `json:"us_width,string"` 50 | Power int `json:"us_power,string"` 51 | Modulation int `json:"us_modulation,string"` 52 | } 53 | 54 | type resultsStruct struct { 55 | DownstreamChannels []dsChannel `json:"cm_conn_ds_gourpObj"` 56 | UpstreamChannels []usChannel `json:"cm_conn_us_gourpObj"` 57 | } 58 | 59 | func (ubee *Modem) extractStats() resultsStruct { 60 | var re = regexp.MustCompile(`var cm_conn_json = '([^']+)';`) 61 | match := re.FindAllStringSubmatch(string(ubee.Stats), 1) 62 | 63 | var results resultsStruct 64 | json.Unmarshal([]byte(match[0][1]), &results) 65 | 66 | return results 67 | } 68 | 69 | func (ubee *Modem) ParseStats() (utils.ModemStats, error) { 70 | if ubee.Stats == nil { 71 | var err error 72 | ubee.Stats, ubee.FetchTime, err = utils.SimpleHTTPFetch(ubee.fetchURL()) 73 | if err != nil { 74 | return utils.ModemStats{}, err 75 | } 76 | } 77 | 78 | results := ubee.extractStats() 79 | var downChannels []utils.ModemChannel 80 | var upChannels []utils.ModemChannel 81 | 82 | var downModulationMap = []string{ 83 | 1: "Unknown", 84 | 2: "OFDM-PLC", 85 | 3: "QAM64", 86 | 4: "QAM256", 87 | 5: "QAM16", 88 | 6: "ALL", 89 | 7: "QAM1024", 90 | 8: "QAM512", 91 | } 92 | 93 | var interfaceTypeMap = []string{ 94 | 128: "SC-QAM", 95 | 129: "ATDMA", 96 | 277: "OFDM", 97 | 278: "OFDMA", 98 | } 99 | 100 | for id, downChannelData := range results.DownstreamChannels { 101 | if downChannelData.Type == 277 { 102 | downChannelData.SNR = downChannelData.SNR * 10 103 | } 104 | snr := int(downChannelData.SNR) 105 | 106 | downChannels = append(downChannels, utils.ModemChannel{ 107 | ChannelID: downChannelData.ID, 108 | Channel: id + 1, 109 | Frequency: downChannelData.Frequency, 110 | Snr: snr, 111 | Power: downChannelData.Power, 112 | Prerserr: downChannelData.PreRS, 113 | Postrserr: downChannelData.PostRS, 114 | Modulation: downModulationMap[downChannelData.Modulation], 115 | Scheme: interfaceTypeMap[downChannelData.Type], 116 | }) 117 | } 118 | 119 | for id, upChannelData := range results.UpstreamChannels { 120 | upChannels = append(upChannels, utils.ModemChannel{ 121 | ChannelID: upChannelData.ID, 122 | Channel: id + 1, 123 | Frequency: upChannelData.Frequency, 124 | Power: upChannelData.Power, 125 | }) 126 | } 127 | 128 | return utils.ModemStats{ 129 | Configs: []utils.ModemConfig{}, 130 | UpChannels: upChannels, 131 | DownChannels: downChannels, 132 | FetchTime: ubee.FetchTime, 133 | ModemType: utils.TypeDocsis, 134 | }, nil 135 | } 136 | -------------------------------------------------------------------------------- /outputs/influx.go: -------------------------------------------------------------------------------- 1 | package outputs 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/msh100/modem-stats/utils" 8 | ) 9 | 10 | func PrintForInflux(routerStats utils.ModemStats) { 11 | for _, downChannel := range routerStats.DownChannels { 12 | var keys []string 13 | var values []string 14 | 15 | if routerStats.ModemType == utils.TypeVDSL { 16 | keys = append(keys, fmt.Sprintf("id=%d", downChannel.ChannelID)) 17 | values = append( 18 | values, 19 | fmt.Sprintf("noise=%d", downChannel.Noise), 20 | fmt.Sprintf("attenuation=%d", downChannel.Attenuation), 21 | ) 22 | } else { 23 | keys = append( 24 | keys, 25 | fmt.Sprintf("channel=%d", downChannel.Channel), 26 | fmt.Sprintf("id=%d", downChannel.ChannelID), 27 | fmt.Sprintf("modulation=%s", downChannel.Modulation), 28 | fmt.Sprintf("scheme=%s", downChannel.Scheme), 29 | ) 30 | values = append( 31 | values, 32 | fmt.Sprintf("frequency=%d", downChannel.Frequency), 33 | fmt.Sprintf("snr=%d", downChannel.Snr), 34 | fmt.Sprintf("power=%d", downChannel.Power), 35 | fmt.Sprintf("prerserr=%d", downChannel.Prerserr), 36 | fmt.Sprintf("postrserr=%d", downChannel.Postrserr), 37 | ) 38 | } 39 | 40 | output := fmt.Sprintf( 41 | "downstream,%s %s", 42 | strings.Join(keys, ","), 43 | strings.Join(values, ","), 44 | ) 45 | fmt.Println(output) 46 | } 47 | for _, upChannel := range routerStats.UpChannels { 48 | var keys []string 49 | var values []string 50 | 51 | if routerStats.ModemType == utils.TypeVDSL { 52 | keys = append(keys, fmt.Sprintf("id=%d", upChannel.ChannelID)) 53 | values = append( 54 | values, 55 | fmt.Sprintf("noise=%d", upChannel.Noise), 56 | fmt.Sprintf("attenuation=%d", upChannel.Attenuation), 57 | ) 58 | } else { 59 | keys = append( 60 | keys, 61 | fmt.Sprintf("channel=%d", upChannel.Channel), 62 | fmt.Sprintf("id=%d", upChannel.ChannelID), 63 | ) 64 | values = append( 65 | values, 66 | fmt.Sprintf("frequency=%d", upChannel.Frequency), 67 | fmt.Sprintf("power=%d", upChannel.Power), 68 | ) 69 | } 70 | 71 | output := fmt.Sprintf( 72 | "upstream,%s %s", 73 | strings.Join(keys, ","), 74 | strings.Join(values, ","), 75 | ) 76 | fmt.Println(output) 77 | } 78 | for _, config := range routerStats.Configs { 79 | values := []string{ 80 | fmt.Sprintf("maxrate=%d", config.Maxrate), 81 | } 82 | if config.Maxburst != 0 { 83 | values = append(values, fmt.Sprintf("maxburst=%d", config.Maxburst)) 84 | } 85 | 86 | output := fmt.Sprintf( 87 | "config,config=%s %s", 88 | config.Config, 89 | strings.Join(values, ","), 90 | ) 91 | fmt.Println(output) 92 | } 93 | 94 | fmt.Println(fmt.Sprintf("shstatsinfo timems=%d", routerStats.FetchTime)) 95 | } 96 | -------------------------------------------------------------------------------- /outputs/prometheus.go: -------------------------------------------------------------------------------- 1 | package outputs 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "net/http" 7 | "strconv" 8 | 9 | "github.com/msh100/modem-stats/utils" 10 | "github.com/prometheus/client_golang/prometheus" 11 | "github.com/prometheus/client_golang/prometheus/promhttp" 12 | ) 13 | 14 | type PrometheusExporter struct { 15 | downFrequency *prometheus.Desc 16 | downPower *prometheus.Desc 17 | downSNR *prometheus.Desc 18 | downPreRS *prometheus.Desc 19 | downPostRS *prometheus.Desc 20 | upFrequency *prometheus.Desc 21 | upPower *prometheus.Desc 22 | maxrate *prometheus.Desc 23 | maxburst *prometheus.Desc 24 | fetchtime *prometheus.Desc 25 | downNoise *prometheus.Desc 26 | downAttenuation *prometheus.Desc 27 | upNoise *prometheus.Desc 28 | upAttenuation *prometheus.Desc 29 | 30 | docsisModem utils.DocsisModem 31 | } 32 | 33 | func (p *PrometheusExporter) Collect(ch chan<- prometheus.Metric) { 34 | utils.ResetStats(p.docsisModem) 35 | modemStats, _ := utils.FetchStats(p.docsisModem) 36 | 37 | for _, c := range modemStats.DownChannels { 38 | var labels []string 39 | 40 | if modemStats.ModemType == utils.TypeVDSL { 41 | labels = []string{ 42 | strconv.Itoa(c.ChannelID), 43 | } 44 | 45 | ch <- prometheus.MustNewConstMetric( 46 | p.downNoise, 47 | prometheus.GaugeValue, 48 | float64(c.Noise), 49 | labels..., 50 | ) 51 | ch <- prometheus.MustNewConstMetric( 52 | p.downAttenuation, 53 | prometheus.GaugeValue, 54 | float64(c.Attenuation), 55 | labels..., 56 | ) 57 | } else { 58 | labels = []string{ 59 | strconv.Itoa(c.Channel), 60 | strconv.Itoa(c.ChannelID), 61 | c.Modulation, 62 | c.Scheme, 63 | } 64 | 65 | ch <- prometheus.MustNewConstMetric( 66 | p.downFrequency, 67 | prometheus.GaugeValue, 68 | float64(c.Frequency), 69 | labels..., 70 | ) 71 | ch <- prometheus.MustNewConstMetric( 72 | p.downPower, 73 | prometheus.GaugeValue, 74 | float64(c.Power), 75 | labels..., 76 | ) 77 | ch <- prometheus.MustNewConstMetric( 78 | p.downSNR, 79 | prometheus.GaugeValue, 80 | float64(c.Snr), 81 | labels..., 82 | ) 83 | ch <- prometheus.MustNewConstMetric( 84 | p.downPreRS, 85 | prometheus.GaugeValue, 86 | float64(c.Prerserr), 87 | labels..., 88 | ) 89 | ch <- prometheus.MustNewConstMetric( 90 | p.downPostRS, 91 | prometheus.GaugeValue, 92 | float64(c.Postrserr), 93 | labels..., 94 | ) 95 | } 96 | } 97 | 98 | for _, c := range modemStats.UpChannels { 99 | var labels []string 100 | 101 | if modemStats.ModemType == utils.TypeVDSL { 102 | labels = []string{ 103 | strconv.Itoa(c.ChannelID), 104 | } 105 | 106 | ch <- prometheus.MustNewConstMetric( 107 | p.upNoise, 108 | prometheus.GaugeValue, 109 | float64(c.Noise), 110 | labels..., 111 | ) 112 | ch <- prometheus.MustNewConstMetric( 113 | p.upAttenuation, 114 | prometheus.GaugeValue, 115 | float64(c.Attenuation), 116 | labels..., 117 | ) 118 | } else { 119 | labels = []string{ 120 | strconv.Itoa(c.Channel), 121 | strconv.Itoa(c.ChannelID), 122 | } 123 | 124 | ch <- prometheus.MustNewConstMetric( 125 | p.upPower, 126 | prometheus.GaugeValue, 127 | float64(c.Power), 128 | labels..., 129 | ) 130 | ch <- prometheus.MustNewConstMetric( 131 | p.upFrequency, 132 | prometheus.GaugeValue, 133 | float64(c.Frequency), 134 | labels..., 135 | ) 136 | } 137 | } 138 | 139 | for _, config := range modemStats.Configs { 140 | ch <- prometheus.MustNewConstMetric( 141 | p.maxrate, 142 | prometheus.GaugeValue, 143 | float64(config.Maxrate), 144 | config.Config, 145 | ) 146 | if config.Maxburst != 0 { 147 | ch <- prometheus.MustNewConstMetric( 148 | p.maxburst, 149 | prometheus.GaugeValue, 150 | float64(config.Maxburst), 151 | config.Config, 152 | ) 153 | } 154 | } 155 | 156 | ch <- prometheus.MustNewConstMetric( 157 | p.fetchtime, 158 | prometheus.GaugeValue, 159 | float64(modemStats.FetchTime), 160 | ) 161 | } 162 | 163 | func (p *PrometheusExporter) Describe(ch chan<- *prometheus.Desc) { 164 | ch <- p.downFrequency 165 | ch <- p.upFrequency 166 | ch <- p.downPower 167 | ch <- p.upPower 168 | ch <- p.downSNR 169 | ch <- p.downPostRS 170 | ch <- p.downPreRS 171 | ch <- p.maxrate 172 | ch <- p.maxburst 173 | ch <- p.fetchtime 174 | ch <- p.downNoise 175 | ch <- p.downAttenuation 176 | ch <- p.upNoise 177 | ch <- p.upAttenuation 178 | } 179 | 180 | func ProExporter(docsisModem utils.DocsisModem) *PrometheusExporter { 181 | namespace := "modemstats" 182 | downLabels := []string{} 183 | upLabels := []string{} 184 | 185 | if docsisModem.Type() == utils.TypeVDSL { 186 | downLabels = []string{"id"} 187 | upLabels = []string{"id"} 188 | } else { 189 | downLabels = []string{"channel", "id", "modulation", "scheme"} 190 | upLabels = []string{"channel", "id"} 191 | } 192 | 193 | return &PrometheusExporter{ 194 | docsisModem: docsisModem, 195 | downFrequency: prometheus.NewDesc( 196 | prometheus.BuildFQName(namespace, "downstream", "frequency"), 197 | "Downstream Frequency in HZ", 198 | downLabels, 199 | nil, 200 | ), 201 | downPower: prometheus.NewDesc( 202 | prometheus.BuildFQName(namespace, "downstream", "power"), 203 | "Downstream Power level in dBmv", 204 | downLabels, 205 | nil, 206 | ), 207 | downSNR: prometheus.NewDesc( 208 | prometheus.BuildFQName(namespace, "downstream", "snr"), 209 | "Downstream SNR in dB", 210 | downLabels, 211 | nil, 212 | ), 213 | downPostRS: prometheus.NewDesc( 214 | prometheus.BuildFQName(namespace, "downstream", "postrserr"), 215 | "Number of Errors per channel Post RS", 216 | downLabels, 217 | nil, 218 | ), 219 | downPreRS: prometheus.NewDesc( 220 | prometheus.BuildFQName(namespace, "downstream", "prerserr"), 221 | "Number of Errors per channel Pre RS", 222 | downLabels, 223 | nil, 224 | ), 225 | downAttenuation: prometheus.NewDesc( 226 | prometheus.BuildFQName(namespace, "downstream", "attenuation"), 227 | "Downstream attenuation in TODO: wtf is this?", 228 | downLabels, 229 | nil, 230 | ), 231 | downNoise: prometheus.NewDesc( 232 | prometheus.BuildFQName(namespace, "downstream", "noise"), 233 | "Downstream noise level in dB", 234 | downLabels, 235 | nil, 236 | ), 237 | upFrequency: prometheus.NewDesc( 238 | prometheus.BuildFQName(namespace, "upstream", "frequency"), 239 | "Upstream Frequency in HZ", 240 | upLabels, 241 | nil, 242 | ), 243 | upPower: prometheus.NewDesc( 244 | prometheus.BuildFQName(namespace, "upstream", "power"), 245 | "Upstream Power level in dBmv", 246 | upLabels, 247 | nil, 248 | ), 249 | upAttenuation: prometheus.NewDesc( 250 | prometheus.BuildFQName(namespace, "upstream", "attenuation"), 251 | "Upstream attenuation in TODO: wtf is this?", 252 | downLabels, 253 | nil, 254 | ), 255 | upNoise: prometheus.NewDesc( 256 | prometheus.BuildFQName(namespace, "upstream", "noise"), 257 | "Upstream noise level in dB", 258 | downLabels, 259 | nil, 260 | ), 261 | maxrate: prometheus.NewDesc( 262 | prometheus.BuildFQName(namespace, "config", "maxrate"), 263 | "Maximum link rate", 264 | []string{"config"}, 265 | nil, 266 | ), 267 | maxburst: prometheus.NewDesc( 268 | prometheus.BuildFQName(namespace, "config", "maxburst"), 269 | "Maximum link burst rate", 270 | []string{"config"}, 271 | nil, 272 | ), 273 | fetchtime: prometheus.NewDesc( 274 | prometheus.BuildFQName(namespace, "shstatsinfo", "timems"), 275 | "Time to fetch statistics from the modem in milliseconds", 276 | []string{}, 277 | nil, 278 | ), 279 | } 280 | } 281 | 282 | func Prometheus(modem utils.DocsisModem, port int) { 283 | prometheus.Unregister(prometheus.NewGoCollector()) 284 | exporter := ProExporter(modem) 285 | prometheus.MustRegister(exporter) 286 | 287 | http.Handle("/metrics", promhttp.Handler()) 288 | fmt.Println(fmt.Sprintf("Starting Prometheus exporter on port %d", port)) 289 | log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil)) 290 | } 291 | -------------------------------------------------------------------------------- /utils/tools.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "crypto/md5" 5 | "fmt" 6 | "io/ioutil" 7 | "math/rand" 8 | "net/http" 9 | "os" 10 | "strconv" 11 | "strings" 12 | "time" 13 | 14 | "github.com/Jeffail/gabs/v2" 15 | ) 16 | 17 | func SimpleHTTPFetch(url string) ([]byte, int64, error) { 18 | timeStart := time.Now().UnixNano() / int64(time.Millisecond) 19 | resp, err := http.Get(url) 20 | if err != nil { 21 | return nil, 0, err 22 | } 23 | if resp.StatusCode != 200 { 24 | return nil, 0, fmt.Errorf("%d status code recieved", resp.StatusCode) 25 | } 26 | 27 | stats, err := ioutil.ReadAll(resp.Body) 28 | if err != nil { 29 | return nil, 0, err 30 | } 31 | fetchTime := (time.Now().UnixNano() / int64(time.Millisecond)) - timeStart 32 | return stats, fetchTime, nil 33 | } 34 | 35 | func RandomInt(min int, max int) int { 36 | rand.Seed(time.Now().UnixNano()) 37 | random := rand.Intn(max-min) + min 38 | return random 39 | } 40 | 41 | func StringToMD5(input string) string { 42 | return fmt.Sprintf("%x", md5.Sum([]byte(input))) 43 | } 44 | 45 | func GabsInt(input *gabs.Container, path string) int { 46 | output, _ := strconv.Atoi(input.Path(path).String()) 47 | return output 48 | } 49 | 50 | func GabsFloat(input *gabs.Container, path string) float64 { 51 | output, _ := strconv.ParseFloat(input.Path(path).String(), 64) 52 | return output 53 | } 54 | 55 | func GabsString(input *gabs.Container, path string) string { 56 | output := input.Path(path).String() 57 | return strings.Trim(output, "\"") 58 | } 59 | 60 | func Getenv(key, fallback string) string { 61 | value := os.Getenv(key) 62 | if len(value) == 0 { 63 | return fallback 64 | } 65 | return value 66 | } 67 | 68 | func FetchStats(router DocsisModem) (ModemStats, error) { 69 | stats, err := router.ParseStats() 70 | return stats, err 71 | } 72 | 73 | func ResetStats(router DocsisModem) { 74 | router.ClearStats() 75 | } 76 | 77 | type HttpResult struct { 78 | Index int 79 | Res http.Response 80 | Err error 81 | } 82 | 83 | func BoundedParallelGet(urls []string, concurrencyLimit int) []HttpResult { 84 | semaphoreChan := make(chan struct{}, concurrencyLimit) 85 | resultsChan := make(chan *HttpResult) 86 | 87 | defer func() { 88 | close(semaphoreChan) 89 | close(resultsChan) 90 | }() 91 | 92 | for i, url := range urls { 93 | go func(i int, url string) { 94 | semaphoreChan <- struct{}{} 95 | res, err := http.Get(url) 96 | result := &HttpResult{i, *res, err} 97 | resultsChan <- result 98 | <-semaphoreChan 99 | }(i, url) 100 | } 101 | 102 | var results []HttpResult 103 | for { 104 | result := <-resultsChan 105 | results = append(results, *result) 106 | if len(results) == len(urls) { 107 | break 108 | } 109 | } 110 | 111 | return results 112 | } 113 | 114 | func ExtractIntValue(valueWithUnit string) int { 115 | parts := strings.Split(valueWithUnit, " ") 116 | if len(parts) > 0 { 117 | intValue, err := strconv.Atoi(parts[0]) 118 | if err == nil { 119 | return intValue 120 | } 121 | } 122 | return 0 123 | } 124 | 125 | func ExtractFloatValue(valueWithUnit string) float64 { 126 | parts := strings.Split(valueWithUnit, " ") 127 | if len(parts) > 0 { 128 | floatValue, err := strconv.ParseFloat(parts[0], 64) 129 | if err == nil { 130 | return floatValue 131 | } 132 | } 133 | return 0.0 134 | } 135 | -------------------------------------------------------------------------------- /utils/types.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | type ModemChannel struct { 4 | ChannelID int 5 | Channel int 6 | Frequency int 7 | Snr int 8 | Power int 9 | Prerserr int 10 | Postrserr int 11 | Modulation string 12 | Scheme string 13 | 14 | Noise int 15 | Attenuation int 16 | } 17 | 18 | type ModemConfig struct { 19 | Config string 20 | Maxrate int 21 | Maxburst int 22 | } 23 | 24 | type ModemStats struct { 25 | Configs []ModemConfig 26 | UpChannels []ModemChannel 27 | DownChannels []ModemChannel 28 | FetchTime int64 29 | ModemType string 30 | } 31 | 32 | type DocsisModem interface { 33 | ParseStats() (ModemStats, error) 34 | ClearStats() 35 | Type() string 36 | } 37 | 38 | const ( 39 | TypeDocsis = "DOCSIS" 40 | TypeVDSL = "VDSL" 41 | ) 42 | --------------------------------------------------------------------------------