Skip to content

Commit

Permalink
Update README + Documentations
Browse files Browse the repository at this point in the history
  • Loading branch information
Thai Dinh Le authored and Thai Dinh Le committed Jun 6, 2021
1 parent dadea35 commit 81ce0ce
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 181 deletions.
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@ The ad hoc library supports the following operations:
- Broadcast data in plain-text to all directly connected neighbors
- Broadcast encrypted data to all directly connected neighbors
- Revoke its certificate (private key compromised)
- Create a secure group in the ad hoc network
- Join an existing secure group in the ad hoc network
- Leave an existing secure group in the ad hoc network
- Create a secure group
- Join an existing secure group
- Leave an existing secure group
- Send encrypted data to an existing secure group
- Provides notifications of specific events related to the library (e.g., connection established, or data received)

## Application Example

See example.
## example

- [Source code](example)

An example showing how to use the library APIs.
24 changes: 19 additions & 5 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class _AdHocMusicClientState extends State<AdHocMusicClient> {
static const PLAYLIST = 0;
static const REQUEST = 1;
static const REPLY = 2;
static const TRANSFER = 3;

static const NONE = 'none';

Expand All @@ -37,17 +38,17 @@ class _AdHocMusicClientState extends State<AdHocMusicClient> {
final List<Pair<String, String>> _playlist = List.empty(growable: true);
final HashMap<String, HashMap<String, PlatformFile>> _globalPlaylist = HashMap();
final HashMap<String, PlatformFile> _localPlaylist = HashMap();
final HashMap<String, bool> _isTransfering = HashMap();
final Set<String> timestamps = <String>{};

// bool _peerRequest = false;
bool _requested = false;
bool _display = false;
String _selected = NONE;

@override
void initState() {
super.initState();
_manager.enableBle(3600);
// _manager.enableBle(3600);
_manager.eventStream.listen(_processAdHocEvent);
_manager.open = true;
}
Expand Down Expand Up @@ -311,6 +312,7 @@ class _AdHocMusicClientState extends State<AdHocMusicClient> {
PlatformFile file;

if (_localPlaylist.containsKey(name)) {
found = true;
bytes = _localPlaylist[name].bytes;
} else {
for (final entry in _globalPlaylist.entries) {
Expand All @@ -332,6 +334,13 @@ class _AdHocMusicClientState extends State<AdHocMusicClient> {
break;
} else {
var message = HashMap<String, dynamic>();
message = HashMap<String, dynamic>();
message.putIfAbsent('type', () => TRANSFER);
message.putIfAbsent('name', () => name);
_manager.sendMessageTo(message, peer.label);

message.clear();

message.putIfAbsent('type', () => REPLY);
message.putIfAbsent('name', () => name);
message.putIfAbsent('song', () => bytes);
Expand All @@ -341,7 +350,6 @@ class _AdHocMusicClientState extends State<AdHocMusicClient> {
break;

case REPLY:
print(data);
var name = data['name'] as String;
var song = Uint8List.fromList((data['song'] as List<dynamic>).cast<int>());

Expand All @@ -360,6 +368,11 @@ class _AdHocMusicClientState extends State<AdHocMusicClient> {
setState(() => _requested = false);
break;

case TRANSFER:
var name = data['name'] as String;
_isTransfering.putIfAbsent(name, () => true);
break;

default:
}
}
Expand Down Expand Up @@ -434,9 +447,10 @@ class _AdHocMusicClientState extends State<AdHocMusicClient> {
_manager.broadcast(message);

setState(() => _requested = true);
_isTransfering.putIfAbsent(_selected, () => false);

Timer(Duration(seconds: 450), () {
if (_requested == true) {
Timer(Duration(seconds: 30), () {
if (_requested == true && _isTransfering[_selected] == false) {
_manager.sendMessageTo(message, peerName);
}
});
Expand Down
13 changes: 11 additions & 2 deletions lib/src/appframework/transfer_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -425,15 +425,24 @@ class TransferManager {
break;

case INTERNAL_EXCEPTION:
data = event.payload as Object;
data = event.payload as Exception;

_controller.add(Event(AdHocType.onInternalException, data: data));
break;

case GROUP_STATUS:
data = event.payload as int;

_controller.add(Event(AdHocType.onGroupInfo, data: data));
break;

case GROUP_KEY_UPDATED:
case GROUP_DATA:
var payload = event.payload as List<dynamic>;

device = payload.first as AdHocDevice;
data = payload.last as Object;

_controller.add(Event(AdHocType.onGroupDataReceived, device: device, data: data));
break;

default:
Expand Down
3 changes: 2 additions & 1 deletion lib/src/network/aodv/aodv_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import 'package:adhoc_plugin/src/network/exceptions/aodv_unknown_dest.dart';
import 'package:adhoc_plugin/src/network/exceptions/aodv_unknown_type.dart';
import 'package:adhoc_plugin/src/presentation/certificate_repository.dart';
import 'package:adhoc_plugin/src/presentation/constants.dart';
import 'package:flutter/foundation.dart';


/// Class representing the core of the AODV protocol. It manages all the
Expand Down Expand Up @@ -170,7 +171,7 @@ class AodvManager {
}

if (display) {
print(buffer.toString());
debugPrint(buffer.toString());
}
}

Expand Down
1 change: 0 additions & 1 deletion lib/src/network/datalinkmanager/wrapper_ble.dart
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,6 @@ class WrapperBle extends WrapperNetwork {
///
/// The [message] represents a message send through the network.
void _processMsgReceived(final MessageAdHoc message) {
print(message.toString());
switch (message.header.messageType) {
case CONNECT_SERVER:
// Recover this own node MAC and BLE address
Expand Down
2 changes: 0 additions & 2 deletions lib/src/network/datalinkmanager/wrapper_wifi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -380,8 +380,6 @@ class WrapperWifi extends WrapperNetwork {
///
/// The [message] represents a message send through the network.
void _processMsgReceived(MessageAdHoc message) async {
print(message.toString());

switch (message.header.messageType) {
case CONNECT_SERVER:
// Save the mapping of remote IP address with its remote MAC address
Expand Down
65 changes: 11 additions & 54 deletions lib/src/presentation/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,57 +22,14 @@ const CERT_REP = 305; // Reply to certificate request
const CERT_REVOCATION = 306; // Certificate revocation notification

// Constants for group management
const GROUP_PROBE = 307; // Group probe
const GROUP_STATUS = 308; // Group status notification
const GROUP_LEAVE = 309; // Group left notification
const GROUP_JOIN = 3010; // Group join notification
const GROUP_KEY_UPDATED = 311; // Group key update notification

// Probe duration
const NET_DELAY = 3000; // 3 minutes

enum CryptoTask {
/// Isoalte initialisation
initialisation,

/// Encryption tag
encryption,

/// Decryption tag
decryption,

/// Group encryption & decryption tag
group_data,
}

enum SecureGroup {
/// Group key computation
key,

/// Group formation initiation
init,

/// Group formation reply
reply,

/// List of group member's label
list,

/// Public Diffie-Hellman share received
share,

/// Group join notification
join,

/// Group join request to leader
join_req,

/// Group join reply of leader
join_rep,

/// Group leave notification
leave,

/// Group data
data
}
const GROUP_STATUS = 307;
const GROUP_LEAVE = 308;
const GROUP_JOIN = 309;
const GROUP_KEY = 310;
const GROUP_INIT = 311;
const GROUP_REPLY = 312;
const GROUP_LIST = 313;
const GROUP_SHARE = 314;
const GROUP_JOIN_REQ = 315;
const GROUP_JOIN_REP = 316;
const GROUP_DATA = 318;
40 changes: 13 additions & 27 deletions lib/src/presentation/crypto_engine.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class CryptoEngine {
/// Initializes internal parameters.
Future<void> initialize() async {
_stream.listen((reply) {
if (reply.rep == CryptoTask.initialisation) {
if (reply.rep == INITIALISATION) {
_sendPorts[reply.data[0] as int] = reply.data[1] as SendPort;
}
});
Expand All @@ -62,11 +62,7 @@ class CryptoEngine {

// Create and initialize a RSA key generator
final keyGen = RSAKeyGenerator()
..init(
ParametersWithRandom(RSAKeyGeneratorParameters(BigInt.parse('65537'), bitLength, 64),
_random(),
),
);
..init(ParametersWithRandom(RSAKeyGeneratorParameters(BigInt.parse('65537'), bitLength, 64), _random()));

// Generate the pair of key
final pair = keyGen.generateKeyPair();
Expand All @@ -87,21 +83,15 @@ class CryptoEngine {
/// performed.
///
/// Returns the encrypted data as a list of dynamic objects.
Future<List<dynamic>> encrypt(
Uint8List data, {RSAPublicKey? publicKey, crypto.SecretKey? sharedKey}
) {
Future<List<dynamic>> encrypt(Uint8List data, {RSAPublicKey? publicKey, crypto.SecretKey? sharedKey}) {
Completer completer = Completer<List<dynamic>>();

// Send request to encryption isolate
if (publicKey != null) {
_sendPorts[ENCRYPTION]!.send(Request(CryptoTask.encryption, data, publicKey: publicKey));
} else {
_sendPorts[ENCRYPTION]!.send(Request(CryptoTask.group_data, data, sharedKey: sharedKey));
}
_sendPorts[ENCRYPTION]!.send(Request(data, publicKey: publicKey, sharedKey: sharedKey));

// Listen to the reply of the encryption isolate
_stream.listen((reply) {
if (reply.rep == CryptoTask.encryption) {
if (reply.rep == ENCRYPTION) {
try {
completer.complete(reply.data as List<dynamic>);
} catch (exception) {}
Expand All @@ -124,15 +114,11 @@ class CryptoEngine {
Completer completer = Completer<Uint8List>();

// Send request to decryption isolate
if (sharedKey == null) {
_sendPorts[DECRYPTION]!.send(Request(CryptoTask.decryption, data, privateKey: _privateKey));
} else {
_sendPorts[DECRYPTION]!.send(Request(CryptoTask.group_data, data, sharedKey: sharedKey));
}
_sendPorts[DECRYPTION]!.send(Request(data, privateKey: _privateKey, sharedKey: sharedKey));

// Listen to the reply of the decryption isolate
_stream.listen((reply) {
if (reply.rep == CryptoTask.decryption) {
if (reply.rep == DECRYPTION) {
try {
completer.complete(Uint8List.fromList((reply.data as List<dynamic>).cast<int>()));
} catch (exception) {}
Expand Down Expand Up @@ -209,7 +195,7 @@ class CryptoEngine {
/// The [port] is used to communicate with the isolate.
void processEncryption(SendPort port) {
var _receivePort = ReceivePort();
port.send(Reply(CryptoTask.initialisation, [ENCRYPTION, _receivePort.sendPort]));
port.send(Reply(INITIALISATION, [ENCRYPTION, _receivePort.sendPort]));

final algorithm = crypto.Chacha20.poly1305Aead();

Expand All @@ -219,7 +205,7 @@ void processEncryption(SendPort port) {

_receivePort.listen((request) async {
var req = request as Request;
if (req.req == CryptoTask.encryption) {
if (req.sharedKey == null) {
encryptor = OAEPEncoding(RSAEngine())
..init(true, PublicKeyParameter<RSAPublicKey>(request.publicKey!));

Expand All @@ -239,7 +225,7 @@ void processEncryption(SendPort port) {
reply[SECRET_KEY] = encryptedKey;
reply[SECRET_DATA] = secretBox.concatenation();

port.send(Reply(CryptoTask.encryption, reply));
port.send(Reply(ENCRYPTION, reply));
});
}

Expand All @@ -248,7 +234,7 @@ void processEncryption(SendPort port) {
/// The [port] is used to communicate with the isolate.
void processDecryption(SendPort port) {
var _receivePort = ReceivePort();
port.send(Reply(CryptoTask.initialisation, [DECRYPTION, _receivePort.sendPort]));
port.send(Reply(INITIALISATION, [DECRYPTION, _receivePort.sendPort]));

final algorithm = crypto.Chacha20.poly1305Aead();

Expand All @@ -259,7 +245,7 @@ void processDecryption(SendPort port) {
var req = request as Request;
var reply = request.data as List<dynamic>;

if (req.req == CryptoTask.decryption) {
if (req.sharedKey == null) {
decryptor = OAEPEncoding(RSAEngine())
..init(false, PrivateKeyParameter<RSAPrivateKey>(request.privateKey!));

Expand All @@ -285,7 +271,7 @@ void processDecryption(SendPort port) {
await algorithm.decrypt(secretBox, secretKey: secretKey),
);

port.send(Reply(CryptoTask.decryption, decrypted));
port.send(Reply(DECRYPTION, decrypted));
});
}

Expand Down
8 changes: 2 additions & 6 deletions lib/src/presentation/presentation_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -235,18 +235,14 @@ class PresentationManager {

_groupController.eventStream.listen((event) {
switch (event.type) {
case DATA_RECEIVED: // TODO: change to group data?
_controller.add(event);
case DATA_RECEIVED:
_controller.add(event..type = GROUP_DATA);
break;

case GROUP_STATUS:
_controller.add(event);
break;

case GROUP_KEY_UPDATED:
_controller.add(event);
break;

default:
}
});
Expand Down
6 changes: 2 additions & 4 deletions lib/src/presentation/reply.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import 'package:adhoc_plugin/src/presentation/constants.dart';

/// Class representing the reply of the encryption/decryption isolate to a
/// request of encryption/decryption.
class Reply {
Object data;
CryptoTask rep;
final int rep;
final Object data;

/// Creates a [Reply] object.
///
Expand Down
Loading

0 comments on commit 81ce0ce

Please sign in to comment.