mirror of
https://github.com/esiur/esiur-dart.git
synced 2025-06-27 14:53:11 +00:00
1.0
This commit is contained in:
2466
bin/Net/IIP/DistributedConnection.dart
Normal file
2466
bin/Net/IIP/DistributedConnection.dart
Normal file
File diff suppressed because it is too large
Load Diff
18
bin/Net/IIP/DistributedPropertyContext.dart
Normal file
18
bin/Net/IIP/DistributedPropertyContext.dart
Normal file
@ -0,0 +1,18 @@
|
||||
import 'DistributedConnection.dart';
|
||||
class DistributedPropertyContext
|
||||
{
|
||||
dynamic value;
|
||||
DistributedConnection connection;
|
||||
dynamic Function(DistributedConnection) method;
|
||||
|
||||
|
||||
DistributedPropertyContext(this.method)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DistributedPropertyContext.setter(this.value, this.connection)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
300
bin/Net/IIP/DistributedResource.dart
Normal file
300
bin/Net/IIP/DistributedResource.dart
Normal file
@ -0,0 +1,300 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2019 Ahmed Kh. Zamil
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
import '../../Resource/IResource.dart';
|
||||
import '../../Core/AsyncReply.dart';
|
||||
import '../../Data/PropertyValue.dart';
|
||||
import '../../Data/Structure.dart';
|
||||
import '../../Data/Codec.dart';
|
||||
import './DistributedConnection.dart';
|
||||
import '../Packets/IIPPacketAction.dart';
|
||||
|
||||
class DistributedResource extends IResource
|
||||
{
|
||||
|
||||
int _instanceId;
|
||||
DistributedConnection _connection;
|
||||
|
||||
|
||||
bool _isAttached = false;
|
||||
bool _isReady = false;
|
||||
|
||||
|
||||
|
||||
String _link;
|
||||
List _properties;
|
||||
|
||||
|
||||
bool _destroyed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Connection responsible for the distributed resource.
|
||||
/// </summary>
|
||||
DistributedConnection get connection => _connection;
|
||||
|
||||
/// <summary>
|
||||
/// Resource link
|
||||
/// </summary>
|
||||
String get link => _link;
|
||||
|
||||
/// <summary>
|
||||
/// Instance Id given by the other end.
|
||||
/// </summary>
|
||||
int get id => _instanceId;
|
||||
|
||||
/// <summary>
|
||||
/// IDestructible interface.
|
||||
/// </summary>
|
||||
void destroy()
|
||||
{
|
||||
_destroyed = true;
|
||||
emitArgs("destroy", [this]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resource is ready when all its properties are attached.
|
||||
/// </summary>
|
||||
bool get isReady => _isReady;
|
||||
|
||||
/// <summary>
|
||||
/// Resource is attached when all its properties are received.
|
||||
/// </summary>
|
||||
bool get IsAttached => _isAttached;
|
||||
|
||||
|
||||
// public DistributedResourceStack Stack
|
||||
//{
|
||||
// get { return stack; }
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new distributed resource.
|
||||
/// </summary>
|
||||
/// <param name="connection">Connection responsible for the distributed resource.</param>
|
||||
/// <param name="template">Resource template.</param>
|
||||
/// <param name="instanceId">Instance Id given by the other end.</param>
|
||||
/// <param name="age">Resource age.</param>
|
||||
DistributedResource(DistributedConnection connection, int instanceId, int age, String link)
|
||||
{
|
||||
this._link = link;
|
||||
this._connection = connection;
|
||||
this._instanceId = instanceId;
|
||||
}
|
||||
|
||||
void _ready()
|
||||
{
|
||||
_isReady = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Export all properties with ResourceProperty attributed as bytes array.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<PropertyValue> serialize()
|
||||
{
|
||||
|
||||
var props = new List<PropertyValue>(_properties.length);
|
||||
|
||||
|
||||
for (var i = 0; i < _properties.length; i++)
|
||||
props[i] = new PropertyValue(_properties[i], instance.getAge(i), instance.getModificationDate(i));
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
bool attached(List<PropertyValue> properties)
|
||||
{
|
||||
if (_isAttached)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
_properties = new List(properties.length);// object[properties.Length];
|
||||
|
||||
//_events = new DistributedResourceEvent[Instance.Template.Events.Length];
|
||||
|
||||
for (var i = 0; i < properties.length; i++)
|
||||
{
|
||||
instance.setAge(i, properties[i].age);
|
||||
instance.setModificationDate(i, properties[i].date);
|
||||
_properties[i] = properties[i].value;
|
||||
}
|
||||
|
||||
// trigger holded events/property updates.
|
||||
//foreach (var r in afterAttachmentTriggers)
|
||||
// r.Key.Trigger(r.Value);
|
||||
|
||||
//afterAttachmentTriggers.Clear();
|
||||
|
||||
_isAttached = true;
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void emitEventByIndex(int index, List<dynamic> args)
|
||||
{
|
||||
var et = instance.template.getEventTemplateByIndex(index);
|
||||
//events[index]?.Invoke(this, args);
|
||||
emitArgs(et.name, args);
|
||||
|
||||
instance.emitResourceEvent(null, null, et.name, args);
|
||||
}
|
||||
|
||||
AsyncReply<dynamic> invokeByNamedArguments(int index, Structure namedArgs)
|
||||
{
|
||||
if (_destroyed)
|
||||
throw new Exception("Trying to access destroyed object");
|
||||
|
||||
if (index >= instance.template.functions.length)
|
||||
throw new Exception("Function index is incorrect");
|
||||
|
||||
|
||||
return connection.sendInvokeByNamedArguments(_instanceId, index, namedArgs);
|
||||
}
|
||||
|
||||
AsyncReply<dynamic> invokeByArrayArguments(int index, List<dynamic> args)
|
||||
{
|
||||
if (_destroyed)
|
||||
throw new Exception("Trying to access destroyed object");
|
||||
|
||||
if (index >= instance.template.functions.length)
|
||||
throw new Exception("Function index is incorrect");
|
||||
|
||||
|
||||
return connection.sendInvokeByArrayArguments(_instanceId, index, args);
|
||||
}
|
||||
|
||||
|
||||
String _getMemberName(Symbol symbol)
|
||||
{
|
||||
var memberName = symbol.toString();
|
||||
if (memberName.endsWith("=\")"))
|
||||
return memberName.substring(8, memberName.length - 3);
|
||||
else
|
||||
return memberName.substring(8, memberName.length - 2);
|
||||
}
|
||||
|
||||
@override //overring noSuchMethod
|
||||
noSuchMethod(Invocation invocation)
|
||||
{
|
||||
var memberName = _getMemberName(invocation.memberName);
|
||||
|
||||
if (invocation.isMethod)
|
||||
{
|
||||
var ft = instance.template.getFunctionTemplateByName(memberName);
|
||||
|
||||
if (_isAttached && ft!=null)
|
||||
{
|
||||
if (invocation.namedArguments.length > 0)
|
||||
{
|
||||
var namedArgs = new Structure();
|
||||
for(var p in invocation.namedArguments.keys)
|
||||
namedArgs[_getMemberName(p)] = invocation.namedArguments[p];
|
||||
|
||||
return invokeByNamedArguments(ft.index, namedArgs);
|
||||
}
|
||||
else
|
||||
{
|
||||
return invokeByArrayArguments(ft.index, invocation.positionalArguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (invocation.isSetter)
|
||||
{
|
||||
var pt = instance.template.getPropertyTemplateByName(memberName);
|
||||
|
||||
if (pt != null)
|
||||
{
|
||||
set(pt.index, invocation.positionalArguments[0]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (invocation.isGetter)
|
||||
{
|
||||
|
||||
var pt = instance.template.getPropertyTemplateByName(memberName);
|
||||
|
||||
if (pt != null)
|
||||
{
|
||||
return get(pt.index);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get a property value.
|
||||
/// </summary>
|
||||
/// <param name="index">Zero-based property index.</param>
|
||||
/// <returns>Value</returns>
|
||||
get(int index)
|
||||
{
|
||||
if (index >= _properties.length)
|
||||
return null;
|
||||
return _properties[index];
|
||||
}
|
||||
|
||||
|
||||
void updatePropertyByIndex(int index, dynamic value)
|
||||
{
|
||||
var pt = instance.template.getPropertyTemplateByIndex(index);
|
||||
_properties[index] = value;
|
||||
instance.emitModification(pt, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set property value.
|
||||
/// </summary>
|
||||
/// <param name="index">Zero-based property index.</param>
|
||||
/// <param name="value">Value</param>
|
||||
/// <returns>Indicator when the property is set.</returns>
|
||||
AsyncReply<dynamic> set(int index, dynamic value)
|
||||
{
|
||||
if (index >= _properties.length)
|
||||
return null;
|
||||
|
||||
var reply = new AsyncReply<dynamic>();
|
||||
|
||||
var parameters = Codec.compose(value, connection);
|
||||
connection.sendRequest(IIPPacketAction.SetProperty)
|
||||
.addUint32(_instanceId)
|
||||
.addUint8(index)
|
||||
.addDC(parameters)
|
||||
.done()
|
||||
.then((res)
|
||||
{
|
||||
// not really needed, server will always send property modified,
|
||||
// this only happens if the programmer forgot to emit in property setter
|
||||
_properties[index] = value;
|
||||
reply.trigger(null);
|
||||
});
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
||||
}
|
39
bin/Net/IIP/DistributedResourceQueueItem.dart
Normal file
39
bin/Net/IIP/DistributedResourceQueueItem.dart
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2019 Ahmed Kh. Zamil
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
import 'DistributedResourceQueueItemType.dart';
|
||||
import 'DistributedResource.dart';
|
||||
|
||||
class DistributedResourceQueueItem
|
||||
{
|
||||
final DistributedResourceQueueItemType type;
|
||||
final int index;
|
||||
final dynamic value;
|
||||
final DistributedResource resource;
|
||||
|
||||
DistributedResourceQueueItem(this.resource, this.type, this.value, this.index)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
5
bin/Net/IIP/DistributedResourceQueueItemType.dart
Normal file
5
bin/Net/IIP/DistributedResourceQueueItemType.dart
Normal file
@ -0,0 +1,5 @@
|
||||
enum DistributedResourceQueueItemType
|
||||
{
|
||||
Propery,
|
||||
Event
|
||||
}
|
134
bin/Net/NetworkBuffer.dart
Normal file
134
bin/Net/NetworkBuffer.dart
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2019 Ahmed Kh. Zamil
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
import '../Data/DC.dart';
|
||||
import 'dart:core';
|
||||
|
||||
class NetworkBuffer
|
||||
{
|
||||
DC _data;
|
||||
|
||||
int _neededDataLength = 0;
|
||||
|
||||
NetworkBuffer()
|
||||
{
|
||||
_data = new DC(0);
|
||||
}
|
||||
|
||||
bool get protected => _neededDataLength > _data.length;
|
||||
|
||||
int get available => _data.length;
|
||||
|
||||
|
||||
|
||||
void holdForNextWrite(DC src, int offset, int size)
|
||||
{
|
||||
holdFor(src, offset, size, size + 1);
|
||||
}
|
||||
|
||||
|
||||
void holdFor(DC src, int offset, int size, int needed)
|
||||
{
|
||||
//lock (syncLock)
|
||||
//{
|
||||
if (size >= needed)
|
||||
throw new Exception("Size >= Needed !");
|
||||
|
||||
//trim = true;
|
||||
_data = DC.combine(src, offset, size, _data, 0, _data.length);
|
||||
_neededDataLength = needed;
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
void holdForNeeded(DC src, int needed)
|
||||
{
|
||||
holdFor(src, 0, src.length, needed);
|
||||
}
|
||||
|
||||
bool protect(DC data, int offset, int needed)
|
||||
{
|
||||
int dataLength = _data.length - offset;
|
||||
|
||||
// protection
|
||||
if (dataLength < needed)
|
||||
{
|
||||
holdFor(data, offset, dataLength, needed);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void write(DC src, int offset, int length)
|
||||
{
|
||||
//lock(syncLock)
|
||||
_data.append(src, offset, length);
|
||||
}
|
||||
|
||||
bool get canRead
|
||||
{
|
||||
if (_data.length == 0)
|
||||
return false;
|
||||
if (_data.length < _neededDataLength)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DC read()
|
||||
{
|
||||
//lock (syncLock)
|
||||
//{
|
||||
if (_data.length == 0)
|
||||
return null;
|
||||
|
||||
DC rt = null;
|
||||
|
||||
if (_neededDataLength == 0)
|
||||
{
|
||||
rt = _data;
|
||||
_data = new DC(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_data.length >= _neededDataLength)
|
||||
{
|
||||
rt = _data;
|
||||
_data = new DC(0);
|
||||
_neededDataLength = 0;
|
||||
return rt;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
//}
|
||||
|
||||
return rt;
|
||||
}
|
||||
}
|
198
bin/Net/NetworkConnection.dart
Normal file
198
bin/Net/NetworkConnection.dart
Normal file
@ -0,0 +1,198 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2019 Ahmed Kh. Zamil
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
import '../Core/IDestructible.dart';
|
||||
import 'Sockets/ISocket.dart';
|
||||
import 'Sockets/SocketState.dart';
|
||||
import 'NetworkBuffer.dart';
|
||||
import '../Data/DC.dart';
|
||||
import 'Sockets/IPEndPoint.dart';
|
||||
|
||||
class NetworkConnection extends IDestructible
|
||||
{
|
||||
ISocket _sock;
|
||||
|
||||
DateTime _lastAction;
|
||||
|
||||
//public delegate void DataReceivedEvent(NetworkConnection sender, NetworkBuffer data);
|
||||
//public delegate void ConnectionClosedEvent(NetworkConnection sender);
|
||||
//public delegate void ConnectionEstablishedEvent(NetworkConnection sender);
|
||||
|
||||
//public event ConnectionEstablishedEvent OnConnect;
|
||||
//public event DataReceivedEvent OnDataReceived;
|
||||
//public event ConnectionClosedEvent OnClose;
|
||||
//public event DestroyedEvent OnDestroy;
|
||||
//object receivingLock = new object();
|
||||
|
||||
bool _processing = false;
|
||||
|
||||
|
||||
void destroy()
|
||||
{
|
||||
// if (connected)
|
||||
close();
|
||||
emitArgs("close", [this]);
|
||||
//OnDestroy?.Invoke(this);
|
||||
}
|
||||
|
||||
NetworkConnection()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
ISocket get socket => _sock;
|
||||
|
||||
void assign(ISocket socket)
|
||||
{
|
||||
_lastAction = DateTime.now();
|
||||
_sock = socket;
|
||||
|
||||
socket.on("receive", socket_OnReceive);
|
||||
socket.on("close", socket_OnClose);
|
||||
socket.on("connect", socket_OnConnect);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void socket_OnConnect()
|
||||
{
|
||||
emitArgs("connect", [this]);
|
||||
}
|
||||
|
||||
void socket_OnClose()
|
||||
{
|
||||
emitArgs("close", [this]);
|
||||
}
|
||||
|
||||
void socket_OnReceive(NetworkBuffer buffer)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Unassigned ?
|
||||
if (_sock == null)
|
||||
return;
|
||||
|
||||
// Closed ?
|
||||
if (_sock.state == SocketState.Closed || _sock.state == SocketState.Terminated) // || !connected)
|
||||
return;
|
||||
|
||||
_lastAction = DateTime.now();
|
||||
|
||||
if (!_processing)
|
||||
{
|
||||
_processing = true;
|
||||
|
||||
try
|
||||
{
|
||||
while (buffer.available > 0 && !buffer.protected)
|
||||
dataReceived(buffer);
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
_processing = false;
|
||||
}
|
||||
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
//Global.Log("NetworkConnection", LogType.Warning, ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
ISocket unassign()
|
||||
{
|
||||
if (_sock != null)
|
||||
{
|
||||
// connected = false;
|
||||
_sock.off("close", socket_OnClose);
|
||||
_sock.off("connect", socket_OnConnect);
|
||||
_sock.off("receive", socket_OnReceive);
|
||||
|
||||
var rt = _sock;
|
||||
_sock = null;
|
||||
|
||||
return rt;
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
void dataReceived(NetworkBuffer data)
|
||||
{
|
||||
emitArgs("dataReceived", [data]);
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
if (_sock != null)
|
||||
_sock.close();
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
//Global.Log("NetworkConenction:Close", LogType.Error, ex.ToString());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
DateTime get lastAction => _lastAction;
|
||||
|
||||
|
||||
IPEndPoint get remoteEndPoint => _sock?.remoteEndPoint;
|
||||
|
||||
IPEndPoint get localEndPoint => _sock?.localEndPoint;
|
||||
|
||||
bool get connected => _sock.state == SocketState.Established;
|
||||
|
||||
|
||||
void send(DC msg)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
if (_sock != null)
|
||||
{
|
||||
_lastAction = DateTime.now();
|
||||
_sock.send(msg);
|
||||
}
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
//Console.WriteLine(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
void sendString(String data)
|
||||
{
|
||||
send(DC.stringToBytes(data));
|
||||
}
|
||||
}
|
278
bin/Net/Packets/IIPAuthPacket.dart
Normal file
278
bin/Net/Packets/IIPAuthPacket.dart
Normal file
@ -0,0 +1,278 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2019 Ahmed Kh. Zamil
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
import '../../Data/DC.dart';
|
||||
import 'IIPAuthPacketAction.dart';
|
||||
import 'IIPAuthPacketCommand.dart';
|
||||
import 'IIPAuthPacketMethod.dart';
|
||||
|
||||
class IIPAuthPacket
|
||||
{
|
||||
|
||||
int command;
|
||||
int action;
|
||||
|
||||
int errorCode;
|
||||
String errorMessage;
|
||||
|
||||
int localMethod;
|
||||
|
||||
DC sourceInfo;
|
||||
|
||||
DC hash;
|
||||
|
||||
DC sessionId;
|
||||
|
||||
int remoteMethod;
|
||||
|
||||
String domain;
|
||||
|
||||
int certificateId;
|
||||
|
||||
String localUsername;
|
||||
|
||||
String remoteUsername;
|
||||
|
||||
DC localPassword;
|
||||
|
||||
DC remotePassword;
|
||||
|
||||
DC localToken;
|
||||
|
||||
DC remoteToken;
|
||||
|
||||
DC asymetricEncryptionKey;
|
||||
|
||||
DC localNonce;
|
||||
|
||||
DC remoteNonce;
|
||||
|
||||
int _dataLengthNeeded;
|
||||
|
||||
bool _notEnough(int offset, int ends, int needed)
|
||||
{
|
||||
if (offset + needed > ends)
|
||||
{
|
||||
_dataLengthNeeded = needed - (ends - offset);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
toString()
|
||||
{
|
||||
return command.toString() + " " + action.toString();
|
||||
}
|
||||
|
||||
int parse(DC data, int offset, int ends)
|
||||
{
|
||||
var oOffset = offset;
|
||||
|
||||
if (_notEnough(offset, ends, 1))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
command = (data[offset] >> 6);
|
||||
|
||||
if (command == IIPAuthPacketCommand.Action)
|
||||
{
|
||||
action = (data[offset++] & 0x3f);
|
||||
|
||||
if (action == IIPAuthPacketAction.AuthenticateHash)
|
||||
{
|
||||
if (_notEnough(offset, ends, 32))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
hash = data.clip(offset, 32);
|
||||
|
||||
//var hash = new byte[32];
|
||||
//Buffer.BlockCopy(data, (int)offset, hash, 0, 32);
|
||||
//Hash = hash;
|
||||
|
||||
offset += 32;
|
||||
}
|
||||
else if (action == IIPAuthPacketAction.NewConnection)
|
||||
{
|
||||
if (_notEnough(offset, ends, 2))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
var length = data.getUint16(offset);
|
||||
|
||||
offset += 2;
|
||||
|
||||
if (_notEnough(offset, ends, length))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
sourceInfo = data.clip(offset, length);
|
||||
|
||||
//var sourceInfo = new byte[length];
|
||||
//Buffer.BlockCopy(data, (int)offset, sourceInfo, 0, length);
|
||||
//SourceInfo = sourceInfo;
|
||||
|
||||
offset += 32;
|
||||
}
|
||||
else if (action == IIPAuthPacketAction.ResumeConnection
|
||||
|| action == IIPAuthPacketAction.ConnectionEstablished)
|
||||
{
|
||||
//var sessionId = new byte[32];
|
||||
|
||||
if (_notEnough(offset, ends, 32))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
sessionId = data.clip(offset, 32);
|
||||
|
||||
//Buffer.BlockCopy(data, (int)offset, sessionId, 0, 32);
|
||||
//SessionId = sessionId;
|
||||
|
||||
offset += 32;
|
||||
}
|
||||
}
|
||||
else if (command == IIPAuthPacketCommand.Declare)
|
||||
{
|
||||
remoteMethod = ((data[offset] >> 4) & 0x3);
|
||||
localMethod = ((data[offset] >> 2) & 0x3);
|
||||
var encrypt = ((data[offset++] & 0x2) == 0x2);
|
||||
|
||||
|
||||
if (_notEnough(offset, ends, 1))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
var domainLength = data[offset++];
|
||||
if (_notEnough(offset, ends, domainLength))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
var domain = data.getString(offset, domainLength);
|
||||
|
||||
this.domain = domain;
|
||||
|
||||
offset += domainLength;
|
||||
|
||||
|
||||
if (remoteMethod == IIPAuthPacketMethod.Credentials)
|
||||
{
|
||||
if (localMethod == IIPAuthPacketMethod.None)
|
||||
{
|
||||
if (_notEnough(offset, ends, 33))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
|
||||
remoteNonce = data.clip(offset, 32);
|
||||
|
||||
offset += 32;
|
||||
|
||||
var length = data[offset++];
|
||||
|
||||
if (_notEnough(offset, ends, length))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
remoteUsername = data.getString(offset, length);
|
||||
|
||||
|
||||
offset += length;
|
||||
}
|
||||
}
|
||||
|
||||
if (encrypt)
|
||||
{
|
||||
if (_notEnough(offset, ends, 2))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
var keyLength = data.getUint16(offset);
|
||||
|
||||
offset += 2;
|
||||
|
||||
if (_notEnough(offset, ends, keyLength))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
|
||||
asymetricEncryptionKey = data.clip(offset, keyLength);
|
||||
|
||||
offset += keyLength;
|
||||
}
|
||||
}
|
||||
else if (command == IIPAuthPacketCommand.Acknowledge)
|
||||
{
|
||||
remoteMethod = ((data[offset] >> 4) & 0x3);
|
||||
localMethod = ((data[offset] >> 2) & 0x3);
|
||||
var encrypt = ((data[offset++] & 0x2) == 0x2);
|
||||
|
||||
if (_notEnough(offset, ends, 1))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
|
||||
if (remoteMethod == IIPAuthPacketMethod.Credentials)
|
||||
{
|
||||
if (localMethod == IIPAuthPacketMethod.None)
|
||||
{
|
||||
if (_notEnough(offset, ends, 32))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
remoteNonce = data.clip(offset, 32);
|
||||
offset += 32;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (encrypt)
|
||||
{
|
||||
if (_notEnough(offset, ends, 2))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
var keyLength = data.getUint16(offset);
|
||||
|
||||
offset += 2;
|
||||
|
||||
if (_notEnough(offset, ends, keyLength))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
asymetricEncryptionKey = data.clip(offset, keyLength);
|
||||
|
||||
offset += keyLength;
|
||||
}
|
||||
}
|
||||
else if (command == IIPAuthPacketCommand.Error)
|
||||
{
|
||||
if (_notEnough(offset, ends, 4))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
offset++;
|
||||
errorCode = data[offset++];
|
||||
|
||||
|
||||
var cl = data.getUint16(offset);
|
||||
offset += 2;
|
||||
|
||||
if (_notEnough(offset, ends, cl))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
errorMessage = data.getString(offset, cl);
|
||||
offset += cl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
return offset - oOffset;
|
||||
|
||||
}
|
||||
|
||||
}
|
16
bin/Net/Packets/IIPAuthPacketAction.dart
Normal file
16
bin/Net/Packets/IIPAuthPacketAction.dart
Normal file
@ -0,0 +1,16 @@
|
||||
class IIPAuthPacketAction
|
||||
{
|
||||
// Authenticate
|
||||
static const int AuthenticateHash = 0;
|
||||
|
||||
|
||||
//Challenge,
|
||||
//CertificateRequest,
|
||||
//CertificateReply,
|
||||
//EstablishRequest,
|
||||
//EstablishReply
|
||||
|
||||
static const int NewConnection = 0x20;
|
||||
static const int ResumeConnection = 0x21;
|
||||
static const int ConnectionEstablished = 0x28;
|
||||
}
|
7
bin/Net/Packets/IIPAuthPacketCommand.dart
Normal file
7
bin/Net/Packets/IIPAuthPacketCommand.dart
Normal file
@ -0,0 +1,7 @@
|
||||
class IIPAuthPacketCommand
|
||||
{
|
||||
static const int Action = 0;
|
||||
static const int Declare = 1;
|
||||
static const int Acknowledge = 2;
|
||||
static const int Error = 3;
|
||||
}
|
8
bin/Net/Packets/IIPAuthPacketMethod.dart
Normal file
8
bin/Net/Packets/IIPAuthPacketMethod.dart
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
class IIPAuthPacketMethod
|
||||
{
|
||||
static const int None = 0;
|
||||
static const int Certificate = 1;
|
||||
static const int Credentials = 2;
|
||||
static const int Token = 3;
|
||||
}
|
727
bin/Net/Packets/IIPPacket.dart
Normal file
727
bin/Net/Packets/IIPPacket.dart
Normal file
@ -0,0 +1,727 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2019 Ahmed Kh. Zamil
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
import '../../Data/DC.dart';
|
||||
import '../../Data/Guid.dart';
|
||||
|
||||
import 'IIPPacketAction.dart';
|
||||
import 'IIPPacketCommand.dart';
|
||||
import 'IIPPacketEvent.dart';
|
||||
import 'IIPPacketReport.dart';
|
||||
import '../../Data/Codec.dart';
|
||||
import '../../Data/DataType.dart';
|
||||
|
||||
class IIPPacket
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int report;
|
||||
|
||||
int command;
|
||||
|
||||
int action;
|
||||
|
||||
int event;
|
||||
|
||||
int previousCommand;
|
||||
|
||||
|
||||
int previousAction;
|
||||
|
||||
int previousEvent;
|
||||
|
||||
|
||||
int resourceId;
|
||||
int newResourceId;
|
||||
|
||||
int childId;
|
||||
int storeId;
|
||||
|
||||
int resourceAge;
|
||||
DC content;
|
||||
int errorCode;
|
||||
String errorMessage;
|
||||
String className ;
|
||||
String resourceLink ;
|
||||
Guid classId ;
|
||||
int methodIndex ;
|
||||
String methodName;
|
||||
int callbackId ;
|
||||
int progressValue;
|
||||
int progressMax ;
|
||||
DateTime fromDate ;
|
||||
DateTime toDate;
|
||||
int fromAge;
|
||||
int toAge;
|
||||
|
||||
int _dataLengthNeeded;
|
||||
int _originalOffset;
|
||||
|
||||
|
||||
bool _notEnough(int offset, int ends, int needed)
|
||||
{
|
||||
if (offset + needed > ends)
|
||||
{
|
||||
//dataLengthNeeded = needed - (ends - offset);
|
||||
_dataLengthNeeded = needed - (ends - _originalOffset);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
int parse(DC data, int offset, int ends)
|
||||
{
|
||||
_originalOffset = offset;
|
||||
|
||||
if (_notEnough(offset, ends, 1))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
previousCommand = command;
|
||||
|
||||
command = (data[offset] >> 6);
|
||||
|
||||
if (command == IIPPacketCommand.Event)
|
||||
{
|
||||
event = (data[offset++] & 0x3f);
|
||||
|
||||
if (_notEnough(offset, ends, 4))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else if (command == IIPPacketCommand.Report)
|
||||
{
|
||||
report = (data[offset++] & 0x3f);
|
||||
|
||||
if (_notEnough(offset, ends, 4))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
callbackId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
previousAction = action;
|
||||
action = (data[offset++] & 0x3f);
|
||||
|
||||
if (_notEnough(offset, ends, 4))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
callbackId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
if (command == IIPPacketCommand.Event)
|
||||
{
|
||||
if (event == IIPPacketEvent.ResourceReassigned)
|
||||
{
|
||||
if (_notEnough(offset, ends, 4))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
newResourceId = data.getUint32( offset);
|
||||
offset += 4;
|
||||
|
||||
}
|
||||
else if (event == IIPPacketEvent.ResourceDestroyed)
|
||||
{
|
||||
// nothing to parse
|
||||
}
|
||||
else if (event == IIPPacketEvent.ChildAdded
|
||||
|| event == IIPPacketEvent.ChildRemoved)
|
||||
{
|
||||
if (_notEnough(offset, ends, 4))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
childId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else if(event == IIPPacketEvent.Renamed)
|
||||
{
|
||||
if (_notEnough(offset, ends, 2))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
var cl = data.getUint16(offset);
|
||||
offset += 2;
|
||||
|
||||
if (_notEnough(offset, ends, cl))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
content = data.clip(offset, cl);
|
||||
|
||||
offset += cl;
|
||||
}
|
||||
else if (event == IIPPacketEvent.PropertyUpdated)
|
||||
{
|
||||
if (_notEnough(offset, ends, 2))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
methodIndex = data[offset++];
|
||||
|
||||
var dt = data[offset++];
|
||||
var size = DataType.size(dt);
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
if (_notEnough(offset, ends, 4))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
var cl = data.getUint32( offset);
|
||||
offset += 4;
|
||||
|
||||
if (_notEnough(offset, ends, cl))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
content = data.clip( offset - 5, cl + 5);
|
||||
offset += cl;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_notEnough(offset, ends, size))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
content = data.clip(offset - 1, size + 1);
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
else if (event == IIPPacketEvent.EventOccurred)
|
||||
{
|
||||
if (_notEnough(offset, ends, 5))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
methodIndex = data[offset++];
|
||||
|
||||
var cl = data.getUint32( offset);
|
||||
offset += 4;
|
||||
|
||||
content = data.clip(offset, cl);
|
||||
offset += cl;
|
||||
|
||||
}
|
||||
// Attribute
|
||||
else if (event == IIPPacketEvent.AttributesUpdated)
|
||||
{
|
||||
if (_notEnough(offset, ends, 4))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
var cl = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
if (_notEnough(offset, ends, cl))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
content = data.clip(offset, cl);
|
||||
|
||||
offset += cl;
|
||||
}
|
||||
}
|
||||
else if (command == IIPPacketCommand.Request)
|
||||
{
|
||||
if (action == IIPPacketAction.AttachResource)
|
||||
{
|
||||
if (_notEnough(offset, ends, 4))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else if (action == IIPPacketAction.ReattachResource)
|
||||
{
|
||||
if (_notEnough(offset, ends, 12))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
resourceAge = data.getUint64(offset);
|
||||
offset += 8;
|
||||
|
||||
}
|
||||
else if (action == IIPPacketAction.DetachResource)
|
||||
{
|
||||
if (_notEnough(offset, ends, 4))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
}
|
||||
else if (action == IIPPacketAction.CreateResource)
|
||||
{
|
||||
if (_notEnough(offset, ends, 12))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
storeId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
var cl = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
if (_notEnough(offset, ends, cl))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
content = data.clip(offset, cl);
|
||||
}
|
||||
else if (action == IIPPacketAction.DeleteResource)
|
||||
{
|
||||
if (_notEnough(offset, ends, 4))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
}
|
||||
else if (action == IIPPacketAction.AddChild
|
||||
|| action == IIPPacketAction.RemoveChild)
|
||||
{
|
||||
if (_notEnough(offset, ends, 8))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
childId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else if (action == IIPPacketAction.RenameResource)
|
||||
{
|
||||
if (_notEnough(offset, ends, 6))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
var cl = data.getUint16(offset);
|
||||
offset += 2;
|
||||
|
||||
if (_notEnough(offset, ends, cl))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
content = data.clip(offset, cl);
|
||||
offset += cl;
|
||||
}
|
||||
else if (action == IIPPacketAction.TemplateFromClassName)
|
||||
{
|
||||
if (_notEnough(offset, ends, 1))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
var cl = data[offset++];
|
||||
|
||||
if (_notEnough(offset, ends, cl))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
className = data.getString(offset, cl);
|
||||
offset += cl;
|
||||
|
||||
}
|
||||
else if (action == IIPPacketAction.TemplateFromClassId)
|
||||
{
|
||||
if (_notEnough(offset, ends, 16))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
classId = data.getGuid(offset);
|
||||
offset += 16;
|
||||
|
||||
}
|
||||
else if (action == IIPPacketAction.TemplateFromResourceId)
|
||||
{
|
||||
if (_notEnough(offset, ends, 4))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else if (action == IIPPacketAction.QueryLink)
|
||||
{
|
||||
if (_notEnough(offset, ends, 2))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
var cl = data.getUint16(offset);
|
||||
offset += 2;
|
||||
|
||||
if (_notEnough(offset, ends, cl))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
resourceLink = data.getString(offset, cl);
|
||||
offset += cl;
|
||||
}
|
||||
else if (action == IIPPacketAction.ResourceChildren
|
||||
|| action == IIPPacketAction.ResourceParents)
|
||||
{
|
||||
if (_notEnough(offset, ends, 4))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else if (action == IIPPacketAction.ResourceHistory)
|
||||
{
|
||||
if (_notEnough(offset, ends, 20))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
fromDate = data.getDateTime(offset);
|
||||
offset += 8;
|
||||
|
||||
toDate = data.getDateTime(offset);
|
||||
offset += 8;
|
||||
|
||||
}
|
||||
else if (action == IIPPacketAction.InvokeFunctionArrayArguments
|
||||
|| action == IIPPacketAction.InvokeFunctionNamedArguments)
|
||||
{
|
||||
if (_notEnough(offset, ends, 9))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
methodIndex = data[offset++];
|
||||
|
||||
var cl = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
if (_notEnough(offset, ends, cl))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
content = data.clip(offset, cl);
|
||||
offset += cl;
|
||||
|
||||
}
|
||||
else if (action == IIPPacketAction.GetProperty)
|
||||
{
|
||||
if (_notEnough(offset, ends, 5))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
methodIndex = data[offset++];
|
||||
|
||||
}
|
||||
else if (action == IIPPacketAction.GetPropertyIfModified)
|
||||
{
|
||||
if (_notEnough(offset, ends, 9))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
methodIndex = data[offset++];
|
||||
|
||||
resourceAge = data.getUint64(offset);
|
||||
offset += 8;
|
||||
|
||||
}
|
||||
else if (action == IIPPacketAction.SetProperty)
|
||||
{
|
||||
if (_notEnough(offset, ends, 6))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
methodIndex = data[offset++];
|
||||
|
||||
|
||||
var dt = data[offset++];
|
||||
var size = DataType.size(dt);
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
if (_notEnough(offset, ends, 4))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
var cl = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
if (_notEnough(offset, ends, cl))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
content = data.clip(offset-5, cl + 5);
|
||||
offset += cl;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_notEnough(offset, ends, size))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
content = data.clip(offset-1, size + 1);
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
// Attributes
|
||||
else if (action == IIPPacketAction.UpdateAllAttributes
|
||||
|| action == IIPPacketAction.GetAttributes
|
||||
|| action == IIPPacketAction.UpdateAttributes
|
||||
|| action == IIPPacketAction.ClearAttributes)
|
||||
{
|
||||
if (_notEnough(offset, ends, 8))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
var cl = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
if (_notEnough(offset, ends, cl))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
content = data.clip(offset, cl);
|
||||
offset += cl;
|
||||
}
|
||||
}
|
||||
else if (command == IIPPacketCommand.Reply)
|
||||
{
|
||||
if (action == IIPPacketAction.AttachResource
|
||||
|| action == IIPPacketAction.ReattachResource)
|
||||
{
|
||||
|
||||
if (_notEnough(offset, ends, 26))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
classId = data.getGuid(offset);
|
||||
offset += 16;
|
||||
|
||||
resourceAge = data.getUint64(offset);
|
||||
offset += 8;
|
||||
|
||||
var cl = data.getUint16(offset);
|
||||
offset += 2;
|
||||
|
||||
if (_notEnough(offset, ends, cl))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
resourceLink = data.getString(offset, cl);
|
||||
offset += cl;
|
||||
|
||||
if (_notEnough(offset, ends, 4))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
cl = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
if (_notEnough(offset, ends, cl))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
content = data.clip(offset, cl);
|
||||
offset += cl;
|
||||
}
|
||||
else if (action == IIPPacketAction.DetachResource)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
else if (action == IIPPacketAction.CreateResource)
|
||||
{
|
||||
if (_notEnough(offset, ends, 20))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
//ClassId = data.GetGuid(offset);
|
||||
//offset += 16;
|
||||
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
}
|
||||
else if (action == IIPPacketAction.DetachResource)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
// Inquire
|
||||
else if (action == IIPPacketAction.TemplateFromClassName
|
||||
|| action == IIPPacketAction.TemplateFromClassId
|
||||
|| action == IIPPacketAction.TemplateFromResourceId
|
||||
|| action == IIPPacketAction.QueryLink
|
||||
|| action == IIPPacketAction.ResourceChildren
|
||||
|| action == IIPPacketAction.ResourceParents
|
||||
|| action == IIPPacketAction.ResourceHistory
|
||||
// Attribute
|
||||
|| action == IIPPacketAction.GetAllAttributes
|
||||
|| action == IIPPacketAction.GetAttributes)
|
||||
{
|
||||
if (_notEnough(offset, ends, 4))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
var cl = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
if (_notEnough(offset, ends, cl))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
content = data.clip(offset, cl);
|
||||
offset += cl;
|
||||
}
|
||||
else if (action == IIPPacketAction.InvokeFunctionArrayArguments
|
||||
|| action == IIPPacketAction.InvokeFunctionNamedArguments
|
||||
|| action == IIPPacketAction.GetProperty
|
||||
|| action == IIPPacketAction.GetPropertyIfModified)
|
||||
{
|
||||
if (_notEnough(offset, ends, 1))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
var dt = data[offset++];
|
||||
var size = DataType.size(dt);
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
if (_notEnough(offset, ends, 4))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
var cl = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
if (_notEnough(offset, ends, cl))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
content = data.clip(offset - 5, cl + 5);
|
||||
offset += cl;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_notEnough(offset, ends, size))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
content = data.clip(offset - 1, size + 1);
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
else if (action == IIPPacketAction.SetProperty)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
else if (command == IIPPacketCommand.Report)
|
||||
{
|
||||
if (report == IIPPacketReport.ManagementError)
|
||||
{
|
||||
if (_notEnough(offset, ends, 2))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
errorCode = data.getUint16(offset);
|
||||
offset += 2;
|
||||
}
|
||||
else if (report == IIPPacketReport.ExecutionError)
|
||||
{
|
||||
if (_notEnough(offset, ends, 2))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
errorCode = data.getUint16(offset);
|
||||
offset += 2;
|
||||
|
||||
if (_notEnough(offset, ends, 2))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
var cl = data.getUint16(offset);
|
||||
offset += 2;
|
||||
|
||||
if (_notEnough(offset, ends, cl))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
errorMessage = data.getString(offset, cl);
|
||||
offset += cl;
|
||||
}
|
||||
else if (report == IIPPacketReport.ProgressReport)
|
||||
{
|
||||
if (_notEnough(offset, ends, 8))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
progressValue = data.getInt32(offset);
|
||||
offset += 4;
|
||||
progressMax = data.getInt32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else if (report == IIPPacketReport.ChunkStream)
|
||||
{
|
||||
if (_notEnough(offset, ends, 1))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
var dt = data[offset++];
|
||||
var size = DataType.size(dt);
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
if (_notEnough(offset, ends, 4))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
var cl = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
if (_notEnough(offset, ends, cl))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
content = data.clip(offset - 5, cl + 5);
|
||||
offset += cl;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_notEnough(offset, ends, size))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
content = data.clip(offset - 1, size + 1);
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return offset - _originalOffset;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
toString()
|
||||
{
|
||||
var rt = command.toString();
|
||||
|
||||
if (command == IIPPacketCommand.Event)
|
||||
{
|
||||
rt += " " + event.toString();
|
||||
}
|
||||
else if (command == IIPPacketCommand.Request)
|
||||
{
|
||||
rt += " " + action.toString();
|
||||
if (action == IIPPacketAction.AttachResource)
|
||||
{
|
||||
rt += " CID: " + callbackId.toString() + " RID: " + resourceId.toString();
|
||||
}
|
||||
}
|
||||
else if (command == IIPPacketCommand.Reply)
|
||||
rt += " " + action.toString();
|
||||
else if (command == IIPPacketCommand.Report)
|
||||
rt += " " + report.toString();
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
}
|
36
bin/Net/Packets/IIPPacketAction.dart
Normal file
36
bin/Net/Packets/IIPPacketAction.dart
Normal file
@ -0,0 +1,36 @@
|
||||
class IIPPacketAction
|
||||
{
|
||||
// Request Manage
|
||||
static const int AttachResource = 0x0;
|
||||
static const int ReattachResource = 0x1;
|
||||
static const int DetachResource = 0x2;
|
||||
static const int CreateResource = 0x3;
|
||||
static const int DeleteResource = 0x4;
|
||||
static const int AddChild = 0x5;
|
||||
static const int RemoveChild = 0x6;
|
||||
static const int RenameResource = 0x7;
|
||||
|
||||
// Request Inquire
|
||||
static const int TemplateFromClassName = 0x8;
|
||||
static const int TemplateFromClassId = 0x9;
|
||||
static const int TemplateFromResourceId = 0xA;
|
||||
static const int QueryLink = 0xB;
|
||||
static const int ResourceHistory = 0xC;
|
||||
static const int ResourceChildren = 0xD;
|
||||
static const int ResourceParents = 0xE;
|
||||
|
||||
// Request Invoke
|
||||
static const int InvokeFunctionArrayArguments = 0x10;
|
||||
static const int GetProperty = 0x11;
|
||||
static const int GetPropertyIfModified = 0x12;
|
||||
static const int SetProperty = 0x13;
|
||||
static const int InvokeFunctionNamedArguments = 0x14;
|
||||
|
||||
// Request Attribute
|
||||
static const int GetAllAttributes = 0x18;
|
||||
static const int UpdateAllAttributes = 0x19;
|
||||
static const int ClearAllAttributes = 0x1A;
|
||||
static const int GetAttributes = 0x1B;
|
||||
static const int UpdateAttributes = 0x1C;
|
||||
static const int ClearAttributes = 0x1D;
|
||||
}
|
7
bin/Net/Packets/IIPPacketCommand.dart
Normal file
7
bin/Net/Packets/IIPPacketCommand.dart
Normal file
@ -0,0 +1,7 @@
|
||||
class IIPPacketCommand
|
||||
{
|
||||
static const int Event = 0;
|
||||
static const int Request = 1;
|
||||
static const int Reply = 2;
|
||||
static const int Report = 3;
|
||||
}
|
15
bin/Net/Packets/IIPPacketEvent.dart
Normal file
15
bin/Net/Packets/IIPPacketEvent.dart
Normal file
@ -0,0 +1,15 @@
|
||||
class IIPPacketEvent
|
||||
{
|
||||
// Event Manage
|
||||
static const int ResourceReassigned = 0;
|
||||
static const int ResourceDestroyed = 1;
|
||||
static const int ChildAdded = 2;
|
||||
static const int ChildRemoved = 3;
|
||||
static const int Renamed = 4;
|
||||
// Event Invoke
|
||||
static const int PropertyUpdated = 0x10;
|
||||
static const int EventOccurred = 0x11;
|
||||
|
||||
// Attribute
|
||||
static const int AttributesUpdated = 0x18;
|
||||
}
|
7
bin/Net/Packets/IIPPacketReport.dart
Normal file
7
bin/Net/Packets/IIPPacketReport.dart
Normal file
@ -0,0 +1,7 @@
|
||||
class IIPPacketReport
|
||||
{
|
||||
static const int ManagementError = 0;
|
||||
static const int ExecutionError = 1;
|
||||
static const int ProgressReport = 0x8;
|
||||
static const int ChunkStream = 0x9;
|
||||
}
|
22
bin/Net/SendList.dart
Normal file
22
bin/Net/SendList.dart
Normal file
@ -0,0 +1,22 @@
|
||||
import '../Data/BinaryList.dart';
|
||||
import '../Core/AsyncReply.dart';
|
||||
import 'NetworkConnection.dart';
|
||||
|
||||
class SendList extends BinaryList
|
||||
{
|
||||
NetworkConnection connection;
|
||||
AsyncReply<List<dynamic>> reply;
|
||||
|
||||
SendList(NetworkConnection connection, AsyncReply<List<dynamic>> reply)
|
||||
{
|
||||
this.reply = reply;
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
@override
|
||||
AsyncReply<List<dynamic>> done()
|
||||
{
|
||||
connection.send(super.toDC());
|
||||
return reply;
|
||||
}
|
||||
}
|
25
bin/Net/Sockets/IPEndPoint.dart
Normal file
25
bin/Net/Sockets/IPEndPoint.dart
Normal file
@ -0,0 +1,25 @@
|
||||
class IPEndPoint
|
||||
{
|
||||
List<int> ip;
|
||||
int port;
|
||||
|
||||
|
||||
String getIP()
|
||||
{
|
||||
return ip.join(".");
|
||||
//return "${(ip >> 24) & 0xFF}.${(ip >> 16) & 0xFF}.${(ip >> 8) & 0xFF}.${ip & 0xFF}";
|
||||
}
|
||||
|
||||
String get address => getIP();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "${getIP()}:${port}";
|
||||
}
|
||||
|
||||
|
||||
IPEndPoint(this.ip, this.port)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
47
bin/Net/Sockets/ISocket.dart
Normal file
47
bin/Net/Sockets/ISocket.dart
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
import '../../Core/IDestructible.dart';
|
||||
import '../../Data/DC.dart';
|
||||
import 'IPEndPoint.dart';
|
||||
import '../../Core/AsyncReply.dart';
|
||||
import 'SocketState.dart';
|
||||
|
||||
abstract class ISocket extends IDestructible
|
||||
{
|
||||
SocketState get state ; //{ get; }
|
||||
|
||||
//event ISocketReceiveEvent OnReceive;
|
||||
//event ISocketConnectEvent OnConnect;
|
||||
//event ISocketCloseEvent OnClose;
|
||||
|
||||
//void send(DC message);
|
||||
void send(DC message, [int offset, int size]);
|
||||
void close();
|
||||
AsyncReply<bool> connect(String hostname, int port);
|
||||
bool begin();
|
||||
|
||||
AsyncReply<ISocket> accept();
|
||||
IPEndPoint remoteEndPoint;
|
||||
IPEndPoint localEndPoint;
|
||||
}
|
9
bin/Net/Sockets/SocketState.dart
Normal file
9
bin/Net/Sockets/SocketState.dart
Normal file
@ -0,0 +1,9 @@
|
||||
enum SocketState
|
||||
{
|
||||
Initial,
|
||||
Listening,
|
||||
Connecting,
|
||||
Established,
|
||||
Closed,
|
||||
Terminated
|
||||
}
|
212
bin/Net/Sockets/TCPSocket.dart
Normal file
212
bin/Net/Sockets/TCPSocket.dart
Normal file
@ -0,0 +1,212 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2019 Ahmed Kh. Zamil
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
import 'dart:io';
|
||||
import 'ISocket.dart';
|
||||
import '../../Data/DC.dart';
|
||||
import '../NetworkBuffer.dart';
|
||||
import 'SocketState.dart';
|
||||
import 'IPEndPoint.dart';
|
||||
import '../../Core/AsyncReply.dart';
|
||||
|
||||
class TCPSocket extends ISocket
|
||||
{
|
||||
Socket sock;
|
||||
NetworkBuffer receiveNetworkBuffer = new NetworkBuffer();
|
||||
|
||||
//bool asyncSending;
|
||||
bool began = false;
|
||||
|
||||
SocketState _state = SocketState.Initial;
|
||||
|
||||
//public event ISocketReceiveEvent OnReceive;
|
||||
//public event ISocketConnectEvent OnConnect;
|
||||
//public event ISocketCloseEvent OnClose;
|
||||
//public event DestroyedEvent OnDestroy;
|
||||
|
||||
//SocketAsyncEventArgs socketArgs = new SocketAsyncEventArgs();
|
||||
|
||||
/*
|
||||
void connected(Task t)
|
||||
{
|
||||
state = SocketState.Established;
|
||||
OnConnect?.Invoke();
|
||||
Begin();
|
||||
}
|
||||
*/
|
||||
|
||||
IPEndPoint _localEP, _remoteEP;
|
||||
|
||||
bool begin()
|
||||
{
|
||||
if (began)
|
||||
return false;
|
||||
|
||||
began = true;
|
||||
|
||||
_localEP = IPEndPoint(sock.address.rawAddress, sock.port);
|
||||
_remoteEP = IPEndPoint(sock.remoteAddress.rawAddress, sock.remotePort);
|
||||
return true;
|
||||
}
|
||||
|
||||
void dataHandler(List<int> data){
|
||||
//print(new String.fromCharCodes(data).trim());
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
if (_state == SocketState.Closed || _state == SocketState.Terminated)
|
||||
return;
|
||||
|
||||
var dc = new DC.fromList(data);
|
||||
receiveNetworkBuffer.write(dc, 0, dc.length);
|
||||
emitArgs("receive", [receiveNetworkBuffer]);
|
||||
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
if (_state != SocketState.Closed)// && !sock.connected)
|
||||
{
|
||||
_state = SocketState.Terminated;
|
||||
close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void errorHandler(error, StackTrace trace){
|
||||
print(error);
|
||||
}
|
||||
|
||||
void doneHandler(){
|
||||
sock.destroy();
|
||||
}
|
||||
|
||||
AsyncReply<bool> connect(String hostname, int port)
|
||||
{
|
||||
var rt = new AsyncReply<bool>();
|
||||
|
||||
try
|
||||
{
|
||||
_state = SocketState.Connecting;
|
||||
|
||||
Socket.connect(hostname, port).then((s){
|
||||
sock = s;
|
||||
s.listen(dataHandler,
|
||||
onError: errorHandler,
|
||||
onDone: doneHandler,
|
||||
cancelOnError: false);
|
||||
_state = SocketState.Established;
|
||||
emitArgs("connect", []);
|
||||
begin();
|
||||
rt.trigger(true);
|
||||
|
||||
}).catchError((ex){
|
||||
close();
|
||||
rt.triggerError(ex);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
rt.triggerError(ex);
|
||||
}
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
IPEndPoint get localEndPoint => _localEP;
|
||||
IPEndPoint get remoteEndPoint => _remoteEP;
|
||||
|
||||
|
||||
SocketState get state => _state;
|
||||
|
||||
|
||||
TCPSocket.fromSocket(Socket socket)
|
||||
{
|
||||
sock = socket;
|
||||
//if (socket.)
|
||||
// _state = SocketState.Established;
|
||||
}
|
||||
|
||||
TCPSocket()
|
||||
{
|
||||
// default constructor
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
if (state != SocketState.Closed && state != SocketState.Terminated)
|
||||
_state = SocketState.Closed;
|
||||
|
||||
sock?.close();
|
||||
|
||||
emitArgs("close", []);
|
||||
}
|
||||
|
||||
|
||||
void send(DC message, [int offset, int size])
|
||||
{
|
||||
if (state == SocketState.Established)
|
||||
sock.add(message.toList());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void destroy()
|
||||
{
|
||||
close();
|
||||
emitArgs("destroy", [this]);
|
||||
}
|
||||
|
||||
AsyncReply<ISocket> accept()
|
||||
{
|
||||
|
||||
|
||||
var reply = new AsyncReply<ISocket>();
|
||||
return reply;
|
||||
|
||||
/*
|
||||
ServerSocket.bind(InternetAddress.ANY_IP_V4, 4567).then(
|
||||
(ServerSocket server) {
|
||||
server.listen(handleClient);
|
||||
}
|
||||
);
|
||||
|
||||
void handleClient(Socket client){
|
||||
print('Connection from '
|
||||
'${client.remoteAddress.address}:${client.remotePort}');
|
||||
|
||||
client.write("Hello from simple server!\n");
|
||||
client.close();
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user