From 4dda10f71b7b50f01e44b1135290d2e116eeb4e2 Mon Sep 17 00:00:00 2001 From: Ulf Bjorkengren Date: Wed, 13 Mar 2024 15:55:36 +0100 Subject: [PATCH] Tutorial links update. Signed-off-by: Ulf Bjorkengren --- tutorial/config.toml | 8 ++--- tutorial/content/_index.md | 8 ++--- tutorial/content/build-system/_index.md | 10 +++--- tutorial/content/client/_index.md | 31 +++++++++--------- tutorial/content/datastore/_index.md | 6 ++-- tutorial/content/datastore/redis/_index.md | 2 +- tutorial/content/datastore/sqlite/_index.md | 4 +-- tutorial/content/feeder/_index.md | 12 +++---- .../content/peripheral-components/_index.md | 14 ++++---- tutorial/content/pocs/_index.md | 6 ++-- tutorial/content/pocs/poc1/_index.md | 14 ++++---- .../server/Access-control-servers/_index.md | 18 +++++----- tutorial/content/server/_index.md | 28 ++++++++-------- tutorial/content/tools/_index.md | 6 ++-- tutorial/layouts/partials/favicon.html | 2 +- tutorial/layouts/partials/logo.html | 2 +- tutorial/static/images/vissv2.png | Bin 14301 -> 14736 bytes 17 files changed, 86 insertions(+), 85 deletions(-) diff --git a/tutorial/config.toml b/tutorial/config.toml index be54c5c2..5a4c65ea 100644 --- a/tutorial/config.toml +++ b/tutorial/config.toml @@ -1,20 +1,20 @@ -baseURL = "https://w3c.github.io/automotive-viss2/" +baseURL = "https://covesa.github.io/vissr/" languageCode = "en-us" -title = "W3C VISSv2 Reference Implementation" +title = "COVESA VISSv2 Reference Implementation (vissr)" theme = "learn" publishDir = "../docs" [params] # Change default color scheme with a variant one. Can be "red", "blue", "green". themeVariant = "blue" disableInlineCopyToClipBoard = true - editURL = "https://github.com/w3c/automotive-viss2/edit/master/tutorial/content/" + editURL = "https://github.com/covesa/vissr/edit/master/tutorial/content/" disableLandingPageButton = true [[menu.shortcuts]] name = " Github repo" identifier = "ds" -url = "https://github.com/w3c/automotive-viss2" +url = "https://github.com/covesa/vissr" weight = 10 # Generation of JSON index to allow search diff --git a/tutorial/content/_index.md b/tutorial/content/_index.md index 680835aa..56d72238 100644 --- a/tutorial/content/_index.md +++ b/tutorial/content/_index.md @@ -1,14 +1,14 @@ --- -title: "W3C Vehicle Information Service Specification ver 2 Reference Implementation Tutorial" +title: "COVESA Vehicle Information Service Specification ver 2 Reference Implementation Tutorial" --- -## W3C Vehicle Information Service Specification ver 2 Reference Implementation Tutorial +## COVESA Vehicle Information Service Specification ver 2 Reference Implementation Tutorial -The W3C VISSv2 specification, soon to become a W3C standard, is developed at the [W3C/automotive github](https://github.com/w3c/automotive). +The COVESA VISSv2 specification is developed at the [COVESA/automotive github](https://github.com/COVESA/vehicle-information-service-specification). A reference implementation in the form of a server that exposes an interface according to the specification is developed on this repo. Also found on this repo are implementations of other components that are needed to realize a communication tech stack that reaches from clients through the server and to the underlying vehicle system interface. -![VISSv2 communication tech stack](/automotive-viss2/images/WAII-tech-stack.jpg?width=40pc) +![VISSv2 communication tech stack](/vissr/images/WAII-tech-stack.jpg?width=40pc) These software components (SwCs) can be categorized as follows: * server diff --git a/tutorial/content/build-system/_index.md b/tutorial/content/build-system/_index.md index 04e415e9..8526854c 100644 --- a/tutorial/content/build-system/_index.md +++ b/tutorial/content/build-system/_index.md @@ -1,5 +1,5 @@ --- -title: "WAII Build System" +title: "VISSR Build System" --- ## Installing Golang @@ -38,11 +38,11 @@ If there is any calls to the "github.com/akamensky/argparse" lib then it is used As the configurations have a default it is always possible to run it without adding any comand line configuration input. The configuration possibilities of the different SwCs are described in the respective chapters of this tutorial. -The server consists of several "actors", see the [README](https://github.com/w3c/automotive-viss2) Overview chapter. +The server consists of several "actors", see the [README](https://github.com/covesa/vissr) Overview chapter. These used to be built as separate processes that communicated over the Websockets protocol. To simplify the building process of thesesoftware components the script W3CServer.sh was created. After the refactoring of these SwCs into one process with ech actor running as a separate thread, -it became more convenient to build without this script, but it is still [avaliable](https://github.com/w3c/automotive-viss2/blob/master/W3CServer.sh). +it became more convenient to build without this script, but it is still [avaliable](https://github.com/covesa/vissr/blob/master/W3CServer.sh). For more details, see the "Multi-process vs single-process server implementation" chapter in the README. There are multiple Software components on this repo, such as feeders, simulators, the DCT tool that are to be built as separate excutables. @@ -89,8 +89,8 @@ For more information see https://github.com/golang/go/wiki/Modules#when-should-i ## Docker -The server can also be built and launched using docker and docker-compose, see the [Docker README](https://github.com/w3c/automotive-viss2/tree/master/docker). +The server can also be built and launched using docker and docker-compose, see the [Docker README](https://github.com/covesa/vissr/tree/master/docker). Current example builds and runs using the redis state storage together with an implementation of the feeder interfacing -the remotiveLabs broker in the cloud.[feeder-rl](https://github.com/w3c/automotive-viss2/tree/master/feeder/feeder-rl) . +the remotiveLabs broker in the cloud.[feeder-rl](https://github.com/covesa/vissr/tree/master/feeder/feeder-rl) . diff --git a/tutorial/content/client/_index.md b/tutorial/content/client/_index.md index 0cf968c6..455273d8 100644 --- a/tutorial/content/client/_index.md +++ b/tutorial/content/client/_index.md @@ -5,7 +5,7 @@ title: "VISSv2 Clients" There are a number of different clients avaliable on this repo in the client/client-1.0 directory. ## Compression client -The [compression client](https://github.com/w3c/automotive-viss2/blob/master/client/client-1.0/compress_client/compress_client.go) can be used for testing three payload compression variants. +The [compression client](https://github.com/covesa/vissr/blob/master/client/client-1.0/compress_client/compress_client.go) can be used for testing three payload compression variants. * Proprietary compression algorithm * Protobuf encoding, level 1 * Protobuf encoding, level 2 @@ -16,7 +16,7 @@ Due to its strong dependence on the payload format it might require rewrites if/ It is not kept up to date on this and is therefore likely to crash if an unsupported payload is applied. ### Protobuf encoding -The encoding uses the VISSv2messages.proto file found [here](https://github.com/w3c/automotive-viss2/tree/master/protobuf). +The encoding uses the VISSv2messages.proto file found [here](https://github.com/covesa/vissr/tree/master/protobuf). The server supports this only for the Websocket protocol, where the websocket transport manager encodes payloads before sending them, and decodes payloads directly after receiving them. The client follows the same encoding/decoding behavior, so that the use of protobuf encoding is abstracted before other layers in both the server and the client get access to the payloads. @@ -24,23 +24,24 @@ Two levels of protobuf encoding are available, level one in which paths and time and level two where these fields are compressed. #### Level 2 -Level 2 compresses the VSS paths by using the [VSS path list](/automotive-viss2/server#pathlist-file-generation) as a lookup table. +Level 2 compresses the VSS paths by using the [VSS path list](/vissr/server#pathlist-file-generation) as a lookup table. Instead of using the string paths in the encoded payload the index into the array is used. Finding the index in the array for a given path is done by applying a binary search, as the array paths are sorted by the server. Going the other way, the array is simply indexed by the integer value from the protobuf encoded payload. -The string based timestamps are replaced by an int32 as shown in the CompressTS() procedure found in [computils.go](https://github.com/w3c/automotive-viss2/blob/master/utils/computils.go). +The string based timestamps are replaced by an int32 as shown in the CompressTS() procedure found in [computils.go](https://github.com/covesa/vissr/blob/master/utils/computils.go). Level 2 achieves compression rates of around 5 or better. ## gRPC client -The gRPC implementation uses the protobuf encoding in the VISSv2messages.proto file found [here](https://github.com/w3c/automotive-viss2/tree/master/grpc_pb). +The gRPC implementation uses the protobuf encoding in the VISSv2messages.proto file found [here](https://github.com/covesa/vissr/tree/master/grpc_pb). The server currently only supports the protobuf level 1 encoding. ## MQTT client -The [MQTT client]() implements the application level protocol described in the [specification](https://raw.githack.com/w3c/automotive/gh-pages/spec/VISSv2_Transport.html#application-level-protocol). +The [MQTT client](https://github.com/UlfBj/vissr/tree/master/client/client-1.0/mqtt_client) implements the application level protocol described in the +[specification](https://raw.githack.com/COVESA/vehicle-information-service-specification/main/spec/VISSv2_Transport.html#application-level-protocol). ## CSV client The [CSV client]() is developed for testing the [curve logging algorithm](https://www.geotab.com/blog/gps-logging-curve-algorithm/) that Geotab has opened for public cuse. -A client can equest it to be aplied to data by using a [filter](https://raw.githack.com/w3c/automotive/gh-pages/spec/VISSv2_Core.html#curvelog-filter-operation) option. +A client can equest it to be aplied to data by using a [filter](https://raw.githack.com/COVESA/vehicle-information-service-specification/main/spec/VISSv2_Core.html#curvelog-filter-operation) option. It generates a comma separated (CSV) file in which it saves the curve logged data that it has reuested from the server. The CSV format makes it easy to import it into an Excel sheet and visualize it as a graph which allows it e. g. to be compared with the original, non-curved data. @@ -48,10 +49,10 @@ The CSV format makes it easy to import it into an Excel sheet and visualize it a ## Java script clients There are a few clients that are written in Javascript, and thus when started opens in a browser. Thes clients can be quite handy for quick testing of the server functionality. -Example payloads that can be used as input are found in the [appclient_commands.txt](https://github.com/w3c/automotive-viss2/blob/master/client/client-1.0/Javascript/appclient_commands.txt) file. +Example payloads that can be used as input are found in the [appclient_commands.txt](https://github.com/covesa/vissr/blob/master/client/client-1.0/Javascript/appclient_commands.txt) file. ### HTTP client -The [HTTP Client](file:///home/ubjorken/Proj/w3c/WAII/client/client-1.0/Javascript/httpclient.html) +The [HTTP Client](https://github.com/covesa/vissr/blob/master/client/client-1.0/Javascript/httpclient.html) requires the server IP address/URL to be written into the field for it, and the IP address button to be pushed. Thereafter paths can be written into the Get field, followed by a push of the Get button. In the case of the client writing a value to the server, the path is written into the Set field, with the value in the following field, before pushing the Post button. @@ -59,33 +60,33 @@ If the data associated with the path is access controlled, then the access token must first be written into the field for the token. Klicking the button to the right of it preserves the token for use in multple requests. ### Websocket client -The [Websocket Client](https://github.com/w3c/automotive-viss2/blob/master/client/client-1.0/Javascript/wsclient_uncompressed.html) +The [Websocket Client](https://github.com/covesa/vissr/blob/master/client/client-1.0/Javascript/wsclient_uncompressed.html) requires the server IP address/URL to be written into the field for it, and the IP address button to be pushed. Thereafter JSON based payloads can be written into the Sed field, followed by a push of the Send button. ### Websocket client (using compression) -The [Websocket Client](https://github.com/w3c/automotive-viss2/blob/master/client/client-1.0/Javascript/wsclient_compressed.html) +The [Websocket Client](https://github.com/covesa/vissr/blob/master/client/client-1.0/Javascript/wsclient_compressed.html) requires the server IP address/URL to be written into the field for it, and the IP address button to be pushed. Thereafter JSON based payloads can be written into the Sed field, followed by a push of the Send button. The difference to the uncompressed Websocket client is that this client opens a Websocket session with the erver in which it requests a session in which proprietary compression is applied to the payloads (see chapter above). ### Access Grant Token Server client -The [AGT client](https://github.com/w3c/automotive-viss2/blob/master/client/client-1.0/Javascript/agtclient.html) +The [AGT client](https://github.com/covesa/vissr/blob/master/client/client-1.0/Javascript/agtclient.html) requests an Access Grant Token from the Access Grant Token server. It requires the AGT server IP address/URL to be written into the field for it, and the Server IP button to be pushed. In the leftmost field below "agtserver" (no quotes) must be written, then in the rightmost field a request payload shall be written. -A payload example can be found in the [appclient_commands.txt](https://github.com/w3c/automotive-viss2/blob/master/client/client-1.0/Javascript/appclient_commands.txt) file. +A payload example can be found in the [appclient_commands.txt](https://github.com/covesa/vissr/blob/master/client/client-1.0/Javascript/appclient_commands.txt) file. The proof value must be "ABC" for a positive validation, in which case an Access Grant token is returned. ### Access Token Server client -The [AT client](https://github.com/w3c/automotive-viss2/blob/master/client/client-1.0/Javascript/atclient.html) +The [AT client](https://github.com/covesa/vissr/blob/master/client/client-1.0/Javascript/atclient.html) requests an Access Token from the Access Token server. It requires the AT server IP address/URL to be written into the field for it, and the Server IP button to be pushed. In the leftmost field below "atserver" (no quotes) must be written, then in the rightmost field a request payload shall be written. -A payload example can be found in the [appclient_commands.txt](https://github.com/w3c/automotive-viss2/blob/master/client/client-1.0/Javascript/appclient_commands.txt) file. +A payload example can be found in the [appclient_commands.txt](https://github.com/covesa/vissr/blob/master/client/client-1.0/Javascript/appclient_commands.txt) file. The token that is provided in the request must include an Access Grant token from the response of a successful reuquest to the AGT server. ## Clients on other repos diff --git a/tutorial/content/datastore/_index.md b/tutorial/content/datastore/_index.md index 7b1221a6..d1b85afd 100644 --- a/tutorial/content/datastore/_index.md +++ b/tutorial/content/datastore/_index.md @@ -1,5 +1,5 @@ --- -title: "WAII Data Storage" +title: "VISSR Data Storage" --- Two realizations of data storage are available on the [COVESA/CCS-components Github](https://github.com/COVESA/ccs-components), @@ -14,6 +14,6 @@ It may be a bit confusing that sometimes this is referred to as "data store/stor The latter name is legacy from a previous COVESA project, the Cloud & Connected Services project, while the former has emerged later in the COVESA architecture group work. An argument for keeping both could be to say that the state storage refers to a storage that only keeps the latest value of a signal, while the data store refers to a more general database that can also keep time series of values of a signal. -There are two scenarios where the VISSv2 server operates on time series data, [curve logging](https://raw.githack.com/w3c/automotive/gh-pages/spec/VISSv2_Core.html#curvelog-filter-operation), -and [historic data](https://raw.githack.com/w3c/automotive/gh-pages/spec/VISSv2_Core.html#history-filter-operation), +There are two scenarios where the VISSv2 server operates on time series data, [curve logging](https://raw.githack.com/covesa/vehicle-information-service-specification/main/spec/VISSv2_Core.html#curvelog-filter-operation), +and [historic data](https://raw.githack.com/covesa/vehicle-information-service-specification/main/spec/VISSv2_Core.html#history-filter-operation), but in this server implementation these data series is temporarily stored within the server, so a "state storage" functionality is sufficient for its needs. diff --git a/tutorial/content/datastore/redis/_index.md b/tutorial/content/datastore/redis/_index.md index 67075cb1..8e3d7200 100644 --- a/tutorial/content/datastore/redis/_index.md +++ b/tutorial/content/datastore/redis/_index.md @@ -1,5 +1,5 @@ --- -title: "WAII Redis" +title: "VISSR Redis" --- ## Redis state storage diff --git a/tutorial/content/datastore/sqlite/_index.md b/tutorial/content/datastore/sqlite/_index.md index dc234982..992fa213 100644 --- a/tutorial/content/datastore/sqlite/_index.md +++ b/tutorial/content/datastore/sqlite/_index.md @@ -1,5 +1,5 @@ --- -title: "WAII SQLite" +title: "VISSR SQLite" --- ## SQLite state storage @@ -7,5 +7,5 @@ When an SQLite database is used as the state storage it is necessary to prepopul To do this there is a [statestorage_mgr](https://github.com/COVESA/ccs-components/tree/master/statestorage/sqlImpl) that takes a file containing a list of all the pathnames, "vsspathlist.json" as input. This file is generated by the server at startup, taking the paths from the VSS tree that it has access to. -This SQLite DB file then needs to be moved to the WAII/server/visv2server/serviceMgr directory, where it should have the name "statestorage.db" +This SQLite DB file then needs to be moved to the vissr/server/visv2server/serviceMgr directory, where it should have the name "statestorage.db" (if server configuration is not changed to another name). diff --git a/tutorial/content/feeder/_index.md b/tutorial/content/feeder/_index.md index ef30d86b..7a9122d8 100644 --- a/tutorial/content/feeder/_index.md +++ b/tutorial/content/feeder/_index.md @@ -1,5 +1,5 @@ --- -title: "WAII Feeders" +title: "VISSR Feeders" --- A feeder is a Sw component that needs to implement three tasks: @@ -12,13 +12,13 @@ which spawns two threads that implement the respective interface task. The architecture shown handle all its communication with the server via the state storage. This leads to a polling paradigm and thus a potential latency and performance weakness. This architecture is therefore not found on the master branch, but available on the datastore-poll branch. -![Feeder Sw architecture, unoptimized polling](/automotive-viss2/images/feeder-sw-design-v1.jpg?width=50pc) +![Feeder Sw architecture, unoptimized polling](/vissr/images/feeder-sw-design-v1.jpg?width=50pc) * Figure 1. Feeder software architecture unoptimized polling An improved architecture that eliminates the mentioned weaknesses for data flowing in the direction from the server to the feeder (i. e client write requests) is shown in figure 2. For write requests the server communicates directly over an IPC channel with the feeder, thus removing the need for the feeder to poll the state storage to find new write requests. -![Feeder Sw architecture, optimized polling](/automotive-viss2/images/feeder-sw-design-v2.jpg?width=50pc) +![Feeder Sw architecture, optimized polling](/vissr/images/feeder-sw-design-v2.jpg?width=50pc) * Figure 2. Feeder software architecture optimized polling A feeder implementing the optimized polling version of the SwA is found at the master branch. @@ -32,15 +32,15 @@ The instructions for how to do this is encoded into one or more configuration fi There are two versions of the feeder instructions, being used in template feederv1 and feederv2, respectively. In version 1 this file only contains a signal name mapping, while version 2 supports also scaling instructions. -For more about the telpate feeders, see the README in [feeder-template](https://github.com/w3c/automotive-viss2/tree/master/feeder/feeder-template) directory. +For more about the telpate feeders, see the README in [feeder-template](https://github.com/covesa/vissr/tree/master/feeder/feeder-template) directory. An OEM wanting to deploy the VISSv2 tech stack needs to implement the Vehicle interface of the feeder, e. g. to implement a CAN bus interface. In the template feeders the Vehicle interface contains a minimal signal simulator that generates random values for the signals it is configured to support. All of that code should be removed and replaced by the code implementing the new interface client. -Besides the feeder templates there is also an [rl-feeder](https://github.com/w3c/automotive-viss2/tree/master/feeder/feeder-rl) +Besides the feeder templates there is also an [rl-feeder](https://github.com/covesa/vissr/tree/master/feeder/feeder-rl) where the Vehicle interface is implemented to connect to a RemotiveLabs broker. [RemotiveLabs](https://remotivelabs.com/) has a public cloud version of its broker that can be used to replay trip data available in VSS format. -There is also an External Vehicle Interface Client [EVIC](https://github.com/w3c/automotive-viss2/tree/master/feeder/feeder-evic) +There is also an External Vehicle Interface Client [EVIC](https://github.com/covesa/vissr/tree/master/feeder/feeder-evic) feeder that enables the interface client to be implemented in a separate executable. diff --git a/tutorial/content/peripheral-components/_index.md b/tutorial/content/peripheral-components/_index.md index 7570f5ae..011d1bd8 100644 --- a/tutorial/content/peripheral-components/_index.md +++ b/tutorial/content/peripheral-components/_index.md @@ -11,23 +11,23 @@ A few other software components that can be useful when setting up a VISSv2 comm The VISS2 specification describes an access control model involving two authorization servers: * Access Grant Token server * Access Token server -For details please read the [VISSv2: Access Control](https://raw.githack.com/w3c/automotive/gh-pages/spec/VISSv2_Core.html#access-control-model), +For details please read the [VISSv2: Access Control](https://raw.githack.com/covesa/vehicle-information-service-specification/main/spec/VISSv2_Core.html#access-control-model), and the [Consent Model]() chapters. To trigger the access control and consent functionality it is necessary to tag the corresponding VSS nodes as described in the spec. This can either be done by editing of the actual vspec files from the [VSS/spec](https://github.com/COVESA/vehicle_signal_specification/tree/master/spec) directory, or by creating overlay files and include them as described in [VSS-tools](https://github.com/COVESA/vss-tools), -and then generate the VSS tree in binary format as described in [VSS tree configuration](https://w3c.github.io/automotive-viss2/server/#vss-tree-configuration). +and then generate the VSS tree in binary format as described in [VSS tree configuration](https://covesa.github.io/vissr/server/#vss-tree-configuration). ### Access Grant Token server (AGTS) -The [AGTS](https://github.com/w3c/automotive-viss2/tree/master/server/agt_server), +The [AGTS](https://github.com/covesa/vissr/tree/master/server/agt_server), which typically will be deployed off-vehicle, in the cloud, is separately built and deployed. -The file agt_public_key.rsa is generated at startup, which must be copied to the [AT server](https://github.com/w3c/automotive-viss2/tree/master/server/vissv2server/atServer) directory. +The file agt_public_key.rsa is generated at startup, which must be copied to the [AT server](https://github.com/covesa/vissr/tree/master/server/vissv2server/atServer) directory. ### Access Token server (ATS) -The [ATS](https://github.com/w3c/automotive-viss2/tree/master/server/vissv2server/atServer) is deployed on a separate thread within the VISSv2 server, -to include it make sure it is uncommented in the serverComponents string array in [viss2server.go](https://github.com/w3c/automotive-viss2/blob/master/server/vissv2server/vissv2server.go). -The ATS uses the [policy documents](https://raw.githack.com/w3c/automotive/gh-pages/spec/VISSv2_Core.html#policy-documents) described in the spec when validating an access token, +The [ATS](https://github.com/covesa/vissr/tree/master/server/vissv2server/atServer) is deployed on a separate thread within the VISSv2 server, +to include it make sure it is uncommented in the serverComponents string array in [viss2server.go](https://github.com/covesa/vissr/blob/master/server/vissv2server/vissv2server.go). +The ATS uses the [policy documents](https://raw.githack.com/covesa/vehicle-information-service-specification/main/spec/VISSv2_Core.html#policy-documents) described in the spec when validating an access token, examples of these are available in the purposelist.json and scopelist.json files. ## Open Vehicle Data Set (OVDS) diff --git a/tutorial/content/pocs/_index.md b/tutorial/content/pocs/_index.md index bd7dadbc..4ba67203 100644 --- a/tutorial/content/pocs/_index.md +++ b/tutorial/content/pocs/_index.md @@ -1,9 +1,9 @@ --- -title: "WAII POCs" +title: "VISSR POCs" --- The WAII communication tech stack architecture can be realized in different "flavors", a few different are presented here as Proof-of-Concept (POC) projects. -* POC1: [Vehicle.Speed subscription example](/automotive-viss2/pocs/poc1) -* POC2: [Next POC..](/automotive-viss2/pocs/poc2) +* POC1: [Vehicle.Speed subscription example](/vissr/pocs/poc1) +* POC2: [Next POC..](/vissr/pocs/poc2) diff --git a/tutorial/content/pocs/poc1/_index.md b/tutorial/content/pocs/poc1/_index.md index 8d7214db..456c86f3 100644 --- a/tutorial/content/pocs/poc1/_index.md +++ b/tutorial/content/pocs/poc1/_index.md @@ -6,11 +6,11 @@ Here follows a minimal example that goes through all the steps nneeded to set up where a client subscribes to Vehicle.Speed, and receives simulated values in return. It is assumed that the development environment has Golang installed. -If not, then instruction for installing Golang is found [here](/automotive-viss2/build-system/). +If not, then instruction for installing Golang is found [here](/vissr/build-system/). If this repo is not cloned to the development environment, this is done by the command: -$ git clone https://github.com/w3c/automotive-viss2.git +$ git clone https://github.com/covesa/vissr.git The POC will be based on the feeder found at the feeder branch, so switching to this branch is done by the command: @@ -31,7 +31,7 @@ $ go build The server uses a binary formatted copy of the VSS tree to verify client requests, so if the signal of interest, Vehicle.Speed, is not in this tree, i is necessary to create a new binary tree containing this signal. -For informtion on how to get tht done, check out [/automotive-viss2/server#vss-tree-configuration). +For informtion on how to get that done, check out [VSS tree configuration](/vissr/server#vss-tree-configuration). Then start the server with the command line configuration for using Redis as statestorage: @@ -42,7 +42,7 @@ To build the feeder, open a new terminal and move the working directory to WAII/ $ go build Before strtign it, it needs to be configured for mapping of the Vehicle.Speed signal, and to generate simulated values for it. -To do this the file [VehicleVssMapData.json](https://github.com/w3c/automotive-viss2/blob/feeder/feeder/VehicleVssMapData.json) needs to be edited +To do this the file [VehicleVssMapData.json](https://github.com/covesa/vissr/blob/feeder/feeder/VehicleVssMapData.json) needs to be edited so that it only contains a mapping for Vehicle.Speed. [{"vssdata":"Vehicle.Speed","vehicledata":"CurrSpd"}] @@ -53,9 +53,9 @@ After the feeder is configured it is started: $ ./feeder What is left now is to start a client and issue the subscribe request. -One solution to this is to write a client, but a quicker solution is to use any of the [existing clients](/automotive-viss2/client). +One solution to this is to write a client, but a quicker solution is to use any of the [existing clients](/vissr/client). -We will here use the [Javascript based client that uses the Websocket protocol](https://github.com/w3c/automotive-viss2/blob/feeder/client/client-1.0/Javascript/wsclient_uncompressed.html). +We will here use the [Javascript based client that uses the Websocket protocol](https://github.com/covesa/vissr/blob/feeder/client/client-1.0/Javascript/wsclient_uncompressed.html). Start it by navigating to the directory using a file browser, then just click on it. @@ -72,7 +72,7 @@ The client should then be connected to the server, which is verified b a printou If that is not shown, either the server is not up and running, or the IP address is not the corrt one. Assuming it got connected, the only thing left is to issue a subscribe request. -The [appclient_commands.txt](https://github.com/w3c/automotive-viss2/blob/feeder/client/client-1.0/Javascript/appclient_commands.txt) contains many examples of client requests +The [appclient_commands.txt](https://github.com/covesa/vissr/blob/feeder/client/client-1.0/Javascript/appclient_commands.txt) contains many examples of client requests From this file, copy the request payload: diff --git a/tutorial/content/server/Access-control-servers/_index.md b/tutorial/content/server/Access-control-servers/_index.md index aa156f7d..c77bef13 100644 --- a/tutorial/content/server/Access-control-servers/_index.md +++ b/tutorial/content/server/Access-control-servers/_index.md @@ -2,12 +2,12 @@ title: "VISSv2 Access Control Servers" --- -The [VISSv2 access control model](https://raw.githack.com/w3c/automotive/gh-pages/spec/VISSv2_Core.html#access-control-model) specifies two authorization servers: +The [VISSv2 access control model](https://raw.githack.com/covesa/vehicle-information-service-specification/main/spec/VISSv2_Core.html#access-control-model) specifies two authorization servers: * Access Grant server * Access Token server ### Access Grant server -This server is in a typical scenario running in the cloud. It is built as a separate executable in the WAII/server/agt_server directory +This server is in a typical scenario running in the cloud. It is built as a separate executable in the vissr/server/agt_server directory $ go build @@ -42,7 +42,7 @@ If the cache is full, caching of one more is rejected until a cached token becom ### Server configuration The configuration available for the servers is whether the protocols that they implement to expose their APIS are TLS protected or not. -The same framework that is used for generating credentials for the client-server communication described [here](https://github.com/w3c/automotive-viss2/tree/master/testCredGen/) +The same framework that is used for generating credentials for the client-server communication described [here](https://github.com/covesa/vissr/tree/master/testCredGen/) can be used in this case also. These credentials should however to follow good security practises be separate from what is used in the client-server communication. The different port number for the respective servers are shown below. @@ -54,7 +54,7 @@ The different port number for the respective servers are shown below. ### VISS web client submodule This submodule implements a [VISSv2 web client](https://github.com/nicslabdev/viss-web-client/) -that exposes a UI that is considerably more sophisticated than what other clients on the WAII repo exposes, +that exposes a UI that is considerably more sophisticated than what other clients on the VISSR repo exposes, and it is particularly helpful when it comes to the client interactions with access control involved. Check out the README on both repos for more information. @@ -63,15 +63,15 @@ The VISSv2 specification provides support for requesting consent from a data own The model for this is that the process for obtaining the owner consent is delegated to an External Consent framework (ECF), and the details ofthis process is out-of-scope in relation to the VISSv2 specification. What is in scope is a high-level description of the protocol between the VISSv2 server and the ECF, see the -[VISSv2 consent support](https://raw.githack.com/w3c/automotive/gh-pages/spec/VISSv2_Core.html#consent-support) chapter. +[VISSv2 consent support](https://raw.githack.com/covesa/vehicle-information-service-specification/main/spec/VISSv2_Core.html#consent-support) chapter. To configure the VISSv2 server to try to connect to an ECF, it must be started with the command parameter -c". The figure below shows the the different steps in the dataflow that is necessary when a client wants to initiate a subscription of data that is access controlled and require consent from the data owner. -![VISSv2 consent subscribe dataflow](/automotive-viss2/images/VISSv2-consent-subscribe-dataflow.jpg?width=40pc) +![VISSv2 consent subscribe dataflow](/vissr/images/VISSv2-consent-subscribe-dataflow.jpg?width=40pc) The dataflow describes a scenario when the client successfully subscribes to data the require both access control and consent by the data owner. Consent can only be required in combination with requiring access control, please see the -[Access Control Model](https://raw.githack.com/w3c/automotive/gh-pages/spec/VISSv2_Core.html#access-control-model) chapter. +[Access Control Model](https://raw.githack.com/covesa/vehicle-information-service-specification/main/spec/VISSv2_Core.html#access-control-model) chapter. 1. The client issues a request to the Access Grant Token server (AGTS). @@ -97,7 +97,7 @@ but if 2.4 happened before, so that the consent no longer has the value NOT_SET, the ATS generates the Access Token (AT), and returns it to the client. If the consent was set to NO, the consent data is returned without the AT. 3. The client issues the subscribe request to the VISSv2 server containing the AT. The AT in the client request my be represented by a handle instead of the entire AT, -see the [Protected Resource Request](https://raw.githack.com/w3c/automotive/gh-pages/spec/VISSv2_Core.html#protected-resource-request) chapter. +see the [Protected Resource Request](https://raw.githack.com/covesa/vehicle-information-service-specification/main/spec/VISSv2_Core.html#protected-resource-request) chapter. 3.1 The VISSv2 server issues an AT validation request to the ATS. The ATS finds it on the Active list, and validates the AT. @@ -167,4 +167,4 @@ Consent cancellation request: {“action”: “consent-cancel”, “messageId Response to above requests: {“action”: “same-as-in-request”, “status”: “200-OK/404-Not found/401-Bad request”} // Status is one of the three examples shown. -See the specification chapter[Purpose list](https://raw.githack.com/w3c/automotive/gh-pages/spec/VISSv2_Core.html#purpose-list) for the definition of the signal_access object. +See the specification chapter[Purpose list](https://raw.githack.com/covesa/vehicle-information-service-specification/main/spec/VISSv2_Core.html#purpose-list) for the definition of the signal_access object. diff --git a/tutorial/content/server/_index.md b/tutorial/content/server/_index.md index 0a9f408b..1cd4fd0f 100644 --- a/tutorial/content/server/_index.md +++ b/tutorial/content/server/_index.md @@ -2,12 +2,12 @@ title: "VISSv2 Server" --- -The VISSv2 server is the Sw component that implements the interface that is exposed to the clients, and that must conform to the W3C VISSv2 specification. +The VISSv2 server is the Sw component that implements the interface that is exposed to the clients, and that must conform to the COVESA VISSv2 specification. ### Build the server -Please check the chapter [VISSv2 Build System](/automotive-viss2/build-system) for general Golang information. +Please check the chapter [VISSv2 Build System](/vissr/build-system) for general Golang information. -To build the server, open a erminal and go to the WAII/server/vissv2 directory and issue the command: +To build the server, open a erminal and go to the vissr/server/vissv2 directory and issue the command: $ go build @@ -23,10 +23,10 @@ and a file containing the binary representation must be created, which is done w $ make binary This generates a file with a name like 'vss_rel_4.1-dev.binary', -which then needs to be renamed to 'vss_vissv2.binary' and stored in the WAII/server/vissv2server directory. +which then needs to be renamed to 'vss_vissv2.binary' and stored in the vissr/server/vissv2server directory. If you want to configure the tree to include access control, access control tags as described in the -[VISSv2 - Access Control Selection chapter](https://raw.githack.com/w3c/automotive/gh-pages/spec/VISSv2_Core.html#access-control-selection) needs to be added to appropriate tree nodes. +[VISSv2 - Access Control Selection chapter](https://raw.githack.com/covesa/vehicle-information-service-specification/main/spec/VISSv2_Core.html#access-control-selection) needs to be added to appropriate tree nodes. This can either be done by editing vspec files directly, or using the [VSS-Tools](https://github.com/covesa/vss-tools) overlay mechanism. #### Command line configuration @@ -41,7 +41,7 @@ The server has the following command line configurations: #### Data storage configuration Currently the server supports two different databases, SQLite and Redis, which one to use is selected in the command line configuration. -However, to get it up and running there are other preparations lso needed, please see the [VISSv2 Data Storage](/automotive-viss2/datastore) chapter. +However, to get it up and running there are other preparations lso needed, please see the [VISSv2 Data Storage](/vissr/datastore) chapter. #### Protocol support configuration @@ -61,7 +61,7 @@ The Websocket protocol manager terminates subscriptions if a client terminats th ##### TLS configuration The server, and several of the clients, can be configured to apply TLS to the protocols (MQTT uses it integrated model for this). -The first step in applying TLS is to generate the credentials needed, which is done by running the testCredGen.sh script found [here](https://github.com/w3c/automotive-viss2/tree/master/testCredGen/). +The first step in applying TLS is to generate the credentials needed, which is done by running the testCredGen.sh script found [here](https://github.com/covesa/vissr/tree/master/testCredGen/). For details about it, please look at the README in that directory. As described there, the generated credentials must then be copied into the appropriate directories for both the server and the client. @@ -88,13 +88,13 @@ SwCs that use this file: * The live simulator. ### History control -The VISSv2 specification provides a capability for clients to issue a request for [historic data](https://raw.githack.com/w3c/automotive/gh-pages/spec/VISSv2_Core.html#history-filter-operation). +The VISSv2 specification provides a capability for clients to issue a request for [historic data](https://raw.githack.com/covesa/vehicle-information-service-specification/main/spec/VISSv2_Core.html#history-filter-operation). This server supports temporary recording of data that can then be requested by a client using a history filter. The model used in the implementation of this is that it is not the server that decides when to start or stop a recording, or how long to keep the recorded data, but it is controlled by some other vehicle system via a Unix domain socket based API. -For more information, please see the [service manager](https://github.com/w3c/automotive-viss2/tree/master/server/vissv2server/serviceMgr) README. +For more information, please see the [service manager](https://github.com/covesa/vissr/tree/master/server/vissv2server/serviceMgr) README. -To test this functionality there is a rudimentary [history control client](https://github.com/w3c/automotive-viss2/blob/master/server/hist_ctrl_client.go) +To test this functionality there is a rudimentary [history control client](https://github.com/covesa/vissr/blob/master/server/hist_ctrl_client.go) that can be used to instruct the server to start/stop/delete recording of signals. To reduce the amount of data that is recorded the server only saves a data value if it has changed compared to the latest captured, so to record more than a start and stop value the signals should be dynamic during a test. @@ -107,9 +107,9 @@ VISSv2 uses JSON as the payload format, and as JSON is a textbased format there A first attempt on applying compression built on a proprietary algorithm that took advantage of knowing the VISSv2 payload format. This yielded compressions rates around 5 times (500%), but due to its strong dependence on the payload format it was hard to keep stable when the payload format evolved. -The [compression client](/automotive-viss2/client#compression-client) can be used to test it out, but some payoads will likely crash it. +The [compression client](/vissr/client#compression-client) can be used to test it out, but some payoads will likely crash it. -A later compression solution was built on protobuf, using the VISSv2messages.proto file found [here](https://github.com/w3c/automotive-viss2/tree/master/protobuf). -For more details, see the [compression client](/automotive-viss2/client#compression-client). +A later compression solution was built on protobuf, using the VISSv2messages.proto file found [here](https://github.com/covesa/vissr/tree/master/protobuf). +For more details, see the [compression client](/vissr/client#compression-client). -The gRPC protocol implementation, which requires that payloads are protobuf encoded, uses the VISSv2.proto file found [here](https://github.com/w3c/automotive-viss2/tree/master/grpc_pb). +The gRPC protocol implementation, which requires that payloads are protobuf encoded, uses the VISSv2.proto file found [here](https://github.com/covesa/vissr/tree/master/grpc_pb). diff --git a/tutorial/content/tools/_index.md b/tutorial/content/tools/_index.md index e7c5c701..c0c0ff0a 100644 --- a/tutorial/content/tools/_index.md +++ b/tutorial/content/tools/_index.md @@ -1,5 +1,5 @@ --- -title: "WAII Tools" +title: "VISSR Tools" --- SwCs categorized as tools are used "off-line" to create artefacts that can then be used by the "on-line" SwCs such as the server or by feeders. @@ -12,7 +12,7 @@ The input to the DCT are three files: * A YAML representation of signals of a northbound domain. * A YAML representation of signals of a southbound domain. * A YAML representation of pairs of signals from respective domain that the feeder should convert between. -For more information plese see the README in the [DCT](https://github.com/w3c/automotive-viss2/tree/master/tools/DomainConversionTool) directory. +For more information plese see the README in the [DCT](https://github.com/covesa/vissr/tree/master/tools/DomainConversionTool) directory. ## VSS-Tools Binary Exporter @@ -35,4 +35,4 @@ binary: ``` needs to be modified to point to the desired file, i.e. the part "./spec/VehicleSignalSpecification.vspec" needs to be changed. -The tool output, a file with the extension ".binary" will then have to be copied to the WAII server directory, and renamed to "vss_vissv2.binary". +The tool output, a file with the extension ".binary" will then have to be copied to the VISSR server directory, and renamed to "vss_vissv2.binary". diff --git a/tutorial/layouts/partials/favicon.html b/tutorial/layouts/partials/favicon.html index 7be53392..0007bb32 100644 --- a/tutorial/layouts/partials/favicon.html +++ b/tutorial/layouts/partials/favicon.html @@ -1 +1 @@ - + diff --git a/tutorial/layouts/partials/logo.html b/tutorial/layouts/partials/logo.html index f2211357..c11fff64 100644 --- a/tutorial/layouts/partials/logo.html +++ b/tutorial/layouts/partials/logo.html @@ -1,3 +1,3 @@ diff --git a/tutorial/static/images/vissv2.png b/tutorial/static/images/vissv2.png index e1d85759e893dcee59ff7f33698652e4d2a520fe..137c177a455f9d600e0000aa24798c5bcad30805 100644 GIT binary patch delta 14424 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