2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-09-13 12:43:17 +00:00
This commit is contained in:
2025-08-12 12:25:07 +03:00
parent 531770820f
commit a490cb9e32
8 changed files with 106 additions and 962 deletions

View File

@@ -1,6 +1,6 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Copyright (c) 2017-2025 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
@@ -22,27 +22,28 @@ SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using Esiur.Net.Sockets;
using Esiur.Core;
using Esiur.Data;
using Esiur.Misc;
using Esiur.Core;
using Esiur.Resource;
using Esiur.Security.Authority;
using Esiur.Resource.Template;
using System.Linq;
using Esiur.Net.HTTP;
using System.Timers;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using Esiur.Net.Packets.HTTP;
using Esiur.Security.Membership;
using Esiur.Net.Packets;
using Esiur.Net.Packets.HTTP;
using Esiur.Net.Sockets;
using Esiur.Resource;
using Esiur.Resource.Template;
using Esiur.Security.Authority;
using Esiur.Security.Membership;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace Esiur.Net.IIP;
public partial class DistributedConnection : NetworkConnection, IStore
@@ -426,10 +427,43 @@ public partial class DistributedConnection : NetworkConnection, IStore
offset += (uint)rt;
if (packet.Command == IIPPacketCommand.Event)
if (packet.DataType != null)
{
switch (packet.Event)
var dt = packet.DataType.Value;
var (_, parsed) = Codec.Parse(msg, dt.Offset, this, null, dt);
parsed.Then(value =>
{
if (packet.Method == IIPPacketMethod.Notification)
{
switch (packet.Notification)
{
case IIPPacketNotification.ResourceDestroyed:
IIPNotificationResourceDestroyed(value);
break;
case IIPPacketNotification.ResourceReassigned:
IIPNotificationResourceReassigned(value);
break;
case IIPPacketNotification.ResourceMoved:
IIPNotificationResourceMoved(value);
break;
case IIPPacketNotification.SystemFailure:
IIPNotificationSystemFailure(value);
break;
case IIPPacketNotification.PropertyModified:
IIPNotificationPropertyModified()
}
}
});
}
if (packet.Method == IIPPacketMethod.Notification)
{
switch (packet.Notification)
{
case IIPPacketNotification.ResourceDestroyed:
case IIPPacketEvent.ResourceReassigned:
IIPEventResourceReassigned(packet.ResourceId, packet.NewResourceId);
break;

View File

@@ -112,13 +112,13 @@ partial class DistributedConnection
return (SendList)SendParams().AddUInt8((byte)(evt));
}
internal AsyncReply SendListenRequest(uint instanceId, byte index)
internal AsyncReply SendSubscribeRequest(uint instanceId, byte index)
{
var reply = new AsyncReply<object>();
var c = callbackCounter++;
requests.Add(c, reply);
SendParams().AddUInt8((byte)(0x40 | (byte)IIPPacketRequest.Listen))
SendParams().AddUInt8((byte)(0x40 | (byte)IIPPacketRequest.Subscribe))
.AddUInt32(c)
.AddUInt32(instanceId)
.AddUInt8(index)
@@ -127,13 +127,13 @@ partial class DistributedConnection
return reply;
}
internal AsyncReply SendUnlistenRequest(uint instanceId, byte index)
internal AsyncReply SendUnsubscribeRequest(uint instanceId, byte index)
{
var reply = new AsyncReply<object>();
var c = callbackCounter++;
requests.Add(c, reply);
SendParams().AddUInt8((byte)(0x40 | (byte)IIPPacketRequest.Unlisten))
SendParams().AddUInt8((byte)(0x40 | (byte)IIPPacketRequest.Unsubscribe))
.AddUInt32(c)
.AddUInt32(instanceId)
.AddUInt8(index)
@@ -331,13 +331,19 @@ partial class DistributedConnection
}
}
void IIPEventResourceReassigned(uint resourceId, uint newResourceId)
void IIPNotificationResourceReassigned(object value)
{
// uint resourceId, uint newResourceId
}
void IIPEventResourceDestroyed(uint resourceId)
void IIPNotificationResourceMoved(object value) { }
void IIPNotificationSystemFailure(object value) { }
void IIPNotificationResourceDestroyed(object value)
{
var resourceId = (uint)value;
if (attachedResources.Contains(resourceId))
{
DistributedResource r;
@@ -362,8 +368,10 @@ partial class DistributedConnection
}
}
void IIPEventPropertyUpdated(uint resourceId, byte index, TransmissionType dataType, byte[] data)
void IIPNotificationPropertyModified(object value)
{
// uint resourceId, byte index, TransmissionType dataType, byte[] data
Fetch(resourceId, null).Then(r =>
{
@@ -387,42 +395,6 @@ partial class DistributedConnection
});
});
/*
if (resources.Contains(resourceId))
{
// push to the queue to gaurantee serialization
var reply = new AsyncReply<DistributedResourceQueueItem>();
queue.Add(reply);
var r = resources[resourceId];
Codec.Parse(content, 0, this).Then((arguments) =>
{
if (!r.IsAttached)
{
// property updated before the template is received
r.AddAfterAttachement(reply,
new DistributedResourceQueueItem((DistributedResource)r,
DistributedResourceQueueItem.DistributedResourceQueueItemType.Propery,
arguments, index));
}
else
{
var pt = r.Instance.Template.GetPropertyTemplate(index);
if (pt != null)
{
reply.Trigger(new DistributedResourceQueueItem((DistributedResource)r,
DistributedResourceQueueItem.DistributedResourceQueueItemType.Propery,
arguments, index));
}
else
{ // ft found, fi not found, this should never happen
queue.Remove(reply);
}
}
});
}
*/
}
@@ -1681,9 +1653,9 @@ partial class DistributedConnection
{
if (r is DistributedResource)
{
(r as DistributedResource).Unlisten(et).Then(x =>
(r as DistributedResource).Unsubscribe(et).Then(x =>
{
SendReply(IIPPacketRequest.Unlisten, callback).Done();
SendReply(IIPPacketRequest.Unsubscribe, callback).Done();
}).Error(x => SendError(ErrorType.Exception, callback, (ushort)ExceptionCode.GeneralFailure));
}
else
@@ -1723,52 +1695,6 @@ partial class DistributedConnection
}
// void IIPRequestGetProperty(uint callback, uint resourceId, byte index)
// {
// Warehouse.GetById(resourceId).Then((r) =>
// {
// if (r != null)
// {
// var pt = r.Instance.Template.GetPropertyTemplateByIndex(index);
// if (pt != null)
// {
// if (r is DistributedResource)
// {
// SendReply(IIPPacket.IIPPacketAction.GetProperty, callback)
// .AddUInt8Array(Codec.Compose((r as DistributedResource)._Get(pt.Index), this))
// .Done();
// }
// else
// {
//#if NETSTANDARD
// var pi = r.GetType().GetTypeInfo().GetProperty(pt.Name);
//#else
// var pi = r.GetType().GetProperty(pt.Name);
//#endif
// if (pi != null)
// {
// SendReply(IIPPacket.IIPPacketAction.GetProperty, callback)
// .AddUInt8Array(Codec.Compose(pi.GetValue(r), this))
// .Done();
// }
// else
// {
// // pt found, pi not found, this should never happen
// }
// }
// }
// else
// {
// // pt not found
// }
// }
// else
// {
// // resource not found
// }
// });
// }
void IIPRequestInquireResourceHistory(uint callback, uint resourceId, DateTime fromDate, DateTime toDate)
{
@@ -1780,23 +1706,6 @@ partial class DistributedConnection
{
var history = DataSerializer.HistoryComposer(results, this, true);
/*
ulong fromAge = 0;
ulong toAge = 0;
if (results.Count > 0)
{
var firstProp = results.Values.First();
//var lastProp = results.Values.Last();
if (firstProp.Length > 0)
{
fromAge = firstProp[0].Age;
toAge = firstProp.Last().Age;
}
}*/
SendReply(IIPPacketRequest.ResourceHistory, callback)
.AddUInt8Array(history)
.Done();
@@ -1806,52 +1715,6 @@ partial class DistributedConnection
});
}
// void IIPRequestGetPropertyIfModifiedSince(uint callback, uint resourceId, byte index, ulong age)
// {
// Warehouse.GetById(resourceId).Then((r) =>
// {
// if (r != null)
// {
// var pt = r.Instance.Template.GetFunctionTemplateByIndex(index);
// if (pt != null)
// {
// if (r.Instance.GetAge(index) > age)
// {
//#if NETSTANDARD
// var pi = r.GetType().GetTypeInfo().GetProperty(pt.Name);
//#else
// var pi = r.GetType().GetProperty(pt.Name);
//#endif
// if (pi != null)
// {
// SendReply(IIPPacket.IIPPacketAction.GetPropertyIfModified, callback)
// .AddUInt8Array(Codec.Compose(pi.GetValue(r), this))
// .Done();
// }
// else
// {
// // pt found, pi not found, this should never happen
// }
// }
// else
// {
// SendReply(IIPPacket.IIPPacketAction.GetPropertyIfModified, callback)
// .AddUInt8((byte)DataType.NotModified)
// .Done();
// }
// }
// else
// {
// // pt not found
// }
// }
// else
// {
// // resource not found
// }
// });
// }
void IIPRequestSetProperty(uint callback, uint resourceId, byte index, TransmissionType transmissionType, byte[] content)
{
@@ -1956,141 +1819,7 @@ partial class DistributedConnection
});
}
/*
void IIPReplyAttachResource(uint callback, uint resourceAge, object[] properties)
{
if (requests.ContainsKey(callback))
{
var req = requests[callback];
var r = resources[(uint)req.Arguments[0]];
if (r == null)
{
r.Instance.Deserialize(properties);
r.Instance.Age = resourceAge;
r.Attached();
// process stack
foreach (var rr in resources.Values)
rr.Stack.ProcessStack();
}
else
{
// resource not found
}
}
}
void IIPReplyReattachResource(uint callback, uint resourceAge, object[] properties)
{
var req = requests.Take(callback);
if (req != null)
{
var r = resources[(uint)req.Arguments[0]];
if (r == null)
{
r.Instance.Deserialize(properties);
r.Instance.Age = resourceAge;
r.Attached();
// process stack
foreach (var rr in resources.Values)
rr.Stack.ProcessStack();
}
else
{
// resource not found
}
}
}
void IIPReplyDetachResource(uint callback)
{
var req = requests.Take(callback);
// nothing to do
}
void IIPReplyCreateResource(uint callback, Guid classId, uint resourceId)
{
var req = requests.Take(callback);
// nothing to do
}
void IIPReplyDeleteResource(uint callback)
{
var req = requests.Take(callback);
// nothing to do
}
void IIPReplyTemplateFromClassName(uint callback, ResourceTemplate template)
{
// cache
if (!templates.ContainsKey(template.ClassId))
templates.Add(template.ClassId, template);
var req = requests.Take(callback);
req?.Trigger(template);
}
void IIPReplyTemplateFromClassId(uint callback, ResourceTemplate template)
{
// cache
if (!templates.ContainsKey(template.ClassId))
templates.Add(template.ClassId, template);
var req = requests.Take(callback);
req?.Trigger(template);
}
void IIPReplyTemplateFromResourceLink(uint callback, ResourceTemplate template)
{
// cache
if (!templates.ContainsKey(template.ClassId))
templates.Add(template.ClassId, template);
var req = requests.Take(callback);
req?.Trigger(template);
}
void IIPReplyTemplateFromResourceId(uint callback, ResourceTemplate template)
{
// cache
if (!templates.ContainsKey(template.ClassId))
templates.Add(template.ClassId, template);
var req = requests.Take(callback);
req?.Trigger(template);
}
void IIPReplyResourceIdFromResourceLink(uint callback, Guid classId, uint resourceId, uint resourceAge)
{
var req = requests.Take(callback);
req?.Trigger(template);
}
void IIPReplyInvokeFunction(uint callback, object returnValue)
{
}
void IIPReplyGetProperty(uint callback, object value)
{
}
void IIPReplyGetPropertyIfModifiedSince(uint callback, object value)
{
}
void IIPReplySetProperty(uint callback)
{
}
*/
/// <summary>
/// Get the ResourceTemplate for a given class Id.

