예제 #1
0
 public void SendGw(MsDevice dev, MsMessage msg)
 {
     msg.GetBytes();
     lock (_sendQueue) {
         _sendQueue.Enqueue(msg);
     }
 }
예제 #2
0
        private void MqsDevCctor(Topic t, Perform.Art a)
        {
            var dev = _devs.FirstOrDefault(z => z.name == t.name);

            if (dev == null)
            {
                dev = new MsDevice(this, t);
                _devs.Add(dev);
            }
        }
예제 #3
0
        public void SendGw(MsDevice dev, MsMessage msg)
        {
            if (_udp == null || msg == null)
            {
                return;
            }

            byte[]    buf = msg.GetBytes();
            IPAddress addr;

            if (dev == null)
            {
                addr = IPAddress.Broadcast;
                if (_bcIps == null)
                {
                    Log.Error("bcIps == null");
                    return;
                }
                foreach (var bc in _bcIps)
                {
                    try {
                        _udp.Send(buf, buf.Length, new IPEndPoint(bc, 1883));
                    }
                    catch (Exception ex) {
                        if (_pl.verbose)
                        {
                            Log.Warning("MsGUdp.SendGw({0}, {1}) - {2}", bc, msg, ex.Message);
                        }
                    }
                }
            }
            else if (dev.addr != null && dev.addr.Length == 4)
            {
                addr = new IPAddress(dev.addr);
                try {
                    _udp.Send(buf, buf.Length, new IPEndPoint(addr, 1883));
                }
                catch (Exception ex) {
                    if (_pl.verbose)
                    {
                        Log.Warning("MsGUdp.SendGw({0}, {1}) - {2}", addr, msg, ex.Message);
                    }
                }
            }
            else
            {
                return;
            }
            if (_pl.verbose)
            {
                Log.Debug("s {0}: {1}  {2}", addr, BitConverter.ToString(buf), msg.ToString());
            }
        }
예제 #4
0
        internal bool ProcessInPacket(IMsGate gate, byte[] addr, byte[] buf, int start, int end)
        {
            var msg = MsMessage.Parse(buf, start, end);

            if (msg == null)
            {
                if (verbose)
                {
                    Log.Warning("r {0}: {1}  bad message", gate.Addr2If(addr), BitConverter.ToString(buf, start, end - start));
                }
                return(false);
            }
            if (msg.MsgTyp == MsMessageType.ADVERTISE || msg.MsgTyp == MsMessageType.GWINFO)
            {
                return(true);
            }
            if (verbose)
            {
                Log.Debug("r {0}: {1}  {2}", gate.Addr2If(addr), BitConverter.ToString(buf, start, end - start), msg.ToString());
            }
            if (msg.MsgTyp == MsMessageType.SEARCHGW)
            {
                if ((msg as MsSearchGW).radius == 0 || (msg as MsSearchGW).radius == gate.gwRadius)
                {
                    gate.SendGw((MsDevice)null, new MsGwInfo(gate.gwIdx));
                }
                return(true);
            }
            if (msg.MsgTyp == MsMessageType.DHCP_REQ)
            {
                var dr = msg as MsDhcpReq;
                if ((dr.radius == 0 || dr.radius == 1))
                {
                    List <byte> ackAddr  = new List <byte>();
                    byte[]      respPrev = null;
                    foreach (byte hLen in dr.hLen)
                    {
                        if (hLen == 0)
                        {
                            continue;
                        }
                        else if (hLen <= 8)
                        {
                            byte[] resp;
                            if (respPrev != null && respPrev.Length == hLen)
                            {
                                resp = respPrev;
                            }
                            else
                            {
                                resp = new byte[hLen];
                                for (int i = 0; i < 5; i++)
                                {
                                    for (int j = 0; j < resp.Length; j++)
                                    {
                                        resp[j] = (byte)_rand.Next(j == 0 ? 4 : 0, (i < 3 && hLen == 1) ? 31 : (j == 0 ? 254 : 255));
                                    }
                                    if (!_devs.Any(z => z.gwIdx == gate.gwIdx && z.CheckAddr(resp)))
                                    {
                                        break;
                                    }
                                    else if (i == 4)
                                    {
                                        for (int j = 0; j < resp.Length; j++)
                                        {
                                            resp[j] = 0xFF;
                                        }
                                    }
                                }
                                respPrev = resp;
                            }
                            ackAddr.AddRange(resp);
                        }
                        else
                        {
                            if (verbose)
                            {
                                Log.Warning("r {0}: {1}  DhcpReq.hLen is too high", gate.Addr2If(addr), BitConverter.ToString(buf, start, end - start));
                            }
                            ackAddr = null;
                            break;
                        }
                    }
                    if (ackAddr != null)
                    {
                        gate.SendGw((MsDevice)null, new MsDhcpAck(gate.gwIdx, dr.xId, ackAddr.ToArray()));
                    }
                }
                return(true);
            }
            if (msg.MsgTyp == MsMessageType.CONNECT)
            {
                var      cm  = msg as MsConnect;
                MsDevice dev = _devs.FirstOrDefault(z => z.owner != null && z.owner.name == cm.ClientId);
                if (dev == null)
                {
                    var dt = Topic.root.Get("/dev/" + cm.ClientId, true, _owner);
                    dev = new MsDevice(this, dt);
                    _devs.Add(dev);
                    dt.SetAttribute(Topic.Attribute.Readonly);
                    dt.SetField("editor", "MsStatus", _owner);
                    dt.SetField("cctor.MqsDev", string.Empty, _owner);
                }
                dev._gate = gate;
                dev.addr  = addr;
                dev.Connect(cm);
                foreach (var dub in _devs.Where(z => z != dev && z.CheckAddr(addr) && z._gate == gate).ToArray())
                {
                    dub.addr  = null;
                    dub._gate = null;
                    dub.state = State.Disconnected;
                }
            }
            else
            {
                MsDevice dev = _devs.FirstOrDefault(z => z.addr != null && z.addr.SequenceEqual(addr) && z._gate == gate);
                if (dev != null && (dev.state != State.Disconnected && dev.state != State.Lost))
                {
                    dev.ProcessInPacket(msg);
                }
                else
                {
                    if (verbose)
                    {
                        if (dev == null || dev.owner == null)
                        {
                            Log.Debug("{0} unknown device", gate.Addr2If(addr));
                        }
                        else
                        {
                            Log.Debug("{0} inactive device: {1}", gate.Addr2If(addr), dev.owner.path);
                        }
                    }
                    gate.SendGw(addr, new MsDisconnect());
                }
            }
            return(true);
        }
