Implementation
int processPacket(
DC msg, int offset, int ends, NetworkBuffer data, int chunkId) {
var packet = new IIPPacket();
if (_ready) {
//print("Inc " + msg.length.toString());
var rt = packet.parse(msg, offset, ends);
//print("Packet " + packet.toString());
if (rt <= 0) {
// print("hold");
var size = ends - offset;
data.holdFor(msg, offset, size, size - rt);
return ends;
} else {
//print("CMD ${packet.command} ${offset} ${ends}");
offset += rt;
if (packet.command == IIPPacketCommand.Event) {
switch (packet.event) {
case IIPPacketEvent.ResourceReassigned:
iipEventResourceReassigned(
packet.resourceId, packet.newResourceId);
break;
case IIPPacketEvent.ResourceDestroyed:
iipEventResourceDestroyed(packet.resourceId);
break;
case IIPPacketEvent.PropertyUpdated:
iipEventPropertyUpdated(packet.resourceId, packet.methodIndex,
packet.dataType ?? TransmissionType.Null, msg);
break;
case IIPPacketEvent.EventOccurred:
iipEventEventOccurred(packet.resourceId, packet.methodIndex,
packet.dataType ?? TransmissionType.Null, msg);
break;
case IIPPacketEvent.ChildAdded:
iipEventChildAdded(packet.resourceId, packet.childId);
break;
case IIPPacketEvent.ChildRemoved:
iipEventChildRemoved(packet.resourceId, packet.childId);
break;
case IIPPacketEvent.Renamed:
iipEventRenamed(packet.resourceId, packet.resourceName);
break;
case IIPPacketEvent.AttributesUpdated:
// @TODO: fix this
//iipEventAttributesUpdated(packet.resourceId, packet.dataType. ?? TransmissionType.Null);
break;
}
} else if (packet.command == IIPPacketCommand.Request) {
switch (packet.action) {
// Manage
case IIPPacketAction.AttachResource:
iipRequestAttachResource(packet.callbackId, packet.resourceId);
break;
case IIPPacketAction.ReattachResource:
iipRequestReattachResource(
packet.callbackId, packet.resourceId, packet.resourceAge);
break;
case IIPPacketAction.DetachResource:
iipRequestDetachResource(packet.callbackId, packet.resourceId);
break;
case IIPPacketAction.CreateResource:
// @TODO: Fix this
//iipRequestCreateResource(packet.callbackId, packet.storeId,
// packet.resourceId, packet.content);
break;
case IIPPacketAction.DeleteResource:
iipRequestDeleteResource(packet.callbackId, packet.resourceId);
break;
case IIPPacketAction.AddChild:
iipRequestAddChild(
packet.callbackId, packet.resourceId, packet.childId);
break;
case IIPPacketAction.RemoveChild:
iipRequestRemoveChild(
packet.callbackId, packet.resourceId, packet.childId);
break;
case IIPPacketAction.RenameResource:
iipRequestRenameResource(
packet.callbackId, packet.resourceId, packet.resourceName);
break;
// Inquire
case IIPPacketAction.TemplateFromClassName:
iipRequestTemplateFromClassName(
packet.callbackId, packet.className);
break;
case IIPPacketAction.TemplateFromClassId:
iipRequestTemplateFromClassId(packet.callbackId, packet.classId);
break;
case IIPPacketAction.TemplateFromResourceId:
iipRequestTemplateFromResourceId(
packet.callbackId, packet.resourceId);
break;
case IIPPacketAction.QueryLink:
iipRequestQueryResources(packet.callbackId, packet.resourceLink);
break;
case IIPPacketAction.ResourceChildren:
iipRequestResourceChildren(packet.callbackId, packet.resourceId);
break;
case IIPPacketAction.ResourceParents:
iipRequestResourceParents(packet.callbackId, packet.resourceId);
break;
case IIPPacketAction.ResourceHistory:
iipRequestInquireResourceHistory(packet.callbackId,
packet.resourceId, packet.fromDate, packet.toDate);
break;
case IIPPacketAction.LinkTemplates:
iipRequestLinkTemplates(packet.callbackId, packet.resourceLink);
break;
// Invoke
case IIPPacketAction.InvokeFunction:
iipRequestInvokeFunction(
packet.callbackId,
packet.resourceId,
packet.methodIndex,
packet.dataType ?? TransmissionType.Null,
msg);
break;
case IIPPacketAction.Listen:
iipRequestListen(
packet.callbackId, packet.resourceId, packet.methodIndex);
break;
case IIPPacketAction.Unlisten:
iipRequestUnlisten(
packet.callbackId, packet.resourceId, packet.methodIndex);
break;
/*
case IIPPacketAction.GetProperty:
iipRequestGetProperty(packet.callbackId, packet.resourceId, packet.methodIndex);
break;
case IIPPacketAction.GetPropertyIfModified:
iipRequestGetPropertyIfModifiedSince(packet.callbackId, packet.resourceId,
packet.methodIndex, packet.resourceAge);
break;
*/
case IIPPacketAction.SetProperty:
iipRequestSetProperty(
packet.callbackId,
packet.resourceId,
packet.methodIndex,
packet.dataType ?? TransmissionType.Null,
msg);
break;
// Attribute
case IIPPacketAction.GetAllAttributes:
// @TODO: fix this
//iipRequestGetAttributes(
// packet.callbackId, packet.resourceId, packet.content, true);
break;
case IIPPacketAction.UpdateAllAttributes:
//iipRequestUpdateAttributes(
// packet.callbackId, packet.resourceId, packet.content, true);
break;
case IIPPacketAction.ClearAllAttributes:
//iipRequestClearAttributes(
// packet.callbackId, packet.resourceId, packet.content, true);
break;
case IIPPacketAction.GetAttributes:
//iipRequestGetAttributes(
// packet.callbackId, packet.resourceId, packet.content, false);
break;
case IIPPacketAction.UpdateAttributes:
//iipRequestUpdateAttributes(
// packet.callbackId, packet.resourceId, packet.content, false);
break;
case IIPPacketAction.ClearAttributes:
//iipRequestClearAttributes(
// packet.callbackId, packet.resourceId, packet.content, false);
break;
case IIPPacketAction.KeepAlive:
iipRequestKeepAlive(
packet.callbackId, packet.currentTime, packet.interval);
break;
case IIPPacketAction.ProcedureCall:
iipRequestProcedureCall(packet.callbackId, packet.procedure,
packet.dataType as TransmissionType, msg);
break;
case IIPPacketAction.StaticCall:
iipRequestStaticCall(packet.callbackId, packet.classId,
packet.methodIndex, packet.dataType as TransmissionType, msg);
break;
}
} else if (packet.command == IIPPacketCommand.Reply) {
switch (packet.action) {
// Manage
case IIPPacketAction.AttachResource:
iipReply(packet.callbackId, [
packet.classId,
packet.resourceAge,
packet.resourceLink,
packet.dataType ?? TransmissionType.Null,
msg
]);
break;
case IIPPacketAction.ReattachResource:
iipReply(packet.callbackId, [
packet.resourceAge,
packet.dataType ?? TransmissionType.Null,
msg
]);
break;
case IIPPacketAction.DetachResource:
iipReply(packet.callbackId);
break;
case IIPPacketAction.CreateResource:
iipReply(packet.callbackId, [packet.resourceId]);
break;
case IIPPacketAction.DeleteResource:
case IIPPacketAction.AddChild:
case IIPPacketAction.RemoveChild:
case IIPPacketAction.RenameResource:
iipReply(packet.callbackId);
break;
// Inquire
case IIPPacketAction.TemplateFromClassName:
case IIPPacketAction.TemplateFromClassId:
case IIPPacketAction.TemplateFromResourceId:
if (packet.dataType != null) {
var content = msg.clip(packet.dataType?.offset ?? 0,
packet.dataType?.contentLength ?? 0);
iipReply(packet.callbackId, [TypeTemplate.parse(content)]);
} else {
iipReportError(packet.callbackId, ErrorType.Management,
ExceptionCode.TemplateNotFound.index, "Template not found");
}
break;
case IIPPacketAction.QueryLink:
case IIPPacketAction.ResourceChildren:
case IIPPacketAction.ResourceParents:
case IIPPacketAction.ResourceHistory:
case IIPPacketAction.LinkTemplates:
iipReply(packet.callbackId,
[packet.dataType ?? TransmissionType.Null, msg]);
break;
// Invoke
case IIPPacketAction.InvokeFunction:
case IIPPacketAction.StaticCall:
case IIPPacketAction.ProcedureCall:
iipReplyInvoke(packet.callbackId,
packet.dataType ?? TransmissionType.Null, msg);
break;
// case IIPPacketAction.GetProperty:
// iipReply(packet.callbackId, [packet.content]);
// break;
// case IIPPacketAction.GetPropertyIfModified:
// iipReply(packet.callbackId, [packet.content]);
// break;
case IIPPacketAction.Listen:
case IIPPacketAction.Unlisten:
case IIPPacketAction.SetProperty:
iipReply(packet.callbackId);
break;
// Attribute
case IIPPacketAction.GetAllAttributes:
case IIPPacketAction.GetAttributes:
iipReply(packet.callbackId,
[packet.dataType ?? TransmissionType.Null, msg]);
break;
case IIPPacketAction.UpdateAllAttributes:
case IIPPacketAction.UpdateAttributes:
case IIPPacketAction.ClearAllAttributes:
case IIPPacketAction.ClearAttributes:
iipReply(packet.callbackId);
break;
case IIPPacketAction.KeepAlive:
iipReply(packet.callbackId, [packet.currentTime, packet.jitter]);
break;
}
} else if (packet.command == IIPPacketCommand.Report) {
switch (packet.report) {
case IIPPacketReport.ManagementError:
iipReportError(packet.callbackId, ErrorType.Management,
packet.errorCode, null);
break;
case IIPPacketReport.ExecutionError:
iipReportError(packet.callbackId, ErrorType.Exception,
packet.errorCode, packet.errorMessage);
break;
case IIPPacketReport.ProgressReport:
iipReportProgress(packet.callbackId, ProgressType.Execution,
packet.progressValue, packet.progressMax);
break;
case IIPPacketReport.ChunkStream:
iipReportChunk(packet.callbackId,
packet.dataType ?? TransmissionType.Null, msg);
break;
}
}
}
} else {
var rt = _authPacket.parse(msg, offset, ends);
if (rt <= 0) {
data.holdForNeeded(msg, ends - rt);
return ends;
} else {
offset += rt;
if (_session?.localAuthentication.type == AuthenticationType.Host) {
if (_authPacket.command == IIPAuthPacketCommand.Declare) {
if (_authPacket.remoteMethod == AuthenticationMethod.Credentials &&
_authPacket.localMethod == AuthenticationMethod.None) {
/*
server.membership.userExists(_authPacket.remoteUsername, _authPacket.domain).then((x)
{
if (x)
{
_session.remoteAuthentication.username = _authPacket.remoteUsername;
_remoteNonce = _authPacket.remoteNonce;
_session.remoteAuthentication.domain = _authPacket.domain;
sendParams()
.addUint8(0xa0)
.addDC(_localNonce)
.done();
}
else
{
sendParams().addUint8(0xc0).addUint8(1).addUint16(14).addString("User not found").done();
}
});
*/
}
} else if (_authPacket.command == IIPAuthPacketCommand.Action) {
if (_authPacket.action == IIPAuthPacketAction.AuthenticateHash) {
var remoteHash = _authPacket.hash;
/*
server.membership.getPassword(_session.remoteAuthentication.username,
_session.remoteAuthentication.domain).then((pw)
{
if (pw != null)
{
//var hash = hashFunc.ComputeHash(BinaryList.ToBytes(pw, remoteNonce, localNonce));
var hash = SHA256.compute((new BinaryList())
.addDC(pw)
.addDC(_remoteNonce)
.addDC(_localNonce)
.toDC());
if (hash.sequenceEqual(remoteHash))
{
// send our hash
//var localHash = hashFunc.ComputeHash(BinaryList.ToBytes(localNonce, remoteNonce, pw));
//SendParams((byte)0, localHash);
var localHash = SHA256.compute
((new BinaryList()).addDC(_localNonce).addDC(_remoteNonce).addDC(pw).toDC());
sendParams().addUint8(0).addDC(localHash).done();
_readyToEstablish = true;
}
else
{
sendParams().addUint8(0xc0).addUint8(1).addUint16(5).addString("Error").done();
}
}
});
*/
} else if (_authPacket.action ==
IIPAuthPacketAction.NewConnection) {
if (_readyToEstablish) {
var r = new Random();
var sid = DC(32);
for (var i = 0; i < 32; i++) sid[i] = r.nextInt(255);
_session?.id = sid;
_sendParams()
..addUint8(0x28)
..addDC(sid)
..done();
_ready = true;
status = ConnectionStatus.Connected;
_openReply?.trigger(true);
_openReply = null;
emitArgs("ready", []);
//OnReady?.Invoke(this);
// server.membership.login(session);
}
}
}
} else if (_session?.localAuthentication.type ==
AuthenticationType.Client) {
if (_authPacket.command == IIPAuthPacketCommand.Acknowledge) {
if (_authPacket.remoteMethod == AuthenticationMethod.None) {
_sendParams()
..addUint8(0x20)
..addUint16(0)
..done();
} else if (_authPacket.remoteMethod ==
AuthenticationMethod.Credentials ||
_authPacket.remoteMethod == AuthenticationMethod.Token) {
_remoteNonce = _authPacket.remoteNonce;
// send our hash
var localHash = SHA256.compute((BinaryList()
..addDC(_localPasswordOrToken as DC)
..addDC(_localNonce as DC)
..addDC(_remoteNonce as DC))
.toDC());
_sendParams()
..addUint8(0)
..addDC(localHash)
..done();
}
//SendParams((byte)0, localHash);
} else if (_authPacket.command == IIPAuthPacketCommand.Action) {
if (_authPacket.action == IIPAuthPacketAction.AuthenticateHash) {
// check if the server knows my password
var remoteHash = SHA256.compute((BinaryList()
..addDC(_remoteNonce as DC)
..addDC(_localNonce as DC)
..addDC(_localPasswordOrToken as DC))
.toDC());
if (remoteHash.sequenceEqual(_authPacket.hash)) {
// send establish request
_sendParams()
..addUint8(0x20)
..addUint16(0)
..done();
} else {
_sendParams()
..addUint8(0xc0)
..addUint8(ExceptionCode.ChallengeFailed.index)
..addUint16(16)
..addString("Challenge Failed")
..done();
//SendParams((byte)0xc0, 1, 5, DC.ToBytes("Error"));
}
} else if (_authPacket.action ==
IIPAuthPacketAction.ConnectionEstablished) {
_session?.id = _authPacket.sessionId;
_ready = true;
status = ConnectionStatus.Connected;
_openReply?.trigger(true);
_openReply = null;
emitArgs("ready", []);
// start perodic keep alive timer
_keepAliveTimer = Timer(
Duration(seconds: keepAliveInterval), _keepAliveTimerElapsed);
}
} else if (_authPacket.command == IIPAuthPacketCommand.Error) {
_invalidCredentials = true;
var ex = AsyncException(ErrorType.Management, _authPacket.errorCode,
_authPacket.errorMessage);
_openReply?.triggerError(ex);
_openReply = null;
emitArgs("error", [ex]);
//OnError?.Invoke(this, authPacket.ErrorCode, authPacket.ErrorMessage);
close();
}
}
}
}
return offset;
//if (offset < ends)
// processPacket(msg, offset, ends, data, chunkId);
}