diff --git a/README.md b/README.md index 3ca43583..ba54aa62 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,8 @@ make ### Docker So building this thing from scratch is not your thing? I can't blame you. It takes some patience and in the end, there's still more work. Here comes `docker` to the rescue. You can run a docker version following -these instructions. The following is the content of the `docker_run.sh` script: +these instructions. The following is the content of the `docker_run.sh` script you can find +[here](https://github.com/stephb9959/ucentralgw/blob/main/docker_run.sh): ```bash #!/bin/sh @@ -181,183 +182,13 @@ file. Once all this is done, you can simply run `docker_run.sh`. ### Configuration The configuration for this service is kept in a properties file. Currently, this configuration file must be kept in the -current directory of uCentral or one level up. This file is called `ucentral.properties`. The file will be loaded from +current directory of uCentral or one level up. This file is called `ucentral.properties` and you can see the latest version +[here](https://github.com/stephb9959/ucentralgw/blob/main/ucentral.properties). The file will be loaded from the directory set by the environment variable `UCENTRAL_CONFIG`. To use environment variables in the configuration, you must use `$`. The path for the logs for the service must exist prior to starting the service. The path is defined under `logging.channels.c2.path`. Only `path names` support the use of environment variables. Here is a sample configuration: -``` -######################################################################## -######################################################################## -######################################################################## -######################################################################## -# -# TIP Portal API access. To be ignored in non TIP uCentral deployments -# -######################################################################## -######################################################################## -######################################################################## -tip.certs.key = $UCENTRAL_ROOT/certs/clientkey.pem -tip.certs.cert = $UCENTRAL_ROOT/certs/clientcert.pem -tip.certs.ca = $UCENTRAL_ROOT/certs/clientcert.pem -tip.certs.password = mypassword -tip.api.login.username = support@example.com -tip.api.login.password = support -tip.api.host = debfarm1-node-a1.arilia.com -tip.api.port = 9051 -tip.gateway.host.0.address = * -tip.gateway.host.0.port = 9031 -tip.gateway.host.0.key = $UCENTRAL_ROOT/certs/server-key.pem -tip.gateway.host.0.cert = $UCENTRAL_ROOT/certs/server-cert.pem -tip.gateway.host.0.password = mypassword -# -# uCentral - TIP Gateway Bridge -# -ucentral.tipgateway.host.0.address = * -ucentral.tipgateway.host.0.port = 14001 -ucentral.tipgateway.host.0.cert = $UCENTRAL_ROOT/certs/server-cert.pem -ucentral.tipgateway.host.0.key = $UCENTRAL_ROOT/certs/server-key.pem -ucentral.tipgateway.host.0.key.password = mypassword -######################################################################## -######################################################################## -######################################################################## - -######################################################################## -######################################################################## -# -# Thw following sections apply to the uCentral service -# -# Logging: please leave as is for now. -# -######################################################################## -######################################################################## - -logging.formatters.f1.class = PatternFormatter -logging.formatters.f1.pattern = %s: [%p] %t -logging.formatters.f1.times = UTC -logging.channels.c1.class = ConsoleChannel -logging.channels.c1.formatter = f1 -logging.channels.c2.class = FileChannel -# This is where the logs will be written. This path MUST exist -logging.channels.c2.path = $UCENTRAL_ROOT/logs/sample.log -logging.channels.c2.formatter.class = PatternFormatter -logging.channels.c2.formatter.pattern = %Y-%m-%d %H:%M:%S %s: [%p] %t -logging.channels.c3.class = ConsoleChannel -logging.channels.c3.pattern = %s: [%p] %t -# External Channel -logging.loggers.root.channel = c2 -logging.loggers.root.level = information -# Inline Channel with PatternFormatter -# logging.loggers.l1.name = logger1 -# logging.loggers.l1.channel.class = ConsoleChannel -# logging.loggers.l1.channel.pattern = %s: [%p] %t -# logging.loggers.l1.level = information -# SplitterChannel -# logging.channels.splitter.class = SplitterChannel -# logging.channels.splitter.channels = l1,l2 -# logging.loggers.l2.name = logger2 -# logging.loggers.l2.channel = splitter -openSSL.client.privateKeyFile = $UCENTRAL_ROOT/certs/clientkey.pem -openSSL.client.certificateFile = $UCENTRAL_ROOT/certs/clientcert.pem -openSSL.client.caConfig = $UCENTRAL_ROOT/certs/cacert.pem -openSSL.client.verificationMode = once -openSSL.client.verificationDepth = 9 -openSSL.client.loadDefaultCAFile = true -openSSL.client.cypherList = ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH -openSSL.client.privateKeyPassphraseHandler.name = KeyFileHandler -openSSL.client.privateKeyPassphraseHandler.options.password = mypassword -openSSL.client.invalidCertificateHandler = AcceptCertificateHandler -openSSL.client.invalidCertificateHandler.options.ignoreError = true -openSSL.client.extendedVerification = false -openSSL.client.cacheSessions = true -openSSL.client.requireTLSv1 = true - -# -# uCentral protocol server for devices. This is where you point -# all your devices. -# -ucentral.websocket.host.0.address = * -ucentral.websocket.host.0.port = 15002 -ucentral.websocket.host.0.cert = $UCENTRAL_ROOT/certs/server-cert.pem -ucentral.websocket.host.0.key = $UCENTRAL_ROOT/certs/server-key.pem -ucentral.websocket.host.0.key.password = mypassword -ucentral.websocket.maxreactors = 5 - -# -# REST API access -# -ucentral.restapi.host.0.address = * -ucentral.restapi.host.0.port = 16001 -ucentral.restapi.host.0.cert = $UCENTRAL_ROOT/certs/server-cert.pem -ucentral.restapi.host.0.key = $UCENTRAL_ROOT/certs/server-key.pem -ucentral.restapi.host.0.key.password = mypassword - -# -# Used to upload files to the service. -# -ucentral.fileuploader.host.0.address = * -ucentral.fileuploader.host.0.name = 192.168.1.176 -ucentral.fileuploader.host.0.port = 16003 -ucentral.fileuploader.host.0.cert = $UCENTRAL_ROOT/certs/server-cert.pem -ucentral.fileuploader.host.0.key = $UCENTRAL_ROOT/certs/server-key.pem -ucentral.fileuploader.host.0.key.password = mypassword -ucentral.fileuploader.path = $UCENTRAL_ROOT/uploads - -# -# This section descrive how to do autoprovisioning -# When enabled, it will allow devices that are not in the system -# to be managed and serviced -# -ucentral.autoprovisioning = true -ucentral.autoprovisioning.type.0 = AP:ea8300,edge -ucentral.autoprovisioning.type.1 = IOT:ea8301,edge2 -ucentral.autoprovisioning.type.2 = AP:ea8302,edge6 - -# -# This section select which form of persistence you need -# Only one selected at a time. If you select multiple, this service will die if a horrible -# death and might make your beer flat. -# -storage.type = sqlite -#storage.type = postgresql -#storage.type = mysql -#storage.type = odbc - -storage.type.sqlite.db = $UCENTRAL_ROOT/devices.db -storage.type.sqlite.idletime = 120 -storage.type.sqlite.maxsessions = 128 - -storage.type.postgresql.maxsessions = 64 -storage.type.postgresql.idletime = 60 -storage.type.postgresql.host = localhost -storage.type.postgresql.username = stephb -storage.type.postgresql.password = snoopy99 -storage.type.postgresql.database = ucentral -storage.type.postgresql.port = 5432 -storage.type.postgresql.connectiontimeout = 60 - -storage.type.mysql.maxsessions = 64 -storage.type.mysql.idletime = 60 -storage.type.mysql.host = localhost -storage.type.mysql.username = stephb -storage.type.mysql.password = snoopy99 -storage.type.mysql.database = ucentral -storage.type.mysql.port = 3306 -storage.type.mysql.connectiontimeout = 60 - -# -# Authentication -# -authentication.enabled = true -authentication.default.username = support@example.com -authentication.default.password = support -authentication.service.type = internal - -ucentral.system.debug = true -ucentral.system.id = 1 -``` - #### Important config entries ##### This is the logging directory - logging.channels.c2.path = $UCENTRAL_ROOT/logs/sample.log @@ -383,407 +214,14 @@ ucentral.system.id = 1 - ucentral.websocket.host.0.cert = $UCENTRAL_ROOT/certs/server-cert.pem - ucentral.websocket.host.0.key = $UCENTRAL_ROOT/certs/server-key.pem -## Device connection to the controller -The devices use the WebSocket protocol to establish a connection to the uCentral controller. While establishing the connection, the device mu include the following header in its connection: `Sec-WebSocket-Protocol: ucentral-broker`. In the [JSON-RPC](https://www.jsonrpc.org/specification) scenario, the AP is considered the server. So the Controller sends commands to the AP using JSON-RPC, and the AP will send notifications to the controller. - -### Event Messages -In this RPC, here are some common interpretations: -- `when` : In a command, this is a suggestion as to when to perform somthing. 0 means right now, or otherwise the UTC time in seconds. -- `serial` : This is the text representation of the serial number the device is using. Usually will be the MAC address of the device without an separator. -- `uuid` : Is an int64 representing the current configuration ID. -- `JSON documents` : when a field requires an JSON document, this is free form JSON and the controller and the AP agree on its content. -- -#### Connection event -AP Sends connection notification to the controller after establishing a connection. The controller -my decide to send the AP a newer configuration if it has a newer one. -``` -{ "jsonrpc" : "2.0" , - "method" : "connect" , - "params" : { - "serial" : , - "uuid" : , - "firmware" : , - "capabilities" : - } -} -``` - -#### State event -AP Sends device state periodically. If the Contoller detects that it has a newer configuration, it -may decide to send this new configuration to the AP. -``` -{ "jsonrpc" : "2.0" , - "method" : "state" , - "params" : { - "serial" : , - "uuid" : , - "state" : - } -} -``` - -#### Healthcheck event -AP Sends `healthcheck` periodically. This message contains information how vital AP subsystems are operating. -``` -{ "jsonrpc" : "2.0" , - "method" : "healthcheck" , - "params" : { - "serial" : , - "uuid" : , - "sanity: - "data" : - } -} -``` - -#### Log event -AP Sends a log whenever necessary. The controller will log this message. -``` -{ "jsonrpc" : "2.0" , - "method" : "log" , - "params" : { - "serial" : , - "log" : - "severity" : , - "data" : - } -} -``` -##### `severity` -The `severity` matches the `syslog` levels. Here are the details: -- 0 : LOG_EMERG 0 /* system is unusable */ -- 1 : LOG_ALERT 1 /* action must be taken immediately */ -- 2 : LOG_CRIT 2 /* critical conditions */ -- 3 : LOG_ERR 3 /* error conditions */ -- 4 : LOG_WARNING 4 /* warning conditions */ -- 5 : LOG_NOTICE 5 /* normal but significant condition */ -- 6 : LOG_INFO 6 /* informational */ -- 7 : LOG_DEBUG 7 /* debug-level messages */ - -#### Crash Log event -AP Sends a Crash log whenever it must reboot, or crashes, or something really bad happened. -``` -{ "jsonrpc" : "2.0" , - "method" : "crashlog" , - "params" : { - "serial" : , - "uuid" : , - "loglines" : [ an array of strings representing the logs from the log file ] - } -} -``` - -#### Config change pending event -AP Sends a log whenever necessary. This message is intended to tell the controller that the AP -has received a configuration but is still running an older configuration. The controller will not -reply to this message. -``` -{ "jsonrpc" : "2.0" , - "method" : "cfgpending" , - "params" : { - "serial" : , - "active" : , - "uuid" : - } -} -``` - -#### Send a keepalive to the controller event -AP Sends a keepalive whenever necessary. The AP will send this message to tell the controller -which version it is running. The Controller may decide to send the AP a newer configuration. -``` -{ "jsonrpc" : "2.0" , - "method" : "ping" , - "params" : { - "serial" : , - "uuid" : - } -} -``` - -### Controller commands -Most controller commands include a `when` member. This is a UTC clock time asking the AP -to perform the command at that time. This is a suggestion only. The AP may ignore this -parameter. If a 0 (zero) is given, the command should be performed immediately. `when` is -always a numeric parameter. - -#### Controller wants the AP to apply a given configuration -Controller sends this command when it believes the AP should load a new configuration. The AP -should send messages with `pending change` events until this version has been applied. -``` -{ "jsonrpc" : "2.0" , - "method" : "configure" , - "params" : { - "serial" : , - "uuid" : , - "when" : Optional - - "config" : -} -``` - -The AP should answer: -``` -{ "jsonrpc" : "2.0" , - "result" : { - "serial" : , - "uuid" : , - "status" : { - "error" : 0 or an error number, - "text" : - "when" : , - "rejected" : [ - { "parameter" : , - "reason" : , - "substitution" : } ... - ] - }, - "id" : -} -``` -##### The AP Answer -The AP can answer and tell the controller it has rejected certain parts of the config and potentially replaced them with -appropriate values. This could be used to allow an AP to replace frequencies for the regions it is localted. The AP can provide an -array of these rejections. The substitution JSON is optional. - -###### Error codes -- 0 : configuration was applied as-is. -- 1 : configuration was applied with the included substitutions in the `rejected` section. The device is operating with the new modified config. -- 2 : configuration was rejected and will not be applied at all. The `rejected` section can be used to tell the controller why. - -###### The `rejected` section -The rejected section is an array containing the following: -- `parameter` : the JSON code in the config that is causing this rejection -- `reason` : anything to explain the rejection. -- `substution` : the JSON code that `parameter` was replaced with. This could be absent meaning that the `parameter` code was simply removed from the configuration. - -#### Controller wants the AP to reboot -Controller sends this command when it believes the AP should reboot. -``` -{ "jsonrpc" : "2.0" , - "method" : "reboot" , - "params" : { - "serial" : , - "when" : Optional - - }, - "id" : -} -``` - -The AP should answer: -``` -{ "jsonrpc" : "2.0" , - "result" : { - "serial" : , - "status" : { - "error" : 0 or an error number, - "text" : , - "when" :