예제 #5
0
        public void Run(MsDevice dev)
        {
            var c = this.Build();

            if (c == null)
            {
                return;
            }
            if (c.ioList != null)
            {
                foreach (var v in c.ioList) // register IO variables
                {
                    var t = _owner.parent.Get(v, true, _owner);
                    t.SetField("MQTT-SN.tag", v);
                }
            }
            var ch_t = JSC.JSObject.CreateObject();

            if (c.varList != null)
            {
                string       n;
                JSC.JSObject o, mo, mqo;
                foreach (var kv in c.varList)
                {
                    n             = kv.Key.Replace('.', '_');
                    o             = JSC.JSObject.CreateObject();
                    mo            = JSC.JSObject.CreateObject();
                    mqo           = JSC.JSObject.CreateObject();
                    mqo["tag"]    = kv.Value;
                    mo["MQTT-SN"] = mqo;
                    o["manifest"] = mo;
                    var            nt = MsDevice.NTTable.FirstOrDefault(z => kv.Value.StartsWith(z.Item1));
                    MsDevice.DType vt = nt == null?MsDevice.DType.Integer:nt.Item2;
                    switch (vt)
                    {
                    case MsDevice.DType.Boolean:
                        o["default"] = false;
                        o["type"]    = "Boolean";
                        break;

                    case MsDevice.DType.ByteArray:
                        o["default"] = null;
                        o["type"]    = "ByteArray";
                        break;

                    case MsDevice.DType.String:
                        o["default"] = string.Empty;
                        o["type"]    = "String";
                        break;

                    default:
                        o["default"] = 0;
                        o["type"]    = "Integer";
                        break;
                    }
                    o["menu"] = "plc";
                    ch_t[n]   = o;
                }
            }
            _owner.parent.SetField("Children", ch_t, _owner);
            string sTag;
            var    varLst = _owner.parent.children.Where(z => (sTag = z.GetField("MQTT-SN.tag").Value as string) != null && sTag.StartsWith("M")).ToArray();
            var    rereg  = new List <Tuple <Topic, string> >();

            foreach (var t in varLst)
            {
                sTag = t.GetField("MQTT-SN.tag").Value as string;
                var vt = c.varList.FirstOrDefault(z => t.name == z.Key.Replace('.', '_'));
                if (vt.Key == null)
                {
                    rereg.Add(new Tuple <Topic, string>(t, string.Empty));
                }
                else if (sTag != vt.Value)
                {
                    rereg.Add(new Tuple <Topic, string>(t, vt.Value));
                }
            }
            if (rereg.Any())
            {
                dev.ReReg(rereg);
            }
            _stackBottom = (c.StackBottom + 3) / 4;
            _prg         = new SortedSet <Chunk>();
            foreach (var kv in c.Hex)
            {
                var ch = new Chunk((int)kv.Key);
                ch.Data   = kv.Value;
                ch.crcCur = Crc16.UpdateCrc(0xFFFF, ch.Data);
                _prg.Add(ch);
                if (System.Threading.Interlocked.CompareExchange(ref _st, 1, 0) == 0)
                {
                    _curChunk = ch;
                }
            }
        }