static BinaryResourceAccessor() { FetchHandlers = new DictionaryTS<eBinaryResourceLocationType, Func<BinaryResourceDescriptor, byte[]>>(); FetchHandlers.Add(eBinaryResourceLocationType.Http, HttpFetchHandler); FetchHandlers.Add(eBinaryResourceLocationType.RedisDB, RedisDBFetchHandler); }
static BinaryResourceAccessor() { FetchHandlers = new DictionaryTS <eBinaryResourceLocationType, Func <BinaryResourceDescriptor, byte[]> >(); FetchHandlers.Add(eBinaryResourceLocationType.Http, HttpFetchHandler); FetchHandlers.Add(eBinaryResourceLocationType.RedisDB, RedisDBFetchHandler); }
//------------------------------------------------------------------------------------------------------------------------ private void RemoteNode_OnChannelOpen(RemoteNode RemoteNode) { BrotherNodes.Add(RemoteNode.RemoteNodeKey, RemoteNode); //raise event if (OnRemoteNodeAssociation != null) { Task.Run(() => { try { OnRemoteNodeAssociation?.Invoke(RemoteNode); } catch (Exception ex) { DebugEx.Assert(ex, "Unhandled exception"); } }); } }
//------------------------------------------------------------------------------------------------------------------------ void HandleNewPacket(byte[] data, string addr) { try { //deserialize packet IDiscoveryMessageBase msg; try { msg = Tools.Marshalling.ToObject(DiscoveryMessageType, data) as IDiscoveryMessageBase; } catch { return; } //is it me? (then discard msg) if (msg.Id == 0 || msg.Id == myID) { return; } //create remote id var remID = new RemoteEndpointID() { IPAddress = addr, ID = msg.Id }; //examine existing association var info = DiscoveredEndpoints.TryGetOrDefault(remID); if (info == null) { DebugEx.TraceLog($"LANDiscoverer : Discovered new endpoint. (ip:{addr} id:{msg.Id} flags:{msg.Flags})"); //create info info = new RemoteEndpointInfo { ID = remID, LastMessageTimestamp = DateTime.Now, LastDiscoveryMessage = msg, }; //add to discovered nodes DiscoveredEndpoints.Add(remID, info); //raise event OnNewEndpointDiscovered?.Invoke(info); } //custom handle? OnEndpointMsgRx?.Invoke(info, msg); //update discovery message and timestamp Interlocked.Exchange(ref info.LastDiscoveryMessage, msg); info.LastMessageTimestamp = DateTime.Now; } catch (Exception ex) { DebugEx.TraceError(ex, "DiscoveryTaskEntryPoint error"); } }
//------------------------------------------------------------------------------------------------------------------------ public object GetSingleValue <Req>(Req data) { var syncid = GetNewSyncId(); var w = new Waiter(); lock (PendingRequests) PendingRequests.Add(syncid, w); //construct sharppy msg SharpPy msg = new SharpPy() { isRequest = true, watcherid = WatcherId, syncid = syncid, pin = this.sensor.Pin.ToString(), operation = (data as SharpPy).operation, payload = (data as SharpPy).payload, }; lock (w) { this.sharppyiface.Send2python(msg); Monitor.Wait(w); } lock (PendingRequests) PendingRequests.Remove(syncid); if (w.response != null) { if (w.response != prevData && w.response != "255" && w.response != "65535") { prevData = w.response; DebugEx.TraceLog("CONT: wId:" + WatcherId + " sId:" + syncid + " response:" + w.response); return(this.sensor.DeserializePayload(w.response)); } //else // DebugEx.TraceLog("DROP: wId:" + WatcherId + " sId:" + syncid + " response:" + w.response); } return(null); }
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()); } } } }
//------------------------------------------------------------------------------------------------------------------------ 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); } }
//------------------------------------------------------------------------------------------------------------------------ private IEnumerable <Thing> SetupSerialPortThing() { // Clean old things things.Clear(); // mNode transport conncted event { var isTransportConnected = new Port() { ioDirection = Yodiwo.API.Plegma.ioPortDirection.Output, Name = "Connected", State = "", ConfFlags = ePortConf.IsTrigger, Type = Yodiwo.API.Plegma.ePortType.Boolean, PortKey = PortKey.BuildFromArbitraryString("$ThingKey$", "0") }; Ports.Add("isTransportConnected", isTransportConnected); var connectionTimestamp = new Port() { ioDirection = Yodiwo.API.Plegma.ioPortDirection.Output, Name = "Timestamp", State = "", ConfFlags = ePortConf.None, Type = Yodiwo.API.Plegma.ePortType.Timestamp, PortKey = PortKey.BuildFromArbitraryString("$ThingKey$", "1") }; Ports.Add("connectionTimestamp", connectionTimestamp); var t = new Yodiwo.API.Plegma.Thing() { ThingKey = ThingKey.BuildFromArbitraryString("$NodeKey$", CreateThingKey("0")), Type = "", Name = "Transport", Config = new List <ConfigParameter>(), UIHints = new ThingUIHints() { IconURI = "http://simpleicon.com/wp-content/uploads/cloud-connection-1.png", }, Ports = new List <Port>() { isTransportConnected, connectionTimestamp } }; t = AddThing(t); things.Add("Transport", t); } // mNode periodic send { var periodicTimestamp = new Port() { ioDirection = Yodiwo.API.Plegma.ioPortDirection.Output, Name = "Timestamp", State = "", ConfFlags = ePortConf.None, Type = Yodiwo.API.Plegma.ePortType.Timestamp, PortKey = PortKey.BuildFromArbitraryString("$ThingKey$", "0") }; Ports.Add("periodicTimestamp", periodicTimestamp); var t = new Yodiwo.API.Plegma.Thing() { ThingKey = ThingKey.BuildFromArbitraryString("$NodeKey$", CreateThingKey("1")), Type = "", Name = "Periodic", Config = new List <ConfigParameter>() { // TODO: Use the actual value of the thing new ConfigParameter() { Description = "Period Seconds", Name = "Period", Value = "10" } }, UIHints = new ThingUIHints() { IconURI = "https://openreferral.org/wp-content/uploads/2015/02/icon_4034-300x300.png", }, Ports = new List <Port>() { periodicTimestamp } }; t = AddThing(t); things.Add("Periodic", t); } // mNode Ping { var echoPortOut = new Port() { ioDirection = Yodiwo.API.Plegma.ioPortDirection.Output, Name = "Echo", State = "", ConfFlags = ePortConf.None, Type = Yodiwo.API.Plegma.ePortType.String, PortKey = PortKey.BuildFromArbitraryString("$ThingKey$", "0") }; Ports.Add("echoPortOut", echoPortOut); var echoPortIn = new Port() { ioDirection = Yodiwo.API.Plegma.ioPortDirection.Input, Name = "Echo", State = "", ConfFlags = ePortConf.None, Type = Yodiwo.API.Plegma.ePortType.String, PortKey = PortKey.BuildFromArbitraryString("$ThingKey$", "1") }; Ports.Add("echoPortIn", echoPortIn); var t = new Yodiwo.API.Plegma.Thing() { ThingKey = ThingKey.BuildFromArbitraryString("$NodeKey$", CreateThingKey("2")), Type = "", Name = "Ping", Config = new List <ConfigParameter>(), UIHints = new ThingUIHints() { IconURI = "https://apk-dl.com/detail/image/com.lipinic.ping-w250.png", }, Ports = new List <Port>() { echoPortIn, echoPortOut } }; t = AddThing(t); things.Add("Ping", t); } return(things.Values); }
//------------------------------------------------------------------------------------------------------------------------ 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"); } }
//------------------------------------------------------------------------------------------------------------------------ private void Discoverer_OnEndpointMsgRx(YPChannel.Transport.Sockets.LANDiscoverer.RemoteEndpointInfo endpoint, YPChannel.Transport.Sockets.IDiscoveryMessageBase __msg) { try { //get valid msg var msg = __msg as DiscoveryMessage; if (msg == null) { return; } //create remotenodekey var rem_nodekey = API.Plegma.NodeKey.FromBytes(msg.NodeKey, 0); if (rem_nodekey.IsInvalid) { return; } //examine existing association lock (RemoteNodes) { var remInfo = RemoteNodes.TryGetOrDefault(endpoint.ID); if (remInfo == null) { //inform DebugEx.TraceLog($"NodeDiscoverer : Discovered new node. (ip:{endpoint.IPAddress} nodekey:{rem_nodekey})"); //create entry for remote node remInfo = new RemoteNode(Node, TimeSpan.FromMinutes(5), this) { RemoteEndpointID = endpoint.ID, DiscoveryMessage = msg, RemoteNodeKey = rem_nodekey, }; //add to discovered remote nodes RemoteNodes.Add(endpoint.ID, remInfo); //hookevents hookNewRemoteNodeEvents(remInfo); //Start a connection attempt remInfo.StartConnectionTask(); //raise event if (OnRemoteNodeDiscovery != null) { Task.Run(() => { try { OnRemoteNodeDiscovery?.Invoke(remInfo); } catch (Exception ex) { DebugEx.Assert(ex, "Unhandled exception"); } }); } } else { //start remote node connection if (!remInfo.IsDisposed && (remInfo.ClientChannel == null || (remInfo.ClientChannel.State == YPChannel.ChannelStates.Closed && !remInfo.ConnectionTaskRunning))) { remInfo.StartConnectionTask(); } } } } catch (Exception ex) { DebugEx.TraceError(ex, "DiscoveryTaskEntryPoint error"); } }