From 3ea7308af0061341211d3a550881847f5e06591a Mon Sep 17 00:00:00 2001 From: Olek Date: Thu, 11 Sep 2025 22:26:30 +0200 Subject: [PATCH] Attempt 1 --- .gitignore | 1 + AppServer/.env | 34 + AppServer/Dockerfile | 31 + AppServer/Makefile | 40 + AppServer/README.md | 61 + AppServer/certs/ca.pem | 30 + AppServer/certs/client.key | 28 + AppServer/certs/client.pem | 25 + AppServer/docker-compose.yml | 39 + AppServer/init.sql | 122 ++ AppServer/postgresql.conf | 3 + AppServer/src/api.go | 180 +++ .../src/app_comm/api/change/change.pb.go | 278 ++++ .../src/app_comm/api/change/change_grpc.pb.go | 178 +++ .../src/app_comm/api/common/common.pb.go | 588 +++++++++ .../src/app_comm/api/device/device.pb.go | 566 ++++++++ .../src/app_comm/api/device/device_grpc.pb.go | 468 +++++++ AppServer/src/app_comm/api/log/log.pb.go | 81 ++ AppServer/src/app_comm/api/log/log_grpc.pb.go | 144 +++ .../src/app_comm/api/message/message.pb.go | 267 ++++ .../app_comm/api/message/message_grpc.pb.go | 178 +++ .../src/app_comm/api/nfccard/nfccard.pb.go | 168 +++ .../app_comm/api/nfccard/nfccard_grpc.pb.go | 180 +++ .../app_comm/api/permission/permission.pb.go | 181 +++ .../api/permission/permission_grpc.pb.go | 180 +++ AppServer/src/app_comm/api/role/role.pb.go | 184 +++ .../src/app_comm/api/role/role_grpc.pb.go | 216 ++++ .../src/app_comm/api/status/status.pb.go | 180 +++ .../src/app_comm/api/status/status_grpc.pb.go | 180 +++ AppServer/src/app_comm/api/user/user.pb.go | 384 ++++++ .../src/app_comm/api/user/user_grpc.pb.go | 360 ++++++ AppServer/src/app_comm/proto/change.proto | 30 + AppServer/src/app_comm/proto/common.proto | 47 + AppServer/src/app_comm/proto/device.proto | 65 + AppServer/src/app_comm/proto/log.proto | 16 + AppServer/src/app_comm/proto/message.proto | 29 + AppServer/src/app_comm/proto/nfccard.proto | 24 + AppServer/src/app_comm/proto/permission.proto | 24 + AppServer/src/app_comm/proto/role.proto | 25 + AppServer/src/app_comm/proto/status.proto | 26 + AppServer/src/app_comm/proto/user.proto | 43 + AppServer/src/go.mod | 28 + AppServer/src/go.sum | 70 + AppServer/src/main.go | 439 +++++++ AppServer/src/serder/serder.go | 312 +++++ AppServer/tarball.tar.gz | Bin 0 -> 41772 bytes Chirpstack_v4/LICENSE | 22 + Chirpstack_v4/Makefile | 5 + Chirpstack_v4/README.md | 99 ++ Chirpstack_v4/certs/ca.key | 52 + Chirpstack_v4/certs/ca.pem | 30 + Chirpstack_v4/certs/cert-gen.sh | 41 + Chirpstack_v4/certs/client.csr | 15 + Chirpstack_v4/certs/client.key | 28 + Chirpstack_v4/certs/client.pem | 25 + Chirpstack_v4/certs/client_ext.cnf | 3 + Chirpstack_v4/certs/server.csr | 15 + Chirpstack_v4/certs/server.key | 28 + Chirpstack_v4/certs/server.pem | 25 + Chirpstack_v4/certs/server_ext.cnf | 4 + ...ack-gateway-bridge-basicstation-as923.toml | 45 + ...k-gateway-bridge-basicstation-as923_2.toml | 45 + ...k-gateway-bridge-basicstation-as923_3.toml | 45 + ...k-gateway-bridge-basicstation-as923_4.toml | 45 + ...k-gateway-bridge-basicstation-au915_0.toml | 45 + ...k-gateway-bridge-basicstation-au915_1.toml | 45 + ...k-gateway-bridge-basicstation-au915_2.toml | 45 + ...k-gateway-bridge-basicstation-au915_3.toml | 45 + ...k-gateway-bridge-basicstation-au915_4.toml | 45 + ...k-gateway-bridge-basicstation-au915_5.toml | 45 + ...k-gateway-bridge-basicstation-au915_6.toml | 45 + ...k-gateway-bridge-basicstation-au915_7.toml | 45 + ...k-gateway-bridge-basicstation-cn470_0.toml | 40 + ...k-gateway-bridge-basicstation-cn470_1.toml | 40 + ...-gateway-bridge-basicstation-cn470_10.toml | 40 + ...-gateway-bridge-basicstation-cn470_11.toml | 40 + ...k-gateway-bridge-basicstation-cn470_2.toml | 40 + ...k-gateway-bridge-basicstation-cn470_3.toml | 40 + ...k-gateway-bridge-basicstation-cn470_4.toml | 40 + ...k-gateway-bridge-basicstation-cn470_5.toml | 40 + ...k-gateway-bridge-basicstation-cn470_6.toml | 40 + ...k-gateway-bridge-basicstation-cn470_7.toml | 40 + ...k-gateway-bridge-basicstation-cn470_8.toml | 40 + ...k-gateway-bridge-basicstation-cn470_9.toml | 40 + ...ack-gateway-bridge-basicstation-eu433.toml | 35 + ...ack-gateway-bridge-basicstation-eu868.toml | 45 + ...ack-gateway-bridge-basicstation-in865.toml | 35 + ...ack-gateway-bridge-basicstation-kr920.toml | 35 + ...ack-gateway-bridge-basicstation-ru864.toml | 34 + ...k-gateway-bridge-basicstation-us915_0.toml | 45 + ...k-gateway-bridge-basicstation-us915_1.toml | 45 + ...k-gateway-bridge-basicstation-us915_2.toml | 45 + ...k-gateway-bridge-basicstation-us915_3.toml | 45 + ...k-gateway-bridge-basicstation-us915_4.toml | 45 + ...k-gateway-bridge-basicstation-us915_5.toml | 45 + ...k-gateway-bridge-basicstation-us915_6.toml | 45 + ...k-gateway-bridge-basicstation-us915_7.toml | 45 + .../chirpstack-gateway-bridge.toml | 46 + .../configuration/chirpstack/chirpstack.toml | 204 +++ .../chirpstack/region_as923.toml | 204 +++ .../chirpstack/region_as923_2.toml | 204 +++ .../chirpstack/region_as923_3.toml | 204 +++ .../chirpstack/region_as923_4.toml | 204 +++ .../chirpstack/region_au915_0.toml | 253 ++++ .../chirpstack/region_au915_1.toml | 253 ++++ .../chirpstack/region_au915_2.toml | 253 ++++ .../chirpstack/region_au915_3.toml | 253 ++++ .../chirpstack/region_au915_4.toml | 253 ++++ .../chirpstack/region_au915_5.toml | 253 ++++ .../chirpstack/region_au915_6.toml | 253 ++++ .../chirpstack/region_au915_7.toml | 253 ++++ .../chirpstack/region_cn470_0.toml | 247 ++++ .../chirpstack/region_cn470_1.toml | 247 ++++ .../chirpstack/region_cn470_10.toml | 247 ++++ .../chirpstack/region_cn470_11.toml | 247 ++++ .../chirpstack/region_cn470_2.toml | 247 ++++ .../chirpstack/region_cn470_3.toml | 247 ++++ .../chirpstack/region_cn470_4.toml | 247 ++++ .../chirpstack/region_cn470_5.toml | 247 ++++ .../chirpstack/region_cn470_6.toml | 247 ++++ .../chirpstack/region_cn470_7.toml | 247 ++++ .../chirpstack/region_cn470_8.toml | 247 ++++ .../chirpstack/region_cn470_9.toml | 247 ++++ .../chirpstack/region_cn779.toml | 210 +++ .../chirpstack/region_eu433.toml | 210 +++ .../chirpstack/region_eu868.toml | 280 ++++ .../chirpstack/region_in865.toml | 210 +++ .../chirpstack/region_ism2400.toml | 210 +++ .../chirpstack/region_kr920.toml | 210 +++ .../chirpstack/region_ru864.toml | 204 +++ .../chirpstack/region_us915_0.toml | 253 ++++ .../chirpstack/region_us915_1.toml | 253 ++++ .../chirpstack/region_us915_2.toml | 253 ++++ .../chirpstack/region_us915_3.toml | 253 ++++ .../chirpstack/region_us915_4.toml | 253 ++++ .../chirpstack/region_us915_5.toml | 253 ++++ .../chirpstack/region_us915_6.toml | 253 ++++ .../chirpstack/region_us915_7.toml | 253 ++++ .../mosquitto/config/mosquitto.conf | 13 + .../initdb/001-chirpstack_extensions.sh | 7 + Chirpstack_v4/docker-compose.yml | 109 ++ Chirpstack_v4/tarball.tar.gz | Bin 0 -> 28090 bytes WebApp/.env | 36 + WebApp/Dockerfile | 35 + WebApp/LICENCE | 38 + WebApp/Makefile | 23 + WebApp/README.md | 29 + WebApp/build/stylesheet.css | 2 + WebApp/docker-compose.yml | 13 + WebApp/package-lock.json | 1133 +++++++++++++++++ WebApp/package.json | 6 + WebApp/page_list.md | 19 + WebApp/src/layouts/components/footer.tmpl | 44 + WebApp/src/layouts/components/meta.tmpl | 8 + WebApp/src/layouts/components/navbar.tmpl | 69 + WebApp/src/layouts/index.tmpl | 51 + WebApp/src/layouts/pages/home.tmpl | 5 + WebApp/src/layouts/pages/login.tmpl | 11 + WebApp/src/layouts/styles/global.css | 79 ++ WebApp/src/main/go.mod | 48 + WebApp/src/main/go.sum | 132 ++ WebApp/src/main/main.go | 271 ++++ WebApp/src/main/pager_api/change/change.pb.go | 278 ++++ .../main/pager_api/change/change_grpc.pb.go | 178 +++ WebApp/src/main/pager_api/common/common.pb.go | 588 +++++++++ WebApp/src/main/pager_api/device/device.pb.go | 566 ++++++++ .../main/pager_api/device/device_grpc.pb.go | 468 +++++++ WebApp/src/main/pager_api/log/log.pb.go | 81 ++ WebApp/src/main/pager_api/log/log_grpc.pb.go | 144 +++ .../src/main/pager_api/message/message.pb.go | 267 ++++ .../main/pager_api/message/message_grpc.pb.go | 178 +++ .../src/main/pager_api/nfccard/nfccard.pb.go | 168 +++ .../main/pager_api/nfccard/nfccard_grpc.pb.go | 180 +++ .../pager_api/permission/permission.pb.go | 181 +++ .../permission/permission_grpc.pb.go | 180 +++ WebApp/src/main/pager_api/role/role.pb.go | 184 +++ .../src/main/pager_api/role/role_grpc.pb.go | 216 ++++ WebApp/src/main/pager_api/status/status.pb.go | 182 +++ .../main/pager_api/status/status_grpc.pb.go | 181 +++ WebApp/src/main/pager_api/user/user.pb.go | 386 ++++++ .../src/main/pager_api/user/user_grpc.pb.go | 361 ++++++ WebApp/tarball.tar.gz | Bin 0 -> 49350 bytes 182 files changed, 25449 insertions(+) create mode 100644 .gitignore create mode 100755 AppServer/.env create mode 100755 AppServer/Dockerfile create mode 100644 AppServer/Makefile create mode 100755 AppServer/README.md create mode 100644 AppServer/certs/ca.pem create mode 100644 AppServer/certs/client.key create mode 100644 AppServer/certs/client.pem create mode 100644 AppServer/docker-compose.yml create mode 100755 AppServer/init.sql create mode 100755 AppServer/postgresql.conf create mode 100644 AppServer/src/api.go create mode 100644 AppServer/src/app_comm/api/change/change.pb.go create mode 100644 AppServer/src/app_comm/api/change/change_grpc.pb.go create mode 100644 AppServer/src/app_comm/api/common/common.pb.go create mode 100644 AppServer/src/app_comm/api/device/device.pb.go create mode 100644 AppServer/src/app_comm/api/device/device_grpc.pb.go create mode 100644 AppServer/src/app_comm/api/log/log.pb.go create mode 100644 AppServer/src/app_comm/api/log/log_grpc.pb.go create mode 100644 AppServer/src/app_comm/api/message/message.pb.go create mode 100644 AppServer/src/app_comm/api/message/message_grpc.pb.go create mode 100644 AppServer/src/app_comm/api/nfccard/nfccard.pb.go create mode 100644 AppServer/src/app_comm/api/nfccard/nfccard_grpc.pb.go create mode 100644 AppServer/src/app_comm/api/permission/permission.pb.go create mode 100644 AppServer/src/app_comm/api/permission/permission_grpc.pb.go create mode 100644 AppServer/src/app_comm/api/role/role.pb.go create mode 100644 AppServer/src/app_comm/api/role/role_grpc.pb.go create mode 100644 AppServer/src/app_comm/api/status/status.pb.go create mode 100644 AppServer/src/app_comm/api/status/status_grpc.pb.go create mode 100644 AppServer/src/app_comm/api/user/user.pb.go create mode 100644 AppServer/src/app_comm/api/user/user_grpc.pb.go create mode 100644 AppServer/src/app_comm/proto/change.proto create mode 100644 AppServer/src/app_comm/proto/common.proto create mode 100644 AppServer/src/app_comm/proto/device.proto create mode 100644 AppServer/src/app_comm/proto/log.proto create mode 100644 AppServer/src/app_comm/proto/message.proto create mode 100644 AppServer/src/app_comm/proto/nfccard.proto create mode 100644 AppServer/src/app_comm/proto/permission.proto create mode 100644 AppServer/src/app_comm/proto/role.proto create mode 100644 AppServer/src/app_comm/proto/status.proto create mode 100644 AppServer/src/app_comm/proto/user.proto create mode 100755 AppServer/src/go.mod create mode 100755 AppServer/src/go.sum create mode 100755 AppServer/src/main.go create mode 100644 AppServer/src/serder/serder.go create mode 100644 AppServer/tarball.tar.gz create mode 100644 Chirpstack_v4/LICENSE create mode 100644 Chirpstack_v4/Makefile create mode 100644 Chirpstack_v4/README.md create mode 100644 Chirpstack_v4/certs/ca.key create mode 100644 Chirpstack_v4/certs/ca.pem create mode 100755 Chirpstack_v4/certs/cert-gen.sh create mode 100644 Chirpstack_v4/certs/client.csr create mode 100644 Chirpstack_v4/certs/client.key create mode 100644 Chirpstack_v4/certs/client.pem create mode 100644 Chirpstack_v4/certs/client_ext.cnf create mode 100644 Chirpstack_v4/certs/server.csr create mode 100644 Chirpstack_v4/certs/server.key create mode 100644 Chirpstack_v4/certs/server.pem create mode 100644 Chirpstack_v4/certs/server_ext.cnf create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-as923.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-as923_2.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-as923_3.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-as923_4.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-au915_0.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-au915_1.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-au915_2.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-au915_3.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-au915_4.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-au915_5.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-au915_6.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-au915_7.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-cn470_0.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-cn470_1.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-cn470_10.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-cn470_11.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-cn470_2.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-cn470_3.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-cn470_4.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-cn470_5.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-cn470_6.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-cn470_7.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-cn470_8.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-cn470_9.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-eu433.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-eu868.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-in865.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-kr920.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-ru864.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-us915_0.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-us915_1.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-us915_2.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-us915_3.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-us915_4.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-us915_5.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-us915_6.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-us915_7.toml create mode 100644 Chirpstack_v4/configuration/chirpstack-gateway-bridge/chirpstack-gateway-bridge.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/chirpstack.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_as923.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_as923_2.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_as923_3.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_as923_4.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_au915_0.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_au915_1.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_au915_2.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_au915_3.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_au915_4.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_au915_5.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_au915_6.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_au915_7.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_cn470_0.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_cn470_1.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_cn470_10.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_cn470_11.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_cn470_2.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_cn470_3.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_cn470_4.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_cn470_5.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_cn470_6.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_cn470_7.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_cn470_8.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_cn470_9.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_cn779.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_eu433.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_eu868.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_in865.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_ism2400.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_kr920.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_ru864.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_us915_0.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_us915_1.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_us915_2.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_us915_3.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_us915_4.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_us915_5.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_us915_6.toml create mode 100644 Chirpstack_v4/configuration/chirpstack/region_us915_7.toml create mode 100644 Chirpstack_v4/configuration/mosquitto/config/mosquitto.conf create mode 100755 Chirpstack_v4/configuration/postgresql/initdb/001-chirpstack_extensions.sh create mode 100644 Chirpstack_v4/docker-compose.yml create mode 100644 Chirpstack_v4/tarball.tar.gz create mode 100644 WebApp/.env create mode 100755 WebApp/Dockerfile create mode 100644 WebApp/LICENCE create mode 100644 WebApp/Makefile create mode 100644 WebApp/README.md create mode 100644 WebApp/build/stylesheet.css create mode 100644 WebApp/docker-compose.yml create mode 100644 WebApp/package-lock.json create mode 100644 WebApp/package.json create mode 100755 WebApp/page_list.md create mode 100644 WebApp/src/layouts/components/footer.tmpl create mode 100644 WebApp/src/layouts/components/meta.tmpl create mode 100644 WebApp/src/layouts/components/navbar.tmpl create mode 100644 WebApp/src/layouts/index.tmpl create mode 100644 WebApp/src/layouts/pages/home.tmpl create mode 100644 WebApp/src/layouts/pages/login.tmpl create mode 100644 WebApp/src/layouts/styles/global.css create mode 100644 WebApp/src/main/go.mod create mode 100644 WebApp/src/main/go.sum create mode 100644 WebApp/src/main/main.go create mode 100644 WebApp/src/main/pager_api/change/change.pb.go create mode 100644 WebApp/src/main/pager_api/change/change_grpc.pb.go create mode 100644 WebApp/src/main/pager_api/common/common.pb.go create mode 100644 WebApp/src/main/pager_api/device/device.pb.go create mode 100644 WebApp/src/main/pager_api/device/device_grpc.pb.go create mode 100644 WebApp/src/main/pager_api/log/log.pb.go create mode 100644 WebApp/src/main/pager_api/log/log_grpc.pb.go create mode 100644 WebApp/src/main/pager_api/message/message.pb.go create mode 100644 WebApp/src/main/pager_api/message/message_grpc.pb.go create mode 100644 WebApp/src/main/pager_api/nfccard/nfccard.pb.go create mode 100644 WebApp/src/main/pager_api/nfccard/nfccard_grpc.pb.go create mode 100644 WebApp/src/main/pager_api/permission/permission.pb.go create mode 100644 WebApp/src/main/pager_api/permission/permission_grpc.pb.go create mode 100644 WebApp/src/main/pager_api/role/role.pb.go create mode 100644 WebApp/src/main/pager_api/role/role_grpc.pb.go create mode 100644 WebApp/src/main/pager_api/status/status.pb.go create mode 100644 WebApp/src/main/pager_api/status/status_grpc.pb.go create mode 100644 WebApp/src/main/pager_api/user/user.pb.go create mode 100644 WebApp/src/main/pager_api/user/user_grpc.pb.go create mode 100644 WebApp/tarball.tar.gz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..049f0f5 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +WebApp/node_modules \ No newline at end of file diff --git a/AppServer/.env b/AppServer/.env new file mode 100755 index 0000000..4215f1d --- /dev/null +++ b/AppServer/.env @@ -0,0 +1,34 @@ +# Docker compose config file +# PostgreSQL settings +DB_USER=admin +DB_PASSWORD=1234 +DB_HOST=pagerino_db +DB_NAME=pager_data + +# App server specific settings +# === Chirpstack API +CHIRP_API_KEY=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJjaGlycHN0YWNrIiwiaXNzIjoiY2hpcnBzdGFjayIsInN1YiI6IjI3YzI5Y2M2LTdjMTUtNDI5Yy1iMjBmLTczNzliZWYzYTI1ZCIsInR5cCI6ImtleSJ9.RsMPIGgPaGluBllRz0Ma_EthxUj3xM9pTPy_uUEAbvk + +# === MQTT broker settings +MQTT_ADDRESS=ssl://mosquitto:8883 +MQTT_CLIENT_ID=app-server +MQTT_QOS=0 +# This App's ID in Chirpstack +# + matches all IDs +# # matches all IDs and all(!) subtopics +APP_ID=d6ccd2ad-0cf7-46ab-8618-7a5a14b8676d + +# Enviroment variables that will be available for every application + +# General version of the system +VERSION=0.1 + +# Optional prefix for logging +LOG_PREFIX=[Pagerino] + +# Main app container name +SERVER_NAME=pagerino-app +SERVER_API_PORT=50222 + +# General preferred connection timeout +TIMEOUT=3s \ No newline at end of file diff --git a/AppServer/Dockerfile b/AppServer/Dockerfile new file mode 100755 index 0000000..46d15e3 --- /dev/null +++ b/AppServer/Dockerfile @@ -0,0 +1,31 @@ +# [0] Go build environment +FROM golang:1.24.5-alpine3.21 AS builder +WORKDIR /app-server/src + +## Dependencies +# Get +COPY ./src/go.mod ./src/go.sum ./ +# Download +RUN go mod download + +## Executable +# Get +COPY ./src . +# Build +RUN go build -o ../build/app_server + +# [1] Final image -> new FS +FROM alpine:latest +WORKDIR /root/ + +# RUN apk add --no-cache ca-certificates +# RUN apk add --no-cache bash + +## Final build +# Get +COPY --from=builder /app-server/build ./build +COPY ./certs ./certs +COPY ./*.env ./build/ + +# Run the app +CMD ["./build/app_server"] diff --git a/AppServer/Makefile b/AppServer/Makefile new file mode 100644 index 0000000..b3eb089 --- /dev/null +++ b/AppServer/Makefile @@ -0,0 +1,40 @@ +# Makefile for compiling all proto files into Go + +PROTO_IN := src/app_comm/proto +PROTO_OUT := src/app_comm/api + +# Find all .proto files recursively +PROTO_FILES := $(shell find $(PROTO_IN) -name "*.proto") +GO_FILES := $(shell find ./src/** -name "*.go") + +# Default target +all: proto + +# Go build +go: $(GO_FILES) + @echo "Building Go application..." + go build -o ../build/app_server -C src + @echo "Done." + +# Compile all proto files +proto: $(PROTO_FILES) + @echo "Generating Go code from proto files..." + @for f in $(PROTO_FILES); do \ + base=$${f##*/}; \ + name=$${base%%.*}; \ + echo "Generating $$f -> $(PROTO_OUT)/$$name"; \ + mkdir -p $(PROTO_OUT)/$$name; \ + protoc -I=$(PROTO_IN) \ + --go_out=$(PROTO_OUT)/$$name --go_opt=paths=source_relative \ + --go-grpc_out=$(PROTO_OUT)/$$name --go-grpc_opt=paths=source_relative \ + $$f || exit 1; \ + done + @echo "Done." + +# Clean builds +clean: + @echo "Deleting built files..." + rm -rf $(PROTO_OUT)/* build/* + @echo "Done." + +.PHONY: all clean diff --git a/AppServer/README.md b/AppServer/README.md new file mode 100755 index 0000000..e53acea --- /dev/null +++ b/AppServer/README.md @@ -0,0 +1,61 @@ +# Pagerino: **Application server** + +### Description + +Dockerized server communicating with Chirpstack (v4) and processing incoming data. + +### Features + +Current working and in-progress capabilities include: + - receiving uplinks + - sending downlinks + - logging messages and telemetery + - managing users, devices, messages and other objects + - accepting api requests + +### Configuration + +Can be found in server.env: +**CHIRP_API_KEY** - used to get more detailed information about the network +of devices from Chirpstack + +**MQTT_ADDRESS** - address for MQTT broker that manages uplinks & downlinks, +do not change unless you reconfigure the chirpstack as well + +**MQTT_CLIENT_ID** - ID to use when communicating with broker, can be anything + +**MQTT_QOS** - quality of service level, leave at zero unless your network supports it + +**APP_ID** - ID of accessing application registred in Chirpstack + +**API_PORT** - port at which API is provided, this and its wrappers are the +only way to officially communicate with the server + +The app requires some other shared variables from shared.env. +If not present, provide the following: +**LOG_PREFIX** +**SERVER_NAME** +**TIMEOUT** - used for establishing connections + +### Prerequisites + +The server communicates through ssl with MQTT and needs the following files +generated from Chirpstack in the certs directory: +- ca.pem +- client.key +- client.pem + +It uses Chirpstack's gRPC API, so it needs the compiled proto files into go in +the src/app_comm/api directory. + +### Usage + +The server requires to be on the same docker network as MQTT broker and Chirpstack +to properly function. + +To start have Chirpstack v4 running in detached state and execute: +```docker compose up``` + + +*Created by Olek \@ Gorak Industries* + diff --git a/AppServer/certs/ca.pem b/AppServer/certs/ca.pem new file mode 100644 index 0000000..19457dd --- /dev/null +++ b/AppServer/certs/ca.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFETCCAvmgAwIBAgIUBcNVhGn2QaXZrzEfo7NEcktfjQowDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNQ2hpcnBTdGFjay1DQTAeFw0yNTA5MDYyMjUwMzlaFw0y +ODA5MDUyMjUwMzlaMBgxFjAUBgNVBAMMDUNoaXJwU3RhY2stQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQDKru8yd0ZYdoxDgL0Ls2IiL5+oYmyoEIAq +GKaQltKOUMBMLOaDXum+/aEnCVoch5yzX7As/rIAH1p6rrGy5HJs7xww1ls5yjon +IcVjlpWMnH3PecilVQuZOXEeny2h6zIVaK0aThVB3/+pEVY3nprk9i29KEz+8biU +ykDce30EvemV4g6hF7AfrGiSv/EFLNTyX9YBPZ9LgbC1EHd4W07vYIz67JNcuw42 +xyYSMnp0hsxBiXv7KXlu2h5MjzNOXR8fI9WEkg5BkmVX6h+Uruvaw26uw5prXbYp +FtakDjnnQ+wS7Q3Jl7e0hF4pejvfgZoqJZXErUpRGIPBGD2Gxm+S5J2RahaUOvKY +AQg32okeoOtwv0YoP4Tei3HPyQkKjgGCWjMog3yUCG7z59zXilcl6GvESZEEh0Q/ +M0VKOzh85MnWSJ2otppjCYzzklyUwm5zvWiUS3xQr6e3EapsthS5ccuAzNa++LMU +Vs6TO7U8BshbgNFUqpc7exBdPPdGVzKbzidwJeanshLy0+zc2ZUH+nIdlmQRSlM1 +cyUk0Z5N0X6so3NouHSag7lhqYBGmESX+P4dOqhwgFw4EfmuSLdduXVehU2Cca/1 +6e7YQi+Zy9lHLCN1kmHU0Eu8xoaDH0D3jnKccrWqsV/fiiainAUnTxHkzV8K8guq +3iTrcBsI2QIDAQABo1MwUTAdBgNVHQ4EFgQUFYNQfsgbp5HNBPVNlZ12GSM3FAIw +HwYDVR0jBBgwFoAUFYNQfsgbp5HNBPVNlZ12GSM3FAIwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAMgeVJHzXHdS47agDhqkz4gPQl4ynohXaZIUw +3tMDLayjj2MuQ/LDuk2by4FTwWCTGGYhbv0WMaPueatdZVygmokh4jXhux+6Yen7 +fBeqV5hkzhl9BPPaMp9Et2FZRYLMkaNXYcEc697NZUQSWkR2VbJ3P+wMk9N61T6n +q0tUdtWW/2EB5w0TtN+Qz2EcANUD1dqdTQkZUUR7yCWbOvUeUvyqx2GBYA9QWxtT +Vg+t4TlXpbSd/28jxpJwjFCrG+kcoyDnnmCqlfKQX3uj0mnuXg0sgKzwf6OroPgR +7wUjL3/RtlQhxxhen2tAoYThVQ6WMfxioSZPUKzkfapib5/pbb2t/srxb7D35ho+ +Iw1qZCIZ1vpRQ7sKeOXqmDmq6wiIHKP3D0ODsppond2BKagb3umJ7LKV3k6hnOTo +vCsnotXXT2apO4S2YcfQ4yTCW6E05Qo8S7hSzXB8RQpq5gGUSB78DB7tAkhf9RIQ +Ek9O+fBDv2LqyPxLUZM7eyaXQ8RzhpQqO+MYESAQgwxu5etPJTjLMxB8eIxrWY0H +CTnTHmKmpbL9YrU4903YvpTh2NDB/0VmlQe9S1PU0FqPws5fCZtaAK4P9Gsfv59j +CiMy2OPUDMrItR/pl3zSAof2lHN1Tp/Lg9yIY5udgwCDzXo7ajxnbL1W+qLC9pq4 +v/HHA+g= +-----END CERTIFICATE----- diff --git a/AppServer/certs/client.key b/AppServer/certs/client.key new file mode 100644 index 0000000..4043a11 --- /dev/null +++ b/AppServer/certs/client.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDR4rPIgeFuktPQ +KRh2DLhUI4IvA+RYOvIjlQRAOawXiQYe/RMwdCsEul36Nsdj+6RQtsANIXgYqdRJ +t8x+pdzmMeczs9dSJcJMZPt3XnMMeW5lV+MeuehzqcVn1xqNYfP8nL7EUGgpXH5t +68bE8xqM8/e/uIwX046WGD2dqbH+WBseJeyo2Zo9mS9jECVv20h1Dzxl3A6tvHB+ +vBxHgZX9X22V0sW5p2oP29CmjG0ETKRznXKCh0udMOiTfkGL4HQ5MTAlXNKaHcO5 +pLow8qGEhG06/s8A+2TahAveGf1dbdzrj2XlaX+FgcYBgeMOLXloFghg77B1C0NI +Fb5dYk1nAgMBAAECggEAJidRakYd/lVHluQZk8AdNAJedIB/HoDcqpY4txokzAR3 +LePwfJLpjQr58XXKykSg6qFGCT0H0Wfx9NKqJG2vWdNBhbcQEdlWWD/VLK5pOJ/M +bzTKTzgZZwk6HvXN2Fyxlz7BOPuq67XqL744HG5a6buh0mLQaLZnCabvcH08I5F5 +VRYq60cEzjVuRzCYwBQuoQi7I4ovIvcKVVQTQ6nPsFlk9CgmBUUK3xzV+ZJSGnZ+ +SzgCXL3XmCdzd2Y/Yhsu4uLNd/LdCuUbgU+audyML+JA5MoiTKHw9fiv9yBeMngA +vdQSM/tMhYDv2liCEMSql7BeQ95/ofv/S7HudF4Z4QKBgQDszjAU//i97efvPRk1 +36taBwCmsnrhK3gHchUdmorU/I1+/2vUh59lf2MHdTpraHWzI1wutCDMOL2PGM5K +CDy2pX8CDM0PBCQUFk+ZeAiGZPyRzOX5OkttqJQId7VzKTzwC9f/9j04rKzY05ps +ga40HpceF5QIfyqmMRgYNTNk4QKBgQDi5ep5m10VDou1/3Xbd8yu+zSVPl6H6ti8 +t3bWdI4/xQF6mowR7Hu6mTlMDBXr44hzjJDdw5Zgfg2GZJJGWM/o5U3jCvwQmtbV +loXwAl246aZ2DvUQ5S9KxoEEZzZ+j44EvX1bmOiOeLR+OsHRTySt5RfFziDMv6jo +/irCp5izRwKBgAGXAMujTFA6IKyChIDQF55rHZ4A5MJOQGgMZAfm2bfEWk7X+Cld +H7zWtht+tf2yndeuDRhjLTUxzFQBnqDwnTe8tLWW0GmhZXydCbvGCoicdPWlooWh +1o/N6fCEnTtAs6AI9FJLnO2ceyyZfxfrZvgCnJEfJ2dHM0oaWkcPVGEBAoGAIa7i +BRWEVvjm0qjO1TrOnvdZ0gIFRIYfkLxnnuSErYDQfGPvAUYrBAN1Fw4APxlzCzxF +0TYU39Q2q8nIUTsj+j34NwlNbCWgWOrUjVG8mhPNi18jEFQFlkMrqfysgVNMUPXU +Y0Gq3GOc39RXK3xlRI9q3QmBowOczqHUtTruF0cCgYEA1XncVWT6ioOhpiv9YXH6 ++GtBeVO8BCyDMiH8cJWYjU1LaljWNmzZDHfWH+cCpb4tNd9RmIhQO27FKVl9BVX7 +xKbi6BXkj8m8H2V7AqCQu/NSKwsYXpAmRLC7vfUqbqlkNPFQSB0gHpIAIrLo2Fjx +hEQcS/cfNEHjKBGNPvFmiTE= +-----END PRIVATE KEY----- diff --git a/AppServer/certs/client.pem b/AppServer/certs/client.pem new file mode 100644 index 0000000..f1a48e1 --- /dev/null +++ b/AppServer/certs/client.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEKjCCAhKgAwIBAgIUX/8vMc8novU3n+VgW4ToUseWZaUwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNQ2hpcnBTdGFjay1DQTAeFw0yNTA5MDYyMjUwMzlaFw0y +NjA5MDYyMjUwMzlaMBUxEzARBgNVBAMMCmNoaXJwc3RhY2swggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDR4rPIgeFuktPQKRh2DLhUI4IvA+RYOvIjlQRA +OawXiQYe/RMwdCsEul36Nsdj+6RQtsANIXgYqdRJt8x+pdzmMeczs9dSJcJMZPt3 +XnMMeW5lV+MeuehzqcVn1xqNYfP8nL7EUGgpXH5t68bE8xqM8/e/uIwX046WGD2d +qbH+WBseJeyo2Zo9mS9jECVv20h1Dzxl3A6tvHB+vBxHgZX9X22V0sW5p2oP29Cm +jG0ETKRznXKCh0udMOiTfkGL4HQ5MTAlXNKaHcO5pLow8qGEhG06/s8A+2TahAve +Gf1dbdzrj2XlaX+FgcYBgeMOLXloFghg77B1C0NIFb5dYk1nAgMBAAGjbzBtMAkG +A1UdEwQCMAAwCwYDVR0PBAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMCMB0GA1Ud +DgQWBBS5GafUu7Y6QBp76DKG+aGP2XpBMzAfBgNVHSMEGDAWgBQVg1B+yBunkc0E +9U2VnXYZIzcUAjANBgkqhkiG9w0BAQsFAAOCAgEABykbcO04AfW9hiSSmp+aI6iF +1867xhTeIPgAHhDAfMgSCc2B0NFccKn+XVK8LkcEP1B8OM1g6m6JdO1eAeKZgwWY +SMxbmT0uTe3+A7GfAHZw6XXQwB7MoMNzfvM98ishi+zWEbzL2nH3y+zgxMdTH4Ar +t94dcjiEbASHVI1MzIWZQohkS/Nof5sSPwDU90DlsoviUY1HswBq7SR3KK+SDSn6 +h46S0R3S3Hn0u+5mxHnkAuSJ0tjEfK0DUSf5hdWOiKQusi1et2VgVyKhc0/+et8K +m/KhzYctfAdEjFkH4j5rqanlX2D6OeAYv26B6l2QgiDF4n3ezTKEcfjUFX4C/LDg +mxX14LoDm9wWkIp2C+WaaXaSN+bew9u8UhJqVgs7cw5yCk7l8i0XsfpvNce8Wv3V +JCBk9hVpgpPRYNDOmcvdAUIxTqCQSqm29qMEGb+XXJFQl+ZujaEQ1T1oJMZlJ4mV +mRn6oF5lA0dU2Pu8l7R9l0F2wnwBrc+JWKFiVi81tAPrKG/COalQ4zyno3zUiTl0 +3BJo/Ey+IS1aeWdWK0kvG+fsVytvDJCKG7VrErRg9qiZ18avPz3wGl8uGX8n0Nel +TA32TeBE22oa1qAfyhSrtfEMpOsQxQ+yYIaFcwLQWuU2Zlz1zejXjz9iS1VTIZNy +nWHD6N8iJHz/kQjCZuA= +-----END CERTIFICATE----- diff --git a/AppServer/docker-compose.yml b/AppServer/docker-compose.yml new file mode 100644 index 0000000..7d177d1 --- /dev/null +++ b/AppServer/docker-compose.yml @@ -0,0 +1,39 @@ +version: '3.0' + +services: + app_server: + build: . + depends_on: + - pagerino_db + networks: + - app_net + - pagerino_net + restart: on-failure:3 + + pagerino_db: + image: postgres:15 + restart: unless-stopped + environment: + POSTGRES_USER: ${DB_USER} + POSTGRES_PASSWORD: ${DB_PASSWORD} + POSTGRES_DB: ${DB_NAME} + networks: + - app_net + volumes: + - dbdata:/var/lib/postgresql/data + - ./init.sql:/docker-entrypoint-initdb.d/init.sql + - ./postgresql.conf:/etc/postgresql/postgresql.conf + command: ["postgres", "-c", "config_file=/etc/postgresql/postgresql.conf"] + # ports: + # - "5432:5432" + + +volumes: + dbdata: + +networks: + app_net: + driver: bridge + pagerino_net: + external: true + diff --git a/AppServer/init.sql b/AppServer/init.sql new file mode 100755 index 0000000..5f2d7fd --- /dev/null +++ b/AppServer/init.sql @@ -0,0 +1,122 @@ +--CREATE EXTENSION IF NOT EXISTS postgis; +CREATE EXTENSION IF NOT EXISTS hstore; + +CREATE DATABASE pager_data; +CREATE USER admin WITH ENCRYPTED PASSWORD '1234'; +GRANT ALL PRIVILEGES ON DATABASE pager_data TO admin; + +-- === Devices === +CREATE TABLE Devices ( + id SERIAL PRIMARY KEY, + created_at TIMESTAMPTZ DEFAULT NOW(), + + euid VARCHAR(16) NOT NULL UNIQUE, -- LoRaWAN Extended Unique ID (hex, 8 bytes) + name VARCHAR(64) NOT NULL, -- ! Not Unique + + fw_version VARCHAR(24) NOT NULL, + + charge NUMERIC(5,2) CHECK (charge >= 0 AND charge <= 100), -- battery in % + last_online TIMESTAMPTZ, -- ! NULL + + -- Location fields: + latitude DOUBLE PRECISION CHECK (latitude >= -90 AND latitude <= 90), + longitude DOUBLE PRECISION CHECK (longitude >= -180 AND longitude <= 180), + altitude DOUBLE PRECISION +); + +CREATE TABLE Messages ( + id SERIAL PRIMARY KEY, + created_at TIMESTAMPTZ DEFAULT NOW(), + + sender_id INT NOT NULL REFERENCES Devices(id) ON DELETE SET NULL, + receiver_id INT REFERENCES Devices(id) ON DELETE SET NULL, -- ! NULL + payload VARCHAR(256) +); + +CREATE TABLE Statuses ( + id SERIAL PRIMARY KEY, + created_at TIMESTAMPTZ DEFAULT NOW(), + + device_id INT NOT NULL REFERENCES Devices(id) ON DELETE CASCADE, + payload VARCHAR(256) +); + +-- === Roles === +CREATE TABLE Roles ( + id SERIAL PRIMARY KEY, + created_at TIMESTAMPTZ DEFAULT NOW(), + + name VARCHAR(64) NOT NULL UNIQUE, + description VARCHAR(128) NOT NULL DEFAULT 'Role description' +); + +INSERT INTO Roles (name, description) VALUES ('Admin', 'Should do everything.'); -- Admin role + +CREATE TABLE Permissions ( + id SERIAL PRIMARY KEY, + created_at TIMESTAMPTZ DEFAULT NOW(), + + name VARCHAR(64) NOT NULL UNIQUE, + description VARCHAR(128) NOT NULL DEFAULT 'Permission description' +); + +INSERT INTO Permissions (name, description) VALUES ('Everything', 'Can do everything.'); -- Admin permission + +-- Join table for Roles & Permissions +CREATE TABLE RolesPermissions ( + role_id INT NOT NULL REFERENCES Roles(id), + permission_id INT NOT NULL REFERENCES Permissions(id) +); + +INSERT INTO RolesPermissions (role_id, permission_id) VALUES (1, 1); -- Tie together role & permission + +-- === Users === +CREATE TABLE Users ( + id SERIAL PRIMARY KEY, + created_at TIMESTAMPTZ DEFAULT NOW(), + + name VARCHAR(64) UNIQUE NOT NULL, + password VARCHAR(64) NOT NULL, + role_id INT DEFAULT 2 REFERENCES Roles(id) ON DELETE SET DEFAULT, -- default low privilleges + last_online TIMESTAMPTZ -- ! NULL +); + +INSERT INTO Users (name, password, role_id) VALUES ('Admin', 'admin', 1); -- Admin user + +CREATE TABLE NFC_Cards ( + id SERIAL PRIMARY KEY, + created_at TIMESTAMPTZ DEFAULT NOW(), + + user_id INT REFERENCES Users(id) ON DELETE SET NULL, -- ! NULL + device_id INT REFERENCES Devices(id) ON DELETE SET NULL, -- ! NULL + uid VARCHAR(7) NOT NULL UNIQUE, + CONSTRAINT uid_length CHECK (length(uid) = 4 OR length(uid) = 7) -- Check for valid UUID +); + +-- === Logs === +CREATE TABLE Logs ( + id SERIAL PRIMARY KEY, + created_at TIMESTAMPTZ DEFAULT NOW(), + + db_user TEXT DEFAULT current_user +); + +CREATE TABLE LogsUsers ( + log_id INT REFERENCES Logs(id) ON DELETE CASCADE, + user_id INT REFERENCES Users(id) ON DELETE CASCADE +); + +CREATE TABLE LogsDevices ( + log_id INT REFERENCES Logs(id) ON DELETE CASCADE, + device_id INT REFERENCES Devices(id) ON DELETE CASCADE +); + +CREATE TABLE Changes ( + id SERIAL PRIMARY KEY, + log_id INT NOT NULL REFERENCES Logs(id) ON DELETE CASCADE, + table_name TEXT NOT NULL, + operation TEXT NOT NULL, + old_value hstore, -- ! NULL + new_value hstore, -- ! NULL + CONSTRAINT change_diff CHECK (old_value != new_value) +); diff --git a/AppServer/postgresql.conf b/AppServer/postgresql.conf new file mode 100755 index 0000000..7e67009 --- /dev/null +++ b/AppServer/postgresql.conf @@ -0,0 +1,3 @@ +log_connections = on +log_destination = 'stderr' +listen_addresses='*' \ No newline at end of file diff --git a/AppServer/src/api.go b/AppServer/src/api.go new file mode 100644 index 0000000..72b14fc --- /dev/null +++ b/AppServer/src/api.go @@ -0,0 +1,180 @@ +/* +Implements gRPC API server. + +Author: Olek +*/ +package main + +import ( + "context" + "errors" + + api_common "server/app_comm/api/common" + api_device "server/app_comm/api/device" + api_user "server/app_comm/api/user" + + "github.com/jackc/pgx/v5" +) + +var ( + ErrNoIndex error = errors.New("no valid index provided for request") +) + +// === Device Service === +type DeviceServiceServer struct { + api_device.UnimplementedDeviceServiceServer + App *AppData +} + +func (s *DeviceServiceServer) GetFull(ctx context.Context, index *api_common.StrIndex) (*api_device.DeviceAllInfo, error) { + info := api_device.DeviceAllInfo{} + var err error + var row pgx.Row + var deviceId int32 + + switch index.Id.(type) { + case *api_common.StrIndex_Num: // Indexing by DB ID + deviceId = index.GetNum() + + row = s.App.DBPool.QueryRow(ctx, ` + SELECT euid, name, fw_version, charge, last_online, latitude, longitude, altitude + FROM Devices WHERE id = $1;`, + deviceId, + ) + err = row.Scan( + &info.Euid, + &info.Name, + &info.FwVersion, + &info.Charge, + &info.LastOnline, + &info.Latitude, + &info.Longitude, + &info.Altitude, + ) + case *api_common.StrIndex_Name: // Indexing by EUID + euid := index.GetName() + info.Euid = euid + + row = s.App.DBPool.QueryRow(ctx, ` + SELECT name, fw_version, charge, last_online, latitude, longitude, altitude, id + FROM Devices WHERE euid = $1;`, + euid, + ) + err = row.Scan( + &info.Name, + &info.FwVersion, + &info.Charge, + &info.LastOnline, + &info.Latitude, + &info.Longitude, + &info.Altitude, + &deviceId, + ) + default: // Zeroed out + return nil, ErrNoIndex + } + + if err != nil { + return &info, err + } + + // Fetch latest Status + row = s.App.DBPool.QueryRow(ctx, ` + SELECT internal_status, native_status + FROM Statuses + WHERE device_id = $1 + ORDER BY created_at DESC LIMIT 1;`, deviceId, + ) + var int_status int16 + var nat_status string + err = row.Scan(&int_status, &nat_status) + if err != nil && !errors.Is(err, pgx.ErrNoRows) { + return &info, err + } + info.InternalStatus = int32(int_status) + info.NativeStatus = nat_status + + // Fetch paired cards + row = s.App.DBPool.QueryRow(ctx, ` + SELECT id + FROM NFC_Cards + WHERE device_id = $1 + ORDER BY created_at DESC;`, deviceId, + ) + var card_ids []int32 + err = row.Scan(&card_ids) + if err != nil && !errors.Is(err, pgx.ErrNoRows) { + return &info, err + } + info.CardIds = card_ids + + return &info, nil +} + +func (s *DeviceServiceServer) GetInfo(ctx context.Context, index *api_common.StrIndex) (*api_device.DeviceBaseInfo, error) { + var err error + var row pgx.Row + var deviceId int32 + info := api_device.DeviceBaseInfo{} + + switch index.Id.(type) { + case *api_common.StrIndex_Num: + row = s.App.DBPool.QueryRow(ctx, "SELECT (id, name, euid, last_online) FROM Devices WHERE id = $1;", index.GetNum()) + err = row.Scan(&deviceId, &info.Name, &info.Euid, &info.LastOnline) + case *api_common.StrIndex_Name: + euid := index.GetName() + info.Euid = euid + + row = s.App.DBPool.QueryRow(ctx, "SELECT (id, name, last_online) FROM Devices WHERE euid = $1;", euid) + err = row.Scan(&deviceId, &info.Name, &info.LastOnline) + default: + return nil, ErrNoIndex + } + + if err != nil && !errors.Is(err, pgx.ErrNoRows) { + return &info, err + } + + row = s.App.DBPool.QueryRow(ctx, ` + SELECT internal_status + FROM Statuses + WHERE device_id = $1 + ORDER BY created_at DESC LIMIT 1;`, deviceId, + ) + var status int16 + err = row.Scan(&status) + if err != nil && !errors.Is(err, pgx.ErrNoRows) { + return &info, err + } + + info.InternalStatus = int32(status) + + return &info, err +} + +// === User Service === +type UserServiceServer struct { + api_user.UnimplementedUserServiceServer + App *AppData +} + +func (s *UserServiceServer) GetPassword(ctx context.Context, index *api_common.StrIndex) (*api_user.Password, error) { + var err error + var row pgx.Row + info := api_user.Password{} + + switch index.Id.(type) { + case *api_common.StrIndex_Num: + row = s.App.DBPool.QueryRow(ctx, "SELECT password FROM Users WHERE id = $1;", index.GetNum()) + err = row.Scan(&info.Password) + case *api_common.StrIndex_Name: + row = s.App.DBPool.QueryRow(ctx, "SELECT password FROM Users WHERE name = $1;", index.GetName()) + err = row.Scan(&info.Password) + default: + return nil, ErrNoIndex + } + + return &info, err +} + +//TODO: finish diff --git a/AppServer/src/app_comm/api/change/change.pb.go b/AppServer/src/app_comm/api/change/change.pb.go new file mode 100644 index 0000000..2eaf33e --- /dev/null +++ b/AppServer/src/app_comm/api/change/change.pb.go @@ -0,0 +1,278 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: change.proto + +package api_change + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + common "server/app_comm/api/common" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ChageAllInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OldValue string `protobuf:"bytes,1,opt,name=old_value,json=oldValue,proto3" json:"old_value,omitempty"` + NewValue string `protobuf:"bytes,2,opt,name=new_value,json=newValue,proto3" json:"new_value,omitempty"` + TableName string `protobuf:"bytes,3,opt,name=table_name,json=tableName,proto3" json:"table_name,omitempty"` + Operation string `protobuf:"bytes,4,opt,name=operation,proto3" json:"operation,omitempty"` + LogId int32 `protobuf:"varint,5,opt,name=log_id,json=logId,proto3" json:"log_id,omitempty"` +} + +func (x *ChageAllInfo) Reset() { + *x = ChageAllInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_change_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ChageAllInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChageAllInfo) ProtoMessage() {} + +func (x *ChageAllInfo) ProtoReflect() protoreflect.Message { + mi := &file_change_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChageAllInfo.ProtoReflect.Descriptor instead. +func (*ChageAllInfo) Descriptor() ([]byte, []int) { + return file_change_proto_rawDescGZIP(), []int{0} +} + +func (x *ChageAllInfo) GetOldValue() string { + if x != nil { + return x.OldValue + } + return "" +} + +func (x *ChageAllInfo) GetNewValue() string { + if x != nil { + return x.NewValue + } + return "" +} + +func (x *ChageAllInfo) GetTableName() string { + if x != nil { + return x.TableName + } + return "" +} + +func (x *ChageAllInfo) GetOperation() string { + if x != nil { + return x.Operation + } + return "" +} + +func (x *ChageAllInfo) GetLogId() int32 { + if x != nil { + return x.LogId + } + return 0 +} + +type Values struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OldValue string `protobuf:"bytes,1,opt,name=old_value,json=oldValue,proto3" json:"old_value,omitempty"` + NewValue string `protobuf:"bytes,2,opt,name=new_value,json=newValue,proto3" json:"new_value,omitempty"` +} + +func (x *Values) Reset() { + *x = Values{} + if protoimpl.UnsafeEnabled { + mi := &file_change_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Values) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Values) ProtoMessage() {} + +func (x *Values) ProtoReflect() protoreflect.Message { + mi := &file_change_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Values.ProtoReflect.Descriptor instead. +func (*Values) Descriptor() ([]byte, []int) { + return file_change_proto_rawDescGZIP(), []int{1} +} + +func (x *Values) GetOldValue() string { + if x != nil { + return x.OldValue + } + return "" +} + +func (x *Values) GetNewValue() string { + if x != nil { + return x.NewValue + } + return "" +} + +var File_change_proto protoreflect.FileDescriptor + +var file_change_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x1a, + 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9c, 0x01, + 0x0a, 0x0c, 0x43, 0x68, 0x61, 0x67, 0x65, 0x41, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, + 0x0a, 0x09, 0x6f, 0x6c, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x6f, 0x6c, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6e, + 0x65, 0x77, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x6e, 0x65, 0x77, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x6c, 0x6f, 0x67, 0x5f, 0x69, 0x64, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x6f, 0x67, 0x49, 0x64, 0x22, 0x42, 0x0a, 0x06, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x6c, 0x64, 0x5f, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x6c, 0x64, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x65, 0x77, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x65, 0x77, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x32, 0xc6, 0x01, 0x0a, 0x0d, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x3a, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x44, 0x69, 0x66, 0x66, 0x12, 0x16, 0x2e, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x17, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x3f, + 0x0a, 0x06, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x12, 0x16, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, + 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x1a, 0x1d, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x2e, 0x43, 0x68, 0x61, 0x67, 0x65, 0x41, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x38, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x16, 0x2e, 0x70, 0x61, 0x67, + 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x64, + 0x65, 0x78, 0x1a, 0x15, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x42, 0x27, 0x5a, 0x25, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x3b, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_change_proto_rawDescOnce sync.Once + file_change_proto_rawDescData = file_change_proto_rawDesc +) + +func file_change_proto_rawDescGZIP() []byte { + file_change_proto_rawDescOnce.Do(func() { + file_change_proto_rawDescData = protoimpl.X.CompressGZIP(file_change_proto_rawDescData) + }) + return file_change_proto_rawDescData +} + +var file_change_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_change_proto_goTypes = []interface{}{ + (*ChageAllInfo)(nil), // 0: pagerino.change.ChageAllInfo + (*Values)(nil), // 1: pagerino.change.Values + (*common.Index)(nil), // 2: pagerino.common.Index + (*common.Meta)(nil), // 3: pagerino.common.Meta +} +var file_change_proto_depIdxs = []int32{ + 2, // 0: pagerino.change.ChangeService.GetDiff:input_type -> pagerino.common.Index + 2, // 1: pagerino.change.ChangeService.GetAll:input_type -> pagerino.common.Index + 2, // 2: pagerino.change.ChangeService.GetMeta:input_type -> pagerino.common.Index + 1, // 3: pagerino.change.ChangeService.GetDiff:output_type -> pagerino.change.Values + 0, // 4: pagerino.change.ChangeService.GetAll:output_type -> pagerino.change.ChageAllInfo + 3, // 5: pagerino.change.ChangeService.GetMeta:output_type -> pagerino.common.Meta + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_change_proto_init() } +func file_change_proto_init() { + if File_change_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_change_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ChageAllInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_change_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Values); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_change_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_change_proto_goTypes, + DependencyIndexes: file_change_proto_depIdxs, + MessageInfos: file_change_proto_msgTypes, + }.Build() + File_change_proto = out.File + file_change_proto_rawDesc = nil + file_change_proto_goTypes = nil + file_change_proto_depIdxs = nil +} diff --git a/AppServer/src/app_comm/api/change/change_grpc.pb.go b/AppServer/src/app_comm/api/change/change_grpc.pb.go new file mode 100644 index 0000000..9f9edcd --- /dev/null +++ b/AppServer/src/app_comm/api/change/change_grpc.pb.go @@ -0,0 +1,178 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package api_change + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + common "server/app_comm/api/common" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// ChangeServiceClient is the client API for ChangeService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ChangeServiceClient interface { + // === DB information + GetDiff(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*Values, error) + GetAll(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*ChageAllInfo, error) + // Common + GetMeta(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Meta, error) +} + +type changeServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewChangeServiceClient(cc grpc.ClientConnInterface) ChangeServiceClient { + return &changeServiceClient{cc} +} + +func (c *changeServiceClient) GetDiff(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*Values, error) { + out := new(Values) + err := c.cc.Invoke(ctx, "/pagerino.change.ChangeService/GetDiff", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *changeServiceClient) GetAll(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*ChageAllInfo, error) { + out := new(ChageAllInfo) + err := c.cc.Invoke(ctx, "/pagerino.change.ChangeService/GetAll", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *changeServiceClient) GetMeta(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Meta, error) { + out := new(common.Meta) + err := c.cc.Invoke(ctx, "/pagerino.change.ChangeService/GetMeta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ChangeServiceServer is the server API for ChangeService service. +// All implementations must embed UnimplementedChangeServiceServer +// for forward compatibility +type ChangeServiceServer interface { + // === DB information + GetDiff(context.Context, *common.Index) (*Values, error) + GetAll(context.Context, *common.Index) (*ChageAllInfo, error) + // Common + GetMeta(context.Context, *common.Index) (*common.Meta, error) + mustEmbedUnimplementedChangeServiceServer() +} + +// UnimplementedChangeServiceServer must be embedded to have forward compatible implementations. +type UnimplementedChangeServiceServer struct { +} + +func (UnimplementedChangeServiceServer) GetDiff(context.Context, *common.Index) (*Values, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetDiff not implemented") +} +func (UnimplementedChangeServiceServer) GetAll(context.Context, *common.Index) (*ChageAllInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAll not implemented") +} +func (UnimplementedChangeServiceServer) GetMeta(context.Context, *common.Index) (*common.Meta, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMeta not implemented") +} +func (UnimplementedChangeServiceServer) mustEmbedUnimplementedChangeServiceServer() {} + +// UnsafeChangeServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ChangeServiceServer will +// result in compilation errors. +type UnsafeChangeServiceServer interface { + mustEmbedUnimplementedChangeServiceServer() +} + +func RegisterChangeServiceServer(s grpc.ServiceRegistrar, srv ChangeServiceServer) { + s.RegisterService(&ChangeService_ServiceDesc, srv) +} + +func _ChangeService_GetDiff_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChangeServiceServer).GetDiff(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.change.ChangeService/GetDiff", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChangeServiceServer).GetDiff(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +func _ChangeService_GetAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChangeServiceServer).GetAll(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.change.ChangeService/GetAll", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChangeServiceServer).GetAll(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +func _ChangeService_GetMeta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChangeServiceServer).GetMeta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.change.ChangeService/GetMeta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChangeServiceServer).GetMeta(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +// ChangeService_ServiceDesc is the grpc.ServiceDesc for ChangeService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ChangeService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pagerino.change.ChangeService", + HandlerType: (*ChangeServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetDiff", + Handler: _ChangeService_GetDiff_Handler, + }, + { + MethodName: "GetAll", + Handler: _ChangeService_GetAll_Handler, + }, + { + MethodName: "GetMeta", + Handler: _ChangeService_GetMeta_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "change.proto", +} diff --git a/AppServer/src/app_comm/api/common/common.pb.go b/AppServer/src/app_comm/api/common/common.pb.go new file mode 100644 index 0000000..b22546d --- /dev/null +++ b/AppServer/src/app_comm/api/common/common.pb.go @@ -0,0 +1,588 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: common.proto + +package api_common + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// For custom logic responses +type RequestCode int32 + +const ( + RequestCode_UNKNOWN RequestCode = 0 + RequestCode_OK RequestCode = 1 + RequestCode_UNAUTHORIZED RequestCode = 2 + RequestCode_NO_DATA RequestCode = 3 + RequestCode_INTERNAL_ERROR RequestCode = 4 +) + +// Enum value maps for RequestCode. +var ( + RequestCode_name = map[int32]string{ + 0: "UNKNOWN", + 1: "OK", + 2: "UNAUTHORIZED", + 3: "NO_DATA", + 4: "INTERNAL_ERROR", + } + RequestCode_value = map[string]int32{ + "UNKNOWN": 0, + "OK": 1, + "UNAUTHORIZED": 2, + "NO_DATA": 3, + "INTERNAL_ERROR": 4, + } +) + +func (x RequestCode) Enum() *RequestCode { + p := new(RequestCode) + *p = x + return p +} + +func (x RequestCode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (RequestCode) Descriptor() protoreflect.EnumDescriptor { + return file_common_proto_enumTypes[0].Descriptor() +} + +func (RequestCode) Type() protoreflect.EnumType { + return &file_common_proto_enumTypes[0] +} + +func (x RequestCode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use RequestCode.Descriptor instead. +func (RequestCode) EnumDescriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{0} +} + +// === DB indexing +type StrIndex struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Id: + // *StrIndex_Num + // *StrIndex_Name + Id isStrIndex_Id `protobuf_oneof:"id"` +} + +func (x *StrIndex) Reset() { + *x = StrIndex{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StrIndex) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StrIndex) ProtoMessage() {} + +func (x *StrIndex) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StrIndex.ProtoReflect.Descriptor instead. +func (*StrIndex) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{0} +} + +func (m *StrIndex) GetId() isStrIndex_Id { + if m != nil { + return m.Id + } + return nil +} + +func (x *StrIndex) GetNum() int32 { + if x, ok := x.GetId().(*StrIndex_Num); ok { + return x.Num + } + return 0 +} + +func (x *StrIndex) GetName() string { + if x, ok := x.GetId().(*StrIndex_Name); ok { + return x.Name + } + return "" +} + +type isStrIndex_Id interface { + isStrIndex_Id() +} + +type StrIndex_Num struct { + Num int32 `protobuf:"varint,1,opt,name=num,proto3,oneof"` // Database ID +} + +type StrIndex_Name struct { + Name string `protobuf:"bytes,2,opt,name=name,proto3,oneof"` // for external fields: username, euid, name... +} + +func (*StrIndex_Num) isStrIndex_Id() {} + +func (*StrIndex_Name) isStrIndex_Id() {} + +type Index struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Num int32 `protobuf:"varint,1,opt,name=num,proto3" json:"num,omitempty"` // Database ID +} + +func (x *Index) Reset() { + *x = Index{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Index) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Index) ProtoMessage() {} + +func (x *Index) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Index.ProtoReflect.Descriptor instead. +func (*Index) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{1} +} + +func (x *Index) GetNum() int32 { + if x != nil { + return x.Num + } + return 0 +} + +// === DB information +type Meta struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` +} + +func (x *Meta) Reset() { + *x = Meta{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Meta) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Meta) ProtoMessage() {} + +func (x *Meta) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Meta.ProtoReflect.Descriptor instead. +func (*Meta) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{2} +} + +func (x *Meta) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Meta) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +type References struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Page int32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` // 32 IDs per page from most recent + RefId []int32 `protobuf:"varint,2,rep,packed,name=ref_id,json=refId,proto3" json:"ref_id,omitempty"` +} + +func (x *References) Reset() { + *x = References{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *References) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*References) ProtoMessage() {} + +func (x *References) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use References.ProtoReflect.Descriptor instead. +func (*References) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{3} +} + +func (x *References) GetPage() int32 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *References) GetRefId() []int32 { + if x != nil { + return x.RefId + } + return nil +} + +type Reference struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RefId int32 `protobuf:"varint,1,opt,name=ref_id,json=refId,proto3" json:"ref_id,omitempty"` +} + +func (x *Reference) Reset() { + *x = Reference{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Reference) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Reference) ProtoMessage() {} + +func (x *Reference) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Reference.ProtoReflect.Descriptor instead. +func (*Reference) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{4} +} + +func (x *Reference) GetRefId() int32 { + if x != nil { + return x.RefId + } + return 0 +} + +type Activity struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LastOnline *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=last_online,json=lastOnline,proto3" json:"last_online,omitempty"` +} + +func (x *Activity) Reset() { + *x = Activity{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Activity) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Activity) ProtoMessage() {} + +func (x *Activity) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Activity.ProtoReflect.Descriptor instead. +func (*Activity) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{5} +} + +func (x *Activity) GetLastOnline() *timestamppb.Timestamp { + if x != nil { + return x.LastOnline + } + return nil +} + +var File_common_proto protoreflect.FileDescriptor + +var file_common_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x1a, + 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x3a, 0x0a, 0x08, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x12, 0x0a, 0x03, + 0x6e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x03, 0x6e, 0x75, 0x6d, + 0x12, 0x14, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x04, 0x0a, 0x02, 0x69, 0x64, 0x22, 0x19, 0x0a, 0x05, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x10, 0x0a, 0x03, 0x6e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x03, 0x6e, 0x75, 0x6d, 0x22, 0x51, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x37, 0x0a, 0x0a, 0x52, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x15, 0x0a, 0x06, + 0x72, 0x65, 0x66, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, 0x52, 0x05, 0x72, 0x65, + 0x66, 0x49, 0x64, 0x22, 0x22, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x12, 0x15, 0x0a, 0x06, 0x72, 0x65, 0x66, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x05, 0x72, 0x65, 0x66, 0x49, 0x64, 0x22, 0x47, 0x0a, 0x08, 0x41, 0x63, 0x74, 0x69, 0x76, + 0x69, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6f, 0x6e, 0x6c, 0x69, + 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x2a, 0x55, 0x0a, 0x0b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, + 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, + 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, + 0x49, 0x5a, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x4e, 0x4f, 0x5f, 0x44, 0x41, 0x54, + 0x41, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x42, 0x27, 0x5a, 0x25, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2f, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x3b, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_common_proto_rawDescOnce sync.Once + file_common_proto_rawDescData = file_common_proto_rawDesc +) + +func file_common_proto_rawDescGZIP() []byte { + file_common_proto_rawDescOnce.Do(func() { + file_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_common_proto_rawDescData) + }) + return file_common_proto_rawDescData +} + +var file_common_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_common_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_common_proto_goTypes = []interface{}{ + (RequestCode)(0), // 0: pagerino.common.RequestCode + (*StrIndex)(nil), // 1: pagerino.common.StrIndex + (*Index)(nil), // 2: pagerino.common.Index + (*Meta)(nil), // 3: pagerino.common.Meta + (*References)(nil), // 4: pagerino.common.References + (*Reference)(nil), // 5: pagerino.common.Reference + (*Activity)(nil), // 6: pagerino.common.Activity + (*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp +} +var file_common_proto_depIdxs = []int32{ + 7, // 0: pagerino.common.Meta.created_at:type_name -> google.protobuf.Timestamp + 7, // 1: pagerino.common.Activity.last_online:type_name -> google.protobuf.Timestamp + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_common_proto_init() } +func file_common_proto_init() { + if File_common_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StrIndex); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Index); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Meta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*References); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Reference); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Activity); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_common_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*StrIndex_Num)(nil), + (*StrIndex_Name)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_common_proto_rawDesc, + NumEnums: 1, + NumMessages: 6, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_common_proto_goTypes, + DependencyIndexes: file_common_proto_depIdxs, + EnumInfos: file_common_proto_enumTypes, + MessageInfos: file_common_proto_msgTypes, + }.Build() + File_common_proto = out.File + file_common_proto_rawDesc = nil + file_common_proto_goTypes = nil + file_common_proto_depIdxs = nil +} diff --git a/AppServer/src/app_comm/api/device/device.pb.go b/AppServer/src/app_comm/api/device/device.pb.go new file mode 100644 index 0000000..b04eca9 --- /dev/null +++ b/AppServer/src/app_comm/api/device/device.pb.go @@ -0,0 +1,566 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: device.proto + +package api_device + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + common "server/app_comm/api/common" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Charge struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Charge float32 `protobuf:"fixed32,1,opt,name=charge,proto3" json:"charge,omitempty"` +} + +func (x *Charge) Reset() { + *x = Charge{} + if protoimpl.UnsafeEnabled { + mi := &file_device_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Charge) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Charge) ProtoMessage() {} + +func (x *Charge) ProtoReflect() protoreflect.Message { + mi := &file_device_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Charge.ProtoReflect.Descriptor instead. +func (*Charge) Descriptor() ([]byte, []int) { + return file_device_proto_rawDescGZIP(), []int{0} +} + +func (x *Charge) GetCharge() float32 { + if x != nil { + return x.Charge + } + return 0 +} + +type Location struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Latitude float64 `protobuf:"fixed64,1,opt,name=latitude,proto3" json:"latitude,omitempty"` + Longitude float64 `protobuf:"fixed64,2,opt,name=longitude,proto3" json:"longitude,omitempty"` + Altitude float32 `protobuf:"fixed32,3,opt,name=altitude,proto3" json:"altitude,omitempty"` +} + +func (x *Location) Reset() { + *x = Location{} + if protoimpl.UnsafeEnabled { + mi := &file_device_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Location) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Location) ProtoMessage() {} + +func (x *Location) ProtoReflect() protoreflect.Message { + mi := &file_device_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Location.ProtoReflect.Descriptor instead. +func (*Location) Descriptor() ([]byte, []int) { + return file_device_proto_rawDescGZIP(), []int{1} +} + +func (x *Location) GetLatitude() float64 { + if x != nil { + return x.Latitude + } + return 0 +} + +func (x *Location) GetLongitude() float64 { + if x != nil { + return x.Longitude + } + return 0 +} + +func (x *Location) GetAltitude() float32 { + if x != nil { + return x.Altitude + } + return 0 +} + +type DeviceBaseInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Euid string `protobuf:"bytes,2,opt,name=euid,proto3" json:"euid,omitempty"` + InternalStatus int32 `protobuf:"zigzag32,3,opt,name=internal_status,json=internalStatus,proto3" json:"internal_status,omitempty"` + LastOnline *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=last_online,json=lastOnline,proto3" json:"last_online,omitempty"` +} + +func (x *DeviceBaseInfo) Reset() { + *x = DeviceBaseInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_device_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeviceBaseInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeviceBaseInfo) ProtoMessage() {} + +func (x *DeviceBaseInfo) ProtoReflect() protoreflect.Message { + mi := &file_device_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeviceBaseInfo.ProtoReflect.Descriptor instead. +func (*DeviceBaseInfo) Descriptor() ([]byte, []int) { + return file_device_proto_rawDescGZIP(), []int{2} +} + +func (x *DeviceBaseInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DeviceBaseInfo) GetEuid() string { + if x != nil { + return x.Euid + } + return "" +} + +func (x *DeviceBaseInfo) GetInternalStatus() int32 { + if x != nil { + return x.InternalStatus + } + return 0 +} + +func (x *DeviceBaseInfo) GetLastOnline() *timestamppb.Timestamp { + if x != nil { + return x.LastOnline + } + return nil +} + +type DeviceAllInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Euid string `protobuf:"bytes,2,opt,name=euid,proto3" json:"euid,omitempty"` + InternalStatus int32 `protobuf:"zigzag32,3,opt,name=internal_status,json=internalStatus,proto3" json:"internal_status,omitempty"` + NativeStatus string `protobuf:"bytes,4,opt,name=native_status,json=nativeStatus,proto3" json:"native_status,omitempty"` + LastOnline *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=last_online,json=lastOnline,proto3" json:"last_online,omitempty"` + FwVersion string `protobuf:"bytes,6,opt,name=fw_version,json=fwVersion,proto3" json:"fw_version,omitempty"` + CardIds []int32 `protobuf:"varint,7,rep,packed,name=card_ids,json=cardIds,proto3" json:"card_ids,omitempty"` + Charge float32 `protobuf:"fixed32,8,opt,name=charge,proto3" json:"charge,omitempty"` + Latitude float64 `protobuf:"fixed64,9,opt,name=latitude,proto3" json:"latitude,omitempty"` + Longitude float64 `protobuf:"fixed64,10,opt,name=longitude,proto3" json:"longitude,omitempty"` + Altitude float32 `protobuf:"fixed32,11,opt,name=altitude,proto3" json:"altitude,omitempty"` +} + +func (x *DeviceAllInfo) Reset() { + *x = DeviceAllInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_device_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeviceAllInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeviceAllInfo) ProtoMessage() {} + +func (x *DeviceAllInfo) ProtoReflect() protoreflect.Message { + mi := &file_device_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeviceAllInfo.ProtoReflect.Descriptor instead. +func (*DeviceAllInfo) Descriptor() ([]byte, []int) { + return file_device_proto_rawDescGZIP(), []int{3} +} + +func (x *DeviceAllInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DeviceAllInfo) GetEuid() string { + if x != nil { + return x.Euid + } + return "" +} + +func (x *DeviceAllInfo) GetInternalStatus() int32 { + if x != nil { + return x.InternalStatus + } + return 0 +} + +func (x *DeviceAllInfo) GetNativeStatus() string { + if x != nil { + return x.NativeStatus + } + return "" +} + +func (x *DeviceAllInfo) GetLastOnline() *timestamppb.Timestamp { + if x != nil { + return x.LastOnline + } + return nil +} + +func (x *DeviceAllInfo) GetFwVersion() string { + if x != nil { + return x.FwVersion + } + return "" +} + +func (x *DeviceAllInfo) GetCardIds() []int32 { + if x != nil { + return x.CardIds + } + return nil +} + +func (x *DeviceAllInfo) GetCharge() float32 { + if x != nil { + return x.Charge + } + return 0 +} + +func (x *DeviceAllInfo) GetLatitude() float64 { + if x != nil { + return x.Latitude + } + return 0 +} + +func (x *DeviceAllInfo) GetLongitude() float64 { + if x != nil { + return x.Longitude + } + return 0 +} + +func (x *DeviceAllInfo) GetAltitude() float32 { + if x != nil { + return x.Altitude + } + return 0 +} + +var File_device_proto protoreflect.FileDescriptor + +var file_device_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x1a, + 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x20, + 0x0a, 0x06, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x72, + 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x02, 0x52, 0x06, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, + 0x22, 0x60, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, + 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, + 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x6e, 0x67, + 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x6c, 0x6f, 0x6e, + 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x6c, 0x74, 0x69, 0x74, 0x75, + 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x08, 0x61, 0x6c, 0x74, 0x69, 0x74, 0x75, + 0x64, 0x65, 0x22, 0x9e, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x73, + 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x75, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x75, 0x69, 0x64, 0x12, 0x27, 0x0a, + 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6f, + 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x4f, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x22, 0xea, 0x02, 0x0a, 0x0d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x6c, + 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x75, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x75, 0x69, 0x64, 0x12, 0x27, 0x0a, + 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, + 0x61, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, + 0x73, 0x74, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x77, 0x5f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x77, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x61, 0x72, 0x64, 0x5f, + 0x69, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x05, 0x52, 0x07, 0x63, 0x61, 0x72, 0x64, 0x49, + 0x64, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x02, 0x52, 0x06, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, + 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x6c, 0x61, + 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, + 0x75, 0x64, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, + 0x74, 0x75, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x6c, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x52, 0x08, 0x61, 0x6c, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, + 0x32, 0x95, 0x06, 0x0a, 0x0d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x12, 0x19, 0x2e, 0x70, + 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, + 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1e, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, + 0x6e, 0x6f, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x41, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x45, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1f, 0x2e, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3f, + 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, 0x19, 0x2e, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, + 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x17, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, + 0x43, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, + 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, + 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4e, 0x66, 0x63, 0x43, 0x61, + 0x72, 0x64, 0x49, 0x64, 0x73, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x46, 0x0a, + 0x0c, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x49, 0x64, 0x73, 0x12, 0x19, 0x2e, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, + 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x4b, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x65, 0x6e, 0x74, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x73, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, + 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x73, 0x12, 0x4f, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x73, 0x12, 0x19, 0x2e, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, + 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x19, + 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, + 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, + 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x1a, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x07, 0x47, + 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x1a, 0x15, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x42, 0x27, 0x5a, 0x25, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2f, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x3b, 0x61, 0x70, 0x69, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_device_proto_rawDescOnce sync.Once + file_device_proto_rawDescData = file_device_proto_rawDesc +) + +func file_device_proto_rawDescGZIP() []byte { + file_device_proto_rawDescOnce.Do(func() { + file_device_proto_rawDescData = protoimpl.X.CompressGZIP(file_device_proto_rawDescData) + }) + return file_device_proto_rawDescData +} + +var file_device_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_device_proto_goTypes = []interface{}{ + (*Charge)(nil), // 0: pagerino.device.Charge + (*Location)(nil), // 1: pagerino.device.Location + (*DeviceBaseInfo)(nil), // 2: pagerino.device.DeviceBaseInfo + (*DeviceAllInfo)(nil), // 3: pagerino.device.DeviceAllInfo + (*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp + (*common.StrIndex)(nil), // 5: pagerino.common.StrIndex + (*common.References)(nil), // 6: pagerino.common.References + (*common.Activity)(nil), // 7: pagerino.common.Activity + (*common.Meta)(nil), // 8: pagerino.common.Meta +} +var file_device_proto_depIdxs = []int32{ + 4, // 0: pagerino.device.DeviceBaseInfo.last_online:type_name -> google.protobuf.Timestamp + 4, // 1: pagerino.device.DeviceAllInfo.last_online:type_name -> google.protobuf.Timestamp + 5, // 2: pagerino.device.DeviceService.GetAll:input_type -> pagerino.common.StrIndex + 5, // 3: pagerino.device.DeviceService.GetInfo:input_type -> pagerino.common.StrIndex + 5, // 4: pagerino.device.DeviceService.GetCharge:input_type -> pagerino.common.StrIndex + 5, // 5: pagerino.device.DeviceService.GetLocation:input_type -> pagerino.common.StrIndex + 5, // 6: pagerino.device.DeviceService.GetNfcCardIds:input_type -> pagerino.common.StrIndex + 5, // 7: pagerino.device.DeviceService.GetStatusIds:input_type -> pagerino.common.StrIndex + 5, // 8: pagerino.device.DeviceService.GetSentMessageIds:input_type -> pagerino.common.StrIndex + 5, // 9: pagerino.device.DeviceService.GetReceivedMessageIds:input_type -> pagerino.common.StrIndex + 5, // 10: pagerino.device.DeviceService.GetLogs:input_type -> pagerino.common.StrIndex + 5, // 11: pagerino.device.DeviceService.GetActivity:input_type -> pagerino.common.StrIndex + 5, // 12: pagerino.device.DeviceService.GetMeta:input_type -> pagerino.common.StrIndex + 3, // 13: pagerino.device.DeviceService.GetAll:output_type -> pagerino.device.DeviceAllInfo + 2, // 14: pagerino.device.DeviceService.GetInfo:output_type -> pagerino.device.DeviceBaseInfo + 0, // 15: pagerino.device.DeviceService.GetCharge:output_type -> pagerino.device.Charge + 1, // 16: pagerino.device.DeviceService.GetLocation:output_type -> pagerino.device.Location + 6, // 17: pagerino.device.DeviceService.GetNfcCardIds:output_type -> pagerino.common.References + 6, // 18: pagerino.device.DeviceService.GetStatusIds:output_type -> pagerino.common.References + 6, // 19: pagerino.device.DeviceService.GetSentMessageIds:output_type -> pagerino.common.References + 6, // 20: pagerino.device.DeviceService.GetReceivedMessageIds:output_type -> pagerino.common.References + 6, // 21: pagerino.device.DeviceService.GetLogs:output_type -> pagerino.common.References + 7, // 22: pagerino.device.DeviceService.GetActivity:output_type -> pagerino.common.Activity + 8, // 23: pagerino.device.DeviceService.GetMeta:output_type -> pagerino.common.Meta + 13, // [13:24] is the sub-list for method output_type + 2, // [2:13] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_device_proto_init() } +func file_device_proto_init() { + if File_device_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_device_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Charge); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_device_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Location); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_device_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeviceBaseInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_device_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeviceAllInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_device_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_device_proto_goTypes, + DependencyIndexes: file_device_proto_depIdxs, + MessageInfos: file_device_proto_msgTypes, + }.Build() + File_device_proto = out.File + file_device_proto_rawDesc = nil + file_device_proto_goTypes = nil + file_device_proto_depIdxs = nil +} diff --git a/AppServer/src/app_comm/api/device/device_grpc.pb.go b/AppServer/src/app_comm/api/device/device_grpc.pb.go new file mode 100644 index 0000000..3467714 --- /dev/null +++ b/AppServer/src/app_comm/api/device/device_grpc.pb.go @@ -0,0 +1,468 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package api_device + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + common "server/app_comm/api/common" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// DeviceServiceClient is the client API for DeviceService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type DeviceServiceClient interface { + // === DB information + GetAll(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*DeviceAllInfo, error) + GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*DeviceBaseInfo, error) + GetCharge(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*Charge, error) + GetLocation(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*Location, error) + // References + GetNfcCardIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + GetStatusIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + GetSentMessageIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + GetReceivedMessageIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + GetLogs(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + // Common + GetActivity(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Activity, error) + GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) +} + +type deviceServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewDeviceServiceClient(cc grpc.ClientConnInterface) DeviceServiceClient { + return &deviceServiceClient{cc} +} + +func (c *deviceServiceClient) GetAll(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*DeviceAllInfo, error) { + out := new(DeviceAllInfo) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetAll", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*DeviceBaseInfo, error) { + out := new(DeviceBaseInfo) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetCharge(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*Charge, error) { + out := new(Charge) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetCharge", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetLocation(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*Location, error) { + out := new(Location) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetLocation", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetNfcCardIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetNfcCardIds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetStatusIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetStatusIds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetSentMessageIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetSentMessageIds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetReceivedMessageIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetReceivedMessageIds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetLogs(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetLogs", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetActivity(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Activity, error) { + out := new(common.Activity) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetActivity", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) { + out := new(common.Meta) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetMeta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// DeviceServiceServer is the server API for DeviceService service. +// All implementations must embed UnimplementedDeviceServiceServer +// for forward compatibility +type DeviceServiceServer interface { + // === DB information + GetAll(context.Context, *common.StrIndex) (*DeviceAllInfo, error) + GetInfo(context.Context, *common.StrIndex) (*DeviceBaseInfo, error) + GetCharge(context.Context, *common.StrIndex) (*Charge, error) + GetLocation(context.Context, *common.StrIndex) (*Location, error) + // References + GetNfcCardIds(context.Context, *common.StrIndex) (*common.References, error) + GetStatusIds(context.Context, *common.StrIndex) (*common.References, error) + GetSentMessageIds(context.Context, *common.StrIndex) (*common.References, error) + GetReceivedMessageIds(context.Context, *common.StrIndex) (*common.References, error) + GetLogs(context.Context, *common.StrIndex) (*common.References, error) + // Common + GetActivity(context.Context, *common.StrIndex) (*common.Activity, error) + GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) + mustEmbedUnimplementedDeviceServiceServer() +} + +// UnimplementedDeviceServiceServer must be embedded to have forward compatible implementations. +type UnimplementedDeviceServiceServer struct { +} + +func (UnimplementedDeviceServiceServer) GetAll(context.Context, *common.StrIndex) (*DeviceAllInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAll not implemented") +} +func (UnimplementedDeviceServiceServer) GetInfo(context.Context, *common.StrIndex) (*DeviceBaseInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetInfo not implemented") +} +func (UnimplementedDeviceServiceServer) GetCharge(context.Context, *common.StrIndex) (*Charge, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetCharge not implemented") +} +func (UnimplementedDeviceServiceServer) GetLocation(context.Context, *common.StrIndex) (*Location, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetLocation not implemented") +} +func (UnimplementedDeviceServiceServer) GetNfcCardIds(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetNfcCardIds not implemented") +} +func (UnimplementedDeviceServiceServer) GetStatusIds(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetStatusIds not implemented") +} +func (UnimplementedDeviceServiceServer) GetSentMessageIds(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSentMessageIds not implemented") +} +func (UnimplementedDeviceServiceServer) GetReceivedMessageIds(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetReceivedMessageIds not implemented") +} +func (UnimplementedDeviceServiceServer) GetLogs(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetLogs not implemented") +} +func (UnimplementedDeviceServiceServer) GetActivity(context.Context, *common.StrIndex) (*common.Activity, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetActivity not implemented") +} +func (UnimplementedDeviceServiceServer) GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMeta not implemented") +} +func (UnimplementedDeviceServiceServer) mustEmbedUnimplementedDeviceServiceServer() {} + +// UnsafeDeviceServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to DeviceServiceServer will +// result in compilation errors. +type UnsafeDeviceServiceServer interface { + mustEmbedUnimplementedDeviceServiceServer() +} + +func RegisterDeviceServiceServer(s grpc.ServiceRegistrar, srv DeviceServiceServer) { + s.RegisterService(&DeviceService_ServiceDesc, srv) +} + +func _DeviceService_GetAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetAll(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetAll", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetAll(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetInfo(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetCharge_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetCharge(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetCharge", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetCharge(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetLocation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetLocation(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetLocation", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetLocation(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetNfcCardIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetNfcCardIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetNfcCardIds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetNfcCardIds(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetStatusIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetStatusIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetStatusIds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetStatusIds(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetSentMessageIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetSentMessageIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetSentMessageIds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetSentMessageIds(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetReceivedMessageIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetReceivedMessageIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetReceivedMessageIds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetReceivedMessageIds(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetLogs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetLogs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetLogs", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetLogs(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetActivity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetActivity(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetActivity", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetActivity(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetMeta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetMeta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetMeta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetMeta(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +// DeviceService_ServiceDesc is the grpc.ServiceDesc for DeviceService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var DeviceService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pagerino.device.DeviceService", + HandlerType: (*DeviceServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetAll", + Handler: _DeviceService_GetAll_Handler, + }, + { + MethodName: "GetInfo", + Handler: _DeviceService_GetInfo_Handler, + }, + { + MethodName: "GetCharge", + Handler: _DeviceService_GetCharge_Handler, + }, + { + MethodName: "GetLocation", + Handler: _DeviceService_GetLocation_Handler, + }, + { + MethodName: "GetNfcCardIds", + Handler: _DeviceService_GetNfcCardIds_Handler, + }, + { + MethodName: "GetStatusIds", + Handler: _DeviceService_GetStatusIds_Handler, + }, + { + MethodName: "GetSentMessageIds", + Handler: _DeviceService_GetSentMessageIds_Handler, + }, + { + MethodName: "GetReceivedMessageIds", + Handler: _DeviceService_GetReceivedMessageIds_Handler, + }, + { + MethodName: "GetLogs", + Handler: _DeviceService_GetLogs_Handler, + }, + { + MethodName: "GetActivity", + Handler: _DeviceService_GetActivity_Handler, + }, + { + MethodName: "GetMeta", + Handler: _DeviceService_GetMeta_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "device.proto", +} diff --git a/AppServer/src/app_comm/api/log/log.pb.go b/AppServer/src/app_comm/api/log/log.pb.go new file mode 100644 index 0000000..002933a --- /dev/null +++ b/AppServer/src/app_comm/api/log/log.pb.go @@ -0,0 +1,81 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: log.proto + +package api_log + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + common "server/app_comm/api/common" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +var File_log_proto protoreflect.FileDescriptor + +var file_log_proto_rawDesc = []byte{ + 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x70, 0x61, 0x67, + 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x6c, 0x6f, 0x67, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x8b, 0x01, 0x0a, 0x0a, 0x4c, 0x6f, 0x67, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x49, 0x64, 0x73, 0x12, 0x16, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1b, + 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x07, 0x47, + 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x16, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x15, + 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x42, 0x21, 0x5a, 0x1f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, + 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6c, 0x6f, 0x67, + 0x3b, 0x61, 0x70, 0x69, 0x5f, 0x6c, 0x6f, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_log_proto_goTypes = []interface{}{ + (*common.Index)(nil), // 0: pagerino.common.Index + (*common.References)(nil), // 1: pagerino.common.References + (*common.Meta)(nil), // 2: pagerino.common.Meta +} +var file_log_proto_depIdxs = []int32{ + 0, // 0: pagerino.log.LogService.GetChangeIds:input_type -> pagerino.common.Index + 0, // 1: pagerino.log.LogService.GetMeta:input_type -> pagerino.common.Index + 1, // 2: pagerino.log.LogService.GetChangeIds:output_type -> pagerino.common.References + 2, // 3: pagerino.log.LogService.GetMeta:output_type -> pagerino.common.Meta + 2, // [2:4] is the sub-list for method output_type + 0, // [0:2] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_log_proto_init() } +func file_log_proto_init() { + if File_log_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_log_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_log_proto_goTypes, + DependencyIndexes: file_log_proto_depIdxs, + }.Build() + File_log_proto = out.File + file_log_proto_rawDesc = nil + file_log_proto_goTypes = nil + file_log_proto_depIdxs = nil +} diff --git a/AppServer/src/app_comm/api/log/log_grpc.pb.go b/AppServer/src/app_comm/api/log/log_grpc.pb.go new file mode 100644 index 0000000..83739f9 --- /dev/null +++ b/AppServer/src/app_comm/api/log/log_grpc.pb.go @@ -0,0 +1,144 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package api_log + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + common "server/app_comm/api/common" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// LogServiceClient is the client API for LogService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type LogServiceClient interface { + // === DB information + // References + GetChangeIds(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.References, error) + // Common + GetMeta(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Meta, error) +} + +type logServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewLogServiceClient(cc grpc.ClientConnInterface) LogServiceClient { + return &logServiceClient{cc} +} + +func (c *logServiceClient) GetChangeIds(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.log.LogService/GetChangeIds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *logServiceClient) GetMeta(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Meta, error) { + out := new(common.Meta) + err := c.cc.Invoke(ctx, "/pagerino.log.LogService/GetMeta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// LogServiceServer is the server API for LogService service. +// All implementations must embed UnimplementedLogServiceServer +// for forward compatibility +type LogServiceServer interface { + // === DB information + // References + GetChangeIds(context.Context, *common.Index) (*common.References, error) + // Common + GetMeta(context.Context, *common.Index) (*common.Meta, error) + mustEmbedUnimplementedLogServiceServer() +} + +// UnimplementedLogServiceServer must be embedded to have forward compatible implementations. +type UnimplementedLogServiceServer struct { +} + +func (UnimplementedLogServiceServer) GetChangeIds(context.Context, *common.Index) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetChangeIds not implemented") +} +func (UnimplementedLogServiceServer) GetMeta(context.Context, *common.Index) (*common.Meta, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMeta not implemented") +} +func (UnimplementedLogServiceServer) mustEmbedUnimplementedLogServiceServer() {} + +// UnsafeLogServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to LogServiceServer will +// result in compilation errors. +type UnsafeLogServiceServer interface { + mustEmbedUnimplementedLogServiceServer() +} + +func RegisterLogServiceServer(s grpc.ServiceRegistrar, srv LogServiceServer) { + s.RegisterService(&LogService_ServiceDesc, srv) +} + +func _LogService_GetChangeIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(LogServiceServer).GetChangeIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.log.LogService/GetChangeIds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LogServiceServer).GetChangeIds(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +func _LogService_GetMeta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(LogServiceServer).GetMeta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.log.LogService/GetMeta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LogServiceServer).GetMeta(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +// LogService_ServiceDesc is the grpc.ServiceDesc for LogService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var LogService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pagerino.log.LogService", + HandlerType: (*LogServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetChangeIds", + Handler: _LogService_GetChangeIds_Handler, + }, + { + MethodName: "GetMeta", + Handler: _LogService_GetMeta_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "log.proto", +} diff --git a/AppServer/src/app_comm/api/message/message.pb.go b/AppServer/src/app_comm/api/message/message.pb.go new file mode 100644 index 0000000..db87644 --- /dev/null +++ b/AppServer/src/app_comm/api/message/message.pb.go @@ -0,0 +1,267 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: message.proto + +package api_message + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + common "server/app_comm/api/common" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type MessageBasicInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SenderId int32 `protobuf:"varint,1,opt,name=sender_id,json=senderId,proto3" json:"sender_id,omitempty"` + ReceiverId int32 `protobuf:"varint,2,opt,name=receiver_id,json=receiverId,proto3" json:"receiver_id,omitempty"` + Payload string `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` +} + +func (x *MessageBasicInfo) Reset() { + *x = MessageBasicInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_message_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MessageBasicInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessageBasicInfo) ProtoMessage() {} + +func (x *MessageBasicInfo) ProtoReflect() protoreflect.Message { + mi := &file_message_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MessageBasicInfo.ProtoReflect.Descriptor instead. +func (*MessageBasicInfo) Descriptor() ([]byte, []int) { + return file_message_proto_rawDescGZIP(), []int{0} +} + +func (x *MessageBasicInfo) GetSenderId() int32 { + if x != nil { + return x.SenderId + } + return 0 +} + +func (x *MessageBasicInfo) GetReceiverId() int32 { + if x != nil { + return x.ReceiverId + } + return 0 +} + +func (x *MessageBasicInfo) GetPayload() string { + if x != nil { + return x.Payload + } + return "" +} + +func (x *MessageBasicInfo) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +type Payload struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Payload string `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` +} + +func (x *Payload) Reset() { + *x = Payload{} + if protoimpl.UnsafeEnabled { + mi := &file_message_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Payload) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Payload) ProtoMessage() {} + +func (x *Payload) ProtoReflect() protoreflect.Message { + mi := &file_message_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Payload.ProtoReflect.Descriptor instead. +func (*Payload) Descriptor() ([]byte, []int) { + return file_message_proto_rawDescGZIP(), []int{1} +} + +func (x *Payload) GetPayload() string { + if x != nil { + return x.Payload + } + return "" +} + +var File_message_proto protoreflect.FileDescriptor + +var file_message_proto_rawDesc = []byte{ + 0x0a, 0x0d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x10, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0xa5, 0x01, 0x0a, 0x10, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x61, 0x73, 0x69, + 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, + 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x39, 0x0a, + 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x23, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, + 0x6f, 0x61, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x32, 0xd2, 0x01, + 0x0a, 0x0e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x45, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x1a, 0x22, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x61, + 0x73, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3f, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x50, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x16, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x19, 0x2e, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x2e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x38, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, + 0x65, 0x74, 0x61, 0x12, 0x16, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x15, 0x2e, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, + 0x74, 0x61, 0x42, 0x29, 0x5a, 0x27, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x70, + 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x3b, 0x61, 0x70, 0x69, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_message_proto_rawDescOnce sync.Once + file_message_proto_rawDescData = file_message_proto_rawDesc +) + +func file_message_proto_rawDescGZIP() []byte { + file_message_proto_rawDescOnce.Do(func() { + file_message_proto_rawDescData = protoimpl.X.CompressGZIP(file_message_proto_rawDescData) + }) + return file_message_proto_rawDescData +} + +var file_message_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_message_proto_goTypes = []interface{}{ + (*MessageBasicInfo)(nil), // 0: pagerino.message.MessageBasicInfo + (*Payload)(nil), // 1: pagerino.message.Payload + (*timestamppb.Timestamp)(nil), // 2: google.protobuf.Timestamp + (*common.Index)(nil), // 3: pagerino.common.Index + (*common.Meta)(nil), // 4: pagerino.common.Meta +} +var file_message_proto_depIdxs = []int32{ + 2, // 0: pagerino.message.MessageBasicInfo.created_at:type_name -> google.protobuf.Timestamp + 3, // 1: pagerino.message.MessageService.GetInfo:input_type -> pagerino.common.Index + 3, // 2: pagerino.message.MessageService.GetPayload:input_type -> pagerino.common.Index + 3, // 3: pagerino.message.MessageService.GetMeta:input_type -> pagerino.common.Index + 0, // 4: pagerino.message.MessageService.GetInfo:output_type -> pagerino.message.MessageBasicInfo + 1, // 5: pagerino.message.MessageService.GetPayload:output_type -> pagerino.message.Payload + 4, // 6: pagerino.message.MessageService.GetMeta:output_type -> pagerino.common.Meta + 4, // [4:7] is the sub-list for method output_type + 1, // [1:4] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_message_proto_init() } +func file_message_proto_init() { + if File_message_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_message_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MessageBasicInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_message_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Payload); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_message_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_message_proto_goTypes, + DependencyIndexes: file_message_proto_depIdxs, + MessageInfos: file_message_proto_msgTypes, + }.Build() + File_message_proto = out.File + file_message_proto_rawDesc = nil + file_message_proto_goTypes = nil + file_message_proto_depIdxs = nil +} diff --git a/AppServer/src/app_comm/api/message/message_grpc.pb.go b/AppServer/src/app_comm/api/message/message_grpc.pb.go new file mode 100644 index 0000000..b43c471 --- /dev/null +++ b/AppServer/src/app_comm/api/message/message_grpc.pb.go @@ -0,0 +1,178 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package api_message + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + common "server/app_comm/api/common" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// MessageServiceClient is the client API for MessageService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type MessageServiceClient interface { + // === DB information + GetInfo(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*MessageBasicInfo, error) + GetPayload(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*Payload, error) + // Common + GetMeta(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Meta, error) +} + +type messageServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewMessageServiceClient(cc grpc.ClientConnInterface) MessageServiceClient { + return &messageServiceClient{cc} +} + +func (c *messageServiceClient) GetInfo(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*MessageBasicInfo, error) { + out := new(MessageBasicInfo) + err := c.cc.Invoke(ctx, "/pagerino.message.MessageService/GetInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *messageServiceClient) GetPayload(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*Payload, error) { + out := new(Payload) + err := c.cc.Invoke(ctx, "/pagerino.message.MessageService/GetPayload", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *messageServiceClient) GetMeta(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Meta, error) { + out := new(common.Meta) + err := c.cc.Invoke(ctx, "/pagerino.message.MessageService/GetMeta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MessageServiceServer is the server API for MessageService service. +// All implementations must embed UnimplementedMessageServiceServer +// for forward compatibility +type MessageServiceServer interface { + // === DB information + GetInfo(context.Context, *common.Index) (*MessageBasicInfo, error) + GetPayload(context.Context, *common.Index) (*Payload, error) + // Common + GetMeta(context.Context, *common.Index) (*common.Meta, error) + mustEmbedUnimplementedMessageServiceServer() +} + +// UnimplementedMessageServiceServer must be embedded to have forward compatible implementations. +type UnimplementedMessageServiceServer struct { +} + +func (UnimplementedMessageServiceServer) GetInfo(context.Context, *common.Index) (*MessageBasicInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetInfo not implemented") +} +func (UnimplementedMessageServiceServer) GetPayload(context.Context, *common.Index) (*Payload, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPayload not implemented") +} +func (UnimplementedMessageServiceServer) GetMeta(context.Context, *common.Index) (*common.Meta, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMeta not implemented") +} +func (UnimplementedMessageServiceServer) mustEmbedUnimplementedMessageServiceServer() {} + +// UnsafeMessageServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to MessageServiceServer will +// result in compilation errors. +type UnsafeMessageServiceServer interface { + mustEmbedUnimplementedMessageServiceServer() +} + +func RegisterMessageServiceServer(s grpc.ServiceRegistrar, srv MessageServiceServer) { + s.RegisterService(&MessageService_ServiceDesc, srv) +} + +func _MessageService_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MessageServiceServer).GetInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.message.MessageService/GetInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MessageServiceServer).GetInfo(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +func _MessageService_GetPayload_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MessageServiceServer).GetPayload(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.message.MessageService/GetPayload", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MessageServiceServer).GetPayload(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +func _MessageService_GetMeta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MessageServiceServer).GetMeta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.message.MessageService/GetMeta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MessageServiceServer).GetMeta(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +// MessageService_ServiceDesc is the grpc.ServiceDesc for MessageService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var MessageService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pagerino.message.MessageService", + HandlerType: (*MessageServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetInfo", + Handler: _MessageService_GetInfo_Handler, + }, + { + MethodName: "GetPayload", + Handler: _MessageService_GetPayload_Handler, + }, + { + MethodName: "GetMeta", + Handler: _MessageService_GetMeta_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "message.proto", +} diff --git a/AppServer/src/app_comm/api/nfccard/nfccard.pb.go b/AppServer/src/app_comm/api/nfccard/nfccard.pb.go new file mode 100644 index 0000000..c055bcc --- /dev/null +++ b/AppServer/src/app_comm/api/nfccard/nfccard.pb.go @@ -0,0 +1,168 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: nfccard.proto + +package api_nfccard + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + common "server/app_comm/api/common" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type NfcCardBaseInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Uid string `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"` +} + +func (x *NfcCardBaseInfo) Reset() { + *x = NfcCardBaseInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_nfccard_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NfcCardBaseInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NfcCardBaseInfo) ProtoMessage() {} + +func (x *NfcCardBaseInfo) ProtoReflect() protoreflect.Message { + mi := &file_nfccard_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NfcCardBaseInfo.ProtoReflect.Descriptor instead. +func (*NfcCardBaseInfo) Descriptor() ([]byte, []int) { + return file_nfccard_proto_rawDescGZIP(), []int{0} +} + +func (x *NfcCardBaseInfo) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + +var File_nfccard_proto protoreflect.FileDescriptor + +var file_nfccard_proto_rawDesc = []byte{ + 0x0a, 0x0d, 0x6e, 0x66, 0x63, 0x63, 0x61, 0x72, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x11, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x6e, 0x66, 0x63, 0x5f, 0x63, 0x61, + 0x72, 0x64, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x23, 0x0a, 0x0f, 0x4e, 0x66, 0x63, 0x43, 0x61, 0x72, 0x64, 0x42, 0x61, 0x73, 0x65, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x75, 0x69, 0x64, 0x32, 0xd4, 0x01, 0x0a, 0x0e, 0x4e, 0x66, 0x63, 0x43, 0x61, 0x72, + 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x22, 0x2e, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x6e, 0x66, 0x63, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x2e, + 0x4e, 0x66, 0x63, 0x43, 0x61, 0x72, 0x64, 0x42, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x41, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x16, + 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1a, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x12, 0x38, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x16, 0x2e, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x15, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x42, 0x29, 0x5a, 0x27, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x6e, 0x66, 0x63, 0x63, 0x61, 0x72, 0x64, 0x3b, 0x61, 0x70, 0x69, 0x5f, + 0x6e, 0x66, 0x63, 0x63, 0x61, 0x72, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_nfccard_proto_rawDescOnce sync.Once + file_nfccard_proto_rawDescData = file_nfccard_proto_rawDesc +) + +func file_nfccard_proto_rawDescGZIP() []byte { + file_nfccard_proto_rawDescOnce.Do(func() { + file_nfccard_proto_rawDescData = protoimpl.X.CompressGZIP(file_nfccard_proto_rawDescData) + }) + return file_nfccard_proto_rawDescData +} + +var file_nfccard_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_nfccard_proto_goTypes = []interface{}{ + (*NfcCardBaseInfo)(nil), // 0: pagerino.nfc_card.NfcCardBaseInfo + (*common.Index)(nil), // 1: pagerino.common.Index + (*common.Reference)(nil), // 2: pagerino.common.Reference + (*common.Meta)(nil), // 3: pagerino.common.Meta +} +var file_nfccard_proto_depIdxs = []int32{ + 1, // 0: pagerino.nfc_card.NfcCardService.GetInfo:input_type -> pagerino.common.Index + 1, // 1: pagerino.nfc_card.NfcCardService.GetDeviceId:input_type -> pagerino.common.Index + 1, // 2: pagerino.nfc_card.NfcCardService.GetMeta:input_type -> pagerino.common.Index + 0, // 3: pagerino.nfc_card.NfcCardService.GetInfo:output_type -> pagerino.nfc_card.NfcCardBaseInfo + 2, // 4: pagerino.nfc_card.NfcCardService.GetDeviceId:output_type -> pagerino.common.Reference + 3, // 5: pagerino.nfc_card.NfcCardService.GetMeta:output_type -> pagerino.common.Meta + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_nfccard_proto_init() } +func file_nfccard_proto_init() { + if File_nfccard_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_nfccard_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NfcCardBaseInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_nfccard_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_nfccard_proto_goTypes, + DependencyIndexes: file_nfccard_proto_depIdxs, + MessageInfos: file_nfccard_proto_msgTypes, + }.Build() + File_nfccard_proto = out.File + file_nfccard_proto_rawDesc = nil + file_nfccard_proto_goTypes = nil + file_nfccard_proto_depIdxs = nil +} diff --git a/AppServer/src/app_comm/api/nfccard/nfccard_grpc.pb.go b/AppServer/src/app_comm/api/nfccard/nfccard_grpc.pb.go new file mode 100644 index 0000000..eb0bade --- /dev/null +++ b/AppServer/src/app_comm/api/nfccard/nfccard_grpc.pb.go @@ -0,0 +1,180 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package api_nfccard + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + common "server/app_comm/api/common" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// NfcCardServiceClient is the client API for NfcCardService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type NfcCardServiceClient interface { + // === DB information + GetInfo(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*NfcCardBaseInfo, error) + // References + GetDeviceId(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Reference, error) + // Common + GetMeta(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Meta, error) +} + +type nfcCardServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewNfcCardServiceClient(cc grpc.ClientConnInterface) NfcCardServiceClient { + return &nfcCardServiceClient{cc} +} + +func (c *nfcCardServiceClient) GetInfo(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*NfcCardBaseInfo, error) { + out := new(NfcCardBaseInfo) + err := c.cc.Invoke(ctx, "/pagerino.nfc_card.NfcCardService/GetInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *nfcCardServiceClient) GetDeviceId(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Reference, error) { + out := new(common.Reference) + err := c.cc.Invoke(ctx, "/pagerino.nfc_card.NfcCardService/GetDeviceId", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *nfcCardServiceClient) GetMeta(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Meta, error) { + out := new(common.Meta) + err := c.cc.Invoke(ctx, "/pagerino.nfc_card.NfcCardService/GetMeta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// NfcCardServiceServer is the server API for NfcCardService service. +// All implementations must embed UnimplementedNfcCardServiceServer +// for forward compatibility +type NfcCardServiceServer interface { + // === DB information + GetInfo(context.Context, *common.Index) (*NfcCardBaseInfo, error) + // References + GetDeviceId(context.Context, *common.Index) (*common.Reference, error) + // Common + GetMeta(context.Context, *common.Index) (*common.Meta, error) + mustEmbedUnimplementedNfcCardServiceServer() +} + +// UnimplementedNfcCardServiceServer must be embedded to have forward compatible implementations. +type UnimplementedNfcCardServiceServer struct { +} + +func (UnimplementedNfcCardServiceServer) GetInfo(context.Context, *common.Index) (*NfcCardBaseInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetInfo not implemented") +} +func (UnimplementedNfcCardServiceServer) GetDeviceId(context.Context, *common.Index) (*common.Reference, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetDeviceId not implemented") +} +func (UnimplementedNfcCardServiceServer) GetMeta(context.Context, *common.Index) (*common.Meta, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMeta not implemented") +} +func (UnimplementedNfcCardServiceServer) mustEmbedUnimplementedNfcCardServiceServer() {} + +// UnsafeNfcCardServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to NfcCardServiceServer will +// result in compilation errors. +type UnsafeNfcCardServiceServer interface { + mustEmbedUnimplementedNfcCardServiceServer() +} + +func RegisterNfcCardServiceServer(s grpc.ServiceRegistrar, srv NfcCardServiceServer) { + s.RegisterService(&NfcCardService_ServiceDesc, srv) +} + +func _NfcCardService_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NfcCardServiceServer).GetInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.nfc_card.NfcCardService/GetInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NfcCardServiceServer).GetInfo(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +func _NfcCardService_GetDeviceId_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NfcCardServiceServer).GetDeviceId(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.nfc_card.NfcCardService/GetDeviceId", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NfcCardServiceServer).GetDeviceId(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +func _NfcCardService_GetMeta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NfcCardServiceServer).GetMeta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.nfc_card.NfcCardService/GetMeta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NfcCardServiceServer).GetMeta(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +// NfcCardService_ServiceDesc is the grpc.ServiceDesc for NfcCardService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var NfcCardService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pagerino.nfc_card.NfcCardService", + HandlerType: (*NfcCardServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetInfo", + Handler: _NfcCardService_GetInfo_Handler, + }, + { + MethodName: "GetDeviceId", + Handler: _NfcCardService_GetDeviceId_Handler, + }, + { + MethodName: "GetMeta", + Handler: _NfcCardService_GetMeta_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "nfccard.proto", +} diff --git a/AppServer/src/app_comm/api/permission/permission.pb.go b/AppServer/src/app_comm/api/permission/permission.pb.go new file mode 100644 index 0000000..a728f8e --- /dev/null +++ b/AppServer/src/app_comm/api/permission/permission.pb.go @@ -0,0 +1,181 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: permission.proto + +package api_permission + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + common "server/app_comm/api/common" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type PermissionBasicInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` +} + +func (x *PermissionBasicInfo) Reset() { + *x = PermissionBasicInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_permission_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PermissionBasicInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PermissionBasicInfo) ProtoMessage() {} + +func (x *PermissionBasicInfo) ProtoReflect() protoreflect.Message { + mi := &file_permission_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PermissionBasicInfo.ProtoReflect.Descriptor instead. +func (*PermissionBasicInfo) Descriptor() ([]byte, []int) { + return file_permission_proto_rawDescGZIP(), []int{0} +} + +func (x *PermissionBasicInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *PermissionBasicInfo) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +var File_permission_proto protoreflect.FileDescriptor + +var file_permission_proto_rawDesc = []byte{ + 0x0a, 0x10, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x13, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4b, 0x0a, 0x13, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x42, 0x61, 0x73, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x32, 0xe6, 0x01, 0x0a, 0x11, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4e, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x28, + 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x42, + 0x61, 0x73, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x44, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x52, + 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x73, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x3b, + 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, + 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, + 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x15, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x42, 0x2f, 0x5a, 0x2d, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3b, 0x61, 0x70, + 0x69, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_permission_proto_rawDescOnce sync.Once + file_permission_proto_rawDescData = file_permission_proto_rawDesc +) + +func file_permission_proto_rawDescGZIP() []byte { + file_permission_proto_rawDescOnce.Do(func() { + file_permission_proto_rawDescData = protoimpl.X.CompressGZIP(file_permission_proto_rawDescData) + }) + return file_permission_proto_rawDescData +} + +var file_permission_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_permission_proto_goTypes = []interface{}{ + (*PermissionBasicInfo)(nil), // 0: pagerino.permission.PermissionBasicInfo + (*common.StrIndex)(nil), // 1: pagerino.common.StrIndex + (*common.References)(nil), // 2: pagerino.common.References + (*common.Meta)(nil), // 3: pagerino.common.Meta +} +var file_permission_proto_depIdxs = []int32{ + 1, // 0: pagerino.permission.PermissionService.GetInfo:input_type -> pagerino.common.StrIndex + 1, // 1: pagerino.permission.PermissionService.GetRoleIds:input_type -> pagerino.common.StrIndex + 1, // 2: pagerino.permission.PermissionService.GetMeta:input_type -> pagerino.common.StrIndex + 0, // 3: pagerino.permission.PermissionService.GetInfo:output_type -> pagerino.permission.PermissionBasicInfo + 2, // 4: pagerino.permission.PermissionService.GetRoleIds:output_type -> pagerino.common.References + 3, // 5: pagerino.permission.PermissionService.GetMeta:output_type -> pagerino.common.Meta + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_permission_proto_init() } +func file_permission_proto_init() { + if File_permission_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_permission_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PermissionBasicInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_permission_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_permission_proto_goTypes, + DependencyIndexes: file_permission_proto_depIdxs, + MessageInfos: file_permission_proto_msgTypes, + }.Build() + File_permission_proto = out.File + file_permission_proto_rawDesc = nil + file_permission_proto_goTypes = nil + file_permission_proto_depIdxs = nil +} diff --git a/AppServer/src/app_comm/api/permission/permission_grpc.pb.go b/AppServer/src/app_comm/api/permission/permission_grpc.pb.go new file mode 100644 index 0000000..ec3370a --- /dev/null +++ b/AppServer/src/app_comm/api/permission/permission_grpc.pb.go @@ -0,0 +1,180 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package api_permission + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + common "server/app_comm/api/common" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// PermissionServiceClient is the client API for PermissionService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type PermissionServiceClient interface { + // === DB information + GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*PermissionBasicInfo, error) + // References + GetRoleIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + // Common + GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) +} + +type permissionServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewPermissionServiceClient(cc grpc.ClientConnInterface) PermissionServiceClient { + return &permissionServiceClient{cc} +} + +func (c *permissionServiceClient) GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*PermissionBasicInfo, error) { + out := new(PermissionBasicInfo) + err := c.cc.Invoke(ctx, "/pagerino.permission.PermissionService/GetInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *permissionServiceClient) GetRoleIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.permission.PermissionService/GetRoleIds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *permissionServiceClient) GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) { + out := new(common.Meta) + err := c.cc.Invoke(ctx, "/pagerino.permission.PermissionService/GetMeta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// PermissionServiceServer is the server API for PermissionService service. +// All implementations must embed UnimplementedPermissionServiceServer +// for forward compatibility +type PermissionServiceServer interface { + // === DB information + GetInfo(context.Context, *common.StrIndex) (*PermissionBasicInfo, error) + // References + GetRoleIds(context.Context, *common.StrIndex) (*common.References, error) + // Common + GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) + mustEmbedUnimplementedPermissionServiceServer() +} + +// UnimplementedPermissionServiceServer must be embedded to have forward compatible implementations. +type UnimplementedPermissionServiceServer struct { +} + +func (UnimplementedPermissionServiceServer) GetInfo(context.Context, *common.StrIndex) (*PermissionBasicInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetInfo not implemented") +} +func (UnimplementedPermissionServiceServer) GetRoleIds(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetRoleIds not implemented") +} +func (UnimplementedPermissionServiceServer) GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMeta not implemented") +} +func (UnimplementedPermissionServiceServer) mustEmbedUnimplementedPermissionServiceServer() {} + +// UnsafePermissionServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to PermissionServiceServer will +// result in compilation errors. +type UnsafePermissionServiceServer interface { + mustEmbedUnimplementedPermissionServiceServer() +} + +func RegisterPermissionServiceServer(s grpc.ServiceRegistrar, srv PermissionServiceServer) { + s.RegisterService(&PermissionService_ServiceDesc, srv) +} + +func _PermissionService_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PermissionServiceServer).GetInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.permission.PermissionService/GetInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PermissionServiceServer).GetInfo(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _PermissionService_GetRoleIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PermissionServiceServer).GetRoleIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.permission.PermissionService/GetRoleIds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PermissionServiceServer).GetRoleIds(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _PermissionService_GetMeta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PermissionServiceServer).GetMeta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.permission.PermissionService/GetMeta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PermissionServiceServer).GetMeta(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +// PermissionService_ServiceDesc is the grpc.ServiceDesc for PermissionService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var PermissionService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pagerino.permission.PermissionService", + HandlerType: (*PermissionServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetInfo", + Handler: _PermissionService_GetInfo_Handler, + }, + { + MethodName: "GetRoleIds", + Handler: _PermissionService_GetRoleIds_Handler, + }, + { + MethodName: "GetMeta", + Handler: _PermissionService_GetMeta_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "permission.proto", +} diff --git a/AppServer/src/app_comm/api/role/role.pb.go b/AppServer/src/app_comm/api/role/role.pb.go new file mode 100644 index 0000000..09aa284 --- /dev/null +++ b/AppServer/src/app_comm/api/role/role.pb.go @@ -0,0 +1,184 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: role.proto + +package api_role + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + common "server/app_comm/api/common" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type RoleBasicInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` +} + +func (x *RoleBasicInfo) Reset() { + *x = RoleBasicInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_role_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RoleBasicInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RoleBasicInfo) ProtoMessage() {} + +func (x *RoleBasicInfo) ProtoReflect() protoreflect.Message { + mi := &file_role_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RoleBasicInfo.ProtoReflect.Descriptor instead. +func (*RoleBasicInfo) Descriptor() ([]byte, []int) { + return file_role_proto_rawDescGZIP(), []int{0} +} + +func (x *RoleBasicInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *RoleBasicInfo) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +var File_role_proto protoreflect.FileDescriptor + +var file_role_proto_rawDesc = []byte{ + 0x0a, 0x0a, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x45, 0x0a, 0x0d, 0x52, 0x6f, 0x6c, + 0x65, 0x42, 0x61, 0x73, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x32, 0xa0, 0x02, 0x0a, 0x0b, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x42, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x2e, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, + 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1c, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x61, 0x73, 0x69, 0x63, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4a, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, + 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, + 0x12, 0x44, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x19, + 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, + 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, + 0x61, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x15, 0x2e, 0x70, + 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, + 0x65, 0x74, 0x61, 0x42, 0x23, 0x5a, 0x21, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x61, 0x70, + 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x3b, + 0x61, 0x70, 0x69, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_role_proto_rawDescOnce sync.Once + file_role_proto_rawDescData = file_role_proto_rawDesc +) + +func file_role_proto_rawDescGZIP() []byte { + file_role_proto_rawDescOnce.Do(func() { + file_role_proto_rawDescData = protoimpl.X.CompressGZIP(file_role_proto_rawDescData) + }) + return file_role_proto_rawDescData +} + +var file_role_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_role_proto_goTypes = []interface{}{ + (*RoleBasicInfo)(nil), // 0: pagerino.role.RoleBasicInfo + (*common.StrIndex)(nil), // 1: pagerino.common.StrIndex + (*common.References)(nil), // 2: pagerino.common.References + (*common.Meta)(nil), // 3: pagerino.common.Meta +} +var file_role_proto_depIdxs = []int32{ + 1, // 0: pagerino.role.RoleService.GetInfo:input_type -> pagerino.common.StrIndex + 1, // 1: pagerino.role.RoleService.GetPermissionIds:input_type -> pagerino.common.StrIndex + 1, // 2: pagerino.role.RoleService.GetUserIds:input_type -> pagerino.common.StrIndex + 1, // 3: pagerino.role.RoleService.GetMeta:input_type -> pagerino.common.StrIndex + 0, // 4: pagerino.role.RoleService.GetInfo:output_type -> pagerino.role.RoleBasicInfo + 2, // 5: pagerino.role.RoleService.GetPermissionIds:output_type -> pagerino.common.References + 2, // 6: pagerino.role.RoleService.GetUserIds:output_type -> pagerino.common.References + 3, // 7: pagerino.role.RoleService.GetMeta:output_type -> pagerino.common.Meta + 4, // [4:8] is the sub-list for method output_type + 0, // [0:4] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_role_proto_init() } +func file_role_proto_init() { + if File_role_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_role_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RoleBasicInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_role_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_role_proto_goTypes, + DependencyIndexes: file_role_proto_depIdxs, + MessageInfos: file_role_proto_msgTypes, + }.Build() + File_role_proto = out.File + file_role_proto_rawDesc = nil + file_role_proto_goTypes = nil + file_role_proto_depIdxs = nil +} diff --git a/AppServer/src/app_comm/api/role/role_grpc.pb.go b/AppServer/src/app_comm/api/role/role_grpc.pb.go new file mode 100644 index 0000000..b5bf872 --- /dev/null +++ b/AppServer/src/app_comm/api/role/role_grpc.pb.go @@ -0,0 +1,216 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package api_role + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + common "server/app_comm/api/common" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// RoleServiceClient is the client API for RoleService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type RoleServiceClient interface { + // === DB information + GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*RoleBasicInfo, error) + // References + GetPermissionIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + GetUserIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + // Common + GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) +} + +type roleServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewRoleServiceClient(cc grpc.ClientConnInterface) RoleServiceClient { + return &roleServiceClient{cc} +} + +func (c *roleServiceClient) GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*RoleBasicInfo, error) { + out := new(RoleBasicInfo) + err := c.cc.Invoke(ctx, "/pagerino.role.RoleService/GetInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *roleServiceClient) GetPermissionIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.role.RoleService/GetPermissionIds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *roleServiceClient) GetUserIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.role.RoleService/GetUserIds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *roleServiceClient) GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) { + out := new(common.Meta) + err := c.cc.Invoke(ctx, "/pagerino.role.RoleService/GetMeta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// RoleServiceServer is the server API for RoleService service. +// All implementations must embed UnimplementedRoleServiceServer +// for forward compatibility +type RoleServiceServer interface { + // === DB information + GetInfo(context.Context, *common.StrIndex) (*RoleBasicInfo, error) + // References + GetPermissionIds(context.Context, *common.StrIndex) (*common.References, error) + GetUserIds(context.Context, *common.StrIndex) (*common.References, error) + // Common + GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) + mustEmbedUnimplementedRoleServiceServer() +} + +// UnimplementedRoleServiceServer must be embedded to have forward compatible implementations. +type UnimplementedRoleServiceServer struct { +} + +func (UnimplementedRoleServiceServer) GetInfo(context.Context, *common.StrIndex) (*RoleBasicInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetInfo not implemented") +} +func (UnimplementedRoleServiceServer) GetPermissionIds(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPermissionIds not implemented") +} +func (UnimplementedRoleServiceServer) GetUserIds(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetUserIds not implemented") +} +func (UnimplementedRoleServiceServer) GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMeta not implemented") +} +func (UnimplementedRoleServiceServer) mustEmbedUnimplementedRoleServiceServer() {} + +// UnsafeRoleServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to RoleServiceServer will +// result in compilation errors. +type UnsafeRoleServiceServer interface { + mustEmbedUnimplementedRoleServiceServer() +} + +func RegisterRoleServiceServer(s grpc.ServiceRegistrar, srv RoleServiceServer) { + s.RegisterService(&RoleService_ServiceDesc, srv) +} + +func _RoleService_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoleServiceServer).GetInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.role.RoleService/GetInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoleServiceServer).GetInfo(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoleService_GetPermissionIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoleServiceServer).GetPermissionIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.role.RoleService/GetPermissionIds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoleServiceServer).GetPermissionIds(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoleService_GetUserIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoleServiceServer).GetUserIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.role.RoleService/GetUserIds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoleServiceServer).GetUserIds(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoleService_GetMeta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoleServiceServer).GetMeta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.role.RoleService/GetMeta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoleServiceServer).GetMeta(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +// RoleService_ServiceDesc is the grpc.ServiceDesc for RoleService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var RoleService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pagerino.role.RoleService", + HandlerType: (*RoleServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetInfo", + Handler: _RoleService_GetInfo_Handler, + }, + { + MethodName: "GetPermissionIds", + Handler: _RoleService_GetPermissionIds_Handler, + }, + { + MethodName: "GetUserIds", + Handler: _RoleService_GetUserIds_Handler, + }, + { + MethodName: "GetMeta", + Handler: _RoleService_GetMeta_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "role.proto", +} diff --git a/AppServer/src/app_comm/api/status/status.pb.go b/AppServer/src/app_comm/api/status/status.pb.go new file mode 100644 index 0000000..5a50e8c --- /dev/null +++ b/AppServer/src/app_comm/api/status/status.pb.go @@ -0,0 +1,180 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: status.proto + +package api_status + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + common "server/app_comm/api/common" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type StatusBasicInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + InternalStatus int32 `protobuf:"zigzag32,1,opt,name=internal_status,json=internalStatus,proto3" json:"internal_status,omitempty"` + NativeStatus string `protobuf:"bytes,2,opt,name=native_status,json=nativeStatus,proto3" json:"native_status,omitempty"` +} + +func (x *StatusBasicInfo) Reset() { + *x = StatusBasicInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_status_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StatusBasicInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StatusBasicInfo) ProtoMessage() {} + +func (x *StatusBasicInfo) ProtoReflect() protoreflect.Message { + mi := &file_status_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StatusBasicInfo.ProtoReflect.Descriptor instead. +func (*StatusBasicInfo) Descriptor() ([]byte, []int) { + return file_status_proto_rawDescGZIP(), []int{0} +} + +func (x *StatusBasicInfo) GetInternalStatus() int32 { + if x != nil { + return x.InternalStatus + } + return 0 +} + +func (x *StatusBasicInfo) GetNativeStatus() string { + if x != nil { + return x.NativeStatus + } + return "" +} + +var File_status_proto protoreflect.FileDescriptor + +var file_status_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, + 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5f, 0x0a, + 0x0f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x61, 0x73, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x11, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x61, 0x74, + 0x69, 0x76, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x32, 0xda, + 0x01, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x46, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x2e, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, + 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x20, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, + 0x61, 0x73, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x44, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, + 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, + 0x65, 0x78, 0x1a, 0x1a, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x3b, + 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, + 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, + 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x15, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x42, 0x27, 0x5a, 0x25, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3b, 0x61, 0x70, 0x69, 0x5f, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_status_proto_rawDescOnce sync.Once + file_status_proto_rawDescData = file_status_proto_rawDesc +) + +func file_status_proto_rawDescGZIP() []byte { + file_status_proto_rawDescOnce.Do(func() { + file_status_proto_rawDescData = protoimpl.X.CompressGZIP(file_status_proto_rawDescData) + }) + return file_status_proto_rawDescData +} + +var file_status_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_status_proto_goTypes = []interface{}{ + (*StatusBasicInfo)(nil), // 0: pagerino.status.StatusBasicInfo + (*common.StrIndex)(nil), // 1: pagerino.common.StrIndex + (*common.Reference)(nil), // 2: pagerino.common.Reference + (*common.Meta)(nil), // 3: pagerino.common.Meta +} +var file_status_proto_depIdxs = []int32{ + 1, // 0: pagerino.status.StatusService.GetInfo:input_type -> pagerino.common.StrIndex + 1, // 1: pagerino.status.StatusService.GetDeviceId:input_type -> pagerino.common.StrIndex + 1, // 2: pagerino.status.StatusService.GetMeta:input_type -> pagerino.common.StrIndex + 0, // 3: pagerino.status.StatusService.GetInfo:output_type -> pagerino.status.StatusBasicInfo + 2, // 4: pagerino.status.StatusService.GetDeviceId:output_type -> pagerino.common.Reference + 3, // 5: pagerino.status.StatusService.GetMeta:output_type -> pagerino.common.Meta + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_status_proto_init() } +func file_status_proto_init() { + if File_status_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_status_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StatusBasicInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_status_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_status_proto_goTypes, + DependencyIndexes: file_status_proto_depIdxs, + MessageInfos: file_status_proto_msgTypes, + }.Build() + File_status_proto = out.File + file_status_proto_rawDesc = nil + file_status_proto_goTypes = nil + file_status_proto_depIdxs = nil +} diff --git a/AppServer/src/app_comm/api/status/status_grpc.pb.go b/AppServer/src/app_comm/api/status/status_grpc.pb.go new file mode 100644 index 0000000..6f6782d --- /dev/null +++ b/AppServer/src/app_comm/api/status/status_grpc.pb.go @@ -0,0 +1,180 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package api_status + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + common "server/app_comm/api/common" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// StatusServiceClient is the client API for StatusService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type StatusServiceClient interface { + // === DB information + GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*StatusBasicInfo, error) + // References + GetDeviceId(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Reference, error) + // Common + GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) +} + +type statusServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewStatusServiceClient(cc grpc.ClientConnInterface) StatusServiceClient { + return &statusServiceClient{cc} +} + +func (c *statusServiceClient) GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*StatusBasicInfo, error) { + out := new(StatusBasicInfo) + err := c.cc.Invoke(ctx, "/pagerino.status.StatusService/GetInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *statusServiceClient) GetDeviceId(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Reference, error) { + out := new(common.Reference) + err := c.cc.Invoke(ctx, "/pagerino.status.StatusService/GetDeviceId", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *statusServiceClient) GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) { + out := new(common.Meta) + err := c.cc.Invoke(ctx, "/pagerino.status.StatusService/GetMeta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// StatusServiceServer is the server API for StatusService service. +// All implementations must embed UnimplementedStatusServiceServer +// for forward compatibility +type StatusServiceServer interface { + // === DB information + GetInfo(context.Context, *common.StrIndex) (*StatusBasicInfo, error) + // References + GetDeviceId(context.Context, *common.StrIndex) (*common.Reference, error) + // Common + GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) + mustEmbedUnimplementedStatusServiceServer() +} + +// UnimplementedStatusServiceServer must be embedded to have forward compatible implementations. +type UnimplementedStatusServiceServer struct { +} + +func (UnimplementedStatusServiceServer) GetInfo(context.Context, *common.StrIndex) (*StatusBasicInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetInfo not implemented") +} +func (UnimplementedStatusServiceServer) GetDeviceId(context.Context, *common.StrIndex) (*common.Reference, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetDeviceId not implemented") +} +func (UnimplementedStatusServiceServer) GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMeta not implemented") +} +func (UnimplementedStatusServiceServer) mustEmbedUnimplementedStatusServiceServer() {} + +// UnsafeStatusServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to StatusServiceServer will +// result in compilation errors. +type UnsafeStatusServiceServer interface { + mustEmbedUnimplementedStatusServiceServer() +} + +func RegisterStatusServiceServer(s grpc.ServiceRegistrar, srv StatusServiceServer) { + s.RegisterService(&StatusService_ServiceDesc, srv) +} + +func _StatusService_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StatusServiceServer).GetInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.status.StatusService/GetInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StatusServiceServer).GetInfo(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _StatusService_GetDeviceId_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StatusServiceServer).GetDeviceId(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.status.StatusService/GetDeviceId", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StatusServiceServer).GetDeviceId(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _StatusService_GetMeta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StatusServiceServer).GetMeta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.status.StatusService/GetMeta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StatusServiceServer).GetMeta(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +// StatusService_ServiceDesc is the grpc.ServiceDesc for StatusService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var StatusService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pagerino.status.StatusService", + HandlerType: (*StatusServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetInfo", + Handler: _StatusService_GetInfo_Handler, + }, + { + MethodName: "GetDeviceId", + Handler: _StatusService_GetDeviceId_Handler, + }, + { + MethodName: "GetMeta", + Handler: _StatusService_GetMeta_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "status.proto", +} diff --git a/AppServer/src/app_comm/api/user/user.pb.go b/AppServer/src/app_comm/api/user/user.pb.go new file mode 100644 index 0000000..c483c78 --- /dev/null +++ b/AppServer/src/app_comm/api/user/user.pb.go @@ -0,0 +1,384 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: user.proto + +package api_user + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + common "server/app_comm/api/common" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Password struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Password string `protobuf:"bytes,1,opt,name=password,proto3" json:"password,omitempty"` +} + +func (x *Password) Reset() { + *x = Password{} + if protoimpl.UnsafeEnabled { + mi := &file_user_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Password) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Password) ProtoMessage() {} + +func (x *Password) ProtoReflect() protoreflect.Message { + mi := &file_user_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Password.ProtoReflect.Descriptor instead. +func (*Password) Descriptor() ([]byte, []int) { + return file_user_proto_rawDescGZIP(), []int{0} +} + +func (x *Password) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +type UserAllInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + RoleId int32 `protobuf:"varint,3,opt,name=role_id,json=roleId,proto3" json:"role_id,omitempty"` + LastOnline *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=last_online,json=lastOnline,proto3" json:"last_online,omitempty"` +} + +func (x *UserAllInfo) Reset() { + *x = UserAllInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_user_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UserAllInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserAllInfo) ProtoMessage() {} + +func (x *UserAllInfo) ProtoReflect() protoreflect.Message { + mi := &file_user_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UserAllInfo.ProtoReflect.Descriptor instead. +func (*UserAllInfo) Descriptor() ([]byte, []int) { + return file_user_proto_rawDescGZIP(), []int{1} +} + +func (x *UserAllInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UserAllInfo) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *UserAllInfo) GetRoleId() int32 { + if x != nil { + return x.RoleId + } + return 0 +} + +func (x *UserAllInfo) GetLastOnline() *timestamppb.Timestamp { + if x != nil { + return x.LastOnline + } + return nil +} + +type UserBaseInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + RoleId int32 `protobuf:"varint,2,opt,name=role_id,json=roleId,proto3" json:"role_id,omitempty"` + LastOnline *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_online,json=lastOnline,proto3" json:"last_online,omitempty"` +} + +func (x *UserBaseInfo) Reset() { + *x = UserBaseInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_user_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UserBaseInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserBaseInfo) ProtoMessage() {} + +func (x *UserBaseInfo) ProtoReflect() protoreflect.Message { + mi := &file_user_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UserBaseInfo.ProtoReflect.Descriptor instead. +func (*UserBaseInfo) Descriptor() ([]byte, []int) { + return file_user_proto_rawDescGZIP(), []int{2} +} + +func (x *UserBaseInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UserBaseInfo) GetRoleId() int32 { + if x != nil { + return x.RoleId + } + return 0 +} + +func (x *UserBaseInfo) GetLastOnline() *timestamppb.Timestamp { + if x != nil { + return x.LastOnline + } + return nil +} + +var File_user_proto protoreflect.FileDescriptor + +var file_user_proto_rawDesc = []byte{ + 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x26, 0x0a, 0x08, 0x50, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x22, 0x93, 0x01, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x41, 0x6c, 0x6c, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x0b, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, + 0x73, 0x74, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x78, 0x0a, 0x0c, 0x55, 0x73, 0x65, 0x72, + 0x42, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, + 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x72, + 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6f, 0x6e, + 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x4f, 0x6e, 0x6c, 0x69, + 0x6e, 0x65, 0x32, 0xa5, 0x04, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x3f, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x12, 0x19, 0x2e, 0x70, + 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, + 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1a, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, + 0x6e, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x41, 0x6c, 0x6c, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x41, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, + 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, + 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x61, + 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x41, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x1a, 0x17, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, + 0x2e, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x42, 0x0a, 0x09, 0x47, 0x65, 0x74, + 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x1a, 0x1a, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x46, 0x0a, + 0x0c, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x73, 0x12, 0x19, 0x2e, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, + 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, + 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, + 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, + 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, + 0x65, 0x78, 0x1a, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x3b, 0x0a, + 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, + 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x1a, 0x15, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x42, 0x23, 0x5a, 0x21, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x3b, 0x61, 0x70, 0x69, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_user_proto_rawDescOnce sync.Once + file_user_proto_rawDescData = file_user_proto_rawDesc +) + +func file_user_proto_rawDescGZIP() []byte { + file_user_proto_rawDescOnce.Do(func() { + file_user_proto_rawDescData = protoimpl.X.CompressGZIP(file_user_proto_rawDescData) + }) + return file_user_proto_rawDescData +} + +var file_user_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_user_proto_goTypes = []interface{}{ + (*Password)(nil), // 0: pagerino.user.Password + (*UserAllInfo)(nil), // 1: pagerino.user.UserAllInfo + (*UserBaseInfo)(nil), // 2: pagerino.user.UserBaseInfo + (*timestamppb.Timestamp)(nil), // 3: google.protobuf.Timestamp + (*common.StrIndex)(nil), // 4: pagerino.common.StrIndex + (*common.Reference)(nil), // 5: pagerino.common.Reference + (*common.References)(nil), // 6: pagerino.common.References + (*common.Activity)(nil), // 7: pagerino.common.Activity + (*common.Meta)(nil), // 8: pagerino.common.Meta +} +var file_user_proto_depIdxs = []int32{ + 3, // 0: pagerino.user.UserAllInfo.last_online:type_name -> google.protobuf.Timestamp + 3, // 1: pagerino.user.UserBaseInfo.last_online:type_name -> google.protobuf.Timestamp + 4, // 2: pagerino.user.UserService.GetAll:input_type -> pagerino.common.StrIndex + 4, // 3: pagerino.user.UserService.GetInfo:input_type -> pagerino.common.StrIndex + 4, // 4: pagerino.user.UserService.GetPassword:input_type -> pagerino.common.StrIndex + 4, // 5: pagerino.user.UserService.GetRoleId:input_type -> pagerino.common.StrIndex + 4, // 6: pagerino.user.UserService.GetDeviceIds:input_type -> pagerino.common.StrIndex + 4, // 7: pagerino.user.UserService.GetLogs:input_type -> pagerino.common.StrIndex + 4, // 8: pagerino.user.UserService.GetActivity:input_type -> pagerino.common.StrIndex + 4, // 9: pagerino.user.UserService.GetMeta:input_type -> pagerino.common.StrIndex + 1, // 10: pagerino.user.UserService.GetAll:output_type -> pagerino.user.UserAllInfo + 2, // 11: pagerino.user.UserService.GetInfo:output_type -> pagerino.user.UserBaseInfo + 0, // 12: pagerino.user.UserService.GetPassword:output_type -> pagerino.user.Password + 5, // 13: pagerino.user.UserService.GetRoleId:output_type -> pagerino.common.Reference + 6, // 14: pagerino.user.UserService.GetDeviceIds:output_type -> pagerino.common.References + 6, // 15: pagerino.user.UserService.GetLogs:output_type -> pagerino.common.References + 7, // 16: pagerino.user.UserService.GetActivity:output_type -> pagerino.common.Activity + 8, // 17: pagerino.user.UserService.GetMeta:output_type -> pagerino.common.Meta + 10, // [10:18] is the sub-list for method output_type + 2, // [2:10] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_user_proto_init() } +func file_user_proto_init() { + if File_user_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_user_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Password); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UserAllInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UserBaseInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_user_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_user_proto_goTypes, + DependencyIndexes: file_user_proto_depIdxs, + MessageInfos: file_user_proto_msgTypes, + }.Build() + File_user_proto = out.File + file_user_proto_rawDesc = nil + file_user_proto_goTypes = nil + file_user_proto_depIdxs = nil +} diff --git a/AppServer/src/app_comm/api/user/user_grpc.pb.go b/AppServer/src/app_comm/api/user/user_grpc.pb.go new file mode 100644 index 0000000..514b278 --- /dev/null +++ b/AppServer/src/app_comm/api/user/user_grpc.pb.go @@ -0,0 +1,360 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package api_user + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + common "server/app_comm/api/common" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// UserServiceClient is the client API for UserService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type UserServiceClient interface { + // === DB information + GetAll(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*UserAllInfo, error) + GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*UserBaseInfo, error) + GetPassword(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*Password, error) + // References + GetRoleId(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Reference, error) + GetDeviceIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + GetLogs(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + // Common + GetActivity(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Activity, error) + GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) +} + +type userServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewUserServiceClient(cc grpc.ClientConnInterface) UserServiceClient { + return &userServiceClient{cc} +} + +func (c *userServiceClient) GetAll(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*UserAllInfo, error) { + out := new(UserAllInfo) + err := c.cc.Invoke(ctx, "/pagerino.user.UserService/GetAll", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*UserBaseInfo, error) { + out := new(UserBaseInfo) + err := c.cc.Invoke(ctx, "/pagerino.user.UserService/GetInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GetPassword(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*Password, error) { + out := new(Password) + err := c.cc.Invoke(ctx, "/pagerino.user.UserService/GetPassword", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GetRoleId(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Reference, error) { + out := new(common.Reference) + err := c.cc.Invoke(ctx, "/pagerino.user.UserService/GetRoleId", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GetDeviceIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.user.UserService/GetDeviceIds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GetLogs(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.user.UserService/GetLogs", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GetActivity(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Activity, error) { + out := new(common.Activity) + err := c.cc.Invoke(ctx, "/pagerino.user.UserService/GetActivity", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) { + out := new(common.Meta) + err := c.cc.Invoke(ctx, "/pagerino.user.UserService/GetMeta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// UserServiceServer is the server API for UserService service. +// All implementations must embed UnimplementedUserServiceServer +// for forward compatibility +type UserServiceServer interface { + // === DB information + GetAll(context.Context, *common.StrIndex) (*UserAllInfo, error) + GetInfo(context.Context, *common.StrIndex) (*UserBaseInfo, error) + GetPassword(context.Context, *common.StrIndex) (*Password, error) + // References + GetRoleId(context.Context, *common.StrIndex) (*common.Reference, error) + GetDeviceIds(context.Context, *common.StrIndex) (*common.References, error) + GetLogs(context.Context, *common.StrIndex) (*common.References, error) + // Common + GetActivity(context.Context, *common.StrIndex) (*common.Activity, error) + GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) + mustEmbedUnimplementedUserServiceServer() +} + +// UnimplementedUserServiceServer must be embedded to have forward compatible implementations. +type UnimplementedUserServiceServer struct { +} + +func (UnimplementedUserServiceServer) GetAll(context.Context, *common.StrIndex) (*UserAllInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAll not implemented") +} +func (UnimplementedUserServiceServer) GetInfo(context.Context, *common.StrIndex) (*UserBaseInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetInfo not implemented") +} +func (UnimplementedUserServiceServer) GetPassword(context.Context, *common.StrIndex) (*Password, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPassword not implemented") +} +func (UnimplementedUserServiceServer) GetRoleId(context.Context, *common.StrIndex) (*common.Reference, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetRoleId not implemented") +} +func (UnimplementedUserServiceServer) GetDeviceIds(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetDeviceIds not implemented") +} +func (UnimplementedUserServiceServer) GetLogs(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetLogs not implemented") +} +func (UnimplementedUserServiceServer) GetActivity(context.Context, *common.StrIndex) (*common.Activity, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetActivity not implemented") +} +func (UnimplementedUserServiceServer) GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMeta not implemented") +} +func (UnimplementedUserServiceServer) mustEmbedUnimplementedUserServiceServer() {} + +// UnsafeUserServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to UserServiceServer will +// result in compilation errors. +type UnsafeUserServiceServer interface { + mustEmbedUnimplementedUserServiceServer() +} + +func RegisterUserServiceServer(s grpc.ServiceRegistrar, srv UserServiceServer) { + s.RegisterService(&UserService_ServiceDesc, srv) +} + +func _UserService_GetAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetAll(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.user.UserService/GetAll", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetAll(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.user.UserService/GetInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetInfo(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GetPassword_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetPassword(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.user.UserService/GetPassword", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetPassword(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GetRoleId_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetRoleId(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.user.UserService/GetRoleId", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetRoleId(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GetDeviceIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetDeviceIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.user.UserService/GetDeviceIds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetDeviceIds(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GetLogs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetLogs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.user.UserService/GetLogs", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetLogs(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GetActivity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetActivity(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.user.UserService/GetActivity", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetActivity(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GetMeta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetMeta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.user.UserService/GetMeta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetMeta(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +// UserService_ServiceDesc is the grpc.ServiceDesc for UserService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var UserService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pagerino.user.UserService", + HandlerType: (*UserServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetAll", + Handler: _UserService_GetAll_Handler, + }, + { + MethodName: "GetInfo", + Handler: _UserService_GetInfo_Handler, + }, + { + MethodName: "GetPassword", + Handler: _UserService_GetPassword_Handler, + }, + { + MethodName: "GetRoleId", + Handler: _UserService_GetRoleId_Handler, + }, + { + MethodName: "GetDeviceIds", + Handler: _UserService_GetDeviceIds_Handler, + }, + { + MethodName: "GetLogs", + Handler: _UserService_GetLogs_Handler, + }, + { + MethodName: "GetActivity", + Handler: _UserService_GetActivity_Handler, + }, + { + MethodName: "GetMeta", + Handler: _UserService_GetMeta_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "user.proto", +} diff --git a/AppServer/src/app_comm/proto/change.proto b/AppServer/src/app_comm/proto/change.proto new file mode 100644 index 0000000..793183c --- /dev/null +++ b/AppServer/src/app_comm/proto/change.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; + +package pagerino.change; +option go_package = "server/app_comm/api/change;api_change"; + +import "common.proto"; + + +message ChageAllInfo { + string old_value = 1; + string new_value = 2; + string table_name = 3; + string operation = 4; + int32 log_id = 5; +} + +message Values { + string old_value = 1; + string new_value = 2; +} + + +service ChangeService { + // === DB information + rpc GetDiff(common.Index) returns (Values); + rpc GetAll(common.Index) returns (ChageAllInfo); + + // Common + rpc GetMeta(common.Index) returns (common.Meta); +} diff --git a/AppServer/src/app_comm/proto/common.proto b/AppServer/src/app_comm/proto/common.proto new file mode 100644 index 0000000..b7c2f00 --- /dev/null +++ b/AppServer/src/app_comm/proto/common.proto @@ -0,0 +1,47 @@ +syntax = "proto3"; + +package pagerino.common; +option go_package = "server/app_comm/api/common;api_common"; + + +import "google/protobuf/timestamp.proto"; + +// For custom logic responses +enum RequestCode { + UNKNOWN = 0; + OK = 1; + UNAUTHORIZED = 2; + NO_DATA = 3; + INTERNAL_ERROR = 4; +} + +// === DB indexing +message StrIndex { + oneof id { + int32 num = 1; // Database ID + string name = 2; // for external fields: username, euid, name... + } +} + +message Index { + int32 num = 1; // Database ID +} + +// === DB information +message Meta { + int32 id = 1; + google.protobuf.Timestamp created_at = 2; +} + +message References { + int32 page = 1; // 32 IDs per page from most recent + repeated int32 ref_id = 2; +} + +message Reference { + int32 ref_id = 1; +} + +message Activity { + google.protobuf.Timestamp last_online = 1; +} diff --git a/AppServer/src/app_comm/proto/device.proto b/AppServer/src/app_comm/proto/device.proto new file mode 100644 index 0000000..df8844d --- /dev/null +++ b/AppServer/src/app_comm/proto/device.proto @@ -0,0 +1,65 @@ +syntax = "proto3"; + +package pagerino.device; +option go_package = "server/app_comm/api/device;api_device"; + +import "google/protobuf/timestamp.proto"; +import "common.proto"; + + +message Charge { + float charge = 1; +} + +message Location { + double latitude = 1; + double longitude = 2; + float altitude = 3; +} + +message DeviceBaseInfo { + string name = 1; + string euid = 2; + sint32 internal_status = 3; + google.protobuf.Timestamp last_online = 4; +} + +message DeviceAllInfo { // Meta not included! + string name = 1; + string euid = 2; + + sint32 internal_status = 3; + string native_status = 4; + + google.protobuf.Timestamp last_online = 5; + string fw_version = 6; + + repeated int32 card_ids = 7; + + float charge = 8; + + double latitude = 9; + double longitude = 10; + float altitude = 11; +} + + +service DeviceService { + // === DB information + rpc GetAll(common.StrIndex) returns (DeviceAllInfo); + rpc GetInfo(common.StrIndex) returns (DeviceBaseInfo); + rpc GetCharge(common.StrIndex) returns (Charge); + rpc GetLocation(common.StrIndex) returns (Location); + + // References + rpc GetNfcCardIds(common.StrIndex) returns (common.References); + rpc GetStatusIds(common.StrIndex) returns (common.References); + rpc GetSentMessageIds(common.StrIndex) returns (common.References); + rpc GetReceivedMessageIds(common.StrIndex) returns (common.References); + rpc GetLogs(common.StrIndex) returns (common.References); + + // Common + rpc GetActivity(common.StrIndex) returns (common.Activity); + rpc GetMeta(common.StrIndex) returns (common.Meta); +} + diff --git a/AppServer/src/app_comm/proto/log.proto b/AppServer/src/app_comm/proto/log.proto new file mode 100644 index 0000000..6a337ac --- /dev/null +++ b/AppServer/src/app_comm/proto/log.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package pagerino.log; +option go_package = "server/app_comm/api/log;api_log"; + +import "common.proto"; + + +service LogService { + // === DB information + // References + rpc GetChangeIds(common.Index) returns (common.References); + + // Common + rpc GetMeta(common.Index) returns (common.Meta); +} diff --git a/AppServer/src/app_comm/proto/message.proto b/AppServer/src/app_comm/proto/message.proto new file mode 100644 index 0000000..99060e7 --- /dev/null +++ b/AppServer/src/app_comm/proto/message.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +package pagerino.message; +option go_package = "server/app_comm/api/message;api_message"; + +import "google/protobuf/timestamp.proto"; +import "common.proto"; + + +message MessageBasicInfo { + int32 sender_id = 1; + int32 receiver_id = 2; + string payload = 3; + google.protobuf.Timestamp created_at = 4; +} + +message Payload { + string payload = 1; +} + + +service MessageService { + // === DB information + rpc GetInfo(common.Index) returns (MessageBasicInfo); + rpc GetPayload(common.Index) returns (Payload); + + // Common + rpc GetMeta(common.Index) returns (common.Meta); +} diff --git a/AppServer/src/app_comm/proto/nfccard.proto b/AppServer/src/app_comm/proto/nfccard.proto new file mode 100644 index 0000000..8975bf5 --- /dev/null +++ b/AppServer/src/app_comm/proto/nfccard.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; + +package pagerino.nfc_card; +option go_package = "server/app_comm/api/nfccard;api_nfccard"; + + +import "common.proto"; + + +message NfcCardBaseInfo { + string uid = 1; +} + + +service NfcCardService { + // === DB information + rpc GetInfo(common.Index) returns (NfcCardBaseInfo); + + // References + rpc GetDeviceId(common.Index) returns (common.Reference); + + // Common + rpc GetMeta(common.Index) returns (common.Meta); +} diff --git a/AppServer/src/app_comm/proto/permission.proto b/AppServer/src/app_comm/proto/permission.proto new file mode 100644 index 0000000..ca46f60 --- /dev/null +++ b/AppServer/src/app_comm/proto/permission.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; + +package pagerino.permission; +option go_package = "server/app_comm/api/permission;api_permission"; + +import "common.proto"; + + +message PermissionBasicInfo { + string name = 1; + string description = 2; +} + + +service PermissionService { + // === DB information + rpc GetInfo(common.StrIndex) returns (PermissionBasicInfo); + + // References + rpc GetRoleIds(common.StrIndex) returns (common.References); + + // Common + rpc GetMeta(common.StrIndex) returns (common.Meta); +} diff --git a/AppServer/src/app_comm/proto/role.proto b/AppServer/src/app_comm/proto/role.proto new file mode 100644 index 0000000..eeeadd3 --- /dev/null +++ b/AppServer/src/app_comm/proto/role.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + +package pagerino.role; +option go_package = "server/app_comm/api/role;api_role"; + +import "common.proto"; + + +message RoleBasicInfo { + string name = 1; + string description = 2; +} + + +service RoleService { + // === DB information + rpc GetInfo(common.StrIndex) returns (RoleBasicInfo); + + // References + rpc GetPermissionIds(common.StrIndex) returns (common.References); + rpc GetUserIds(common.StrIndex) returns (common.References); + + // Common + rpc GetMeta(common.StrIndex) returns (common.Meta); +} diff --git a/AppServer/src/app_comm/proto/status.proto b/AppServer/src/app_comm/proto/status.proto new file mode 100644 index 0000000..673d3cf --- /dev/null +++ b/AppServer/src/app_comm/proto/status.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; + +package pagerino.status; +option go_package = "server/app_comm/api/status;api_status"; + + +import "common.proto"; + + +message StatusBasicInfo { + sint32 internal_status = 1; + string native_status = 2; +} + + +// When getting Status, string index is for Device! +service StatusService { + // === DB information + rpc GetInfo(common.StrIndex) returns (StatusBasicInfo); + + // References + rpc GetDeviceId(common.StrIndex) returns (common.Reference); + + // Common + rpc GetMeta(common.StrIndex) returns (common.Meta); +} diff --git a/AppServer/src/app_comm/proto/user.proto b/AppServer/src/app_comm/proto/user.proto new file mode 100644 index 0000000..76b817d --- /dev/null +++ b/AppServer/src/app_comm/proto/user.proto @@ -0,0 +1,43 @@ +syntax = "proto3"; + +package pagerino.user; +option go_package = "server/app_comm/api/user;api_user"; + +import "google/protobuf/timestamp.proto"; +import "common.proto"; + + +message Password { + string password = 1; +} + +message UserAllInfo { // Meta not included! + string name = 1; + string password = 2; + + int32 role_id = 3; + google.protobuf.Timestamp last_online = 4; +} + +message UserBaseInfo { + string name = 1; + int32 role_id = 2; + google.protobuf.Timestamp last_online = 3; +} + + +service UserService { + // === DB information + rpc GetAll(common.StrIndex) returns (UserAllInfo); + rpc GetInfo(common.StrIndex) returns (UserBaseInfo); + rpc GetPassword(common.StrIndex) returns (Password); + + // References + rpc GetRoleId(common.StrIndex) returns (common.Reference); + rpc GetDeviceIds(common.StrIndex) returns (common.References); + rpc GetLogs(common.StrIndex) returns (common.References); + + // Common + rpc GetActivity(common.StrIndex) returns (common.Activity); + rpc GetMeta(common.StrIndex) returns (common.Meta); +} diff --git a/AppServer/src/go.mod b/AppServer/src/go.mod new file mode 100755 index 0000000..22fdf72 --- /dev/null +++ b/AppServer/src/go.mod @@ -0,0 +1,28 @@ +module server + +go 1.24.5 + +require ( + github.com/eclipse/paho.mqtt.golang v1.5.0 // direct + github.com/jackc/pgx/v5 v5.7.5 // direct +) + +require ( + github.com/chirpstack/chirpstack/api/go/v4 v4.14.1 + golang.org/x/crypto v0.39.0 + google.golang.org/grpc v1.75.0 + google.golang.org/protobuf v1.36.8 +) + +require ( + github.com/gorilla/websocket v1.5.3 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect + github.com/jackc/puddle/v2 v2.2.2 // indirect + golang.org/x/net v0.41.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.33.0 // indirect + golang.org/x/text v0.26.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250826171959-ef028d996bc1 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c // indirect +) diff --git a/AppServer/src/go.sum b/AppServer/src/go.sum new file mode 100755 index 0000000..1550403 --- /dev/null +++ b/AppServer/src/go.sum @@ -0,0 +1,70 @@ +github.com/chirpstack/chirpstack/api/go/v4 v4.14.1 h1:w961GhhQArXqWxLcudZ4wI6AzcCkpHgPfuf03f3DtiM= +github.com/chirpstack/chirpstack/api/go/v4 v4.14.1/go.mod h1:EqvcS3qE73PunKGKkwxQ69pBx+xPcGAwVE6FFYSIzhk= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/eclipse/paho.mqtt.golang v1.5.0 h1:EH+bUVJNgttidWFkLLVKaQPGmkTUfQQqjOsyvMGvD6o= +github.com/eclipse/paho.mqtt.golang v1.5.0/go.mod h1:du/2qNQVqJf/Sqs4MEL77kR8QTqANF7XU7Fk0aOTAgk= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.7.5 h1:JHGfMnQY+IEtGM63d+NGMjoRpysB2JBwDr5fsngwmJs= +github.com/jackc/pgx/v5 v5.7.5/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M= +github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= +github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= +golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/api v0.0.0-20250826171959-ef028d996bc1 h1:APHvLLYBhtZvsbnpkfknDZ7NyH4z5+ub/I0u8L3Oz6g= +google.golang.org/genproto/googleapis/api v0.0.0-20250826171959-ef028d996bc1/go.mod h1:xUjFWUnWDpZ/C0Gu0qloASKFb6f8/QXiiXhSPFsD668= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c h1:qXWI/sQtv5UKboZ/zUk7h+mrf/lXORyI+n9DKDAusdg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/AppServer/src/main.go b/AppServer/src/main.go new file mode 100755 index 0000000..cda0006 --- /dev/null +++ b/AppServer/src/main.go @@ -0,0 +1,439 @@ +/* +Basic functionality to receive uplink messages from TTN, +process them and send appropriate responses to devices. + +Author: Olek +*/ +package main + +// go mod vendor -> for static libraries +// go mod tidy -> to download to /go/pkg/mod +// or just use docker +import ( + "context" + "crypto/tls" + "crypto/x509" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "log" + "net" + "os" + "os/signal" + "strconv" + "syscall" + "time" + + api_user "server/app_comm/api/user" + serder "server/serder" + + chirp_api "github.com/chirpstack/chirpstack/api/go/v4/api" + + mqtt "github.com/eclipse/paho.mqtt.golang" + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgxpool" + "golang.org/x/crypto/bcrypt" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +const ( + MAX_CHAR_LEN = 64 // Limits fields like: names, passwords... + MAX_PING_RETRIES = 6 +) + +// FPort signifies meaning of each port's message +const ( + FNotif uint8 = iota + 1 // Basic notfication message + FTask // Assigned task message + FAuth // Authorization message: system, device, NFC, NFC Reader... + FWarn // Warning message: emergency, help request... +) + +// Internal Pagerino status table +type Status uint16 + +const ( + StatUnknown Status = iota + StatOperational + StatIssue // Cannot operate until fixed, small issue + StatTempUnavailable // Cannot operate for a period of time regardless of any action + StatRepair // Explicitly repaired and unavailable + StatOffline // Not powered on or not disconnected from system + StatFatal // Cannot operate until professionally repaired or replaced + StatMAX // Maximum value, no other meaning +) + +// AppData holds data and connections needed througout the program +type AppData struct { + ExitSig chan os.Signal // Use on fatal error to graciously exit, otherwise potential leaks + DBPool *pgxpool.Pool // Execute queries on internal DB on this pool + APIServer *grpc.Server // Provide API for apps + MQTTClient mqtt.Client // Get Uplinks and downlinks + ChirpGateClient chirp_api.GatewayServiceClient // Check gateway stats and manage them + Timeout time.Duration // General connection/request timeout +} + +// Uplink reflects Chirpstack's uplink format +type Uplink struct { + ApplicationID string `json:"applicationID"` + DevEUI string `json:"devEUI"` + FCnt uint32 `json:"fCnt"` + FPort uint8 `json:"fPort"` + Data string `json:"data"` // Base64 payload + RxInfo []struct { + GatewayID string `json:"gatewayID"` + Time string `json:"time"` + RSSI int32 `json:"rssi"` + SNR float64 `json:"snr"` + } `json:"rxInfo"` + DecodedPayload map[string]any `json:"decodedPayload,omitempty"` +} + +// Downlink reflects Chirpstack's downlink format +type Downlink struct { + Confirmed bool `json:"confirmed"` // false for no Ack + FPort uint8 `json:"fPort"` // refer to FPort enum + Data string `json:"data"` // Base64 payload +} + +// Common errors +var ( + ErrNotFound error = errors.New("query returned empty") + ErrTooLong error = errors.New("given parameter(s) is too long") + ErrTimedOut error = errors.New("operation did not complete before timeout") + ErrModify error = errors.New("database data manipulation error") +) + +type RPCCredentials struct { + Token string +} + +func (cred *RPCCredentials) GetRequestMetadata(ctx context.Context, url ...string) (map[string]string, error) { + return map[string]string{ + "authorization": "Bearer " + cred.Token, + }, nil +} + +// TODO: Change to true if want certs +func (cred *RPCCredentials) RequireTransportSecurity() bool { + return false +} + +// Get non-empty config value, otherwise terminate program +func FindEnv(name string) string { + val := os.Getenv(name) + if val == "" { + log.Fatalln("Missing or empty configuration value for: " + name) + } + + return val +} + +// MakeTLSConfig loads client certificates for TLS and SSL +func MakeTLSConfig() (*tls.Config, error) { + // Load CA certificate + caCert, err := os.ReadFile("./certs/ca.pem") + if err != nil { + return nil, err + } + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + + // Load client certificate + cert, err := tls.LoadX509KeyPair("./certs/client.pem", "./certs/client.key") + if err != nil { + return nil, err + } + + return &tls.Config{ + RootCAs: caCertPool, + Certificates: []tls.Certificate{cert}, + MinVersion: tls.VersionTLS12, + }, nil +} + +// VerifyCredentials returns no error if password matches in DB +func VerifyCredentials(username string, password string, data *AppData) error { + if len(username) > MAX_CHAR_LEN || len(password) > MAX_CHAR_LEN { + return ErrTooLong + } + + hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) + if err != nil { + return err + } + + ctx, close_ctx := context.WithTimeout(context.Background(), data.Timeout) + defer close_ctx() + + row := data.DBPool.QueryRow(ctx, "SELECT password FROM User WHERE name = $1;") + + var pass string + if err = row.Scan(&pass); err != nil { + if errors.Is(err, pgx.ErrNoRows) { + return fmt.Errorf("%w for: User.name", ErrNotFound) + } else { + return err + } + } + + err = bcrypt.CompareHashAndPassword(hash, []byte(pass)) + + return err +} + +// SendDownlink sends downlink message to MQTT broker +func SendDownlink(data *AppData, topic string, msg *Downlink) error { + jsonData, _ := json.Marshal(msg) + publish_token := data.MQTTClient.Publish(topic, 0, false, jsonData) + if ok := publish_token.WaitTimeout(data.Timeout); !ok { + return fmt.Errorf("%w for: Downlink", ErrTimedOut) + } + + return nil +} + +// makeMQTTHandler returns a callback function that hanldes uplink messages +// from MQTT broker. +// +// Does most of the application logic. +func makeMQTTHandler(data *AppData) mqtt.MessageHandler { + return func(client mqtt.Client, msg mqtt.Message) { + var uplink Uplink + // Parse + err := json.Unmarshal(msg.Payload(), &uplink) + if err != nil { + log.Println("Failed to parse uplink message: " + err.Error()) + return + } + + // Decode to original + saves space + decoded, err := base64.StdEncoding.DecodeString(uplink.Data) + if err != nil { + log.Println("Failed to decode uplink payload: " + err.Error()) + return + } + + // Print + log.Println("Uplink from DeviceEUI [" + uplink.DevEUI + "]") + + switch uplink.FPort { + case FNotif: + log.Println("Uplink is responding to a normal message or notification") + case FTask: + log.Println("Uplink is responding to a task") + case FAuth: + log.Println("Uplink is responding to an authentication message") + case FWarn: + log.Println("Uplink is responding to a warning") + default: + log.Println("Uplink is responding in an unrecognized channel") + } + + // Query timeout + ctx, close := context.WithTimeout(context.Background(), data.Timeout) + defer close() + + // Get device IDs + row := data.DBPool.QueryRow(ctx, + "SELECT id FROM Devices WHERE euid = '$1'", + uplink.DevEUI, + ) + + var dev_id int32 + if err = row.Scan(&dev_id); err != nil { + log.Println(ErrNotFound.Error() + ": Device.euid = " + uplink.DevEUI) + return + } + + // Add Message to DB + _, err = data.DBPool.Exec(ctx, + "INSERT INTO Messages (sender_id, receiver_id, payload) VALUES ($1, $2, $3)", + dev_id, nil, decoded, + ) + + if err != nil { + log.Println(ErrModify.Error() + ": Message") + return + } + + // Get decoded custom payload + pager_msg, err := serder.Deserialize(decoded) + if err != nil { + log.Println(err.Error() + ": deserialization") + return + } + + log.Println("Received Pagerino payload for AppID[", pager_msg.AppID, "]:") + for _, field := range pager_msg.Fields { + log.Println(field) + } + } +} + +func main() { + // = Quit signal + quit_signal := make(chan os.Signal, 1) + signal.Notify(quit_signal, syscall.SIGINT, syscall.SIGTERM) + + Data := AppData{ + ExitSig: quit_signal, + } + + // === Logger settings + log.SetFlags(log.Ldate | log.Ltime | log.Lmsgprefix | log.Lshortfile) + log.SetPrefix(FindEnv("LOG_PREFIX") + " ") + + tmout, err := time.ParseDuration(FindEnv("TIMEOUT")) + if err != nil { + log.Println(`Format misconfiguration for TIMEOUT: +Expected: [number]{h|m|s|ms|us|ns}...`) + return + } + Data.Timeout = tmout + + // === PostgreSQL database + ctx_tmout, cancel_ctx := context.WithTimeout(context.Background(), Data.Timeout) + defer cancel_ctx() + + db_pool, err := pgxpool.New(ctx_tmout, + "postgres://"+FindEnv("DB_USER")+":"+FindEnv("DB_PASSWORD")+"@"+ + FindEnv("DB_HOST")+":5432/"+FindEnv("DB_NAME"), + ) + if err != nil { + log.Println("DB connection pool creation failed: " + err.Error()) + return + } + defer db_pool.Close() + log.Println("Created database connection.") + + Data.DBPool = db_pool + + // Check responsiveness + failed := true + for count := 0; count < MAX_PING_RETRIES; count++ { + if err = db_pool.Ping(ctx_tmout); err != nil { + time.Sleep(200 * time.Millisecond) + } else { + failed = false + break + } + } + if failed { + log.Println("Database is not responding: " + err.Error()) + return + } + + // === MQTT broker + tls_config, err := MakeTLSConfig() + if err != nil { + log.Println("Error creating TLS configuration: " + err.Error()) + return + } + opts := mqtt.NewClientOptions(). + AddBroker(FindEnv("MQTT_ADDRESS")). + SetClientID(FindEnv("MQTT_CLIENT_ID")). + SetTLSConfig(tls_config). + SetKeepAlive(30 * time.Second) + + client := mqtt.NewClient(opts) + connect_token := client.Connect() + if err := connect_token.Error(); err != nil { + log.Println("Failed to connect to MQTT broker: " + err.Error()) + return + } + + if ok := connect_token.WaitTimeout(Data.Timeout); !ok { + + log.Println("Connection to MQTT broker timed out") + return + } + + log.Println("Created MQTT broker connection.") + defer client.Disconnect(150) + + Data.MQTTClient = client + + // === API Server + api_port := FindEnv("SERVER_API_PORT") + net_listen, err := net.Listen("tcp", ":"+api_port) + if err != nil { + log.Println("Failed to listen on port " + api_port + ": " + err.Error()) + return + } + + grpc_server := grpc.NewServer() + // User service + api_user.RegisterUserServiceServer( + grpc_server, + &UserServiceServer{App: &Data}, + ) + Data.APIServer = grpc_server + + // Serve gRPC + go func() { + if err := grpc_server.Serve(net_listen); err != nil { + log.Println("Failed to serve gRPC API") + return + } + }() + log.Println("gRPC API serving on port: " + api_port) + + // === Chirpstack's gRPC API + dialOpts := []grpc.DialOption{ + //grpc.WithBlock(), + grpc.WithPerRPCCredentials(&RPCCredentials{FindEnv("CHIRP_API_KEY")}), + grpc.WithTransportCredentials(insecure.NewCredentials()), // remove this when using TLS + } + + grpc_conn, err := grpc.Dial("chirpstack:8080", dialOpts...) + if err != nil { + log.Println("Failed to create a gRPC connection to Chirpstack's API: " + err.Error()) + return + } + + Data.ChirpGateClient = chirp_api.NewGatewayServiceClient(grpc_conn) + defer grpc_conn.Close() + + log.Println("Created Chirpstack's API connection.") + + // Test gRPC connection + ctx_tmout, cancel_ctx = context.WithTimeout(context.Background(), Data.Timeout) + defer cancel_ctx() + + resp, err := Data.ChirpGateClient.List(ctx_tmout, &chirp_api.ListGatewaysRequest{ + Limit: 10, + Offset: 0, + OrderByDesc: true, + }) + if err != nil { + log.Println("Failed to test Chirpstack's API connection: "+err.Error(), resp) + return + } + + log.Println("Found the following gateways (first 10):") + for idx, gate := range resp.Result { + log.Println(strconv.FormatInt(int64(idx), 10) + ": App[" + + gate.TenantId + "] GateID[" + gate.GatewayId + "] Name[" + + gate.Name + "]") + } + log.Println("[END]") + + // === Listen for Uplinks + // Subscribe to topics + topic := "application/" + FindEnv("APP_ID") + "/device/+/event/up" + qos, err := strconv.Atoi(FindEnv("MQTT_QOS")) + if err != nil { + log.Println("Format misconfiguration for MQTT_QOS: " + err.Error()) + return + } + + client.Subscribe(topic, byte(qos), makeMQTTHandler(&Data)) + log.Println("Subscribed to uplink data on: " + topic + ".") + + // === Shutdown + <-Data.ExitSig // Continue here on force quit + log.Println("The server is shutting down.") +} diff --git a/AppServer/src/serder/serder.go b/AppServer/src/serder/serder.go new file mode 100644 index 0000000..90d6f8f --- /dev/null +++ b/AppServer/src/serder/serder.go @@ -0,0 +1,312 @@ +/* +Serialize and deserialize data with custom +Pagerino message templates. + +Author: Olek +*/ +package serder + +import ( + "encoding/binary" + "errors" + "fmt" + "math" +) + +const ( + NFC_LENGTH = 7 +) + +var ( + ErrTooShort error = errors.New("insufficient bytes in message") + ErrNoType error = errors.New("encountered unknown data type") + ErrNoLength error = errors.New("data type has no defined length") + ErrUndefined error = errors.New("encountered unexpected symbol, behaviour undefined") + ErrInvalidData error = errors.New("invalid underlying data provided") + ErrTooLong error = errors.New("data provided is too long") +) + +type Reaction uint8 + +const ( + React_OK Reaction = iota + React_IN + React_OUT +) + +const ( + DT_NULL byte = iota + DT_Char // byte + DT_Array // array + DT_Location // Location + DT_Temperature // float + DT_Charge // float + DT_Authorization // UID + DT_Reaction // byte + DT_NFCPair // UID + DT_NFCUnpair // None +) + +var DataSizeMap = map[byte]int{ + DT_NULL: 0, + DT_Array: 2, // type + length + DT_Char: 1, + DT_Location: 20, + DT_Temperature: 4, + DT_Charge: 4, + DT_Authorization: 7, + DT_Reaction: 1, + DT_NFCPair: 7, + DT_NFCUnpair: 0, +} + +type Location struct { + Latitude float64 + Longitude float64 + Altitude float32 +} + +type Field struct { + DType byte + Value any +} + +type PagerMessage struct { + AppID uint16 + Fields []Field +} + +// readArray reads a subset of bytes marked with DT_Array. +// This data is copied, it is not parsed. +func readArray(data []byte, offset int, dest *[]byte) (int, error) { + if offset+2 >= len(data) { + return offset, ErrTooShort + } + + dtype := data[offset] + offset++ + + length := int(data[offset]) + offset++ + + size, found := DataSizeMap[dtype] + if !found { + return offset, ErrNoLength + } + + if size*length+offset >= len(data) { + return len(data), ErrTooShort + } + + // Untyped! + *dest = append(*dest, data[offset:offset+length*size]...) + return offset + length*size, nil +} + +// readField returns single Field struct reflecting the next data segment +func readField(data []byte, offset int) (Field, int, error) { + pair := Field{} + if offset >= len(data) { + return pair, offset, ErrTooShort + } + + // Get type + pair.DType = data[offset] + offset++ + + size, found := DataSizeMap[pair.DType] + if !found { + return pair, offset, ErrNoLength + } + + if size != 0 { + if offset+size >= len(data) { + return pair, offset, ErrTooShort + } + + switch pair.DType { + case DT_Char, DT_Reaction: + pair.Value = data[offset] + offset++ + + case DT_Array: + sub_pair := Field{DType: data[offset]} + val, ok := sub_pair.Value.([]byte) + if !ok { + return pair, offset, ErrInvalidData + } + + offset, err := readArray(data, offset, &val) + if err != nil { + return pair, offset, err + } + + pair.Value = sub_pair + + case DT_Charge, DT_Temperature: + pair.Value = math.Float32frombits(binary.LittleEndian.Uint32(data[offset:])) + offset += 4 + + case DT_Authorization, DT_NFCPair: + pair.Value = data[offset : offset+NFC_LENGTH] + offset += NFC_LENGTH + + case DT_Location: + val := Location{Latitude: math.Float64frombits(binary.LittleEndian.Uint64(data[offset:]))} + offset += 8 + val.Longitude = math.Float64frombits(binary.LittleEndian.Uint64(data[offset:])) + offset += 8 + val.Altitude = math.Float32frombits(binary.LittleEndian.Uint32(data[offset:])) + offset += 4 + + pair.Value = val + + default: + return pair, offset, ErrNoType + } + } + + return pair, offset, nil +} + +// writeField encodes a field into buffer +func writeField(field *Field, buf []byte) ([]byte, error) { + buf = append(buf, field.DType) + + switch field.DType { + case DT_Array: + sub_pair, ok := field.Value.(Field) + if !ok { + return buf, ErrInvalidData + } + buf = append(buf, sub_pair.DType) + + size, ok := DataSizeMap[sub_pair.DType] + if !ok { + return buf, ErrNoLength + } + + val, ok := sub_pair.Value.([]byte) + if !ok { + return buf, ErrInvalidData + } + + length := len(val) / size + if length > 255 { + return buf, ErrTooLong + } + + buf = append(buf, byte(length)) + buf = append(buf, val...) + case DT_Char, DT_Reaction: + val, ok := field.Value.(byte) + if !ok { + return buf, ErrInvalidData + } + + buf = append(buf, val) + + case DT_Authorization, DT_NFCPair: + val, ok := field.Value.([7]byte) + if !ok { + return buf, ErrInvalidData + } + + buf = append(buf, val[:]...) + + case DT_Charge, DT_Temperature: + val, ok := field.Value.(float32) + if !ok { + return buf, ErrInvalidData + } + + buf = binary.LittleEndian.AppendUint32(buf, math.Float32bits(val)) + + case DT_Location: + val, ok := field.Value.(Location) + if !ok { + return buf, ErrInvalidData + } + + buf = binary.LittleEndian.AppendUint64(buf, math.Float64bits(val.Latitude)) + buf = binary.LittleEndian.AppendUint64(buf, math.Float64bits(val.Longitude)) + buf = binary.LittleEndian.AppendUint32(buf, math.Float32bits(val.Altitude)) + + case DT_NULL, DT_NFCUnpair: + + default: + return buf, ErrNoType + } + + return buf, nil +} + +// SplitByLimit splits encoded message into parts +// with maximum length derived from data rate. +// +// These messages are not decodable on the server, as +// data is fractured. (TODO) +func SplitByLimit(buf []byte, data_rate int) ([][]byte, error) { + var limit int + if data_rate >= 0 && data_rate <= 3 { + limit = 51 + } else if data_rate == 4 { + limit = 115 + } else if data_rate >= 5 && data_rate <= 7 { + limit = 222 + } else { + return nil, ErrUndefined + } + + length := len(buf) + count := length / limit + if length%limit != 0 { + count++ + } + + output := make([][]byte, 0, count) + offset := 0 + for ; offset+limit < length; offset += limit { + output = append(output, buf[offset:offset+limit]) + } + output = append(output, buf[offset:length]) + + return output, nil +} + +// Deserialize deserializes bytes into a structured message +func Deserialize(input []byte) (*PagerMessage, error) { + output := PagerMessage{} + + length := len(input) + if length < 2 { + return &output, fmt.Errorf("%w while reading AppID", ErrTooShort) + } + offset := 0 + output.AppID = binary.LittleEndian.Uint16(input[offset:]) + offset += 2 + + var err error + var field Field + for ; err == nil && offset < length; field, offset, err = readField(input, offset) { + output.Fields = append(output.Fields, field) + } + + return &output, err +} + +// Serialize serializes a message into bytes. +// +// Resulting array length is not limited, to get +// split messages for downlink use "SplitByLimit()" +func Serialize(msg *PagerMessage) ([]byte, error) { + buf := make([]byte, 0, 2+len(msg.Fields)*2) // May overalloc! + buf = binary.LittleEndian.AppendUint16(buf, msg.AppID) + + var err error + for idx := 0; idx < len(msg.Fields) && err == nil; idx++ { + buf, err = writeField(&msg.Fields[idx], buf) + } + + return buf, err +} diff --git a/AppServer/tarball.tar.gz b/AppServer/tarball.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..46687e646347ee542a8c5d172de9ba3edb8760e3 GIT binary patch literal 41772 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.cnf <client_ext.cnf <:@/?sslmode=. + # + # SSL mode options: + # * disable - Do not use TLS + # * prefer - Attempt to connect with TLS but allow sessions without + # * require - Require the use of TLS + dsn="postgres://chirpstack:chirpstack@$POSTGRESQL_HOST/chirpstack?sslmode=disable" + + # Max open connections. + # + # This sets the max. number of open connections that are allowed in the + # PostgreSQL connection pool. + max_open_connections=10 + + # Min idle connections. + # + # This sets the min. number of idle connections in the PostgreSQL connection + # pool (0 = equal to max_open_connections). + min_idle_connections=0 + + +# Redis configuration. +[redis] + + # Server address or addresses. + # + # Set multiple addresses when connecting to a cluster. + servers=[ + "redis://$REDIS_HOST/", + ] + + # TLS enabled. + tls_enabled=false + + # Redis Cluster. + # + # Set this to true when the provided URLs are pointing to a Redis Cluster + # instance. + cluster=false + + +# Network related configuration. +[network] + + # Network identifier (NetID, 3 bytes) encoded as HEX (e.g. 010203). + net_id="10204" + + # Enabled regions. + # + # Multiple regions can be enabled simultaneously. Each region must match + # the 'name' parameter of the region configuration in '[[regions]]'. + enabled_regions=[ + # "as923", + # "as923_2", + # "as923_3", + # "as923_4", + # "au915_0", + # "cn470_10", + # "cn779", + # "eu433", + "eu868" + # "in865", + # "ism2400", + # "kr920", + # "ru864", + # "us915_0", + # "us915_1", + ] + + +# API interface configuration. +[api] + + # interface:port to bind the API interface to. + bind="0.0.0.0:8080" + + # Secret. + # + # This secret is used for generating login and API tokens, make sure this + # is never exposed. Changing this secret will invalidate all login and API + # tokens. The following command can be used to generate a random secret: + # openssl rand -base64 32 + secret="7E7bNXrmFoFznYKTqWBUrz5lGBpHx3N2zdabP1jCd5s=" + + +# Global gateway configuration. +# Please note that backend configuration can be found in the per-region +# configuration. +[gateway] + + # CA certificate and key file (optional). + # + # If setting the CA certificate and key file options, ChirpStack + # will generate client certificates which can be used by the gateway for + # authentication and authorization. The Common Name of the certificate will + # be set to the Gateway ID. + # + # The ca_key is expected to be in PKCS#8 format (you can use openssl to + # convert to PKCS#8). + ca_cert="/etc/chirpstack/certs/ca.pem" + ca_key="/etc/chirpstack/certs/ca-key.pem" + + # Certificate lifetime. + # + # This defines how long (after generating) the certificate remains valid. + client_cert_lifetime="365days" + + # Allow unknown gateways. + # + # If set to true, then uplinks received from gateways not configured in + # ChirpStack will be allowed. + allow_unknown_gateways=false + + # RX timestamp max. drift. + # + # If the delta between the gateway reported RX timestamp vs ChirpStack + # server time is bigger than the configured value, then ChirpStack will + # ignore it. ChirpStack will then use the RX timestamp from the other + # receiving gateways, or failing that, will fall back onto the current + # server time. + rx_timestamp_max_drift="30s" + + +[integration] + enabled=["mqtt"] + + [integration.mqtt] + # Event topic template. + event_topic="application/{{application_id}}/device/{{dev_eui}}/event/{{event}}" + + # Command topic. + # + # This is the topic on which the MQTT subscribes for receiving (enqueue) commands. + command_topic="application/{{application_id}}/device/{{dev_eui}}/command/{{command}}" + + # Use JSON encoding instead of Protobuf (binary). + json=true + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="ssl://$MQTT_BROKER_HOST:8883/" + + # Connect with the given username (optional) + # username="" + + # Connect with the given password (optional) + # password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="chirpstack" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="/etc/chirpstack/certs/ca.pem" + + # TLS certificate file (optional) + tls_cert="/etc/chirpstack/certs/client.pem" + + # TLS key file (PKCS#8) (optional) + tls_key="/etc/chirpstack/certs/client.key" + diff --git a/Chirpstack_v4/configuration/chirpstack/region_as923.toml b/Chirpstack_v4/configuration/chirpstack/region_as923.toml new file mode 100644 index 0000000..0992c00 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_as923.toml @@ -0,0 +1,204 @@ +# This file contains an example AS923 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="as923" + + # Description is a short description for this region. + description="AS923" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AS923" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="as923" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=923200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=923400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=2 + + # RX2 frequency (Hz) + rx2_frequency=923200000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=3 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_as923_2.toml b/Chirpstack_v4/configuration/chirpstack/region_as923_2.toml new file mode 100644 index 0000000..04f865e --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_as923_2.toml @@ -0,0 +1,204 @@ +# This file contains an example AS923_2 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="as923_2" + + # Description is a short description for this region. + description="AS923-2" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AS923_2" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="as923_2" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=921400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=921600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=921400000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=3 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_as923_3.toml b/Chirpstack_v4/configuration/chirpstack/region_as923_3.toml new file mode 100644 index 0000000..7792267 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_as923_3.toml @@ -0,0 +1,204 @@ +# This file contains an example AS923_3 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="as923_3" + + # Description is a short description for this region. + description="AS923-3" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AS923_3" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="as923_3" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=916600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=916800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=2 + + # RX2 frequency (Hz) + rx2_frequency=916600000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=3 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_as923_4.toml b/Chirpstack_v4/configuration/chirpstack/region_as923_4.toml new file mode 100644 index 0000000..d8a17f7 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_as923_4.toml @@ -0,0 +1,204 @@ +# This file contains an example AS923_4 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="as923_4" + + # Description is a short description for this region. + description="AS923-4" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AS923_4" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="as923_4" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=917300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=917500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=2 + + # RX2 frequency (Hz) + rx2_frequency=917300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=3 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_au915_0.toml b/Chirpstack_v4/configuration/chirpstack/region_au915_0.toml new file mode 100644 index 0000000..29f903b --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_au915_0.toml @@ -0,0 +1,253 @@ +# This file contains an example AU915 example (channels 0-7 + 64). +[[regions]] + + # ID is an use-defined identifier for this region. + id="au915_0" + + # Description is a short description for this region. + description="AU915 (channels 0-7 + 64)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AU915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="au915_0" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=915200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=915400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=915600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=915800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=916000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=916200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=916400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=916600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=915900000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[0, 1, 2, 3, 4, 5, 6, 7, 64] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_au915_1.toml b/Chirpstack_v4/configuration/chirpstack/region_au915_1.toml new file mode 100644 index 0000000..6d2e31d --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_au915_1.toml @@ -0,0 +1,253 @@ +# This file contains an example AU915 example (channels 8-15 + 65). +[[regions]] + + # ID is an use-defined identifier for this region. + id="au915_1" + + # Description is a short description for this region. + description="AU915 (channels 8-15 + 65)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AU915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="au915_1" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=916800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=917000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=917200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=917400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=917600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=917800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=918000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=918200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=917500000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[8, 9, 10, 11, 12, 13, 14, 15, 65] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_au915_2.toml b/Chirpstack_v4/configuration/chirpstack/region_au915_2.toml new file mode 100644 index 0000000..3d1e5e7 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_au915_2.toml @@ -0,0 +1,253 @@ +# This file contains an example AU915 example (channels 16-23 + 66). +[[regions]] + + # ID is an use-defined identifier for this region. + id="au915_2" + + # Description is a short description for this region. + description="AU915 (channels 16-23 + 65)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AU915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="au915_2" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=918400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=918600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=918800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=919000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=919200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=919400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=919600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=919800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=919100000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[16, 17, 18, 19, 20, 21, 22, 23, 65] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_au915_3.toml b/Chirpstack_v4/configuration/chirpstack/region_au915_3.toml new file mode 100644 index 0000000..c1098c7 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_au915_3.toml @@ -0,0 +1,253 @@ +# This file contains an example AU915 example (channels 24-31 + 67). +[[regions]] + + # ID is an use-defined identifier for this region. + id="au915_3" + + # Description is a short description for this region. + description="AU915 (channels 24-31 + 67)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AU915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="au915_3" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=920000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=920200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=920400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=920600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=920800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=921000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=921200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=921400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=920700000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[24, 25, 26, 27, 28, 29, 30, 31, 67] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_au915_4.toml b/Chirpstack_v4/configuration/chirpstack/region_au915_4.toml new file mode 100644 index 0000000..ec51fef --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_au915_4.toml @@ -0,0 +1,253 @@ +# This file contains an example AU915 example (channels 32-39 + 68). +[[regions]] + + # ID is an use-defined identifier for this region. + id="au915_4" + + # Description is a short description for this region. + description="AU915 (channels 32-39 + 68)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AU915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="au915_4" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=921600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=921800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=922000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=922200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=922400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=922600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=922800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=923000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=922300000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[32, 33, 34, 35, 36, 37, 38, 39, 68] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_au915_5.toml b/Chirpstack_v4/configuration/chirpstack/region_au915_5.toml new file mode 100644 index 0000000..59b5f40 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_au915_5.toml @@ -0,0 +1,253 @@ +# This file contains an example AU915 example (channels 40-47 + 69). +[[regions]] + + # ID is an use-defined identifier for this region. + id="au915_5" + + # Description is a short description for this region. + description="AU915 (channels 40-47 + 69)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AU915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="au915_5" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=923200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=923400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=923600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=923800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=924000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=924200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=924400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=924600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=923900000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[40, 41, 42, 43, 44, 45, 46, 47, 69] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_au915_6.toml b/Chirpstack_v4/configuration/chirpstack/region_au915_6.toml new file mode 100644 index 0000000..2181344 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_au915_6.toml @@ -0,0 +1,253 @@ +# This file contains an example AU915 example (channels 48-55 + 70). +[[regions]] + + # ID is an use-defined identifier for this region. + id="au915_6" + + # Description is a short description for this region. + description="AU915 (channels 48-55 + 70)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AU915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="au915_6" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=924800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=925000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=925200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=925400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=925600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=925800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=926000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=926200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=925500000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[48, 49, 50, 51, 52, 53, 54, 55, 70] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_au915_7.toml b/Chirpstack_v4/configuration/chirpstack/region_au915_7.toml new file mode 100644 index 0000000..09c5dba --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_au915_7.toml @@ -0,0 +1,253 @@ +# This file contains an example AU915 example (channels 56-63 + 71). +[[regions]] + + # ID is an use-defined identifier for this region. + id="au915_7" + + # Description is a short description for this region. + description="AU915 (channels 56-63 + 71)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AU915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="au915_7" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=926400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=926600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=926800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=927000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=927200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=927400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=927600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=927800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=927100000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[56, 57, 58, 59, 60, 61, 62, 63, 71] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_cn470_0.toml b/Chirpstack_v4/configuration/chirpstack/region_cn470_0.toml new file mode 100644 index 0000000..5686f6e --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_cn470_0.toml @@ -0,0 +1,247 @@ +# This file contains an example CN470 example (channels 0-7). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_0" + + # Description is a short description for this region. + description="CN470 (channels 0-7)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_0" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=470300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=470500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=470700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=470900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=471100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=471300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=471500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=471700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[0, 1, 2, 3, 4, 5, 6, 7] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_cn470_1.toml b/Chirpstack_v4/configuration/chirpstack/region_cn470_1.toml new file mode 100644 index 0000000..277b900 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_cn470_1.toml @@ -0,0 +1,247 @@ +# This file contains an example CN470 example (channels 8-15). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_1" + + # Description is a short description for this region. + description="CN470 (channels 8-15)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_1" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=471900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=472100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=472300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=472500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=472700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=472900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=473100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=473300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[8, 9, 10, 11, 12, 13, 14, 15] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_cn470_10.toml b/Chirpstack_v4/configuration/chirpstack/region_cn470_10.toml new file mode 100644 index 0000000..bd02dd1 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_cn470_10.toml @@ -0,0 +1,247 @@ +# This file contains an example CN470 example (channels 80-87). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_10" + + # Description is a short description for this region. + description="CN470 (channels 80-87)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_10" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=486300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=486500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=486700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=486900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=487100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=487300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=487500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=487700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[80, 81, 82, 83, 84, 85, 86, 87] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_cn470_11.toml b/Chirpstack_v4/configuration/chirpstack/region_cn470_11.toml new file mode 100644 index 0000000..fb043c6 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_cn470_11.toml @@ -0,0 +1,247 @@ +# This file contains an example CN470 example (channels 88-95). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_11" + + # Description is a short description for this region. + description="CN470 (channels 88-95)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_11" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=487900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=488100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=488300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=488500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=488700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=488900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=489100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=489300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[88, 89, 90, 91, 92, 93, 94, 95] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_cn470_2.toml b/Chirpstack_v4/configuration/chirpstack/region_cn470_2.toml new file mode 100644 index 0000000..bc30825 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_cn470_2.toml @@ -0,0 +1,247 @@ +# This file contains an example CN470 example (channels 16-23). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_2" + + # Description is a short description for this region. + description="CN470 (channels 16-23)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_2" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=473500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=473700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=473900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=474100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=474300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=474500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=474700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=474900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[16, 17, 18, 19, 20, 21, 22, 23] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_cn470_3.toml b/Chirpstack_v4/configuration/chirpstack/region_cn470_3.toml new file mode 100644 index 0000000..6efc24d --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_cn470_3.toml @@ -0,0 +1,247 @@ +# This file contains an example CN470 example (channels 24-31). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_3" + + # Description is a short description for this region. + description="CN470 (channels 24-31)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_3" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=475100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=475300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=475500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=475700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=475900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=476100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=476300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=476500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[24, 25, 26, 27, 28, 29, 30, 31] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_cn470_4.toml b/Chirpstack_v4/configuration/chirpstack/region_cn470_4.toml new file mode 100644 index 0000000..17f46b8 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_cn470_4.toml @@ -0,0 +1,247 @@ +# This file contains an example CN470 example (channels 32-39). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_4" + + # Description is a short description for this region. + description="CN470 (channels 32-39)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_4" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=476700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=476900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=477100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=477300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=477500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=477700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=477900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=478100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[32, 33, 34, 35, 36, 37, 38, 39] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_cn470_5.toml b/Chirpstack_v4/configuration/chirpstack/region_cn470_5.toml new file mode 100644 index 0000000..75256fd --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_cn470_5.toml @@ -0,0 +1,247 @@ +# This file contains an example CN470 example (channels 40-47). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_5" + + # Description is a short description for this region. + description="CN470 (channels 40-47)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_5" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=478300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=478500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=478700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=478900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=479100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=479300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=479500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=479700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[40, 41, 42, 43, 44, 45, 46, 47] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_cn470_6.toml b/Chirpstack_v4/configuration/chirpstack/region_cn470_6.toml new file mode 100644 index 0000000..b1d6693 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_cn470_6.toml @@ -0,0 +1,247 @@ +# This file contains an example CN470 example (channels 48-55). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_6" + + # Description is a short description for this region. + description="CN470 (channels 48-55)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_6" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=479900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=480100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=480300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=480500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=480700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=480900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=481100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=481300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[48, 49, 50, 51, 52, 53, 54, 55] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_cn470_7.toml b/Chirpstack_v4/configuration/chirpstack/region_cn470_7.toml new file mode 100644 index 0000000..70937cf --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_cn470_7.toml @@ -0,0 +1,247 @@ +# This file contains an example CN470 example (channels 56-63). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_7" + + # Description is a short description for this region. + description="CN470 (channels 56-63)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_7" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=481500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=481700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=481900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=482100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=482300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=482500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=482700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=482900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[56, 57, 58, 59, 60, 61, 62, 63] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_cn470_8.toml b/Chirpstack_v4/configuration/chirpstack/region_cn470_8.toml new file mode 100644 index 0000000..8fcf3b0 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_cn470_8.toml @@ -0,0 +1,247 @@ +# This file contains an example CN470 example (channels 64-71). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_8" + + # Description is a short description for this region. + description="CN470 (channels 64-71)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_8" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=483100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=483300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=483500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=483700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=483900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=484100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=484300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=484500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[64, 65, 66, 67, 68, 69, 70, 71] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_cn470_9.toml b/Chirpstack_v4/configuration/chirpstack/region_cn470_9.toml new file mode 100644 index 0000000..87973f7 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_cn470_9.toml @@ -0,0 +1,247 @@ +# This file contains an example CN470 example (channels 72-79). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_9" + + # Description is a short description for this region. + description="CN470 (channels 72-79)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_9" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=484700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=484900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=485100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=485300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=485500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=485700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=485900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=486100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[72, 73, 74, 75, 76, 77, 78, 79] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_cn779.toml b/Chirpstack_v4/configuration/chirpstack/region_cn779.toml new file mode 100644 index 0000000..94aa163 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_cn779.toml @@ -0,0 +1,210 @@ +# This file contains an example CN779 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="cn779" + + # Description is a short description for this region. + description="CN779" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN779" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn779" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=779500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=779700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=779900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=786000000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=3 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_eu433.toml b/Chirpstack_v4/configuration/chirpstack/region_eu433.toml new file mode 100644 index 0000000..c471542 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_eu433.toml @@ -0,0 +1,210 @@ +# This file contains an example EU433 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="eu433" + + # Description is a short description for this region. + description="EU443" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="EU433" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="eu433" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=433175000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=433375000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=433575000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=434665000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=3 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_eu868.toml b/Chirpstack_v4/configuration/chirpstack/region_eu868.toml new file mode 100644 index 0000000..af83452 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_eu868.toml @@ -0,0 +1,280 @@ +# This file contains an example EU868 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="eu868" + + # Description is a short description for this region. + description="EU868" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="EU868" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="eu868" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="ssl://$MQTT_BROKER_HOST:8883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="/etc/chirpstack/certs/ca.pem" + + # TLS certificate file (optional) + tls_cert="/etc/chirpstack/certs/client.pem" + + # TLS key file (PKCS#8) (optional) + tls_key="/etc/chirpstack/certs/client.key" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=868100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=868300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=868500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=867100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=867300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=867500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=867700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=867900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=868300000 + bandwidth=250000 + modulation="LORA" + spreading_factors=[7] + + [[regions.gateway.channels]] + frequency=868800000 + bandwidth=125000 + modulation="FSK" + datarate=50000 + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=869525000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=3 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 + + + # Below is the common set of extra channels. Please make sure that these + # channels are also supported by the gateways. + [[regions.network.extra_channels]] + frequency=867100000 + min_dr=0 + max_dr=5 + + [[regions.network.extra_channels]] + frequency=867300000 + min_dr=0 + max_dr=5 + + [[regions.network.extra_channels]] + frequency=867500000 + min_dr=0 + max_dr=5 + + [[regions.network.extra_channels]] + frequency=867700000 + min_dr=0 + max_dr=5 + + [[regions.network.extra_channels]] + frequency=867900000 + min_dr=0 + max_dr=5 diff --git a/Chirpstack_v4/configuration/chirpstack/region_in865.toml b/Chirpstack_v4/configuration/chirpstack/region_in865.toml new file mode 100644 index 0000000..6b0930b --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_in865.toml @@ -0,0 +1,210 @@ +# This file contains an example IN865 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="in865" + + # Description is a short description for this region. + description="IN865" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="IN865" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="in865" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=865062500 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=865402500 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=865985000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=2 + + # RX2 frequency (Hz) + rx2_frequency=866550000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=4 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_ism2400.toml b/Chirpstack_v4/configuration/chirpstack/region_ism2400.toml new file mode 100644 index 0000000..9b37d2d --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_ism2400.toml @@ -0,0 +1,210 @@ +# This file contains an example ISM2400 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="ism2400" + + # Description is a short description for this region. + description="ISM2400" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="ISM2400" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="ism2400" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=2403000000 + bandwidth=812000 + modulation="LORA" + spreading_factors=[12] + + [[regions.gateway.channels]] + frequency=2479000000 + bandwidth=812000 + modulation="LORA" + spreading_factors=[12] + + [[regions.gateway.channels]] + frequency=2425000000 + bandwidth=812000 + modulation="LORA" + spreading_factors=[12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=2423000000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=7 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=0 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_kr920.toml b/Chirpstack_v4/configuration/chirpstack/region_kr920.toml new file mode 100644 index 0000000..c20a9db --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_kr920.toml @@ -0,0 +1,210 @@ +# This file contains an example KR920 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="kr920" + + # Description is a short description for this region. + description="KR920" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="KR920" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="kr920" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=922100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=922300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=922500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=921900000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=3 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_ru864.toml b/Chirpstack_v4/configuration/chirpstack/region_ru864.toml new file mode 100644 index 0000000..071be02 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_ru864.toml @@ -0,0 +1,204 @@ +# This file contains an example RU864 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="ru864" + + # Description is a short description for this region. + description="RU864" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="RU864" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="ru864" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=868900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=869100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=869100000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=3 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_us915_0.toml b/Chirpstack_v4/configuration/chirpstack/region_us915_0.toml new file mode 100644 index 0000000..0bca96f --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_us915_0.toml @@ -0,0 +1,253 @@ +# This file contains an example US915 example (channels 0-7 + 64). +[[regions]] + + # ID is an use-defined identifier for this region. + id="us915_0" + + # Description is a short description for this region. + description="US915 (channels 0-7 + 64)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="US915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="us915_0" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=902300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=902500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=902700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=902900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=903100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=903300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=903500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=903700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=903000000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=3 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[0, 1, 2, 3, 4, 5, 6, 7, 64] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_us915_1.toml b/Chirpstack_v4/configuration/chirpstack/region_us915_1.toml new file mode 100644 index 0000000..2ed6b3f --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_us915_1.toml @@ -0,0 +1,253 @@ +# This file contains an example US915 example (channels 8-15 + 65). +[[regions]] + + # ID is an use-defined identifier for this region. + id="us915_1" + + # Description is a short description for this region. + description="US915 (channels 8-15 + 65)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="US915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="us915_1" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=903900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=904100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=904300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=904500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=904700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=904900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=905100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=905300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=904600000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=3 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[8, 9, 10, 11, 12, 13, 14, 15, 65] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_us915_2.toml b/Chirpstack_v4/configuration/chirpstack/region_us915_2.toml new file mode 100644 index 0000000..7d906cd --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_us915_2.toml @@ -0,0 +1,253 @@ +# This file contains an example US915 example (channels 16-23 + 66). +[[regions]] + + # ID is an use-defined identifier for this region. + id="us915_2" + + # Description is a short description for this region. + description="US915 (channels 16-23 + 66)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="US915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="us915_2" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=905500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=905700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=905900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=906100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=906300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=906500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=906700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=906900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=906200000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=3 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[16, 17, 18, 19, 20, 21, 22, 23, 66] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_us915_3.toml b/Chirpstack_v4/configuration/chirpstack/region_us915_3.toml new file mode 100644 index 0000000..708e810 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_us915_3.toml @@ -0,0 +1,253 @@ +# This file contains an example US915 example (channels 24-31 + 67). +[[regions]] + + # ID is an use-defined identifier for this region. + id="us915_3" + + # Description is a short description for this region. + description="US915 (channels 24-31 + 67)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="US915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="us915_3" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=907100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=907300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=907500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=907700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=907900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=908100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=908300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=908500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=907800000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=3 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[24, 25, 26, 27, 28, 29, 30, 31, 67] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_us915_4.toml b/Chirpstack_v4/configuration/chirpstack/region_us915_4.toml new file mode 100644 index 0000000..bd0ac39 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_us915_4.toml @@ -0,0 +1,253 @@ +# This file contains an example US915 example (channels 32-39 + 68). +[[regions]] + + # ID is an use-defined identifier for this region. + id="us915_4" + + # Description is a short description for this region. + description="US915 (channels 32-39 + 68)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="US915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="us915_4" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=908700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=908900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=909100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=909300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=909500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=909700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=909900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=910100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=909400000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=3 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[32, 33, 34, 35, 36, 37, 38, 39, 68] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_us915_5.toml b/Chirpstack_v4/configuration/chirpstack/region_us915_5.toml new file mode 100644 index 0000000..3d27aaf --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_us915_5.toml @@ -0,0 +1,253 @@ +# This file contains an example US915 example (channels 40-47 + 69). +[[regions]] + + # ID is an use-defined identifier for this region. + id="us915_5" + + # Description is a short description for this region. + description="US915 (channels 40-47 + 69)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="US915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="us915_5" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=910300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=910500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=910700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=910900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=911100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=911300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=911500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=911700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=911000000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=3 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[40, 41, 42, 43, 44, 45, 46, 47, 69] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_us915_6.toml b/Chirpstack_v4/configuration/chirpstack/region_us915_6.toml new file mode 100644 index 0000000..d02d935 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_us915_6.toml @@ -0,0 +1,253 @@ +# This file contains an example US915 example (channels 48-55 + 70). +[[regions]] + + # ID is an use-defined identifier for this region. + id="us915_6" + + # Description is a short description for this region. + description="US915 (channels 48-55 + 70)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="US915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="us915_6" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=911900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=912100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=912300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=912500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=912700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=912900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=913100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=913300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=912600000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=3 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[48, 49, 50, 51, 52, 53, 54, 55, 70] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/chirpstack/region_us915_7.toml b/Chirpstack_v4/configuration/chirpstack/region_us915_7.toml new file mode 100644 index 0000000..f563ce3 --- /dev/null +++ b/Chirpstack_v4/configuration/chirpstack/region_us915_7.toml @@ -0,0 +1,253 @@ +# This file contains an example US915 example (channels 56-63 + 71). +[[regions]] + + # ID is an use-defined identifier for this region. + id="us915_7" + + # Description is a short description for this region. + description="US915 (channels 56-63 + 71)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="US915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="us915_7" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://$MQTT_BROKER_HOST:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=913500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=913700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=913900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=914100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=914300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=914500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=914700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=914900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=914200000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=3 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[56, 57, 58, 59, 60, 61, 62, 63, 71] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 diff --git a/Chirpstack_v4/configuration/mosquitto/config/mosquitto.conf b/Chirpstack_v4/configuration/mosquitto/config/mosquitto.conf new file mode 100644 index 0000000..2d040f2 --- /dev/null +++ b/Chirpstack_v4/configuration/mosquitto/config/mosquitto.conf @@ -0,0 +1,13 @@ +# listener 1883 +# allow_anonymous true + +listener 8883 +protocol mqtt + +cafile /mosquitto/certs/ca.pem +certfile /mosquitto/certs/server.pem +keyfile /mosquitto/certs/server.key + +require_certificate true # enforce client cert +use_identity_as_username true # CN becomes MQTT username +allow_anonymous true # optional: false for strict auth diff --git a/Chirpstack_v4/configuration/postgresql/initdb/001-chirpstack_extensions.sh b/Chirpstack_v4/configuration/postgresql/initdb/001-chirpstack_extensions.sh new file mode 100755 index 0000000..4028a2d --- /dev/null +++ b/Chirpstack_v4/configuration/postgresql/initdb/001-chirpstack_extensions.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -e + +psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname="$POSTGRES_DB" <<-EOSQL + create extension pg_trgm; + create extension hstore; +EOSQL diff --git a/Chirpstack_v4/docker-compose.yml b/Chirpstack_v4/docker-compose.yml new file mode 100644 index 0000000..ebca3db --- /dev/null +++ b/Chirpstack_v4/docker-compose.yml @@ -0,0 +1,109 @@ +version: '3.0' + +services: + chirpstack: + image: chirpstack/chirpstack:4 + command: -c /etc/chirpstack + restart: unless-stopped + networks: + pagerino_net: + chirp_net: + volumes: + - ./configuration/chirpstack:/etc/chirpstack + - ./certs:/etc/chirpstack/certs + depends_on: + - postgres + - mosquitto + - redis + environment: + - MQTT_BROKER_HOST=mosquitto + - REDIS_HOST=redis + - POSTGRESQL_HOST=postgres + - RUST_LOG=debug + ports: + - "8080:8080" + + chirpstack-gateway-bridge: + image: chirpstack/chirpstack-gateway-bridge:4 + restart: unless-stopped + networks: + chirp_net: + ports: + - "1700:1700/udp" + volumes: + - ./configuration/chirpstack-gateway-bridge:/etc/chirpstack-gateway-bridge + - ./certs:/etc/chirpstack-gateway-bridge/certs + environment: + - INTEGRATION__MQTT__EVENT_TOPIC_TEMPLATE=eu868/gateway/{{ .GatewayID }}/event/{{ .EventType }} + - INTEGRATION__MQTT__STATE_TOPIC_TEMPLATE=eu868/gateway/{{ .GatewayID }}/state/{{ .StateType }} + - INTEGRATION__MQTT__COMMAND_TOPIC_TEMPLATE=eu868/gateway/{{ .GatewayID }}/command/# + depends_on: + - mosquitto + + # chirpstack-gateway-bridge-basicstation: + # image: chirpstack/chirpstack-gateway-bridge:4 + # restart: 'no' + # networks: + # chirp_net: + # command: -c /etc/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-eu868.toml + # ports: + # - "3001:3001" + # volumes: + # - ./configuration/chirpstack-gateway-bridge:/etc/chirpstack-gateway-bridge + # - ./certs:/etc/chirpstack-gateway-bridge/certs + # depends_on: + # - mosquitto + + chirpstack-rest-api: + image: chirpstack/chirpstack-rest-api:4 + restart: unless-stopped + networks: + chirp_net: + command: --server chirpstack:8080 --bind 0.0.0.0:8090 --insecure + ports: + - "8090:8090" + depends_on: + - chirpstack + + postgres: + image: postgres:14-alpine + restart: unless-stopped + networks: + chirp_net: + volumes: + - ./configuration/postgresql/initdb:/docker-entrypoint-initdb.d + - postgresqldata:/var/lib/postgresql/data + environment: + - POSTGRES_USER=chirpstack + - POSTGRES_PASSWORD=chirpstack + - POSTGRES_DB=chirpstack + + redis: + image: redis:7-alpine + restart: unless-stopped + networks: + chirp_net: + command: redis-server --save 300 1 --save 60 100 --appendonly no + volumes: + - redisdata:/data + + mosquitto: + image: eclipse-mosquitto:2 + restart: unless-stopped + networks: + pagerino_net: + chirp_net: + ports: + - "8883:8883" + volumes: + - ./configuration/mosquitto/config/:/mosquitto/config/ + - ./certs:/mosquitto/certs + +volumes: + postgresqldata: + redisdata: + +networks: + pagerino_net: + external: true + chirp_net: diff --git a/Chirpstack_v4/tarball.tar.gz b/Chirpstack_v4/tarball.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..88236b96c8c38581111d79f9bfeaa00eb56abe25 GIT binary patch literal 28090 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 z%0D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 literal 0 HcmV?d00001 diff --git a/WebApp/.env b/WebApp/.env new file mode 100644 index 0000000..8280d19 --- /dev/null +++ b/WebApp/.env @@ -0,0 +1,36 @@ +# Enviroment variables that will be available for every application + +# General version of the system +VERSION=0.1 + +# Optional prefix for logging +LOG_PREFIX=[Pagerino] + +# Main app container name +SERVER_NAME=pagerino-app +SERVER_API_PORT=50222 + +# General preferred connection timeout +TIMEOUT=3s + +WS_NAME=send +WS_TIMEOUT=3s +WS_SIZE=512 +CROSS_ORIGINS= # CSV format for all URLs that can communicate with web app + +# === Basic +APP_NAME=Pagerino +LOG_PREFIX=[Pagerino Web] + +DEV_MODE=true + +# === Host settings +WEB_PORT=8222 + +# === UX configs +HOME_NAME=dashboard # Leave empty for default "/" +SESSION_DURATION=12h # one authorization duration + + +# === Secets & keys +JWT_SECRET=7jkNtpI4mM2QSW23ZILh2z6v0+gvKadNXi8I8jThiHU= diff --git a/WebApp/Dockerfile b/WebApp/Dockerfile new file mode 100755 index 0000000..3e2830d --- /dev/null +++ b/WebApp/Dockerfile @@ -0,0 +1,35 @@ +# [0] Go build environment +FROM golang:1.24.5-alpine3.21 AS builder +WORKDIR /web-server + +## Dependencies +# Get +COPY ./src/main/go.mod ./src/main/go.sum ./src/ +# Download +RUN cd ./src && \ + go mod download + +## Executable +# Get +COPY ./src/main/ ./src/ +# Build +RUN cd ./src && \ + go build -o ../build/web_server + +# [1] Final image -> new FS +FROM alpine:latest +WORKDIR /root/ + +# Add certs for net communication +RUN apk add --no-cache ca-certificates + +## Final build +# Get +COPY --from=builder /web-server/build ./build/ +COPY ./build/stylesheet.css ./layouts/ +COPY ./src/layouts ./layouts/ +COPY ./config ./config/ +COPY ./shared.env ./config/shared.env + +# Run +CMD ["./build/web_server"] diff --git a/WebApp/LICENCE b/WebApp/LICENCE new file mode 100644 index 0000000..8b98c19 --- /dev/null +++ b/WebApp/LICENCE @@ -0,0 +1,38 @@ +PAGERINO(tm) WEB APPLICATION LICENSE AGREEMENT + +1. Parties & Purpose +This License Agreement (“Agreement”) is entered into between GORAK Industries s.r.o., hereinafter “Licensor,” and [Client Name], hereinafter “Licensee,” for the use of the proprietary web application (“Software”) designed to work with specific provided and configured devices for the Pagerino(tm) system ("Devices"). + +2. Intended Use +The Software is designed for operation within a private local area network environment ("Environment") together with Devices and optimized for use in such a setting. If the Licensee chooses to expose the Software to external networks, use unathorized devices, use any parts of the Pagerino(tm) system in undocumented ways, the Licensee assumes full responsibility for any resulting risks, data breaches, performance degradation, or service interruptions. The Licensor is not liable for damages or losses arising from such use. + +3. Rights Granted +Licensee may install and run the Software on approved internal servers and grant access to Licensee's authorized employees. Backup copies may be made for disaster recovery only. No rights are granted to modify, reverse-engineer, redistribute, rent, lease, or sublicense the Software. + +4. Ownership +All intellectual property rights, including source code, remain the sole property of the Licensor. This Agreement does not transfer ownership of the Software or any associated rights, except the limited right to use as stated herein. + +5. Fees and Support +The license fee covers the right to use the Software in its delivered state. Updates, upgrades, enhancements, and technical support are not included in the license fee and will be provided only under separate agreements and at prices determined by the Licensor’s company at the time of service. The Licensor is not obliged to provide updates or support unless explicitly agreed in writing. + +6. Limitations + + The Software’s performance and accuracy depend on the network environment and the connected devices’ compliance with supported protocols. + + The Licensor is not liable for malfunctions caused by third-party hardware, network configuration errors, incompatible devices, or environmental factors outside its control. + + In case of system relocation, hardware replacement, or major infrastructure changes, reinstallation or reconfiguration support is considered a billable service. + + If the Licensee modifies the Software without authorization, the Licensor may terminate the Agreement immediately. + +7. Liability +The Software is provided “as-is.” To the maximum extent permitted under Czech law, the Licensor disclaims all warranties, whether express or implied, including fitness for a particular purpose. The Licensor’s liability for damages is limited to the amount actually paid for the license. Indirect, incidental, or consequential damages (including downtime, lost profits, or data loss) are excluded. + +8. Term & Termination +This license is granted as perpetual, allowing the Licensee to use the Software for an unlimited time, subject to compliance with this Agreement. The Licensee’s right to use the Software may be terminated by the Licensor only if the Licensee breaches the terms of this Agreement. Upon termination, the Licensee must cease all use of the Software and destroy all copies in its possession. + +9. Governing Law & Jurisdiction +This Agreement is governed by the laws of the Czech Republic. Any disputes will be resolved before the courts of Brno. + +10. Language & Final Provisions +This Agreement may be provided in multiple languages. In case of discrepancies, the Czech version shall prevail. This document contains the entire agreement between the parties concerning the Software. \ No newline at end of file diff --git a/WebApp/Makefile b/WebApp/Makefile new file mode 100644 index 0000000..ae3a79e --- /dev/null +++ b/WebApp/Makefile @@ -0,0 +1,23 @@ +# Variables +CSS_INPUT:=./src/layouts/styles/global.css +CSS_OUTPUT:=./build/stylesheet.css +NAME:=web-app + +all: css + +# Build Tailwind +css: ./src/layouts/**/*.css ./src/layouts/**/*.tmpl + npx tailwindcss -i $(CSS_INPUT) -o $(CSS_OUTPUT) --minify + +# Build App +go: ./src/main/*.go + go build -o ./build/$(NAME) ./src/main.go + +run: css go + ./build/$(NAME) + +# Clear build +clean: + rm -rf ./build/$(NAME) ./build/stylesheet.css + +.PHONY: run clean all \ No newline at end of file diff --git a/WebApp/README.md b/WebApp/README.md new file mode 100644 index 0000000..d59e62b --- /dev/null +++ b/WebApp/README.md @@ -0,0 +1,29 @@ +# Pagerino: **Web server** + +### Description + +Dockerized server communicating with Pagerino applications to provide an interface. + +### Features + +Current working and in-progress capabilities include: + - list all devices + - add/modify/remove users, devices, roles and other objects + - see user, device, role and other's properties + - see live map view of devices + +### Usage + +The web app connects to other Pagerino applications after user authorization, +so all of the accessed apps have to be running and reachable. + +First build the Tailwind css: +```make css``` + +Then to start the server with docker: +```docker compose up``` + +Alternatively you can just run it normally: +```make go && make run``` + +*Created by Olek \@ Gorak Industries* diff --git a/WebApp/build/stylesheet.css b/WebApp/build/stylesheet.css new file mode 100644 index 0000000..3358cbe --- /dev/null +++ b/WebApp/build/stylesheet.css @@ -0,0 +1,2 @@ +/*! tailwindcss v4.1.12 | MIT License | https://tailwindcss.com */ +@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-gray-100:oklch(96.7% .003 264.542);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-900:oklch(21% .034 264.665);--color-white:#fff;--spacing:.25rem;--container-7xl:80rem;--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.fixed{position:fixed}.top-0{top:calc(var(--spacing)*0)}.z-50{z-index:50}.mx-auto{margin-inline:auto}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-12{margin-top:calc(var(--spacing)*12)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.ml-2{margin-left:calc(var(--spacing)*2)}.flex{display:flex}.hidden{display:none}.h-6{height:calc(var(--spacing)*6)}.h-8{height:calc(var(--spacing)*8)}.h-12{height:calc(var(--spacing)*12)}.w-6{width:calc(var(--spacing)*6)}.w-full{width:100%}.max-w-7xl{max-width:var(--container-7xl)}.flex-1{flex:1}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-8{gap:calc(var(--spacing)*8)}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*2)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-4>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*4)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-6>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*6)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-x-reverse)))}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-gray-700{border-color:var(--color-gray-700)}.bg-\[var\(--primary-bg\)\]{background-color:var(--primary-bg)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-900{background-color:var(--color-gray-900)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-2{padding-block:calc(var(--spacing)*2)}.py-3{padding-block:calc(var(--spacing)*3)}.py-10{padding-block:calc(var(--spacing)*10)}.pt-6{padding-top:calc(var(--spacing)*6)}.text-center{text-align:center}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.text-\[var\(--accent\)\]{color:var(--accent)}.text-\[var\(--text-primary\)\]{color:var(--text-primary)}.text-gray-300{color:var(--color-gray-300)}.text-gray-500{color:var(--color-gray-500)}.text-white{color:var(--color-white)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-300{--tw-duration:.3s;transition-duration:.3s}@media (hover:hover){.hover\:text-\[var\(--accent\)\]:hover{color:var(--accent)}.hover\:text-\[var\(--accent-light\)\]:hover{color:var(--accent-light)}.hover\:underline:hover{text-decoration-line:underline}}@media (min-width:48rem){.md\:flex{display:flex}.md\:hidden{display:none}.md\:h-10{height:calc(var(--spacing)*10)}.md\:h-16{height:calc(var(--spacing)*16)}.md\:flex-row{flex-direction:row}.md\:justify-between{justify-content:space-between}.md\:py-3{padding-block:calc(var(--spacing)*3)}.md\:py-4{padding-block:calc(var(--spacing)*4)}.md\:text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}}}:root{--color-bg:#f8f9fa;--color-bg-alt:#e9ecef;--color-surface:#111213;--color-surface-alt:#1c1d1f;--color-text:#111213;--color-text-muted:#555;--color-text-inverse:#f8f9fa;--color-accent:#4f46e5;--color-accent-hover:#6366f1;--color-accent-muted:#818cf8;--color-success:#22c55e;--color-warning:#eab308;--color-danger:#ef4444}body{background-color:var(--color-bg);color:var(--color-text);margin:0;font-family:Inter,system-ui,-apple-system,Segoe UI,Roboto,sans-serif;line-height:1.6}a{color:var(--color-accent);text-decoration:none;transition:color .2s}a:hover{color:var(--color-accent-hover);text-decoration:underline}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:"*";inherits:false} \ No newline at end of file diff --git a/WebApp/docker-compose.yml b/WebApp/docker-compose.yml new file mode 100644 index 0000000..eb406c3 --- /dev/null +++ b/WebApp/docker-compose.yml @@ -0,0 +1,13 @@ +version: '3.0' + +services: + web_server: + build: . + container_name: web_server + networks: + pagerino_net: + restart: on-failure:3 + +networks: + pagerino_net: + external: true \ No newline at end of file diff --git a/WebApp/package-lock.json b/WebApp/package-lock.json new file mode 100644 index 0000000..9928eaa --- /dev/null +++ b/WebApp/package-lock.json @@ -0,0 +1,1133 @@ +{ + "name": "WebApp", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@tailwindcss/cli": "^4.1.12", + "tailwindcss": "^4.1.12" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.30", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", + "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/cli": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.1.12.tgz", + "integrity": "sha512-2PyJ5MGh/6JPS+cEaAq6MGDx3UemkX/mJt+/phm7/VOpycpecwNnHuFZbbgx6TNK/aIjvFOhhTVlappM7tmqvQ==", + "license": "MIT", + "dependencies": { + "@parcel/watcher": "^2.5.1", + "@tailwindcss/node": "4.1.12", + "@tailwindcss/oxide": "4.1.12", + "enhanced-resolve": "^5.18.3", + "mri": "^1.2.0", + "picocolors": "^1.1.1", + "tailwindcss": "4.1.12" + }, + "bin": { + "tailwindcss": "dist/index.mjs" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.12.tgz", + "integrity": "sha512-3hm9brwvQkZFe++SBt+oLjo4OLDtkvlE8q2WalaD/7QWaeM7KEJbAiY/LJZUaCs7Xa8aUu4xy3uoyX4q54UVdQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "enhanced-resolve": "^5.18.3", + "jiti": "^2.5.1", + "lightningcss": "1.30.1", + "magic-string": "^0.30.17", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.12" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.12.tgz", + "integrity": "sha512-gM5EoKHW/ukmlEtphNwaGx45fGoEmP10v51t9unv55voWh6WrOL19hfuIdo2FjxIaZzw776/BUQg7Pck++cIVw==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.4", + "tar": "^7.4.3" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.12", + "@tailwindcss/oxide-darwin-arm64": "4.1.12", + "@tailwindcss/oxide-darwin-x64": "4.1.12", + "@tailwindcss/oxide-freebsd-x64": "4.1.12", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.12", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.12", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.12", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.12", + "@tailwindcss/oxide-linux-x64-musl": "4.1.12", + "@tailwindcss/oxide-wasm32-wasi": "4.1.12", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.12", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.12" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.12.tgz", + "integrity": "sha512-oNY5pq+1gc4T6QVTsZKwZaGpBb2N1H1fsc1GD4o7yinFySqIuRZ2E4NvGasWc6PhYJwGK2+5YT1f9Tp80zUQZQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.12.tgz", + "integrity": "sha512-cq1qmq2HEtDV9HvZlTtrj671mCdGB93bVY6J29mwCyaMYCP/JaUBXxrQQQm7Qn33AXXASPUb2HFZlWiiHWFytw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.12.tgz", + "integrity": "sha512-6UCsIeFUcBfpangqlXay9Ffty9XhFH1QuUFn0WV83W8lGdX8cD5/+2ONLluALJD5+yJ7k8mVtwy3zMZmzEfbLg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.12.tgz", + "integrity": "sha512-JOH/f7j6+nYXIrHobRYCtoArJdMJh5zy5lr0FV0Qu47MID/vqJAY3r/OElPzx1C/wdT1uS7cPq+xdYYelny1ww==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.12.tgz", + "integrity": "sha512-v4Ghvi9AU1SYgGr3/j38PD8PEe6bRfTnNSUE3YCMIRrrNigCFtHZ2TCm8142X8fcSqHBZBceDx+JlFJEfNg5zQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.12.tgz", + "integrity": "sha512-YP5s1LmetL9UsvVAKusHSyPlzSRqYyRB0f+Kl/xcYQSPLEw/BvGfxzbH+ihUciePDjiXwHh+p+qbSP3SlJw+6g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.12.tgz", + "integrity": "sha512-V8pAM3s8gsrXcCv6kCHSuwyb/gPsd863iT+v1PGXC4fSL/OJqsKhfK//v8P+w9ThKIoqNbEnsZqNy+WDnwQqCA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.12.tgz", + "integrity": "sha512-xYfqYLjvm2UQ3TZggTGrwxjYaLB62b1Wiysw/YE3Yqbh86sOMoTn0feF98PonP7LtjsWOWcXEbGqDL7zv0uW8Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.12.tgz", + "integrity": "sha512-ha0pHPamN+fWZY7GCzz5rKunlv9L5R8kdh+YNvP5awe3LtuXb5nRi/H27GeL2U+TdhDOptU7T6Is7mdwh5Ar3A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.12.tgz", + "integrity": "sha512-4tSyu3dW+ktzdEpuk6g49KdEangu3eCYoqPhWNsZgUhyegEda3M9rG0/j1GV/JjVVsj+lG7jWAyrTlLzd/WEBg==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.5", + "@emnapi/runtime": "^1.4.5", + "@emnapi/wasi-threads": "^1.0.4", + "@napi-rs/wasm-runtime": "^0.2.12", + "@tybys/wasm-util": "^0.10.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.12.tgz", + "integrity": "sha512-iGLyD/cVP724+FGtMWslhcFyg4xyYyM+5F4hGvKA7eifPkXHRAUDFaimu53fpNg9X8dfP75pXx/zFt/jlNF+lg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.12.tgz", + "integrity": "sha512-NKIh5rzw6CpEodv/++r0hGLlfgT/gFN+5WNdZtvh6wpU2BpGNgdjvj6H2oFc8nCM839QM1YOhjpgbAONUb4IxA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide/node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "license": "Apache-2.0", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/jiti": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", + "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/lightningcss": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", + "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.30.1", + "lightningcss-darwin-x64": "1.30.1", + "lightningcss-freebsd-x64": "1.30.1", + "lightningcss-linux-arm-gnueabihf": "1.30.1", + "lightningcss-linux-arm64-gnu": "1.30.1", + "lightningcss-linux-arm64-musl": "1.30.1", + "lightningcss-linux-x64-gnu": "1.30.1", + "lightningcss-linux-x64-musl": "1.30.1", + "lightningcss-win32-arm64-msvc": "1.30.1", + "lightningcss-win32-x64-msvc": "1.30.1" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", + "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", + "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", + "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", + "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", + "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", + "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", + "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", + "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", + "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", + "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss/node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", + "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tailwindcss": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.12.tgz", + "integrity": "sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA==", + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + } + } +} diff --git a/WebApp/package.json b/WebApp/package.json new file mode 100644 index 0000000..7714e6c --- /dev/null +++ b/WebApp/package.json @@ -0,0 +1,6 @@ +{ + "dependencies": { + "@tailwindcss/cli": "^4.1.12", + "tailwindcss": "^4.1.12" + } +} diff --git a/WebApp/page_list.md b/WebApp/page_list.md new file mode 100755 index 0000000..492830b --- /dev/null +++ b/WebApp/page_list.md @@ -0,0 +1,19 @@ +## List of pages for web app: +- Network page: + - List of devices + one gate: expandable device info in vertical layout + link to device page + - Search function with filters +- Live map view: clickable devices linking to their page +- Device page: + - Full overview of device's properties and history logs + - *Can message, assign task and ping device?* +- Account page: + - Properties + - Name & password change + - 2FA + - Account deletion +- Home/Personal page: + - Assigned device & card status + - Recent messages, mentions, tasks, logs + - *Provides interface to send messages remotely through web?* +- Analytics: Displays various insights about daily work & communication like: messages sent, tasks assigned/in-progress/completed... +- Console attachment: at the bottom of any page if role is Admin diff --git a/WebApp/src/layouts/components/footer.tmpl b/WebApp/src/layouts/components/footer.tmpl new file mode 100644 index 0000000..8e2b08d --- /dev/null +++ b/WebApp/src/layouts/components/footer.tmpl @@ -0,0 +1,44 @@ +{{ define "footer" -}} + +{{- end }} diff --git a/WebApp/src/layouts/components/meta.tmpl b/WebApp/src/layouts/components/meta.tmpl new file mode 100644 index 0000000..ea47f5f --- /dev/null +++ b/WebApp/src/layouts/components/meta.tmpl @@ -0,0 +1,8 @@ +{{ define "meta" -}} +{{ .meta.Title }} + + + + +{{- end }} \ No newline at end of file diff --git a/WebApp/src/layouts/components/navbar.tmpl b/WebApp/src/layouts/components/navbar.tmpl new file mode 100644 index 0000000..9eacf70 --- /dev/null +++ b/WebApp/src/layouts/components/navbar.tmpl @@ -0,0 +1,69 @@ +{{ define "navbar" }} + + + +{{ end }} \ No newline at end of file diff --git a/WebApp/src/layouts/index.tmpl b/WebApp/src/layouts/index.tmpl new file mode 100644 index 0000000..2b1d4fe --- /dev/null +++ b/WebApp/src/layouts/index.tmpl @@ -0,0 +1,51 @@ +{{ define "layout" }} + + + + + + + + + + {{ template "meta" . }} + + + {{ template "navbar" . }} +
+ {{ template "content" . }} +
+
+ {{ template "footer" . }} +
+ + + + +{{ end }} \ No newline at end of file diff --git a/WebApp/src/layouts/pages/home.tmpl b/WebApp/src/layouts/pages/home.tmpl new file mode 100644 index 0000000..73c37e8 --- /dev/null +++ b/WebApp/src/layouts/pages/home.tmpl @@ -0,0 +1,5 @@ +{{ define "content" -}} +

+ Hello, Pagerino User! +

+{{- end }} \ No newline at end of file diff --git a/WebApp/src/layouts/pages/login.tmpl b/WebApp/src/layouts/pages/login.tmpl new file mode 100644 index 0000000..4e1cf59 --- /dev/null +++ b/WebApp/src/layouts/pages/login.tmpl @@ -0,0 +1,11 @@ +{{ define "content" -}} +
+ + + + + + + +
+{{- end }} \ No newline at end of file diff --git a/WebApp/src/layouts/styles/global.css b/WebApp/src/layouts/styles/global.css new file mode 100644 index 0000000..34efc60 --- /dev/null +++ b/WebApp/src/layouts/styles/global.css @@ -0,0 +1,79 @@ +@import "tailwindcss"; + +/* Global theme variables */ +:root { + /* Core palette */ + --color-bg: #f8f9fa; /* main background (soft white) */ + --color-bg-alt: #e9ecef; /* alternate background (slightly darker gray) */ + --color-surface: #111213; /* text surfaces or headers */ + --color-surface-alt: #1c1d1f; + + /* Accent tones */ + --color-text: #111213; /* main text (almost black) */ + --color-text-muted: #555; /* muted text (medium gray) */ + --color-text-inverse: #f8f9fa; /* for buttons on dark backgrounds */ + + /* Feedback tones */ + --color-accent: #4f46e5; /* indigo-ish */ + --color-accent-hover: #6366f1; + --color-accent-muted: #818cf8; + + --color-success: #22c55e; /* green-500 */ + --color-warning: #eab308; /* yellow-500 */ + --color-danger: #ef4444; /* red-500 */ +} + +/* Base reset / typography */ +body { + margin: 0; + font-family: 'Inter', system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; + background-color: var(--color-bg); + color: var(--color-text); + line-height: 1.6; +} + +/* Links */ +a { + color: var(--color-accent); + text-decoration: none; + transition: color 0.2s ease; +} +a:hover { + color: var(--color-accent-hover); + text-decoration: underline; +} + +/* Muted text */ +/* .text-muted { + color: var(--color-text-muted); +} */ + +/* Card-like containers */ +/* .card { + background-color: var(--color-bg-alt); + border-radius: 0.75rem; + padding: 1rem; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4); +} */ + +/* Buttons */ +/* .btn { + display: inline-block; + padding: 0.5rem 1rem; + border-radius: 0.5rem; + font-weight: 500; + text-align: center; + cursor: pointer; + background-color: var(--color-accent); + color: var(--color-text); + transition: background-color 0.2s ease; +} + +.btn:hover { + background-color: var(--color-accent-hover); +} + +.btn-muted { + background-color: var(--color-bg-alt); + color: var(--color-text-muted); +} */ \ No newline at end of file diff --git a/WebApp/src/main/go.mod b/WebApp/src/main/go.mod new file mode 100644 index 0000000..5e3011d --- /dev/null +++ b/WebApp/src/main/go.mod @@ -0,0 +1,48 @@ +module pagerino-web + +go 1.23.0 + +toolchain go1.24.6 + +require ( + github.com/gin-gonic/gin v1.10.1 + github.com/joho/godotenv v1.5.1 +) + +require ( + github.com/kr/pretty v0.3.0 // indirect + github.com/rogpeppe/go-internal v1.14.1 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect +) + +require ( + github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.20.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/golang-jwt/jwt/v5 v5.3.0 + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/crypto v0.39.0 + golang.org/x/net v0.41.0 // indirect + golang.org/x/sys v0.33.0 // indirect + golang.org/x/text v0.26.0 // indirect + google.golang.org/grpc v1.75.0 + google.golang.org/protobuf v1.36.6 + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/WebApp/src/main/go.sum b/WebApp/src/main/go.sum new file mode 100644 index 0000000..c0dc62f --- /dev/null +++ b/WebApp/src/main/go.sum @@ -0,0 +1,132 @@ +github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= +github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= +github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= +github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= +github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= +github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= +golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/WebApp/src/main/main.go b/WebApp/src/main/main.go new file mode 100644 index 0000000..e38425b --- /dev/null +++ b/WebApp/src/main/main.go @@ -0,0 +1,271 @@ +/* +Pagerino web application designed for management and various +views of devices and system-related data. +Author: Olek +*/ +package main + +import ( + "log" + "os" + "os/signal" + "strings" + "syscall" + "time" + + api_common "pagerino-web/pager_api/common" + api_user "pagerino-web/pager_api/user" + + "github.com/joho/godotenv" + "google.golang.org/grpc" + + "github.com/golang-jwt/jwt/v5" + "golang.org/x/crypto/bcrypt" + + "net/http" + + "github.com/gin-gonic/gin" +) + +// App objects and data needed througout the program +type AppData struct { + ExitSig chan os.Signal + ApiUserClient api_user.UserServiceClient + Timeout time.Duration +} + +func (data *AppData) FindEnv(name string) string { + val := os.Getenv(name) + if val == "" { + log.Println("Missing config value for: " + name) + data.ExitSig <- os.Interrupt + log.Fatalln("Shutting down...") + } + + return val +} + +// === Server Render Data === + +// Basic User information +type UserData struct { + Name string + ID int64 + Authorized bool +} + +// Webpage metadata +type PageMeta struct { + Title string + Description string + IconFile string +} + +// === Utilities === + +// Shortcut to get split up URL from *gin.Context +func SplitPath(ctx *gin.Context) []string { + return strings.Split(ctx.Request.URL.EscapedPath(), "/") +} + +// === Helpers === + +// GenerateToken creates a signed JWT for a user +func GenerateToken(username string) (string, error) { + expiration, err := time.ParseDuration(os.Getenv("SESSION_DURATION")) + if err != nil { + return "", err + } + + now := time.Now() + + token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.RegisteredClaims{ + Subject: username, + ExpiresAt: jwt.NewNumericDate(now.Add(expiration)), + IssuedAt: jwt.NewNumericDate(now), + Issuer: os.Getenv("APP_NAME"), + }) + return token.SignedString(os.Getenv("JWT_SECRET")) +} + +// CheckAuth aborts with 401 if JWT is invalid or not present +func CheckAuth(ctx *gin.Context) { + auth_header := ctx.GetHeader("Authorization") + if auth_header == "" { // No token -> login + ctx.Redirect(http.StatusTemporaryRedirect, "/login") + return + } + + // Expect "Bearer " + parts := strings.Split(auth_header, " ") + if len(parts) != 2 || parts[0] != "Bearer" { + ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid token format"}) + return + } + + token_str := parts[1] + claims := &jwt.RegisteredClaims{} + + token, err := jwt.ParseWithClaims(token_str, claims, func(token *jwt.Token) (any, error) { + return os.Getenv("JWT_SECRET"), nil + }) + + if err != nil { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "Could not parse token"}) + log.Println("Failed to parse authentication token: " + token_str) + return + } + + if !token.Valid { // Token expired -> login + ctx.Redirect(http.StatusTemporaryRedirect, "/login") + return + } + + // Store username in context for handlers/templates + ctx.Set("username", claims.Subject) +} + +// === Handlers === + +// loginHandler is a handler for POST forms in "/login" +func loginPost(ctx *gin.Context, app_data *AppData) { + username := ctx.PostForm("username") + password := ctx.PostForm("password") + + db_pass, err := app_data.ApiUserClient.GetPassword(ctx, + &api_common.StrIndex{Id: &api_common.StrIndex_Name{Name: username}}, + ) + if err != nil { + ctx.AbortWithStatusJSON( + http.StatusInternalServerError, + gin.H{"error": "Could not fetch user password"}, + ) + log.Println("Failed to fetch user password from DB") + return + } + + err = bcrypt.CompareHashAndPassword([]byte(db_pass.GetPassword()), []byte(password)) + if err != nil { + ctx.AbortWithStatusJSON( + http.StatusBadRequest, + gin.H{"error": "User password does not match"}, + ) + return + } + + token, err := GenerateToken(username) + if err != nil { + log.Println(" JWT generation fail") + ctx.AbortWithStatusJSON( + http.StatusInternalServerError, + gin.H{"error": "Could not generate token"}, + ) + log.Println("Failed to generate user authentication token") + return + } + + ctx.Header("Authorization", "Bearer "+token) + ctx.Status(http.StatusAccepted) +} + +func main() { + // = Exit signal + Data := AppData{ + ExitSig: make(chan os.Signal), + } + signal.Notify(Data.ExitSig, syscall.SIGINT, syscall.SIGTERM) + + // = Load configs + godotenv.Load("./config/app_config.env", "./config/shared.env", "./config/socket_config.env") + + // = Setup logger + log.SetFlags(log.Lmsgprefix | log.LUTC | log.Lshortfile) + log.SetPrefix(Data.FindEnv("LOG_PREFIX") + " ") + + // === Router + router := gin.Default() + + // Load assets and HTML templates + router.Static("./layouts/static", "./layouts/static") + router.LoadHTMLGlob("./layouts/**/*.tmpl") + + HOME_NAME := os.Getenv("HOME_NAME") + + // Redirect to home + if HOME_NAME != "" { + router.GET("/", func(ctx *gin.Context) { + ctx.Redirect(http.StatusPermanentRedirect, "/"+HOME_NAME) + }) + } + + tmout, err := time.ParseDuration(Data.FindEnv("TIMEOUT")) + if err != nil { + log.Println("Format misconfiguration: TIMEOUT") + return + } + + Data.Timeout = tmout + + dial_opts := []grpc.DialOption{ + //grpc.WithBlock(), + grpc.WithInsecure(), + } + grpc_client, err := grpc.Dial( + "app_server:"+Data.FindEnv("SERVER_API_PORT"), + dial_opts..., + ) + if err != nil { + log.Println("Failed to connect to gRPC API") + return + } + Data.ApiUserClient = api_user.NewUserServiceClient(grpc_client) + + // Create auth group + auth_group := router.Group("/", CheckAuth) + + // Starting home page + auth_group.GET("/"+HOME_NAME, func(ctx *gin.Context) { + var title string + if HOME_NAME == "" { + title = "Home" + } else { + title = strings.ToTitle(HOME_NAME) + } + + ctx.HTML(http.StatusOK, "home.tmpl", gin.H{ + "meta": PageMeta{ + Title: title, + Description: "Pagerino system home page", + }, + }) + }) + + // Login page (escape auth handler) + router.GET("/login", func(ctx *gin.Context) { + ctx.HTML(http.StatusOK, "login.tmpl", gin.H{ + "meta": PageMeta{ + Title: "Login", + Description: "Pagerino system login page", + }, + }) + }) + + // Login attempt handler + router.POST("/login", func(ctx *gin.Context) { + loginPost(ctx, &Data) + }) + + // Run server in another thread for graceful shutdown + go func() { + if err := router.Run("localhost:" + Data.FindEnv("WEB_PORT")); err != nil && err != http.ErrServerClosed { + log.Println("HTTP Server error: " + err.Error()) + } + log.Println("HTTP server shutdown.") + + Data.ExitSig <- syscall.SIGINT + }() + + // = Graceful shutdown + <-Data.ExitSig + log.Println("Shutting down...") +} diff --git a/WebApp/src/main/pager_api/change/change.pb.go b/WebApp/src/main/pager_api/change/change.pb.go new file mode 100644 index 0000000..2eaf33e --- /dev/null +++ b/WebApp/src/main/pager_api/change/change.pb.go @@ -0,0 +1,278 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: change.proto + +package api_change + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + common "server/app_comm/api/common" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ChageAllInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OldValue string `protobuf:"bytes,1,opt,name=old_value,json=oldValue,proto3" json:"old_value,omitempty"` + NewValue string `protobuf:"bytes,2,opt,name=new_value,json=newValue,proto3" json:"new_value,omitempty"` + TableName string `protobuf:"bytes,3,opt,name=table_name,json=tableName,proto3" json:"table_name,omitempty"` + Operation string `protobuf:"bytes,4,opt,name=operation,proto3" json:"operation,omitempty"` + LogId int32 `protobuf:"varint,5,opt,name=log_id,json=logId,proto3" json:"log_id,omitempty"` +} + +func (x *ChageAllInfo) Reset() { + *x = ChageAllInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_change_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ChageAllInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChageAllInfo) ProtoMessage() {} + +func (x *ChageAllInfo) ProtoReflect() protoreflect.Message { + mi := &file_change_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChageAllInfo.ProtoReflect.Descriptor instead. +func (*ChageAllInfo) Descriptor() ([]byte, []int) { + return file_change_proto_rawDescGZIP(), []int{0} +} + +func (x *ChageAllInfo) GetOldValue() string { + if x != nil { + return x.OldValue + } + return "" +} + +func (x *ChageAllInfo) GetNewValue() string { + if x != nil { + return x.NewValue + } + return "" +} + +func (x *ChageAllInfo) GetTableName() string { + if x != nil { + return x.TableName + } + return "" +} + +func (x *ChageAllInfo) GetOperation() string { + if x != nil { + return x.Operation + } + return "" +} + +func (x *ChageAllInfo) GetLogId() int32 { + if x != nil { + return x.LogId + } + return 0 +} + +type Values struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OldValue string `protobuf:"bytes,1,opt,name=old_value,json=oldValue,proto3" json:"old_value,omitempty"` + NewValue string `protobuf:"bytes,2,opt,name=new_value,json=newValue,proto3" json:"new_value,omitempty"` +} + +func (x *Values) Reset() { + *x = Values{} + if protoimpl.UnsafeEnabled { + mi := &file_change_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Values) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Values) ProtoMessage() {} + +func (x *Values) ProtoReflect() protoreflect.Message { + mi := &file_change_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Values.ProtoReflect.Descriptor instead. +func (*Values) Descriptor() ([]byte, []int) { + return file_change_proto_rawDescGZIP(), []int{1} +} + +func (x *Values) GetOldValue() string { + if x != nil { + return x.OldValue + } + return "" +} + +func (x *Values) GetNewValue() string { + if x != nil { + return x.NewValue + } + return "" +} + +var File_change_proto protoreflect.FileDescriptor + +var file_change_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x1a, + 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9c, 0x01, + 0x0a, 0x0c, 0x43, 0x68, 0x61, 0x67, 0x65, 0x41, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, + 0x0a, 0x09, 0x6f, 0x6c, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x6f, 0x6c, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6e, + 0x65, 0x77, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x6e, 0x65, 0x77, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x6c, 0x6f, 0x67, 0x5f, 0x69, 0x64, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x6f, 0x67, 0x49, 0x64, 0x22, 0x42, 0x0a, 0x06, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x6c, 0x64, 0x5f, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x6c, 0x64, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x65, 0x77, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x65, 0x77, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x32, 0xc6, 0x01, 0x0a, 0x0d, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x3a, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x44, 0x69, 0x66, 0x66, 0x12, 0x16, 0x2e, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x17, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x3f, + 0x0a, 0x06, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x12, 0x16, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, + 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x1a, 0x1d, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x2e, 0x43, 0x68, 0x61, 0x67, 0x65, 0x41, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x38, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x16, 0x2e, 0x70, 0x61, 0x67, + 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x64, + 0x65, 0x78, 0x1a, 0x15, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x42, 0x27, 0x5a, 0x25, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x3b, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_change_proto_rawDescOnce sync.Once + file_change_proto_rawDescData = file_change_proto_rawDesc +) + +func file_change_proto_rawDescGZIP() []byte { + file_change_proto_rawDescOnce.Do(func() { + file_change_proto_rawDescData = protoimpl.X.CompressGZIP(file_change_proto_rawDescData) + }) + return file_change_proto_rawDescData +} + +var file_change_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_change_proto_goTypes = []interface{}{ + (*ChageAllInfo)(nil), // 0: pagerino.change.ChageAllInfo + (*Values)(nil), // 1: pagerino.change.Values + (*common.Index)(nil), // 2: pagerino.common.Index + (*common.Meta)(nil), // 3: pagerino.common.Meta +} +var file_change_proto_depIdxs = []int32{ + 2, // 0: pagerino.change.ChangeService.GetDiff:input_type -> pagerino.common.Index + 2, // 1: pagerino.change.ChangeService.GetAll:input_type -> pagerino.common.Index + 2, // 2: pagerino.change.ChangeService.GetMeta:input_type -> pagerino.common.Index + 1, // 3: pagerino.change.ChangeService.GetDiff:output_type -> pagerino.change.Values + 0, // 4: pagerino.change.ChangeService.GetAll:output_type -> pagerino.change.ChageAllInfo + 3, // 5: pagerino.change.ChangeService.GetMeta:output_type -> pagerino.common.Meta + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_change_proto_init() } +func file_change_proto_init() { + if File_change_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_change_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ChageAllInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_change_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Values); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_change_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_change_proto_goTypes, + DependencyIndexes: file_change_proto_depIdxs, + MessageInfos: file_change_proto_msgTypes, + }.Build() + File_change_proto = out.File + file_change_proto_rawDesc = nil + file_change_proto_goTypes = nil + file_change_proto_depIdxs = nil +} diff --git a/WebApp/src/main/pager_api/change/change_grpc.pb.go b/WebApp/src/main/pager_api/change/change_grpc.pb.go new file mode 100644 index 0000000..9f9edcd --- /dev/null +++ b/WebApp/src/main/pager_api/change/change_grpc.pb.go @@ -0,0 +1,178 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package api_change + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + common "server/app_comm/api/common" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// ChangeServiceClient is the client API for ChangeService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ChangeServiceClient interface { + // === DB information + GetDiff(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*Values, error) + GetAll(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*ChageAllInfo, error) + // Common + GetMeta(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Meta, error) +} + +type changeServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewChangeServiceClient(cc grpc.ClientConnInterface) ChangeServiceClient { + return &changeServiceClient{cc} +} + +func (c *changeServiceClient) GetDiff(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*Values, error) { + out := new(Values) + err := c.cc.Invoke(ctx, "/pagerino.change.ChangeService/GetDiff", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *changeServiceClient) GetAll(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*ChageAllInfo, error) { + out := new(ChageAllInfo) + err := c.cc.Invoke(ctx, "/pagerino.change.ChangeService/GetAll", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *changeServiceClient) GetMeta(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Meta, error) { + out := new(common.Meta) + err := c.cc.Invoke(ctx, "/pagerino.change.ChangeService/GetMeta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ChangeServiceServer is the server API for ChangeService service. +// All implementations must embed UnimplementedChangeServiceServer +// for forward compatibility +type ChangeServiceServer interface { + // === DB information + GetDiff(context.Context, *common.Index) (*Values, error) + GetAll(context.Context, *common.Index) (*ChageAllInfo, error) + // Common + GetMeta(context.Context, *common.Index) (*common.Meta, error) + mustEmbedUnimplementedChangeServiceServer() +} + +// UnimplementedChangeServiceServer must be embedded to have forward compatible implementations. +type UnimplementedChangeServiceServer struct { +} + +func (UnimplementedChangeServiceServer) GetDiff(context.Context, *common.Index) (*Values, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetDiff not implemented") +} +func (UnimplementedChangeServiceServer) GetAll(context.Context, *common.Index) (*ChageAllInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAll not implemented") +} +func (UnimplementedChangeServiceServer) GetMeta(context.Context, *common.Index) (*common.Meta, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMeta not implemented") +} +func (UnimplementedChangeServiceServer) mustEmbedUnimplementedChangeServiceServer() {} + +// UnsafeChangeServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ChangeServiceServer will +// result in compilation errors. +type UnsafeChangeServiceServer interface { + mustEmbedUnimplementedChangeServiceServer() +} + +func RegisterChangeServiceServer(s grpc.ServiceRegistrar, srv ChangeServiceServer) { + s.RegisterService(&ChangeService_ServiceDesc, srv) +} + +func _ChangeService_GetDiff_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChangeServiceServer).GetDiff(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.change.ChangeService/GetDiff", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChangeServiceServer).GetDiff(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +func _ChangeService_GetAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChangeServiceServer).GetAll(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.change.ChangeService/GetAll", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChangeServiceServer).GetAll(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +func _ChangeService_GetMeta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChangeServiceServer).GetMeta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.change.ChangeService/GetMeta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChangeServiceServer).GetMeta(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +// ChangeService_ServiceDesc is the grpc.ServiceDesc for ChangeService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ChangeService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pagerino.change.ChangeService", + HandlerType: (*ChangeServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetDiff", + Handler: _ChangeService_GetDiff_Handler, + }, + { + MethodName: "GetAll", + Handler: _ChangeService_GetAll_Handler, + }, + { + MethodName: "GetMeta", + Handler: _ChangeService_GetMeta_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "change.proto", +} diff --git a/WebApp/src/main/pager_api/common/common.pb.go b/WebApp/src/main/pager_api/common/common.pb.go new file mode 100644 index 0000000..b22546d --- /dev/null +++ b/WebApp/src/main/pager_api/common/common.pb.go @@ -0,0 +1,588 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: common.proto + +package api_common + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// For custom logic responses +type RequestCode int32 + +const ( + RequestCode_UNKNOWN RequestCode = 0 + RequestCode_OK RequestCode = 1 + RequestCode_UNAUTHORIZED RequestCode = 2 + RequestCode_NO_DATA RequestCode = 3 + RequestCode_INTERNAL_ERROR RequestCode = 4 +) + +// Enum value maps for RequestCode. +var ( + RequestCode_name = map[int32]string{ + 0: "UNKNOWN", + 1: "OK", + 2: "UNAUTHORIZED", + 3: "NO_DATA", + 4: "INTERNAL_ERROR", + } + RequestCode_value = map[string]int32{ + "UNKNOWN": 0, + "OK": 1, + "UNAUTHORIZED": 2, + "NO_DATA": 3, + "INTERNAL_ERROR": 4, + } +) + +func (x RequestCode) Enum() *RequestCode { + p := new(RequestCode) + *p = x + return p +} + +func (x RequestCode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (RequestCode) Descriptor() protoreflect.EnumDescriptor { + return file_common_proto_enumTypes[0].Descriptor() +} + +func (RequestCode) Type() protoreflect.EnumType { + return &file_common_proto_enumTypes[0] +} + +func (x RequestCode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use RequestCode.Descriptor instead. +func (RequestCode) EnumDescriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{0} +} + +// === DB indexing +type StrIndex struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Id: + // *StrIndex_Num + // *StrIndex_Name + Id isStrIndex_Id `protobuf_oneof:"id"` +} + +func (x *StrIndex) Reset() { + *x = StrIndex{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StrIndex) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StrIndex) ProtoMessage() {} + +func (x *StrIndex) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StrIndex.ProtoReflect.Descriptor instead. +func (*StrIndex) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{0} +} + +func (m *StrIndex) GetId() isStrIndex_Id { + if m != nil { + return m.Id + } + return nil +} + +func (x *StrIndex) GetNum() int32 { + if x, ok := x.GetId().(*StrIndex_Num); ok { + return x.Num + } + return 0 +} + +func (x *StrIndex) GetName() string { + if x, ok := x.GetId().(*StrIndex_Name); ok { + return x.Name + } + return "" +} + +type isStrIndex_Id interface { + isStrIndex_Id() +} + +type StrIndex_Num struct { + Num int32 `protobuf:"varint,1,opt,name=num,proto3,oneof"` // Database ID +} + +type StrIndex_Name struct { + Name string `protobuf:"bytes,2,opt,name=name,proto3,oneof"` // for external fields: username, euid, name... +} + +func (*StrIndex_Num) isStrIndex_Id() {} + +func (*StrIndex_Name) isStrIndex_Id() {} + +type Index struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Num int32 `protobuf:"varint,1,opt,name=num,proto3" json:"num,omitempty"` // Database ID +} + +func (x *Index) Reset() { + *x = Index{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Index) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Index) ProtoMessage() {} + +func (x *Index) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Index.ProtoReflect.Descriptor instead. +func (*Index) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{1} +} + +func (x *Index) GetNum() int32 { + if x != nil { + return x.Num + } + return 0 +} + +// === DB information +type Meta struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` +} + +func (x *Meta) Reset() { + *x = Meta{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Meta) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Meta) ProtoMessage() {} + +func (x *Meta) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Meta.ProtoReflect.Descriptor instead. +func (*Meta) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{2} +} + +func (x *Meta) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Meta) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +type References struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Page int32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` // 32 IDs per page from most recent + RefId []int32 `protobuf:"varint,2,rep,packed,name=ref_id,json=refId,proto3" json:"ref_id,omitempty"` +} + +func (x *References) Reset() { + *x = References{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *References) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*References) ProtoMessage() {} + +func (x *References) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use References.ProtoReflect.Descriptor instead. +func (*References) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{3} +} + +func (x *References) GetPage() int32 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *References) GetRefId() []int32 { + if x != nil { + return x.RefId + } + return nil +} + +type Reference struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RefId int32 `protobuf:"varint,1,opt,name=ref_id,json=refId,proto3" json:"ref_id,omitempty"` +} + +func (x *Reference) Reset() { + *x = Reference{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Reference) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Reference) ProtoMessage() {} + +func (x *Reference) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Reference.ProtoReflect.Descriptor instead. +func (*Reference) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{4} +} + +func (x *Reference) GetRefId() int32 { + if x != nil { + return x.RefId + } + return 0 +} + +type Activity struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LastOnline *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=last_online,json=lastOnline,proto3" json:"last_online,omitempty"` +} + +func (x *Activity) Reset() { + *x = Activity{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Activity) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Activity) ProtoMessage() {} + +func (x *Activity) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Activity.ProtoReflect.Descriptor instead. +func (*Activity) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{5} +} + +func (x *Activity) GetLastOnline() *timestamppb.Timestamp { + if x != nil { + return x.LastOnline + } + return nil +} + +var File_common_proto protoreflect.FileDescriptor + +var file_common_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x1a, + 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x3a, 0x0a, 0x08, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x12, 0x0a, 0x03, + 0x6e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x03, 0x6e, 0x75, 0x6d, + 0x12, 0x14, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x04, 0x0a, 0x02, 0x69, 0x64, 0x22, 0x19, 0x0a, 0x05, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x10, 0x0a, 0x03, 0x6e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x03, 0x6e, 0x75, 0x6d, 0x22, 0x51, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x37, 0x0a, 0x0a, 0x52, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x15, 0x0a, 0x06, + 0x72, 0x65, 0x66, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, 0x52, 0x05, 0x72, 0x65, + 0x66, 0x49, 0x64, 0x22, 0x22, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x12, 0x15, 0x0a, 0x06, 0x72, 0x65, 0x66, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x05, 0x72, 0x65, 0x66, 0x49, 0x64, 0x22, 0x47, 0x0a, 0x08, 0x41, 0x63, 0x74, 0x69, 0x76, + 0x69, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6f, 0x6e, 0x6c, 0x69, + 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x2a, 0x55, 0x0a, 0x0b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, + 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, + 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, + 0x49, 0x5a, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x4e, 0x4f, 0x5f, 0x44, 0x41, 0x54, + 0x41, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x42, 0x27, 0x5a, 0x25, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2f, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x3b, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_common_proto_rawDescOnce sync.Once + file_common_proto_rawDescData = file_common_proto_rawDesc +) + +func file_common_proto_rawDescGZIP() []byte { + file_common_proto_rawDescOnce.Do(func() { + file_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_common_proto_rawDescData) + }) + return file_common_proto_rawDescData +} + +var file_common_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_common_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_common_proto_goTypes = []interface{}{ + (RequestCode)(0), // 0: pagerino.common.RequestCode + (*StrIndex)(nil), // 1: pagerino.common.StrIndex + (*Index)(nil), // 2: pagerino.common.Index + (*Meta)(nil), // 3: pagerino.common.Meta + (*References)(nil), // 4: pagerino.common.References + (*Reference)(nil), // 5: pagerino.common.Reference + (*Activity)(nil), // 6: pagerino.common.Activity + (*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp +} +var file_common_proto_depIdxs = []int32{ + 7, // 0: pagerino.common.Meta.created_at:type_name -> google.protobuf.Timestamp + 7, // 1: pagerino.common.Activity.last_online:type_name -> google.protobuf.Timestamp + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_common_proto_init() } +func file_common_proto_init() { + if File_common_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StrIndex); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Index); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Meta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*References); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Reference); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Activity); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_common_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*StrIndex_Num)(nil), + (*StrIndex_Name)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_common_proto_rawDesc, + NumEnums: 1, + NumMessages: 6, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_common_proto_goTypes, + DependencyIndexes: file_common_proto_depIdxs, + EnumInfos: file_common_proto_enumTypes, + MessageInfos: file_common_proto_msgTypes, + }.Build() + File_common_proto = out.File + file_common_proto_rawDesc = nil + file_common_proto_goTypes = nil + file_common_proto_depIdxs = nil +} diff --git a/WebApp/src/main/pager_api/device/device.pb.go b/WebApp/src/main/pager_api/device/device.pb.go new file mode 100644 index 0000000..b04eca9 --- /dev/null +++ b/WebApp/src/main/pager_api/device/device.pb.go @@ -0,0 +1,566 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: device.proto + +package api_device + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + common "server/app_comm/api/common" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Charge struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Charge float32 `protobuf:"fixed32,1,opt,name=charge,proto3" json:"charge,omitempty"` +} + +func (x *Charge) Reset() { + *x = Charge{} + if protoimpl.UnsafeEnabled { + mi := &file_device_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Charge) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Charge) ProtoMessage() {} + +func (x *Charge) ProtoReflect() protoreflect.Message { + mi := &file_device_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Charge.ProtoReflect.Descriptor instead. +func (*Charge) Descriptor() ([]byte, []int) { + return file_device_proto_rawDescGZIP(), []int{0} +} + +func (x *Charge) GetCharge() float32 { + if x != nil { + return x.Charge + } + return 0 +} + +type Location struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Latitude float64 `protobuf:"fixed64,1,opt,name=latitude,proto3" json:"latitude,omitempty"` + Longitude float64 `protobuf:"fixed64,2,opt,name=longitude,proto3" json:"longitude,omitempty"` + Altitude float32 `protobuf:"fixed32,3,opt,name=altitude,proto3" json:"altitude,omitempty"` +} + +func (x *Location) Reset() { + *x = Location{} + if protoimpl.UnsafeEnabled { + mi := &file_device_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Location) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Location) ProtoMessage() {} + +func (x *Location) ProtoReflect() protoreflect.Message { + mi := &file_device_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Location.ProtoReflect.Descriptor instead. +func (*Location) Descriptor() ([]byte, []int) { + return file_device_proto_rawDescGZIP(), []int{1} +} + +func (x *Location) GetLatitude() float64 { + if x != nil { + return x.Latitude + } + return 0 +} + +func (x *Location) GetLongitude() float64 { + if x != nil { + return x.Longitude + } + return 0 +} + +func (x *Location) GetAltitude() float32 { + if x != nil { + return x.Altitude + } + return 0 +} + +type DeviceBaseInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Euid string `protobuf:"bytes,2,opt,name=euid,proto3" json:"euid,omitempty"` + InternalStatus int32 `protobuf:"zigzag32,3,opt,name=internal_status,json=internalStatus,proto3" json:"internal_status,omitempty"` + LastOnline *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=last_online,json=lastOnline,proto3" json:"last_online,omitempty"` +} + +func (x *DeviceBaseInfo) Reset() { + *x = DeviceBaseInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_device_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeviceBaseInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeviceBaseInfo) ProtoMessage() {} + +func (x *DeviceBaseInfo) ProtoReflect() protoreflect.Message { + mi := &file_device_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeviceBaseInfo.ProtoReflect.Descriptor instead. +func (*DeviceBaseInfo) Descriptor() ([]byte, []int) { + return file_device_proto_rawDescGZIP(), []int{2} +} + +func (x *DeviceBaseInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DeviceBaseInfo) GetEuid() string { + if x != nil { + return x.Euid + } + return "" +} + +func (x *DeviceBaseInfo) GetInternalStatus() int32 { + if x != nil { + return x.InternalStatus + } + return 0 +} + +func (x *DeviceBaseInfo) GetLastOnline() *timestamppb.Timestamp { + if x != nil { + return x.LastOnline + } + return nil +} + +type DeviceAllInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Euid string `protobuf:"bytes,2,opt,name=euid,proto3" json:"euid,omitempty"` + InternalStatus int32 `protobuf:"zigzag32,3,opt,name=internal_status,json=internalStatus,proto3" json:"internal_status,omitempty"` + NativeStatus string `protobuf:"bytes,4,opt,name=native_status,json=nativeStatus,proto3" json:"native_status,omitempty"` + LastOnline *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=last_online,json=lastOnline,proto3" json:"last_online,omitempty"` + FwVersion string `protobuf:"bytes,6,opt,name=fw_version,json=fwVersion,proto3" json:"fw_version,omitempty"` + CardIds []int32 `protobuf:"varint,7,rep,packed,name=card_ids,json=cardIds,proto3" json:"card_ids,omitempty"` + Charge float32 `protobuf:"fixed32,8,opt,name=charge,proto3" json:"charge,omitempty"` + Latitude float64 `protobuf:"fixed64,9,opt,name=latitude,proto3" json:"latitude,omitempty"` + Longitude float64 `protobuf:"fixed64,10,opt,name=longitude,proto3" json:"longitude,omitempty"` + Altitude float32 `protobuf:"fixed32,11,opt,name=altitude,proto3" json:"altitude,omitempty"` +} + +func (x *DeviceAllInfo) Reset() { + *x = DeviceAllInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_device_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeviceAllInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeviceAllInfo) ProtoMessage() {} + +func (x *DeviceAllInfo) ProtoReflect() protoreflect.Message { + mi := &file_device_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeviceAllInfo.ProtoReflect.Descriptor instead. +func (*DeviceAllInfo) Descriptor() ([]byte, []int) { + return file_device_proto_rawDescGZIP(), []int{3} +} + +func (x *DeviceAllInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DeviceAllInfo) GetEuid() string { + if x != nil { + return x.Euid + } + return "" +} + +func (x *DeviceAllInfo) GetInternalStatus() int32 { + if x != nil { + return x.InternalStatus + } + return 0 +} + +func (x *DeviceAllInfo) GetNativeStatus() string { + if x != nil { + return x.NativeStatus + } + return "" +} + +func (x *DeviceAllInfo) GetLastOnline() *timestamppb.Timestamp { + if x != nil { + return x.LastOnline + } + return nil +} + +func (x *DeviceAllInfo) GetFwVersion() string { + if x != nil { + return x.FwVersion + } + return "" +} + +func (x *DeviceAllInfo) GetCardIds() []int32 { + if x != nil { + return x.CardIds + } + return nil +} + +func (x *DeviceAllInfo) GetCharge() float32 { + if x != nil { + return x.Charge + } + return 0 +} + +func (x *DeviceAllInfo) GetLatitude() float64 { + if x != nil { + return x.Latitude + } + return 0 +} + +func (x *DeviceAllInfo) GetLongitude() float64 { + if x != nil { + return x.Longitude + } + return 0 +} + +func (x *DeviceAllInfo) GetAltitude() float32 { + if x != nil { + return x.Altitude + } + return 0 +} + +var File_device_proto protoreflect.FileDescriptor + +var file_device_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x1a, + 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x20, + 0x0a, 0x06, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x72, + 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x02, 0x52, 0x06, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, + 0x22, 0x60, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, + 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, + 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x6e, 0x67, + 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x6c, 0x6f, 0x6e, + 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x6c, 0x74, 0x69, 0x74, 0x75, + 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x08, 0x61, 0x6c, 0x74, 0x69, 0x74, 0x75, + 0x64, 0x65, 0x22, 0x9e, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x73, + 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x75, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x75, 0x69, 0x64, 0x12, 0x27, 0x0a, + 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6f, + 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x4f, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x22, 0xea, 0x02, 0x0a, 0x0d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x6c, + 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x75, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x75, 0x69, 0x64, 0x12, 0x27, 0x0a, + 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, + 0x61, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, + 0x73, 0x74, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x77, 0x5f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x77, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x61, 0x72, 0x64, 0x5f, + 0x69, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x05, 0x52, 0x07, 0x63, 0x61, 0x72, 0x64, 0x49, + 0x64, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x02, 0x52, 0x06, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, + 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x6c, 0x61, + 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, + 0x75, 0x64, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, + 0x74, 0x75, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x6c, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x52, 0x08, 0x61, 0x6c, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, + 0x32, 0x95, 0x06, 0x0a, 0x0d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x12, 0x19, 0x2e, 0x70, + 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, + 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1e, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, + 0x6e, 0x6f, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x41, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x45, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1f, 0x2e, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3f, + 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, 0x19, 0x2e, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, + 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x17, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, + 0x43, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, + 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, + 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4e, 0x66, 0x63, 0x43, 0x61, + 0x72, 0x64, 0x49, 0x64, 0x73, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x46, 0x0a, + 0x0c, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x49, 0x64, 0x73, 0x12, 0x19, 0x2e, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, + 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x4b, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x65, 0x6e, 0x74, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x73, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, + 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x73, 0x12, 0x4f, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x73, 0x12, 0x19, 0x2e, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, + 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x19, + 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, + 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, + 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x1a, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x07, 0x47, + 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x1a, 0x15, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x42, 0x27, 0x5a, 0x25, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2f, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x3b, 0x61, 0x70, 0x69, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_device_proto_rawDescOnce sync.Once + file_device_proto_rawDescData = file_device_proto_rawDesc +) + +func file_device_proto_rawDescGZIP() []byte { + file_device_proto_rawDescOnce.Do(func() { + file_device_proto_rawDescData = protoimpl.X.CompressGZIP(file_device_proto_rawDescData) + }) + return file_device_proto_rawDescData +} + +var file_device_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_device_proto_goTypes = []interface{}{ + (*Charge)(nil), // 0: pagerino.device.Charge + (*Location)(nil), // 1: pagerino.device.Location + (*DeviceBaseInfo)(nil), // 2: pagerino.device.DeviceBaseInfo + (*DeviceAllInfo)(nil), // 3: pagerino.device.DeviceAllInfo + (*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp + (*common.StrIndex)(nil), // 5: pagerino.common.StrIndex + (*common.References)(nil), // 6: pagerino.common.References + (*common.Activity)(nil), // 7: pagerino.common.Activity + (*common.Meta)(nil), // 8: pagerino.common.Meta +} +var file_device_proto_depIdxs = []int32{ + 4, // 0: pagerino.device.DeviceBaseInfo.last_online:type_name -> google.protobuf.Timestamp + 4, // 1: pagerino.device.DeviceAllInfo.last_online:type_name -> google.protobuf.Timestamp + 5, // 2: pagerino.device.DeviceService.GetAll:input_type -> pagerino.common.StrIndex + 5, // 3: pagerino.device.DeviceService.GetInfo:input_type -> pagerino.common.StrIndex + 5, // 4: pagerino.device.DeviceService.GetCharge:input_type -> pagerino.common.StrIndex + 5, // 5: pagerino.device.DeviceService.GetLocation:input_type -> pagerino.common.StrIndex + 5, // 6: pagerino.device.DeviceService.GetNfcCardIds:input_type -> pagerino.common.StrIndex + 5, // 7: pagerino.device.DeviceService.GetStatusIds:input_type -> pagerino.common.StrIndex + 5, // 8: pagerino.device.DeviceService.GetSentMessageIds:input_type -> pagerino.common.StrIndex + 5, // 9: pagerino.device.DeviceService.GetReceivedMessageIds:input_type -> pagerino.common.StrIndex + 5, // 10: pagerino.device.DeviceService.GetLogs:input_type -> pagerino.common.StrIndex + 5, // 11: pagerino.device.DeviceService.GetActivity:input_type -> pagerino.common.StrIndex + 5, // 12: pagerino.device.DeviceService.GetMeta:input_type -> pagerino.common.StrIndex + 3, // 13: pagerino.device.DeviceService.GetAll:output_type -> pagerino.device.DeviceAllInfo + 2, // 14: pagerino.device.DeviceService.GetInfo:output_type -> pagerino.device.DeviceBaseInfo + 0, // 15: pagerino.device.DeviceService.GetCharge:output_type -> pagerino.device.Charge + 1, // 16: pagerino.device.DeviceService.GetLocation:output_type -> pagerino.device.Location + 6, // 17: pagerino.device.DeviceService.GetNfcCardIds:output_type -> pagerino.common.References + 6, // 18: pagerino.device.DeviceService.GetStatusIds:output_type -> pagerino.common.References + 6, // 19: pagerino.device.DeviceService.GetSentMessageIds:output_type -> pagerino.common.References + 6, // 20: pagerino.device.DeviceService.GetReceivedMessageIds:output_type -> pagerino.common.References + 6, // 21: pagerino.device.DeviceService.GetLogs:output_type -> pagerino.common.References + 7, // 22: pagerino.device.DeviceService.GetActivity:output_type -> pagerino.common.Activity + 8, // 23: pagerino.device.DeviceService.GetMeta:output_type -> pagerino.common.Meta + 13, // [13:24] is the sub-list for method output_type + 2, // [2:13] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_device_proto_init() } +func file_device_proto_init() { + if File_device_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_device_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Charge); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_device_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Location); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_device_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeviceBaseInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_device_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeviceAllInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_device_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_device_proto_goTypes, + DependencyIndexes: file_device_proto_depIdxs, + MessageInfos: file_device_proto_msgTypes, + }.Build() + File_device_proto = out.File + file_device_proto_rawDesc = nil + file_device_proto_goTypes = nil + file_device_proto_depIdxs = nil +} diff --git a/WebApp/src/main/pager_api/device/device_grpc.pb.go b/WebApp/src/main/pager_api/device/device_grpc.pb.go new file mode 100644 index 0000000..3467714 --- /dev/null +++ b/WebApp/src/main/pager_api/device/device_grpc.pb.go @@ -0,0 +1,468 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package api_device + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + common "server/app_comm/api/common" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// DeviceServiceClient is the client API for DeviceService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type DeviceServiceClient interface { + // === DB information + GetAll(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*DeviceAllInfo, error) + GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*DeviceBaseInfo, error) + GetCharge(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*Charge, error) + GetLocation(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*Location, error) + // References + GetNfcCardIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + GetStatusIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + GetSentMessageIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + GetReceivedMessageIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + GetLogs(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + // Common + GetActivity(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Activity, error) + GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) +} + +type deviceServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewDeviceServiceClient(cc grpc.ClientConnInterface) DeviceServiceClient { + return &deviceServiceClient{cc} +} + +func (c *deviceServiceClient) GetAll(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*DeviceAllInfo, error) { + out := new(DeviceAllInfo) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetAll", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*DeviceBaseInfo, error) { + out := new(DeviceBaseInfo) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetCharge(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*Charge, error) { + out := new(Charge) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetCharge", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetLocation(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*Location, error) { + out := new(Location) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetLocation", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetNfcCardIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetNfcCardIds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetStatusIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetStatusIds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetSentMessageIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetSentMessageIds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetReceivedMessageIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetReceivedMessageIds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetLogs(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetLogs", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetActivity(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Activity, error) { + out := new(common.Activity) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetActivity", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceServiceClient) GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) { + out := new(common.Meta) + err := c.cc.Invoke(ctx, "/pagerino.device.DeviceService/GetMeta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// DeviceServiceServer is the server API for DeviceService service. +// All implementations must embed UnimplementedDeviceServiceServer +// for forward compatibility +type DeviceServiceServer interface { + // === DB information + GetAll(context.Context, *common.StrIndex) (*DeviceAllInfo, error) + GetInfo(context.Context, *common.StrIndex) (*DeviceBaseInfo, error) + GetCharge(context.Context, *common.StrIndex) (*Charge, error) + GetLocation(context.Context, *common.StrIndex) (*Location, error) + // References + GetNfcCardIds(context.Context, *common.StrIndex) (*common.References, error) + GetStatusIds(context.Context, *common.StrIndex) (*common.References, error) + GetSentMessageIds(context.Context, *common.StrIndex) (*common.References, error) + GetReceivedMessageIds(context.Context, *common.StrIndex) (*common.References, error) + GetLogs(context.Context, *common.StrIndex) (*common.References, error) + // Common + GetActivity(context.Context, *common.StrIndex) (*common.Activity, error) + GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) + mustEmbedUnimplementedDeviceServiceServer() +} + +// UnimplementedDeviceServiceServer must be embedded to have forward compatible implementations. +type UnimplementedDeviceServiceServer struct { +} + +func (UnimplementedDeviceServiceServer) GetAll(context.Context, *common.StrIndex) (*DeviceAllInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAll not implemented") +} +func (UnimplementedDeviceServiceServer) GetInfo(context.Context, *common.StrIndex) (*DeviceBaseInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetInfo not implemented") +} +func (UnimplementedDeviceServiceServer) GetCharge(context.Context, *common.StrIndex) (*Charge, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetCharge not implemented") +} +func (UnimplementedDeviceServiceServer) GetLocation(context.Context, *common.StrIndex) (*Location, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetLocation not implemented") +} +func (UnimplementedDeviceServiceServer) GetNfcCardIds(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetNfcCardIds not implemented") +} +func (UnimplementedDeviceServiceServer) GetStatusIds(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetStatusIds not implemented") +} +func (UnimplementedDeviceServiceServer) GetSentMessageIds(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSentMessageIds not implemented") +} +func (UnimplementedDeviceServiceServer) GetReceivedMessageIds(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetReceivedMessageIds not implemented") +} +func (UnimplementedDeviceServiceServer) GetLogs(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetLogs not implemented") +} +func (UnimplementedDeviceServiceServer) GetActivity(context.Context, *common.StrIndex) (*common.Activity, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetActivity not implemented") +} +func (UnimplementedDeviceServiceServer) GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMeta not implemented") +} +func (UnimplementedDeviceServiceServer) mustEmbedUnimplementedDeviceServiceServer() {} + +// UnsafeDeviceServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to DeviceServiceServer will +// result in compilation errors. +type UnsafeDeviceServiceServer interface { + mustEmbedUnimplementedDeviceServiceServer() +} + +func RegisterDeviceServiceServer(s grpc.ServiceRegistrar, srv DeviceServiceServer) { + s.RegisterService(&DeviceService_ServiceDesc, srv) +} + +func _DeviceService_GetAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetAll(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetAll", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetAll(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetInfo(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetCharge_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetCharge(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetCharge", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetCharge(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetLocation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetLocation(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetLocation", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetLocation(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetNfcCardIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetNfcCardIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetNfcCardIds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetNfcCardIds(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetStatusIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetStatusIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetStatusIds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetStatusIds(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetSentMessageIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetSentMessageIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetSentMessageIds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetSentMessageIds(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetReceivedMessageIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetReceivedMessageIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetReceivedMessageIds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetReceivedMessageIds(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetLogs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetLogs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetLogs", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetLogs(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetActivity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetActivity(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetActivity", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetActivity(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceService_GetMeta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceServiceServer).GetMeta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.device.DeviceService/GetMeta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceServiceServer).GetMeta(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +// DeviceService_ServiceDesc is the grpc.ServiceDesc for DeviceService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var DeviceService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pagerino.device.DeviceService", + HandlerType: (*DeviceServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetAll", + Handler: _DeviceService_GetAll_Handler, + }, + { + MethodName: "GetInfo", + Handler: _DeviceService_GetInfo_Handler, + }, + { + MethodName: "GetCharge", + Handler: _DeviceService_GetCharge_Handler, + }, + { + MethodName: "GetLocation", + Handler: _DeviceService_GetLocation_Handler, + }, + { + MethodName: "GetNfcCardIds", + Handler: _DeviceService_GetNfcCardIds_Handler, + }, + { + MethodName: "GetStatusIds", + Handler: _DeviceService_GetStatusIds_Handler, + }, + { + MethodName: "GetSentMessageIds", + Handler: _DeviceService_GetSentMessageIds_Handler, + }, + { + MethodName: "GetReceivedMessageIds", + Handler: _DeviceService_GetReceivedMessageIds_Handler, + }, + { + MethodName: "GetLogs", + Handler: _DeviceService_GetLogs_Handler, + }, + { + MethodName: "GetActivity", + Handler: _DeviceService_GetActivity_Handler, + }, + { + MethodName: "GetMeta", + Handler: _DeviceService_GetMeta_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "device.proto", +} diff --git a/WebApp/src/main/pager_api/log/log.pb.go b/WebApp/src/main/pager_api/log/log.pb.go new file mode 100644 index 0000000..002933a --- /dev/null +++ b/WebApp/src/main/pager_api/log/log.pb.go @@ -0,0 +1,81 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: log.proto + +package api_log + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + common "server/app_comm/api/common" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +var File_log_proto protoreflect.FileDescriptor + +var file_log_proto_rawDesc = []byte{ + 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x70, 0x61, 0x67, + 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x6c, 0x6f, 0x67, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x8b, 0x01, 0x0a, 0x0a, 0x4c, 0x6f, 0x67, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x49, 0x64, 0x73, 0x12, 0x16, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1b, + 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x07, 0x47, + 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x16, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x15, + 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x42, 0x21, 0x5a, 0x1f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, + 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6c, 0x6f, 0x67, + 0x3b, 0x61, 0x70, 0x69, 0x5f, 0x6c, 0x6f, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_log_proto_goTypes = []interface{}{ + (*common.Index)(nil), // 0: pagerino.common.Index + (*common.References)(nil), // 1: pagerino.common.References + (*common.Meta)(nil), // 2: pagerino.common.Meta +} +var file_log_proto_depIdxs = []int32{ + 0, // 0: pagerino.log.LogService.GetChangeIds:input_type -> pagerino.common.Index + 0, // 1: pagerino.log.LogService.GetMeta:input_type -> pagerino.common.Index + 1, // 2: pagerino.log.LogService.GetChangeIds:output_type -> pagerino.common.References + 2, // 3: pagerino.log.LogService.GetMeta:output_type -> pagerino.common.Meta + 2, // [2:4] is the sub-list for method output_type + 0, // [0:2] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_log_proto_init() } +func file_log_proto_init() { + if File_log_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_log_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_log_proto_goTypes, + DependencyIndexes: file_log_proto_depIdxs, + }.Build() + File_log_proto = out.File + file_log_proto_rawDesc = nil + file_log_proto_goTypes = nil + file_log_proto_depIdxs = nil +} diff --git a/WebApp/src/main/pager_api/log/log_grpc.pb.go b/WebApp/src/main/pager_api/log/log_grpc.pb.go new file mode 100644 index 0000000..83739f9 --- /dev/null +++ b/WebApp/src/main/pager_api/log/log_grpc.pb.go @@ -0,0 +1,144 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package api_log + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + common "server/app_comm/api/common" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// LogServiceClient is the client API for LogService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type LogServiceClient interface { + // === DB information + // References + GetChangeIds(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.References, error) + // Common + GetMeta(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Meta, error) +} + +type logServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewLogServiceClient(cc grpc.ClientConnInterface) LogServiceClient { + return &logServiceClient{cc} +} + +func (c *logServiceClient) GetChangeIds(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.log.LogService/GetChangeIds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *logServiceClient) GetMeta(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Meta, error) { + out := new(common.Meta) + err := c.cc.Invoke(ctx, "/pagerino.log.LogService/GetMeta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// LogServiceServer is the server API for LogService service. +// All implementations must embed UnimplementedLogServiceServer +// for forward compatibility +type LogServiceServer interface { + // === DB information + // References + GetChangeIds(context.Context, *common.Index) (*common.References, error) + // Common + GetMeta(context.Context, *common.Index) (*common.Meta, error) + mustEmbedUnimplementedLogServiceServer() +} + +// UnimplementedLogServiceServer must be embedded to have forward compatible implementations. +type UnimplementedLogServiceServer struct { +} + +func (UnimplementedLogServiceServer) GetChangeIds(context.Context, *common.Index) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetChangeIds not implemented") +} +func (UnimplementedLogServiceServer) GetMeta(context.Context, *common.Index) (*common.Meta, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMeta not implemented") +} +func (UnimplementedLogServiceServer) mustEmbedUnimplementedLogServiceServer() {} + +// UnsafeLogServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to LogServiceServer will +// result in compilation errors. +type UnsafeLogServiceServer interface { + mustEmbedUnimplementedLogServiceServer() +} + +func RegisterLogServiceServer(s grpc.ServiceRegistrar, srv LogServiceServer) { + s.RegisterService(&LogService_ServiceDesc, srv) +} + +func _LogService_GetChangeIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(LogServiceServer).GetChangeIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.log.LogService/GetChangeIds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LogServiceServer).GetChangeIds(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +func _LogService_GetMeta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(LogServiceServer).GetMeta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.log.LogService/GetMeta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LogServiceServer).GetMeta(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +// LogService_ServiceDesc is the grpc.ServiceDesc for LogService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var LogService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pagerino.log.LogService", + HandlerType: (*LogServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetChangeIds", + Handler: _LogService_GetChangeIds_Handler, + }, + { + MethodName: "GetMeta", + Handler: _LogService_GetMeta_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "log.proto", +} diff --git a/WebApp/src/main/pager_api/message/message.pb.go b/WebApp/src/main/pager_api/message/message.pb.go new file mode 100644 index 0000000..db87644 --- /dev/null +++ b/WebApp/src/main/pager_api/message/message.pb.go @@ -0,0 +1,267 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: message.proto + +package api_message + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + common "server/app_comm/api/common" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type MessageBasicInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SenderId int32 `protobuf:"varint,1,opt,name=sender_id,json=senderId,proto3" json:"sender_id,omitempty"` + ReceiverId int32 `protobuf:"varint,2,opt,name=receiver_id,json=receiverId,proto3" json:"receiver_id,omitempty"` + Payload string `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` +} + +func (x *MessageBasicInfo) Reset() { + *x = MessageBasicInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_message_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MessageBasicInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessageBasicInfo) ProtoMessage() {} + +func (x *MessageBasicInfo) ProtoReflect() protoreflect.Message { + mi := &file_message_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MessageBasicInfo.ProtoReflect.Descriptor instead. +func (*MessageBasicInfo) Descriptor() ([]byte, []int) { + return file_message_proto_rawDescGZIP(), []int{0} +} + +func (x *MessageBasicInfo) GetSenderId() int32 { + if x != nil { + return x.SenderId + } + return 0 +} + +func (x *MessageBasicInfo) GetReceiverId() int32 { + if x != nil { + return x.ReceiverId + } + return 0 +} + +func (x *MessageBasicInfo) GetPayload() string { + if x != nil { + return x.Payload + } + return "" +} + +func (x *MessageBasicInfo) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +type Payload struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Payload string `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` +} + +func (x *Payload) Reset() { + *x = Payload{} + if protoimpl.UnsafeEnabled { + mi := &file_message_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Payload) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Payload) ProtoMessage() {} + +func (x *Payload) ProtoReflect() protoreflect.Message { + mi := &file_message_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Payload.ProtoReflect.Descriptor instead. +func (*Payload) Descriptor() ([]byte, []int) { + return file_message_proto_rawDescGZIP(), []int{1} +} + +func (x *Payload) GetPayload() string { + if x != nil { + return x.Payload + } + return "" +} + +var File_message_proto protoreflect.FileDescriptor + +var file_message_proto_rawDesc = []byte{ + 0x0a, 0x0d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x10, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0xa5, 0x01, 0x0a, 0x10, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x61, 0x73, 0x69, + 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, + 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x39, 0x0a, + 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x23, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, + 0x6f, 0x61, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x32, 0xd2, 0x01, + 0x0a, 0x0e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x45, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x1a, 0x22, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x61, + 0x73, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3f, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x50, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x16, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x19, 0x2e, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x2e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x38, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, + 0x65, 0x74, 0x61, 0x12, 0x16, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x15, 0x2e, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, + 0x74, 0x61, 0x42, 0x29, 0x5a, 0x27, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x70, + 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x3b, 0x61, 0x70, 0x69, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_message_proto_rawDescOnce sync.Once + file_message_proto_rawDescData = file_message_proto_rawDesc +) + +func file_message_proto_rawDescGZIP() []byte { + file_message_proto_rawDescOnce.Do(func() { + file_message_proto_rawDescData = protoimpl.X.CompressGZIP(file_message_proto_rawDescData) + }) + return file_message_proto_rawDescData +} + +var file_message_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_message_proto_goTypes = []interface{}{ + (*MessageBasicInfo)(nil), // 0: pagerino.message.MessageBasicInfo + (*Payload)(nil), // 1: pagerino.message.Payload + (*timestamppb.Timestamp)(nil), // 2: google.protobuf.Timestamp + (*common.Index)(nil), // 3: pagerino.common.Index + (*common.Meta)(nil), // 4: pagerino.common.Meta +} +var file_message_proto_depIdxs = []int32{ + 2, // 0: pagerino.message.MessageBasicInfo.created_at:type_name -> google.protobuf.Timestamp + 3, // 1: pagerino.message.MessageService.GetInfo:input_type -> pagerino.common.Index + 3, // 2: pagerino.message.MessageService.GetPayload:input_type -> pagerino.common.Index + 3, // 3: pagerino.message.MessageService.GetMeta:input_type -> pagerino.common.Index + 0, // 4: pagerino.message.MessageService.GetInfo:output_type -> pagerino.message.MessageBasicInfo + 1, // 5: pagerino.message.MessageService.GetPayload:output_type -> pagerino.message.Payload + 4, // 6: pagerino.message.MessageService.GetMeta:output_type -> pagerino.common.Meta + 4, // [4:7] is the sub-list for method output_type + 1, // [1:4] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_message_proto_init() } +func file_message_proto_init() { + if File_message_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_message_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MessageBasicInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_message_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Payload); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_message_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_message_proto_goTypes, + DependencyIndexes: file_message_proto_depIdxs, + MessageInfos: file_message_proto_msgTypes, + }.Build() + File_message_proto = out.File + file_message_proto_rawDesc = nil + file_message_proto_goTypes = nil + file_message_proto_depIdxs = nil +} diff --git a/WebApp/src/main/pager_api/message/message_grpc.pb.go b/WebApp/src/main/pager_api/message/message_grpc.pb.go new file mode 100644 index 0000000..b43c471 --- /dev/null +++ b/WebApp/src/main/pager_api/message/message_grpc.pb.go @@ -0,0 +1,178 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package api_message + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + common "server/app_comm/api/common" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// MessageServiceClient is the client API for MessageService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type MessageServiceClient interface { + // === DB information + GetInfo(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*MessageBasicInfo, error) + GetPayload(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*Payload, error) + // Common + GetMeta(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Meta, error) +} + +type messageServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewMessageServiceClient(cc grpc.ClientConnInterface) MessageServiceClient { + return &messageServiceClient{cc} +} + +func (c *messageServiceClient) GetInfo(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*MessageBasicInfo, error) { + out := new(MessageBasicInfo) + err := c.cc.Invoke(ctx, "/pagerino.message.MessageService/GetInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *messageServiceClient) GetPayload(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*Payload, error) { + out := new(Payload) + err := c.cc.Invoke(ctx, "/pagerino.message.MessageService/GetPayload", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *messageServiceClient) GetMeta(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Meta, error) { + out := new(common.Meta) + err := c.cc.Invoke(ctx, "/pagerino.message.MessageService/GetMeta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MessageServiceServer is the server API for MessageService service. +// All implementations must embed UnimplementedMessageServiceServer +// for forward compatibility +type MessageServiceServer interface { + // === DB information + GetInfo(context.Context, *common.Index) (*MessageBasicInfo, error) + GetPayload(context.Context, *common.Index) (*Payload, error) + // Common + GetMeta(context.Context, *common.Index) (*common.Meta, error) + mustEmbedUnimplementedMessageServiceServer() +} + +// UnimplementedMessageServiceServer must be embedded to have forward compatible implementations. +type UnimplementedMessageServiceServer struct { +} + +func (UnimplementedMessageServiceServer) GetInfo(context.Context, *common.Index) (*MessageBasicInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetInfo not implemented") +} +func (UnimplementedMessageServiceServer) GetPayload(context.Context, *common.Index) (*Payload, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPayload not implemented") +} +func (UnimplementedMessageServiceServer) GetMeta(context.Context, *common.Index) (*common.Meta, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMeta not implemented") +} +func (UnimplementedMessageServiceServer) mustEmbedUnimplementedMessageServiceServer() {} + +// UnsafeMessageServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to MessageServiceServer will +// result in compilation errors. +type UnsafeMessageServiceServer interface { + mustEmbedUnimplementedMessageServiceServer() +} + +func RegisterMessageServiceServer(s grpc.ServiceRegistrar, srv MessageServiceServer) { + s.RegisterService(&MessageService_ServiceDesc, srv) +} + +func _MessageService_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MessageServiceServer).GetInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.message.MessageService/GetInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MessageServiceServer).GetInfo(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +func _MessageService_GetPayload_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MessageServiceServer).GetPayload(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.message.MessageService/GetPayload", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MessageServiceServer).GetPayload(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +func _MessageService_GetMeta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MessageServiceServer).GetMeta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.message.MessageService/GetMeta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MessageServiceServer).GetMeta(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +// MessageService_ServiceDesc is the grpc.ServiceDesc for MessageService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var MessageService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pagerino.message.MessageService", + HandlerType: (*MessageServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetInfo", + Handler: _MessageService_GetInfo_Handler, + }, + { + MethodName: "GetPayload", + Handler: _MessageService_GetPayload_Handler, + }, + { + MethodName: "GetMeta", + Handler: _MessageService_GetMeta_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "message.proto", +} diff --git a/WebApp/src/main/pager_api/nfccard/nfccard.pb.go b/WebApp/src/main/pager_api/nfccard/nfccard.pb.go new file mode 100644 index 0000000..c055bcc --- /dev/null +++ b/WebApp/src/main/pager_api/nfccard/nfccard.pb.go @@ -0,0 +1,168 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: nfccard.proto + +package api_nfccard + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + common "server/app_comm/api/common" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type NfcCardBaseInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Uid string `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"` +} + +func (x *NfcCardBaseInfo) Reset() { + *x = NfcCardBaseInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_nfccard_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NfcCardBaseInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NfcCardBaseInfo) ProtoMessage() {} + +func (x *NfcCardBaseInfo) ProtoReflect() protoreflect.Message { + mi := &file_nfccard_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NfcCardBaseInfo.ProtoReflect.Descriptor instead. +func (*NfcCardBaseInfo) Descriptor() ([]byte, []int) { + return file_nfccard_proto_rawDescGZIP(), []int{0} +} + +func (x *NfcCardBaseInfo) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + +var File_nfccard_proto protoreflect.FileDescriptor + +var file_nfccard_proto_rawDesc = []byte{ + 0x0a, 0x0d, 0x6e, 0x66, 0x63, 0x63, 0x61, 0x72, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x11, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x6e, 0x66, 0x63, 0x5f, 0x63, 0x61, + 0x72, 0x64, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x23, 0x0a, 0x0f, 0x4e, 0x66, 0x63, 0x43, 0x61, 0x72, 0x64, 0x42, 0x61, 0x73, 0x65, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x75, 0x69, 0x64, 0x32, 0xd4, 0x01, 0x0a, 0x0e, 0x4e, 0x66, 0x63, 0x43, 0x61, 0x72, + 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x22, 0x2e, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x6e, 0x66, 0x63, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x2e, + 0x4e, 0x66, 0x63, 0x43, 0x61, 0x72, 0x64, 0x42, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x41, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x16, + 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1a, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x12, 0x38, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x16, 0x2e, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x15, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x42, 0x29, 0x5a, 0x27, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x6e, 0x66, 0x63, 0x63, 0x61, 0x72, 0x64, 0x3b, 0x61, 0x70, 0x69, 0x5f, + 0x6e, 0x66, 0x63, 0x63, 0x61, 0x72, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_nfccard_proto_rawDescOnce sync.Once + file_nfccard_proto_rawDescData = file_nfccard_proto_rawDesc +) + +func file_nfccard_proto_rawDescGZIP() []byte { + file_nfccard_proto_rawDescOnce.Do(func() { + file_nfccard_proto_rawDescData = protoimpl.X.CompressGZIP(file_nfccard_proto_rawDescData) + }) + return file_nfccard_proto_rawDescData +} + +var file_nfccard_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_nfccard_proto_goTypes = []interface{}{ + (*NfcCardBaseInfo)(nil), // 0: pagerino.nfc_card.NfcCardBaseInfo + (*common.Index)(nil), // 1: pagerino.common.Index + (*common.Reference)(nil), // 2: pagerino.common.Reference + (*common.Meta)(nil), // 3: pagerino.common.Meta +} +var file_nfccard_proto_depIdxs = []int32{ + 1, // 0: pagerino.nfc_card.NfcCardService.GetInfo:input_type -> pagerino.common.Index + 1, // 1: pagerino.nfc_card.NfcCardService.GetDeviceId:input_type -> pagerino.common.Index + 1, // 2: pagerino.nfc_card.NfcCardService.GetMeta:input_type -> pagerino.common.Index + 0, // 3: pagerino.nfc_card.NfcCardService.GetInfo:output_type -> pagerino.nfc_card.NfcCardBaseInfo + 2, // 4: pagerino.nfc_card.NfcCardService.GetDeviceId:output_type -> pagerino.common.Reference + 3, // 5: pagerino.nfc_card.NfcCardService.GetMeta:output_type -> pagerino.common.Meta + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_nfccard_proto_init() } +func file_nfccard_proto_init() { + if File_nfccard_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_nfccard_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NfcCardBaseInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_nfccard_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_nfccard_proto_goTypes, + DependencyIndexes: file_nfccard_proto_depIdxs, + MessageInfos: file_nfccard_proto_msgTypes, + }.Build() + File_nfccard_proto = out.File + file_nfccard_proto_rawDesc = nil + file_nfccard_proto_goTypes = nil + file_nfccard_proto_depIdxs = nil +} diff --git a/WebApp/src/main/pager_api/nfccard/nfccard_grpc.pb.go b/WebApp/src/main/pager_api/nfccard/nfccard_grpc.pb.go new file mode 100644 index 0000000..eb0bade --- /dev/null +++ b/WebApp/src/main/pager_api/nfccard/nfccard_grpc.pb.go @@ -0,0 +1,180 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package api_nfccard + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + common "server/app_comm/api/common" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// NfcCardServiceClient is the client API for NfcCardService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type NfcCardServiceClient interface { + // === DB information + GetInfo(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*NfcCardBaseInfo, error) + // References + GetDeviceId(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Reference, error) + // Common + GetMeta(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Meta, error) +} + +type nfcCardServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewNfcCardServiceClient(cc grpc.ClientConnInterface) NfcCardServiceClient { + return &nfcCardServiceClient{cc} +} + +func (c *nfcCardServiceClient) GetInfo(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*NfcCardBaseInfo, error) { + out := new(NfcCardBaseInfo) + err := c.cc.Invoke(ctx, "/pagerino.nfc_card.NfcCardService/GetInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *nfcCardServiceClient) GetDeviceId(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Reference, error) { + out := new(common.Reference) + err := c.cc.Invoke(ctx, "/pagerino.nfc_card.NfcCardService/GetDeviceId", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *nfcCardServiceClient) GetMeta(ctx context.Context, in *common.Index, opts ...grpc.CallOption) (*common.Meta, error) { + out := new(common.Meta) + err := c.cc.Invoke(ctx, "/pagerino.nfc_card.NfcCardService/GetMeta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// NfcCardServiceServer is the server API for NfcCardService service. +// All implementations must embed UnimplementedNfcCardServiceServer +// for forward compatibility +type NfcCardServiceServer interface { + // === DB information + GetInfo(context.Context, *common.Index) (*NfcCardBaseInfo, error) + // References + GetDeviceId(context.Context, *common.Index) (*common.Reference, error) + // Common + GetMeta(context.Context, *common.Index) (*common.Meta, error) + mustEmbedUnimplementedNfcCardServiceServer() +} + +// UnimplementedNfcCardServiceServer must be embedded to have forward compatible implementations. +type UnimplementedNfcCardServiceServer struct { +} + +func (UnimplementedNfcCardServiceServer) GetInfo(context.Context, *common.Index) (*NfcCardBaseInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetInfo not implemented") +} +func (UnimplementedNfcCardServiceServer) GetDeviceId(context.Context, *common.Index) (*common.Reference, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetDeviceId not implemented") +} +func (UnimplementedNfcCardServiceServer) GetMeta(context.Context, *common.Index) (*common.Meta, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMeta not implemented") +} +func (UnimplementedNfcCardServiceServer) mustEmbedUnimplementedNfcCardServiceServer() {} + +// UnsafeNfcCardServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to NfcCardServiceServer will +// result in compilation errors. +type UnsafeNfcCardServiceServer interface { + mustEmbedUnimplementedNfcCardServiceServer() +} + +func RegisterNfcCardServiceServer(s grpc.ServiceRegistrar, srv NfcCardServiceServer) { + s.RegisterService(&NfcCardService_ServiceDesc, srv) +} + +func _NfcCardService_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NfcCardServiceServer).GetInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.nfc_card.NfcCardService/GetInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NfcCardServiceServer).GetInfo(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +func _NfcCardService_GetDeviceId_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NfcCardServiceServer).GetDeviceId(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.nfc_card.NfcCardService/GetDeviceId", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NfcCardServiceServer).GetDeviceId(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +func _NfcCardService_GetMeta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.Index) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NfcCardServiceServer).GetMeta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.nfc_card.NfcCardService/GetMeta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NfcCardServiceServer).GetMeta(ctx, req.(*common.Index)) + } + return interceptor(ctx, in, info, handler) +} + +// NfcCardService_ServiceDesc is the grpc.ServiceDesc for NfcCardService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var NfcCardService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pagerino.nfc_card.NfcCardService", + HandlerType: (*NfcCardServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetInfo", + Handler: _NfcCardService_GetInfo_Handler, + }, + { + MethodName: "GetDeviceId", + Handler: _NfcCardService_GetDeviceId_Handler, + }, + { + MethodName: "GetMeta", + Handler: _NfcCardService_GetMeta_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "nfccard.proto", +} diff --git a/WebApp/src/main/pager_api/permission/permission.pb.go b/WebApp/src/main/pager_api/permission/permission.pb.go new file mode 100644 index 0000000..a728f8e --- /dev/null +++ b/WebApp/src/main/pager_api/permission/permission.pb.go @@ -0,0 +1,181 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: permission.proto + +package api_permission + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + common "server/app_comm/api/common" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type PermissionBasicInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` +} + +func (x *PermissionBasicInfo) Reset() { + *x = PermissionBasicInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_permission_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PermissionBasicInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PermissionBasicInfo) ProtoMessage() {} + +func (x *PermissionBasicInfo) ProtoReflect() protoreflect.Message { + mi := &file_permission_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PermissionBasicInfo.ProtoReflect.Descriptor instead. +func (*PermissionBasicInfo) Descriptor() ([]byte, []int) { + return file_permission_proto_rawDescGZIP(), []int{0} +} + +func (x *PermissionBasicInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *PermissionBasicInfo) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +var File_permission_proto protoreflect.FileDescriptor + +var file_permission_proto_rawDesc = []byte{ + 0x0a, 0x10, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x13, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4b, 0x0a, 0x13, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x42, 0x61, 0x73, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x32, 0xe6, 0x01, 0x0a, 0x11, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4e, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x28, + 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x42, + 0x61, 0x73, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x44, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x52, + 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x73, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x3b, + 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, + 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, + 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x15, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x42, 0x2f, 0x5a, 0x2d, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3b, 0x61, 0x70, + 0x69, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_permission_proto_rawDescOnce sync.Once + file_permission_proto_rawDescData = file_permission_proto_rawDesc +) + +func file_permission_proto_rawDescGZIP() []byte { + file_permission_proto_rawDescOnce.Do(func() { + file_permission_proto_rawDescData = protoimpl.X.CompressGZIP(file_permission_proto_rawDescData) + }) + return file_permission_proto_rawDescData +} + +var file_permission_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_permission_proto_goTypes = []interface{}{ + (*PermissionBasicInfo)(nil), // 0: pagerino.permission.PermissionBasicInfo + (*common.StrIndex)(nil), // 1: pagerino.common.StrIndex + (*common.References)(nil), // 2: pagerino.common.References + (*common.Meta)(nil), // 3: pagerino.common.Meta +} +var file_permission_proto_depIdxs = []int32{ + 1, // 0: pagerino.permission.PermissionService.GetInfo:input_type -> pagerino.common.StrIndex + 1, // 1: pagerino.permission.PermissionService.GetRoleIds:input_type -> pagerino.common.StrIndex + 1, // 2: pagerino.permission.PermissionService.GetMeta:input_type -> pagerino.common.StrIndex + 0, // 3: pagerino.permission.PermissionService.GetInfo:output_type -> pagerino.permission.PermissionBasicInfo + 2, // 4: pagerino.permission.PermissionService.GetRoleIds:output_type -> pagerino.common.References + 3, // 5: pagerino.permission.PermissionService.GetMeta:output_type -> pagerino.common.Meta + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_permission_proto_init() } +func file_permission_proto_init() { + if File_permission_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_permission_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PermissionBasicInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_permission_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_permission_proto_goTypes, + DependencyIndexes: file_permission_proto_depIdxs, + MessageInfos: file_permission_proto_msgTypes, + }.Build() + File_permission_proto = out.File + file_permission_proto_rawDesc = nil + file_permission_proto_goTypes = nil + file_permission_proto_depIdxs = nil +} diff --git a/WebApp/src/main/pager_api/permission/permission_grpc.pb.go b/WebApp/src/main/pager_api/permission/permission_grpc.pb.go new file mode 100644 index 0000000..ec3370a --- /dev/null +++ b/WebApp/src/main/pager_api/permission/permission_grpc.pb.go @@ -0,0 +1,180 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package api_permission + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + common "server/app_comm/api/common" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// PermissionServiceClient is the client API for PermissionService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type PermissionServiceClient interface { + // === DB information + GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*PermissionBasicInfo, error) + // References + GetRoleIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + // Common + GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) +} + +type permissionServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewPermissionServiceClient(cc grpc.ClientConnInterface) PermissionServiceClient { + return &permissionServiceClient{cc} +} + +func (c *permissionServiceClient) GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*PermissionBasicInfo, error) { + out := new(PermissionBasicInfo) + err := c.cc.Invoke(ctx, "/pagerino.permission.PermissionService/GetInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *permissionServiceClient) GetRoleIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.permission.PermissionService/GetRoleIds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *permissionServiceClient) GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) { + out := new(common.Meta) + err := c.cc.Invoke(ctx, "/pagerino.permission.PermissionService/GetMeta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// PermissionServiceServer is the server API for PermissionService service. +// All implementations must embed UnimplementedPermissionServiceServer +// for forward compatibility +type PermissionServiceServer interface { + // === DB information + GetInfo(context.Context, *common.StrIndex) (*PermissionBasicInfo, error) + // References + GetRoleIds(context.Context, *common.StrIndex) (*common.References, error) + // Common + GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) + mustEmbedUnimplementedPermissionServiceServer() +} + +// UnimplementedPermissionServiceServer must be embedded to have forward compatible implementations. +type UnimplementedPermissionServiceServer struct { +} + +func (UnimplementedPermissionServiceServer) GetInfo(context.Context, *common.StrIndex) (*PermissionBasicInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetInfo not implemented") +} +func (UnimplementedPermissionServiceServer) GetRoleIds(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetRoleIds not implemented") +} +func (UnimplementedPermissionServiceServer) GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMeta not implemented") +} +func (UnimplementedPermissionServiceServer) mustEmbedUnimplementedPermissionServiceServer() {} + +// UnsafePermissionServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to PermissionServiceServer will +// result in compilation errors. +type UnsafePermissionServiceServer interface { + mustEmbedUnimplementedPermissionServiceServer() +} + +func RegisterPermissionServiceServer(s grpc.ServiceRegistrar, srv PermissionServiceServer) { + s.RegisterService(&PermissionService_ServiceDesc, srv) +} + +func _PermissionService_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PermissionServiceServer).GetInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.permission.PermissionService/GetInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PermissionServiceServer).GetInfo(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _PermissionService_GetRoleIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PermissionServiceServer).GetRoleIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.permission.PermissionService/GetRoleIds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PermissionServiceServer).GetRoleIds(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _PermissionService_GetMeta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PermissionServiceServer).GetMeta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.permission.PermissionService/GetMeta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PermissionServiceServer).GetMeta(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +// PermissionService_ServiceDesc is the grpc.ServiceDesc for PermissionService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var PermissionService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pagerino.permission.PermissionService", + HandlerType: (*PermissionServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetInfo", + Handler: _PermissionService_GetInfo_Handler, + }, + { + MethodName: "GetRoleIds", + Handler: _PermissionService_GetRoleIds_Handler, + }, + { + MethodName: "GetMeta", + Handler: _PermissionService_GetMeta_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "permission.proto", +} diff --git a/WebApp/src/main/pager_api/role/role.pb.go b/WebApp/src/main/pager_api/role/role.pb.go new file mode 100644 index 0000000..09aa284 --- /dev/null +++ b/WebApp/src/main/pager_api/role/role.pb.go @@ -0,0 +1,184 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: role.proto + +package api_role + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + common "server/app_comm/api/common" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type RoleBasicInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` +} + +func (x *RoleBasicInfo) Reset() { + *x = RoleBasicInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_role_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RoleBasicInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RoleBasicInfo) ProtoMessage() {} + +func (x *RoleBasicInfo) ProtoReflect() protoreflect.Message { + mi := &file_role_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RoleBasicInfo.ProtoReflect.Descriptor instead. +func (*RoleBasicInfo) Descriptor() ([]byte, []int) { + return file_role_proto_rawDescGZIP(), []int{0} +} + +func (x *RoleBasicInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *RoleBasicInfo) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +var File_role_proto protoreflect.FileDescriptor + +var file_role_proto_rawDesc = []byte{ + 0x0a, 0x0a, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x45, 0x0a, 0x0d, 0x52, 0x6f, 0x6c, + 0x65, 0x42, 0x61, 0x73, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x32, 0xa0, 0x02, 0x0a, 0x0b, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x42, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x2e, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, + 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1c, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x61, 0x73, 0x69, 0x63, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4a, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, + 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, + 0x12, 0x44, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x19, + 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, + 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, + 0x61, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x15, 0x2e, 0x70, + 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, + 0x65, 0x74, 0x61, 0x42, 0x23, 0x5a, 0x21, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x61, 0x70, + 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x3b, + 0x61, 0x70, 0x69, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_role_proto_rawDescOnce sync.Once + file_role_proto_rawDescData = file_role_proto_rawDesc +) + +func file_role_proto_rawDescGZIP() []byte { + file_role_proto_rawDescOnce.Do(func() { + file_role_proto_rawDescData = protoimpl.X.CompressGZIP(file_role_proto_rawDescData) + }) + return file_role_proto_rawDescData +} + +var file_role_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_role_proto_goTypes = []interface{}{ + (*RoleBasicInfo)(nil), // 0: pagerino.role.RoleBasicInfo + (*common.StrIndex)(nil), // 1: pagerino.common.StrIndex + (*common.References)(nil), // 2: pagerino.common.References + (*common.Meta)(nil), // 3: pagerino.common.Meta +} +var file_role_proto_depIdxs = []int32{ + 1, // 0: pagerino.role.RoleService.GetInfo:input_type -> pagerino.common.StrIndex + 1, // 1: pagerino.role.RoleService.GetPermissionIds:input_type -> pagerino.common.StrIndex + 1, // 2: pagerino.role.RoleService.GetUserIds:input_type -> pagerino.common.StrIndex + 1, // 3: pagerino.role.RoleService.GetMeta:input_type -> pagerino.common.StrIndex + 0, // 4: pagerino.role.RoleService.GetInfo:output_type -> pagerino.role.RoleBasicInfo + 2, // 5: pagerino.role.RoleService.GetPermissionIds:output_type -> pagerino.common.References + 2, // 6: pagerino.role.RoleService.GetUserIds:output_type -> pagerino.common.References + 3, // 7: pagerino.role.RoleService.GetMeta:output_type -> pagerino.common.Meta + 4, // [4:8] is the sub-list for method output_type + 0, // [0:4] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_role_proto_init() } +func file_role_proto_init() { + if File_role_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_role_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RoleBasicInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_role_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_role_proto_goTypes, + DependencyIndexes: file_role_proto_depIdxs, + MessageInfos: file_role_proto_msgTypes, + }.Build() + File_role_proto = out.File + file_role_proto_rawDesc = nil + file_role_proto_goTypes = nil + file_role_proto_depIdxs = nil +} diff --git a/WebApp/src/main/pager_api/role/role_grpc.pb.go b/WebApp/src/main/pager_api/role/role_grpc.pb.go new file mode 100644 index 0000000..b5bf872 --- /dev/null +++ b/WebApp/src/main/pager_api/role/role_grpc.pb.go @@ -0,0 +1,216 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package api_role + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + common "server/app_comm/api/common" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// RoleServiceClient is the client API for RoleService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type RoleServiceClient interface { + // === DB information + GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*RoleBasicInfo, error) + // References + GetPermissionIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + GetUserIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + // Common + GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) +} + +type roleServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewRoleServiceClient(cc grpc.ClientConnInterface) RoleServiceClient { + return &roleServiceClient{cc} +} + +func (c *roleServiceClient) GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*RoleBasicInfo, error) { + out := new(RoleBasicInfo) + err := c.cc.Invoke(ctx, "/pagerino.role.RoleService/GetInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *roleServiceClient) GetPermissionIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.role.RoleService/GetPermissionIds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *roleServiceClient) GetUserIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.role.RoleService/GetUserIds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *roleServiceClient) GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) { + out := new(common.Meta) + err := c.cc.Invoke(ctx, "/pagerino.role.RoleService/GetMeta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// RoleServiceServer is the server API for RoleService service. +// All implementations must embed UnimplementedRoleServiceServer +// for forward compatibility +type RoleServiceServer interface { + // === DB information + GetInfo(context.Context, *common.StrIndex) (*RoleBasicInfo, error) + // References + GetPermissionIds(context.Context, *common.StrIndex) (*common.References, error) + GetUserIds(context.Context, *common.StrIndex) (*common.References, error) + // Common + GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) + mustEmbedUnimplementedRoleServiceServer() +} + +// UnimplementedRoleServiceServer must be embedded to have forward compatible implementations. +type UnimplementedRoleServiceServer struct { +} + +func (UnimplementedRoleServiceServer) GetInfo(context.Context, *common.StrIndex) (*RoleBasicInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetInfo not implemented") +} +func (UnimplementedRoleServiceServer) GetPermissionIds(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPermissionIds not implemented") +} +func (UnimplementedRoleServiceServer) GetUserIds(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetUserIds not implemented") +} +func (UnimplementedRoleServiceServer) GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMeta not implemented") +} +func (UnimplementedRoleServiceServer) mustEmbedUnimplementedRoleServiceServer() {} + +// UnsafeRoleServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to RoleServiceServer will +// result in compilation errors. +type UnsafeRoleServiceServer interface { + mustEmbedUnimplementedRoleServiceServer() +} + +func RegisterRoleServiceServer(s grpc.ServiceRegistrar, srv RoleServiceServer) { + s.RegisterService(&RoleService_ServiceDesc, srv) +} + +func _RoleService_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoleServiceServer).GetInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.role.RoleService/GetInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoleServiceServer).GetInfo(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoleService_GetPermissionIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoleServiceServer).GetPermissionIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.role.RoleService/GetPermissionIds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoleServiceServer).GetPermissionIds(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoleService_GetUserIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoleServiceServer).GetUserIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.role.RoleService/GetUserIds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoleServiceServer).GetUserIds(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoleService_GetMeta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoleServiceServer).GetMeta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.role.RoleService/GetMeta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoleServiceServer).GetMeta(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +// RoleService_ServiceDesc is the grpc.ServiceDesc for RoleService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var RoleService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pagerino.role.RoleService", + HandlerType: (*RoleServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetInfo", + Handler: _RoleService_GetInfo_Handler, + }, + { + MethodName: "GetPermissionIds", + Handler: _RoleService_GetPermissionIds_Handler, + }, + { + MethodName: "GetUserIds", + Handler: _RoleService_GetUserIds_Handler, + }, + { + MethodName: "GetMeta", + Handler: _RoleService_GetMeta_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "role.proto", +} diff --git a/WebApp/src/main/pager_api/status/status.pb.go b/WebApp/src/main/pager_api/status/status.pb.go new file mode 100644 index 0000000..60286b9 --- /dev/null +++ b/WebApp/src/main/pager_api/status/status.pb.go @@ -0,0 +1,182 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: status.proto + +package api_status + +import ( + common "pagerino-web/pager_api/common" + reflect "reflect" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type StatusBasicInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + InternalStatus int32 `protobuf:"zigzag32,1,opt,name=internal_status,json=internalStatus,proto3" json:"internal_status,omitempty"` + NativeStatus string `protobuf:"bytes,2,opt,name=native_status,json=nativeStatus,proto3" json:"native_status,omitempty"` +} + +func (x *StatusBasicInfo) Reset() { + *x = StatusBasicInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_status_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StatusBasicInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StatusBasicInfo) ProtoMessage() {} + +func (x *StatusBasicInfo) ProtoReflect() protoreflect.Message { + mi := &file_status_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StatusBasicInfo.ProtoReflect.Descriptor instead. +func (*StatusBasicInfo) Descriptor() ([]byte, []int) { + return file_status_proto_rawDescGZIP(), []int{0} +} + +func (x *StatusBasicInfo) GetInternalStatus() int32 { + if x != nil { + return x.InternalStatus + } + return 0 +} + +func (x *StatusBasicInfo) GetNativeStatus() string { + if x != nil { + return x.NativeStatus + } + return "" +} + +var File_status_proto protoreflect.FileDescriptor + +var file_status_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, + 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5f, 0x0a, + 0x0f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x61, 0x73, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x11, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x61, 0x74, + 0x69, 0x76, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x32, 0xda, + 0x01, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x46, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x2e, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, + 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x20, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, + 0x61, 0x73, 0x69, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x44, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, + 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, + 0x65, 0x78, 0x1a, 0x1a, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x3b, + 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, + 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, + 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x15, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x42, 0x27, 0x5a, 0x25, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3b, 0x61, 0x70, 0x69, 0x5f, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_status_proto_rawDescOnce sync.Once + file_status_proto_rawDescData = file_status_proto_rawDesc +) + +func file_status_proto_rawDescGZIP() []byte { + file_status_proto_rawDescOnce.Do(func() { + file_status_proto_rawDescData = protoimpl.X.CompressGZIP(file_status_proto_rawDescData) + }) + return file_status_proto_rawDescData +} + +var file_status_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_status_proto_goTypes = []interface{}{ + (*StatusBasicInfo)(nil), // 0: pagerino.status.StatusBasicInfo + (*common.StrIndex)(nil), // 1: pagerino.common.StrIndex + (*common.Reference)(nil), // 2: pagerino.common.Reference + (*common.Meta)(nil), // 3: pagerino.common.Meta +} +var file_status_proto_depIdxs = []int32{ + 1, // 0: pagerino.status.StatusService.GetInfo:input_type -> pagerino.common.StrIndex + 1, // 1: pagerino.status.StatusService.GetDeviceId:input_type -> pagerino.common.StrIndex + 1, // 2: pagerino.status.StatusService.GetMeta:input_type -> pagerino.common.StrIndex + 0, // 3: pagerino.status.StatusService.GetInfo:output_type -> pagerino.status.StatusBasicInfo + 2, // 4: pagerino.status.StatusService.GetDeviceId:output_type -> pagerino.common.Reference + 3, // 5: pagerino.status.StatusService.GetMeta:output_type -> pagerino.common.Meta + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_status_proto_init() } +func file_status_proto_init() { + if File_status_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_status_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StatusBasicInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_status_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_status_proto_goTypes, + DependencyIndexes: file_status_proto_depIdxs, + MessageInfos: file_status_proto_msgTypes, + }.Build() + File_status_proto = out.File + file_status_proto_rawDesc = nil + file_status_proto_goTypes = nil + file_status_proto_depIdxs = nil +} diff --git a/WebApp/src/main/pager_api/status/status_grpc.pb.go b/WebApp/src/main/pager_api/status/status_grpc.pb.go new file mode 100644 index 0000000..9542b91 --- /dev/null +++ b/WebApp/src/main/pager_api/status/status_grpc.pb.go @@ -0,0 +1,181 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package api_status + +import ( + context "context" + common "pagerino-web/pager_api/common" + + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// StatusServiceClient is the client API for StatusService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type StatusServiceClient interface { + // === DB information + GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*StatusBasicInfo, error) + // References + GetDeviceId(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Reference, error) + // Common + GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) +} + +type statusServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewStatusServiceClient(cc grpc.ClientConnInterface) StatusServiceClient { + return &statusServiceClient{cc} +} + +func (c *statusServiceClient) GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*StatusBasicInfo, error) { + out := new(StatusBasicInfo) + err := c.cc.Invoke(ctx, "/pagerino.status.StatusService/GetInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *statusServiceClient) GetDeviceId(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Reference, error) { + out := new(common.Reference) + err := c.cc.Invoke(ctx, "/pagerino.status.StatusService/GetDeviceId", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *statusServiceClient) GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) { + out := new(common.Meta) + err := c.cc.Invoke(ctx, "/pagerino.status.StatusService/GetMeta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// StatusServiceServer is the server API for StatusService service. +// All implementations must embed UnimplementedStatusServiceServer +// for forward compatibility +type StatusServiceServer interface { + // === DB information + GetInfo(context.Context, *common.StrIndex) (*StatusBasicInfo, error) + // References + GetDeviceId(context.Context, *common.StrIndex) (*common.Reference, error) + // Common + GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) + mustEmbedUnimplementedStatusServiceServer() +} + +// UnimplementedStatusServiceServer must be embedded to have forward compatible implementations. +type UnimplementedStatusServiceServer struct { +} + +func (UnimplementedStatusServiceServer) GetInfo(context.Context, *common.StrIndex) (*StatusBasicInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetInfo not implemented") +} +func (UnimplementedStatusServiceServer) GetDeviceId(context.Context, *common.StrIndex) (*common.Reference, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetDeviceId not implemented") +} +func (UnimplementedStatusServiceServer) GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMeta not implemented") +} +func (UnimplementedStatusServiceServer) mustEmbedUnimplementedStatusServiceServer() {} + +// UnsafeStatusServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to StatusServiceServer will +// result in compilation errors. +type UnsafeStatusServiceServer interface { + mustEmbedUnimplementedStatusServiceServer() +} + +func RegisterStatusServiceServer(s grpc.ServiceRegistrar, srv StatusServiceServer) { + s.RegisterService(&StatusService_ServiceDesc, srv) +} + +func _StatusService_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StatusServiceServer).GetInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.status.StatusService/GetInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StatusServiceServer).GetInfo(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _StatusService_GetDeviceId_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StatusServiceServer).GetDeviceId(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.status.StatusService/GetDeviceId", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StatusServiceServer).GetDeviceId(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _StatusService_GetMeta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StatusServiceServer).GetMeta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.status.StatusService/GetMeta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StatusServiceServer).GetMeta(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +// StatusService_ServiceDesc is the grpc.ServiceDesc for StatusService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var StatusService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pagerino.status.StatusService", + HandlerType: (*StatusServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetInfo", + Handler: _StatusService_GetInfo_Handler, + }, + { + MethodName: "GetDeviceId", + Handler: _StatusService_GetDeviceId_Handler, + }, + { + MethodName: "GetMeta", + Handler: _StatusService_GetMeta_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "status.proto", +} diff --git a/WebApp/src/main/pager_api/user/user.pb.go b/WebApp/src/main/pager_api/user/user.pb.go new file mode 100644 index 0000000..298bc41 --- /dev/null +++ b/WebApp/src/main/pager_api/user/user.pb.go @@ -0,0 +1,386 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: user.proto + +package api_user + +import ( + common "pagerino-web/pager_api/common" + reflect "reflect" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Password struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Password string `protobuf:"bytes,1,opt,name=password,proto3" json:"password,omitempty"` +} + +func (x *Password) Reset() { + *x = Password{} + if protoimpl.UnsafeEnabled { + mi := &file_user_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Password) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Password) ProtoMessage() {} + +func (x *Password) ProtoReflect() protoreflect.Message { + mi := &file_user_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Password.ProtoReflect.Descriptor instead. +func (*Password) Descriptor() ([]byte, []int) { + return file_user_proto_rawDescGZIP(), []int{0} +} + +func (x *Password) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +type UserAllInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + RoleId int32 `protobuf:"varint,3,opt,name=role_id,json=roleId,proto3" json:"role_id,omitempty"` + LastOnline *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=last_online,json=lastOnline,proto3" json:"last_online,omitempty"` +} + +func (x *UserAllInfo) Reset() { + *x = UserAllInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_user_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UserAllInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserAllInfo) ProtoMessage() {} + +func (x *UserAllInfo) ProtoReflect() protoreflect.Message { + mi := &file_user_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UserAllInfo.ProtoReflect.Descriptor instead. +func (*UserAllInfo) Descriptor() ([]byte, []int) { + return file_user_proto_rawDescGZIP(), []int{1} +} + +func (x *UserAllInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UserAllInfo) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *UserAllInfo) GetRoleId() int32 { + if x != nil { + return x.RoleId + } + return 0 +} + +func (x *UserAllInfo) GetLastOnline() *timestamppb.Timestamp { + if x != nil { + return x.LastOnline + } + return nil +} + +type UserBaseInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + RoleId int32 `protobuf:"varint,2,opt,name=role_id,json=roleId,proto3" json:"role_id,omitempty"` + LastOnline *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_online,json=lastOnline,proto3" json:"last_online,omitempty"` +} + +func (x *UserBaseInfo) Reset() { + *x = UserBaseInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_user_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UserBaseInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserBaseInfo) ProtoMessage() {} + +func (x *UserBaseInfo) ProtoReflect() protoreflect.Message { + mi := &file_user_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UserBaseInfo.ProtoReflect.Descriptor instead. +func (*UserBaseInfo) Descriptor() ([]byte, []int) { + return file_user_proto_rawDescGZIP(), []int{2} +} + +func (x *UserBaseInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UserBaseInfo) GetRoleId() int32 { + if x != nil { + return x.RoleId + } + return 0 +} + +func (x *UserBaseInfo) GetLastOnline() *timestamppb.Timestamp { + if x != nil { + return x.LastOnline + } + return nil +} + +var File_user_proto protoreflect.FileDescriptor + +var file_user_proto_rawDesc = []byte{ + 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x26, 0x0a, 0x08, 0x50, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x22, 0x93, 0x01, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x41, 0x6c, 0x6c, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x0b, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, + 0x73, 0x74, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x78, 0x0a, 0x0c, 0x55, 0x73, 0x65, 0x72, + 0x42, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, + 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x72, + 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6f, 0x6e, + 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x4f, 0x6e, 0x6c, 0x69, + 0x6e, 0x65, 0x32, 0xa5, 0x04, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x3f, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x12, 0x19, 0x2e, 0x70, + 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, + 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1a, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, + 0x6e, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x41, 0x6c, 0x6c, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x41, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, + 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, + 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x61, + 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x41, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x1a, 0x17, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, + 0x2e, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x42, 0x0a, 0x09, 0x47, 0x65, 0x74, + 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, + 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x1a, 0x1a, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x46, 0x0a, + 0x0c, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x73, 0x12, 0x19, 0x2e, + 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, + 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, + 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x1b, 0x2e, 0x70, 0x61, + 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, + 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, + 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, 0x64, + 0x65, 0x78, 0x1a, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x3b, 0x0a, + 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x19, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, + 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x1a, 0x15, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x6f, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x42, 0x23, 0x5a, 0x21, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x3b, 0x61, 0x70, 0x69, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_user_proto_rawDescOnce sync.Once + file_user_proto_rawDescData = file_user_proto_rawDesc +) + +func file_user_proto_rawDescGZIP() []byte { + file_user_proto_rawDescOnce.Do(func() { + file_user_proto_rawDescData = protoimpl.X.CompressGZIP(file_user_proto_rawDescData) + }) + return file_user_proto_rawDescData +} + +var file_user_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_user_proto_goTypes = []interface{}{ + (*Password)(nil), // 0: pagerino.user.Password + (*UserAllInfo)(nil), // 1: pagerino.user.UserAllInfo + (*UserBaseInfo)(nil), // 2: pagerino.user.UserBaseInfo + (*timestamppb.Timestamp)(nil), // 3: google.protobuf.Timestamp + (*common.StrIndex)(nil), // 4: pagerino.common.StrIndex + (*common.Reference)(nil), // 5: pagerino.common.Reference + (*common.References)(nil), // 6: pagerino.common.References + (*common.Activity)(nil), // 7: pagerino.common.Activity + (*common.Meta)(nil), // 8: pagerino.common.Meta +} +var file_user_proto_depIdxs = []int32{ + 3, // 0: pagerino.user.UserAllInfo.last_online:type_name -> google.protobuf.Timestamp + 3, // 1: pagerino.user.UserBaseInfo.last_online:type_name -> google.protobuf.Timestamp + 4, // 2: pagerino.user.UserService.GetAll:input_type -> pagerino.common.StrIndex + 4, // 3: pagerino.user.UserService.GetInfo:input_type -> pagerino.common.StrIndex + 4, // 4: pagerino.user.UserService.GetPassword:input_type -> pagerino.common.StrIndex + 4, // 5: pagerino.user.UserService.GetRoleId:input_type -> pagerino.common.StrIndex + 4, // 6: pagerino.user.UserService.GetDeviceIds:input_type -> pagerino.common.StrIndex + 4, // 7: pagerino.user.UserService.GetLogs:input_type -> pagerino.common.StrIndex + 4, // 8: pagerino.user.UserService.GetActivity:input_type -> pagerino.common.StrIndex + 4, // 9: pagerino.user.UserService.GetMeta:input_type -> pagerino.common.StrIndex + 1, // 10: pagerino.user.UserService.GetAll:output_type -> pagerino.user.UserAllInfo + 2, // 11: pagerino.user.UserService.GetInfo:output_type -> pagerino.user.UserBaseInfo + 0, // 12: pagerino.user.UserService.GetPassword:output_type -> pagerino.user.Password + 5, // 13: pagerino.user.UserService.GetRoleId:output_type -> pagerino.common.Reference + 6, // 14: pagerino.user.UserService.GetDeviceIds:output_type -> pagerino.common.References + 6, // 15: pagerino.user.UserService.GetLogs:output_type -> pagerino.common.References + 7, // 16: pagerino.user.UserService.GetActivity:output_type -> pagerino.common.Activity + 8, // 17: pagerino.user.UserService.GetMeta:output_type -> pagerino.common.Meta + 10, // [10:18] is the sub-list for method output_type + 2, // [2:10] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_user_proto_init() } +func file_user_proto_init() { + if File_user_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_user_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Password); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UserAllInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UserBaseInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_user_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_user_proto_goTypes, + DependencyIndexes: file_user_proto_depIdxs, + MessageInfos: file_user_proto_msgTypes, + }.Build() + File_user_proto = out.File + file_user_proto_rawDesc = nil + file_user_proto_goTypes = nil + file_user_proto_depIdxs = nil +} diff --git a/WebApp/src/main/pager_api/user/user_grpc.pb.go b/WebApp/src/main/pager_api/user/user_grpc.pb.go new file mode 100644 index 0000000..c742e47 --- /dev/null +++ b/WebApp/src/main/pager_api/user/user_grpc.pb.go @@ -0,0 +1,361 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package api_user + +import ( + context "context" + common "pagerino-web/pager_api/common" + + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// UserServiceClient is the client API for UserService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type UserServiceClient interface { + // === DB information + GetAll(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*UserAllInfo, error) + GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*UserBaseInfo, error) + GetPassword(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*Password, error) + // References + GetRoleId(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Reference, error) + GetDeviceIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + GetLogs(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) + // Common + GetActivity(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Activity, error) + GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) +} + +type userServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewUserServiceClient(cc grpc.ClientConnInterface) UserServiceClient { + return &userServiceClient{cc} +} + +func (c *userServiceClient) GetAll(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*UserAllInfo, error) { + out := new(UserAllInfo) + err := c.cc.Invoke(ctx, "/pagerino.user.UserService/GetAll", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GetInfo(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*UserBaseInfo, error) { + out := new(UserBaseInfo) + err := c.cc.Invoke(ctx, "/pagerino.user.UserService/GetInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GetPassword(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*Password, error) { + out := new(Password) + err := c.cc.Invoke(ctx, "/pagerino.user.UserService/GetPassword", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GetRoleId(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Reference, error) { + out := new(common.Reference) + err := c.cc.Invoke(ctx, "/pagerino.user.UserService/GetRoleId", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GetDeviceIds(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.user.UserService/GetDeviceIds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GetLogs(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.References, error) { + out := new(common.References) + err := c.cc.Invoke(ctx, "/pagerino.user.UserService/GetLogs", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GetActivity(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Activity, error) { + out := new(common.Activity) + err := c.cc.Invoke(ctx, "/pagerino.user.UserService/GetActivity", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GetMeta(ctx context.Context, in *common.StrIndex, opts ...grpc.CallOption) (*common.Meta, error) { + out := new(common.Meta) + err := c.cc.Invoke(ctx, "/pagerino.user.UserService/GetMeta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// UserServiceServer is the server API for UserService service. +// All implementations must embed UnimplementedUserServiceServer +// for forward compatibility +type UserServiceServer interface { + // === DB information + GetAll(context.Context, *common.StrIndex) (*UserAllInfo, error) + GetInfo(context.Context, *common.StrIndex) (*UserBaseInfo, error) + GetPassword(context.Context, *common.StrIndex) (*Password, error) + // References + GetRoleId(context.Context, *common.StrIndex) (*common.Reference, error) + GetDeviceIds(context.Context, *common.StrIndex) (*common.References, error) + GetLogs(context.Context, *common.StrIndex) (*common.References, error) + // Common + GetActivity(context.Context, *common.StrIndex) (*common.Activity, error) + GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) + mustEmbedUnimplementedUserServiceServer() +} + +// UnimplementedUserServiceServer must be embedded to have forward compatible implementations. +type UnimplementedUserServiceServer struct { +} + +func (UnimplementedUserServiceServer) GetAll(context.Context, *common.StrIndex) (*UserAllInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAll not implemented") +} +func (UnimplementedUserServiceServer) GetInfo(context.Context, *common.StrIndex) (*UserBaseInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetInfo not implemented") +} +func (UnimplementedUserServiceServer) GetPassword(context.Context, *common.StrIndex) (*Password, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPassword not implemented") +} +func (UnimplementedUserServiceServer) GetRoleId(context.Context, *common.StrIndex) (*common.Reference, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetRoleId not implemented") +} +func (UnimplementedUserServiceServer) GetDeviceIds(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetDeviceIds not implemented") +} +func (UnimplementedUserServiceServer) GetLogs(context.Context, *common.StrIndex) (*common.References, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetLogs not implemented") +} +func (UnimplementedUserServiceServer) GetActivity(context.Context, *common.StrIndex) (*common.Activity, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetActivity not implemented") +} +func (UnimplementedUserServiceServer) GetMeta(context.Context, *common.StrIndex) (*common.Meta, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMeta not implemented") +} +func (UnimplementedUserServiceServer) mustEmbedUnimplementedUserServiceServer() {} + +// UnsafeUserServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to UserServiceServer will +// result in compilation errors. +type UnsafeUserServiceServer interface { + mustEmbedUnimplementedUserServiceServer() +} + +func RegisterUserServiceServer(s grpc.ServiceRegistrar, srv UserServiceServer) { + s.RegisterService(&UserService_ServiceDesc, srv) +} + +func _UserService_GetAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetAll(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.user.UserService/GetAll", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetAll(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.user.UserService/GetInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetInfo(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GetPassword_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetPassword(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.user.UserService/GetPassword", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetPassword(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GetRoleId_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetRoleId(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.user.UserService/GetRoleId", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetRoleId(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GetDeviceIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetDeviceIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.user.UserService/GetDeviceIds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetDeviceIds(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GetLogs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetLogs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.user.UserService/GetLogs", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetLogs(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GetActivity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetActivity(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.user.UserService/GetActivity", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetActivity(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GetMeta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(common.StrIndex) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetMeta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pagerino.user.UserService/GetMeta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetMeta(ctx, req.(*common.StrIndex)) + } + return interceptor(ctx, in, info, handler) +} + +// UserService_ServiceDesc is the grpc.ServiceDesc for UserService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var UserService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pagerino.user.UserService", + HandlerType: (*UserServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetAll", + Handler: _UserService_GetAll_Handler, + }, + { + MethodName: "GetInfo", + Handler: _UserService_GetInfo_Handler, + }, + { + MethodName: "GetPassword", + Handler: _UserService_GetPassword_Handler, + }, + { + MethodName: "GetRoleId", + Handler: _UserService_GetRoleId_Handler, + }, + { + MethodName: "GetDeviceIds", + Handler: _UserService_GetDeviceIds_Handler, + }, + { + MethodName: "GetLogs", + Handler: _UserService_GetLogs_Handler, + }, + { + MethodName: "GetActivity", + Handler: _UserService_GetActivity_Handler, + }, + { + MethodName: "GetMeta", + Handler: _UserService_GetMeta_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "user.proto", +} diff --git a/WebApp/tarball.tar.gz b/WebApp/tarball.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..ab4d6094bc17f31b87727cba6e6026e4c9d47e68 GIT binary patch literal 49350 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

$@v^ZW+2{$*LJbYKLc;1LEzq);Hhm`VjlLwE|iK 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 WC{Un4fdU2oFYz~EYnciF*aQF%nzT{? literal 0 HcmV?d00001