Exemple #1
0
        //------------------------------------------------------------------------------------------------------------------------
        public override void OnTransportConnected(string msg)
        {
            base.OnTransportConnected(msg);
            _CloudConnected = true;


            // Send the connection timestamp
            TaskEx.RunSafe(() =>
            {
                // Send the report 10Second after connection to avoid the timing issue with active port key
                // TODO: Fix this case !!!!
                Thread.Sleep(10000);
                if (Ports?.ContainsKey("connectionTimestamp") ?? false)
                {
                    SetPortState(new List <TupleS <string, string> >()
                    {
                        new TupleS <string, string>(Ports["connectionTimestamp"].PortKey, DateTime.UtcNow.ToStringInvariant()),
                        new TupleS <string, string>(Ports["isTransportConnected"].PortKey, "True"),
                    });
                }
            });
        }
Exemple #2
0
        //------------------------------------------------------------------------------------------------------------------------
        public void SendVBMToBrothers(List <VirtualBlockEvent> events)
        {
            try
            {
                //split into packets-per brother
                var brotherPackets = new Dictionary <NodeKey, List <VirtualBlockEvent> >();
                foreach (var ev in events)
                {
                    var bk = (BlockKey)ev.BlockKey;
                    var nk = bk.GraphKey.NodeKey;
                    if (BrotherNodes.ContainsKey(nk))
                    {
                        //get (or create) packet list
                        var packets = brotherPackets.TryGetOrDefault(nk);
                        if (packets == null)
                        {
                            brotherPackets.Add(nk, packets = new List <VirtualBlockEvent>());
                        }
                        //add packet for brother node
                        packets.Add(ev);
                    }
                }

                //send to brothers and consume
                foreach (var bpkv in brotherPackets)
                {
                    //get brother
                    var brother = BrotherNodes.TryGetOrDefault(bpkv.Key);
                    if (brother != null && brother.IsConnected)
                    {
                        var msgReq = new VirtualBlockEventMsg()
                        {
                            BlockEvents = bpkv.Value.ToArray(),
                        };
                        var rsp = brother.SendRequest <GenericRsp>(msgReq, Timeout: TimeSpan.FromSeconds(3));
                        if (rsp != null && rsp.IsSuccess)
                        {
                            //consume events from original set
                            msgReq.BlockEvents.ForEach(e => events.Remove(e));
                        }
                    }
                }
            }
            catch (Exception ex) { DebugEx.Assert(ex, "Unhandled exception in SendVBMToBrothers"); }
        }
        /// <summary>
        /// Get resource based on given descriptor
        /// </summary>
        /// <param name="descriptor"></param>
        /// <returns></returns>
        public static byte[] GetResource(BinaryResourceDescriptor descriptor)
        {
            byte[] resource = null;

            try
            {
                if (FetchHandlers.ContainsKey(descriptor.LocationType))
                {
                    resource = FetchHandlers[descriptor.LocationType](descriptor);
                }
                else
                {
                    DebugEx.TraceError("No handler for resource descriptor of type: " + descriptor.LocationType.ToString());
                }
            }
            catch (Exception ex)
            {
                DebugEx.Assert(ex, "Error getting resource from specified resource descriptor");
            }

            return(resource);
        }
