protected override bool WriteRequested(GattSession session, GattWriteRequest request) { byte[] receivedWrite; CryptographicBuffer.CopyToByteArray(request.Value, out receivedWrite); var receivedWriteHexString = Helpers.ToHexString(request.Value); if ((request.Value.Length != 6) || (receivedWrite[5] != 0xFF)) { Debug.WriteLine($"Light Bulb color Write requested, INVALID INPUT: {receivedWriteHexString} ({request.Value.Length})"); //send notification to user OnPropertyChanged(new PropertyChangedEventArgs("InvalidRequest")); //do not update Value, return return(true); } // ARGB request if (receivedWrite[0] == 0xAA) { ProcessARGB(receivedWrite); } // password protected request else if (receivedWrite[0] == 0xBE) { ProcessPassProtected(receivedWrite); } //send to scenario return(true); }
protected override bool WriteRequested(GattSession session, GattWriteRequest request) { byte[] receivedWrite; CryptographicBuffer.CopyToByteArray(request.Value, out receivedWrite); var receivedWriteHexString = Helpers.ToHexString(request.Value); QuickLockMainService parent = (QuickLockMainService)this.ParentService; //expected: 0066612666 (pcap), or 006661266600000000 (also correct) if ((request.Value.Length != 5) && (request.Value.Length != 9)) { Debug.WriteLine($"Smart lock auth WriteRequested, but invalid format: {receivedWriteHexString} ({request.Value.Length})"); //do not update Value, return OnPropertyChanged(new PropertyChangedEventArgs("InvalidRequest")); return(true); } //check just the first byte and password, ignore rest if provided if ((receivedWrite[0] != 0x00) || (receivedWrite[1] != password[0]) || (receivedWrite[2] != password[1]) || (receivedWrite[3] != password[2]) || (receivedWrite[4] != password[3])) { Debug.WriteLine($"Smart lock auth WriteRequested: INVALID PASSWORD: {receivedWriteHexString} ({request.Value.Length})"); //do not update Value, return OnPropertyChanged(new PropertyChangedEventArgs("InvalidPin")); return(true); } parent.UpdateAuthenticationState(true); OnPropertyChanged(new PropertyChangedEventArgs("AuthenticationState")); return(true); }
// if received "01", send logs via notification from HistoryData characteristic protected override bool WriteRequested(GattSession session, GattWriteRequest request) { byte[] receivedWrite; CryptographicBuffer.CopyToByteArray(request.Value, out receivedWrite); var receivedWriteHexString = Helpers.ToHexString(request.Value); QuickLockHistoryService parent = (QuickLockHistoryService)this.ParentService; if ((request.Value.Length != 1) || (receivedWrite[0] != 0x01)) { Debug.WriteLine($"Quicklock history cmd WriteRequested, but invalid format: {receivedWriteHexString} ({request.Value.Length})"); //do not update Value, return OnPropertyChanged(new PropertyChangedEventArgs("InvalidRequest")); return(true); } Debug.WriteLine($"Quicklock history cmd received, sending out logs"); // OnPropertyChanged(new PropertyChangedEventArgs("Logs")); // set the status characteristic and send notification parent.QuickLockHistoryData.SendLogs(); return(true); }
/// <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()}"); } }); }
private async void OperatorCharacteristic_WriteRequestedAsync(GattLocalCharacteristic sender, GattWriteRequestedEventArgs args) { using (args.GetDeferral()) { // Get the request information. This requires device access before an app can access the device's request. GattWriteRequest request = await args.GetRequestAsync(); if (request == null) { // No access allowed to the device. Application should indicate this to the user. return; } ProcessWriteCharacteristic(request, CalculatorCharacteristics.Operator); } }
protected override bool WriteRequested(GattSession session, GattWriteRequest request) { //check if this is write command not write request if (request.Option == GattWriteOption.WriteWithResponse) { OnPropertyChanged(new PropertyChangedEventArgs("InvalidRequest")); Debug.WriteLine("Write request"); } else { Debug.WriteLine("Write command"); Value = request.Value; } return(true); }
/// <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 receivedWrite = Helpers.ToHexString(request.Value); // invalid input, discard if (!receivedWrite.Equals("00") && !receivedWrite.Equals("01")) { Debug.WriteLine($"Light Bulb cmd WriteRequested: INVALID INPUT: {receivedWrite} ({request.Value.Length})"); //send notification to user OnPropertyChanged(new PropertyChangedEventArgs("InvalidRequest")); //do not update Value, return return(true); } //check for macros blink challenge currentTime = DateTime.Now; span = currentTime.Subtract(previousTime); Debug.WriteLine($"Time span from previoius write: {span.TotalMilliseconds} ms"); previousTime = currentTime; // previus write less than 0.5s ago if (span.TotalMilliseconds < 500) { Debug.WriteLine("Time span less than 0.5s!"); //check if previous value != current (light bulb swith) if (Value != request.Value) { switchCounter++; Debug.WriteLine($"Value switch - OK {switchCounter}"); } else { switchCounter = 0; } } if (switchCounter > 10) { OnPropertyChanged(new PropertyChangedEventArgs("BlinkPassed")); } // Set the characteristic Value Value = request.Value; return(true); }
public static async void Op1Characteristic_WriteRequestedAsync(GattLocalCharacteristic sender, GattWriteRequestedEventArgs args) { // BT_Code: Processing a write request. using (args.GetDeferral()) { ApplicationData.Current.LocalSettings.Values["Op1ReceivedEver"] = "yes"; // Get the request information. This requires device access before an app can access the device's request. GattWriteRequest request = await args.GetRequestAsync(); if (request == null) { // No access allowed to the device. Application should indicate this to the user. return; } ProcessWriteCharacteristic(request, SDKTemplate.Calculator.CalculatorCharacteristics.Operand1); //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); }
protected override bool WriteRequested(GattSession session, GattWriteRequest request) { byte[] receivedWrite; CryptographicBuffer.CopyToByteArray(request.Value, out receivedWrite); var receivedWriteHexString = Helpers.ToHexString(request.Value); // valid format: one byte of length, followed by ascii hex username, and padded with 00 up to 15 bytes // for now just check the length and accept 15 chars only if ((request.Value.Length != 15)) { Debug.WriteLine($"Quicklock username WriteRequested, wrong length: {receivedWriteHexString} ({request.Value.Length})"); //do not update Value, return OnPropertyChanged(new PropertyChangedEventArgs("InvalidRequest")); return(true); } // Set the characteristic Value to the value received Value = request.Value; return(true); }
protected override bool WriteRequested(GattSession session, GattWriteRequest request) { byte[] receivedWrite; CryptographicBuffer.CopyToByteArray(request.Value, out receivedWrite); var receivedWriteHexString = Helpers.ToHexString(request.Value); QuickLockMainService parent = (QuickLockMainService)this.ParentService; if (!parent.isAuthenticated) { Debug.WriteLine($"Quicklock cmd WriteRequested, but not authenticated {receivedWriteHexString} ({request.Value.Length})"); //do not update Value, return OnPropertyChanged(new PropertyChangedEventArgs("Unauthenticated")); return(true); } if ((request.Value.Length != 1) || ((receivedWrite[0] != 0x00) && (receivedWrite[0] != 0x01))) { Debug.WriteLine($"Quicklock cmd WriteRequested, but invalid format {receivedWriteHexString} ({request.Value.Length})"); //do not update Value, return OnPropertyChanged(new PropertyChangedEventArgs("InvalidRequest")); return(true); } Debug.WriteLine($"Quicklock cmd received: {receivedWriteHexString} ({request.Value.Length})"); if (receivedWrite[0] == 00) // lock { Debug.WriteLine($"Locking!"); parent.UpdateUnlockState(false); } else if (receivedWrite[0] == 01) // unlock { Debug.WriteLine($"Unlocking!"); parent.UpdateUnlockState(true); } OnPropertyChanged(new PropertyChangedEventArgs("LockState")); return(true); }
protected virtual bool WriteRequested(GattSession session, GattWriteRequest request) { Debug.WriteLine("Request not completed by derrived class."); 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"); }