Ejemplo n.º 1
0
        public async Task Init(GattLocalService gatt)
        {
            var ch = await gatt.CreateCharacteristicAsync(
                this.Uuid,
                new GattLocalCharacteristicParameters
            {
                CharacteristicProperties = this.ToNative(this.Properties),

                ReadProtectionLevel = this.Permissions.HasFlag(GattPermissions.ReadEncrypted)
                        ? GattProtectionLevel.EncryptionAndAuthenticationRequired
                        : GattProtectionLevel.Plain,

                WriteProtectionLevel = this.Permissions.HasFlag(GattPermissions.WriteEncrypted)
                        ? GattProtectionLevel.EncryptionAndAuthenticationRequired
                        : GattProtectionLevel.Plain,
            }
                );

            foreach (var descriptor in this.Descriptors.OfType <IUwpGattDescriptor>())
            {
                await descriptor.Init(ch.Characteristic);
            }
            this.native = ch.Characteristic;
            this.nativeReady.OnNext(ch.Characteristic);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MSFTReadLongCharacteristic" /> class.
 /// </summary>
 /// <param name="characteristic">Characteristic this wraps</param>
 public MicrosoftReadLongCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service)
 {
     for (int i = 0; i < longCharacteristicData.Length; i++)
     {
         longCharacteristicData[i] = (byte)(i % 10);
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Base implementation for the read callback
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        protected virtual void Characteristic_ReadRequested(GattLocalCharacteristic sender, GattReadRequestedEventArgs args)
        {
            // Grab the event deferral before performing any async operations in the handler.
            var deferral = args.GetDeferral();

            Characteristic_ReadRequested(sender, args, deferral);
        }
        /// <summary>
        /// Starts the Heart rate service
        /// </summary>
        public override async Task Init()
        {
            await CreateServiceProvider(GattServiceUuids.HeartRate);

            // Preparing the Blood pressure characteristics
            var heartRateCharacteristics = PlainNotifyParameters;

            heartRateCharacteristics.UserDescription = "Heart Rates in Beats per Minute";
            heartRateCharacteristics.PresentationFormats.Add(
                GattPresentationFormat.FromParts(
                    Convert.ToByte(PresentationFormats.FormatTypes.Unsigned16BitInteger),
                    PresentationFormats.Exponent,
                    Convert.ToUInt16(PresentationFormats.Units.PeriodBeatsPerMinute),
                    Convert.ToByte(PresentationFormats.NamespaceId.BluetoothSigAssignedNumber),
                    PresentationFormats.Description));

            // Create the heart rate characteristic for the service
            GattLocalCharacteristicResult result =
                await ServiceProvider.Service.CreateCharacteristicAsync(
                    GattCharacteristicUuids.HeartRateMeasurement,
                    PlainNotifyParameters);

            // Grab the characterist object from the service set it to the HeartRate property which is of a specfic Characteristic type
            GattLocalCharacteristic baseHeartRateMeasurement = null;

            GattServicesHelper.GetCharacteristicsFromResult(result, ref baseHeartRateMeasurement);

            if (baseHeartRateMeasurement != null)
            {
                HeartRateMeasurement = new Characteristics.HeartRateMeasurementCharacteristic(baseHeartRateMeasurement, this);
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// handles Reads on the STDOUT characteristic.  If the command thread is done, restart command thread.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private async void WriteCharacteristic_WriteRequested(GattLocalCharacteristic sender, GattWriteRequestedEventArgs args)
        {
            var deferral = args.GetDeferral();

            var request = await args.GetRequestAsync();

            var reader = DataReader.FromBuffer(request.Value);

            //string data = reader.ReadString(reader.UnconsumedBufferLength);
            byte[] data = new byte[reader.UnconsumedBufferLength];
            reader.ReadBytes(data);
            if (cmd.getCmdRunning() == true)
            {
                cmd.writeStdin(data);
                Indicate();
            }
            else
            {
                cmd.startCommand();
                Indicate();
            }

            if (request.Option == GattWriteOption.WriteWithResponse)
            {
                request.Respond();
            }

            deferral.Complete();
        }
        /// <summary>
        /// Base implementation for the read callback
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private async void Characteristic_ReadRequested(GattLocalCharacteristic sender, GattReadRequestedEventArgs args)
        {
            // Grab the event deferral before performing any async operations in the handler.
            var deferral = args.GetDeferral();

            Debug.WriteLine($"({this.GetType()})Entering base.Characteristic_ReadRequested");

            // In order to get the remote request, access to the device must be provided by the user.
            // This can be accomplished by calling BluetoothLEDevice.RequestAccessAsync(), or by getting the request on the UX thread.
            //
            // Note that subsequent calls to RequestAccessAsync or GetRequestAsync for the same device do not need to be called on the UX thread.
            await CoreApplication.MainView.CoreWindow.Dispatcher.RunTaskAsync(
                async() =>
            {
                var request = await args.GetRequestAsync();
                if (request != null)
                {
                    Debug.WriteLine($"Characteristic_ReadRequested - Length {request.Length}, State: {request.State}, Offset: {request.Offset}");

                    if (!ReadRequested(args.Session, request))
                    {
                        request.RespondWithValue(Value);
                    }
                }
                else
                {
                    var Msg = new MessageDialog("There was a communication issue. As a temporary workaround, please try pairing the device with Windows first.", "BLE HackMe Comm. Issue");
                    await Msg.ShowAsync();
                }

                deferral.Complete();
            });
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Starts the Heart rate service
        /// </summary>
        public override async Task Init()
        {
            await CreateServiceProvider(GattServiceUuids.HeartRate);

            // Preparing the heart rate characteristics
            var heartRateCharacteristicsParameters = PlainReadNotifyParameters;

            //random 4 digits added to manufacturer specific advertisement text
            Random rnd = new Random();

            randomForDescriptor = Convert.ToString(rnd.Next(1000, 9999));

            heartRateCharacteristicsParameters.UserDescription = $"{Constants.heartRateDescriptorText}{randomForDescriptor}";

            // Create the heart rate characteristic for the service
            GattLocalCharacteristicResult result =
                await ServiceProvider.Service.CreateCharacteristicAsync(
                    GattCharacteristicUuids.HeartRateMeasurement,
                    heartRateCharacteristicsParameters);

            // Grab the characteristic object from the service set it to the HeartRate property which is of a specfic Characteristic type
            GattLocalCharacteristic baseHeartRateMeasurement = null;

            BLEServices.Helpers.GetCharacteristicsFromResult(result, ref baseHeartRateMeasurement);

            if (baseHeartRateMeasurement != null)
            {
                HeartRateMeasurement = new BLEServices.HeartRateMeasurementCharacteristic(baseHeartRateMeasurement, this);
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Asynchronous initialization
        /// </summary>
        /// <returns>Initialization Task</returns>
        public override async Task Init()
        {
            await CreateServiceProvider(GattServiceUuids.Battery);

            // Preparing the Battery Level characteristics
            GattLocalCharacteristicParameters batteryCharacteristicsParameters = PlainReadParameters;

            // Set the user descriptions
//            batteryCharacteristicsParameters.UserDescription = "Battery Level percentage remaining";

            // Create the characteristic for the service
            GattLocalCharacteristicResult result =
                await ServiceProvider.Service.CreateCharacteristicAsync(
                    GattCharacteristicUuids.BatteryLevel,
                    batteryCharacteristicsParameters);

            // Grab the characterist object from the service set it to the BatteryLevel property which is of a specfic Characteristic type
            GattLocalCharacteristic baseBatteryLevel = null;

            BLEServices.Helpers.GetCharacteristicsFromResult(result, ref baseBatteryLevel);

            if (baseBatteryLevel != null)
            {
                BatteryLevel = new BLEServices.BatteryLevelCharacteristic(baseBatteryLevel, this);
            }
        }
Ejemplo n.º 9
0
        //---------------------------------------------------------------------
        // Event callback for Write
        //---------------------------------------------------------------------

        protected virtual void Characteristic_WriteRequested(
            GattLocalCharacteristic sender,
            GattWriteRequestedEventArgs args
            )
        {
            Characteristic_WriteRequested(sender, args, args.GetDeferral());
        }
Ejemplo n.º 10
0
        // Helper function for async Read callback
        protected virtual async void Characteristic_ReadRequested(
            GattLocalCharacteristic sender,
            GattReadRequestedEventArgs args,
            Deferral deferral = null
            )
        {
            Debug.WriteLine($"base.Characteristic_ReadRequested Entry");

            // Get an event deferral for async operations if we don't have one
            if (deferral == null)
            {
                deferral = args.GetDeferral();
            }

            //
            // Normally, GetRequestAsync() is recommended to run on a UI thread
            // because, even with paired devices, the device may prompt the
            // user for consent. But, we're running in a background service so
            // we won't run this on a UI thread. According to one of the devs
            // on the core Bluetooth team, because this is for a "test
            // application," consent prompts are not currently part of MS's
            // policy and it will be auto-accepted.
            //
            var request = await args.GetRequestAsync();

            request.RespondWithValue(Value);
            Debug.WriteLine($"Characteristic ReadRequested- Length: " +
                            $"{request.Length}, State: {request.State}, " +
                            $"Offset: {request.Offset}"
                            );

            deferral.Complete();

            Debug.WriteLine("base.Characteristic_ReadRequested Exit");
        }
Ejemplo n.º 11
0
        //---------------------------------------------------------------------
        // Event callback for when number of subscribers to this characteristic
        // change
        //---------------------------------------------------------------------

        protected virtual void Characteristic_SubscribedClientsChanged(
            GattLocalCharacteristic sender,
            object args
            )
        {
            Debug.WriteLine("Subscribers: {0}", sender.SubscribedClients.Count());
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MSFTNotifyCharacteristic" /> class.
        /// </summary>
        /// <param name="characteristic">Characteristic this wraps</param>
        public MicrosoftNotifyCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service)
        {
            DataWriter writer = new DataWriter();

            writer.WriteString("Hello World!");
            Value = writer.DetachBuffer();
        }
Ejemplo n.º 13
0
        private void CleanupInternal()
        {
            if (mStatus == Status.Advertise)
            {
                mServiceProvider.StopAdvertising();
            }

            SetStatus(Status.Invalid);

            if (mInitializationCancelTokenSource != null)
            {
                mInitializationCancelTokenSource.Dispose();
                mInitializationCancelTokenSource = null;
            }

            mUploadCharacteristic   = null;
            mDownloadCharacteristic = null;
            mServiceProvider        = null;

            mSubscribedCentrals.Clear();


            // TODO


            mCallback = null;
            mFinished = true;
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Asynchronous initialization
        /// </summary>
        /// <returns>Initialization Task</returns>
        public override async Task Init()
        {
            await CreateServiceProvider(GattServiceUuids.Battery);

            // Preparing the Battery Level characteristics
            GattLocalCharacteristicParameters batteryCharacteristicsParameters = PlainReadNotifyParameters;

            // Set the user descriptions
            batteryCharacteristicsParameters.UserDescription = "Battery Level percentage remaining";

            // Add presentation format - 16-bit integer, with exponent 0, the unit is percentage, defined per Bluetooth SIG with Microsoft as descriptor
            batteryCharacteristicsParameters.PresentationFormats.Add(
                GattPresentationFormat.FromParts(
                    Convert.ToByte(PresentationFormats.FormatTypes.Unsigned8BitInteger),
                    PresentationFormats.Exponent,
                    Convert.ToUInt16(PresentationFormats.Units.Percentage),
                    Convert.ToByte(PresentationFormats.NamespaceId.BluetoothSigAssignedNumber),
                    PresentationFormats.Description));

            // Create the characteristic for the service
            GattLocalCharacteristicResult result =
                await ServiceProvider.Service.CreateCharacteristicAsync(
                    GattCharacteristicUuids.BatteryLevel,
                    batteryCharacteristicsParameters);

            // Grab the characterist object from the service set it to the BatteryLevel property which is of a specfic Characteristic type
            GattLocalCharacteristic baseBatteryLevel = null;

            GattServicesHelper.GetCharacteristicsFromResult(result, ref baseBatteryLevel);

            if (baseBatteryLevel != null)
            {
                BatteryLevel = new Characteristics.BatteryLevelCharacteristic(baseBatteryLevel, this);
            }
        }
        private async void ResultCharacteristic_ReadRequestedAsync(GattLocalCharacteristic sender, GattReadRequestedEventArgs args)
        {
            // BT_Code: Process a read request.
            using (args.GetDeferral())
            {
                // Get the request information.  This requires device access before an app can access the device's request.
                GattReadRequest request = await args.GetRequestAsync();

                if (request == null)
                {
                    // No access allowed to the device.  Application should indicate this to the user.
                    rootPage.NotifyUser("Access to device not allowed", NotifyType.ErrorMessage);
                    return;
                }

                var writer = new DataWriter();
                writer.ByteOrder = ByteOrder.LittleEndian;
                writer.WriteInt32(resultVal);

                // Can get details about the request such as the size and offset, as well as monitor the state to see if it has been completed/cancelled externally.
                // request.Offset
                // request.Length
                // request.State
                // request.StateChanged += <Handler>

                // Gatt code to handle the response
                request.RespondWithValue(writer.DetachBuffer());
            }
        }
        private async Task CreateCharacteristics(GattServiceProvider gattServiceProvider)
        {
            var statusCharacteristicParams = new GattLocalCharacteristicParameters
            {
                CharacteristicProperties = GattCharacteristicProperties.Read | GattCharacteristicProperties.Notify,
                WriteProtectionLevel     = GattProtectionLevel.Plain,
                UserDescription          = "Status Characteristic"
            };

            statusCharacteristicParams.PresentationFormats.Add(GattPresentationFormat.FromParts(GattPresentationFormatTypes.Utf8,
                                                                                                GattPresentationFormatExponent,
                                                                                                GattPresentationFormatUnitless,
                                                                                                GattPresentationFormatNamespaceId,
                                                                                                GattPresentationFormatDescription));

            var statusCharacteristicResult = await gattServiceProvider.Service.CreateCharacteristicAsync(
                BluetoothConstants.StatusCharacteristicUuid,
                statusCharacteristicParams);

            if (statusCharacteristicResult.Error != BluetoothError.Success)
            {
                throw new InvalidOperationException($"Failed to create GATT status characteristic with error {statusCharacteristicResult.Error}");
            }

            _statusCharacteristic = statusCharacteristicResult.Characteristic;

            var commandCharacteristicResult = await gattServiceProvider.Service.CreateCharacteristicAsync(
                BluetoothConstants.CommandCharacteristicUuid,
                new GattLocalCharacteristicParameters
            {
                CharacteristicProperties = GattCharacteristicProperties.Write
                                           | GattCharacteristicProperties.WriteWithoutResponse,
                WriteProtectionLevel = GattProtectionLevel.Plain,
                UserDescription      = "Command Characteristic"
            });

            if (commandCharacteristicResult.Error != BluetoothError.Success)
            {
                throw new InvalidOperationException($"Failed to create GATT command characteristic with error {commandCharacteristicResult.Error}");
            }

            var brightnessCharacteristicResult = await gattServiceProvider.Service.CreateCharacteristicAsync(
                BluetoothConstants.BrightnessCharacteristicUuid,
                new GattLocalCharacteristicParameters
            {
                CharacteristicProperties = GattCharacteristicProperties.Write
                                           | GattCharacteristicProperties.WriteWithoutResponse,
                WriteProtectionLevel = GattProtectionLevel.Plain,
                UserDescription      = "Brightness Characteristic"
            });

            if (brightnessCharacteristicResult.Error != BluetoothError.Success)
            {
                throw new InvalidOperationException($"Failed to create GATT brightness characteristic with error {brightnessCharacteristicResult.Error}");
            }

            _statusCharacteristic.ReadRequested += StatusCharacteristic_ReadRequested;
            commandCharacteristicResult.Characteristic.WriteRequested    += CommandCharacteristic_WriteRequested;
            brightnessCharacteristicResult.Characteristic.WriteRequested += BrightnessCharacteristic_WriteRequested;
        }
        private async void WifiListCharacteristic_ReadRequestedAsync(GattLocalCharacteristic sender, GattReadRequestedEventArgs args)
        {
            using (args.GetDeferral())
            {
                // Get the request information.  This requires device access before an app can access the device's request.
                GattReadRequest request = await args.GetRequestAsync();

                if (request == null)
                {
                    // No access allowed to the device.  Application should indicate this to the user.
                    return;
                }

                var writer = new DataWriter();

                var result = JsonConvert.SerializeObject(
                    new WIfiNetworkPayload
                {
                    AvailableAdapters =
                        this.WiFiAdapter.NetworkReport.AvailableNetworks.Select(x => new WifiNetwork {
                        Ssid = x.Ssid
                    })
                });

                writer.WriteString(result);
                //var wifiAdapters =
                //writer.WriteString("{ \"AvailableAdapters\": [{ \"Ssid\": \"ilab\" }, { \"Ssid\": \"uqconnect\" }] }");

                // Gatt code to handle the response
                request.RespondWithValue(writer.DetachBuffer());
            }
        }
        private async void writeRemoteCanStop(GattLocalCharacteristic sender, GattWriteRequestedEventArgs args)
        {
            var deferral = args.GetDeferral();
            var request  = await args.GetRequestAsync();

            if (request == null)
            {
                Debug.WriteLine("Write of Can Stop had a null request! Make sure the application manifest allows Bluetooth access.");
                deferral.Complete();
                return;
            }

            // The "Can Stop" characteristic is a single byte of data - 0 for false, and 1 for true.
            var reader = DataReader.FromBuffer(request.Value);

            if (reader.UnconsumedBufferLength > 0)
            {
                var value = reader.ReadByte();
                await eventDispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    canStop = value > 0;
                    Debug.WriteLine("Can Stop is now: {0}", canStop);
                    StateChanged?.Invoke(this, null);
                });
            }

            if (request.Option == GattWriteOption.WriteWithResponse)
            {
                request.Respond();
            }

            deferral.Complete();
        }
 public void Dispose()
 {
     // Windows BLE seems to get unreliable if services etc aren't disposed correctly.
     if (continueButtonCharacteristic != null)
     {
         continueButtonCharacteristic.ReadRequested            -= readContinueButtonValue;
         continueButtonCharacteristic.SubscribedClientsChanged -= subscribedClientsChanged;
         continueButtonCharacteristic = null;
     }
     if (stopButtonCharacteristic != null)
     {
         stopButtonCharacteristic.ReadRequested -= readStopButtonValue;
         stopButtonCharacteristic = null;
     }
     if (remoteCanContinueCharacteristic != null)
     {
         remoteCanContinueCharacteristic.WriteRequested -= writeRemoteCanContinue;
         remoteCanContinueCharacteristic = null;
     }
     if (remoteCanStopCharacteristic != null)
     {
         remoteCanStopCharacteristic.WriteRequested -= writeRemoteCanStop;
         remoteCanStopCharacteristic = null;
     }
     if (userMessageCharacteristic != null)
     {
         userMessageCharacteristic.WriteRequested -= writeUserMessage;
         userMessageCharacteristic = null;
     }
     if (cascableService != null)
     {
         cascableService.StopAdvertising();
         cascableService = null;
     }
 }
Ejemplo n.º 20
0
        private void OnCharacteristicSubscribedClientsChanged(GattLocalCharacteristic characteristic, object args)
        {
            Utils.Info("OnCharacteristicSubscribedClientsChanged");

            // TODO
            var unsubscribedCentrals = mSubscribedCentrals.Where(ctx => !characteristic.SubscribedClients.Contains(ctx.client)).ToList(); // Unsubscribed

            foreach (var context in unsubscribedCentrals)
            {
                Utils.Info("unsubscribed: {0}", context.client.Session.DeviceId.Id);
                RemoveCentral(context);
            }

            foreach (var client in characteristic.SubscribedClients)
            {
                if (!mSubscribedCentrals.Exists(ctx => { return(ctx.client == client); })) // Subscribed
                {
                    Utils.Info("subscribed: {0}", client.Session.DeviceId.Id);

                    client.Session.SessionStatusChanged += OnSessionStatusChanged;

                    var context = new CentralContext(client);


                    // TODO: timeout


                    mSubscribedCentrals.Add(context);
                }
            }
        }
        protected override void Characteristic_SubscribedClientsChanged(GattLocalCharacteristic sender, object args)
        {
            lock (this)
            {
                if (sender.SubscribedClients.Count == 0)
                {
                    if (m_timeUpdate != null)
                    {
                        m_timeUpdate.Cancel();
                        m_timeUpdate = null;
                    }
                }
                else if (m_timeUpdate == null)
                {
                    m_timeUpdate = ThreadPoolTimer.CreatePeriodicTimer(
                        (source) =>
                    {
                        UpdateCurrentTimeValue();
                        NotifyValue();
                    },
                        TimeSpan.FromMinutes(15));
                }
            }

            base.Characteristic_SubscribedClientsChanged(sender, args);
        }
Ejemplo n.º 22
0
        private async void OnWriteMessage(GattLocalCharacteristic sender, GattWriteRequestedEventArgs args)
        {
            var deferral = args.GetDeferral();

            try
            {
                var req = await args.GetRequestAsync();

                var reader = DataReader.FromBuffer(req.Value);

                var buf = new byte[reader.UnconsumedBufferLength];
                reader.ReadBytes(buf);
                var xml = DMessenger.MessageEncoder.Decode(buf);
                var msg = new DMessenger.Message(xml);

                if (req.Option == GattWriteOption.WriteWithResponse)
                {
                    req.Respond();
                }
            }
            finally
            {
                deferral.Complete();
            }
        }
Ejemplo n.º 23
0
        private void HandleError()
        {
            mUploadCharacteristic   = null;
            mDownloadCharacteristic = null;
            mServiceProvider        = null;

            mCallback.OnFail();
        }
 private async void subscribedClientsChanged(GattLocalCharacteristic sender, object args)
 {
     await eventDispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
     {
         Debug.WriteLine("Subscribed clients changed!!");
         StateChanged?.Invoke(this, null);
     });
 }
Ejemplo n.º 25
0
 private async void Op1Characteristic_WriteRequestedAsync(GattLocalCharacteristic sender, GattWriteRequestedEventArgs args)
 {
     // BT_Code: Processing a write request.
     using (args.GetDeferral())
     {
         PlayMusic();
     }
 }
        //---------------------------------------------------------------------
        // Write request callback to receive the header length of an IPv6
        // packet that had its header compressed
        //---------------------------------------------------------------------

        protected override void Characteristic_WriteRequested(
            GattLocalCharacteristic sender,
            GattWriteRequestedEventArgs args
            )
        {
            // Receive the Write request into this characteristic's Value buffer
            base.Characteristic_WriteRequested(sender, args);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="BatteryLevelCharacteristic" /> class.
        /// </summary>
        /// <param name="characteristic">The characteristic that this wraps</param>
        public BatteryLevelCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service)
        {
            // generate random value 1-100%
            Random rnd = new Random();

            batteryLevelIndication = rnd.Next(1, 100);
            Value = BLEServices.Helpers.ToIBuffer(batteryLevelIndication);
        }
Ejemplo n.º 28
0
        internal async Task <bool> Initialize()
        {
            try
            {
                GattServiceProviderResult result = await GattServiceProvider.CreateAsync(_serviceId);

                if (result.Error != BluetoothError.Success)
                {
                    Robot.Message("can't create GATT BlueTooth service with id " + _serviceId.ToString(), MessageType.Error);
                    Robot.Message("without bluetooth service, remote controller won't work", MessageType.Warning);
                    return(_init);
                }
                _service = result.ServiceProvider;

                byte[] value = new byte[] { 0x21 };
                var    constantParameters = new GattLocalCharacteristicParameters
                {
                    CharacteristicProperties = (GattCharacteristicProperties.Read),
                    StaticValue         = value.AsBuffer(),
                    ReadProtectionLevel = GattProtectionLevel.Plain,
                };

                GattLocalCharacteristicResult characteristicResult = await _service.Service.CreateCharacteristicAsync(_notifyId, new GattLocalCharacteristicParameters
                {
                    CharacteristicProperties = GattCharacteristicProperties.Notify,
                    ReadProtectionLevel      = GattProtectionLevel.Plain,
                    StaticValue = value.AsBuffer()
                });

                if (characteristicResult.Error != BluetoothError.Success)
                {
                    Robot.Message("can't create GATT BlueTooth service with id " + _serviceId.ToString(), MessageType.Error);
                    Robot.Message("without bluetooth service, remote controller won't work", MessageType.Warning);
                    return(_init);
                }
                _notifyCharacteristic = characteristicResult.Characteristic;
                //_notifyCharacteristic.SubscribedClientsChanged += _btNotify_SubscribedClientsChanged;

                GattServiceProviderAdvertisingParameters advParameters = new GattServiceProviderAdvertisingParameters
                {
                    IsDiscoverable = true,
                    IsConnectable  = true
                };
                _service.StartAdvertising(advParameters);
                Robot.Message("created Bluetooth GATT service with id " + _serviceId.ToString(), MessageType.Success);
                _init = true;
            }
            catch (Exception x)
            {
                while (x != null)
                {
                    Robot.Message(x.Message, MessageType.Error);
                    x = x.InnerException;
                }
                Robot.Message("without bluetooth service, remote controller won't work", MessageType.Warning);
            }
            return(_init);
        }
        /// <summary>
        /// Base implementation for the write callback
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private async void Characteristic_WriteRequested(GattLocalCharacteristic sender, GattWriteRequestedEventArgs args)
        {
            Debug.WriteLine("Characteristic_WriteRequested: Write Requested");

            // Grab the event deferral before performing any async operations in the handler.
            var deferral = args.GetDeferral();

            // In order to get the remote request, access to the device must be provided by the user.
            // This can be accomplished by calling BluetoothLEDevice.RequestAccessAsync(), or by getting the request on the UX thread.
            //
            // Note that subsequent calls to RequestAccessAsync or GetRequestAsync for the same device do not need to be called on the UX thread.
            await CoreApplication.MainView.CoreWindow.Dispatcher.RunTaskAsync(
                async() =>
            {
                // Grab the request
                var request = await args.GetRequestAsync();

                Debug.WriteLine($"Characteristic_WriteRequested - Length {request.Value.Length}, State: {request.State}, Offset: {request.Offset}");

                // WriteRequested overriden if needed to set up the Value
                // if not - set the Value here
                if (!WriteRequested(args.Session, request))
                {
                    // Set the characteristic Value
                    Value = request.Value;
                }
                else
                {
                    Debug.WriteLine("Characteristic_WriteRequested: Looks like write completed in derived class");
                }

                // Complete request (respond with confirmation in case of WRITE REQ) even if the overriden WriteRequested did not change the Value.
                // As side effect this will show in nRF Connect that the value has changed even if it hasn't.
                if (request.Option == GattWriteOption.WriteWithResponse)
                {
                    Debug.WriteLine("Characteristic_WriteRequested: Completing request with responds");
                    request.Respond();
                }
                else
                {
                    Debug.WriteLine("Characteristic_WriteRequested: Completing request without responds");
                }

                byte[] data;
                CryptographicBuffer.CopyToByteArray(Value, out data);

                if (data == null)
                {
                    Debug.WriteLine("Characteristic_WriteRequested: Value after write complete was NULL");
                }
                else
                {
                    Debug.WriteLine($"Characteristic_WriteRequested: New Value: {data.BytesToString()}");
                }

                deferral.Complete();
            });
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Read request callback to update the value
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        protected override async void Characteristic_ReadRequested(GattLocalCharacteristic sender, GattReadRequestedEventArgs args)
        {
            Deferral deferral = args.GetDeferral();

            Debug.WriteLine($"MSFTLongReadCharacteristic: ReadRequested - MaxPduSize {args.Session.MaxPduSize}");
            await UpdateValue(args);

            base.Characteristic_ReadRequested(sender, args, deferral);
        }