// tuned to (exactly) the same frequency? public bool SameFrequency(EntryFrequencyUpdate other) { return TxFreq == other.TxFreq && RxFreq == other.RxFreq && Mode == other.Mode && Split == other.Split; }
// all the data settings are equal? public bool Equals(EntryFrequencyUpdate other) { return TxFreq == other.TxFreq && RxFreq == other.RxFreq && Mode == other.Mode && Split == other.Split && NetLetter == other.NetLetter && LeftRight == other.LeftRight; }
/* As we find Entry Window's locally (on WriteLog running on this machine) ** update the local ListBox */ private void AddOrUpdateLocal(EntryFrequencyUpdate efu) { foreach (Object o in listBoxLocal.Items) { EntryFrequencyUpdate onScreen = o as EntryFrequencyUpdate; if (onScreen.SameRig(efu)) { bool same = onScreen.Equals(efu); onScreen.UpdateFrom(efu); if (!same) listBoxLocal.Invalidate(); return; } } efu.ListIndex = listBoxLocal.Items.Add(efu); }
/* As we find Entry Window's remotely (via UDP) ** update the remote ListBox. Our UDP listener hears our own ** UDP sends. They are not filted out here, so they appear ** in both ListBox's. That is not really a problem.*/ private void AddOrUpdateRemote(EntryFrequencyUpdate efu) { bool found = false; foreach (Object o in listBoxRemote.Items) { EntryFrequencyUpdate onScreen = o as EntryFrequencyUpdate; if (onScreen.SameRig(efu)) { found = true; bool same = onScreen.Equals(efu); onScreen.UpdateFrom(efu); if (!same) listBoxRemote.Invalidate(); break; } } if (!found) efu.ListIndex = listBoxRemote.Items.Add(efu); /* on hearing from a remote Entry Window rig, ** see if its linked, and, if so, update the local Entry Window */ foreach (Object o in listBoxLocal.Items) { EntryFrequencyUpdate localEntry = o as EntryFrequencyUpdate; EntryFrequencyUpdate linked = localEntry.LinkUpdatesFrom; if (linked != null) { if (linked.SameRig(efu) && localEntry.EntryWindow != null) { /* The SameFrequency/UpdateFrom routine is an optimization ** that prevents multiple quick updates in the case ** where the rig takes time to update */ if (!localEntry.SameFrequency(efu)) { localEntry.EntryWindow.SetLogFrequencyEx(efu.Mode, efu.RxFreq, efu.TxFreq, efu.Split); localEntry.UpdateFrom(efu); listBoxLocal.Invalidate(); } } } } }
// match the frequency of other public void UpdateFrom(EntryFrequencyUpdate other) { TxFreq = other.TxFreq; RxFreq = other.RxFreq; Mode = other.Mode; Split = other.Split; }
public bool SameRig(EntryFrequencyUpdate other) { return other.NetLetter == NetLetter && other.LeftRight == LeftRight; }
private void timer1_Tick(object sender, EventArgs e) { List<EntryFrequencyUpdate> toSend = new List<EntryFrequencyUpdate>(); try { // iterate through the local Entry Window's short netLetter = m_wl.NetLetter; for (short i = 0; ; i++) { ISingleEntry e1 = m_wl.GetEntry(i) as ISingleEntry; if (e1 == null) break; short lr = e1.GetLeftRight(); short mode = 0; double rx = 0; double tx = 0; short split = 0; e1.GetLogFrequency(ref mode, ref rx, ref tx, ref split); EntryFrequencyUpdate efu = new EntryFrequencyUpdate(netLetter, lr, tx, rx, split, mode); efu.EntryWindow = e1; AddOrUpdateLocal(efu); toSend.Add(efu); } } catch { timer1.Enabled = false; MessageBox.Show("Failed to talk to WriteLog"); Close(); } if (toSend.Any()) { // Send a UDP update (one message) for all our active Entry Window rigs. SoapFormatter formatter = new SoapFormatter(); byte[] bytes; using (MemoryStream stream = new MemoryStream()) { foreach (EntryFrequencyUpdate efu in toSend) { formatter.Serialize(stream, efu); } bytes = stream.ToArray(); } // want to broadcast, but can't just send to "255.255.255.255" cuz that goes everywhere on the internet. // Instead, iterate through all the interfaces on this PC and broadcast on each of them. // Only works for interfaces configured for IPv4... System.Net.NetworkInformation.NetworkInterface[] locals = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces(); foreach (System.Net.NetworkInformation.NetworkInterface iface in locals) { if (iface.NetworkInterfaceType == System.Net.NetworkInformation.NetworkInterfaceType.Loopback) continue; if (iface.OperationalStatus != System.Net.NetworkInformation.OperationalStatus.Up) continue; System.Net.NetworkInformation.UnicastIPAddressInformationCollection col = iface.GetIPProperties().UnicastAddresses; foreach (System.Net.NetworkInformation.UnicastIPAddressInformation ad in col) { /* This calculation is IPv4 specific.... */ System.Net.IPAddress broadcast = ad.Address; byte[] addr = broadcast.GetAddressBytes(); byte[] mask = ad.IPv4Mask.GetAddressBytes(); if (addr.Length != mask.Length) continue; uint total = 0; for (int k = 0; k < addr.Length; k++) { total += addr[k]; addr[k] |= (byte)~mask[k]; } if (total == 0) continue; IPAddress bc2 = new System.Net.IPAddress(addr); IPEndPoint ep = new IPEndPoint(bc2, FreqUpdateUdpListener.UDP_PORT); Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); s.SetSocketOption(System.Net.Sockets.SocketOptionLevel.Socket, System.Net.Sockets.SocketOptionName.Broadcast, 1); s.SendTo(bytes, ep); } } } }
// OnReceivedFreq is called from the FreqUpdateUdpListener threaed private void OnReceivedFreq(EntryFrequencyUpdate efu) { // transfer the notification to the Form's thread (Main) InvokeDelegate id = new InvokeDelegate(AddOrUpdateRemote); BeginInvoke(id, efu); }