/// <summary> /// Base implementation for the write callback /// </summary> /// <param name="sender"></param> /// <param name="args"></param> /// <param name="deferral">The deferral in case a specific implementation had to do async tasks</param> protected virtual async void Characteristic_WriteRequested(GattLocalCharacteristic sender, GattWriteRequestedEventArgs args, Deferral deferral) { Debug.WriteLine("Characteristic_WriteRequested: Write Requested"); GattWriteRequest request = null; // Grab the event deferral before performing any async operations in the handler. if (deferral == null) { 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.RunAsync( CoreDispatcherPriority.Normal, async() => { // Grab the request request = await args.GetRequestAsync(); // Set the characteristic Value Value = request.Value; // Respond with completed if (request.Option == GattWriteOption.WriteWithResponse) { Debug.WriteLine("Characteristic_WriteRequested: Completing request with responds"); request.Respond(); } else { Debug.WriteLine("Characteristic_WriteRequested: Completing request without responds"); } // everything below this is debug. Should implement this on non-UI thread based on // https://github.com/Microsoft/Windows-task-snippets/blob/master/tasks/UI-thread-task-await-from-background-thread.md 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()}"); } }); }
/// <summary> /// BT_Code: Processing a write request.Takes in a GATT Write request and updates UX based on opcode. /// </summary> /// <param name="request"></param> /// <param name="opCode">Operand (1 or 2) and Operator (3)</param> private void ProcessWriteCharacteristic(GattWriteRequest request, CalculatorCharacteristics opCode) { if (request.Value.Length != 4) { // Input is the wrong length. Respond with a protocol error if requested. if (request.Option == GattWriteOption.WriteWithResponse) { request.RespondWithProtocolError(GattProtocolError.InvalidAttributeValueLength); } return; } var reader = DataReader.FromBuffer(request.Value); reader.ByteOrder = ByteOrder.LittleEndian; int val = reader.ReadInt32(); switch (opCode) { case CalculatorCharacteristics.Operand1: operand1Received = val; break; case CalculatorCharacteristics.Operand2: operand2Received = val; break; case CalculatorCharacteristics.Operator: if (!Enum.IsDefined(typeof(CalculatorOperators), val)) { if (request.Option == GattWriteOption.WriteWithResponse) { request.RespondWithProtocolError(GattProtocolError.InvalidPdu); } return; } operatorReceived = (CalculatorOperators)val; break; } // Complete the request if needed if (request.Option == GattWriteOption.WriteWithResponse) { request.Respond(); } UpdateUX(); }
protected override bool WriteRequested(GattSession session, GattWriteRequest request) { var service = base.ParentService as GattServicesLibrary.Services.AlertNotificationService; if (service != null) { AlertNotificationControlPointCommand command = new AlertNotificationControlPointCommand(); var byteAccess = request.Value.ToArray(); command.CommandId = (CharacteristicParameterValues.AlertNotificationControlPointCommandId)byteAccess[0]; command.CategotyId = (CharacteristicParameterValues.AlertCategoryId)byteAccess[1]; service.ProcessCommand(command); Value = request.Value; request.Respond(); return(true); } return(false); }
// Helper function for async Write callback protected virtual async void Characteristic_WriteRequested( GattLocalCharacteristic sender, GattWriteRequestedEventArgs args, Deferral deferral ) { Debug.WriteLine("base.Characteristic_WriteRequested Entry"); GattWriteRequest request = null; // 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. // request = await args.GetRequestAsync(); if (request == null) { Debug.WriteLine("Could not retrieve request from the " + "GattWriteRequestedEventArgs. Request was " + "null." ); goto Exit; } // Set the value Value = request.Value; // Respond with completion notification if requested if (request.Option == GattWriteOption.WriteWithResponse) { Debug.WriteLine("Completing write request with response."); request.Respond(); } else { Debug.WriteLine("Completing write request without response."); } // Debugging print! //byte[] data; //CryptographicBuffer.CopyToByteArray(Value, out data); //if(data == null) //{ // Debug.WriteLine("Value after write completion was NULL. :("); //} //else //{ // Debug.WriteLine($"Write completed. Received packet from {args.Session.DeviceId.ToString()}, value is now {Utilities.BytesToString(data)}"); //} Exit: deferral.Complete(); Debug.WriteLine("base.Characteristic_WriteRequested Exit"); }