View File

@@ -245,41 +245,41 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
return connection.SendInvoke(instanceId, index, args);
}
public AsyncReply Listen(EventTemplate et)
public AsyncReply Subscribe(EventTemplate et)
{
if (et == null)
return new AsyncReply().TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.MethodNotFound, ""));
if (!et.Listenable)
return new AsyncReply().TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.NotListenable, ""));
if (!et.Subscribable)
return new AsyncReply().TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.NotSubscribable, ""));
return connection.SendListenRequest(instanceId, et.Index);
}
public AsyncReply Listen(string eventName)
public AsyncReply Subscribe(string eventName)
{
var et = Instance.Template.GetEventTemplateByName(eventName);
return Listen(et);
return Subscribe(et);
}
public AsyncReply Unlisten(EventTemplate et)
public AsyncReply Unsubscribe(EventTemplate et)
{
if (et == null)
return new AsyncReply().TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.MethodNotFound, ""));
if (!et.Listenable)
if (!et.Subscribable)
return new AsyncReply().TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.NotListenable, ""));
return connection.SendUnlistenRequest(instanceId, et.Index);
}
public AsyncReply Unlisten(string eventName)
public AsyncReply Unsubscribe(string eventName)
{
var et = Instance.Template.GetEventTemplateByName(eventName);
return Unlisten(et);
return Unsubscribe(et);
}