Exemple #4
0
        private void GotButton(Bdaddr bdAddr)
        {
            DebugEx.TraceLog("Got Button");
            var thing = flicThings.TryGetOrDefault(bdAddr);

            if (thing == null)
            {
                thing = ThingTools.FlicThing.CreateThing(bdAddr.ToString().Replace(":", ""), bdAddr.ToString());
                thing = AddThing(thing);
                flicThings.Add(bdAddr, thing);
            }

            DebugEx.TraceLog("===========>Add Button Thing Completed");
            var channel = ButtonChannels.TryGetOrDefault(bdAddr);

            if (channel == null)
            {
                DebugEx.TraceLog("===========>New Channel is created");
                channel = new ButtonConnectionChannel(bdAddr);

                channel.CreateConnectionChannelResponse += (sender1, eventArgs) =>
                {
                    if (eventArgs.Error == CreateConnectionChannelError.NoError)
                    {
                        _channelConnected((ButtonConnectionChannel)sender1);
                    }
                    else
                    {
                        DebugEx.TraceError(((ButtonConnectionChannel)sender1).BdAddr.ToString() + " could not be connected");
                    }
                };
                channel.Removed += (sender1, eventArgs) =>
                {
                    _channelDisconnected((ButtonConnectionChannel)sender1);
                };
                channel.ConnectionStatusChanged += (sender1, eventArgs) =>
                {
                    var chan = (ButtonConnectionChannel)sender1;
                    if (eventArgs.ConnectionStatus == ConnectionStatus.Disconnected)
                    {
                        _channelDisconnected(chan);
                    }
                };
                channel.ButtonSingleOrDoubleClickOrHold += (sender1, eventArgs) =>
                {
                    var chan      = (ButtonConnectionChannel)sender1;
                    var thisThing = flicThings.TryGetOrDefault(chan.BdAddr);
                    if (thisThing == null)
                    {
                        return;
                    }

                    DebugEx.TraceLog(eventArgs.ClickType + " for " + thisThing.Name + " (key:" + thisThing.ThingKey + ")");
                    switch (eventArgs.ClickType)
                    {
                    case ClickType.ButtonSingleClick:
                        SetPortState(PortKey.BuildFromArbitraryString(thisThing.ThingKey, ThingTools.FlicThing.SingleClick), "True");
                        break;

                    case ClickType.ButtonDoubleClick:
                        SetPortState(PortKey.BuildFromArbitraryString(thisThing.ThingKey, ThingTools.FlicThing.DoubleClick), "True");
                        break;

                    case ClickType.ButtonHold:
                        SetPortState(PortKey.BuildFromArbitraryString(thisThing.ThingKey, ThingTools.FlicThing.LongClick), "True");
                        break;

                    default:
                        break;
                    }

                    if (!ButtonChannels.ContainsKey(chan.BdAddr))
                    {
                        _channelConnected(chan);
                    }
                };

                //try to add channel
                _flicClient.AddConnectionChannel(channel);
                DebugEx.TraceLog("===========>Add Connection Channel Completed");

                foreach (var navctx in NavigationContext.Values)
                {
                    DebugEx.TraceLog("===========>navctx.CurrentPage.Title: " + navctx.CurrentPage.Title);
                    if (navctx.CurrentPage.Title == "Flic Pairing")
                    {
                        DebugEx.TraceLog("=====>here I am <======");
                        navctx.GoBack();
                        navctx.UpdateCurrentPage(createDiscoverPage());
                    }
                }
            }
        }
