/// <summary> /// Initializes a new instance. /// </summary> /// <param name="targetDeviceId"></param> /// <param name="sourceDeviceId"></param> /// <param name="targetPath"></param> /// <param name="sourcePath"></param> /// <param name="packetNumber"></param> /// <param name="packetCount"></param> /// <param name="data"></param> public RnetRequestDataMessage(RnetDeviceId targetDeviceId, RnetDeviceId sourceDeviceId, RnetPath targetPath, RnetPath sourcePath, RnetRequestMessageType type) : base(targetDeviceId, sourceDeviceId, RnetMessageType.RequestData) { TargetPath = targetPath; SourcePath = sourcePath; Type = type; }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="targetDeviceId"></param> /// <param name="sourceDeviceId"></param> /// <param name="targetPath"></param> /// <param name="sourcePath"></param> /// <param name="packetNumber"></param> /// <param name="packetCount"></param> /// <param name="data"></param> public RnetSetDataMessage(RnetDeviceId targetDeviceId, RnetDeviceId sourceDeviceId, RnetPath targetPath, RnetPath sourcePath, ushort packetNumber, ushort packetCount, RnetData data) : base(targetDeviceId, sourceDeviceId, RnetMessageType.SetData) { TargetPath = targetPath; SourcePath = sourcePath; PacketNumber = packetNumber; PacketCount = packetCount; Data = data; }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="targetDeviceId"></param> /// <param name="sourceDeviceId"></param> /// <param name="targetPath"></param> /// <param name="sourcePath"></param> public RnetEventMessage(RnetDeviceId targetDeviceId, RnetDeviceId sourceDeviceId, RnetPath targetPath, RnetPath sourcePath, RnetEvent evt, ushort timestamp, ushort data, RnetPriority priority) : base(targetDeviceId, sourceDeviceId, RnetMessageType.Event) { TargetPath = targetPath; SourcePath = sourcePath; Event = evt; Timestamp = timestamp; Data = data; Priority = priority; }
/// <summary> /// Gets or creates a data handle to the given path. /// </summary> /// <param name="path"></param> /// <returns></returns> protected internal RnetDataHandle GetOrCreateDataHandle(RnetPath path) { Contract.Requires<ArgumentException>(path.Length > 0); Contract.Ensures(Contract.Result<RnetDataHandle>() != null); lock (handles) return handles .GetOrCreate(path, i => CreateDataHandle(i)); }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="device"></param> /// <param name="path"></param> internal RnetLocalDataHandle(RnetLocalDevice device, RnetPath path) : base(device, path) { }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="device"></param> /// <param name="path"></param> internal RnetRemoteDataHandle(RnetRemoteDevice device, RnetPath path) : base(device, path) { Contract.Requires<ArgumentException>(path.Length > 0); }
/// <summary> /// Issues a request data message to the device. /// </summary> /// <param name="path"></param> /// <param name="cancellationToken"></param> /// <returns></returns> internal async Task SendRequestData(RnetPath path, CancellationToken cancellationToken) { Contract.Requires<ArgumentException>(path.Length != 0); // only one request at a time using (await send.LockAsync(cancellationToken)) await Bus.Client.Send(new RnetRequestDataMessage( DeviceId, Bus.LocalDevice.DeviceId, path, RnetPath.Empty, RnetRequestMessageType.Data)); }
/// <summary> /// Gets or creates a data handle to the given path. /// </summary> /// <param name="path"></param> /// <returns></returns> new RnetRemoteDataHandle GetOrCreateDataHandle(RnetPath path) { Contract.Requires<ArgumentException>(path.Length > 0); return (RnetRemoteDataHandle)base.GetOrCreateDataHandle(path); }
/// <summary> /// Creates a new data handle to the given path. /// </summary> /// <param name="path"></param> /// <returns></returns> protected internal override RnetDataHandle CreateDataHandle(RnetPath path) { return new RnetRemoteDataHandle(this, path); }
/// <summary> /// Issues an event message to the device. /// </summary> /// <param name="path"></param> /// <param name="evt"></param> /// <param name="timestamp"></param> /// <param name="data"></param> /// <returns></returns> public async Task SendEvent(RnetPath path, RnetEvent evt, ushort timestamp, ushort data, RnetPriority priority, CancellationToken cancellationToken) { using (await send.LockAsync(cancellationToken)) using (await handshake.EnterAsync(cancellationToken)) { handshakeMessage = null; // send set data packet await Bus.Client.Send(new RnetEventMessage( DeviceId, Bus.LocalDevice.DeviceId, path, RnetPath.Empty, evt, timestamp, data, priority)); // wait for handshake if (priority == RnetPriority.High) while (handshakeMessage == null) await handshake.WaitAsync(cancellationToken); } }
/// <summary> /// Issues an event message to the device. /// </summary> /// <param name="path"></param> /// <param name="evt"></param> /// <param name="timestamp"></param> /// <param name="data"></param> /// <param name="priority"></param> /// <returns></returns> public Task SendEvent(RnetPath path, RnetEvent evt, ushort timestamp = 0, ushort data = 0, RnetPriority priority = RnetPriority.Low) { return SendEvent(path, evt, timestamp, data, priority, CancellationToken.None); }
/// <summary> /// Issues a set data message to the device. /// </summary> /// <param name="targetPath"></param> /// <param name="sourcePath"></param> /// <param name="data"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task SendSetData(RnetPath targetPath, RnetPath sourcePath, byte[] data, CancellationToken cancellationToken) { Contract.Requires(data != null); Contract.Requires(data.Length <= 1024); // only one writer at a time using (await send.LockAsync(cancellationToken)) { // number of packets to send int c = data.Length / 16; if (data.Length % 16 > 0) c++; // send until all data sent for (int i = 0; i < c; i++) { // length of packet (remainder of data, max 16) var r = data.Length - i * 16; var l = r % 16 > 0 ? r % 16 : 16; var d = new byte[l]; Array.Copy(data, i * 16, d, 0, l); // set data must wait for a handshake using (await handshake.EnterAsync(cancellationToken)) { handshakeMessage = null; // send set data packet await Bus.Client.Send(new RnetSetDataMessage( DeviceId, Bus.LocalDevice.DeviceId, targetPath, sourcePath, (byte)i, (byte)c, new RnetData(d))); // wait for handshake while (handshakeMessage == null) await handshake.WaitAsync(cancellationToken); } } } }
/// <summary> /// Issues a set data message to the device in response to a request data message. /// </summary> /// <param name="sourcePath"></param> /// <param name="data"></param> /// <param name="cancellationToken"></param> /// <returns></returns> Task SendSetDataReply(RnetPath sourcePath, byte[] data, CancellationToken cancellationToken) { return SendSetData(RnetPath.Empty, sourcePath, data, cancellationToken); }
/// <summary> /// Issues a set data message to the device. /// </summary> /// <param name="targetPath"></param> /// <param name="data"></param> /// <param name="cancellationToken"></param> /// <returns></returns> internal Task SendSetData(RnetPath targetPath, byte[] data, CancellationToken cancellationToken) { return SendSetData(targetPath, RnetPath.Empty, data, cancellationToken); }
/// <summary> /// Creates a new data handle to the given path. /// </summary> /// <param name="path"></param> /// <returns></returns> protected internal abstract RnetDataHandle CreateDataHandle(RnetPath path);
/// <summary> /// Gets a handle to the given path. /// </summary> /// <param name="path"></param> /// <param name="packetCount"></param> /// <returns></returns> RnetDataHandleWriter GetOrCreateDataHandleWriter(RnetPath path, int packetCount) { Contract.Requires<ArgumentException>(path.Length > 0); Contract.Requires<ArgumentOutOfRangeException>(packetCount > 0); return writers .GetOrAdd(path, i => new WeakReference<RnetDataHandleWriter>(new RnetDataHandleWriter(packetCount))) .GetTargetOrDefault(); }
/// <summary> /// Gets a data handle to the given path. /// </summary> /// <param name="path"></param> /// <returns></returns> public RnetDataHandle this[RnetPath path] { get { return GetOrCreateDataHandle(path); } }
/// <summary> /// Invoked when a set data message arrives with data from this device. Integrates the data into the path /// handle. /// </summary> /// <param name="path"></param> /// <param name="data"></param> /// <returns></returns> Task ReceiveData(RnetPath path, byte[] data) { Contract.Requires(path.Length > 0); Contract.Requires(data != null); return GetOrCreateDataHandle(path).Receive(data); }