View File

@@ -1,6 +1,6 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Copyright (c) 2017-2025 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
@@ -35,55 +35,14 @@ namespace Esiur.Net.Packets;
class IIPPacket : Packet
{
public override string ToString()
{
var rt = Method.ToString();
if (Method == IIPPacketMethod.Notification)
{
rt += " " + Notification.ToString();
}
else if (Method == IIPPacketMethod.Request)
{
rt += " " + Request.ToString();
}
else if (Method == IIPPacketMethod.Reply)
{
rt += " " + Reply.ToString();
}
return rt;
}
public uint CallbackId { get; set; }
public IIPPacketMethod Method { get; set; }
public IIPPacketRequest Request { get; set; }
public IIPPacketReply Reply { get; set; }
public IIPPacketNotification Notification { get; set; }
public IIPPacketMethod Method
{
get;
set;
}
public IIPPacketRequest Request
{
get;
set;
}
public IIPPacketReply Reply
{
get;
set;
}
public byte Extention { get; set; }
public IIPPacketNotification Notification
{
get;
set;
}
public byte Extension { get; set; }
public TransmissionType? DataType { get; set; }
@@ -101,7 +60,6 @@ class IIPPacket : Packet
if (offset + needed > ends)
{
dataLengthNeeded = needed - (ends - offset);
//dataLengthNeeded = needed - (ends - originalOffset);
return true;
}
@@ -123,7 +81,6 @@ class IIPPacket : Packet
if (Method == IIPPacketMethod.Notification)
{
Notification = (IIPPacketNotification)(data[offset++] & 0x3f);
}
else if (Method == IIPPacketMethod.Request)
{
@@ -147,595 +104,20 @@ class IIPPacket : Packet
}
else if (Method == IIPPacketMethod.Extension)
{
Extention = (byte)(data[offset++] & 0x3f);
Extension = (byte)(data[offset++] & 0x3f);
}
if (Command == IIPPacketCommand.Event)
if (hasDTU)
{
if (Event == IIPPacketEvent.ResourceReassigned)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
NewResourceId = data.GetUInt32(offset, Endian.Little);
offset += 4;
(var size, DataType) = TransmissionType.Parse(data, offset, ends);
}
else if (Event == IIPPacketEvent.ResourceDestroyed)
{
// nothing to parse
}
else if (Event == IIPPacketEvent.ChildAdded
|| Event == IIPPacketEvent.ChildRemoved)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
if (DataType == null)
return -(int)size;
ChildId = data.GetUInt32(offset, Endian.Little);
offset += 4;
}
else if (Event == IIPPacketEvent.Renamed)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var cl = data.GetUInt16(offset, Endian.Little);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ResourceName = data.GetString(offset, cl);
//Content = data.Clip(offset, cl);
offset += cl;
}
else if (Event == IIPPacketEvent.PropertyUpdated
|| Event == IIPPacketEvent.EventOccurred)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
MethodIndex = data[offset++];
(var size, DataType) = TransmissionType.Parse(data, offset, ends);
//var dt = (DataType)data[offset++];
//var size = dt.Size();// Codec.SizeOf(dt);
if (DataType == null)
return -(int)size;
//Content = data.Clip(DataType.Value.Offset, (uint)DataType.Value.ContentLength);
offset += (uint)size;
}
//else if (Event == IIPPacketEvent.EventOccurred)
//{
// if (NotEnough(offset, ends, 5))
// return -dataLengthNeeded;
// MethodIndex = data[offset++];
// var cl = data.GetUInt32(offset);
// offset += 4;
// if (NotEnough(offset, ends, cl))
// return -dataLengthNeeded;
// 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, Endian.Little);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
//@TODO: Fix this
//Content = data.Clip(offset, cl);
offset += cl;
}
}
else if (Command == IIPPacketCommand.Request)
{
if (Action == IIPPacketRequest.AttachResource)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset, Endian.Little);
offset += 4;
}
else if (Action == IIPPacketRequest.ReattachResource)
{
if (NotEnough(offset, ends, 12))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset, Endian.Little);
offset += 4;
ResourceAge = data.GetUInt64(offset, Endian.Little);
offset += 8;
}
else if (Action == IIPPacketRequest.DetachResource)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset, Endian.Little);
offset += 4;
}
else if (Action == IIPPacketRequest.CreateResource)
{
if (NotEnough(offset, ends, 12))
return -dataLengthNeeded;
StoreId = data.GetUInt32(offset, Endian.Little);
offset += 4;
ResourceId = data.GetUInt32(offset, Endian.Little);
offset += 4;
var cl = data.GetUInt32(offset, Endian.Little);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
// @TODO: fix this
//this.Content = data.Clip(offset, cl);
}
else if (Action == IIPPacketRequest.DeleteResource)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset, Endian.Little);
offset += 4;
}
else if (Action == IIPPacketRequest.AddChild
|| Action == IIPPacketRequest.RemoveChild)
{
if (NotEnough(offset, ends, 8))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset, Endian.Little);
offset += 4;
ChildId = data.GetUInt32(offset, Endian.Little);
offset += 4;
}
else if (Action == IIPPacketRequest.RenameResource)
{
if (NotEnough(offset, ends, 6))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset, Endian.Little);
offset += 4;
var cl = data.GetUInt16(offset, Endian.Little);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ResourceName = data.GetString(offset, cl);
//Content = data.Clip(offset, cl);
offset += cl;
}
else if (Action == IIPPacketRequest.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 == IIPPacketRequest.TemplateFromClassId)
{
if (NotEnough(offset, ends, 16))
return -dataLengthNeeded;
ClassId = data.GetUUID(offset);
offset += 16;
}
else if (Action == IIPPacketRequest.TemplateFromResourceId)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset, Endian.Little);
offset += 4;
}
else if (Action == IIPPacketRequest.QueryLink
|| Action == IIPPacketRequest.LinkTemplates)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var cl = data.GetUInt16(offset, Endian.Little);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ResourceLink = data.GetString(offset, cl);
offset += cl;
}
else if (Action == IIPPacketRequest.ResourceChildren
|| Action == IIPPacketRequest.ResourceParents)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset, Endian.Little);
offset += 4;
}
else if (Action == IIPPacketRequest.ResourceHistory)
{
if (NotEnough(offset, ends, 20))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset, Endian.Little);
offset += 4;
FromDate = data.GetDateTime(offset, Endian.Little);
offset += 8;
ToDate = data.GetDateTime(offset, Endian.Little);
offset += 8;
}
else if (Action == IIPPacketRequest.InvokeFunction)
{
if (NotEnough(offset, ends, 6))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset, Endian.Little);
offset += 4;
MethodIndex = data[offset++];
(var size, DataType) = TransmissionType.Parse(data, offset, ends);
if (DataType == null)
return -(int)size;
offset += (uint)size;
//var cl = data.GetUInt32(offset);
//offset += 4;
//if (NotEnough(offset, ends, cl))
// return -dataLengthNeeded;
//Content = data.Clip(offset, cl);
//offset += cl;
}
else if (Action == IIPPacketRequest.Listen
|| Action == IIPPacketRequest.Unlisten)// .GetProperty)
{
if (NotEnough(offset, ends, 5))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset, Endian.Little);
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 == IIPPacketRequest.SetProperty)
{
if (NotEnough(offset, ends, 6))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset, Endian.Little);
offset += 4;
MethodIndex = data[offset++];
(var size, DataType) = TransmissionType.Parse(data, offset, ends);
if (DataType == null)
return -(int)size;
//Content = data.Clip(DataType.Value.Offset, (uint)DataType.Value.ContentLength);
offset += (uint)size;
}
// Attributes
else if (Action == IIPPacketRequest.UpdateAllAttributes
|| Action == IIPPacketRequest.GetAttributes
|| Action == IIPPacketRequest.UpdateAttributes
|| Action == IIPPacketRequest.ClearAttributes)
{
if (NotEnough(offset, ends, 8))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset, Endian.Little);
offset += 4;
var cl = data.GetUInt32(offset, Endian.Little);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
// @TODO: fix this
//Content = data.Clip(offset, cl);
offset += cl;
}
else if (Action == IIPPacketRequest.KeepAlive)
{
if (NotEnough(offset, ends, 12))
return -dataLengthNeeded;
CurrentTime = data.GetDateTime(offset, Endian.Little);
offset += 8;
Interval = data.GetUInt32(offset, Endian.Little);
offset += 4;
}
else if (Action == IIPPacketRequest.ProcedureCall)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var cl = data.GetUInt16(offset, Endian.Little);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Procedure = data.GetString(offset, cl);
offset += cl;
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
(var size, DataType) = TransmissionType.Parse(data, offset, ends);
if (DataType == null)
return -(int)size;
offset += (uint)size;
}
else if (Action == IIPPacketRequest.StaticCall)
{
if (NotEnough(offset, ends, 18))
return -dataLengthNeeded;
ClassId = data.GetUUID(offset);//, Endian.Little);
offset += 16;
MethodIndex = data[offset++];
(var size, DataType) = TransmissionType.Parse(data, offset, ends);
if (DataType == null)
return -(int)size;
offset += (uint)size;
}
}
else if (Command == IIPPacketCommand.Reply)
{
if (Action == IIPPacketRequest.AttachResource
|| Action == IIPPacketRequest.ReattachResource)
{
if (NotEnough(offset, ends, 26))
return -dataLengthNeeded;
ClassId = data.GetUUID(offset);
offset += 16;
ResourceAge = data.GetUInt64(offset, Endian.Little);
offset += 8;
uint cl = data.GetUInt16(offset, Endian.Little);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ResourceLink = data.GetString(offset, cl);
offset += cl;
//if (NotEnough(offset, ends, 4))
// return -dataLengthNeeded;
(var size, DataType) = TransmissionType.Parse(data, offset, ends);
if (DataType == null)
return -(int)size;
offset += (uint)size;
//Content = data.Clip(DataType.Value.Offset, (uint)DataType.Value.ContentLength);
}
else if (Action == IIPPacketRequest.DetachResource)
{
// nothing to do
}
else if (Action == IIPPacketRequest.CreateResource)
{
if (NotEnough(offset, ends, 20))
return -dataLengthNeeded;
//ClassId = data.GetGuid(offset);
//offset += 16;
ResourceId = data.GetUInt32(offset, Endian.Little);
offset += 4;
}
else if (Action == IIPPacketRequest.DetachResource)
{
// nothing to do
}
// Inquire
else if (Action == IIPPacketRequest.TemplateFromClassName
|| Action == IIPPacketRequest.TemplateFromClassId
|| Action == IIPPacketRequest.TemplateFromResourceId
|| Action == IIPPacketRequest.QueryLink
|| Action == IIPPacketRequest.ResourceChildren
|| Action == IIPPacketRequest.ResourceParents
|| Action == IIPPacketRequest.ResourceHistory
|| Action == IIPPacketRequest.LinkTemplates
// Attribute
|| Action == IIPPacketRequest.GetAllAttributes
|| Action == IIPPacketRequest.GetAttributes)
{
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
(var size, DataType) = TransmissionType.Parse(data, offset, ends);
if (DataType == null)
return -(int)size;
offset += (uint)size;
//var cl = data.GetUInt32(offset);
//offset += 4;
//if (NotEnough(offset, ends, cl))
// return -dataLengthNeeded;
//Content = data.Clip(offset, cl);
//offset += cl;
}
else if (Action == IIPPacketRequest.InvokeFunction
|| Action == IIPPacketRequest.ProcedureCall
|| Action == IIPPacketRequest.StaticCall)
{
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
(var size, DataType) = TransmissionType.Parse(data, offset, ends);
if (DataType == null)
return -(int)size;
offset += (uint)size;
//Content = data.Clip(DataType.Value.Offset, (uint)DataType.Value.ContentLength);
}
else if (Action == IIPPacketRequest.SetProperty
|| Action == IIPPacketRequest.Listen
|| Action == IIPPacketRequest.Unlisten)
{
// nothing to do
}
else if (Action == IIPPacketRequest.KeepAlive)
{
if (NotEnough(offset, ends, 12))
return -dataLengthNeeded;
CurrentTime = data.GetDateTime(offset, Endian.Little);
offset += 8;
Jitter = data.GetUInt32(offset, Endian.Little);
offset += 4;
}
}
else if (Command == IIPPacketCommand.Report)
{
if (Report == IIPPacketReport.ManagementError)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
ErrorCode = data.GetUInt16(offset, Endian.Little);
offset += 2;
}
else if (Report == IIPPacketReport.ExecutionError)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
ErrorCode = data.GetUInt16(offset, Endian.Little);
offset += 2;
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var cl = data.GetUInt16(offset, Endian.Little);
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, Endian.Little);
offset += 4;
ProgressMax = data.GetInt32(offset, Endian.Little);
offset += 4;
}
else if (Report == IIPPacketReport.ChunkStream)
{
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
(var size, DataType) = TransmissionType.Parse(Data, offset, ends);
if (DataType == null)
return -(int)size;
offset += (uint)size;
//Content = data.Clip(DataType.Value.Offset, (uint)DataType.Value.ContentLength);
}
offset += (uint)size;
}
return offset - originalOffset;