예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        /// <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();
            }
        }
예제 #4
0
        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을 알 수 있기 때문에 추가로 받아 처리할 필요는 아직까진 없다.
            }
        }
예제 #5
0
        /// <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));
        }
예제 #6
0
        /// <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();
            }
        }
예제 #7
0
        /// <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);
            }
        }
예제 #8
0
        // 람다식을 써도되지만 함수로 굳이 쓴 이유는 가독성
        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);
            }
        }
예제 #9
0
        /// <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);
            }
        }
예제 #10
0
        /// <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);
        }
예제 #11
0
 private void LePenClient_onAddPenController(IPenClient sender, PenInformation args)
 {
     onAddPenController?.Invoke(this, args);
 }
예제 #12
0
 /// <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));
 }