Skip to content

Commit

Permalink
Merge branch 'develop' into feature/serial-configuring
Browse files Browse the repository at this point in the history
  • Loading branch information
hhvrc committed Oct 5, 2023
2 parents 0e625ba + 9d792dd commit 294ffec
Show file tree
Hide file tree
Showing 26 changed files with 1,131 additions and 308 deletions.
1 change: 0 additions & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@ SpaceBeforeParens: Custom
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: false
AfterFunctionDeclationName: false
AfterIfMacros: false
AfterOverloadedOperator: false
AfterRequiresInClause: false
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -185,5 +185,5 @@ jobs:
with:
name: OpenShock_${{ matrix.board }}
path: OpenShock.${{ matrix.board }}.bin
retention-days: 1
retention-days: 7
if-no-files-found: error
22 changes: 3 additions & 19 deletions WebUI/src/lib/WebSocketClient.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { browser } from "$app/environment";
import { getToastStore } from "@skeletonlabs/skeleton";
import { WiFiStateStore } from "./stores";
import type { WiFiNetwork } from "./types/WiFiNetwork";
import { WebSocketMessageHandler } from "./WebSocketMessageHandler";

export enum ConnectionState {
DISCONNECTED = 0,
Expand Down Expand Up @@ -134,22 +132,8 @@ export class WebSocketClient {
return;
}

if (message.networks !== undefined) {
WiFiStateStore.setNetworks(message.networks as WiFiNetwork[]);
return;
}

if (message.scanning !== undefined) {
const toastStore = getToastStore();
if (message.scanning) {
toastStore.trigger({ message: 'Scanning for WiFi networks...', background: 'bg-blue-500' });
} else {
toastStore.trigger({ message: 'Scanning for WiFi networks finished', background: 'bg-green-500' });
}

WiFiStateStore.setScanning(message.scanning as boolean);
return;
}
// Handle message
WebSocketMessageHandler(message);
}
private AbortWebSocket() {
if (this._socket) {
Expand Down
112 changes: 112 additions & 0 deletions WebUI/src/lib/WebSocketMessageHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { WebSocketClient } from './WebSocketClient';
import { WiFiStateStore } from './stores';
import type { WiFiNetwork } from './types/WiFiNetwork';

interface InvalidMessage {
type: undefined | null;
}

interface PoggiesMessage {
type: 'poggies';
}

interface WiFiScanStartedMessage {
type: 'wifi';
subject: 'scan';
status: 'started';
}

interface WiFiScanDiscoveryMessage {
type: 'wifi';
subject: 'scan';
status: 'discovery';
data: WiFiNetwork;
}

interface WiFiScanCompletedMessage {
type: 'wifi';
subject: 'scan';
status: 'completed';
}

interface WiFiScanErrorMessage {
type: 'wifi';
subject: 'scan';
status: 'error';
}

export type WiFiScanMessage = WiFiScanStartedMessage | WiFiScanDiscoveryMessage | WiFiScanCompletedMessage | WiFiScanErrorMessage;
export type WiFiMessage = WiFiScanMessage;
export type WebSocketMessage = InvalidMessage | PoggiesMessage | WiFiMessage;

export function WebSocketMessageHandler(message: WebSocketMessage) {
const type = message.type;
if (!type) {
console.warn('[WS] Received invalid message: ', message);
return;
}

switch (type) {
case 'poggies':
handlePoggiesMessage();
break;
case 'wifi':
handleWiFiMessage(message);
break;
default:
console.warn('[WS] Received invalid message: ', message);
return;
}
}

function handlePoggiesMessage() {
WebSocketClient.Instance.Send('{ "type": "wifi", "action": "scan", "run": true }');
}

function handleWiFiMessage(message: WiFiMessage) {
switch (message.subject) {
case 'scan':
handleWiFiScanMessage(message);
break;
default:
console.warn('[WS] Received invalid wifi message: ', message);
return;
}
}

function handleWiFiScanMessage(message: WiFiScanMessage) {
switch (message.status) {
case 'started':
handleWiFiScanStartedMessage();
break;
case 'discovery':
handleWiFiScanDiscoveryMessage(message);
break;
case 'completed':
handleWiFiScanCompletedMessage();
break;
case 'error':
handleWiFiScanErrorMessage(message);
break;
default:
console.warn('[WS] Received invalid scan message: ', message);
return;
}
}

function handleWiFiScanStartedMessage() {
WiFiStateStore.setScanning(true);
}

function handleWiFiScanDiscoveryMessage(message: WiFiScanDiscoveryMessage) {
WiFiStateStore.addNetwork(message.data);
}

function handleWiFiScanCompletedMessage() {
WiFiStateStore.setScanning(false);
}

function handleWiFiScanErrorMessage(message: WiFiScanErrorMessage) {
console.error('[WS] Received WiFi scan error message: ', message);
WiFiStateStore.setScanning(false);
}
79 changes: 42 additions & 37 deletions WebUI/src/lib/components/WiFiList.svelte
Original file line number Diff line number Diff line change
@@ -1,57 +1,58 @@
<script lang="ts">
import { getModalStore } from '@skeletonlabs/skeleton';
import WiFiInfo from '$lib/components/modals/WiFiInfo.svelte';
import type { WiFiNetwork } from '$lib/types/WiFiNetwork';
import { WiFiStateStore } from '$lib/stores';
import { WebSocketClient } from '$lib/WebSocketClient';
import { getModalStore } from '@skeletonlabs/skeleton';
import WiFiInfo from '$lib/components/modals/WiFiDetails.svelte';
import type { WiFiNetwork } from '$lib/types/WiFiNetwork';
import { WiFiStateStore } from '$lib/stores';
import { WebSocketClient } from '$lib/WebSocketClient';
const modalStore = getModalStore();
let connectedIndex = -1;
let connectedBSSID: string | null = null;
function wifiScan() {
WebSocketClient.Instance.Send('{ "type": "startScan" }');
if ($WiFiStateStore.scanning) {
WebSocketClient.Instance.Send('{ "type": "wifi", "action": "scan", "run": false }');
} else {
WebSocketClient.Instance.Send('{ "type": "wifi", "action": "scan", "run": true }');
}
}
function wifiPair(item: WiFiNetwork) {
/*
modalStore.trigger({
type: 'prompt',
title: 'Enter password',
body: 'Enter the password for the network',
value: '',
valueAttr: { type: 'password', minlength: 1, maxlength: 32, required: true },
response: (r: string) => {
let index = items.findIndex(i => i.id === item.id);
items[index].saved = true;
}
});
*/
function wifiAuthenticate(item: WiFiNetwork) {
if (item.security !== 'Open') {
modalStore.trigger({
type: 'prompt',
title: 'Enter password',
body: 'Enter the password for the network',
value: '',
valueAttr: { type: 'password', minlength: 1, maxlength: 63, required: true },
response: (password: string) => {
WebSocketClient.Instance.Send(`{ "type": "wifi", "action": "authenticate", "bssid": "${item.bssid}", "password": "${password}" }`);
},
});
} else {
WebSocketClient.Instance.Send(`{ "type": "wifi", "action": "authenticate", "bssid": "${item.bssid}" }`);
}
}
function wifiConnect(item: WiFiNetwork) {
console.log("wifiConnect", item);
connectedIndex = item.index;
WebSocketClient.Instance.Send(`{ "type": "wifi", "action": "connect", "bssid": "${item.bssid}" }`);
}
function wifiDisconnect(item: WiFiNetwork) {
if (connectedIndex !== item.index) return;
console.log("wifiDisconnect", item);
connectedIndex = -1;
WebSocketClient.Instance.Send(`{ "type": "wifi", "action": "disconnect", "bssid": "${item.bssid}" }`);
}
function wifiSettings(item: WiFiNetwork) {
modalStore.trigger({
type: 'component',
component: {
ref: WiFiInfo,
props: { bssid: item.bssid },
slot: '<p>Skeleton</p>'
},
});
}
</script>

<div>
<div class="flex justify-between items-center mb-2">
<h3 class="h3">Configure WiFi</h3>
<button class="btn variant-outline" on:click={wifiScan} disabled={$WiFiStateStore.scanning}>
<h3 class="h3">Configure WiFi</h3>
<button class="btn variant-outline" on:click={wifiScan}>
{#if $WiFiStateStore.scanning}
<i class="fa fa-spinner fa-spin"></i>
{:else}
Expand All @@ -60,23 +61,27 @@
</button>
</div>
<div class="max-h-64 overflow-auto">
{#each $WiFiStateStore.networks as item (item.index)}
{#each Object.values($WiFiStateStore.networks) as item (item.bssid)}
<div class="card mb-2 p-2 flex justify-between items-center">
<span>
{#if item.index === connectedIndex}
<i class="fa fa-wifi text-green-500"/>
{#if item.bssid === connectedBSSID}
<i class="fa fa-wifi text-green-500" />
{:else}
<i class="fa fa-wifi" />
{/if}
{#if item.ssid}
<span class="ml-2">{item.ssid}</span>
{:else}
<i class="fa fa-wifi"/>
<span class="ml-2">{item.bssid}</span><span class="text-gray-500 ml-1">(Hidden)</span>
{/if}
{item.ssid}
</span>
<div class="btn-group variant-outline">
{#if item.saved}
<button on:click={() => wifiConnect(item)}><i class="fa fa-arrow-right text-green-500"/></button>
<button on:click={() => wifiConnect(item)}><i class="fa fa-arrow-right text-green-500" /></button>
{:else}
<button on:click={() => wifiPair(item)}><i class="fa fa-link text-green-500"/></button>
<button on:click={() => wifiAuthenticate(item)}><i class="fa fa-link text-green-500" /></button>
{/if}
<button on:click={() => wifiSettings(item)}><i class="fa fa-cog"/></button>
<button on:click={() => wifiSettings(item)}><i class="fa fa-cog" /></button>
</div>
</div>
{/each}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
<script lang="ts">
import { WiFiStateStore } from "$lib/stores";
import { getModalStore } from "@skeletonlabs/skeleton";
import { WiFiStateStore } from '$lib/stores';
import { getModalStore } from '@skeletonlabs/skeleton';
export let bssid: string;
const modalStore = getModalStore();
$: item = $WiFiStateStore.networks.find(i => i.bssid === bssid);
$: item = $WiFiStateStore.networks[bssid];
$: rows = item ? [
{ key: 'SSID', value: item.ssid },
{ key: 'BSSID', value: item.bssid },
{ key: 'Channel', value: item.channel },
{ key: 'RSSI', value: item.rssi },
{ key: 'Secure', value: item.secure },
{ key: 'Saved', value: item.saved },
] : [];
$: rows = item
? [
{ key: 'SSID', value: item.ssid },
{ key: 'BSSID', value: item.bssid },
{ key: 'Channel', value: item.channel },
{ key: 'RSSI', value: item.rssi },
{ key: 'Security', value: item.security },
{ key: 'Saved', value: item.saved },
]
: [];
</script>

<div class="card p-4 w-[24rem] flex-col space-y-4">
Expand All @@ -32,7 +34,7 @@
<div class="flex justify-end space-x-2">
<div class="btn-group variant-outline">
{#if item.saved}
<button on:click={() => modalStore.close()}><i class="fa fa-wifi mr-2 text-green-500"></i>Connect</button>
<button on:click={() => modalStore.close()}><i class="fa fa-wifi mr-2 text-green-500"></i>Connect</button>
<button on:click={() => modalStore.close()}><i class="fa fa-trash mr-2 text-red-500"></i>Forget</button>
{:else}
<button on:click={() => modalStore.close()}><i class="fa fa-link mr-2 text-green-500"></i>Connect</button>
Expand Down
9 changes: 4 additions & 5 deletions WebUI/src/lib/stores/WiFiStateStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { writable } from 'svelte/store';
const { subscribe, update } = writable<WiFiState>({
initialized: false,
scanning: false,
networks: [],
networks: {},
});

export const WiFiStateStore = {
Expand All @@ -22,16 +22,15 @@ export const WiFiStateStore = {
return store;
});
},
setNetworks(networks: WiFiNetwork[]) {
addNetwork(network: WiFiNetwork) {
update((store) => {
store.scanning = false;
store.networks = networks;
store.networks[network.bssid] = network;
return store;
});
},
clearNetworks() {
update((store) => {
store.networks = [];
store.networks = {};
return store;
});
},
Expand Down
3 changes: 1 addition & 2 deletions WebUI/src/lib/types/WiFiNetwork.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
export type WiFiNetwork = {
index: number;
ssid: string;
bssid: string;
rssi: number;
channel: number;
secure: boolean;
security: 'Open' | 'WEP' | 'WPA PSK' | 'WPA2 PSK' | 'WPA/WPA2 PSK' | 'WPA2 Enterprise' | 'WPA3 PSK' | 'WPA2/WPA3 PSK' | 'WAPI PSK' | null;
saved: boolean;
};
4 changes: 2 additions & 2 deletions WebUI/src/lib/types/WiFiState.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { WiFiNetwork } from "./WiFiNetwork";
import type { WiFiNetwork } from './WiFiNetwork';

export type WiFiState = {
initialized: boolean;
scanning: boolean;
networks: WiFiNetwork[];
networks: { [bssid: string]: WiFiNetwork };
};
5 changes: 3 additions & 2 deletions include/AuthenticationManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
#include <cstdint>

namespace OpenShock::AuthenticationManager {
bool Authenticate(unsigned int pairCode);
bool IsPaired();
bool Pair(unsigned int pairCode);
void UnPair();

bool IsAuthenticated();
String GetAuthToken();
void ClearAuthToken();
} // namespace OpenShock::AuthenticationManager
Loading

0 comments on commit 294ffec

Please sign in to comment.