Skip to content

Commit

Permalink
api: fix handling of CoAP signal messages
Browse files Browse the repository at this point in the history
  • Loading branch information
Danielius1922 committed Oct 24, 2023
1 parent 44b0fed commit e82af7f
Show file tree
Hide file tree
Showing 18 changed files with 635 additions and 275 deletions.
19 changes: 14 additions & 5 deletions api/client/oc_client_cb.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@
#include "api/oc_discovery_internal.h"
#include "api/oc_event_callback_internal.h"
#include "api/oc_helpers_internal.h"
#include "api/oc_ping_internal.h"
#include "api/oc_rep_internal.h"
#include "api/oc_ri_internal.h"
#include "messaging/coap/coap_options.h"
#include "oc_client_state.h"
#include "util/oc_list.h"
#include "util/oc_memb.h"
#include "util/oc_macros_internal.h"

#ifdef OC_TCP
#include "messaging/coap/coap_signal.h"
Expand Down Expand Up @@ -226,6 +228,16 @@ oc_client_cb_free(oc_client_cb_t *cb)
oc_client_cb_dealloc(cb);
}

#ifdef OC_TCP
static bool
client_cb_is_ping_response(const oc_client_cb_t *cb)
{
return ((oc_string_len(cb->uri) == OC_CHAR_ARRAY_LEN(OC_PING_URI)) &&
(memcmp(oc_string(cb->uri), OC_PING_URI,
OC_CHAR_ARRAY_LEN(OC_PING_URI)) == 0));
}
#endif /* OC_TCP */

static void
client_cb_notify_with_code(oc_client_cb_t *cb, oc_status_t code)
{
Expand All @@ -246,8 +258,7 @@ client_cb_notify_with_code(oc_client_cb_t *cb, oc_status_t code)
handler(&client_response);

#ifdef OC_TCP
if ((oc_string_len(cb->uri) == 5) &&
(memcmp((const char *)oc_string(cb->uri), "/ping", 5) == 0)) {
if (client_cb_is_ping_response(cb)) {
oc_ri_remove_timed_event_callback(cb, oc_remove_ping_handler_async);
}
#endif /* OC_TCP */
Expand Down Expand Up @@ -497,9 +508,7 @@ oc_client_cb_invoke(const coap_packet_t *response, oc_client_cb_t *cb,
}

#ifdef OC_TCP
if (response->code == PONG_7_03 ||
(oc_string_len(cb->uri) == 5 &&
memcmp(oc_string(cb->uri), "/ping", 5) == 0)) {
if (response->code == PONG_7_03 || client_cb_is_ping_response(cb)) {
oc_ri_remove_timed_event_callback(cb, oc_remove_ping_handler_async);
}
#endif /* OC_TCP */
Expand Down
42 changes: 0 additions & 42 deletions api/oc_client_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -616,48 +616,6 @@ oc_stop_observe(const char *uri, const oc_endpoint_t *endpoint)
return dispatch_coap_request();
}

#ifdef OC_TCP
oc_event_callback_retval_t
oc_remove_ping_handler_async(void *data)
{
oc_client_cb_t *cb = (oc_client_cb_t *)data;

oc_client_response_t timeout_response;
timeout_response.code = OC_PING_TIMEOUT;
timeout_response.endpoint = &cb->endpoint;
timeout_response.user_data = cb->user_data;
cb->handler.response(&timeout_response);

return oc_client_cb_remove_async(cb);
}

bool
oc_send_ping(bool custody, const oc_endpoint_t *endpoint,
uint16_t timeout_seconds, oc_response_handler_t handler,
void *user_data)
{
oc_client_handler_t client_handler = {
.response = handler,
.discovery = NULL,
.discovery_all = NULL,
};

oc_client_cb_t *cb = oc_ri_alloc_client_cb(
"/ping", endpoint, 0, NULL, client_handler, LOW_QOS, user_data);
if (!cb)
return false;

if (!coap_send_ping_message(endpoint, custody ? 1 : 0, cb->token,
cb->token_len)) {
oc_client_cb_free(cb);
return false;
}

oc_set_delayed_callback(cb, oc_remove_ping_handler_async, timeout_seconds);
return true;
}
#endif /* OC_TCP */

#ifdef OC_IPV4
static oc_client_cb_t *
oc_do_ipv4_discovery(const char *query, oc_client_handler_t handler,
Expand Down
78 changes: 78 additions & 0 deletions api/oc_ping.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/****************************************************************************
*
* Copyright (c) 2016 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License"),
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*
****************************************************************************/

#include "oc_config.h"

#if defined(OC_CLIENT) && defined(OC_TCP)

#include "api/client/oc_client_cb_internal.h"
#include "api/oc_ping_internal.h"
#include "messaging/coap/coap_signal.h"
#include "oc_api.h"
#include "oc_client_state.h"
#include "oc_ri.h"

oc_event_callback_retval_t
oc_remove_ping_handler_async(void *data)
{
oc_client_cb_t *cb = (oc_client_cb_t *)data;

oc_client_response_t timeout_response;
timeout_response.code = OC_PING_TIMEOUT;
timeout_response.endpoint = &cb->endpoint;
timeout_response.user_data = cb->user_data;
cb->handler.response(&timeout_response);

return oc_client_cb_remove_async(cb);
}

bool
oc_send_ping(bool custody, const oc_endpoint_t *endpoint,
uint16_t timeout_seconds, oc_response_handler_t handler,
void *user_data)
{
if (endpoint == NULL || handler == NULL) {
OC_ERR("oc_send_ping: invalid parameters (endpoint=%s, handler=%s)",
endpoint != NULL ? "ok" : "null", handler != NULL ? "ok" : "null");
return false;
}

oc_client_handler_t client_handler = {
.response = handler,
.discovery = NULL,
.discovery_all = NULL,
};

oc_client_cb_t *cb =
oc_ri_alloc_client_cb(OC_PING_URI, endpoint, /*method*/ 0, /*query*/ NULL,
client_handler, LOW_QOS, user_data);
if (cb == NULL) {
return false;
}

if (!coap_send_ping_message(endpoint, custody ? 1 : 0, cb->token,
cb->token_len)) {
oc_client_cb_free(cb);
return false;
}

oc_set_delayed_callback(cb, oc_remove_ping_handler_async, timeout_seconds);
return true;
}

#endif /* OC_CLIENT && OC_TCP */
41 changes: 41 additions & 0 deletions api/oc_ping_internal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/****************************************************************************
*
* Copyright (c) 2016 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License"),
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*
****************************************************************************/

#ifndef OC_PING_INTERNAL_H
#define OC_PING_INTERNAL_H

#if defined(OC_CLIENT) && defined(OC_TCP)

#include "oc_ri.h"

#ifdef __cplusplus
extern "C" {
#endif

#define OC_PING_URI "/ping"

/** Ping timeout callback */
oc_event_callback_retval_t oc_remove_ping_handler_async(void *data);

#ifdef __cplusplus
}
#endif

#endif /* OC_CLIENT && OC_TCP */

#endif /* OC_PING_INTERNAL_H */
6 changes: 6 additions & 0 deletions api/oc_ri.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@

#ifdef OC_TCP
#include "api/oc_session_events_internal.h"
#include "messaging/coap/coap_signal.h"
#endif /* OC_TCP */

#include <assert.h>
Expand Down Expand Up @@ -330,6 +331,11 @@ oc_coap_status_to_status(coap_status_t status)
return i;
}
}
#ifdef OC_TCP
if ((uint8_t)status == PONG_7_03) {
return OC_STATUS_OK;
}
#endif /* OC_TCP */
OC_WRN("oc_coap_status_to_status: invalid coap status code %d", (int)status);
return -1;
}
Expand Down
4 changes: 0 additions & 4 deletions api/oc_ri_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,6 @@ bool oc_ri_invoke_coap_entity_handler(coap_make_response_ctx_t *ctx,
oc_endpoint_t *endpoint, void *user_data)
OC_NONNULL(1, 2);