Exemple #5
0
        //------------------------------------------------------------------------------------------------------------------------
        public GenericRsp HandleGraphDeploymentReq(GraphDeploymentReq req, bool SupressSave)
        {
            lock (locker)
            {
                var res = new GenericRsp();
                try
                {
                    //get graphkey
                    var graphkey = (GraphKey)req.GraphKey;
                    if (graphkey.IsInvalid)
                    {
                        res.IsSuccess = false;
                        res.Message   = "Invalid GraphKey";
                        return(res);
                    }
                    if (graphkey.NodeId != this.Node.NodeKey.NodeID)
                    {
                        res.IsSuccess = false;
                        res.Message   = "Invalid NodeID in GraphKey";
                        return(res);
                    }

                    //collect sets
                    var sets = Node.BeginActiveThingsUpdate();

                    //deploy or undeploy?
                    if (req.IsDeployed)
                    {
                        //deserialize graph descriptor
                        GraphDescriptor graphDescriptor;
                        try { graphDescriptor = GraphBuilder.GetGraphDescriptorFromJson(req.GraphDescriptor, false); }
                        catch (Exception ex)
                        {
                            DebugEx.Assert(ex, "Could not deserialize graph descriptor");
                            res.IsSuccess = false;
                            res.Message   = "Could not deserialize graph descriptor";
                            return(res);
                        }
                        graphDescriptor.GraphKey = graphkey;

                        //Build Graph
                        Graph graph;
                        try { graph = BuildGraph(graphDescriptor); }
                        catch (Exception ex)
                        {
                            DebugEx.Assert(ex, "Could not build graph from graph descriptor (unhandled exception)");
                            res.IsSuccess = false;
                            res.Message   = "Could not  build graph from graph descriptor (unhandled exception)";
                            return(res);
                        }
                        if (graph == null)
                        {
                            DebugEx.Assert("Could not build graph from graph descriptor");
                            res.IsSuccess = false;
                            res.Message   = "Could not  build graph from graph descriptor";
                            return(res);
                        }

                        //set key
                        graph.GraphKey = graphkey;

                        //do i already have it?
                        if (Graphs.ContainsKey(graphkey))
                        {
                            //invalidate graph
                            _GraphManager.InvalidateGraph(graphkey);
                            //remove information
                            Graphs.Remove(graphkey);
                        }

                        //try deploy graph
                        try
                        {
                            Exception exception;
                            var       depres = graph.OnDeploy(true, null, out exception);
                            if (!depres)
                            {
                                res.IsSuccess = false;
                                res.Message   = "Graph OnDeploy() failed. Message : " + (exception?.Message ?? "null");
                                return(res);
                            }
                        }
                        catch (Exception ex)
                        {
                            DebugEx.Assert(ex, "Graph OnDeploy() failed");
                            res.IsSuccess = false;
                            res.Message   = "Graph OnDeploy() failed. Message : " + ex.Message;
                            return(res);
                        }

                        //add to lookup
                        var gi = new GraphInfo()
                        {
                            GraphKey              = graphkey,
                            GraphDescriptor       = graphDescriptor,
                            GraphDescriptorString = req.GraphDescriptor,
                            Graph = graph,
                        };
                        Graphs.Add(graphkey, gi);

                        //save!
                        if (IsInitialized && !SupressSave)
                        {
                            Save();
                        }

                        //associate block keys
                        foreach (var thingblock in graph.Blocks.OfType <BaseThings>())
                        {
                            //Add to Thing2Block set
                            {
                                //find block key set
                                var set = ThingKey2BlockKey.TryGetOrDefault(thingblock.ThingKey);
                                if (set == null)
                                {
                                    set = new HashSetTS <BlockKey>();
                                    ThingKey2BlockKey.Add(thingblock.ThingKey, set);
                                }
                                //add to loockup set
                                set.Add(thingblock.BlockKey);
                            }

                            //Add only for thingIn
                            if (thingblock.IsThingIn)
                            {
                                //find block key set
                                var set = ThingKey2ThingInBlockKey.TryGetOrDefault(thingblock.ThingKey);
                                if (set == null)
                                {
                                    set = new HashSetTS <BlockKey>();
                                    ThingKey2ThingInBlockKey.Add(thingblock.ThingKey, set);
                                }
                                //add to loockup set
                                set.Add(thingblock.BlockKey);
                            }
                        }

                        //Handle Deploy
                        res.IsSuccess = true;
                        res.Message   = "Graph Deployed Successfully";
                    }
                    else
                    {
                        //Handle UnDeploy
                        if (Graphs.ContainsKey(graphkey) == false)
                        {
                            res.IsSuccess = true;
                            res.Message   = "Graph Undeployed Successfully (was not deployed)";
                        }
                        else
                        {
                            //get graph
                            var gi    = Graphs[graphkey];
                            var graph = gi.Graph;
                            //inform graph
                            Exception exception;
                            try
                            {
                                if (graph.OnUndeploy(null, out exception) == false)
                                {
                                    DebugEx.Assert(exception, "Graph OnUndeploy failed");
                                }
                            }
                            catch (Exception ex) { DebugEx.Assert(ex, "Graph OnUndeploy failed"); }
                            //invalidate graph
                            _GraphManager.InvalidateGraph(graphkey);
                            //remove information
                            Graphs.Remove(graphkey);
                            //save!
                            if (IsInitialized && !SupressSave)
                            {
                                Save();
                            }
                            //disassociate block keys
                            if (graph != null)
                            {
                                foreach (var thingblock in gi.Graph.Blocks.OfType <BaseThings>())
                                {
                                    //remove from thing2block
                                    {
                                        var set = ThingKey2BlockKey.TryGetOrDefault(thingblock.ThingKey);
                                        if (set != null)
                                        {
                                            set.Remove(thingblock.BlockKey);
                                        }
                                    }

                                    //remove from thignIn2block
                                    if (thingblock.IsThingIn)
                                    {
                                        var set = ThingKey2ThingInBlockKey.TryGetOrDefault(thingblock.ThingKey);
                                        if (set != null)
                                        {
                                            set.Remove(thingblock.BlockKey);
                                        }
                                    }
                                }
                            }
                            //done
                            res.IsSuccess = true;
                            res.Message   = "Graph Undeployed Successfully";
                        }
                    }

                    //finish update
                    Node.EndActiveThingsUpdate(sets);
                }
                catch (Exception ex)
                {
                    res.IsSuccess = false;
                    res.Message   = "Unhandled exception in GraphDeploymentReq(). Message=" + ex.Message;
                }
                finally
                {
                    //begin activation state snapshot
                    var sets = Node.BeginActiveThingsUpdate();

                    //update active ports/things
                    var activeThings = ThingKey2BlockKey.Where(kv => kv.Value.Count > 0)
                                       .Select(kv => Node.Things.TryGetOrDefaultReadOnly(kv.Key))
                                       .WhereNotNull().ToHashSetTS();
                    var activeThingKeys = activeThings.Select(t => (ThingKey)t.ThingKey).ToHashSetTS();

                    var activePorts     = activeThings.SelectMany(t => t.Ports).ToHashSetTS();
                    var activePortsKeys = activePorts.Select(p => (PortKey)p.PortKey).ToHashSetTS();

                    //update sets
                    Interlocked.Exchange(ref _ActiveThings, activeThings);
                    Interlocked.Exchange(ref _ActivePorts, activePorts);
                    Interlocked.Exchange(ref _ActiveThingKeys, activeThingKeys);
                    Interlocked.Exchange(ref _ActivePortKeys, activePortsKeys);

                    //trigger node thing activation update
                    Node.EndActiveThingsUpdate(sets);
                }
                //return result msg
                return(res);
            }
        }
