mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
Fix Action Data Elements construction.
Data Elements representing an action should have the type set to kActionFieldType, and the actual action stored in the value. PiperOrigin-RevId: 465365230
This commit is contained in:
committed by
Copybara-Service
parent
4d6bc3d62f
commit
ce6c5893d7
@@ -26,10 +26,37 @@ constexpr int kContentTimestampMask = 0x0F;
|
||||
constexpr int kContentTimestampShift = 12;
|
||||
constexpr int kEmptyMask = 0;
|
||||
|
||||
// The values below match the bitmasks in Base NP Intent.
|
||||
constexpr int kTapToTransferMask = 1 << 11;
|
||||
constexpr int kActiveUnlockMask = 1 << 7;
|
||||
constexpr int kNearbyShareMask = 1 << 6;
|
||||
constexpr int kFastPairMask = 1 << 5;
|
||||
constexpr int kFitCastMask = 1 << 4;
|
||||
|
||||
namespace {
|
||||
int GetActionMask(int action) {
|
||||
switch (action) {
|
||||
case action::kActiveUnlockAction:
|
||||
return kActiveUnlockMask;
|
||||
case action::kTapToTransferAction:
|
||||
return kTapToTransferMask;
|
||||
case action::kNearbyShareAction:
|
||||
return kNearbyShareMask;
|
||||
case action::kFastPairAction:
|
||||
return kFastPairMask;
|
||||
case action::kFitCastAction:
|
||||
return kFitCastMask;
|
||||
}
|
||||
NEARBY_LOG(WARNING, "Unsupported action %d", action);
|
||||
return kEmptyMask;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int ActionFactory::GetMask(const DataElement& element) {
|
||||
int type = element.GetType();
|
||||
switch (type) {
|
||||
case DataElement::kContextTimestamp: {
|
||||
case DataElement::kContextTimestampFieldType: {
|
||||
auto value = element.GetValue();
|
||||
if (!value.empty()) {
|
||||
return (value[0] & kContentTimestampMask) << kContentTimestampShift;
|
||||
@@ -38,13 +65,13 @@ int ActionFactory::GetMask(const DataElement& element) {
|
||||
return kEmptyMask;
|
||||
}
|
||||
}
|
||||
case DataElement::kActiveUnlock:
|
||||
case DataElement::kTapToTransfer:
|
||||
case DataElement::kNearbyShare:
|
||||
case DataElement::kFastPair:
|
||||
case DataElement::kFitCast:
|
||||
case DataElement::kPresenceManager:
|
||||
return type;
|
||||
case DataElement::kActionFieldType: {
|
||||
if (element.GetValue().empty()) {
|
||||
NEARBY_LOG(WARNING, "Action Data Element without value");
|
||||
return kEmptyMask;
|
||||
}
|
||||
return GetActionMask(element.GetValue()[0]);
|
||||
}
|
||||
}
|
||||
NEARBY_LOG(WARNING, "Data Element 0x%x not supported in base advertisement",
|
||||
type);
|
||||
|
||||
@@ -30,18 +30,20 @@ namespace {
|
||||
|
||||
TEST(ActionFactory, CreateActiveUnlockAction) {
|
||||
std::vector<DataElement> data_elements;
|
||||
data_elements.emplace_back(DataElement::kActiveUnlock, "");
|
||||
data_elements.emplace_back(DataElement::kActionFieldType,
|
||||
action::kActiveUnlockAction);
|
||||
|
||||
Action action = ActionFactory::createAction(data_elements);
|
||||
|
||||
EXPECT_EQ(action.action, 1 << 11);
|
||||
EXPECT_EQ(action.action, 1 << 7);
|
||||
}
|
||||
|
||||
TEST(ActionFactory, CreateContextTimestamp) {
|
||||
const std::string kTimestamp = absl::HexStringToBytes("0B");
|
||||
|
||||
std::vector<DataElement> data_elements;
|
||||
data_elements.emplace_back(DataElement::kContextTimestamp, kTimestamp);
|
||||
data_elements.emplace_back(DataElement::kContextTimestampFieldType,
|
||||
kTimestamp);
|
||||
|
||||
Action action = ActionFactory::createAction(data_elements);
|
||||
|
||||
@@ -52,12 +54,14 @@ TEST(ActionFactory, CreateContextTimestampAndFastPair) {
|
||||
const std::string kTimestamp = absl::HexStringToBytes("0B");
|
||||
|
||||
std::vector<DataElement> data_elements;
|
||||
data_elements.emplace_back(DataElement::kContextTimestamp, kTimestamp);
|
||||
data_elements.emplace_back(DataElement::kFastPair, "");
|
||||
data_elements.emplace_back(DataElement::kContextTimestampFieldType,
|
||||
kTimestamp);
|
||||
data_elements.emplace_back(DataElement::kActionFieldType,
|
||||
action::kFastPairAction);
|
||||
|
||||
Action action = ActionFactory::createAction(data_elements);
|
||||
|
||||
EXPECT_EQ(action.action, (0x0B << 12) | 0x100);
|
||||
EXPECT_EQ(action.action, (0x0B << 12) | 0x20);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -50,7 +50,8 @@ TEST(AdvertisementFactory, CreateAdvertisementFromPrivateIdentity) {
|
||||
NiceMock<MockCertificateManager> certificate_manager;
|
||||
PresenceIdentity identity;
|
||||
std::vector<DataElement> data_elements;
|
||||
data_elements.emplace_back(DataElement::kActiveUnlock, "");
|
||||
data_elements.emplace_back(DataElement::kActionFieldType,
|
||||
action::kActiveUnlockAction);
|
||||
Action action = ActionFactory::createAction(data_elements);
|
||||
BroadcastRequest request =
|
||||
BroadcastRequest(BasePresenceRequestBuilder(identity)
|
||||
@@ -61,7 +62,7 @@ TEST(AdvertisementFactory, CreateAdvertisementFromPrivateIdentity) {
|
||||
.WillOnce(Return(absl::HexStringToBytes("1011121314151617181920212223")));
|
||||
EXPECT_CALL(
|
||||
certificate_manager,
|
||||
EncryptDataElements(identity, salt, absl::HexStringToBytes("1505260800")))
|
||||
EncryptDataElements(identity, salt, absl::HexStringToBytes("1505260080")))
|
||||
.WillOnce(Return(absl::HexStringToBytes("5051525354")));
|
||||
|
||||
AdvertisementFactory factory(&certificate_manager);
|
||||
@@ -84,7 +85,8 @@ TEST(AdvertisementFactory,
|
||||
NiceMock<MockCertificateManager> certificate_manager;
|
||||
PresenceIdentity identity;
|
||||
std::vector<DataElement> data_elements;
|
||||
data_elements.emplace_back(DataElement::kActiveUnlock, "");
|
||||
data_elements.emplace_back(DataElement::kActionFieldType,
|
||||
action::kActiveUnlockAction);
|
||||
Action action = ActionFactory::createAction(data_elements);
|
||||
BroadcastRequest request =
|
||||
BroadcastRequest(BasePresenceRequestBuilder(identity)
|
||||
|
||||
+26
-15
@@ -23,24 +23,18 @@
|
||||
namespace nearby {
|
||||
namespace presence {
|
||||
|
||||
// Reserved Action types when the field type is kActionFieldType
|
||||
namespace action {
|
||||
constexpr int kTapToTransferAction = 4;
|
||||
constexpr int kActiveUnlockAction = 8;
|
||||
constexpr int kNearbyShareAction = 9;
|
||||
constexpr int kFastPairAction = 10;
|
||||
constexpr int kFitCastAction = 11;
|
||||
} // namespace action
|
||||
|
||||
/** Describes a custom Data element in NP advertisement. */
|
||||
class DataElement {
|
||||
public:
|
||||
DataElement(uint16_t type, absl::string_view value)
|
||||
: type_(type), value_(value) {}
|
||||
|
||||
uint16_t GetType() const { return type_; }
|
||||
absl::string_view GetValue() const { return value_; }
|
||||
|
||||
static constexpr int kContextTimestamp = 1 << 12;
|
||||
// The values below match the bitmasks in Base NP Intent.
|
||||
static constexpr int kActiveUnlock = 1 << 11;
|
||||
static constexpr int kTapToTransfer = 1 << 10;
|
||||
static constexpr int kNearbyShare = 1 << 9;
|
||||
static constexpr int kFastPair = 1 << 8;
|
||||
static constexpr int kFitCast = 1 << 7;
|
||||
static constexpr int kPresenceManager = 1 << 6;
|
||||
|
||||
// The field types listed below require special processing when generating and
|
||||
// parsing NP advertisements.
|
||||
static constexpr int kSaltFieldType = 0;
|
||||
@@ -50,6 +44,13 @@ class DataElement {
|
||||
static constexpr int kProvisionedIdentityFieldType = 4;
|
||||
static constexpr int kTxPowerFieldType = 5;
|
||||
static constexpr int kActionFieldType = 6;
|
||||
static constexpr int kModelIdFieldType = 7;
|
||||
static constexpr int kEddystoneIdFieldType = 8;
|
||||
static constexpr int kAccountKeyDataFieldType = 9;
|
||||
static constexpr int kConnectionStatusFieldType = 10;
|
||||
static constexpr int kBatteryFieldType = 11;
|
||||
static constexpr int kAdvertisementSignature = 12;
|
||||
static constexpr int kContextTimestampFieldType = 13;
|
||||
// Maximum allowed Data Element's value length
|
||||
static constexpr int kMaxDataElementLength = 15;
|
||||
// Maximum allowed Data Element's type
|
||||
@@ -57,6 +58,16 @@ class DataElement {
|
||||
// The DE header is (length << kDataElementLengthShift | type)
|
||||
static constexpr int kDataElementLengthShift = 4;
|
||||
|
||||
DataElement(uint16_t type, absl::string_view value)
|
||||
: type_(type), value_(value) {}
|
||||
|
||||
DataElement(uint16_t type, uint8_t value)
|
||||
: type_(type),
|
||||
value_(reinterpret_cast<const char*>(&value), sizeof(value)) {}
|
||||
|
||||
uint16_t GetType() const { return type_; }
|
||||
absl::string_view GetValue() const { return value_; }
|
||||
|
||||
private:
|
||||
uint16_t type_;
|
||||
std::string value_;
|
||||
|
||||
Reference in New Issue
Block a user