了解 BluetoothLE 写入特性中的十六进制数据格式(Windows UWP 示例应用程序)
Understanding hexadecimal data format in BluetoothLE write characteristic (Windows UWP Sample app)
我已经使用 iPhone 上 here. I'm using LightBlue 提供的代码设置了一个 UWP 示例 BluetoothLE 服务器作为客户端 read/write 数据到服务器公开的特征。
这是服务的描述:
This scenario allows the system to publish a calculator service. Remote
clients (including this sample on another machine) can supply 2
operands and an operator and get a result.
Valid range for Operand is integer values. Valid range for Operator is
1-4 corresponding to +,-,*,/ respectively.
所以有3个写特征,1个读特征。在我的 iPhone 上使用 LightBlue,我以十六进制格式将数据写入操作数特征,但是我有点困惑。
我希望写出 32 位无符号整数的十六进制表示,例如:
(hex) 00000001 = (binary) 00000000 00000000 00000000 00000001 = (decimal) 1
然而这被服务器解释为十进制16777216。经过试验,我确定
(hex) 01000000 = (decimal) 1.
我对十六进制数据格式的假设显然是错误的。
我相信这是负责从客户端接收请求的服务器脚本中的方法,完整的class可用here。
/// <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();
}
谁能解释一下我错过了什么?主要来自前端 Web 开发背景;数据类型不是我的强项!
您应该更改此行
reader.ByteOrder = ByteOrder.LittleEndian;
至此
reader.ByteOrder = ByteOrder.BigEndian;
或反转您传递给服务的十六进制字符串中的字节顺序。
我已经使用 iPhone 上 here. I'm using LightBlue 提供的代码设置了一个 UWP 示例 BluetoothLE 服务器作为客户端 read/write 数据到服务器公开的特征。
这是服务的描述:
This scenario allows the system to publish a calculator service. Remote clients (including this sample on another machine) can supply 2 operands and an operator and get a result.
Valid range for Operand is integer values. Valid range for Operator is 1-4 corresponding to +,-,*,/ respectively.
所以有3个写特征,1个读特征。在我的 iPhone 上使用 LightBlue,我以十六进制格式将数据写入操作数特征,但是我有点困惑。
我希望写出 32 位无符号整数的十六进制表示,例如:
(hex) 00000001 = (binary) 00000000 00000000 00000000 00000001 = (decimal) 1
然而这被服务器解释为十进制16777216。经过试验,我确定
(hex) 01000000 = (decimal) 1.
我对十六进制数据格式的假设显然是错误的。
我相信这是负责从客户端接收请求的服务器脚本中的方法,完整的class可用here。
/// <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();
}
谁能解释一下我错过了什么?主要来自前端 Web 开发背景;数据类型不是我的强项!
您应该更改此行
reader.ByteOrder = ByteOrder.LittleEndian;
至此
reader.ByteOrder = ByteOrder.BigEndian;
或反转您传递给服务的十六进制字符串中的字节顺序。