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

@@ -41,7 +41,7 @@ public enum ExceptionCode : ushort
NotAttached, NotAttached,
AlreadyListened, AlreadyListened,
AlreadyUnlistened, AlreadyUnlistened,
NotListenable, NotSubscribable,
ParseError, ParseError,
Timeout, Timeout,
NotSupported, NotSupported,

View File

@@ -112,7 +112,6 @@ public static class Codec
/// <returns>Value</returns> /// <returns>Value</returns>
public static (uint, AsyncReply) Parse(byte[] data, uint offset, DistributedConnection connection, uint[] requestSequence, TransmissionType? dataType = null) public static (uint, AsyncReply) Parse(byte[] data, uint offset, DistributedConnection connection, uint[] requestSequence, TransmissionType? dataType = null)
{ {
uint len = 0; uint len = 0;
if (dataType == null) if (dataType == null)

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 Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -22,27 +22,28 @@ SOFTWARE.
*/ */
using System; using Esiur.Core;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using Esiur.Net.Sockets;
using Esiur.Data; using Esiur.Data;
using Esiur.Misc; 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 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;
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; namespace Esiur.Net.IIP;
public partial class DistributedConnection : NetworkConnection, IStore public partial class DistributedConnection : NetworkConnection, IStore
@@ -426,10 +427,43 @@ public partial class DistributedConnection : NetworkConnection, IStore
offset += (uint)rt; 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: case IIPPacketEvent.ResourceReassigned:
IIPEventResourceReassigned(packet.ResourceId, packet.NewResourceId); IIPEventResourceReassigned(packet.ResourceId, packet.NewResourceId);
break; break;

View File

@@ -112,13 +112,13 @@ partial class DistributedConnection
return (SendList)SendParams().AddUInt8((byte)(evt)); 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 reply = new AsyncReply<object>();
var c = callbackCounter++; var c = callbackCounter++;
requests.Add(c, reply); requests.Add(c, reply);
SendParams().AddUInt8((byte)(0x40 | (byte)IIPPacketRequest.Listen)) SendParams().AddUInt8((byte)(0x40 | (byte)IIPPacketRequest.Subscribe))
.AddUInt32(c) .AddUInt32(c)
.AddUInt32(instanceId) .AddUInt32(instanceId)
.AddUInt8(index) .AddUInt8(index)
@@ -127,13 +127,13 @@ partial class DistributedConnection
return reply; return reply;
} }
internal AsyncReply SendUnlistenRequest(uint instanceId, byte index) internal AsyncReply SendUnsubscribeRequest(uint instanceId, byte index)
{ {
var reply = new AsyncReply<object>(); var reply = new AsyncReply<object>();
var c = callbackCounter++; var c = callbackCounter++;
requests.Add(c, reply); requests.Add(c, reply);
SendParams().AddUInt8((byte)(0x40 | (byte)IIPPacketRequest.Unlisten)) SendParams().AddUInt8((byte)(0x40 | (byte)IIPPacketRequest.Unsubscribe))
.AddUInt32(c) .AddUInt32(c)
.AddUInt32(instanceId) .AddUInt32(instanceId)
.AddUInt8(index) .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)) if (attachedResources.Contains(resourceId))
{ {
DistributedResource r; 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 => 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) 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)); }).Error(x => SendError(ErrorType.Exception, callback, (ushort)ExceptionCode.GeneralFailure));
} }
else 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) void IIPRequestInquireResourceHistory(uint callback, uint resourceId, DateTime fromDate, DateTime toDate)
{ {
@@ -1780,23 +1706,6 @@ partial class DistributedConnection
{ {
var history = DataSerializer.HistoryComposer(results, this, true); 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) SendReply(IIPPacketRequest.ResourceHistory, callback)
.AddUInt8Array(history) .AddUInt8Array(history)
.Done(); .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) 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> /// <summary>
/// Get the ResourceTemplate for a given class Id. /// 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); return connection.SendInvoke(instanceId, index, args);
} }
public AsyncReply Listen(EventTemplate et) public AsyncReply Subscribe(EventTemplate et)
{ {
if (et == null) if (et == null)
return new AsyncReply().TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.MethodNotFound, "")); 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 new AsyncReply().TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.NotSubscribable, ""));
return connection.SendListenRequest(instanceId, et.Index); return connection.SendListenRequest(instanceId, et.Index);
} }
public AsyncReply Listen(string eventName) public AsyncReply Subscribe(string eventName)
{ {
var et = Instance.Template.GetEventTemplateByName(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) if (et == null)
return new AsyncReply().TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.MethodNotFound, "")); 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 new AsyncReply().TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.NotListenable, ""));
return connection.SendUnlistenRequest(instanceId, et.Index); return connection.SendUnlistenRequest(instanceId, et.Index);
} }
public AsyncReply Unlisten(string eventName) public AsyncReply Unsubscribe(string eventName)
{ {
var et = Instance.Template.GetEventTemplateByName(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 Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -35,55 +35,14 @@ namespace Esiur.Net.Packets;
class IIPPacket : Packet 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 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 public byte Extension { get; set; }
{
get;
set;
}
public IIPPacketRequest Request
{
get;
set;
}
public IIPPacketReply Reply
{
get;
set;
}
public byte Extention { get; set; }
public IIPPacketNotification Notification
{
get;
set;
}
public TransmissionType? DataType { get; set; } public TransmissionType? DataType { get; set; }
@@ -101,7 +60,6 @@ class IIPPacket : Packet
if (offset + needed > ends) if (offset + needed > ends)
{ {
dataLengthNeeded = needed - (ends - offset); dataLengthNeeded = needed - (ends - offset);
//dataLengthNeeded = needed - (ends - originalOffset);
return true; return true;
} }
@@ -123,7 +81,6 @@ class IIPPacket : Packet
if (Method == IIPPacketMethod.Notification) if (Method == IIPPacketMethod.Notification)
{ {
Notification = (IIPPacketNotification)(data[offset++] & 0x3f); Notification = (IIPPacketNotification)(data[offset++] & 0x3f);
} }
else if (Method == IIPPacketMethod.Request) else if (Method == IIPPacketMethod.Request)
{ {
@@ -147,595 +104,20 @@ class IIPPacket : Packet
} }
else if (Method == IIPPacketMethod.Extension) 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, 1))
{ return -dataLengthNeeded;
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
NewResourceId = data.GetUInt32(offset, Endian.Little); (var size, DataType) = TransmissionType.Parse(data, offset, ends);
offset += 4;
} if (DataType == null)
else if (Event == IIPPacketEvent.ResourceDestroyed) return -(int)size;
{
// nothing to parse
}
else if (Event == IIPPacketEvent.ChildAdded
|| Event == IIPPacketEvent.ChildRemoved)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ChildId = data.GetUInt32(offset, Endian.Little); offset += (uint)size;
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);
}
} }
return offset - originalOffset; return offset - originalOffset;