Exemple #6
0
        //------------------------------------------------------------------------------------------------------------------------
        void HandleNewConnection(Socket newsocket)
        {
            try
            {
                #region check reconnection throttle
                try
                {
                    //setup socket
                    newsocket.ReceiveTimeout = -1;
                    newsocket.SendTimeout    = 60 * 1000;

#if NETFX
                    var re = newsocket.RemoteEndPoint.GetIPAddress().ToStringInvariant();
#elif UNIVERSAL
                    var re = newsocket.Information.RemoteAddress.ToStringInvariant();
#endif
                    //filtering
                    if (OnNewSocketConnectionFilter != null && OnNewSocketConnectionFilter(this, re) == false)
                    {
#if NETFX
                        try { newsocket.Close(); } catch { }
#endif
                        try { newsocket.Dispose(); } catch { }
                        DebugEx.TraceWarning("Connection from " + re + " closed from filter");
                        return;
                    }

                    if (IsReconnectionThrottleEnabled && re != "127.0.0.1" && re != "localhost") //no reconnection throttle for localhost connections
                    {
                        var rbe = reconnectThrottleBookKeeper.TryGetOrDefault(re);
                        if (rbe == null)
                        {
                            rbe = new ReconnectionBookkeepEntry()
                            {
                                ConnectionTimestamp = DateTime.Now + TimeSpan.FromMilliseconds(100),
                                Connections         = 1,
                            };
                            reconnectThrottleBookKeeper.ForceAdd(re, rbe);
                        }
                        else
                        {
                            if (++rbe.Connections > ReconnectionThrottleAfterConnectionCount)
                            {
                                var elapsed = DateTime.Now - rbe.ConnectionTimestamp;
                                if (elapsed < ReconnectionThrottleTimeout)
                                {
#if NETFX
                                    try { newsocket.Close(); } catch { }
#endif
                                    try { newsocket.Dispose(); } catch { }
                                    DebugEx.TraceWarning("Connection from " + re + " closed due to reconnection throttle (" + elapsed.Seconds + " sec)");
                                    return;
                                }
                            }
                        }
                    }
                }
                catch (Exception ex) { DebugEx.TraceWarning(ex, "YPServer Reconnection throttle exception"); }

                //cleanup old entries
                reconnectThrottleBookKeeper.RemoveWhere(e => DateTime.Now - e.Value.ConnectionTimestamp > ReconnectionThrottleTimeout);
                #endregion

                //start task new connection
                Task.Run(() =>
                {
                    ServerChannel channel = null;
                    string channelKey     = null;

                    Thread.Sleep(MathTools.GetRandomNumber(1, 100));
                    try
                    {
                        //check
#if NETFX
                        if (!newsocket.Connected)
                        {
                            DebugEx.TraceWarning("YPServer newsocket not connected?");
                            try { newsocket.Close(); } catch { }
                            return;
                        }
#endif
                        //create channel
                        var con = ChannelConstructor;
                        channel = con == null ? new ServerChannel(this, Protocols, SupportedChannelSerializationModes, PreferredChannelSerializationModes, newsocket) : con(Protocols, newsocket);
                        if (channel == null)
                        {
                            DebugEx.Assert("Could not create channel");
#if NETFX
                            try { newsocket.Close(); } catch { }
#endif
                            try { newsocket.Dispose(); } catch { }
                            return;
                        }

                        //add to set
                        lock (_Channels)
                        {
                            //generate unique key
                            while (IssuedKeys.ContainsKey(channelKey = MathTools.GenerateRandomAlphaNumericString(64)))
                            {
                                ;
                            }
                            //set on channel
                            channel._ChannelKey = channelKey;
                            //add to lookups
                            _Channels.Add(channel);
                            IssuedKeys.Add(channelKey, channel);
                        }

                        //start task timeout monitor
                        bool setupFinished = false;
                        Task.Run(() =>
                        {
                            try
                            {
                                //wait
                                Thread.Sleep(30000);
                                //check
                                if (!setupFinished)
                                {
                                    DebugEx.TraceLog($"ServerChannel setup timeout ({channel})");
                                    try { channel.Close("ServerChannel setup timeout"); } catch { }
#if NETFX
                                    try { newsocket?.Close(); } catch { }
#endif
                                    try { newsocket?.Dispose(); } catch { }

                                    //remove from lookups
                                    lock (_Channels)
                                    {
                                        if (channel != null)
                                        {
                                            _Channels.Remove(channel);
                                        }
                                        if (channelKey != null)
                                        {
                                            IssuedKeys.Remove(channelKey);
                                        }
                                    }
                                    return;
                                }
                            }
                            catch (Exception ex)
                            {
                                DebugEx.Assert(ex, $"Unhandled exception ({channel})");
#if NETFX
                                try { newsocket?.Close(); } catch { }
#endif
                                try { newsocket?.Dispose(); } catch { }

                                //remove from lookups
                                lock (_Channels)
                                {
                                    if (channel != null)
                                    {
                                        _Channels.Remove(channel);
                                    }
                                    if (channelKey != null)
                                    {
                                        IssuedKeys.Remove(channelKey);
                                    }
                                }
                                return;
                            }
                        });

                        //set serializer
                        channel.MsgPack = MsgPackSerializer;

                        //setup channel socket
                        if (channel.SetupServerSocket() == false)
                        {
#if NETFX
                            try { newsocket?.Close(); } catch { }
#endif
                            try { newsocket?.Dispose(); } catch { }

                            //remove from lookups
                            lock (_Channels)
                            {
                                if (channel != null)
                                {
                                    _Channels.Remove(channel);
                                }
                                if (channelKey != null)
                                {
                                    IssuedKeys.Remove(channelKey);
                                }
                            }
                            return;
                        }

                        //mark setup finish
                        setupFinished = true;

                        //call event
                        OnNewChannel?.Invoke(this, channel);

                        //start heartbeat
                        channel.Start();
                    }
                    catch (Exception ex)
                    {
                        DebugEx.Assert(ex, "YPServer: Failed setting up new connection for " + channel);
#if NETFX
                        try { newsocket.Close(); } catch { }
#endif
                        try { newsocket.Dispose(); } catch { }

                        //remove from lookups
                        lock (_Channels)
                        {
                            if (channel != null)
                            {
                                _Channels.Remove(channel);
                            }
                            if (channelKey != null)
                            {
                                IssuedKeys.Remove(channelKey);
                            }
                        }
                        return;
                    }
                });
            }
            catch (Exception ex)
            {
                DebugEx.Assert(ex, "YPChannel server setup new connection error");
            }
        }