/// <summary> /// This thread method continually loops through the set of managed /// BluetoothConnections, aggregating and dispatching sequences /// of pending commands from each connection in a round-robin fashion. /// </summary> /// <remarks> /// Notes on scheduling: /// Step through and process all pending commands for now... /// /// Should really be doing time slicing because in many situations the next command /// from a connection may not come in until the last one was completed /// /// Each connection should maintain it's own device state/config. /// Depending on how well/whether device states/configs match between connections, /// we should be able to overlap certain AT commands (like device queries when /// in INQUIRY/PAGE/SCAN mode) and combine results of others (just did an INQUIRY, /// so timestamp result and return that result to any other connections asking). /// /// Should also guarantee that if a single thread exists, it will not be connected, /// disconnected, etc. It just does what it needs to without interruption /// </remarks> private void AggregateAndDispatch() { while (true) { m_newCommand.WaitOne(); // Check if we are terminating this thread and shutdown if (m_outstandingConnections.Count == 0) { break; } if (0 == PendingConnections()) { continue; } BTConnection currentConnection = null; do { BTConnection.BTCmd cmd; currentConnection = (BTConnection)m_connectionsToBeProcessed[0]; m_connectionsToBeProcessed.RemoveAt(0); // Execute the command while (null != (cmd = currentConnection.GetNextCommand())) { bool error = true; m_pp.ApplyPolicy(m_driver, currentConnection, cmd); try { cmd.Execute(currentConnection, m_driver); error = false; currentConnection.CmdCompletedCallback(cmd, error); } catch { // swallow the exception from the user-provided callback } } } while (0 < PendingConnections()); m_pp.ApplyPolicy(m_driver, currentConnection, null); } // end while /////////////////////////////////////// // SHUTDOWN // // Clear the queue on shutdown m_connectionsToBeProcessed.Clear(); // Apply default power policy m_pp.ApplyPolicy(m_driver, null, null); }
public override void Execute(BTConnection conn, BTDriver driver) { conn.Connected = false; conn.IsMaster = false; conn.ConnectedToAddr = null; if (null != this.Address) { this.Success = driver.PageScanForAddress(this.Address, Timeout); } else { this.Success = driver.InquiryAndPageScans(Timeout); if (this.Success) { try { this.Address = driver.GetLastConnectedAddress(); } catch { this.Address = null; } } } conn.Connected = this.Success; conn.ConnectedToAddr = this.Address; }
/// <summary> /// Sets the power state of the provided IPowerState given that the /// specified BTCmd will be executed next. A null BTCmd indicates that /// there are no more pending BTCmds to be executed from any connection. /// </summary> /// <param name="ips"> /// The IPowerState /// </param> /// <param name="conn"> /// The BTConnection for which the BTCmd is being executed. /// </param> /// <param name="cmd"> /// The next BTCmd to be executed, or null if there are no pending BTCmds. /// </param> public void ApplyPolicy(IPowerState ips, BTConnection conn, BTConnection.BTCmd cmd) { lock (this) { if (null != cmd) { // Dispose of the Timer if it's active, then PARK the chip if (null != m_powerOffTimer) { m_powerOffTimer.Dispose(); m_powerOffTimer = null; } PowerState state = PowerState.Park; while (!ips.SetPowerState(ref state)) { Thread.Sleep(1); } } else { // Then set a Timer that will turn the chip OFF if no new commands in the specified timeout if (null == conn || !conn.Connected) { if (null == m_powerOffTimer) { m_powerOffTimer = new Timer(PowerOffTimerFired, ips, c_powerOffTimeout, Timeout.Infinite); } } } } }
/// <summary> /// Called by a BTConnection after queueing one or more new commands; sets /// the new command event so that the AggregateAndDispatch thread will wake /// up and execute the commands. /// </summary> /// <param name="conn"> /// The calling BTConnection /// </param> internal void OnNewCommand(BTConnection conn) { lock (m_connectionsToBeProcessed) { m_connectionsToBeProcessed.Add(conn); } m_newCommand.Set(); }
public override void Execute(BTConnection conn, BTDriver driver) { Devices = driver.Inquiry(); if (null != Devices) { Success = true; } }
public override void Execute(BTConnection conn, BTDriver driver) { NumReceived = driver.Receive(ref Data, Timeout); Success = (0 <= NumReceived); // Check for disconnect if (!Success) { conn.Connected = false; } }
public BTConnection CreateBTConnection() { if (m_disposed) { throw new InvalidOperationException("Manager was disposed"); } BTConnection conn = new BTConnection(this); m_outstandingConnections.Add(conn); return(conn); }
public override void Execute(BTConnection conn, BTDriver driver) { if (null != Data) { NumSent = driver.Send(Data); Success = (0 <= NumSent); // Check for disconnect if (!Success) { conn.Connected = false; } } }
public override void Execute(BTConnection conn, BTDriver driver) { conn.Connected = false; conn.IsMaster = true; conn.ConnectedToAddr = null; if (null != Address) { Success = driver.PageAddress(Address, Timeout); conn.Connected = this.Success; conn.IsMaster = true; conn.ConnectedToAddr = this.Address; } }
public override void Execute(BTConnection conn, BTDriver driver) { NumReceived = driver.Receive(ref Data, Timeout); Success = (0 <= NumReceived); // Check for disconnect if (!Success) conn.Connected = false; }
public override void Execute(BTConnection conn, BTDriver driver) { this.Success = driver.Disconnect(); conn.Connected = !this.Success; }
internal void RemoveBTConnection(BTConnection conn) { m_outstandingConnections.Remove(conn); }
public override void Execute(BTConnection conn, BTDriver driver) { Success = driver.InquiryScan(Timeout); }
public override void Execute(BTConnection conn, BTDriver driver) { Success = driver.CheckDevicePresent(); }
public override void Execute(BTConnection conn, BTDriver driver) { Success = driver.SetPassKey(PassKey); }
public abstract void Execute(BTConnection conn, BTDriver driver);
public override void Execute(BTConnection conn, BTDriver driver) { Success = driver.SetFriendlyDeviceName(Name); }
public override void Execute(BTConnection conn, BTDriver driver) { if (null != Data) { NumSent = driver.Send(Data); Success = (0 <= NumSent); // Check for disconnect if (!Success) conn.Connected = false; } }
public override void Execute(BTConnection conn, BTDriver driver) { Devices = driver.Inquiry(); if (null != Devices) Success = true; }
public BTConnection CreateBTConnection() { if (m_disposed) throw new InvalidOperationException("Manager was disposed"); BTConnection conn = new BTConnection(this); m_outstandingConnections.Add(conn); return conn; }