diff --git a/sys/include/net/gnrc/netreg.h b/sys/include/net/gnrc/netreg.h index cea7d13635..11455c703a 100644 --- a/sys/include/net/gnrc/netreg.h +++ b/sys/include/net/gnrc/netreg.h @@ -333,19 +333,6 @@ void gnrc_netreg_unregister(gnrc_nettype_t type, gnrc_netreg_entry_t *entry); */ gnrc_netreg_entry_t *gnrc_netreg_lookup(gnrc_nettype_t type, uint32_t demux_ctx); -/** - * @brief Returns number of entries with the same gnrc_netreg_entry_t::type and - * gnrc_netreg_entry_t::demux_ctx. - * - * @param[in] type Type of the protocol. - * @param[in] demux_ctx The demultiplexing context for the registered thread. - * See gnrc_netreg_entry_t::demux_ctx. - * - * @return Number of entries with the same gnrc_netreg_entry_t::type and - * gnrc_netreg_entry_t::demux_ctx as the given parameters. - */ -int gnrc_netreg_num(gnrc_nettype_t type, uint32_t demux_ctx); - /** * @brief Returns the next entry after @p entry with the same * gnrc_netreg_entry_t::type and gnrc_netreg_entry_t::demux_ctx as the diff --git a/sys/net/gnrc/application_layer/tftp/gnrc_tftp.c b/sys/net/gnrc/application_layer/tftp/gnrc_tftp.c index 6cf78233db..0c952e73fe 100644 --- a/sys/net/gnrc/application_layer/tftp/gnrc_tftp.c +++ b/sys/net/gnrc/application_layer/tftp/gnrc_tftp.c @@ -367,7 +367,7 @@ int _tftp_init_ctxt(ipv6_addr_t *addr, const char *file_name, /* generate a random source UDP source port */ do { ctxt->src_port = (random_uint32() & 0xff) + GNRC_TFTP_DEFAULT_SRC_PORT; - } while (gnrc_netreg_num(GNRC_NETTYPE_UDP, ctxt->src_port)); + } while (gnrc_netreg_lookup(GNRC_NETTYPE_UDP, ctxt->src_port)); return TS_FINISHED; } diff --git a/sys/net/gnrc/netapi/gnrc_netapi.c b/sys/net/gnrc/netapi/gnrc_netapi.c index 9d7fbee96e..afe5998813 100644 --- a/sys/net/gnrc/netapi/gnrc_netapi.c +++ b/sys/net/gnrc/netapi/gnrc_netapi.c @@ -94,54 +94,52 @@ static inline int _snd_rcv_mbox(mbox_t *mbox, uint16_t type, gnrc_pktsnip_t *pkt int gnrc_netapi_dispatch(gnrc_nettype_t type, uint32_t demux_ctx, uint16_t cmd, gnrc_pktsnip_t *pkt) { - int numof = gnrc_netreg_num(type, demux_ctx); + int numof = 0; + gnrc_netreg_entry_t *sendto = gnrc_netreg_lookup(type, demux_ctx); - if (numof != 0) { - gnrc_netreg_entry_t *sendto = gnrc_netreg_lookup(type, demux_ctx); - - gnrc_pktbuf_hold(pkt, numof - 1); - - while (sendto) { + while (sendto) { + if (numof != 0) { + gnrc_pktbuf_hold(pkt, 1); + } #if defined(MODULE_GNRC_NETAPI_MBOX) || defined(MODULE_GNRC_NETAPI_CALLBACKS) - int release = 0; - switch (sendto->type) { - case GNRC_NETREG_TYPE_DEFAULT: - if (_snd_rcv(sendto->target.pid, cmd, pkt) < 1) { - /* unable to dispatch packet */ - release = 1; - } - break; + int release = 0; + switch (sendto->type) { + case GNRC_NETREG_TYPE_DEFAULT: + if (_snd_rcv(sendto->target.pid, cmd, pkt) < 1) { + /* unable to dispatch packet */ + release = 1; + } + break; #ifdef MODULE_GNRC_NETAPI_MBOX - case GNRC_NETREG_TYPE_MBOX: - if (_snd_rcv_mbox(sendto->target.mbox, cmd, pkt) < 1) { - /* unable to dispatch packet */ - release = 1; - } - break; + case GNRC_NETREG_TYPE_MBOX: + if (_snd_rcv_mbox(sendto->target.mbox, cmd, pkt) < 1) { + /* unable to dispatch packet */ + release = 1; + } + break; #endif #ifdef MODULE_GNRC_NETAPI_CALLBACKS - case GNRC_NETREG_TYPE_CB: - sendto->target.cbd->cb(cmd, pkt, sendto->target.cbd->ctx); - break; + case GNRC_NETREG_TYPE_CB: + sendto->target.cbd->cb(cmd, pkt, sendto->target.cbd->ctx); + break; #endif - default: - /* unknown dispatch type */ - release = 1; - break; - } - if (release) { - gnrc_pktbuf_release(pkt); - } -#else - if (_snd_rcv(sendto->target.pid, cmd, pkt) < 1) { - /* unable to dispatch packet */ - gnrc_pktbuf_release(pkt); - } -#endif - sendto = gnrc_netreg_getnext(sendto); + default: + /* unknown dispatch type */ + release = 1; + break; } + if (release) { + gnrc_pktbuf_release(pkt); + } +#else + if (_snd_rcv(sendto->target.pid, cmd, pkt) < 1) { + /* unable to dispatch packet */ + gnrc_pktbuf_release(pkt); + } +#endif + numof++; + sendto = gnrc_netreg_getnext(sendto); } - return numof; } diff --git a/sys/net/gnrc/netreg/gnrc_netreg.c b/sys/net/gnrc/netreg/gnrc_netreg.c index 521ec60e75..8d8ef83462 100644 --- a/sys/net/gnrc/netreg/gnrc_netreg.c +++ b/sys/net/gnrc/netreg/gnrc_netreg.c @@ -65,54 +65,40 @@ void gnrc_netreg_unregister(gnrc_nettype_t type, gnrc_netreg_entry_t *entry) LL_DELETE(netreg[type], entry); } -gnrc_netreg_entry_t *gnrc_netreg_lookup(gnrc_nettype_t type, uint32_t demux_ctx) +/** + * @brief Searches the next entry in the registry that matches given + * parameters, start lookup from beginning or given entry. + * + * @param[in] from A registry entry to lookup from or NULL to start fresh + * @param[in] type Type of the protocol. + * @param[in] demux_ctx The demultiplexing context for the registered thread. + * See gnrc_netreg_entry_t::demux_ctx. + * + * @return The first entry fitting the given parameters on success + * @return NULL if no entry can be found. + */ +static gnrc_netreg_entry_t *_netreg_lookup(gnrc_netreg_entry_t *from, + gnrc_nettype_t type, + uint32_t demux_ctx) { - gnrc_netreg_entry_t *res; + gnrc_netreg_entry_t *res = NULL; - if (_INVALID_TYPE(type)) { - return NULL; + if (from || !_INVALID_TYPE(type)) { + gnrc_netreg_entry_t *head = (from) ? from->next : netreg[type]; + LL_SEARCH_SCALAR(head, res, demux_ctx, demux_ctx); } - LL_SEARCH_SCALAR(netreg[type], res, demux_ctx, demux_ctx); - return res; } -int gnrc_netreg_num(gnrc_nettype_t type, uint32_t demux_ctx) +gnrc_netreg_entry_t *gnrc_netreg_lookup(gnrc_nettype_t type, uint32_t demux_ctx) { - int num = 0; - gnrc_netreg_entry_t *entry; - - if (_INVALID_TYPE(type)) { - return 0; - } - - entry = netreg[type]; - - while (entry != NULL) { - if (entry->demux_ctx == demux_ctx) { - num++; - } - - entry = entry->next; - } - - return num; + return _netreg_lookup(NULL, type, demux_ctx); } gnrc_netreg_entry_t *gnrc_netreg_getnext(gnrc_netreg_entry_t *entry) { - uint32_t demux_ctx; - - if (entry == NULL) { - return NULL; - } - - demux_ctx = entry->demux_ctx; - - LL_SEARCH_SCALAR(entry->next, entry, demux_ctx, demux_ctx); - - return entry; + return (entry ? _netreg_lookup(entry, 0, entry->demux_ctx) : NULL); } int gnrc_netreg_calc_csum(gnrc_pktsnip_t *hdr, gnrc_pktsnip_t *pseudo_hdr) diff --git a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c index ee9619f4ea..fa6cf2097c 100644 --- a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c +++ b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c @@ -219,7 +219,7 @@ static void _dispatch_next_header(gnrc_pktsnip_t *current, gnrc_pktsnip_t *pkt, /* dispatch IPv6 extension header only once */ if (should_dispatch_current_type) { - bool should_release = (gnrc_netreg_num(GNRC_NETTYPE_IPV6, nh) == 0) && + bool should_release = (!gnrc_netreg_lookup(GNRC_NETTYPE_IPV6, nh)) && (!interested); if (!should_release) { diff --git a/tests/unittests/tests-netreg/tests-netreg.c b/tests/unittests/tests-netreg/tests-netreg.c index b56a68861f..2416dac424 100644 --- a/tests/unittests/tests-netreg/tests-netreg.c +++ b/tests/unittests/tests-netreg/tests-netreg.c @@ -85,6 +85,13 @@ void test_netreg_unregister__success3(void) TEST_ASSERT_NULL(gnrc_netreg_lookup(GNRC_NETTYPE_TEST, TEST_UINT16)); } +void test_netreg_lookup__empty(void) +{ + TEST_ASSERT_NULL(gnrc_netreg_lookup(GNRC_NETTYPE_TEST, TEST_UINT16)); + TEST_ASSERT_NULL(gnrc_netreg_lookup(GNRC_NETTYPE_TEST, TEST_UINT16 + 1)); + TEST_ASSERT_NULL(gnrc_netreg_lookup(GNRC_NETTYPE_TEST, GNRC_NETREG_DEMUX_CTX_ALL)); +} + void test_netreg_lookup__wrong_type_undef(void) { TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_register(GNRC_NETTYPE_TEST, &entries[0])); @@ -97,31 +104,17 @@ void test_netreg_lookup__wrong_type_numof(void) TEST_ASSERT_NULL(gnrc_netreg_lookup(GNRC_NETTYPE_NUMOF, TEST_UINT16)); } -void test_netreg_num__empty(void) -{ - TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_num(GNRC_NETTYPE_TEST, TEST_UINT16)); - TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_num(GNRC_NETTYPE_TEST, TEST_UINT16 + 1)); - TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_num(GNRC_NETTYPE_TEST, GNRC_NETREG_DEMUX_CTX_ALL)); -} - -void test_netreg_num__wrong_type_undef(void) +void test_netreg_lookup__2_entries(void) { + gnrc_netreg_entry_t *res = NULL; + /* add first entry, first lookup != NULL; second == NULL */ TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_register(GNRC_NETTYPE_TEST, &entries[0])); - TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_num(GNRC_NETTYPE_UNDEF, TEST_UINT16)); -} - -void test_netreg_num__wrong_type_numof(void) -{ - TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_register(GNRC_NETTYPE_TEST, &entries[0])); - TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_num(GNRC_NETTYPE_NUMOF, TEST_UINT16)); -} - -void test_netreg_num__2_entries(void) -{ - TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_register(GNRC_NETTYPE_TEST, &entries[0])); - TEST_ASSERT_EQUAL_INT(1, gnrc_netreg_num(GNRC_NETTYPE_TEST, TEST_UINT16)); + TEST_ASSERT_NOT_NULL((res = gnrc_netreg_lookup(GNRC_NETTYPE_TEST, TEST_UINT16))); + TEST_ASSERT_NULL((res = gnrc_netreg_getnext(res))); + /* add second entry, both lookups != NULL */ TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_register(GNRC_NETTYPE_TEST, &entries[1])); - TEST_ASSERT_EQUAL_INT(2, gnrc_netreg_num(GNRC_NETTYPE_TEST, TEST_UINT16)); + TEST_ASSERT_NOT_NULL((res = gnrc_netreg_lookup(GNRC_NETTYPE_TEST, TEST_UINT16))); + TEST_ASSERT_NOT_NULL((res = gnrc_netreg_getnext(res))); } void test_netreg_getnext__NULL(void) @@ -134,7 +127,7 @@ void test_netreg_getnext__2_entries(void) { gnrc_netreg_entry_t *res = NULL; - test_netreg_num__2_entries(); + test_netreg_lookup__2_entries(); TEST_ASSERT_NOT_NULL((res = gnrc_netreg_lookup(GNRC_NETTYPE_TEST, TEST_UINT16))); TEST_ASSERT_NOT_NULL(gnrc_netreg_getnext(res)); } @@ -147,12 +140,10 @@ Test *tests_netreg_tests(void) new_TestFixture(test_netreg_unregister__success), new_TestFixture(test_netreg_unregister__success2), new_TestFixture(test_netreg_unregister__success3), + new_TestFixture(test_netreg_lookup__empty), new_TestFixture(test_netreg_lookup__wrong_type_undef), new_TestFixture(test_netreg_lookup__wrong_type_numof), - new_TestFixture(test_netreg_num__empty), - new_TestFixture(test_netreg_num__wrong_type_undef), - new_TestFixture(test_netreg_num__wrong_type_numof), - new_TestFixture(test_netreg_num__2_entries), + new_TestFixture(test_netreg_lookup__2_entries), new_TestFixture(test_netreg_getnext__NULL), new_TestFixture(test_netreg_getnext__2_entries), };