private async Task <PenInformation> SearchDeviceWithoutWatcher(string macAddress) { string deviceSelector = FIND_UNPAIRED_SELECTOR + $" AND System.Devices.Aep.DeviceAddress:=\"{macAddress.ToUpper()}\""; var deviceInfo = await DeviceInformation.FindAllAsync(deviceSelector, RequestedProperties); var info = deviceInfo.FirstOrDefault(); if (info == null) { return(null); } object value; int rssi = 0; info.Properties.TryGetValue("System.Devices.Aep.SignalStrength", out value); if (value != null) { rssi = (int)value; } PenInformation penInfo = new PenInformation(info); penInfo.MacAddress = macAddress; penInfo.Rssi = rssi; return(penInfo); }
private async Task <List <PenInformation> > SearchDevicesWithoutWatcher(string deviceSelector) { penList.Clear(); var deviceInfo = await DeviceInformation.FindAllAsync(deviceSelector, RequestedProperties); foreach (var info in deviceInfo) { object value; if (info.Properties.TryGetValue("System.Devices.Aep.DeviceAddress", out value)) { if (ValidateMacAddress(value.ToString())) { object valueRssi; int rssi = 0; info.Properties.TryGetValue("System.Devices.Aep.SignalStrength", out valueRssi); if (valueRssi != null) { rssi = (int)valueRssi; } PenInformation penInfo = new PenInformation(info); penInfo.MacAddress = value.ToString(); penInfo.Rssi = rssi; penList.Add(penInfo); } } } return(penList); }
/// <summary> /// Try to connect with the pen. /// </summary> /// <param name="macAddress">Mac address of the pen to connect</param> /// <returns>True or false if the connection is successful</returns> public async Task <bool> Connect(string macAddress) { try { await semaphreSlime.WaitAsync(); PenInformation penInfo = GetPenInformationByAddress(macAddress); if (penInfo == null || penInfo.Protocol == Protocols.NONE) { return(false); } if (penInfo.Protocol == Protocols.V2) { ConnectedDeviceIsLe = true; return(await lePenClient.Connect(penInfo)); } else { ConnectedDeviceIsLe = false; return(await classicPenClient.Connect(macAddress)); } } catch { return(false); } finally { semaphreSlime.Release(); } }
private async void BluetoothLEAdvertisementWatcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args) { if (args.AdvertisementType == BluetoothLEAdvertisementType.ConnectableUndirected) { // 여기서 사용하는 uuid도 상수로 뺄지 고민해볼 필요있음 if (!args.Advertisement.ServiceUuids.Contains(ServiceUuidV1) && !args.Advertisement.ServiceUuids.Contains(ServiceUuidV2)) { return; } // mac address를 안쓰고 virtual mac address를 쓴이유는 advertisement는 굉장히 많이 들어오는 값이기 떄문에 좀더 빠르게 검색하기 위해 if (penList.Exists(x => x.VirtualMacAddress == args.BluetoothAddress)) { return; } BluetoothLEDevice bleDevice = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress); PenInformation penCtrl = new PenInformation(bleDevice.DeviceInformation); string mac = string.Empty; foreach (var data in args.Advertisement.DataSections) { if (data.DataType == 0xFF) { var b = new byte[data.Data.Length]; using (var reader = DataReader.FromBuffer(data.Data)) { reader.ReadBytes(b); } mac = BitConverter.ToString(b); mac.Replace('-', ':'); break; } } // 현재 방식에서는 필요가 없어서 일단 제거해둠 //Protocol protocol = Client.Protocol.PenCommV1; //if ( args.Advertisement.ServiceUuids.Contains(MakeServiceUuid(0x19f1)) ) //{ // protocol = Client.Protocol.PenCommV2; //} //else if ( args.Advertisement.ServiceUuids.Contains(MakeServiceUuid(0x18f1)) ) //{ // protocol = Client.Protocol.PenCommV1; //} //else { /* error */ } //penInfo.protocol = protocol; penCtrl.MacAddress = mac; penList.Add(penCtrl); onAddPenController(this, penCtrl); } else if (args.AdvertisementType == BluetoothLEAdvertisementType.ScanResponse) { // ScanResponse에 name이 추가정보로 오는데 DeviceInformaion을 가져오면 Name을 알 수 있기 때문에 추가로 받아 처리할 필요는 아직까진 없다. } }
/// <summary> /// Connect the client to a remote bluetooth host using mac address /// </summary> /// <param name="macAddress">The mac address of the remote host</param> /// <returns>When this method completes successfully, it returns a boolean result</returns> public async Task <bool> Connect(string macAddress) { List <PenInformation> penList = await FindPairedDevices(); PenInformation find = penList.Find(x => x.MacAddress.ToUpper() == macAddress.ToUpper()); if (find == null) { find = await FindUnpairedDevice(macAddress); } if (find == null) { return(false); } return(await Connect(find)); }
/// <summary> /// Try to connect with the pen in the bluetooth classic way. /// </summary> /// <param name="penInformation">PenInformation instance that holds the pen's information</param> /// <returns>True or false if the connection is successful</returns> public async Task <bool> ConnectByClassic(PenInformation penInformation) { try { await semaphreSlime.WaitAsync(); if (penInformation == null || penInformation.Protocol == Protocols.NONE) { return(false); } ConnectedDeviceIsLe = false; return(await classicPenClient.Connect(penInformation)); } catch { return(false); } finally { semaphreSlime.Release(); } }
/// <summary> /// To conduct pairing with the specified device /// </summary> /// <param name="penInformation">The instance of PenInformation class</param> /// <returns>When this method completes successfully, it returns a boolean result</returns> public async Task <bool> Pairing(PenInformation penInformation) { if (penInformation.deviceInformation == null) { return(false); } var result = await penInformation.deviceInformation.Pairing.PairAsync(); switch (result.Status) { case DevicePairingResultStatus.Paired: case DevicePairingResultStatus.AlreadyPaired: return(true); //case DevicePairingResultStatus.AccessDenied: //case DevicePairingResultStatus.AuthenticationFailure: //case DevicePairingResultStatus.AuthenticationNotAllowed: //case DevicePairingResultStatus.AuthenticationTimeout: //case DevicePairingResultStatus.ConnectionRejected: //case DevicePairingResultStatus.Failed: //case DevicePairingResultStatus.HardwareFailure: //case DevicePairingResultStatus.InvalidCeremonyData: //case DevicePairingResultStatus.NoSupportedProfiles: //case DevicePairingResultStatus.NotPaired: //case DevicePairingResultStatus.NotReadyToPair: //case DevicePairingResultStatus.OperationAlreadyInProgress: //case DevicePairingResultStatus.PairingCanceled: //case DevicePairingResultStatus.ProtectionLevelCouldNotBeMet: //case DevicePairingResultStatus.RejectedByHandler: //case DevicePairingResultStatus.RemoteDeviceHasAssociation: //case DevicePairingResultStatus.RequiredHandlerNotRegistered: //case DevicePairingResultStatus.TooManyConnections: // return false; default: return(false); } }
// 람다식을 써도되지만 함수로 굳이 쓴 이유는 가독성 private void DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation args) { string mac = GetMacAddressFromDeviceID(args.Id); if (penList.Exists(x => x.MacAddress == mac)) { return; } if (ValidateMacAddress(mac)) { object value; int rssi = 0; args.Properties.TryGetValue("System.Devices.Aep.SignalStrength", out value); if (value != null) { rssi = (int)value; } PenInformation penInfo = new PenInformation(args); penInfo.MacAddress = mac; penInfo.Rssi = rssi; onAddPenController(this, penInfo); } }
/// <summary> /// To conduct unpairing with the specified device /// </summary> /// <param name="penInformation">The instance of PenInformation class</param> /// <returns>When this method completes successfully, it returns a boolean result</returns> public async Task <bool> UnPairing(PenInformation penInformation) { if (penInformation.deviceInformation == null) { return(false); } var result = await penInformation.deviceInformation.Pairing.UnpairAsync(); switch (result.Status) { case DeviceUnpairingResultStatus.Unpaired: case DeviceUnpairingResultStatus.AlreadyUnpaired: return(true); //case DeviceUnpairingResultStatus.AccessDenied: //case DeviceUnpairingResultStatus.Failed: //case DeviceUnpairingResultStatus.OperationAlreadyInProgress: // return false; default: return(false); } }
/// <summary> /// Connect the client to a remote bluetooth host using PenInformation instance /// </summary> /// <param name="penInformation">The instance of PenInformation class</param> /// <returns>When this method completes successfully, it returns a boolean result</returns> public async Task <bool> Connect(PenInformation penInformation) { try { // lock try 블럭 안으로 이동 await semaphreSlime.WaitAsync(); if (Alive) { return(false); } bool ret = await Pairing(penInformation); if (ret == false) { return(false); } // 소켓을 멤버 변수로 가지고 있게끔 streamSocket = new StreamSocket(); //BluetoothDevice bluetoothDevice = await BluetoothDevice.FromIdAsync(penInformation.deviceInformation.Id); // le의 deviceinformation id를 이용해 BluetoothDevice를 가져올 수 없기 때문에 이런식으로 우회함 BluetoothDevice bluetoothDevice = await BluetoothDevice.FromBluetoothAddressAsync(penInformation.BluetoothAddress); if (bluetoothDevice == null) { return(false); } //var rfcommServices = await bluetoothDevice.GetRfcommServicesForIdAsync(RfcommServiceId.SerialPort, BluetoothCacheMode.Uncached); var rfcommServices = await bluetoothDevice.GetRfcommServicesForIdAsync(RfcommServiceId.FromUuid(RfcommServiceId.SerialPort.Uuid), BluetoothCacheMode.Uncached); RfcommDeviceService chatService = null; if (rfcommServices.Services.Count > 0) { chatService = rfcommServices.Services[0]; } else { return(false); } await streamSocket.ConnectAsync(bluetoothDevice.HostName, chatService.ConnectionServiceName); // 여기가 좀 지저분함 PenController.Protocol = penInformation.Protocol == Protocols.V2 || bluetoothDevice.ClassOfDevice.RawValue == ClassOfDeviceV2 ? Protocols.V2 : Protocols.V1; await Task.Delay(200); Bind(streamSocket); } catch (Exception ex) { switch ((uint)ex.HResult) { case (0x80070490): // ERROR_ELEMENT_NOT_FOUND return(false); case (0x800710DF): // ERROR_DEVICE_NOT_AVAILABLE return(false); default: Debug.WriteLine($"Exception : {ex.Message}"); Debug.WriteLine($"Exception : {ex.StackTrace}"); return(false); } } finally { semaphreSlime.Release(); } return(true); }
private void LePenClient_onAddPenController(IPenClient sender, PenInformation args) { onAddPenController?.Invoke(this, args); }
/// <summary> /// To conduct unpairing with the specified device /// </summary> /// <param name="penInformation">The instance of PenInformation class</param> /// <returns>When this method completes successfully, it returns a boolean result</returns> public async Task <bool> UnPairing(PenInformation penInformation) { return(await classicPenClient.UnPairing(penInformation)); }