From 7966d510949892815e4be1c8414aafc3af323712 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Wed, 30 Oct 2019 14:44:18 +0000 Subject: [PATCH] Add file trees for all microservices --- src/SUMMARY.md | 6 ++ src/chapter_3_1_1.md | 9 +++ src/chapter_3_2.md | 10 +-- src/chapter_3_2_1.md | 74 ++++++++++++++++++++++ src/chapter_3_2_2.md | 99 +++++++++++++++++++++++++++++ src/chapter_3_2_3.md | 123 ++++++++++++++++++++++++++++++++++++ src/chapter_3_2_4.md | 144 +++++++++++++++++++++++++++++++++++++++++++ src/chapter_3_2_5.md | 87 ++++++++++++++++++++++++++ 8 files changed, 547 insertions(+), 5 deletions(-) create mode 100644 src/chapter_3_1_1.md create mode 100644 src/chapter_3_2_1.md create mode 100644 src/chapter_3_2_2.md create mode 100644 src/chapter_3_2_3.md create mode 100644 src/chapter_3_2_4.md create mode 100644 src/chapter_3_2_5.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index ea292f1..577db1e 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -6,7 +6,13 @@ - [GPIO Pinout](./chapter_2_2.md) - [Software](./chapter_3.md) - [Operating System](./chapter_3_1.md) + - [Networking](./chapter_3_1_1.md) - [Microservices](./chapter_3_2.md) + - [peach-buttons](./chapter_3_2_1.md) + - [peach-menu](./chapter_3_2_2.md) + - [peach-network](./chapter_3_2_3.md) + - [peach-oled](./chapter_3_2_4.md) + - [peach-stats](./chapter_3_2_5.md) - [Interfaces](./chapter_3_3.md) - [Physical Interface](./chapter_3_3_1.md) - [Web Interface](./chapter_3_3_2.md) diff --git a/src/chapter_3_1_1.md b/src/chapter_3_1_1.md new file mode 100644 index 0000000..cd0d376 --- /dev/null +++ b/src/chapter_3_1_1.md @@ -0,0 +1,9 @@ +# Networking + +PeachCloud has three primary network interfaces: `eth0`, `wlan0` and `ap0` (virtual interface). The device supports two wireless modes: client and access point (AP). + +In client mode, the `wlan0` interface is managed by `wpa_supplicant`. This allows the PeachCloud device to connect to a WiFi access point in the vicinity. The IP address of the `wlan0` interface is dynamically-assigned by the WiFi router it is associated with. While the device is running in this mode, the `ap0` interface is set `DOWN` and the `dnsmasq` and `hostapd` processes are stopped. + +In access point mode, the `ap0` interface is managed by `hostapd` - with DNS and DHCP leasing being handled by `dnsmasq`. The IP address of the `ap0` interface is set to `11.11.11.10` by default. Connected devices are leased IP addresses in the range of `11.11.11.11 - 11.11.11.30` (_for now_). While the device is running in this mode, the `wlan0` interface is set `DOWN` and the `wpa_supplicant` process is stopped. + +The `peach-network` microservice exposes `activate_ap()` and `activate_client()` RPC calls for simple switching of the networking mode. This functionality is also exposed by the menu system of the physical interface. diff --git a/src/chapter_3_2.md b/src/chapter_3_2.md index 680d3f0..12c11c6 100644 --- a/src/chapter_3_2.md +++ b/src/chapter_3_2.md @@ -4,13 +4,13 @@ PeachCloud is built primarily with a [microservices architecture](https://micros The suite of PeachCloud microservices currently includes: - - [peach-buttons](https://github.com/peachcloud/peach-buttons) + - **peach-buttons** [(repo)](https://github.com/peachcloud/peach-buttons) - poll GPIO pins for button presses and emit events via pub-sub - - [peach-menu](https://github.com/peachcloud/peach-menu) + - **peach-menu** [(repo)](https://github.com/peachcloud/peach-menu) - monitor and interact with the device via the physical interface - - [peach-network](https://github.com/peachcloud/peach-network) + - **peach-network** [(repo)](https://github.com/peachcloud/peach-network) - query and configure network interfaces - - [peach-oled](https://github.com/peachcloud/peach-oled) + - **peach-oled** [(repo)](https://github.com/peachcloud/peach-oled) - write and draw to the OLED display - - [peach-stats](https://github.com/peachcloud/peach-menu) + - **peach-stats** [(repo)](https://github.com/peachcloud/peach-menu) - query system statistics diff --git a/src/chapter_3_2_1.md b/src/chapter_3_2_1.md new file mode 100644 index 0000000..2ca74c0 --- /dev/null +++ b/src/chapter_3_2_1.md @@ -0,0 +1,74 @@ +# peach-buttons + +GPIO microservice module for handling button presses. `peach-buttons` implements a JSON-RPC server with [Publish-Subscribe extension](https://docs.rs/jsonrpc-pubsub/11.0.0/jsonrpc_pubsub/). Each button press results in a JSON-RPC request being sent over websockets to any subscribers. A button code for the pressed button is sent with the request to subscribers, allowing state-specific actions to be taken by the subscriber. + +In the case of PeachCloud, the `peach-menu` microservice subscribes to `peach-buttons` in order to update the state of the menu after each button press. + +_Note: This module is relatively stable but is still a work-in-progress._ + +### File Tree + +``` +. +├── Cargo.lock +├── Cargo.toml +├── README.md +├── src +│ ├── error.rs // custom ButtonError type and From implementation +│ ├── interrupt.rs // interrupt handler with GPIO polling +│ ├── lib.rs // RPC server and pubsub handler, pin definitions +│ └── main.rs // init logger, call run() & catch application errors +``` + +### Pin to Button to Button Code Mappings + +``` +4 => Center => 0, +27 => Left => 1, +23 => Right => 2, +17 => Up => 3, +22 => Down => 4, +5 => A => 5, +6 => B => 6 +``` + +_Note: `peach-buttons` utilizes the GPIO character device ABI. This API, stabilized with Linux v4.4, deprecates the legacy sysfs interface to GPIOs that is planned to be removed from the upstream kernel after year 2020._ + +### Setup + +Clone this repo: + +`git clone https://github.com/peachcloud/peach-buttons.git` + +Move into the repo and compile: + +`cd peach-buttons` +`cargo build --release` + +Run the binary with sudo: + +`sudo ./target/release/peach-buttons` + +Logging is made availabe with `env_logger`: + +`sudo RUST_LOG=info ./target/release/peach-buttons` + +_Other logging levels include debug, warn and error._ + +### Testing Subscription + +Request: + +`{"id":1,"jsonrpc":"2.0","method":"subscribe_buttons"}` + +Response: + +`{"jsonrpc":"2.0","result":1,"id":1}` + +Event: + +`{"jsonrpc":"2.0","method":"button_press","params":[0]}` + +### Licensing + +AGPL-3.0 diff --git a/src/chapter_3_2_2.md b/src/chapter_3_2_2.md new file mode 100644 index 0000000..a8d6882 --- /dev/null +++ b/src/chapter_3_2_2.md @@ -0,0 +1,99 @@ +# peach-menu + +[![Build Status](https://travis-ci.com/peachcloud/peach-menu.svg?branch=master)](https://travis-ci.com/peachcloud/peach-menu) + +OLED menu microservice module for PeachCloud. A state machine which listens for GPIO events (button presses) by subscribing to `peach-buttons` over websockets and makes [JSON-RPC](https://www.jsonrpc.org/specification) calls to relevant PeachCloud microservices (`peach-network`, `peach-oled`, `peach-stats`). + +_Note: This module is a work-in-progress._ + +### File Tree + +``` +. +├── Cargo.lock +├── Cargo.toml +├── README.md +├── src +│ ├── buttons.rs // JSON-RPC WebSocket client for peach-buttons +│ ├── error.rs // custom MenuError type & From implementations +│ ├── lib.rs // launch state machine & RPC client for buttons +│ ├── main.rs // init logger, call run() & catch application errors +│ ├── network.rs // JSON-RPC HTTP client for peach-network +│ ├── oled.rs // JSON-RPC HTTP client for peach-oled +│ ├── state_machine.rs // state machine & state_changer() +│ ├── states.rs // state-specific logic called by state machine +│ ├── stats.rs // JSON-RPC HTTP client for peach-stats +│ └── structs.rs // data types used by RPC clients +``` + +### Button Code Mappings + +``` +0 => Center, +1 => Left, +2 => Right, +3 => Up, +4 => Down, +5 => A, +6 => B +``` + +### States + +``` +Home(0), // home menu +Home(1), // networking selected +Home(2), // system stats selected +Home(3), // display off selected +Home(4), // shutdown selected +Logo, // logo splash screen +Network, // network device view +NetworkConf(0), // network configuration menu +NetworkConf(1), // client mode selected +NetworkConf(2), // access point mode selected +NetworkMode(0), // client mode activated +NetworkMode(1), // access point mode activated +OledPower(0), // oled display off +OledPower(1), // oled display on +Shutdown, // shutting down +Stats, // system statistics view +``` + +### Setup + +Clone this repo: + +`git clone https://github.com/peachcloud/peach-menu.git` + +Move into the repo and compile: + +`cd peach-menu` +`cargo build --release` + +Run the binary: + +`./target/target/peach-menu` + +_Note: Will currently panic if `peach_buttons` is not running (connection to ws server fails)._ + +### Environment + +The JSON-RPC HTTP server address and port for the OLED microservice can be configured with the `PEACH_OLED_SERVER` environment variable: + +`export PEACH_OLED_SERVER=127.0.0.1:5000` + +When not set, the value defaults to `127.0.0.1:5112`. + +Logging is made available with `env_logger`: + +`export RUST_LOG=info` + +Other logging levels include `debug`, `warn` and `error`. + +### Resources + +This work was made much, much easier by the awesome blog post titled [Pretty State Machine Patterns in Rust](https://hoverbear.org/2016/10/12/rust-state-machine-pattern/) by [hoverbear](https://hoverbear.org/about/). Thanks hoverbear! + +### Licensing + +AGPL-3.0 diff --git a/src/chapter_3_2_3.md b/src/chapter_3_2_3.md new file mode 100644 index 0000000..2d43914 --- /dev/null +++ b/src/chapter_3_2_3.md @@ -0,0 +1,123 @@ +# peach-network + +[![Build Status](https://travis-ci.com/peachcloud/peach-network.svg?branch=master)](https://travis-ci.com/peachcloud/peach-network) + +Networking microservice module for PeachCloud. Query and configure device interfaces using [JSON-RPC](https://www.jsonrpc.org/specification) over HTTP. + +Interaction with wireless interfaces occurs primarily through the [wpactrl crate](https://docs.rs/wpactrl/0.3.1/wpactrl/) which provides "a pure-Rust lowlevel library for controlling wpasupplicant remotely". This approach is akin to using `wpa_cli` (a WPA command line client). + +_Note: This module is a work-in-progress._ + +### JSON-RPC API + +| Method | Parameters | Description | +| --- | --- | --- | +| `activate_ap` | | Activate WiFi access point (stop `wpa_supplicant` and start `hostapd` and `dnsmasq`) | +| `activate_client` | | Activate WiFi client connection (stop `hostapd` and `dnsmasq` and start `wpa_supplicant`) | +| `add_wifi` | `ssid`, `pass` | Connect to WiFi with given SSID and password | +| `get_ip` | `iface` | Return IP of given network interface | +| `get_rssi` | `iface` | Return average signal strength for given interface | +| `get_ssid` | `iface` | Return SSID of currently-connected network for given interface | +| `get_state` | `iface` | Return state of given interface | +| `get_traffic` | `iface` | Return network traffic for given interface | +| `if_checker` | | Run AP / client-mode configuration script | +| `list_networks` | | List all networks saved in wpasupplicant config | +| `ping` | | Respond with `success` if microservice is running | +| `scan_networks` | `iface` | List all networks in range of given interface | +| `reconnect_wifi` | `iface` | Disconnect and reconnect given interface | +| `reassociate_wifi` | `iface` | Reassociate with current AP for given interface | + +### File Tree + +``` +. +├── Cargo.lock +├── Cargo.toml +├── README.md +├── src +│ ├── error.rs // custom NetworkError type & From implementations +│ ├── lib.rs // RPC server, methods & tests +│ ├── main.rs // init logger, call run() & catch application errors +│ └── network.rs // logic for network methods exposed via RPC +``` + +### Setup + +Clone this repo: + +`git clone https://github.com/peachcloud/peach-network.git` + +Move into the repo and compile: + +`cd peach-network` +`cargo build --release` + +Run the binary (sudo needed to satisfy permission requirements): + +`sudo ./target/release/peach-network` + +### Environment + +The JSON-RPC HTTP server address and port can be configured with the `PEACH_NETWORK_SERVER` environment variable: + +`export PEACH_NETWORK_SERVER=127.0.0.1:5000` + +When not set, the value defaults to `127.0.0.1:5110`. + +Logging is made available with `env_logger`: + +`export RUST_LOG=info` + +Other logging levels include `debug`, `warn` and `error`. + +### Example Usage + +**Retrieve IP address for wlan0** + +With microservice running, open a second terminal window and use `curl` to call server methods: + +`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "get_ip", "params" : {"iface": "wlan0" }, "id":1 }' 127.0.0.1:5000` + +Server responds with: + +`{"jsonrpc":"2.0","result":"192.168.1.21","id":1}` + +**Retrieve SSID of connected access point for wlan1** + +`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "get_ssid", "params" : {"iface": "wlan1" }, "id":1 }' 127.0.0.1:5000` + +Server response when interface is connected: + +`{"jsonrpc":"2.0","result":"Home","id":1}` + +Server response when interface is not connected: + +`{"jsonrpc":"2.0","error":{"code":-32003,"message":"Failed to retrieve SSID for wlan1. Interface may not be connected."},"id":1}` + +**Retrieve list of SSIDs for all networks in range of wlan0** + +`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "scan_networks", "params" : {"iface": "wlan0" }, "id":1 }' 127.0.0.1:5000` + +Server response when interface is connected: + +`{"jsonrpc":"2.0","result":"[\"Home\",\"TP-LINK_254700\"]","id":1}` + +Server response when interface is not connected: + +`{"jsonrpc":"2.0","error":{"code":-32006,"message":"No networks found in range of wlan0"},"id":1}` + +**Retrieve network traffic statistics for wlan1** + +`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "get_traffic", "params" : {"iface": "wlan1" }, "id":1 }' 127.0.0.1:5000` + +Server response if interface exists: + +`{"jsonrpc":"2.0","result":"{\"received\":26396361,\"transmitted\":22352530}","id":1}` + +Server response when interface is not found: + +`{"jsonrpc":"2.0","error":{"code":-32004,"message":"Failed to retrieve network traffic for wlan3. Interface may not be connected"},"id":1}` + +### Licensing + +AGPL-3.0 diff --git a/src/chapter_3_2_4.md b/src/chapter_3_2_4.md new file mode 100644 index 0000000..877c702 --- /dev/null +++ b/src/chapter_3_2_4.md @@ -0,0 +1,144 @@ +# peach-oled + +[![Build Status](https://travis-ci.com/peachcloud/peach-oled.svg?branch=master)](https://travis-ci.com/peachcloud/peach-oled) + +OLED microservice module for PeachCloud. Write to a 128x64 OLED display with SDD1306 driver (I2C) using [JSON-RPC](https://www.jsonrpc.org/specification) over HTTP. + +### JSON-RPC API + +| Method | Parameters | Description | +| --- | --- | --- | +| `clear` | | Clear the display buffer | +| `draw` | `bytes`, `width`, `height`, `x_coord`, `y_coord` | Draw graphic to display buffer for given byte array, dimensions and co-ordinates | +| `flush` | | Flush the display | +| `ping` | | Respond with `success` if microservice is running | +| `write` | `x_coord`, `y_coord`, `string`, `font_size` | Write message to display buffer for given co-ordinates using given font size | + +`peach-oled` allows text to be written with the following font sizes: + +| Font Sizes | +| --- | +| `6x8` | +| `6x12` | +| `8x16` | +| `12x16` | + +### File Tree + +``` +. +├── Cargo.lock +├── Cargo.toml +├── docs +│ └── images +│ └── peachcloud_oled.jpg +├── README.md +├── src +│ ├── error.rs // custom OledError type & From implementations +│ ├── lib.rs // RPC server, methods & tests (includes OLED logic) +│ └── main.rs // init logger, call run() & catch application errors +``` + +### Setup + +Clone this repo: + +`git clone https://github.com/peachcloud/peach-oled.git` + +Move into the repo and compile: + +`cd peach-oled` +`cargo build --release` + +Run the binary: + +`./target/release/peach-oled` + +### Environment + +The JSON-RPC HTTP server address and port can be configured with the `PEACH_OLED_SERVER` environment variable: + +`export PEACH_OLED_SERVER=127.0.0.1:5000` + +When not set, the value defaults to `127.0.0.1:5112`. + +Logging is made available with `env_logger`: + +`export RUST_LOG=info` + +Other logging levels include `debug`, `warn` and `error`. + +### Example Usage + +**Write Text to the OLED Display** + +With microservice running, open a second terminal window and use `curl` to call server methods: + +`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "write", "params" : {"x_coord": 0, "y_coord": 0, "string": "Welcome to PeachCloud", "font_size": "6x8" }, "id":1 }' 127.0.0.1:5112` + +Server responds with: + +`{"jsonrpc":"2.0","result":success","id":1}` + +OLED will remain blank because no flush command has been issued. + +Write to the second line of the display: + +`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "write", "params" : {"x_coord": 0, "y_coord": 8, "string": "Born in cypherspace", "font_size": "6x12" }, "id":1 }' 127.0.0.1:5112` + +Flush the display: + +`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "flush", "id":1 }' 127.0.0.1:5112` + +OLED display shows: + +`Welcome to PeachCloud!` +`Born in cypherspace` + +Validation checks are performed for all three parameters: `x_coord`, `y_coord` and `string`. An appropriate error is returned if the validation checks are not satisfied: + +`{"jsonrpc":"2.0","error":{"code":1,"message":"Validation error: coordinate x out of range 0-128: 129."},"id":1}` + +`{"jsonrpc":"2.0","error":{"code":1,"message":"validation error","data":"y_coord not in range 0-57"},"id":1}` + +`{"jsonrpc":"2.0","error":{"code":1,"message":"Validation error: string length 47 out of range 0-21."},"id":1}` + +An error is returned if one or all of the expected parameters are not supplied: + +`{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params: missing field `font_size`."},"id":1}` + +----- + +**Draw Graphic to the OLED Display** + +With microservice running, open a second terminal window and use `curl` to call server methods: + +`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "draw", "params" : {"bytes": [30, 0, 33, 0, 64, 128, 128, 64, 140, 64, 140, 64, 128, 64, 64, 128, 33, 0, 30, 0], "width": 10, "height": 10, "x_coord": 32, "y_coord": 32}, "id":1 }' 127.0.0.1:5112` + +Server responds with: + +`{"jsonrpc":"2.0","result":success","id":1}` + +OLED will remain blank because no flush command has been issued. + +Flush the display: + +`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "flush", "id":1 }' 127.0.0.1:5112` + +OLED display shows a 10x10 graphic of a dot inside a circle. + +No validation checks are currently performed on the parameters of the `draw` RPC, aside from type-checks when the parameters are parsed. + +----- + +**Clear the Display** + +`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "clear", "id":1 }' 127.0.0.1:5112` + +Server responds with: + +`{"jsonrpc":"2,0","result":"success","id":1}` + +### Licensing + +AGPL-3.0 diff --git a/src/chapter_3_2_5.md b/src/chapter_3_2_5.md new file mode 100644 index 0000000..fc7e762 --- /dev/null +++ b/src/chapter_3_2_5.md @@ -0,0 +1,87 @@ +# peach-stats + +[![Build Status](https://travis-ci.com/peachcloud/peach-stats.svg?branch=master)](https://travis-ci.com/peachcloud/peach-stats) + +System statistics microservice module for PeachCloud. Provides a JSON-RPC wrapper around the [probes](https://crates.io/crates/probes) and [systemstat](https://crates.io/crates/systemstat) crates. + +### JSON-API + +| Method | Description | Returns | +| --- | --- | --- | +| `cpu_stats` | CPU statistics | `user`, `system`, `nice`, `idle` | +| `cpu_stats_percent` | CPU statistics as percentages | `user`, `system`, `nice`, `idle` | +| `disk_usage` | Disk usage statistics (array of disks) | `filesystem`, `one_k_blocks`, `one_k_blocks_used`, `one_k_blocks_free`, `used_percentage`, `mountpoint` | +| `load_average` | Load average statistics | `one`, `five`, `fifteen` | +| `mem_stats` | Memory statistics | `total`, `free`, `used` | +| `uptime` | System uptime | `secs`, `nanos` | + +### File Tree + +``` +. +├── Cargo.lock +├── Cargo.toml +├── README.md +└── src + ├── error.rs // custom StatError type & From implementations + ├── lib.rs // RPC server, methods & tests + ├── main.rs // init logger, call run() & catch application errors + ├── stats.rs // logic for stats methods exposed via RPC + └── structs.rs // data types for stats +``` + +### Setup + +Clone this repo: + +`git clone https://github.com/peachcloud/peach-stats.git` + +Move into the repo and compile a release build: + +`cd peach-stats` +`cargo build --release` + +Run the binary: + +`./target/release/peach-stats` + +### Environment + +The JSON-RPC HTTP server address and port can be configured with the `PEACH_STATS_SERVER` environment variable: + +`export PEACH_STATS_SERVER=127.0.0.1:5000` + +When not set, the value defaults to `127.0.0.1:5113`. + +Logging is made available with `env_logger`: + +`export RUST_LOG=info` + +Other logging levels include `debug`, `warn` and `error`. + +### Example Usage + +**Get CPU Statistics** + +With microservice running, open a second terminal window and use `curl` to call server methods: + +`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "cpu_stats", "id":1 }' 127.0.0.1:5113` + +Server responds with: + +`{"jsonrpc":"2.0","result":"{\"user\":4661083,\"system\":1240371,\"idle\":326838290,\"nice\":0}","id":1}` + +**Get System Uptime** + +With microservice running, open a second terminal window and use `curl` to call server methods: + +`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "uptime", "id":1 }' 127.0.0.1:5113` + +Server responds with: + +`{"jsonrpc":"2.0","result":"{\"secs\":840968,\"nanos\":0}","id":1}` + +### Licensing + +AGPL-3.0 +