void OnFrame()

in netmf/NetMFLite/Client.cs [446:596]


        void OnFrame(ushort channel, ulong code, List fields, ByteBuffer payload)
        {
            switch (code)
            {
                case 0x10ul:  // open
                    Fx.DebugPrint(false, channel, "open", fields, "container-id", "host-name", "max-frame-size", "channel-max", "idle-time-out");
                    this.state |= OpenReceived;

                    // process open.idle-time-out if exists: final value is determined by the min of the local and the remote values
                    uint remoteValue = uint.MaxValue;
                    if (fields.Count >= 5 && fields[4] != null)
                    {
                        remoteValue = (uint)fields[4];
                    }
                    uint timeout = this.idleTimeout < remoteValue ? this.idleTimeout : remoteValue;
                    if (timeout < uint.MaxValue)
                    {
                        timeout -= 5000;
                        timeout = timeout > MaxIdleTimeout ? MaxIdleTimeout : timeout;
                        this.heartBeatTimer = new Timer(onHeartBeatTimer, this, (int)timeout, (int)timeout);
                    }
                    break;
                case 0x11ul:  // begin
                    Fx.DebugPrint(false, channel, "begin", fields, "remote-channel", "next-outgoing-id", "incoming-window", "outgoing-window", "handle-max");
                    this.nextIncomingId = (uint)fields[1];
                    this.outWindow = (uint)fields[2];
                    this.state |= BeginReceived;
                    break;
                case 0x12ul:  // attach
                {
                    Fx.DebugPrint(false, channel, "attach", fields, "name", "handle", "role", "snd-mode", "rcv-mode", "source", "target");
                    Link link = null;
                    uint remoteHandle = (uint)fields[1];
                    Fx.AssertAndThrow(ErrorCode.ClientInvalidHandle, remoteHandle < this.links.Length);
                    lock (this)
                    {
                        for (int i = 0; i < this.links.Length; i++)
                        {
                            if (this.links[i] != null && this.links[i].Name.Equals(fields[0]))
                            {
                                link = this.links[i];
                                int index = (int)~link.RemoteHandle;
                                Fx.AssertAndThrow(ErrorCode.ClientInvalidHandle, index == i);
                                if (index != (int)remoteHandle)
                                {
                                    Fx.AssertAndThrow(ErrorCode.ClientHandlInUse, this.links[(int)remoteHandle] == null);
                                    this.links[(int)remoteHandle] = link;
                                    this.links[i] = null;
                                }
                                break;
                            }
                        }
                    }
                    Fx.AssertAndThrow(ErrorCode.ClientLinkNotFound, link != null);
                    link.RemoteHandle = remoteHandle;
                    link.State |= AttachReceived;
                    link.OnAttach(fields);
                    break;
                }
                case 0x13ul:  // flow
                {
                    Fx.DebugPrint(false, channel, "flow", fields, "next-in-id", "in-window", "next-out", "out-window", "handle", "dc", "credit");
                    uint nextIncomingId = (uint)fields[0];
                    uint incomingWindow = (uint)fields[1];
                    lock(this)
                    {
                        this.outWindow = incomingWindow < uint.MaxValue ?
                            nextIncomingId + incomingWindow - this.nextOutgoingId :
                            uint.MaxValue;
                    }

                    if (fields[4] != null)
                    {
                        Link link = this.links[(uint)fields[4]];
                        Fx.AssertAndThrow(ErrorCode.ClientLinkNotFound, link != null);
                        link.OnFlow(fields);
                    }
                    break;
                }
                case 0x14ul:  // transfer
                {
                    lock (this)
                    {
                        this.nextOutgoingId++;
                        if (--this.inWindow == 0)
                        {
                            this.inWindow = DefaultWindowSize;
                            List flow = new List() { this.nextIncomingId, this.inWindow, this.nextOutgoingId, this.outWindow };
                            this.WriteFrame(0, 0, 0x13, flow);
                            Fx.DebugPrint(true, 0, "flow", flow, "next-in-id", "in-window", "next-out", "out-window", "handle", "dc", "credit");
                        }
                    }

                    Link link = this.links[(uint)fields[0]];
                    Fx.AssertAndThrow(ErrorCode.ClientLinkNotFound, link != null);
                    ((Receiver)link).OnTransfer(fields, payload);
                    break;
                }
                case 0x15ul:  // disposition
                {
                    Fx.DebugPrint(false, channel, "disposition", fields, "role", "first", "last");
                    bool role = (bool)fields[0];
                    uint first = (uint)fields[1];
                    uint last = fields[2] == null ? first : (uint)fields[2];
                    for (int i = 0; i < this.links.Length; i++)
                    {
                        Link link = this.links[i];
                        if (link != null && role != link.Role)
                        {
                            link.OnDisposition(first, last, fields[4] as DescribedValue);
                        }
                    }
                    break;
                }
                case 0x16ul:  // detach
                {
                    Fx.DebugPrint(false, channel, "detach", fields, "handle");
                    Link link = this.links[(uint)fields[0]];
                    Fx.AssertAndThrow(ErrorCode.ClientLinkNotFound, link != null);
                    link.State |= DetachReceived;
                    if ((link.State & DetachSent) == 0)
                    {
                        this.CloseLink(link);
                        this.RaiseErrorEvent(link, GetError(fields, 2));
                    }
                    break;
                }
                case 0x17ul:  // end
                    Fx.DebugPrint(false, channel, "end", null);
                    this.state |= EndReceived;
                    if ((this.state & EndSent) == 0)
                    {
                        this.WriteFrame(0, 0, 0x17ul, new List());
                        Fx.DebugPrint(true, channel, "end", null);
                        this.ClearLinks();
                    }
                    break;
                case 0x18ul:  // close
                    Fx.DebugPrint(false, channel, "close", null);
                    this.state |= CloseReceived;
                    if ((this.state & CloseSent) == 0)
                    {
                        this.Close();
                        this.RaiseErrorEvent(null, GetError(fields, 0));
                    }
                    break;
                default:
                    Fx.AssertAndThrow(ErrorCode.ClientInvalidCodeOnFrame, false);
                    break;
            }
        }