private static void ScanPorts(object o, bool b) {
if(Interlocked.Exchange(ref _scanBusy, 1)!=0) {
return;
}
byte[] buf=new byte[64];
byte[] tmpBuf=new byte[64];
byte[] disconnectAll=(new MsDisconnect()).GetBytes();
bool escChar;
int cnt=0, tryCnt;
SerialPort port=null;
int length;
bool found;
List<string> pns=new List<string>();
Topic dev=Topic.root.Get("/dev");
lock(dev) {
var ifs=dev.children.Where(z => z.valueType==typeof(MsDevice)).Cast<DVar<MsDevice>>().Where(z => z.value!=null).Select(z => z.value).ToArray();
foreach(var devSer in ifs) {
cnt++;
if(devSer.state==State.Connected) {
continue;
}
if(string.IsNullOrWhiteSpace(devSer.via)) {
_scanAllPorts=true;
break;
}
string via=devSer.via;
if(via!="offline" && !pns.Exists(z => string.Equals(z, via, StringComparison.InvariantCultureIgnoreCase))) {
pns.Add(via);
}
}
}
if(_scanAllPorts || cnt==0) {
_scanAllPorts=false;
pns.Clear();
pns.AddRange(SerialPort.GetPortNames());
} else {
pns=pns.Intersect(SerialPort.GetPortNames()).ToList();
}
Topic tmp;
if(Topic.root.Exist("/local/cfg/MQTT-SN.Serial/whitelist", out tmp)) {
var whl=tmp as DVar<string>;
if(whl!=null && !string.IsNullOrEmpty(whl.value)) {
var wps=whl.value.Split(';', ',');
if(wps!=null && wps.Length>0) {
pns=pns.Intersect(wps).ToList();
}
}
}
if(Topic.root.Exist("/local/cfg/MQTT-SN.Serial/blacklist", out tmp)) {
var bll=tmp as DVar<string>;
if(bll!=null && !string.IsNullOrEmpty(bll.value)) {
var bps=bll.value.Split(';', ',');
if(bps!=null && bps.Length>0) {
pns=pns.Except(bps).ToList();
}
}
}
for(int i=0; i<pns.Count; i++) {
if(_gates.Exists(z => z.name==pns[i])) {
continue;
}
try {
port=new SerialPort(pns[i], 38400, Parity.None, 8, StopBits.One);
port.ReadBufferSize=300;
port.WriteBufferSize=300;
port.Open();
port.DiscardInBuffer();
SendRaw(port, disconnectAll, tmpBuf); // Send Disconnect
Thread.Sleep(500);
cnt=-1;
tryCnt=30;
escChar=false;
length=-1;
found=false;
while(--tryCnt>0) {
if(GetPacket(port, ref length, buf, ref cnt, ref escChar)) {
var msgTyp=(MsMessageType)(buf[0]>1?buf[1]:buf[3]);
if(msgTyp==MsMessageType.SEARCHGW || msgTyp==MsMessageType.DHCP_REQ) { // Received Ack
found=true;
MsGSerial gw;
lock(_gates) {
gw=new MsGSerial(port);
_gates.Add(gw);
}
MsDevice.ProcessInPacket(gw, gw._gateAddr, buf, 0, cnt);
break;
} else if(_verbose.value) {
Log.Debug("r {0}: {1} {2}", pns[i], BitConverter.ToString(buf, 0, cnt), msgTyp);
}
SendRaw(port, disconnectAll, tmpBuf); // Send Disconnect
}
Thread.Sleep(90);
}
if(!found) {
port.Close();
continue;
}
}
catch(Exception ex) {
if(_verbose.value) {
Log.Debug("MQTT-SN.Serial search on {0} - {1}", pns[i], ex.Message);
}
try {
if(port!=null) {
if(port!=null && port.IsOpen) {
port.Close();
}
port.Dispose();
}
}
catch(Exception) {
}
}
port=null;
}
_scanBusy=0;
}
private static bool GetPacket(SerialPort port, ref int length, byte[] buf, ref int cnt, ref bool escChar) {