예제 #1
0
        public IdpPacket ProcessPayload(UInt16 nodeAddress, IdpPacket packet)
        {
            var incoming = new IncomingTransaction(packet);
            var outgoing = new OutgoingTransaction(0xA000, incoming.TransactionId, IdpCommandFlags.None);

            if (_commandHandlers.ContainsKey(incoming.CommandId))
            {
                outgoing.Write((byte)IdpResponseCode.OK);
                outgoing.Write(incoming.CommandId);

                var responseCode = _commandHandlers[incoming.CommandId](incoming, outgoing);

                if (incoming.Flags.HasFlag(IdpCommandFlags.ResponseExpected))
                {
                    outgoing.WithResponseCode(responseCode);

                    return(outgoing.ToPacket(nodeAddress, packet.Source));
                }
            }
            else
            {
                outgoing.Write((byte)IdpResponseCode.UnknownCommand);
                outgoing.Write(incoming.CommandId);

                return(outgoing.ToPacket(nodeAddress, packet.Source));
            }

            return(null);
        }
예제 #2
0
        private IdpResponseCode OnEnumerateAdaptorCommand(UInt16 source, UInt16 address, UInt32 transactionId, OutgoingTransaction outgoing)
        {
            var adaptor = GetNextUnenumeratedAdaptor();

            if (adaptor == null)
            {
                outgoing.Write(false);

                return(IdpResponseCode.OK);
            }
            else
            {
                adaptor.IsRenumerated = true;

                bool adaptorProbed = false;

                if (!adaptor.IsEnumerated)
                {
                    var request = new OutgoingTransaction((UInt16)NodeCommand.RouterDetect, transactionId, IdpCommandFlags.None).Write(address);

                    adaptorProbed = SendRequest(adaptor, source, 0xFFFF, request);

                    if (adaptorProbed)
                    {
                        _currentlyEnumeratingAdaptor = adaptor;
                    }
                }

                outgoing.Write(true).Write(adaptorProbed).WithResponseCode(IdpResponseCode.OK);

                SendRequest(source, outgoing);

                return(IdpResponseCode.Deferred);
            }
        }
예제 #3
0
        private async Task EnumerateRouterAdaptor(UInt16 routerAddress)
        {
            var address = GetFreeAddress();

            var responseTask = Manager.WaitForResponseAsync((UInt16)NodeCommand.RouterDetect, 500);

            var(success, response) = await SendRequestAsync(routerAddress, OutgoingTransaction.Create((UInt16)NodeCommand.RouterEnumerateAdaptor, CreateTransactionId()).Write(address));

            if (response != null && response.ResponseCode == IdpResponseCode.OK)
            {
                var enumerated = response.Transaction.Read <bool>();

                if (enumerated)
                {
                    var routerDetectResponse = await responseTask;

                    if (routerDetectResponse != null && routerDetectResponse.ResponseCode == IdpResponseCode.OK)
                    {
                        var routerEnumerated = routerDetectResponse.Transaction.Read <bool>();

                        if (routerEnumerated)
                        {
                            await OnNodeAdded(routerAddress, address);

                            return;
                        }
                    }
                }
            }

            _freeAddresses.Push(address);

            _currentEnumerationNode.EnumerationState = NodeEnumerationState.Idle;
        }
예제 #4
0
        private async Task OnNodeAdded(UInt16 parentAddress, UInt16 address)
        {
            _nodeInfo[address] = new NodeInfo(_nodeInfo[parentAddress], address);

            _nodeInfo[parentAddress].Children.Add(_nodeInfo[address]);

            var(success, response) = await SendRequestAsync(address, OutgoingTransaction.Create((UInt16)NodeCommand.GetNodeInfo, CreateTransactionId()));

            if (response != null && response.ResponseCode == IdpResponseCode.OK)
            {
                _nodeInfo[address].Guid = response.Transaction.Read <Guid>();

                _nodeInfo[address].Name = response.Transaction.ReadUtf8String();

                // TODO read string.

                if (_nodeInfo[address].IsRouter)
                {
                    _nodeInfo[address].EnumerationState = NodeEnumerationState.Pending;
                }
                else
                {
                    _nodeInfo[address].EnumerationState = NodeEnumerationState.Idle;
                }

                // normally on enumerate called here...
            }
        }
예제 #5
0
        public async Task <bool> DisconnectAsync()
        {
            var(success, response) = await SendRequestAsync(OutgoingTransaction.Create((UInt16)ClientCommand.Disconnect, CreateTransactionId()));

            if (success && response != null && response.ResponseCode == IdpResponseCode.OK)
            {
                return(true);
            }

            return(false);
        }
