11//
2- // This source file is part of the LCLPing open source project
2+ // This source file is part of the LCL open source project
33//
44// Copyright (c) 2021-2024 Local Connectivity Lab and the project authors
55// Licensed under Apache License v2.0
1313import Foundation
1414import ArgumentParser
1515import LCLPing
16- import LCLPingAuth
16+ import LCLAuth
1717import Crypto
1818
1919extension LCLCLI {
@@ -26,29 +26,32 @@ extension LCLCLI {
2626
2727 func run( ) async throws {
2828 let encoder : JSONEncoder = JSONEncoder ( )
29- var sites : [ CellularSite ]
30- let result : Result < [ CellularSite ] ? , CLIError > = await NetworkingAPI . get ( from: NetworkingAPI . Endpoint. site. url)
31- switch result {
32- case . failure( let error) :
33- throw error
34- case . success( let cs) :
35- if let s = cs {
36- sites = s
37- } else {
38- throw CLIError . failedToLoadContent ( " No cellular site is available. Please check your internet connection or talk to the SCN administrator. " )
39- }
40-
41- }
42- var picker = Picker < CellularSite > ( title: " Choose the cellular site you are currently at. " , options: sites)
29+
30+ // var sites: [CellularSite]
31+ // let result: Result<[CellularSite]?, CLIError> = await NetworkingAPI.get(from: NetworkingAPI.Endpoint.site.url)
32+ // switch result {
33+ // case .failure(let error):
34+ // throw error
35+ // case .success(let cs):
36+ // if let s = cs {
37+ // sites = s
38+ // } else {
39+ // throw CLIError.failedToLoadContent("No cellular site is available. Please check your internet connection or talk to the SCN administrator.")
40+ // }
41+
42+ // }
43+ // var picker = Picker<CellularSite>(title: "Choose the cellular site you are currently at.", options: sites)
4344
4445 let homeURL = FileIO . default. home. appendingPathComponent ( " .lcl " )
4546 let skURL = homeURL. appendingPathComponent ( " sk " )
4647 let sigURL = homeURL. appendingPathComponent ( " sig " )
4748 let rURL = homeURL. appendingPathComponent ( " r " )
4849 let hpkrURL = homeURL. appendingPathComponent ( " hpkr " )
4950 let keyURL = homeURL. appendingPathComponent ( " key " )
50-
5151 let keyData = try loadData ( keyURL)
52+
53+ let symmetricKeyRecovered = SymmetricKey ( data: keyData)
54+
5255 let symmetricKey = SymmetricKey ( data: keyData)
5356 let skDataEncrypted = try loadData ( skURL)
5457 let skData = try decrypt ( cipher: skDataEncrypted, key: symmetricKey)
@@ -62,87 +65,89 @@ extension LCLCLI {
6265 let validationResultJSON = try encoder. encode ( ValidationResult ( R: rData, skT: skData, hPKR: hpkrData) )
6366 let ecPrivateKey = try ECDSA . deserializePrivateKey ( raw: skData)
6467
65- guard try ECDSA . verify ( message: validationResultJSON, signature: sigData, publicKey: ecPrivateKey. publicKey) else {
66- throw CLIError . contentCorrupted
67- }
68-
69- let pingOptions = LCLPing . Options ( )
70- let pingConfig = LCLPing . PingConfiguration ( type: . icmp, endpoint: . ipv4( " google.com " , 0 ) )
71- let outputFormats : Set < OutputFormat > = [ . default]
72-
73- var ping = LCLPing ( options: pingOptions)
74- let speedTest = SpeedTest ( testType: . downloadAndUpload)
75-
76- signal ( SIGINT, SIG_IGN)
77- let stopSignal = DispatchSource . makeSignalSource ( signal: SIGINT, queue: . main)
78- stopSignal. setEventHandler {
79- print ( " Exit from SCN Measurement Test " )
80- picker. exit ( )
81- ping. stop ( )
82- speedTest. stop ( )
83- return
84- }
85-
86- stopSignal. resume ( )
87-
88- guard let selectedSite = picker. pick ( ) else {
89- throw CLIError . noCellularSiteSelected
90- }
91-
92- let deviceId = UUID ( ) . uuidString
93-
94- var isPingComplete : Bool = false
95- try await ping. start ( pingConfiguration: pingConfig)
96- switch ping. status {
97- case . error, . ready, . running:
98- print ( " Ping Test encountered some error while running tests " )
99- case . stopped, . finished:
100- isPingComplete = true
101- }
102-
103- let speedTestResults = try await speedTest. run ( )
104- let downloadSummary = prepareSpeedTestSummary ( data: speedTestResults. download, unit: . Mbps)
105- let uploadSummary = prepareSpeedTestSummary ( data: speedTestResults. upload, unit: . Mbps)
106- if isPingComplete {
107- generatePingSummary ( ping. summary, for: . icmp, formats: outputFormats)
108- }
109- generateSpeedTestSummary ( downloadSummary, kind: . download, formats: outputFormats, unit: . Mbps)
110- generateSpeedTestSummary ( uploadSummary, kind: . upload, formats: outputFormats, unit: . Mbps)
111-
112- // MARK: Upload test results to the server
113- encoder. outputFormatting = . prettyPrinted
114- do {
115- let report = ConnectivityReportModel (
116- cellId: selectedSite. cellId. first!,
117- deviceId: deviceId,
118- downloadSpeed: downloadSummary. avg,
119- uploadSpeed: uploadSummary. avg,
120- latitude: selectedSite. latitude,
121- longitude: selectedSite. longitude,
122- packetLoss: Double ( ping. summary. timeout. count) / Double( ping. summary. totalCount) ,
123- ping: ping. summary. avg,
124- timestamp: Date . getCurrentTime ( ) ,
125- jitter: ping. summary. jitter
126- )
127- let serialized = try encoder. encode ( report)
128- let sig_m = try ECDSA . sign ( message: serialized, privateKey: ECDSA . deserializePrivateKey ( raw: skData) )
129- let measurementReport = MeasurementReportModel ( sigmaM: sig_m. hex, hPKR: hpkrData. hex, M: serialized. hex, showData: showData)
130-
131- let reportToSent = try encoder. encode ( measurementReport)
132- let result = await NetworkingAPI . send ( to: NetworkingAPI . Endpoint. report. url, using: reportToSent)
133- switch result {
134- case . success:
135- print ( " Data reported successfully. " )
136- case . failure( let error) :
137- print ( " Data report failed with error: \( error) " )
138- }
139- } catch EncodingError . invalidValue {
140- print ( " Measurement data is corruptted. " )
141- } catch let error as LCLPingAuthError {
142- print ( " Registration info is corruptted. \( error) " )
143- } catch {
144- print ( " Data report failed with error: \( error) " )
145- }
68+ // guard try ECDSA.verify(message: validationResultJSON, signature: sigData, publicKey: ecPrivateKey.publicKey) else {
69+ // throw CLIError.contentCorrupted
70+ // }
71+
72+ // let pingOptions = LCLPing.Options()
73+ // let pingConfig = LCLPing.PingConfiguration(type: .icmp, endpoint: .ipv4("google.com", 0))
74+ // let outputFormats: Set<OutputFormat> = [.default]
75+
76+ // var ping = LCLPing(options: pingOptions)
77+ // let speedTest = SpeedTest(testType: .downloadAndUpload)
78+
79+ // signal(SIGINT, SIG_IGN)
80+ // let stopSignal = DispatchSource.makeSignalSource(signal: SIGINT, queue: .main)
81+ // stopSignal.setEventHandler {
82+ // print("Exit from SCN Measurement Test")
83+ // // picker.exit()
84+ // ping.stop()
85+ // speedTest.stop()
86+ // return
87+ // }
88+
89+ // stopSignal.resume()
90+
91+ // // guard let selectedSite = picker.pick() else {
92+ // // throw CLIError.noCellularSiteSelected
93+ // // }
94+ // let selectedSite = CellularSite(address: "address", cellId: ["a", "b"], latitude: 1.0, longitude: 2.0, name: "name", status: CellularSite.SiteStatus.active)
95+
96+ // let deviceId = UUID().uuidString
97+
98+ // var isPingComplete: Bool = false
99+ // try await ping.start(pingConfiguration: pingConfig)
100+ // switch ping.status {
101+ // case .error, .ready, .running:
102+ // print("Ping Test encountered some error while running tests")
103+ // case .stopped, .finished:
104+ // isPingComplete = true
105+ // }
106+
107+ // let speedTestResults = try await speedTest.run()
108+ // let downloadSummary = prepareSpeedTestSummary(data: speedTestResults.download, unit: .Mbps)
109+ // let uploadSummary = prepareSpeedTestSummary(data: speedTestResults.upload, unit: .Mbps)
110+ // if isPingComplete {
111+ // generatePingSummary(ping.summary, for: .icmp, formats: outputFormats)
112+ // }
113+ // generateSpeedTestSummary(downloadSummary, kind: .download, formats: outputFormats, unit: .Mbps)
114+ // generateSpeedTestSummary(uploadSummary, kind: .upload, formats: outputFormats, unit: .Mbps)
115+
116+ // // MARK: Upload test results to the server
117+ // encoder.outputFormatting = .prettyPrinted
118+ // do {
119+ // let report = ConnectivityReportModel(
120+ // cellId: selectedSite.cellId.first!,
121+ // deviceId: deviceId,
122+ // downloadSpeed: downloadSummary.avg,
123+ // uploadSpeed: uploadSummary.avg,
124+ // latitude: selectedSite.latitude,
125+ // longitude: selectedSite.longitude,
126+ // packetLoss: Double(ping.summary.timeout.count) / Double(ping.summary.totalCount),
127+ // ping: ping.summary.avg,
128+ // timestamp: Date.getCurrentTime(),
129+ // jitter: ping.summary.jitter
130+ // )
131+ // let serialized = try encoder.encode(report)
132+ // let sig_m = try ECDSA.sign(message: serialized, privateKey: ECDSA.deserializePrivateKey(raw: skData))
133+ // let measurementReport = MeasurementReportModel(sigmaM: sig_m.hex, hPKR: hpkrData.hex, M: serialized.hex, showData: showData)
134+
135+ // let reportToSent = try encoder.encode(measurementReport)
136+ // let result = await NetworkingAPI.send(to: NetworkingAPI.Endpoint.report.url, using: reportToSent)
137+ // switch result {
138+ // case .success:
139+ // print("Data reported successfully.")
140+ // case .failure(let error):
141+ // print("Data report failed with error: \(error)")
142+ // }
143+ print ( " DONE! " )
144+ // } catch EncodingError.invalidValue {
145+ // print("Measurement data is corruptted.")
146+ // } catch let error as LCLAuthError {
147+ // print("Registration info is corruptted. \(error)")
148+ // } catch {
149+ // print("Data report failed with error: \(error)")
150+ // }
146151 }
147152
148153 private func loadData( _ from: URL ) throws -> Data {
@@ -151,5 +156,11 @@ extension LCLCLI {
151156 }
152157 return data
153158 }
159+
160+ private func encryptAndWriteData( _ data: Data , to fileURL: URL , using key: SymmetricKey ) throws {
161+ var data = try LCLAuth . encrypt ( plainText: data, key: key)
162+ try FileIO . default. write ( data: data, to: fileURL)
163+ data. removeAll ( )
164+ }
154165 }
155166}
0 commit comments