Compare commits
No commits in common. "main" and "BTConnectionExperiments" have entirely different histories.
main
...
BTConnecti
22
LICENSE
22
LICENSE
@ -1,22 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2023 Severin Memmishofer
|
|
||||||
Copyright (c) 2023 Sebastian Lenzlinger
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
@ -1,6 +1,2 @@
|
|||||||
# RippleChat
|
# RippleChat
|
||||||
RippleChat is a meant to be a TinySSB compatible chat client. It is started as a university project as a proof of concept for p2p messaging in a Secure Scuttlebut fashion on iOS.
|
2023 © Severin Memmishofer, Sebastian Lenzlinger
|
||||||
At this stage it communicates via BLE.
|
|
||||||
It is not currently compatible with TinySSB conforming apps like [Tremola](https://github.com/cn-uofbasel/tremola).
|
|
||||||
Future work includes switching to the tinySSB protocol and heavily beautifying th UI.
|
|
||||||
|
|
||||||
|
|||||||
@ -15,10 +15,11 @@
|
|||||||
96454F362A558EBE0040BEBD /* RippleChatUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96454F352A558EBE0040BEBD /* RippleChatUITests.swift */; };
|
96454F362A558EBE0040BEBD /* RippleChatUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96454F352A558EBE0040BEBD /* RippleChatUITests.swift */; };
|
||||||
96454F382A558EBE0040BEBD /* RippleChatUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96454F372A558EBE0040BEBD /* RippleChatUITestsLaunchTests.swift */; };
|
96454F382A558EBE0040BEBD /* RippleChatUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96454F372A558EBE0040BEBD /* RippleChatUITestsLaunchTests.swift */; };
|
||||||
96454F452A5593900040BEBD /* .gitignore in Resources */ = {isa = PBXBuildFile; fileRef = 96454F442A5593900040BEBD /* .gitignore */; };
|
96454F452A5593900040BEBD /* .gitignore in Resources */ = {isa = PBXBuildFile; fileRef = 96454F442A5593900040BEBD /* .gitignore */; };
|
||||||
|
96BD330E2A5C254B007A6E53 /* TextApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BD330D2A5C254B007A6E53 /* TextApp.swift */; };
|
||||||
96BD33102A5C27B0007A6E53 /* NewFeedEntryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BD330F2A5C27B0007A6E53 /* NewFeedEntryView.swift */; };
|
96BD33102A5C27B0007A6E53 /* NewFeedEntryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BD330F2A5C27B0007A6E53 /* NewFeedEntryView.swift */; };
|
||||||
96BD33132A5C400B007A6E53 /* FeedListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BD33122A5C400B007A6E53 /* FeedListView.swift */; };
|
96BD33132A5C400B007A6E53 /* FeedListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BD33122A5C400B007A6E53 /* FeedListView.swift */; };
|
||||||
96BD33162A5C403C007A6E53 /* DiscoveryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BD33152A5C403C007A6E53 /* DiscoveryView.swift */; };
|
96BD33162A5C403C007A6E53 /* PeeringView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BD33152A5C403C007A6E53 /* PeeringView.swift */; };
|
||||||
F581F59B2A5AE72F0081C383 /* BTCentral.swift in Sources */ = {isa = PBXBuildFile; fileRef = F581F59A2A5AE72F0081C383 /* BTCentral.swift */; };
|
F581F59B2A5AE72F0081C383 /* BluetoothController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F581F59A2A5AE72F0081C383 /* BluetoothController.swift */; };
|
||||||
F5847B622A599BF4009E28D4 /* Bodyy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5847B612A599BF4009E28D4 /* Bodyy.swift */; };
|
F5847B622A599BF4009E28D4 /* Bodyy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5847B612A599BF4009E28D4 /* Bodyy.swift */; };
|
||||||
F5847B642A599CC3009E28D4 /* LogEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5847B632A599CC3009E28D4 /* LogEntry.swift */; };
|
F5847B642A599CC3009E28D4 /* LogEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5847B632A599CC3009E28D4 /* LogEntry.swift */; };
|
||||||
F5847B662A599EA4009E28D4 /* Feed.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5847B652A599EA4009E28D4 /* Feed.swift */; };
|
F5847B662A599EA4009E28D4 /* Feed.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5847B652A599EA4009E28D4 /* Feed.swift */; };
|
||||||
@ -62,10 +63,11 @@
|
|||||||
96454F352A558EBE0040BEBD /* RippleChatUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RippleChatUITests.swift; sourceTree = "<group>"; };
|
96454F352A558EBE0040BEBD /* RippleChatUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RippleChatUITests.swift; sourceTree = "<group>"; };
|
||||||
96454F372A558EBE0040BEBD /* RippleChatUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RippleChatUITestsLaunchTests.swift; sourceTree = "<group>"; };
|
96454F372A558EBE0040BEBD /* RippleChatUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RippleChatUITestsLaunchTests.swift; sourceTree = "<group>"; };
|
||||||
96454F442A5593900040BEBD /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = "<group>"; };
|
96454F442A5593900040BEBD /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = "<group>"; };
|
||||||
|
96BD330D2A5C254B007A6E53 /* TextApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextApp.swift; sourceTree = "<group>"; };
|
||||||
96BD330F2A5C27B0007A6E53 /* NewFeedEntryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewFeedEntryView.swift; sourceTree = "<group>"; };
|
96BD330F2A5C27B0007A6E53 /* NewFeedEntryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewFeedEntryView.swift; sourceTree = "<group>"; };
|
||||||
96BD33122A5C400B007A6E53 /* FeedListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListView.swift; sourceTree = "<group>"; };
|
96BD33122A5C400B007A6E53 /* FeedListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListView.swift; sourceTree = "<group>"; };
|
||||||
96BD33152A5C403C007A6E53 /* DiscoveryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscoveryView.swift; sourceTree = "<group>"; };
|
96BD33152A5C403C007A6E53 /* PeeringView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeeringView.swift; sourceTree = "<group>"; };
|
||||||
F581F59A2A5AE72F0081C383 /* BTCentral.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTCentral.swift; sourceTree = "<group>"; };
|
F581F59A2A5AE72F0081C383 /* BluetoothController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BluetoothController.swift; sourceTree = "<group>"; };
|
||||||
F5847B612A599BF4009E28D4 /* Bodyy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bodyy.swift; sourceTree = "<group>"; };
|
F5847B612A599BF4009E28D4 /* Bodyy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bodyy.swift; sourceTree = "<group>"; };
|
||||||
F5847B632A599CC3009E28D4 /* LogEntry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogEntry.swift; sourceTree = "<group>"; };
|
F5847B632A599CC3009E28D4 /* LogEntry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogEntry.swift; sourceTree = "<group>"; };
|
||||||
F5847B652A599EA4009E28D4 /* Feed.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Feed.swift; sourceTree = "<group>"; };
|
F5847B652A599EA4009E28D4 /* Feed.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Feed.swift; sourceTree = "<group>"; };
|
||||||
@ -133,7 +135,7 @@
|
|||||||
96454F1A2A558EBC0040BEBD /* RippleChatApp.swift */,
|
96454F1A2A558EBC0040BEBD /* RippleChatApp.swift */,
|
||||||
96454F1C2A558EBC0040BEBD /* ContentView.swift */,
|
96454F1C2A558EBC0040BEBD /* ContentView.swift */,
|
||||||
96BD33112A5C3FFC007A6E53 /* Views */,
|
96BD33112A5C3FFC007A6E53 /* Views */,
|
||||||
F581F59A2A5AE72F0081C383 /* BTCentral.swift */,
|
F581F59A2A5AE72F0081C383 /* BluetoothController.swift */,
|
||||||
F5A4B1222A5D5F8B00F5AE01 /* BTPeripheral.swift */,
|
F5A4B1222A5D5F8B00F5AE01 /* BTPeripheral.swift */,
|
||||||
96454F1E2A558EBD0040BEBD /* Assets.xcassets */,
|
96454F1E2A558EBD0040BEBD /* Assets.xcassets */,
|
||||||
96454F202A558EBD0040BEBD /* Preview Content */,
|
96454F202A558EBD0040BEBD /* Preview Content */,
|
||||||
@ -141,6 +143,7 @@
|
|||||||
F5847B632A599CC3009E28D4 /* LogEntry.swift */,
|
F5847B632A599CC3009E28D4 /* LogEntry.swift */,
|
||||||
F5847B652A599EA4009E28D4 /* Feed.swift */,
|
F5847B652A599EA4009E28D4 /* Feed.swift */,
|
||||||
F5847B692A59AB24009E28D4 /* FeedStore.swift */,
|
F5847B692A59AB24009E28D4 /* FeedStore.swift */,
|
||||||
|
96BD330D2A5C254B007A6E53 /* TextApp.swift */,
|
||||||
F5A4B1242A5D7A8D00F5AE01 /* DataStore.swift */,
|
F5A4B1242A5D7A8D00F5AE01 /* DataStore.swift */,
|
||||||
);
|
);
|
||||||
path = RippleChat;
|
path = RippleChat;
|
||||||
@ -176,7 +179,7 @@
|
|||||||
children = (
|
children = (
|
||||||
96BD330F2A5C27B0007A6E53 /* NewFeedEntryView.swift */,
|
96BD330F2A5C27B0007A6E53 /* NewFeedEntryView.swift */,
|
||||||
96BD33122A5C400B007A6E53 /* FeedListView.swift */,
|
96BD33122A5C400B007A6E53 /* FeedListView.swift */,
|
||||||
96BD33152A5C403C007A6E53 /* DiscoveryView.swift */,
|
96BD33152A5C403C007A6E53 /* PeeringView.swift */,
|
||||||
F5A4B1202A5D4D1F00F5AE01 /* SettingsView.swift */,
|
F5A4B1202A5D4D1F00F5AE01 /* SettingsView.swift */,
|
||||||
F5A4B1262A5D861E00F5AE01 /* SettingsEditView.swift */,
|
F5A4B1262A5D861E00F5AE01 /* SettingsEditView.swift */,
|
||||||
F5F1419B2A5EFA3600C81B1A /* LogEntryView.swift */,
|
F5F1419B2A5EFA3600C81B1A /* LogEntryView.swift */,
|
||||||
@ -319,7 +322,7 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
F5847B622A599BF4009E28D4 /* Bodyy.swift in Sources */,
|
F5847B622A599BF4009E28D4 /* Bodyy.swift in Sources */,
|
||||||
96BD33162A5C403C007A6E53 /* DiscoveryView.swift in Sources */,
|
96BD33162A5C403C007A6E53 /* PeeringView.swift in Sources */,
|
||||||
F5847B662A599EA4009E28D4 /* Feed.swift in Sources */,
|
F5847B662A599EA4009E28D4 /* Feed.swift in Sources */,
|
||||||
96BD33132A5C400B007A6E53 /* FeedListView.swift in Sources */,
|
96BD33132A5C400B007A6E53 /* FeedListView.swift in Sources */,
|
||||||
F5847B642A599CC3009E28D4 /* LogEntry.swift in Sources */,
|
F5847B642A599CC3009E28D4 /* LogEntry.swift in Sources */,
|
||||||
@ -331,9 +334,10 @@
|
|||||||
F5A4B1272A5D861E00F5AE01 /* SettingsEditView.swift in Sources */,
|
F5A4B1272A5D861E00F5AE01 /* SettingsEditView.swift in Sources */,
|
||||||
F59375722A5FF344001FA46A /* FeedDetailView.swift in Sources */,
|
F59375722A5FF344001FA46A /* FeedDetailView.swift in Sources */,
|
||||||
F5F1419E2A5EFA4700C81B1A /* FeedCardView.swift in Sources */,
|
F5F1419E2A5EFA4700C81B1A /* FeedCardView.swift in Sources */,
|
||||||
F581F59B2A5AE72F0081C383 /* BTCentral.swift in Sources */,
|
F581F59B2A5AE72F0081C383 /* BluetoothController.swift in Sources */,
|
||||||
96454F1D2A558EBC0040BEBD /* ContentView.swift in Sources */,
|
96454F1D2A558EBC0040BEBD /* ContentView.swift in Sources */,
|
||||||
F5A4B1212A5D4D1F00F5AE01 /* SettingsView.swift in Sources */,
|
F5A4B1212A5D4D1F00F5AE01 /* SettingsView.swift in Sources */,
|
||||||
|
96BD330E2A5C254B007A6E53 /* TextApp.swift in Sources */,
|
||||||
96454F1B2A558EBC0040BEBD /* RippleChatApp.swift in Sources */,
|
96454F1B2A558EBC0040BEBD /* RippleChatApp.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import CoreBluetooth
|
import CoreBluetooth
|
||||||
|
|
||||||
class BTCentral: NSObject, ObservableObject {
|
class BluetoothController: NSObject, ObservableObject {
|
||||||
private var centralManager: CBCentralManager?
|
private var centralManager: CBCentralManager?
|
||||||
private var peripherals: [CBPeripheral] = []
|
private var peripherals: [CBPeripheral] = []
|
||||||
@Published var peripheralNames: [String] = []
|
@Published var peripheralNames: [String] = []
|
||||||
@ -27,7 +27,7 @@ class BTCentral: NSObject, ObservableObject {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
extension BTCentral: CBCentralManagerDelegate, CBPeripheralDelegate {
|
extension BluetoothController: CBCentralManagerDelegate, CBPeripheralDelegate {
|
||||||
|
|
||||||
func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
||||||
if central.state == .poweredOn {
|
if central.state == .poweredOn {
|
||||||
@ -11,7 +11,7 @@ import CoreBluetooth
|
|||||||
struct ContentView: View {
|
struct ContentView: View {
|
||||||
@State var currentView = 0
|
@State var currentView = 0
|
||||||
@EnvironmentObject var dataStore: DataStore
|
@EnvironmentObject var dataStore: DataStore
|
||||||
@StateObject private var bluetoothController = BTCentral()
|
@StateObject private var bluetoothController = BluetoothController()
|
||||||
@StateObject private var bluetoothPeripheral = BluetoothPeripheral()
|
@StateObject private var bluetoothPeripheral = BluetoothPeripheral()
|
||||||
@Environment(\.scenePhase) private var scenePhase
|
@Environment(\.scenePhase) private var scenePhase
|
||||||
let saveAction: ()->Void
|
let saveAction: ()->Void
|
||||||
@ -20,7 +20,7 @@ struct ContentView: View {
|
|||||||
VStack {
|
VStack {
|
||||||
switch self.currentView {
|
switch self.currentView {
|
||||||
case 0:
|
case 0:
|
||||||
DiscoveryView()
|
PeeringView()
|
||||||
.environmentObject(dataStore)
|
.environmentObject(dataStore)
|
||||||
.environmentObject(bluetoothController)
|
.environmentObject(bluetoothController)
|
||||||
.environmentObject(bluetoothPeripheral)
|
.environmentObject(bluetoothPeripheral)
|
||||||
|
|||||||
@ -7,17 +7,17 @@
|
|||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct DiscoveryView: View {
|
struct PeeringView: View {
|
||||||
@EnvironmentObject var dataStore: DataStore
|
@EnvironmentObject var dataStore: DataStore
|
||||||
@EnvironmentObject var btCentral: BTCentral
|
@EnvironmentObject var btController: BluetoothController
|
||||||
@EnvironmentObject var btPeripheral: BluetoothPeripheral
|
@EnvironmentObject var btPeripheral: BluetoothPeripheral
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
List(btCentral.peripheralNames, id: \.self) { peripheral in
|
List(btController.peripheralNames, id: \.self) { peripheral in
|
||||||
Text(peripheral)
|
Text(peripheral)
|
||||||
}
|
}
|
||||||
.navigationTitle("Peer Discovery")
|
.navigationTitle("Peering")
|
||||||
.navigationViewStyle(StackNavigationViewStyle())
|
.navigationViewStyle(StackNavigationViewStyle())
|
||||||
List {
|
List {
|
||||||
ForEach(btPeripheral.wantVector.friends.keys.sorted(), id: \.self) { friend in
|
ForEach(btPeripheral.wantVector.friends.keys.sorted(), id: \.self) { friend in
|
||||||
@ -34,7 +34,7 @@ struct DiscoveryView: View {
|
|||||||
combinedDict[dataStore.personalFeed.feedID] = dataStore.personalFeed.feed.count
|
combinedDict[dataStore.personalFeed.feedID] = dataStore.personalFeed.feed.count
|
||||||
let WANT_msg = WantMessage(friends: combinedDict)
|
let WANT_msg = WantMessage(friends: combinedDict)
|
||||||
let encoded_msg = try JSONEncoder().encode(WANT_msg)
|
let encoded_msg = try JSONEncoder().encode(WANT_msg)
|
||||||
btCentral.writeToCharacteristics(message: String(data: encoded_msg, encoding: .utf8)!)
|
btController.writeToCharacteristics(message: String(data: encoded_msg, encoding: .utf8)!)
|
||||||
//btController.writeToCharacteristics(message: "Test")
|
//btController.writeToCharacteristics(message: "Test")
|
||||||
print("Pressed Button")
|
print("Pressed Button")
|
||||||
} catch {
|
} catch {
|
||||||
@ -62,11 +62,11 @@ struct DiscoveryView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DiscoveryView_Previews: PreviewProvider {
|
struct PeeringView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
DiscoveryView()
|
PeeringView()
|
||||||
.environmentObject(BluetoothPeripheral())
|
.environmentObject(BluetoothPeripheral())
|
||||||
.environmentObject(BTCentral())
|
.environmentObject(BluetoothController())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user