Skip to content

Commit

Permalink
discovery: allow to ignore resource in batch notification
Browse files Browse the repository at this point in the history
Use OC_IGNORE response code to ignore resource in batch notification.
  • Loading branch information
Danielius1922 committed Apr 19, 2024
1 parent 603de5a commit cccfd14
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 16 deletions.
26 changes: 18 additions & 8 deletions api/oc_discovery.c
Original file line number Diff line number Diff line change
Expand Up @@ -780,14 +780,24 @@ discovery_process_batch_response(
}

#ifdef OC_DISCOVERY_RESOURCE_OBSERVABLE
if (is_notification && response_buffer.code == CONTENT_2_05) {
const uint8_t *payload =
oc_rep_get_encoder_buf() + (ptrdiff_t)total_payload_start;
if (payload_size == 0 ||
(!is_collection && payload_size == 2 &&
oc_rep_encoded_payload_is_empty_object(oc_rep_encoder_get_type(),
payload, payload_size))) {
OC_DBG("ignoring empty resource(%s)", oc_string(resource->uri));
if (is_notification) {
bool ignore = false;
if (response_buffer.code == CLEAR_TRANSACTION) {
OC_DBG("ignoring resource(%s) with CLEAR_TRANSACTION",
oc_string(resource->uri));
ignore = true;
} else if (response_buffer.code == CONTENT_2_05) {
const uint8_t *payload =
oc_rep_get_encoder_buf() + (ptrdiff_t)total_payload_start;
if (payload_size == 0 ||
(!is_collection && payload_size == 2 &&
oc_rep_encoded_payload_is_empty_object(oc_rep_encoder_get_type(),
payload, payload_size))) {
OC_DBG("ignoring empty resource(%s)", oc_string(resource->uri));
ignore = true;
}
}
if (ignore) {
memcpy(encoder, &prev.links, sizeof(CborEncoder));
memcpy(oc_rep_get_encoder(), &prev.global, sizeof(CborEncoder));
return false;
Expand Down
18 changes: 15 additions & 3 deletions api/unittest/discovery/discovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,14 @@ TestDiscoveryWithServer::onGetEmptyDynamicResource(oc_request_t *request,
oc_send_response(request, OC_STATUS_OK);
}

void
TestDiscoveryWithServer::onGetIgnoredDynamicResource(oc_request_t *request,
oc_interface_mask_t,
void *)
{
oc_send_response(request, OC_IGNORE);
}

void
TestDiscoveryWithServer::addDynamicResources()
{
Expand All @@ -353,6 +361,9 @@ TestDiscoveryWithServer::addDynamicResources()
oc::DynamicResourceHandler handlers3{};
handlers3.onGet = onGetEmptyDynamicResource;

oc::DynamicResourceHandler handlers4{};
handlers4.onGet = onGetIgnoredDynamicResource;

std::vector<oc::DynamicResourceToAdd> dynResources = {
oc::makeDynamicResourceToAdd("Dynamic Resource 1",
std::string(kDynamicURI1),
Expand All @@ -366,6 +377,10 @@ TestDiscoveryWithServer::addDynamicResources()
"Dynamic Resource 3", std::string(kDynamicURI3),
{ "oic.d.observable", "oic.d.test" }, { OC_IF_BASELINE, OC_IF_R },
handlers3, OC_DISCOVERABLE | OC_OBSERVABLE),
oc::makeDynamicResourceToAdd(
"Dynamic Resource 4", std::string(kDynamicURI4),
{ "oic.d.ignored", "oic.d.test" }, { OC_IF_BASELINE, OC_IF_R }, handlers4,
OC_DISCOVERABLE | OC_OBSERVABLE),
};
for (const auto &dr : dynResources) {
oc_resource_t *res = oc::TestDevice::AddDynamicResource(dr, kDeviceID);
Expand Down Expand Up @@ -401,7 +416,6 @@ TestDiscoveryWithServer::addColletions()
dynamicResources[std::string(kColDynamicURI1)] = { 404 };
handlers1.onGet = onGetDynamicResource;
handlers1.onGetData = &dynamicResources[std::string(kColDynamicURI1)];

auto dr1 = oc::makeDynamicResourceToAdd(
"Collection Resource 1", std::string(kColDynamicURI1),
{ std::string(powerSwitchRT), "oic.d.test" }, { OC_IF_BASELINE, OC_IF_R },
Expand All @@ -416,7 +430,6 @@ TestDiscoveryWithServer::addColletions()
dynamicResources[std::string(kColDynamicURI2)] = { 1 };
handlers2.onGet = onGetDynamicResource;
handlers2.onGetData = &dynamicResources[std::string(kColDynamicURI2)];

auto dr2 = oc::makeDynamicResourceToAdd(
"Collection Resource 2", std::string(kColDynamicURI2),
{ std::string(powerSwitchRT), "oic.d.test" }, { OC_IF_BASELINE, OC_IF_R },
Expand All @@ -429,7 +442,6 @@ TestDiscoveryWithServer::addColletions()

oc::DynamicResourceHandler handlers3{};
handlers3.onGet = onGetEmptyDynamicResource;

auto dr3 = oc::makeDynamicResourceToAdd(
"Collection Resource 3", std::string(kColDynamicURI3),
{ std::string(powerSwitchRT), "oic.d.test" }, { OC_IF_BASELINE, OC_IF_R },
Expand Down
9 changes: 5 additions & 4 deletions api/unittest/discovery/discovery.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,12 @@ class TestDiscoveryWithServer : public ::testing::Test {
void SetUp() override;
void TearDown() override;

static void onGetDynamicResource(oc_request_t *request,
oc_interface_mask_t interface,
static void onGetDynamicResource(oc_request_t *request, oc_interface_mask_t,
void *user_data);
static void onGetEmptyDynamicResource(oc_request_t *request,
oc_interface_mask_t interface,
void *user_data);
oc_interface_mask_t, void *);
static void onGetIgnoredDynamicResource(oc_request_t *request,
oc_interface_mask_t, void *);

static void addDynamicResources();
#ifdef OC_COLLECTIONS
Expand Down Expand Up @@ -154,6 +154,7 @@ constexpr size_t kDeviceID{ 0 };
constexpr std::string_view kDynamicURI1 = "/dyn/discoverable";
constexpr std::string_view kDynamicURI2 = "/dyn/undiscoverable";
constexpr std::string_view kDynamicURI3 = "/dyn/empty";
constexpr std::string_view kDynamicURI4 = "/dyn/ignored";

#ifdef OC_COLLECTIONS

Expand Down
36 changes: 35 additions & 1 deletion api/unittest/discovery/discoveryobservetest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ TEST_F(TestDiscoveryWithServer, ObserveBatchWithResourceAdded)
verifyBatchPayload(obd.batch, &ep);
}

TEST_F(TestDiscoveryWithServer, ObserveBatchIgnoreEmptyChange)
TEST_F(TestDiscoveryWithServer, ObserveBatchSkipEmptyResourceChange)
{
ASSERT_TRUE(oc_get_con_res_announced());

Expand Down Expand Up @@ -451,6 +451,40 @@ TEST_F(TestDiscoveryWithServer, ObserveBatchIgnoreEmptyChange)
EXPECT_TRUE(obd.batch.empty());
}

TEST_F(TestDiscoveryWithServer, ObserveBatchSkipIgnoreResourceChange)
{
ASSERT_TRUE(oc_get_con_res_announced());

auto epOpt = oc::TestDevice::GetEndpoint(kDeviceID);
ASSERT_TRUE(epOpt.has_value());
auto ep = std::move(*epOpt);

observeBatchData obd{};
ASSERT_TRUE(oc_do_observe(OCF_RES_URI, &ep, "if=" OC_IF_B_STR, onBatchObserve,
HIGH_QOS, &obd));
oc::TestDevice::PoolEventsMsV1(1s);
EXPECT_EQ(OC_COAP_OPTION_OBSERVE_REGISTER, obd.observe);
ASSERT_FALSE(obd.batch.empty());
// all resources should be in the first payload
verifyBatchPayload(obd.batch, &ep);
obd.observe = 0;
obd.batch.clear();

auto *res = oc_ri_get_app_resource_by_uri(kDynamicURI4.data(),
kDynamicURI4.size(), kDeviceID);
ASSERT_NE(nullptr, res);
// notification with payload from resource that returns OC_IGNORE should be
// ignored
oc_notify_resource_changed(res);
int repeats = 0;
while (obd.observe == 0 && repeats < 30) {
oc::TestDevice::PoolEventsMsV1(10ms);
++repeats;
}
EXPECT_EQ(0, obd.observe);
EXPECT_TRUE(obd.batch.empty());
}

TEST_F(TestDiscoveryWithServer, ObserveBatchWithEmptyPayload)
{
// TODO: remove resource from payload -> make it undiscoverable in runtime
Expand Down

0 comments on commit cccfd14

Please sign in to comment.