#ifdef OC_TCP
oc_event_callback_retval_t oc_remove_ping_handler_async(void *data);
#endif /* OC_TCP */

#ifdef __cplusplus
}
#endif
Expand Down
64 changes: 63 additions & 1 deletion api/unittest/RITest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,25 @@
#include "api/oc_runtime_internal.h"
#include "port/oc_network_event_handler_internal.h"

#ifdef OC_TCP
#include "messaging/coap/coap_signal.h"
#endif /* OC_TCP */

#include <gtest/gtest.h>
#include <limits>
#include <set>
#include <string>
#include <vector>

class TestOcRi : public testing::Test {
protected:
public:
void SetUp() override
{
oc_network_event_handler_mutex_init();
oc_runtime_init();
oc_ri_init();
}

void TearDown() override
{
oc_ri_shutdown();
Expand All @@ -59,6 +66,61 @@ TEST_F(TestOcRi, StatusCodeToCoapCode)
}
}

TEST_F(TestOcRi, CoapCodeToStatusCode)
{
std::vector<coap_status_t> coapCodes{
CREATED_2_01,
DELETED_2_02,
VALID_2_03,
CHANGED_2_04,
CONTENT_2_05,

BAD_REQUEST_4_00,
UNAUTHORIZED_4_01,
BAD_OPTION_4_02,
FORBIDDEN_4_03,
NOT_FOUND_4_04,
METHOD_NOT_ALLOWED_4_05,
NOT_ACCEPTABLE_4_06,
REQUEST_ENTITY_TOO_LARGE_4_13,

INTERNAL_SERVER_ERROR_5_00,
NOT_IMPLEMENTED_5_01,
BAD_GATEWAY_5_02,
SERVICE_UNAVAILABLE_5_03,
GATEWAY_TIMEOUT_5_04,
PROXYING_NOT_SUPPORTED_5_05,

#ifdef OC_TCP
static_cast<coap_status_t>(PONG_7_03),
#endif /* OC_TCP */
};

for (auto coapCode : coapCodes) {
EXPECT_NE(-1, oc_coap_status_to_status(coapCode));
}
}

TEST_F(TestOcRi, CoapCodeToStatusCode_F)
{
std::vector<coap_status_t> coapCodesWithoutConversion{
COAP_NO_ERROR,
CONTINUE_2_31,
PRECONDITION_FAILED_4_12,

#ifdef OC_TCP
static_cast<coap_status_t>(CSM_7_01),
static_cast<coap_status_t>(PING_7_02),
static_cast<coap_status_t>(RELEASE_7_04),
static_cast<coap_status_t>(ABORT_7_05),
#endif /* OC_TCP */
};

for (auto coapCode : coapCodesWithoutConversion) {
EXPECT_EQ(-1, oc_coap_status_to_status(coapCode));
}
}

TEST_F(TestOcRi, StatusCodeToStr)
{
for (int i = OC_STATUS_OK; i < __NUM_OC_STATUS_CODES__; ++i) {
Expand Down
Loading

0 comments on commit e82af7f

Please sign in to comment.