View File

@@ -30,10 +30,10 @@ using System.Threading.Tasks;
namespace Esiur.Resource; namespace Esiur.Resource;
[AttributeUsage(AttributeTargets.Event)] [AttributeUsage(AttributeTargets.Event)]
public class ListenableAttribute : System.Attribute public class SubscribableAttribute : System.Attribute
{ {
public ListenableAttribute() public SubscribableAttribute()
{ {
} }

View File

@@ -17,7 +17,7 @@ public class EventTemplate : MemberTemplate
set; set;
} }
public bool Listenable { get; set; } public bool Subscribable { get; set; }
public EventInfo EventInfo { get; set; } public EventInfo EventInfo { get; set; }
@@ -29,7 +29,7 @@ public class EventTemplate : MemberTemplate
var hdr = Inherited ? (byte)0x80 : (byte)0; var hdr = Inherited ? (byte)0x80 : (byte)0;
if (Listenable) if (Subscribable)
hdr |= 0x8; hdr |= 0x8;
if (Annotation != null) if (Annotation != null)
@@ -55,11 +55,11 @@ public class EventTemplate : MemberTemplate
.ToArray(); .ToArray();
} }
public EventTemplate(TypeTemplate template, byte index, string name, bool inherited, RepresentationType argumentType, string annotation = null, bool listenable = false) public EventTemplate(TypeTemplate template, byte index, string name, bool inherited, RepresentationType argumentType, string annotation = null, bool subscribable = false)
: base(template, index, name, inherited) : base(template, index, name, inherited)
{ {
this.Annotation = annotation; this.Annotation = annotation;
this.Listenable = listenable; this.Subscribable = subscribable;
this.ArgumentType = argumentType; this.ArgumentType = argumentType;
} }
@@ -81,7 +81,7 @@ public class EventTemplate : MemberTemplate
throw new Exception($"Unsupported type `{argType}` in event `{type.Name}.{ei.Name}`"); throw new Exception($"Unsupported type `{argType}` in event `{type.Name}.{ei.Name}`");
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true); var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true); var subscribableAttr = ei.GetCustomAttribute<SubscribableAttribute>(true);
//evtType.Nullable = new NullabilityInfoContext().Create(ei).ReadState is NullabilityState.Nullable; //evtType.Nullable = new NullabilityInfoContext().Create(ei).ReadState is NullabilityState.Nullable;
@@ -120,8 +120,8 @@ public class EventTemplate : MemberTemplate
if (annotationAttr != null) if (annotationAttr != null)
et.Annotation = annotationAttr.Annotation; et.Annotation = annotationAttr.Annotation;
if (listenableAttr != null) if (subscribableAttr != null)
et.Listenable = true; et.Subscribable = true;
return et; return et;
} }