예제 #6
0
        public async Task <UInt16> QueryInterfaceAsync(Guid guid)
        {
            UInt16 result = 0;

            var(success, response) = await SendRequestAsync(0,
                                                            OutgoingTransaction.Create((UInt16)NodeCommand.QueryInterface, CreateTransactionId(), IdpCommandFlags.None)
                                                            .Write(guid));

            if (success && response != null && response.ResponseCode == IdpResponseCode.OK)
            {
                result = response.Transaction.Source;
            }

            return(result);
        }
예제 #7
0
        private async Task StartEnumeratingAdaptors(UInt16 routerAddress)
        {
            var(success, response) = await SendRequestAsync(routerAddress,
                                                            OutgoingTransaction.Create((UInt16)NodeCommand.RouterPrepareToEnumerateAdaptors, CreateTransactionId()));

            if (response != null && response.ResponseCode == IdpResponseCode.OK)
            {
                if (_currentEnumerationNode != null)
                {
                    _currentEnumerationNode.EnumerationState = NodeEnumerationState.EnumeratingAdaptors;
                }
            }
            else
            {
                if (_currentEnumerationNode != null)
                {
                    _currentEnumerationNode.EnumerationState = NodeEnumerationState.Idle;
                }
            }
        }
예제 #8
0
        private async Task EnumerateRouterNode(UInt16 routerAddress)
        {
            var address = GetFreeAddress();

            var(success, response) = await SendRequestAsync(routerAddress, OutgoingTransaction.Create((UInt16)NodeCommand.RouterEnumerateNode, CreateTransactionId()).Write(address));

            if (response != null && response.ResponseCode == IdpResponseCode.OK)
            {
                var enumerated = response.Transaction.Read <bool>();

                if (enumerated)
                {
                    await OnNodeAdded(routerAddress, address);

                    return;
                }
            }

            _freeAddresses.Push(address);

            _currentEnumerationNode.EnumerationState = NodeEnumerationState.StartEnumeratingAdaptors;
        }
예제 #9
0
        private async Task DetectRouter()
        {
            var address = GetFreeAddress();

            var(success, response) = await SendRequestAsync(0xFFFF, OutgoingTransaction.Create((UInt16)NodeCommand.RouterDetect, CreateTransactionId()).Write(address));

            if (success && response != null && response.ResponseCode == IdpResponseCode.OK)
            {
                var enumerated = response.Transaction.Read <bool>();

                if (enumerated)
                {
                    _currentEnumerationNode.EnumerationState = NodeEnumerationState.Idle;

                    await OnNodeAdded(Address, address);

                    return;
                }
            }

            _freeAddresses.Push(address);

            // normally on enumerate called.
        }
예제 #10
0
 private bool SendRequest(IPacketTransmit adaptor, UInt16 source, UInt16 destination, OutgoingTransaction request)
 {
     return(adaptor.Transmit(request.ToPacket(source, destination)));
 }
예제 #11
0
        private IdpResponseCode OnEnumerateNodesCommand(UInt16 source, UInt16 address, OutgoingTransaction outgoing)
        {
            if (_unenumeratedNodes.Count != 0)
            {
                var node = _unenumeratedNodes.First();

                node.Address = address;
                //node.SetEnumerated();

                if (MarkEnumerated(node))
                {
                    outgoing.Write(true);
                    outgoing.WithResponseCode(IdpResponseCode.OK);

                    SendRequest(address, source, outgoing);

                    return(IdpResponseCode.Deferred);
                }
                else
                {
                    node.Address = UnassignedAddress;

                    outgoing.Write(false);

                    return(IdpResponseCode.InvalidParameters);
                }
            }
            else
            {
                outgoing.Write(false);
            }

            return(IdpResponseCode.OK);
        }
예제 #12
0
 public void ResetNetwork()
 {
     SendRequest(0x0000, OutgoingTransaction.Create((UInt16)NodeCommand.Reset, CreateTransactionId(), IdpCommandFlags.None));
 }
예제 #13
0
        public void PollNetwork()
        {
            //InvalidateNodes();

            SendRequest(0x0000, OutgoingTransaction.Create(0xA002, CreateTransactionId()));
        }
예제 #14
0
 public bool SendRequest(OutgoingTransaction transaction)
 {
     return(SendRequest(_serverAddress, transaction));
 }
예제 #15
0
 public async Task <(bool success, IdpResponse response)> SendRequestAsync(OutgoingTransaction request, UInt32 timeout = IdpNode.DefaultTimeoutMsec)
 {
     return(await SendRequestAsync(_serverAddress, request, timeout));
 }
예제 #16
0
        public void QueryInterface(UInt16 vid, UInt16 pid)
        {
            Manager.RegisterResponseHandler((UInt16)NodeCommand.QueryInterface, response => OnQueryInterfaceResponse(response));

            SendRequest(0, OutgoingTransaction.Create((UInt16)NodeCommand.QueryInterface, CreateTransactionId()).Write(vid).Write(pid));
        }