1

In my device configuration, gatt.xml, I added a custom GATT characteristic with a custom UUID and enabled the read and write properties. Using windows Bluetooth API after pairing, when I try to read from the GATT characteristic, it's working fine, but writing to the GATT characteristic is not working. I am getting access denied with an exception all the time. Below I added sample gatt.xml, bgs, and C# code. I am using Bluegiga v1.3.1_API. The current setup works fine with the USB dongle, but I am trying to replace it with the Windows Bluetooth API.

gatt.xml

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>

<service uuid="180A">
  <description>Device Information</description>
  
  <characteristic uuid="2a29">
    <properties read="true" const="true" />
    <value>company name</value>
    <description>Manufacturer Name String</description>
  </characteristic>
  
  <characteristic uuid="2a24">
    <properties read="true" const="true" />
    <value>device name</value>
    <description>Model Number String</description>
  </characteristic>
      
  <characteristic uuid="2a27">
    <properties read="true" const="true"/>
    <value>2.0</value>
    <description>Hardware Revision String</description>
  </characteristic>
  
  <characteristic uuid="95551f84-7562-4c30-9455-be0750914ac2" id="xgatt_Params">
    <properties read="true" write="true"/>
    <value type="user" length="5"/>
    <description>Params</description>

  </characteristic>
      
</service>
    
</configuration>

attributes_value event from bgs script

event attributes_value(connection, reason, handle, offset, value_len, value_data)
    if handle = xgatt_Params then
        if value_len = 2 then
            if value_data(0:2) = $0115 then
                memcpy(addrPaired(0), addrConnected(0),6)
                updatePairing=1
                call attributes_user_write_response(connection, 0)
            else
                call attributes_user_write_response(connection, $80)
            end if
        else
            if value_len >= numParams then
                memcpy(params(0), value_data(0), numParams)
                call updateParams()
                call attributes_user_write_response(connection, 0)
            else
                call attributes_user_write_response(connection, $80)
            end if
        end if
    end if
end

C# code

if (properties.HasFlag(GattCharacteristicProperties.Write))
{
    try
    {
        var writer = new DataWriter();
        writer.WriteByte(01);
        writer.WriteByte(15);
        var result = await characteristic.WriteValueAsync(writer.DetachBuffer(), 
GattWriteOption.WriteWithResponse);

        if (result == GattCommunicationStatus.Success)
        {
            Console.Write("\n Success");
        }
        else if (result == GattCommunicationStatus.AccessDenied)
        {
            Console.Write("\n Access Denied");
        }
        else if (result == GattCommunicationStatus.Unreachable)
        {
            Console.Write("\n Unreachable");
        }

        else if (result == GattCommunicationStatus.ProtocolError)
        {
            Console.Write("\n ProtocolError");
        }
    }
    catch (Exception ex) when ((uint)ex.HResult == 0x80650003 || (uint)ex.HResult == 
0x80070005)
    {
        Console.Write("\n " + ex.Message);
    }

}
Loop
  • 58
  • 7
  • You can't read from a DataWriter : var result = await characteristic.WriteValueAsync(writer.DetachBuffer(), GattWriteOption.WriteWithResponse); – jdweng Jun 06 '21 at 12:40
  • For reading I am using ReadValueAsync. I am having problem with writing that's why I posted writing code section. – Loop Jun 06 '21 at 13:45
  • In Net is you have a Write Stream you cannot read the stream. the issue is with "writer.DetachBuffer()" – jdweng Jun 06 '21 at 15:43
  • Sorry I didn't understand your point. As far as I understand you wanted to say I can not read and write at a time? If that's what you mean, only writing is also not working. Or you mean that the result I am getting after write is not readable? Could you please clarify. – Loop Jun 06 '21 at 16:50
  • The following shows which are reads and which are writes : https://os.mbed.com/docs/mbed-os/v6.7/mbed-os-api-doxy/class_gatt_characteristic.html – jdweng Jun 06 '21 at 21:30

1 Answers1

0

Windows do not allow to write into GAP services. So what I did is made a service with characteristics using a custom UUID like below, and now it's working.

<service uuid="97b6682c-ca92-11eb-b8bc-0242ac130003">
  <description>meso service</description>

  <!-- custom write-only characteristic -->
    <characteristic uuid="97b66a7a-ca92-11eb-b8bc-0242ac130003" id="xgatt_params_windows">
      <description>Data</description>
      <properties write="true" />
      <value type="user" length="5"/>
    </characteristic>
</service>

Another thing to keep in mind is you need to write the hex value from windows in reverse order. For example, in my BGScript, it's expecting value 0115, so you should write the value from the windows in reverse. This completely depends on which system you are using, for example, BigEndian (MSB first, e.g.: Motorola processors), or LittleEndian (LSB first, e.g.: Intel processors).

var writer = new DataWriter();
writer.WriteByte(15);
writer.WriteByte(01);
Loop
  • 58
  • 7