/// <summary> /// Get a screenshot, either via wifi or via bluetooth /// </summary> public async void Screenshot() { if (HasWifi) { // wifi connection is enabled, try getting a screenshot via wifi first. Task <byte[]> task = wifi.GetScreenshot(); CancellationTokenSource CancelDelay = new CancellationTokenSource(); CancellationTokenSource CancelFetch = new CancellationTokenSource(); // Wait maximum 1.5s for the screenshot over wifi if (await Task.WhenAny(task, Task.Delay(1500, CancelDelay.Token)) == task) { // GetScreenshot() returned before the timeout, let's check the result byte[] picbuf = await task; CancelDelay.Cancel(); // Cancel the timeout delay, it's no longer needed if (picbuf == null) { // Wifi failed somehow, fallback to bluetooth and disable the wifi client handler.UpdateStatus("Connected (wifi errors)"); HasWifi = false; wifi = null; bt.Send("sc"); } else { // Successfully got a screenshot over wifi Bitmap bitmap = BitmapFactory.DecodeByteArray(picbuf, 0, picbuf.Length); Console.WriteLine("Bitmap (from wifi) ready, sending over to main thread"); handler.ObtainMessage((int)UIUpdateHandler.MessageType.BITMAP, bitmap).SendToTarget(); } } else { // Timeout from wifi... fallback to bluetooth WifiTimeoutCount++; bt.Send("sc"); if (bt.state == BluetoothClient.State.CONNECTED) { handler.UpdateStatus("Connected (flakey wifi?)"); } if (WifiTimeoutCount > 2) { // WiFi timed-out three times, and therefor is not to be trusted. HasWifi = false; wifi = null; if (bt.state == BluetoothClient.State.CONNECTED) { handler.UpdateStatus("Connected (wifi disabled)"); } } } } else { // No wifi, just ask for a screenshot over Bluetooth bt.Send("sc"); } }
/// <summary> /// This method is called as a callback by the bluetooth client when it changes state /// </summary> /// <param name="state"></param> private void StateChangedCallback(BluetoothClient.State state) { if (state == BluetoothClient.State.NOT_CONNECTED) { // Bluetooth client disconnected, make sure we discard the old wifi client HasWifi = false; wifi = null; } }
/// <summary> /// Connect to a BluetoothDevice /// </summary> /// <param name="device">The device you want to connect to</param> /// <returns></returns> public bool Connect(BluetoothDevice device) { if (state != State.NOT_CONNECTED || device == null || paused) { return(true); // Don't try to connect again if the connection is open, don't try to connect to null devices, and don't try to connect when paused } lock ("connectlock") { Console.WriteLine("Connecting to " + device); SetState(State.CONNECTING); this.device = device; sock = device.CreateRfcommSocketToServiceRecord(MY_UUID); try { sock.Connect(); } catch (Java.IO.IOException) { SetState(State.NOT_CONNECTED); handler.UpdateStatus("Connection failed"); Console.WriteLine("Crap, connection failed"); return(false); } Console.WriteLine("Probably connected"); OutStream = sock.OutputStream; InStream = sock.InputStream; SetState(State.CONNECTED); last_ping = DateTime.UtcNow; if (!RecieveThread.IsAlive) { RecieveThread.Start(); } // we don't use Send() here because we want it to be sent first Byte[] handshake = Encoding.UTF8.GetBytes(WifiClient.WifiHandshake(context)); OutStream.Write(handshake, 0, handshake.Length); if (SendQueue.Count > 0) { Send(); // Poke the send thread so we can make sure the queue is proccessed } StartPing(); return(true); } }
/// <summary> /// This method is called as a callback by the bluetooth client when it gets the wifi negotiation handshake. /// </summary> /// <param name="handshake">The wifi negotiation handshake we recieved from the server</param> private void WifiCallback(byte[] handshake) { if (handshake == null) { HasWifi = false; wifi = null; } else { wifi = new WifiClient(handshake); HasWifi = true; if (bt.state == BluetoothClient.State.CONNECTED) { handler.UpdateStatus("Connected (with wifi)"); } } if (bt.state == BluetoothClient.State.CONNECTED) { Screenshot(); // Ask for a screenshot, since the handshake is now complete } }